2 * Copyright (C) 2005-2013 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
21 #include "Database/DatabaseEnv.h"
22 #include "WorldPacket.h"
23 #include "WorldSession.h"
27 #include "ObjectMgr.h"
28 #include "ObjectGuid.h"
30 #include "UpdateMask.h"
31 #include "GridNotifiersImpl.h"
33 #include "AccountMgr.h"
35 #include "PoolManager.h"
36 #include "GameEventMgr.h"
37 #include "AuctionHouseBot/AuctionHouseBot.h"
39 // Supported shift-links (client generated and server side)
40 // |color|Hachievement:achievement_id:player_guid_hex:completed_0_1:mm:dd:yy_from_2000:criteriaMask1:criteriaMask2:criteriaMask3:criteriaMask4|h[name]|h|r
41 // - client, item icon shift click, not used in server currently
42 // |color|Hachievement_criteria:criteria_id|h[name]|h|r
43 // |color|Harea:area_id|h[name]|h|r
44 // |color|Hareatrigger:id|h[name]|h|r
45 // |color|Hareatrigger_target:id|h[name]|h|r
46 // |color|Hcreature:creature_guid|h[name]|h|r
47 // |color|Hcreature_entry:creature_id|h[name]|h|r
48 // |color|Hcurrency:currency_id||h[name]|h|r
49 // |color|Hinstancelock:player_guid:map_id:is_completed:encounter_mask|h[instance_name]|h|r
50 // |color|Henchant:recipe_spell_id|h[prof_name: recipe_name]|h|r - client, at shift click in recipes list dialog
51 // |color|Hgameevent:id|h[name]|h|r
52 // |color|Hgameobject:go_guid|h[name]|h|r
53 // |color|Hgameobject_entry:go_id|h[name]|h|r
54 // |color|Hglyph:glyph_slot_id:glyph_prop_id|h[%s]|h|r - client, at shift click in glyphs dialog, GlyphSlot.dbc, GlyphProperties.dbc
55 // |color|Hitem:item_id:perm_ench_id:gem1:gem2:gem3:0:0:0:0:reporter_level|h[name]|h|r
56 // - client, item icon shift click
57 // |color|Hitemset:itemset_id|h[name]|h|r
58 // |color|Hplayer:name|h[name]|h|r - client, in some messages, at click copy only name instead link, so no way generate it in client string send to server
59 // |color|Hpool:pool_id|h[name]|h|r
60 // |color|Hquest:quest_id:quest_level|h[name]|h|r - client, quest list name shift-click
61 // |color|Hskill:skill_id|h[name]|h|r
62 // |color|Hspell:spell_id|h[name]|h|r - client, spellbook spell icon shift-click
63 // |color|Htalent:talent_id,rank|h[name]|h|r - client, talent icon shift-click rank==-1 if shift-copy unlearned talent
64 // |color|Htaxinode:id|h[name]|h|r
65 // |color|Htele:id|h[name]|h|r
66 // |color|Htitle:id|h[name]|h|r
67 // |color|Htrade:spell_id:cur_value:max_value:unk3int:unk3str|h[name]|h|r - client, spellbook profession icon shift-click
69 bool ChatHandler::load_command_table
= true;
71 ChatCommand
* ChatHandler::getCommandTable()
73 static ChatCommand accountSetCommandTable
[] =
75 { "addon", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAccountSetAddonCommand
, "", NULL
},
76 { "gmlevel", SEC_CONSOLE
, true, &ChatHandler::HandleAccountSetGmLevelCommand
, "", NULL
},
77 { "password", SEC_CONSOLE
, true, &ChatHandler::HandleAccountSetPasswordCommand
, "", NULL
},
78 { NULL
, 0, false, NULL
, "", NULL
}
81 static ChatCommand accountCommandTable
[] =
83 { "characters", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAccountCharactersCommand
, "", NULL
},
84 { "create", SEC_CONSOLE
, true, &ChatHandler::HandleAccountCreateCommand
, "", NULL
},
85 { "delete", SEC_CONSOLE
, true, &ChatHandler::HandleAccountDeleteCommand
, "", NULL
},
86 { "onlinelist", SEC_CONSOLE
, true, &ChatHandler::HandleAccountOnlineListCommand
, "", NULL
},
87 { "lock", SEC_PLAYER
, true, &ChatHandler::HandleAccountLockCommand
, "", NULL
},
88 { "set", SEC_ADMINISTRATOR
, true, NULL
, "", accountSetCommandTable
},
89 { "password", SEC_PLAYER
, true, &ChatHandler::HandleAccountPasswordCommand
, "", NULL
},
90 { "", SEC_PLAYER
, true, &ChatHandler::HandleAccountCommand
, "", NULL
},
91 { NULL
, 0, false, NULL
, "", NULL
}
94 static ChatCommand achievementCriteriaCommandTable
[] =
96 { "add", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAchievementCriteriaAddCommand
, "", NULL
},
97 { "remove", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAchievementCriteriaRemoveCommand
, "", NULL
},
98 { NULL
, 0, true, NULL
, "", NULL
}
101 static ChatCommand achievementCommandTable
[] =
103 { "criteria", SEC_ADMINISTRATOR
, true, NULL
, "", achievementCriteriaCommandTable
},
104 { "add", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAchievementAddCommand
, "", NULL
},
105 { "remove", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAchievementRemoveCommand
, "", NULL
},
106 { "", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAchievementCommand
, "", NULL
},
107 { NULL
, 0, true, NULL
, "", NULL
}
110 static ChatCommand ahbotItemsAmountCommandTable
[] =
112 { "grey", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAHBotItemsAmountQualityCommand
<AUCTION_QUALITY_GREY
>, "", NULL
},
113 { "white", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAHBotItemsAmountQualityCommand
<AUCTION_QUALITY_WHITE
>, "", NULL
},
114 { "green", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAHBotItemsAmountQualityCommand
<AUCTION_QUALITY_GREEN
>, "", NULL
},
115 { "blue", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAHBotItemsAmountQualityCommand
<AUCTION_QUALITY_BLUE
>, "", NULL
},
116 { "purple", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAHBotItemsAmountQualityCommand
<AUCTION_QUALITY_PURPLE
>, "", NULL
},
117 { "orange", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAHBotItemsAmountQualityCommand
<AUCTION_QUALITY_ORANGE
>, "", NULL
},
118 { "yellow", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAHBotItemsAmountQualityCommand
<AUCTION_QUALITY_YELLOW
>, "", NULL
},
119 { "", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAHBotItemsAmountCommand
, "", NULL
},
120 { NULL
, 0, true, NULL
, "", NULL
}
123 static ChatCommand ahbotItemsRatioCommandTable
[] =
125 { "alliance", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAHBotItemsRatioHouseCommand
<AUCTION_HOUSE_ALLIANCE
>, "", NULL
},
126 { "horde", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAHBotItemsRatioHouseCommand
<AUCTION_HOUSE_HORDE
>, "", NULL
},
127 { "neutral", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAHBotItemsRatioHouseCommand
<AUCTION_HOUSE_NEUTRAL
>, "", NULL
},
128 { "", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAHBotItemsRatioCommand
, "", NULL
},
129 { NULL
, 0, true, NULL
, "", NULL
}
132 static ChatCommand ahbotItemsCommandTable
[] =
134 { "amount", SEC_ADMINISTRATOR
, true, NULL
, "", ahbotItemsAmountCommandTable
},
135 { "ratio", SEC_ADMINISTRATOR
, true, NULL
, "", ahbotItemsRatioCommandTable
},
136 { NULL
, 0, true, NULL
, "", NULL
}
139 static ChatCommand ahbotCommandTable
[] =
141 { "items", SEC_ADMINISTRATOR
, true, NULL
, "", ahbotItemsCommandTable
},
142 { "rebuild", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAHBotRebuildCommand
, "", NULL
},
143 { "reload", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAHBotReloadCommand
, "", NULL
},
144 { "status", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAHBotStatusCommand
, "", NULL
},
145 { NULL
, 0, true, NULL
, "", NULL
}
148 static ChatCommand auctionCommandTable
[] =
150 { "alliance", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleAuctionAllianceCommand
, "", NULL
},
151 { "goblin", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleAuctionGoblinCommand
, "", NULL
},
152 { "horde", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleAuctionHordeCommand
, "", NULL
},
153 { "item", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleAuctionItemCommand
, "", NULL
},
154 { "", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleAuctionCommand
, "", NULL
},
155 { NULL
, 0, false, NULL
, "", NULL
}
158 static ChatCommand banCommandTable
[] =
160 { "account", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleBanAccountCommand
, "", NULL
},
161 { "character", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleBanCharacterCommand
, "", NULL
},
162 { "ip", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleBanIPCommand
, "", NULL
},
163 { NULL
, 0, false, NULL
, "", NULL
}
166 static ChatCommand baninfoCommandTable
[] =
168 { "account", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleBanInfoAccountCommand
, "", NULL
},
169 { "character", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleBanInfoCharacterCommand
, "", NULL
},
170 { "ip", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleBanInfoIPCommand
, "", NULL
},
171 { NULL
, 0, false, NULL
, "", NULL
}
174 static ChatCommand banlistCommandTable
[] =
176 { "account", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleBanListAccountCommand
, "", NULL
},
177 { "character", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleBanListCharacterCommand
, "", NULL
},
178 { "ip", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleBanListIPCommand
, "", NULL
},
179 { NULL
, 0, false, NULL
, "", NULL
}
182 static ChatCommand castCommandTable
[] =
184 { "back", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleCastBackCommand
, "", NULL
},
185 { "dist", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleCastDistCommand
, "", NULL
},
186 { "self", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleCastSelfCommand
, "", NULL
},
187 { "target", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleCastTargetCommand
, "", NULL
},
188 { "", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleCastCommand
, "", NULL
},
189 { NULL
, 0, false, NULL
, "", NULL
}
192 static ChatCommand characterDeletedCommandTable
[] =
194 { "delete", SEC_CONSOLE
, true, &ChatHandler::HandleCharacterDeletedDeleteCommand
, "", NULL
},
195 { "list", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleCharacterDeletedListCommand
, "", NULL
},
196 { "restore", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleCharacterDeletedRestoreCommand
, "", NULL
},
197 { "old", SEC_CONSOLE
, true, &ChatHandler::HandleCharacterDeletedOldCommand
, "", NULL
},
198 { NULL
, 0, false, NULL
, "", NULL
}
201 static ChatCommand characterCommandTable
[] =
203 { "achievements", SEC_GAMEMASTER
, true, &ChatHandler::HandleCharacterAchievementsCommand
, "", NULL
},
204 { "customize", SEC_GAMEMASTER
, true, &ChatHandler::HandleCharacterCustomizeCommand
, "", NULL
},
205 { "deleted", SEC_GAMEMASTER
, true, NULL
, "", characterDeletedCommandTable
},
206 { "erase", SEC_CONSOLE
, true, &ChatHandler::HandleCharacterEraseCommand
, "", NULL
},
207 { "level", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleCharacterLevelCommand
, "", NULL
},
208 { "rename", SEC_GAMEMASTER
, true, &ChatHandler::HandleCharacterRenameCommand
, "", NULL
},
209 { "reputation", SEC_GAMEMASTER
, true, &ChatHandler::HandleCharacterReputationCommand
, "", NULL
},
210 { "titles", SEC_GAMEMASTER
, true, &ChatHandler::HandleCharacterTitlesCommand
, "", NULL
},
211 { NULL
, 0, false, NULL
, "", NULL
}
214 static ChatCommand debugPlayCommandTable
[] =
216 { "cinematic", SEC_MODERATOR
, false, &ChatHandler::HandleDebugPlayCinematicCommand
, "", NULL
},
217 { "movie", SEC_MODERATOR
, false, &ChatHandler::HandleDebugPlayMovieCommand
, "", NULL
},
218 { "sound", SEC_MODERATOR
, false, &ChatHandler::HandleDebugPlaySoundCommand
, "", NULL
},
219 { NULL
, 0, false, NULL
, "", NULL
}
222 static ChatCommand debugSendCommandTable
[] =
224 { "buyerror", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugSendBuyErrorCommand
, "", NULL
},
225 { "channelnotify", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugSendChannelNotifyCommand
, "", NULL
},
226 { "chatmmessage", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugSendChatMsgCommand
, "", NULL
},
227 { "equiperror", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugSendEquipErrorCommand
, "", NULL
},
228 { "largepacket", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugSendLargePacketCommand
, "", NULL
},
229 { "opcode", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugSendOpcodeCommand
, "", NULL
},
230 { "poi", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugSendPoiCommand
, "", NULL
},
231 { "qpartymsg", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugSendQuestPartyMsgCommand
, "", NULL
},
232 { "qinvalidmsg", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugSendQuestInvalidMsgCommand
, "", NULL
},
233 { "sellerror", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugSendSellErrorCommand
, "", NULL
},
234 { "setphaseshift", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugSendSetPhaseShiftCommand
, "", NULL
},
235 { "spellfail", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugSendSpellFailCommand
, "", NULL
},
236 { NULL
, 0, false, NULL
, "", NULL
}
239 static ChatCommand debugCommandTable
[] =
241 { "anim", SEC_GAMEMASTER
, false, &ChatHandler::HandleDebugAnimCommand
, "", NULL
},
242 { "arena", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugArenaCommand
, "", NULL
},
243 { "bg", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugBattlegroundCommand
, "", NULL
},
244 { "getitemstate", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugGetItemStateCommand
, "", NULL
},
245 { "lootrecipient", SEC_GAMEMASTER
, false, &ChatHandler::HandleDebugGetLootRecipientCommand
, "", NULL
},
246 { "getitemvalue", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugGetItemValueCommand
, "", NULL
},
247 { "getvalue", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugGetValueCommand
, "", NULL
},
248 { "moditemvalue", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugModItemValueCommand
, "", NULL
},
249 { "modvalue", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugModValueCommand
, "", NULL
},
250 { "play", SEC_MODERATOR
, false, NULL
, "", debugPlayCommandTable
},
251 { "send", SEC_ADMINISTRATOR
, false, NULL
, "", debugSendCommandTable
},
252 { "setaurastate", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugSetAuraStateCommand
, "", NULL
},
253 { "setitemvalue", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugSetItemValueCommand
, "", NULL
},
254 { "setvalue", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugSetValueCommand
, "", NULL
},
255 { "spellcheck", SEC_CONSOLE
, true, &ChatHandler::HandleDebugSpellCheckCommand
, "", NULL
},
256 { "spellcoefs", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleDebugSpellCoefsCommand
, "", NULL
},
257 { "spellmods", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugSpellModsCommand
, "", NULL
},
258 { "uws", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDebugUpdateWorldStateCommand
, "", NULL
},
259 { NULL
, 0, false, NULL
, "", NULL
}
262 static ChatCommand eventCommandTable
[] =
264 { "list", SEC_GAMEMASTER
, true, &ChatHandler::HandleEventListCommand
, "", NULL
},
265 { "start", SEC_GAMEMASTER
, true, &ChatHandler::HandleEventStartCommand
, "", NULL
},
266 { "stop", SEC_GAMEMASTER
, true, &ChatHandler::HandleEventStopCommand
, "", NULL
},
267 { "", SEC_GAMEMASTER
, true, &ChatHandler::HandleEventInfoCommand
, "", NULL
},
268 { NULL
, 0, false, NULL
, "", NULL
}
271 static ChatCommand gmCommandTable
[] =
273 { "chat", SEC_MODERATOR
, false, &ChatHandler::HandleGMChatCommand
, "", NULL
},
274 { "fly", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleGMFlyCommand
, "", NULL
},
275 { "ingame", SEC_PLAYER
, true, &ChatHandler::HandleGMListIngameCommand
, "", NULL
},
276 { "list", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleGMListFullCommand
, "", NULL
},
277 { "visible", SEC_MODERATOR
, false, &ChatHandler::HandleGMVisibleCommand
, "", NULL
},
278 { "setview", SEC_MODERATOR
, false, &ChatHandler::HandleSetViewCommand
, "", NULL
},
279 { "", SEC_MODERATOR
, false, &ChatHandler::HandleGMCommand
, "", NULL
},
280 { NULL
, 0, false, NULL
, "", NULL
}
283 static ChatCommand goCommandTable
[] =
285 { "creature", SEC_MODERATOR
, false, &ChatHandler::HandleGoCreatureCommand
, "", NULL
},
286 { "graveyard", SEC_MODERATOR
, false, &ChatHandler::HandleGoGraveyardCommand
, "", NULL
},
287 { "grid", SEC_MODERATOR
, false, &ChatHandler::HandleGoGridCommand
, "", NULL
},
288 { "object", SEC_MODERATOR
, false, &ChatHandler::HandleGoObjectCommand
, "", NULL
},
289 { "taxinode", SEC_MODERATOR
, false, &ChatHandler::HandleGoTaxinodeCommand
, "", NULL
},
290 { "trigger", SEC_MODERATOR
, false, &ChatHandler::HandleGoTriggerCommand
, "", NULL
},
291 { "zonexy", SEC_MODERATOR
, false, &ChatHandler::HandleGoZoneXYCommand
, "", NULL
},
292 { "xy", SEC_MODERATOR
, false, &ChatHandler::HandleGoXYCommand
, "", NULL
},
293 { "xyz", SEC_MODERATOR
, false, &ChatHandler::HandleGoXYZCommand
, "", NULL
},
294 { "", SEC_MODERATOR
, false, &ChatHandler::HandleGoCommand
, "", NULL
},
295 { NULL
, 0, false, NULL
, "", NULL
}
298 static ChatCommand gobjectCommandTable
[] =
300 { "add", SEC_GAMEMASTER
, false, &ChatHandler::HandleGameObjectAddCommand
, "", NULL
},
301 { "delete", SEC_GAMEMASTER
, false, &ChatHandler::HandleGameObjectDeleteCommand
, "", NULL
},
302 { "move", SEC_GAMEMASTER
, false, &ChatHandler::HandleGameObjectMoveCommand
, "", NULL
},
303 { "near", SEC_GAMEMASTER
, false, &ChatHandler::HandleGameObjectNearCommand
, "", NULL
},
304 { "setphase", SEC_GAMEMASTER
, false, &ChatHandler::HandleGameObjectPhaseCommand
, "", NULL
},
305 { "target", SEC_GAMEMASTER
, false, &ChatHandler::HandleGameObjectTargetCommand
, "", NULL
},
306 { "turn", SEC_GAMEMASTER
, false, &ChatHandler::HandleGameObjectTurnCommand
, "", NULL
},
307 { NULL
, 0, false, NULL
, "", NULL
}
310 static ChatCommand guildCommandTable
[] =
312 { "create", SEC_GAMEMASTER
, true, &ChatHandler::HandleGuildCreateCommand
, "", NULL
},
313 { "delete", SEC_GAMEMASTER
, true, &ChatHandler::HandleGuildDeleteCommand
, "", NULL
},
314 { "invite", SEC_GAMEMASTER
, true, &ChatHandler::HandleGuildInviteCommand
, "", NULL
},
315 { "uninvite", SEC_GAMEMASTER
, true, &ChatHandler::HandleGuildUninviteCommand
, "", NULL
},
316 { "rank", SEC_GAMEMASTER
, true, &ChatHandler::HandleGuildRankCommand
, "", NULL
},
317 { NULL
, 0, false, NULL
, "", NULL
}
320 static ChatCommand honorCommandTable
[] =
322 { "add", SEC_GAMEMASTER
, false, &ChatHandler::HandleHonorAddCommand
, "", NULL
},
323 { "addkill", SEC_GAMEMASTER
, false, &ChatHandler::HandleHonorAddKillCommand
, "", NULL
},
324 { "updatekills", SEC_GAMEMASTER
, false, &ChatHandler::HandleHonorKillsUpdateCommand
, "", NULL
},
325 { NULL
, 0, false, NULL
, "", NULL
}
328 static ChatCommand instanceCommandTable
[] =
330 { "listbinds", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleInstanceListBindsCommand
, "", NULL
},
331 { "unbind", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleInstanceUnbindCommand
, "", NULL
},
332 { "stats", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleInstanceStatsCommand
, "", NULL
},
333 { "savedata", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleInstanceSaveDataCommand
, "", NULL
},
334 { NULL
, 0, false, NULL
, "", NULL
}
337 static ChatCommand learnCommandTable
[] =
339 { "all", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleLearnAllCommand
, "", NULL
},
340 { "all_gm", SEC_GAMEMASTER
, false, &ChatHandler::HandleLearnAllGMCommand
, "", NULL
},
341 { "all_crafts", SEC_GAMEMASTER
, false, &ChatHandler::HandleLearnAllCraftsCommand
, "", NULL
},
342 { "all_default", SEC_MODERATOR
, false, &ChatHandler::HandleLearnAllDefaultCommand
, "", NULL
},
343 { "all_lang", SEC_MODERATOR
, false, &ChatHandler::HandleLearnAllLangCommand
, "", NULL
},
344 { "all_myclass", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleLearnAllMyClassCommand
, "", NULL
},
345 { "all_mypettalents", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleLearnAllMyPetTalentsCommand
, "", NULL
},
346 { "all_myspells", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleLearnAllMySpellsCommand
, "", NULL
},
347 { "all_mytalents", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleLearnAllMyTalentsCommand
, "", NULL
},
348 { "all_recipes", SEC_GAMEMASTER
, false, &ChatHandler::HandleLearnAllRecipesCommand
, "", NULL
},
349 { "", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleLearnCommand
, "", NULL
},
350 { NULL
, 0, false, NULL
, "", NULL
}
353 static ChatCommand listCommandTable
[] =
355 { "auras", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleListAurasCommand
, "", NULL
},
356 { "creature", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleListCreatureCommand
, "", NULL
},
357 { "item", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleListItemCommand
, "", NULL
},
358 { "object", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleListObjectCommand
, "", NULL
},
359 { "talents", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleListTalentsCommand
, "", NULL
},
360 { NULL
, 0, false, NULL
, "", NULL
}
363 static ChatCommand lookupAccountCommandTable
[] =
365 { "email", SEC_GAMEMASTER
, true, &ChatHandler::HandleLookupAccountEmailCommand
, "", NULL
},
366 { "ip", SEC_GAMEMASTER
, true, &ChatHandler::HandleLookupAccountIpCommand
, "", NULL
},
367 { "name", SEC_GAMEMASTER
, true, &ChatHandler::HandleLookupAccountNameCommand
, "", NULL
},
368 { NULL
, 0, false, NULL
, "", NULL
}
371 static ChatCommand lookupPlayerCommandTable
[] =
373 { "account", SEC_GAMEMASTER
, true, &ChatHandler::HandleLookupPlayerAccountCommand
, "", NULL
},
374 { "email", SEC_GAMEMASTER
, true, &ChatHandler::HandleLookupPlayerEmailCommand
, "", NULL
},
375 { "ip", SEC_GAMEMASTER
, true, &ChatHandler::HandleLookupPlayerIpCommand
, "", NULL
},
376 { NULL
, 0, false, NULL
, "", NULL
}
379 static ChatCommand lookupCommandTable
[] =
381 { "account", SEC_GAMEMASTER
, true, NULL
, "", lookupAccountCommandTable
},
382 { "achievement", SEC_GAMEMASTER
, true, &ChatHandler::HandleLookupAchievementCommand
, "", NULL
},
383 { "area", SEC_MODERATOR
, true, &ChatHandler::HandleLookupAreaCommand
, "", NULL
},
384 { "creature", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleLookupCreatureCommand
, "", NULL
},
385 { "currency", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleLookupCurrencyCommand
, "", NULL
},
386 { "event", SEC_GAMEMASTER
, true, &ChatHandler::HandleLookupEventCommand
, "", NULL
},
387 { "faction", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleLookupFactionCommand
, "", NULL
},
388 { "item", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleLookupItemCommand
, "", NULL
},
389 { "itemset", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleLookupItemSetCommand
, "", NULL
},
390 { "object", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleLookupObjectCommand
, "", NULL
},
391 { "quest", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleLookupQuestCommand
, "", NULL
},
392 { "player", SEC_GAMEMASTER
, true, NULL
, "", lookupPlayerCommandTable
},
393 { "pool", SEC_GAMEMASTER
, true, &ChatHandler::HandleLookupPoolCommand
, "", NULL
},
394 { "skill", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleLookupSkillCommand
, "", NULL
},
395 { "spell", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleLookupSpellCommand
, "", NULL
},
396 { "taxinode", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleLookupTaxiNodeCommand
, "", NULL
},
397 { "tele", SEC_MODERATOR
, true, &ChatHandler::HandleLookupTeleCommand
, "", NULL
},
398 { "title", SEC_GAMEMASTER
, true, &ChatHandler::HandleLookupTitleCommand
, "", NULL
},
399 { NULL
, 0, false, NULL
, "", NULL
}
402 static ChatCommand mmapCommandTable
[] =
404 { "path", SEC_GAMEMASTER
, false, &ChatHandler::HandleMmapPathCommand
, "", NULL
},
405 { "loc", SEC_GAMEMASTER
, false, &ChatHandler::HandleMmapLocCommand
, "", NULL
},
406 { "loadedtiles", SEC_GAMEMASTER
, false, &ChatHandler::HandleMmapLoadedTilesCommand
, "", NULL
},
407 { "stats", SEC_GAMEMASTER
, false, &ChatHandler::HandleMmapStatsCommand
, "", NULL
},
408 { "testarea", SEC_GAMEMASTER
, false, &ChatHandler::HandleMmapTestArea
, "", NULL
},
409 { "", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleMmap
, "", NULL
},
410 { NULL
, 0, false, NULL
, "", NULL
}
413 static ChatCommand modifyCommandTable
[] =
415 { "currency", SEC_GAMEMASTER
, false, &ChatHandler::HandleModifyCurrencyCommand
, "", NULL
},
416 { "holypower", SEC_MODERATOR
, false, &ChatHandler::HandleModifyHolyPowerCommand
, "", NULL
},
417 { "hp", SEC_MODERATOR
, false, &ChatHandler::HandleModifyHPCommand
, "", NULL
},
418 { "mana", SEC_MODERATOR
, false, &ChatHandler::HandleModifyManaCommand
, "", NULL
},
419 { "rage", SEC_MODERATOR
, false, &ChatHandler::HandleModifyRageCommand
, "", NULL
},
420 { "runicpower", SEC_MODERATOR
, false, &ChatHandler::HandleModifyRunicPowerCommand
, "", NULL
},
421 { "energy", SEC_MODERATOR
, false, &ChatHandler::HandleModifyEnergyCommand
, "", NULL
},
422 { "money", SEC_MODERATOR
, false, &ChatHandler::HandleModifyMoneyCommand
, "", NULL
},
423 { "speed", SEC_MODERATOR
, false, &ChatHandler::HandleModifySpeedCommand
, "", NULL
},
424 { "swim", SEC_MODERATOR
, false, &ChatHandler::HandleModifySwimCommand
, "", NULL
},
425 { "scale", SEC_MODERATOR
, false, &ChatHandler::HandleModifyScaleCommand
, "", NULL
},
426 { "bwalk", SEC_MODERATOR
, false, &ChatHandler::HandleModifyBWalkCommand
, "", NULL
},
427 { "fly", SEC_MODERATOR
, false, &ChatHandler::HandleModifyFlyCommand
, "", NULL
},
428 { "aspeed", SEC_MODERATOR
, false, &ChatHandler::HandleModifyASpeedCommand
, "", NULL
},
429 { "faction", SEC_MODERATOR
, false, &ChatHandler::HandleModifyFactionCommand
, "", NULL
},
430 { "tp", SEC_MODERATOR
, false, &ChatHandler::HandleModifyTalentCommand
, "", NULL
},
431 { "mount", SEC_MODERATOR
, false, &ChatHandler::HandleModifyMountCommand
, "", NULL
},
432 { "rep", SEC_GAMEMASTER
, false, &ChatHandler::HandleModifyRepCommand
, "", NULL
},
433 { "drunk", SEC_MODERATOR
, false, &ChatHandler::HandleModifyDrunkCommand
, "", NULL
},
434 { "standstate", SEC_GAMEMASTER
, false, &ChatHandler::HandleModifyStandStateCommand
, "", NULL
},
435 { "morph", SEC_GAMEMASTER
, false, &ChatHandler::HandleModifyMorphCommand
, "", NULL
},
436 { "phase", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleModifyPhaseCommand
, "", NULL
},
437 { "gender", SEC_GAMEMASTER
, false, &ChatHandler::HandleModifyGenderCommand
, "", NULL
},
438 { NULL
, 0, false, NULL
, "", NULL
}
441 static ChatCommand npcCommandTable
[] =
443 { "add", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcAddCommand
, "", NULL
},
444 { "addcurrency", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcAddVendorCurrencyCommand
,"", NULL
},
445 { "additem", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcAddVendorItemCommand
, "", NULL
},
446 { "addmove", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcAddMoveCommand
, "", NULL
},
447 { "aiinfo", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcAIInfoCommand
, "", NULL
},
448 { "allowmove", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleNpcAllowMovementCommand
, "", NULL
},
449 { "changeentry", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleNpcChangeEntryCommand
, "", NULL
},
450 { "changelevel", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcChangeLevelCommand
, "", NULL
},
451 { "delete", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcDeleteCommand
, "", NULL
},
452 { "delcurrency", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcDelVendorCurrencyCommand
,"", NULL
},
453 { "delitem", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcDelVendorItemCommand
, "", NULL
},
454 { "factionid", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcFactionIdCommand
, "", NULL
},
455 { "flag", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcFlagCommand
, "", NULL
},
456 { "follow", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcFollowCommand
, "", NULL
},
457 { "info", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleNpcInfoCommand
, "", NULL
},
458 { "move", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcMoveCommand
, "", NULL
},
459 { "playemote", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleNpcPlayEmoteCommand
, "", NULL
},
460 { "setmodel", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcSetModelCommand
, "", NULL
},
461 { "setmovetype", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcSetMoveTypeCommand
, "", NULL
},
462 { "setphase", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcSetPhaseCommand
, "", NULL
},
463 { "spawndist", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcSpawnDistCommand
, "", NULL
},
464 { "spawntime", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcSpawnTimeCommand
, "", NULL
},
465 { "say", SEC_MODERATOR
, false, &ChatHandler::HandleNpcSayCommand
, "", NULL
},
466 { "textemote", SEC_MODERATOR
, false, &ChatHandler::HandleNpcTextEmoteCommand
, "", NULL
},
467 { "unfollow", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcUnFollowCommand
, "", NULL
},
468 { "whisper", SEC_MODERATOR
, false, &ChatHandler::HandleNpcWhisperCommand
, "", NULL
},
469 { "yell", SEC_MODERATOR
, false, &ChatHandler::HandleNpcYellCommand
, "", NULL
},
470 { "tame", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcTameCommand
, "", NULL
},
471 { "setdeathstate", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcSetDeathStateCommand
, "", NULL
},
473 //{ TODO: fix or remove this commands
474 { "addweapon", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleNpcAddWeaponCommand
, "", NULL
},
475 { "name", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcNameCommand
, "", NULL
},
476 { "subname", SEC_GAMEMASTER
, false, &ChatHandler::HandleNpcSubNameCommand
, "", NULL
},
479 { NULL
, 0, false, NULL
, "", NULL
}
482 static ChatCommand pdumpCommandTable
[] =
484 { "load", SEC_ADMINISTRATOR
, true, &ChatHandler::HandlePDumpLoadCommand
, "", NULL
},
485 { "write", SEC_ADMINISTRATOR
, true, &ChatHandler::HandlePDumpWriteCommand
, "", NULL
},
486 { NULL
, 0, false, NULL
, "", NULL
}
489 static ChatCommand poolCommandTable
[] =
491 { "list", SEC_GAMEMASTER
, false, &ChatHandler::HandlePoolListCommand
, "", NULL
},
492 { "spawns", SEC_GAMEMASTER
, false, &ChatHandler::HandlePoolSpawnsCommand
, "", NULL
},
493 { "", SEC_GAMEMASTER
, true, &ChatHandler::HandlePoolInfoCommand
, "", NULL
},
494 { NULL
, 0, false, NULL
, "", NULL
}
497 static ChatCommand questCommandTable
[] =
499 { "add", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleQuestAddCommand
, "", NULL
},
500 { "complete", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleQuestCompleteCommand
, "", NULL
},
501 { "remove", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleQuestRemoveCommand
, "", NULL
},
502 { NULL
, 0, false, NULL
, "", NULL
}
505 static ChatCommand reloadCommandTable
[] =
507 { "all", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadAllCommand
, "", NULL
},
508 { "all_achievement", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadAllAchievementCommand
, "", NULL
},
509 { "all_area", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadAllAreaCommand
, "", NULL
},
510 { "all_eventai", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadAllEventAICommand
, "", NULL
},
511 { "all_gossips", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadAllGossipsCommand
, "", NULL
},
512 { "all_item", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadAllItemCommand
, "", NULL
},
513 { "all_locales", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadAllLocalesCommand
, "", NULL
},
514 { "all_loot", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadAllLootCommand
, "", NULL
},
515 { "all_npc", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadAllNpcCommand
, "", NULL
},
516 { "all_quest", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadAllQuestCommand
, "", NULL
},
517 { "all_scripts", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadAllScriptsCommand
, "", NULL
},
518 { "all_spell", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadAllSpellCommand
, "", NULL
},
520 { "config", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadConfigCommand
, "", NULL
},
522 { "achievement_criteria_requirement", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadAchievementCriteriaRequirementCommand
, "", NULL
},
523 { "achievement_reward", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadAchievementRewardCommand
, "", NULL
},
524 { "areatrigger_involvedrelation", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadQuestAreaTriggersCommand
, "", NULL
},
525 { "areatrigger_tavern", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadAreaTriggerTavernCommand
, "", NULL
},
526 { "areatrigger_teleport", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadAreaTriggerTeleportCommand
, "", NULL
},
527 { "command", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadCommandCommand
, "", NULL
},
528 { "conditions", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadConditionsCommand
, "", NULL
},
529 { "creature_ai_scripts", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadEventAIScriptsCommand
, "", NULL
},
530 { "creature_ai_summons", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadEventAISummonsCommand
, "", NULL
},
531 { "creature_ai_texts", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadEventAITextsCommand
, "", NULL
},
532 { "creature_battleground", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadBattleEventCommand
, "", NULL
},
533 { "creature_involvedrelation", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadCreatureQuestInvRelationsCommand
, "", NULL
},
534 { "creature_loot_template", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadLootTemplatesCreatureCommand
, "", NULL
},
535 { "creature_questrelation", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadCreatureQuestRelationsCommand
, "", NULL
},
536 { "db_script_string", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadDbScriptStringCommand
, "", NULL
},
537 { "disenchant_loot_template", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadLootTemplatesDisenchantCommand
, "", NULL
},
538 { "event_scripts", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadEventScriptsCommand
, "", NULL
},
539 { "fishing_loot_template", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadLootTemplatesFishingCommand
, "", NULL
},
540 { "game_graveyard_zone", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadGameGraveyardZoneCommand
, "", NULL
},
541 { "game_tele", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadGameTeleCommand
, "", NULL
},
542 { "gameobject_involvedrelation", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadGOQuestInvRelationsCommand
, "", NULL
},
543 { "gameobject_loot_template", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadLootTemplatesGameobjectCommand
, "", NULL
},
544 { "gameobject_questrelation", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadGOQuestRelationsCommand
, "", NULL
},
545 { "gameobject_scripts", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadGameObjectScriptsCommand
, "", NULL
},
546 { "gameobject_battleground", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadBattleEventCommand
, "", NULL
},
547 { "gossip_menu", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadGossipMenuCommand
, "", NULL
},
548 { "gossip_menu_option", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadGossipMenuCommand
, "", NULL
},
549 { "gossip_scripts", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadGossipScriptsCommand
, "", NULL
},
550 { "item_convert", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadItemConvertCommand
, "", NULL
},
551 { "item_enchantment_template", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadItemEnchantementsCommand
, "", NULL
},
552 { "item_loot_template", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadLootTemplatesItemCommand
, "", NULL
},
553 { "item_required_target", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadItemRequiredTragetCommand
, "", NULL
},
554 { "locales_achievement_reward", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadLocalesAchievementRewardCommand
, "", NULL
},
555 { "locales_creature", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadLocalesCreatureCommand
, "", NULL
},
556 { "locales_gameobject", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadLocalesGameobjectCommand
, "", NULL
},
557 { "locales_gossip_menu_option", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadLocalesGossipMenuOptionCommand
, "", NULL
},
558 { "locales_item", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadLocalesItemCommand
, "", NULL
},
559 { "locales_npc_text", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadLocalesNpcTextCommand
, "", NULL
},
560 { "locales_page_text", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadLocalesPageTextCommand
, "", NULL
},
561 { "locales_points_of_interest", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadLocalesPointsOfInterestCommand
, "", NULL
},
562 { "locales_quest", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadLocalesQuestCommand
, "", NULL
},
563 { "mail_level_reward", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadMailLevelRewardCommand
, "", NULL
},
564 { "mail_loot_template", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadLootTemplatesMailCommand
, "", NULL
},
565 { "mangos_string", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadMangosStringCommand
, "", NULL
},
566 { "milling_loot_template", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadLootTemplatesMillingCommand
, "", NULL
},
567 { "npc_gossip", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadNpcGossipCommand
, "", NULL
},
568 { "npc_text", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadNpcTextCommand
, "", NULL
},
569 { "npc_spellclick_spells", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadSpellClickSpellsCommand
, "", NULL
},
570 { "npc_trainer", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadNpcTrainerCommand
, "", NULL
},
571 { "npc_vendor", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadNpcVendorCommand
, "", NULL
},
572 { "page_text", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadPageTextsCommand
, "", NULL
},
573 { "pickpocketing_loot_template", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadLootTemplatesPickpocketingCommand
, "", NULL
},
574 { "points_of_interest", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadPointsOfInterestCommand
, "", NULL
},
575 { "prospecting_loot_template", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadLootTemplatesProspectingCommand
, "", NULL
},
576 { "quest_end_scripts", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadQuestEndScriptsCommand
, "", NULL
},
577 { "quest_poi", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadQuestPOICommand
, "", NULL
},
578 { "quest_start_scripts", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadQuestStartScriptsCommand
, "", NULL
},
579 { "quest_template", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadQuestTemplateCommand
, "", NULL
},
580 { "reference_loot_template", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadLootTemplatesReferenceCommand
, "", NULL
},
581 { "reserved_name", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadReservedNameCommand
, "", NULL
},
582 { "reputation_reward_rate", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadReputationRewardRateCommand
, "", NULL
},
583 { "reputation_spillover_template", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadReputationSpilloverTemplateCommand
, "", NULL
},
584 { "skill_discovery_template", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadSkillDiscoveryTemplateCommand
, "", NULL
},
585 { "skill_extra_item_template", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadSkillExtraItemTemplateCommand
, "", NULL
},
586 { "skill_fishing_base_level", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadSkillFishingBaseLevelCommand
, "", NULL
},
587 { "skinning_loot_template", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadLootTemplatesSkinningCommand
, "", NULL
},
588 { "spell_area", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadSpellAreaCommand
, "", NULL
},
589 { "spell_bonus_data", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadSpellBonusesCommand
, "", NULL
},
590 { "spell_chain", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadSpellChainCommand
, "", NULL
},
591 { "spell_elixir", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadSpellElixirCommand
, "", NULL
},
592 { "spell_learn_spell", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadSpellLearnSpellCommand
, "", NULL
},
593 { "spell_loot_template", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadLootTemplatesSpellCommand
, "", NULL
},
594 { "spell_pet_auras", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadSpellPetAurasCommand
, "", NULL
},
595 { "spell_proc_event", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadSpellProcEventCommand
, "", NULL
},
596 { "spell_proc_item_enchant", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadSpellProcItemEnchantCommand
, "", NULL
},
597 { "spell_script_target", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadSpellScriptTargetCommand
, "", NULL
},
598 { "spell_scripts", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadSpellScriptsCommand
, "", NULL
},
599 { "spell_target_position", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadSpellTargetPositionCommand
, "", NULL
},
600 { "spell_threats", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReloadSpellThreatsCommand
, "", NULL
},
602 { NULL
, 0, false, NULL
, "", NULL
}
605 static ChatCommand resetCommandTable
[] =
607 { "achievements", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleResetAchievementsCommand
, "", NULL
},
608 { "honor", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleResetHonorCommand
, "", NULL
},
609 { "level", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleResetLevelCommand
, "", NULL
},
610 { "specs", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleResetSpecsCommand
, "", NULL
},
611 { "spells", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleResetSpellsCommand
, "", NULL
},
612 { "stats", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleResetStatsCommand
, "", NULL
},
613 { "talents", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleResetTalentsCommand
, "", NULL
},
614 { "all", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleResetAllCommand
, "", NULL
},
615 { NULL
, 0, false, NULL
, "", NULL
}
618 static ChatCommand sendMassCommandTable
[] =
620 { "items", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleSendMassItemsCommand
, "", NULL
},
621 { "mail", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleSendMassMailCommand
, "", NULL
},
622 { "money", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleSendMassMoneyCommand
, "", NULL
},
623 { NULL
, 0, false, NULL
, "", NULL
}
626 static ChatCommand sendCommandTable
[] =
628 { "mass", SEC_ADMINISTRATOR
, true, NULL
, "", sendMassCommandTable
},
630 { "items", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleSendItemsCommand
, "", NULL
},
631 { "mail", SEC_MODERATOR
, true, &ChatHandler::HandleSendMailCommand
, "", NULL
},
632 { "message", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleSendMessageCommand
, "", NULL
},
633 { "money", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleSendMoneyCommand
, "", NULL
},
634 { NULL
, 0, false, NULL
, "", NULL
}
637 static ChatCommand serverIdleRestartCommandTable
[] =
639 { "cancel", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleServerShutDownCancelCommand
, "", NULL
},
640 { "" , SEC_ADMINISTRATOR
, true, &ChatHandler::HandleServerIdleRestartCommand
, "", NULL
},
641 { NULL
, 0, false, NULL
, "", NULL
}
644 static ChatCommand serverIdleShutdownCommandTable
[] =
646 { "cancel", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleServerShutDownCancelCommand
, "", NULL
},
647 { "" , SEC_ADMINISTRATOR
, true, &ChatHandler::HandleServerIdleShutDownCommand
, "", NULL
},
648 { NULL
, 0, false, NULL
, "", NULL
}
651 static ChatCommand serverRestartCommandTable
[] =
653 { "cancel", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleServerShutDownCancelCommand
, "", NULL
},
654 { "" , SEC_ADMINISTRATOR
, true, &ChatHandler::HandleServerRestartCommand
, "", NULL
},
655 { NULL
, 0, false, NULL
, "", NULL
}
658 static ChatCommand serverShutdownCommandTable
[] =
660 { "cancel", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleServerShutDownCancelCommand
, "", NULL
},
661 { "" , SEC_ADMINISTRATOR
, true, &ChatHandler::HandleServerShutDownCommand
, "", NULL
},
662 { NULL
, 0, false, NULL
, "", NULL
}
665 static ChatCommand serverLogCommandTable
[] =
667 { "filter", SEC_CONSOLE
, true, &ChatHandler::HandleServerLogFilterCommand
, "", NULL
},
668 { "level", SEC_CONSOLE
, true, &ChatHandler::HandleServerLogLevelCommand
, "", NULL
},
669 { NULL
, 0, false, NULL
, "", NULL
}
672 static ChatCommand serverSetCommandTable
[] =
674 { "motd", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleServerSetMotdCommand
, "", NULL
},
675 { NULL
, 0, false, NULL
, "", NULL
}
678 static ChatCommand serverCommandTable
[] =
680 { "corpses", SEC_GAMEMASTER
, true, &ChatHandler::HandleServerCorpsesCommand
, "", NULL
},
681 { "exit", SEC_CONSOLE
, true, &ChatHandler::HandleServerExitCommand
, "", NULL
},
682 { "idlerestart", SEC_ADMINISTRATOR
, true, NULL
, "", serverIdleRestartCommandTable
},
683 { "idleshutdown", SEC_ADMINISTRATOR
, true, NULL
, "", serverShutdownCommandTable
},
684 { "info", SEC_PLAYER
, true, &ChatHandler::HandleServerInfoCommand
, "", NULL
},
685 { "log", SEC_CONSOLE
, true, NULL
, "", serverLogCommandTable
},
686 { "motd", SEC_PLAYER
, true, &ChatHandler::HandleServerMotdCommand
, "", NULL
},
687 { "plimit", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleServerPLimitCommand
, "", NULL
},
688 { "restart", SEC_ADMINISTRATOR
, true, NULL
, "", serverRestartCommandTable
},
689 { "shutdown", SEC_ADMINISTRATOR
, true, NULL
, "", serverShutdownCommandTable
},
690 { "set", SEC_ADMINISTRATOR
, true, NULL
, "", serverSetCommandTable
},
691 { NULL
, 0, false, NULL
, "", NULL
}
694 static ChatCommand teleCommandTable
[] =
696 { "add", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleTeleAddCommand
, "", NULL
},
697 { "del", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleTeleDelCommand
, "", NULL
},
698 { "name", SEC_MODERATOR
, true, &ChatHandler::HandleTeleNameCommand
, "", NULL
},
699 { "group", SEC_MODERATOR
, false, &ChatHandler::HandleTeleGroupCommand
, "", NULL
},
700 { "", SEC_MODERATOR
, false, &ChatHandler::HandleTeleCommand
, "", NULL
},
701 { NULL
, 0, false, NULL
, "", NULL
}
704 static ChatCommand titlesCommandTable
[] =
706 { "add", SEC_GAMEMASTER
, false, &ChatHandler::HandleTitlesAddCommand
, "", NULL
},
707 { "current", SEC_GAMEMASTER
, false, &ChatHandler::HandleTitlesCurrentCommand
, "", NULL
},
708 { "remove", SEC_GAMEMASTER
, false, &ChatHandler::HandleTitlesRemoveCommand
, "", NULL
},
709 { "setmask", SEC_GAMEMASTER
, false, &ChatHandler::HandleTitlesSetMaskCommand
, "", NULL
},
710 { NULL
, 0, false, NULL
, "", NULL
}
713 static ChatCommand triggerCommandTable
[] =
715 { "active", SEC_GAMEMASTER
, false, &ChatHandler::HandleTriggerActiveCommand
, "", NULL
},
716 { "near", SEC_GAMEMASTER
, false, &ChatHandler::HandleTriggerNearCommand
, "", NULL
},
717 { "", SEC_GAMEMASTER
, true, &ChatHandler::HandleTriggerCommand
, "", NULL
},
718 { NULL
, 0, false, NULL
, "", NULL
}
721 static ChatCommand unbanCommandTable
[] =
723 { "account", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleUnBanAccountCommand
, "", NULL
},
724 { "character", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleUnBanCharacterCommand
, "", NULL
},
725 { "ip", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleUnBanIPCommand
, "", NULL
},
726 { NULL
, 0, false, NULL
, "", NULL
}
729 static ChatCommand wpCommandTable
[] =
731 { "show", SEC_GAMEMASTER
, false, &ChatHandler::HandleWpShowCommand
, "", NULL
},
732 { "add", SEC_GAMEMASTER
, false, &ChatHandler::HandleWpAddCommand
, "", NULL
},
733 { "modify", SEC_GAMEMASTER
, false, &ChatHandler::HandleWpModifyCommand
, "", NULL
},
734 { "export", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleWpExportCommand
, "", NULL
},
735 { "import", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleWpImportCommand
, "", NULL
},
736 { NULL
, 0, false, NULL
, "", NULL
}
739 static ChatCommand commandTable
[] =
741 { "account", SEC_PLAYER
, true, NULL
, "", accountCommandTable
},
742 { "achievement", SEC_ADMINISTRATOR
, true, NULL
, "", achievementCommandTable
},
743 { "auction", SEC_ADMINISTRATOR
, false, NULL
, "", auctionCommandTable
},
744 { "ahbot", SEC_ADMINISTRATOR
, true, NULL
, "", ahbotCommandTable
},
745 { "cast", SEC_ADMINISTRATOR
, false, NULL
, "", castCommandTable
},
746 { "character", SEC_GAMEMASTER
, true, NULL
, "", characterCommandTable
},
747 { "debug", SEC_MODERATOR
, true, NULL
, "", debugCommandTable
},
748 { "event", SEC_GAMEMASTER
, false, NULL
, "", eventCommandTable
},
749 { "gm", SEC_PLAYER
, true, NULL
, "", gmCommandTable
},
750 { "honor", SEC_GAMEMASTER
, false, NULL
, "", honorCommandTable
},
751 { "go", SEC_MODERATOR
, false, NULL
, "", goCommandTable
},
752 { "gobject", SEC_GAMEMASTER
, false, NULL
, "", gobjectCommandTable
},
753 { "guild", SEC_GAMEMASTER
, true, NULL
, "", guildCommandTable
},
754 { "instance", SEC_ADMINISTRATOR
, true, NULL
, "", instanceCommandTable
},
755 { "learn", SEC_MODERATOR
, false, NULL
, "", learnCommandTable
},
756 { "list", SEC_ADMINISTRATOR
, true, NULL
, "", listCommandTable
},
757 { "lookup", SEC_MODERATOR
, true, NULL
, "", lookupCommandTable
},
758 { "modify", SEC_MODERATOR
, false, NULL
, "", modifyCommandTable
},
759 { "npc", SEC_MODERATOR
, false, NULL
, "", npcCommandTable
},
760 { "pool", SEC_GAMEMASTER
, true, NULL
, "", poolCommandTable
},
761 { "pdump", SEC_ADMINISTRATOR
, true, NULL
, "", pdumpCommandTable
},
762 { "quest", SEC_ADMINISTRATOR
, false, NULL
, "", questCommandTable
},
763 { "reload", SEC_ADMINISTRATOR
, true, NULL
, "", reloadCommandTable
},
764 { "reset", SEC_ADMINISTRATOR
, true, NULL
, "", resetCommandTable
},
765 { "server", SEC_PLAYER
, true, NULL
, "", serverCommandTable
},
766 { "tele", SEC_MODERATOR
, true, NULL
, "", teleCommandTable
},
767 { "titles", SEC_GAMEMASTER
, false, NULL
, "", titlesCommandTable
},
768 { "trigger", SEC_GAMEMASTER
, false, NULL
, "", triggerCommandTable
},
769 { "wp", SEC_GAMEMASTER
, false, NULL
, "", wpCommandTable
},
771 { "aura", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleAuraCommand
, "", NULL
},
772 { "unaura", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleUnAuraCommand
, "", NULL
},
773 { "announce", SEC_MODERATOR
, true, &ChatHandler::HandleAnnounceCommand
, "", NULL
},
774 { "notify", SEC_MODERATOR
, true, &ChatHandler::HandleNotifyCommand
, "", NULL
},
775 { "goname", SEC_MODERATOR
, false, &ChatHandler::HandleGonameCommand
, "", NULL
},
776 { "namego", SEC_MODERATOR
, false, &ChatHandler::HandleNamegoCommand
, "", NULL
},
777 { "groupgo", SEC_MODERATOR
, false, &ChatHandler::HandleGroupgoCommand
, "", NULL
},
778 { "commands", SEC_PLAYER
, true, &ChatHandler::HandleCommandsCommand
, "", NULL
},
779 { "demorph", SEC_GAMEMASTER
, false, &ChatHandler::HandleDeMorphCommand
, "", NULL
},
780 { "die", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDieCommand
, "", NULL
},
781 { "revive", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleReviveCommand
, "", NULL
},
782 { "dismount", SEC_PLAYER
, false, &ChatHandler::HandleDismountCommand
, "", NULL
},
783 { "gps", SEC_MODERATOR
, false, &ChatHandler::HandleGPSCommand
, "", NULL
},
784 { "guid", SEC_GAMEMASTER
, false, &ChatHandler::HandleGUIDCommand
, "", NULL
},
785 { "help", SEC_PLAYER
, true, &ChatHandler::HandleHelpCommand
, "", NULL
},
786 { "itemmove", SEC_GAMEMASTER
, false, &ChatHandler::HandleItemMoveCommand
, "", NULL
},
787 { "cooldown", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleCooldownCommand
, "", NULL
},
788 { "unlearn", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleUnLearnCommand
, "", NULL
},
789 { "distance", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleGetDistanceCommand
, "", NULL
},
790 { "recall", SEC_MODERATOR
, false, &ChatHandler::HandleRecallCommand
, "", NULL
},
791 { "save", SEC_PLAYER
, false, &ChatHandler::HandleSaveCommand
, "", NULL
},
792 { "saveall", SEC_MODERATOR
, true, &ChatHandler::HandleSaveAllCommand
, "", NULL
},
793 { "kick", SEC_GAMEMASTER
, true, &ChatHandler::HandleKickPlayerCommand
, "", NULL
},
794 { "ban", SEC_ADMINISTRATOR
, true, NULL
, "", banCommandTable
},
795 { "unban", SEC_ADMINISTRATOR
, true, NULL
, "", unbanCommandTable
},
796 { "baninfo", SEC_ADMINISTRATOR
, false, NULL
, "", baninfoCommandTable
},
797 { "banlist", SEC_ADMINISTRATOR
, true, NULL
, "", banlistCommandTable
},
798 { "start", SEC_PLAYER
, false, &ChatHandler::HandleStartCommand
, "", NULL
},
799 { "taxicheat", SEC_MODERATOR
, false, &ChatHandler::HandleTaxiCheatCommand
, "", NULL
},
800 { "linkgrave", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleLinkGraveCommand
, "", NULL
},
801 { "neargrave", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleNearGraveCommand
, "", NULL
},
802 { "explorecheat", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleExploreCheatCommand
, "", NULL
},
803 { "levelup", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleLevelUpCommand
, "", NULL
},
804 { "showarea", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleShowAreaCommand
, "", NULL
},
805 { "hidearea", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleHideAreaCommand
, "", NULL
},
806 { "additem", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleAddItemCommand
, "", NULL
},
807 { "additemset", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleAddItemSetCommand
, "", NULL
},
808 { "bank", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleBankCommand
, "", NULL
},
809 { "mailbox", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleMailBoxCommand
, "", NULL
},
810 { "wchange", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleChangeWeatherCommand
, "", NULL
},
811 { "ticket", SEC_GAMEMASTER
, true, &ChatHandler::HandleTicketCommand
, "", NULL
},
812 { "delticket", SEC_GAMEMASTER
, true, &ChatHandler::HandleDelTicketCommand
, "", NULL
},
813 { "maxskill", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleMaxSkillCommand
, "", NULL
},
814 { "setskill", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleSetSkillCommand
, "", NULL
},
815 { "whispers", SEC_MODERATOR
, false, &ChatHandler::HandleWhispersCommand
, "", NULL
},
816 { "pinfo", SEC_GAMEMASTER
, true, &ChatHandler::HandlePInfoCommand
, "", NULL
},
817 { "respawn", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleRespawnCommand
, "", NULL
},
818 { "send", SEC_MODERATOR
, true, NULL
, "", sendCommandTable
},
819 { "loadscripts", SEC_ADMINISTRATOR
, true, &ChatHandler::HandleLoadScriptsCommand
, "", NULL
},
820 { "mute", SEC_MODERATOR
, true, &ChatHandler::HandleMuteCommand
, "", NULL
},
821 { "unmute", SEC_MODERATOR
, true, &ChatHandler::HandleUnmuteCommand
, "", NULL
},
822 { "movegens", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleMovegensCommand
, "", NULL
},
823 { "cometome", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleComeToMeCommand
, "", NULL
},
824 { "damage", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleDamageCommand
, "", NULL
},
825 { "combatstop", SEC_GAMEMASTER
, false, &ChatHandler::HandleCombatStopCommand
, "", NULL
},
826 { "repairitems", SEC_GAMEMASTER
, true, &ChatHandler::HandleRepairitemsCommand
, "", NULL
},
827 { "stable", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleStableCommand
, "", NULL
},
828 { "waterwalk", SEC_GAMEMASTER
, false, &ChatHandler::HandleWaterwalkCommand
, "", NULL
},
829 { "quit", SEC_CONSOLE
, true, &ChatHandler::HandleQuitCommand
, "", NULL
},
830 { "gearscore", SEC_ADMINISTRATOR
, false, &ChatHandler::HandleShowGearScoreCommand
, "", NULL
},
831 { "mmap", SEC_GAMEMASTER
, false, NULL
, "", mmapCommandTable
},
833 { NULL
, 0, false, NULL
, "", NULL
}
836 if (load_command_table
)
838 load_command_table
= false;
840 // check hardcoded part integrity
841 CheckIntegrity(commandTable
, NULL
);
843 QueryResult
* result
= WorldDatabase
.Query("SELECT name,security,help FROM command");
848 Field
* fields
= result
->Fetch();
849 std::string name
= fields
[0].GetCppString();
851 SetDataForCommandInTable(commandTable
, name
.c_str(), fields
[1].GetUInt16(), fields
[2].GetCppString());
854 while (result
->NextRow());
862 ChatHandler::ChatHandler(WorldSession
* session
) : m_session(session
) {}
864 ChatHandler::ChatHandler(Player
* player
) : m_session(player
->GetSession()) {}
866 ChatHandler::~ChatHandler() {}
868 const char* ChatHandler::GetMangosString(int32 entry
) const
870 return m_session
->GetMangosString(entry
);
873 const char* ChatHandler::GetOnOffStr(bool value
) const
875 return value
? GetMangosString(LANG_ON
) : GetMangosString(LANG_OFF
);
878 uint32
ChatHandler::GetAccountId() const
880 return m_session
->GetAccountId();
883 AccountTypes
ChatHandler::GetAccessLevel() const
885 return m_session
->GetSecurity();
888 bool ChatHandler::isAvailable(ChatCommand
const& cmd
) const
890 // check security level only for simple command (without child commands)
891 return GetAccessLevel() >= (AccountTypes
)cmd
.SecurityLevel
;
894 std::string
ChatHandler::GetNameLink() const
896 return GetNameLink(m_session
->GetPlayer());
899 bool ChatHandler::HasLowerSecurity(Player
* target
, ObjectGuid guid
, bool strong
)
901 WorldSession
* target_session
= NULL
;
902 uint32 target_account
= 0;
905 target_session
= target
->GetSession();
907 target_account
= sObjectMgr
.GetPlayerAccountIdByGUID(guid
);
909 if (!target_session
&& !target_account
)
911 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
912 SetSentErrorMessage(true);
916 return HasLowerSecurityAccount(target_session
, target_account
, strong
);
919 bool ChatHandler::HasLowerSecurityAccount(WorldSession
* target
, uint32 target_account
, bool strong
)
921 AccountTypes target_sec
;
923 // ignore only for non-players for non strong checks (when allow apply command at least to same sec level)
924 if (GetAccessLevel() > SEC_PLAYER
&& !strong
&& !sWorld
.getConfig(CONFIG_BOOL_GM_LOWER_SECURITY
))
928 target_sec
= target
->GetSecurity();
929 else if (target_account
)
930 target_sec
= sAccountMgr
.GetSecurity(target_account
);
932 return true; // caller must report error for (target==NULL && target_account==0)
934 if (GetAccessLevel() < target_sec
|| (strong
&& GetAccessLevel() <= target_sec
))
936 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW
);
937 SetSentErrorMessage(true);
944 bool ChatHandler::hasStringAbbr(const char* name
, const char* part
)
949 // "" part from non-"" command
959 else if (tolower(*name
) != tolower(*part
))
964 // allow with any for ""
969 void ChatHandler::SendSysMessage(const char* str
)
973 // need copy to prevent corruption by strtok call in LineFromMessage original string
974 char* buf
= mangos_strdup(str
);
977 while (char* line
= LineFromMessage(pos
))
979 FillSystemMessageData(&data
, line
);
980 m_session
->SendPacket(&data
);
986 void ChatHandler::SendGlobalSysMessage(const char* str
)
991 // need copy to prevent corruption by strtok call in LineFromMessage original string
992 char* buf
= mangos_strdup(str
);
995 while (char* line
= LineFromMessage(pos
))
997 FillSystemMessageData(&data
, line
);
998 sWorld
.SendGlobalMessage(&data
);
1004 void ChatHandler::SendSysMessage(int32 entry
)
1006 SendSysMessage(GetMangosString(entry
));
1009 void ChatHandler::PSendSysMessage(int32 entry
, ...)
1011 const char* format
= GetMangosString(entry
);
1014 va_start(ap
, entry
);
1015 vsnprintf(str
, 2048, format
, ap
);
1017 SendSysMessage(str
);
1020 void ChatHandler::PSendSysMessage(const char* format
, ...)
1024 va_start(ap
, format
);
1025 vsnprintf(str
, 2048, format
, ap
);
1027 SendSysMessage(str
);
1030 void ChatHandler::CheckIntegrity(ChatCommand
* table
, ChatCommand
* parentCommand
)
1032 for (uint32 i
= 0; table
[i
].Name
!= NULL
; ++i
)
1034 ChatCommand
* command
= &table
[i
];
1036 if (parentCommand
&& command
->SecurityLevel
< parentCommand
->SecurityLevel
)
1037 sLog
.outError("Subcommand '%s' of command '%s' have less access level (%u) that parent (%u)",
1038 command
->Name
, parentCommand
->Name
, command
->SecurityLevel
, parentCommand
->SecurityLevel
);
1040 if (!parentCommand
&& strlen(command
->Name
) == 0)
1041 sLog
.outError("Subcommand '' at top level");
1043 if (command
->ChildCommands
)
1045 if (command
->Handler
)
1048 sLog
.outError("Subcommand '%s' of command '%s' have handler and subcommands in same time, must be used '' subcommand for handler instead.",
1049 command
->Name
, parentCommand
->Name
);
1051 sLog
.outError("First level command '%s' have handler and subcommands in same time, must be used '' subcommand for handler instead.",
1055 if (parentCommand
&& strlen(command
->Name
) == 0)
1056 sLog
.outError("Subcommand '' of command '%s' have subcommands", parentCommand
->Name
);
1058 CheckIntegrity(command
->ChildCommands
, command
);
1060 else if (!command
->Handler
)
1063 sLog
.outError("Subcommand '%s' of command '%s' not have handler and subcommands in same time. Must have some from its!",
1064 command
->Name
, parentCommand
->Name
);
1066 sLog
.outError("First level command '%s' not have handler and subcommands in same time. Must have some from its!",
1073 * Search (sub)command for command line available for chat handler access level
1075 * @param text Command line string that will parsed for (sub)command search
1077 * @return Pointer to found command structure or NULL if appropriate command not found
1079 ChatCommand
const* ChatHandler::FindCommand(char const* text
)
1081 ChatCommand
* command
= NULL
;
1082 char const* textPtr
= text
;
1084 return FindCommand(getCommandTable(), textPtr
, command
) == CHAT_COMMAND_OK
? command
: NULL
;
1088 * Search (sub)command for command line available for chat handler access level with options and fail case additional info
1090 * @param table Pointer to command C-style array first level command where will be searched
1091 * @param text Command line string that will parsed for (sub)command search,
1092 * it modified at return from function and pointed to not parsed tail
1093 * @param command At success this is found command, at other cases this is last found parent command
1094 * before subcommand search fail
1095 * @param parentCommand Output arg for optional return parent command for command arg.
1096 * @param cmdNamePtr Output arg for optional return last parsed command name.
1097 * @param allAvailable Optional arg (with false default value) control use command access level checks while command search.
1098 * @param exactlyName Optional arg (with false default value) control use exactly name in checks while command search.
1100 * @return one from enum value of ChatCommandSearchResult. Output args return values highly dependent from this return result:
1102 * CHAT_COMMAND_OK - Command found!
1103 * text point to non parsed tail with possible command specific data, command store found command pointer,
1104 * parentCommand have parent of found command or NULL if command found in table array directly
1105 * cmdNamePtr store found command name in original form from command line
1106 * CHAT_COMMAND_UNKNOWN - Command not found in table directly
1107 * text only skip possible whitespaces,
1109 * parentCommand is NULL
1110 * cmdNamePtr store command name that not found as it extracted from command line
1111 * CHAT_COMMAND_UNKNOWN_SUBCOMMAND - Subcommand not found in some deed subcomand lists
1112 * text point to non parsed tail including not found command name in command line,
1113 * command store last found parent command if any
1114 * parentCommand have parent of command in command arg or NULL
1115 * cmdNamePtr store command name that not found as it extracted from command line
1117 ChatCommandSearchResult
ChatHandler::FindCommand(ChatCommand
* table
, char const*& text
, ChatCommand
*& command
, ChatCommand
** parentCommand
/*= NULL*/, std::string
* cmdNamePtr
/*= NULL*/, bool allAvailable
/*= false*/, bool exactlyName
/*= false*/)
1119 std::string cmd
= "";
1122 while (*text
!= ' ' && *text
!= '\0')
1128 while (*text
== ' ') ++text
;
1130 // search first level command in table
1131 for (uint32 i
= 0; table
[i
].Name
!= NULL
; ++i
)
1135 size_t len
= strlen(table
[i
].Name
);
1136 if (strncmp(table
[i
].Name
, cmd
.c_str(), len
+ 1) != 0)
1141 if (!hasStringAbbr(table
[i
].Name
, cmd
.c_str()))
1144 // select subcommand from child commands list
1145 if (table
[i
].ChildCommands
!= NULL
)
1147 char const* oldchildtext
= text
;
1148 ChatCommand
* parentSubcommand
= NULL
;
1149 ChatCommandSearchResult res
= FindCommand(table
[i
].ChildCommands
, text
, command
, &parentSubcommand
, cmdNamePtr
, allAvailable
, exactlyName
);
1153 case CHAT_COMMAND_OK
:
1155 // if subcommand success search not return parent command, then this parent command is owner of child commands
1157 *parentCommand
= parentSubcommand
? parentSubcommand
: &table
[i
];
1159 // Name == "" is special case: restore original command text for next level "" (where parentSubcommand==NULL)
1160 if (strlen(command
->Name
) == 0 && !parentSubcommand
)
1161 text
= oldchildtext
;
1163 return CHAT_COMMAND_OK
;
1165 case CHAT_COMMAND_UNKNOWN
:
1167 // command not found directly in child command list, return child command list owner
1168 command
= &table
[i
];
1170 *parentCommand
= NULL
; // we don't known parent of table list at this point
1172 text
= oldchildtext
; // restore text to stated just after parse found parent command
1173 return CHAT_COMMAND_UNKNOWN_SUBCOMMAND
; // we not found subcommand for table[i]
1175 case CHAT_COMMAND_UNKNOWN_SUBCOMMAND
:
1178 // some deep subcommand not found, if this second level subcommand then parentCommand can be NULL, use known value for it
1180 *parentCommand
= parentSubcommand
? parentSubcommand
: &table
[i
];
1186 // must be available (not checked for subcommands case because parent command expected have most low access that all subcommands always
1187 if (!allAvailable
&& !isAvailable(table
[i
]))
1190 // must be have handler is explicitly selected
1191 if (!table
[i
].Handler
)
1194 // command found directly in to table
1195 command
= &table
[i
];
1197 // unknown table owner at this point
1199 *parentCommand
= NULL
;
1204 return CHAT_COMMAND_OK
;
1207 // command not found in table directly
1210 // unknown table owner at this point
1212 *parentCommand
= NULL
;
1217 return CHAT_COMMAND_UNKNOWN
;
1221 * Execute (sub)command available for chat handler access level with options in command line string
1223 * @param text Command line string that will parsed for (sub)command search and command specific data
1225 * Command output and errors in command execution will send to chat handler.
1227 void ChatHandler::ExecuteCommand(const char* text
)
1229 std::string fullcmd
= text
; // original `text` can't be used. It content destroyed in command code processing.
1231 ChatCommand
* command
= NULL
;
1232 ChatCommand
* parentCommand
= NULL
;
1234 ChatCommandSearchResult res
= FindCommand(getCommandTable(), text
, command
, &parentCommand
);
1238 case CHAT_COMMAND_OK
:
1240 SetSentErrorMessage(false);
1241 if ((this->*(command
->Handler
))((char*)text
)) // text content destroyed at call
1243 if (command
->SecurityLevel
> SEC_PLAYER
)
1244 LogCommand(fullcmd
.c_str());
1246 // some commands have custom error messages. Don't send the default one in these cases.
1247 else if (!HasSentErrorMessage())
1249 if (!command
->Help
.empty())
1250 SendSysMessage(command
->Help
.c_str());
1252 SendSysMessage(LANG_CMD_SYNTAX
);
1254 if (ChatCommand
* showCommand
= (strlen(command
->Name
) == 0 && parentCommand
? parentCommand
: command
))
1255 if (ChatCommand
* childs
= showCommand
->ChildCommands
)
1256 ShowHelpForSubCommands(childs
, showCommand
->Name
);
1258 SetSentErrorMessage(true);
1262 case CHAT_COMMAND_UNKNOWN_SUBCOMMAND
:
1264 SendSysMessage(LANG_NO_SUBCMD
);
1265 ShowHelpForCommand(command
->ChildCommands
, text
);
1266 SetSentErrorMessage(true);
1269 case CHAT_COMMAND_UNKNOWN
:
1271 SendSysMessage(LANG_NO_CMD
);
1272 SetSentErrorMessage(true);
1279 * Function find appropriate command and update command security level and help text
1281 * @param commandTable Table for first level command search
1282 * @param text Command line string that will parsed for (sub)command search
1283 * @param security New security level for command
1284 * @param help New help text for command
1286 * @return true if command has been found, and false in other case
1288 * All problems found while command search and updated output as to DB errors log
1290 bool ChatHandler::SetDataForCommandInTable(ChatCommand
* commandTable
, const char* text
, uint32 security
, std::string
const& help
)
1292 std::string fullcommand
= text
; // original `text` can't be used. It content destroyed in command code processing.
1294 ChatCommand
* command
= NULL
;
1295 std::string cmdName
;
1297 ChatCommandSearchResult res
= FindCommand(commandTable
, text
, command
, NULL
, &cmdName
, true, true);
1301 case CHAT_COMMAND_OK
:
1303 if (command
->SecurityLevel
!= security
)
1304 DETAIL_LOG("Table `command` overwrite for command '%s' default security (%u) by %u",
1305 fullcommand
.c_str(), command
->SecurityLevel
, security
);
1307 command
->SecurityLevel
= security
;
1308 command
->Help
= help
;
1311 case CHAT_COMMAND_UNKNOWN_SUBCOMMAND
:
1313 // command have subcommands, but not '' subcommand and then any data in `command` useless for it.
1314 if (cmdName
.empty())
1315 sLog
.outErrorDb("Table `command` have command '%s' that only used with some subcommand selection, it can't have help or overwritten access level, skip.", cmdName
.c_str());
1317 sLog
.outErrorDb("Table `command` have unexpected subcommand '%s' in command '%s', skip.", cmdName
.c_str(), fullcommand
.c_str());
1320 case CHAT_COMMAND_UNKNOWN
:
1322 sLog
.outErrorDb("Table `command` have nonexistent command '%s', skip.", cmdName
.c_str());
1330 bool ChatHandler::ParseCommands(const char* text
)
1332 MANGOS_ASSERT(text
);
1333 MANGOS_ASSERT(*text
);
1335 // if(m_session->GetSecurity() == SEC_PLAYER)
1338 /// chat case (.command or !command format)
1341 if (text
[0] != '!' && text
[0] != '.')
1344 /// ignore single . and ! in line
1345 if (strlen(text
) < 2)
1349 /// ignore messages staring from many dots.
1350 if ((text
[0] == '.' && text
[1] == '.') || (text
[0] == '!' && text
[1] == '!'))
1353 /// skip first . or ! (in console allowed use command with . and ! and without its)
1354 if (text
[0] == '!' || text
[0] == '.')
1357 ExecuteCommand(text
);
1362 bool ChatHandler::ShowHelpForSubCommands(ChatCommand
* table
, char const* cmd
)
1365 for (uint32 i
= 0; table
[i
].Name
!= NULL
; ++i
)
1367 // must be available (ignore handler existence for show command with possible available subcommands
1368 if (!isAvailable(table
[i
]))
1376 list
+= table
[i
].Name
;
1378 if (table
[i
].ChildCommands
)
1385 if (table
== getCommandTable())
1387 SendSysMessage(LANG_AVIABLE_CMD
);
1388 SendSysMessage(list
.c_str());
1392 PSendSysMessage(LANG_SUBCMDS_LIST
, cmd
);
1393 SendSysMessage(list
.c_str());
1398 bool ChatHandler::ShowHelpForCommand(ChatCommand
* table
, const char* cmd
)
1400 char const* oldCmd
= cmd
;
1401 ChatCommand
* command
= NULL
;
1402 ChatCommand
* parentCommand
= NULL
;
1404 ChatCommand
* showCommand
= NULL
;
1405 ChatCommand
* childCommands
= NULL
;
1407 ChatCommandSearchResult res
= FindCommand(table
, cmd
, command
, &parentCommand
);
1411 case CHAT_COMMAND_OK
:
1413 // for "" subcommand use parent command if any for subcommands list output
1414 if (strlen(command
->Name
) == 0 && parentCommand
)
1416 showCommand
= parentCommand
;
1420 showCommand
= command
;
1422 childCommands
= showCommand
->ChildCommands
;
1425 case CHAT_COMMAND_UNKNOWN_SUBCOMMAND
:
1426 showCommand
= command
;
1427 childCommands
= showCommand
->ChildCommands
;
1429 case CHAT_COMMAND_UNKNOWN
:
1430 // not show command list at error in first level command find fail
1431 childCommands
= table
!= getCommandTable() || strlen(oldCmd
) == 0 ? table
: NULL
;
1436 if (command
&& !command
->Help
.empty())
1437 SendSysMessage(command
->Help
.c_str());
1440 if (ShowHelpForSubCommands(childCommands
, showCommand
? showCommand
->Name
: ""))
1443 if (command
&& command
->Help
.empty())
1444 SendSysMessage(LANG_NO_HELP_CMD
);
1446 return command
|| childCommands
;
1449 bool ChatHandler::isValidChatMessage(const char* message
)
1454 |cff00aa00|Hcurrency:391|h[Ðåêîìåíäàòåëüíûé çíà÷îê Òîë Áàðàäà]|h|r
1455 |cffff8000|Hinstancelock:070000000177AF81:532:0:1|h[Êàðàæàí]|h|r NYI
1456 |cffa335ee|Hitem:812:0:0:0:0:0:0:0:70|h[Glowing Brightwood Staff]|h|r
1457 |cff808080|Hquest:2278:47|h[The Platinum Discs]|h|r
1458 |cffffd000|Htrade:4037:1:150:1:6AAAAAAAAAAAAAAAAAAAAAAOAADAAAAAAAAAAAAAAAAIAAAAAAAAA|h[Engineering]|h|r
1459 |cff4e96f7|Htalent:2232:-1|h[Taste for Blood]|h|r
1460 |cff71d5ff|Hspell:21563|h[Command]|h|r
1461 |cffffd000|Henchant:3919|h[Engineering: Rough Dynamite]|h|r
1462 |cffffff00|Hachievement:546:0000000000000001:0:0:0:-1:0:0:0:0|h[Safe Deposit]|h|r
1463 |cff66bbff|Hglyph:21:762|h[Glyph of Bladestorm]|h|r
1465 | will be escaped to ||
1468 if (strlen(message
) > 255)
1471 const char validSequence
[6] = "cHhhr";
1472 const char* validSequenceIterator
= validSequence
;
1474 // more simple checks
1475 if (sWorld
.getConfig(CONFIG_UINT32_CHAT_STRICT_LINK_CHECKING_SEVERITY
) < 3)
1477 const std::string validCommands
= "cHhr|";
1481 // find next pipe command
1482 message
= strchr(message
, '|');
1488 char commandChar
= *message
;
1489 if (validCommands
.find(commandChar
) == std::string::npos
)
1493 // validate sequence
1494 if (sWorld
.getConfig(CONFIG_UINT32_CHAT_STRICT_LINK_CHECKING_SEVERITY
) == 2)
1496 if (commandChar
== *validSequenceIterator
)
1498 if (validSequenceIterator
== validSequence
+ 4)
1499 validSequenceIterator
= validSequence
;
1501 ++validSequenceIterator
;
1503 else if (commandChar
!= '|')
1510 std::istringstream
reader(message
);
1515 CurrencyTypesEntry
const* linkedCurrency
= NULL
;
1516 ItemPrototype
const* linkedItem
= NULL
;
1517 Quest
const* linkedQuest
= NULL
;
1518 SpellEntry
const* linkedSpell
= NULL
;
1519 AchievementEntry
const* linkedAchievement
= NULL
;
1520 ItemRandomPropertiesEntry
const* itemProperty
= NULL
;
1521 ItemRandomSuffixEntry
const* itemSuffix
= NULL
;
1523 while (!reader
.eof())
1525 if (validSequence
== validSequenceIterator
)
1527 linkedCurrency
= NULL
;
1531 linkedAchievement
= NULL
;
1532 itemProperty
= NULL
;
1535 reader
.ignore(255, '|');
1537 else if (reader
.get() != '|')
1539 DEBUG_LOG("ChatHandler::isValidChatMessage sequence aborted unexpectedly");
1543 // pipe has always to be followed by at least one char
1544 if (reader
.peek() == '\0')
1546 DEBUG_LOG("ChatHandler::isValidChatMessage pipe followed by \\0");
1550 // no further pipe commands
1555 reader
>> commandChar
;
1557 // | in normal messages is escaped by ||
1558 if (commandChar
!= '|')
1560 if (commandChar
== *validSequenceIterator
)
1562 if (validSequenceIterator
== validSequence
+ 4)
1563 validSequenceIterator
= validSequence
;
1565 ++validSequenceIterator
;
1569 DEBUG_LOG("ChatHandler::isValidChatMessage invalid sequence, expected %c but got %c", *validSequenceIterator
, commandChar
);
1573 else if (validSequence
!= validSequenceIterator
)
1575 // no escaped pipes in sequences
1576 DEBUG_LOG("ChatHandler::isValidChatMessage got escaped pipe in sequence");
1580 switch (commandChar
)
1584 // validate color, expect 8 hex chars
1585 for (int i
= 0; i
< 8; ++i
)
1591 DEBUG_LOG("ChatHandler::isValidChatMessage got \\0 while reading color in |c command");
1596 // check for hex char
1597 if (c
>= '0' && c
<= '9')
1602 if (c
>= 'a' && c
<= 'f')
1604 color
|= 10 + c
- 'a';
1607 DEBUG_LOG("ChatHandler::isValidChatMessage got non hex char '%c' while reading color", c
);
1612 // read chars up to colon = link type
1613 reader
.getline(buffer
, 256, ':');
1614 if (reader
.eof()) // : must be
1617 if (strcmp(buffer
, "currency") == 0)
1619 if (color
!= CHAT_LINK_COLOR_CURRENCY
)
1622 uint32 currencyEntry
= 0;
1623 // read currency entry
1624 char c
= reader
.peek();
1625 while (c
>= '0' && c
<= '9')
1628 currencyEntry
*= 10;
1629 currencyEntry
+= c
- '0';
1632 linkedCurrency
= sCurrencyTypesStore
.LookupEntry(currencyEntry
);
1633 if (!linkedCurrency
)
1636 else if (strcmp(buffer
, "item") == 0)
1639 reader
.getline(buffer
, 256, ':');
1640 if (reader
.eof()) // : must be
1643 linkedItem
= ObjectMgr::GetItemPrototype(atoi(buffer
));
1646 DEBUG_LOG("ChatHandler::isValidChatMessage got invalid itemID %u in |item command", atoi(buffer
));
1650 if (color
!= ItemQualityColors
[linkedItem
->Quality
])
1652 DEBUG_LOG("ChatHandler::isValidChatMessage linked item has color %u, but user claims %u", ItemQualityColors
[linkedItem
->Quality
],
1657 // the itementry is followed by several integers which describe an instance of this item
1659 // position relative after itemEntry
1660 const uint8 randomPropertyPosition
= 6;
1662 int32 propertyId
= 0;
1663 bool negativeNumber
= false;
1665 for (uint8 i
= 0; i
< randomPropertyPosition
; ++i
)
1668 negativeNumber
= false;
1669 while ((c
= reader
.get()) != ':')
1671 if (c
>= '0' && c
<= '9')
1674 propertyId
+= c
- '0';
1677 negativeNumber
= true;
1687 itemProperty
= sItemRandomPropertiesStore
.LookupEntry(propertyId
);
1691 else if (propertyId
< 0)
1693 itemSuffix
= sItemRandomSuffixStore
.LookupEntry(-propertyId
);
1698 // ignore other integers
1699 while ((c
>= '0' && c
<= '9') || c
== ':')
1705 else if (strcmp(buffer
, "quest") == 0)
1707 // no color check for questlinks, each client will adapt it anyway
1710 char c
= reader
.peek();
1711 while (c
>= '0' && c
<= '9')
1719 linkedQuest
= sObjectMgr
.GetQuestTemplate(questid
);
1723 DEBUG_LOG("ChatHandler::isValidChatMessage Questtemplate %u not found", questid
);
1729 DEBUG_LOG("ChatHandler::isValidChatMessage Invalid quest link structure");
1736 uint32 questlevel
= 0;
1737 while (c
>= '0' && c
<= '9')
1741 questlevel
+= c
- '0';
1745 if (questlevel
>= STRONG_MAX_LEVEL
)
1747 DEBUG_LOG("ChatHandler::isValidChatMessage Quest level %u too big", questlevel
);
1753 DEBUG_LOG("ChatHandler::isValidChatMessage Invalid quest link structure");
1757 else if (strcmp(buffer
, "trade") == 0)
1759 if (color
!= CHAT_LINK_COLOR_TRADE
)
1763 reader
.getline(buffer
, 256, ':');
1764 if (reader
.eof()) // : must be
1767 linkedSpell
= sSpellStore
.LookupEntry(atoi(buffer
));
1771 char c
= reader
.peek();
1772 // base64 encoded stuff
1773 while (c
!= '|' && c
!= '\0')
1779 else if (strcmp(buffer
, "talent") == 0)
1781 // talent links are always supposed to be blue
1782 if (color
!= CHAT_LINK_COLOR_TALENT
)
1785 // read talent entry
1786 reader
.getline(buffer
, 256, ':');
1787 if (reader
.eof()) // : must be
1790 TalentEntry
const* talentInfo
= sTalentStore
.LookupEntry(atoi(buffer
));
1794 linkedSpell
= sSpellStore
.LookupEntry(talentInfo
->RankID
[0]);
1798 char c
= reader
.peek();
1799 // skillpoints? whatever, drop it
1800 while (c
!= '|' && c
!= '\0')
1806 else if (strcmp(buffer
, "spell") == 0)
1808 if (color
!= CHAT_LINK_COLOR_SPELL
)
1813 char c
= reader
.peek();
1814 while (c
>= '0' && c
<= '9')
1821 linkedSpell
= sSpellStore
.LookupEntry(spellid
);
1825 else if (strcmp(buffer
, "enchant") == 0)
1827 if (color
!= CHAT_LINK_COLOR_ENCHANT
)
1832 char c
= reader
.peek();
1833 while (c
>= '0' && c
<= '9')
1840 linkedSpell
= sSpellStore
.LookupEntry(spellid
);
1844 else if (strcmp(buffer
, "achievement") == 0)
1846 if (color
!= CHAT_LINK_COLOR_ACHIEVEMENT
)
1849 reader
.getline(buffer
, 256, ':');
1850 if (reader
.eof()) // : must be
1853 uint32 achievementId
= atoi(buffer
);
1854 linkedAchievement
= sAchievementStore
.LookupEntry(achievementId
);
1856 if (!linkedAchievement
)
1859 char c
= reader
.peek();
1861 while (c
!= '|' && c
!= '\0')
1867 else if (strcmp(buffer
, "glyph") == 0)
1869 if (color
!= CHAT_LINK_COLOR_GLYPH
)
1872 // first id is slot, drop it
1873 reader
.getline(buffer
, 256, ':');
1874 if (reader
.eof()) // : must be
1878 char c
= reader
.peek();
1879 while (c
>= '0' && c
<= '9')
1886 GlyphPropertiesEntry
const* glyph
= sGlyphPropertiesStore
.LookupEntry(glyphId
);
1890 linkedSpell
= sSpellStore
.LookupEntry(glyph
->SpellId
);
1897 DEBUG_LOG("ChatHandler::isValidChatMessage user sent unsupported link type '%s'", buffer
);
1902 // if h is next element in sequence, this one must contain the linked text :)
1903 if (*validSequenceIterator
== 'h')
1905 // links start with '['
1906 if (reader
.get() != '[')
1908 DEBUG_LOG("ChatHandler::isValidChatMessage link caption doesn't start with '['");
1911 reader
.getline(buffer
, 256, ']');
1912 if (reader
.eof()) // ] must be
1915 // verify the link name
1918 if (linkedCurrency
->ID
== CURRENCY_CONQUEST_ARENA_META
|| linkedCurrency
->ID
== CURRENCY_CONQUEST_BG_META
)
1921 bool foundName
= false;
1922 for (uint8 i
= 0; i
< MAX_LOCALE
; ++i
)
1924 if (*linkedCurrency
->name
[i
] && strcmp(linkedCurrency
->name
[i
], buffer
) == 0)
1933 else if (linkedSpell
)
1935 // spells with that flag have a prefix of "$PROFESSION: "
1936 if (linkedSpell
->HasAttribute(SPELL_ATTR_TRADESPELL
))
1939 SkillLineAbilityMapBounds bounds
= sSpellMgr
.GetSkillLineAbilityMapBounds(linkedSpell
->Id
);
1940 if (bounds
.first
== bounds
.second
)
1945 SkillLineAbilityEntry
const* skillInfo
= bounds
.first
->second
;
1952 SkillLineEntry
const* skillLine
= sSkillLineStore
.LookupEntry(skillInfo
->skillId
);
1958 for (uint8 i
= 0; i
< MAX_LOCALE
; ++i
)
1960 uint32 skillLineNameLength
= strlen(skillLine
->name
[i
]);
1961 if (skillLineNameLength
> 0 && strncmp(skillLine
->name
[i
], buffer
, skillLineNameLength
) == 0)
1963 // found the prefix, remove it to perform spellname validation below
1964 // -2 = strlen(": ")
1965 uint32 spellNameLength
= strlen(buffer
) - skillLineNameLength
- 2;
1966 memmove(buffer
, buffer
+ skillLineNameLength
+ 2, spellNameLength
+ 1);
1970 bool foundName
= false;
1971 for (uint8 i
= 0; i
< MAX_LOCALE
; ++i
)
1973 if (*linkedSpell
->SpellName
[i
] && strcmp(linkedSpell
->SpellName
[i
], buffer
) == 0)
1982 else if (linkedQuest
)
1984 if (linkedQuest
->GetTitle() != buffer
)
1986 QuestLocale
const* ql
= sObjectMgr
.GetQuestLocale(linkedQuest
->GetQuestId());
1990 DEBUG_LOG("ChatHandler::isValidChatMessage default questname didn't match and there is no locale");
1994 bool foundName
= false;
1995 for (uint8 i
= 0; i
< ql
->Title
.size(); ++i
)
1997 if (ql
->Title
[i
] == buffer
)
2005 DEBUG_LOG("ChatHandler::isValidChatMessage no quest locale title matched");
2010 else if (linkedItem
)
2012 DBCString suffix
= itemSuffix
?itemSuffix
->nameSuffix
:(itemProperty
?itemProperty
->nameSuffix
:NULL
);
2014 std::string expectedName
= std::string(linkedItem
->Name1
);
2017 expectedName
+= " ";
2018 expectedName
+= suffix
[LOCALE_enUS
];
2021 if (expectedName
!= buffer
)
2023 ItemLocale
const* il
= sObjectMgr
.GetItemLocale(linkedItem
->ItemId
);
2025 bool foundName
= false;
2026 for (uint8 i
= LOCALE_koKR
; i
< MAX_LOCALE
; ++i
)
2028 int8 dbIndex
= sObjectMgr
.GetIndexForLocale(LocaleConstant(i
));
2029 if (dbIndex
== -1 || il
== NULL
|| (size_t)dbIndex
>= il
->Name
.size())
2030 // using strange database/client combinations can lead to this case
2031 expectedName
= linkedItem
->Name1
;
2033 expectedName
= il
->Name
[dbIndex
];
2036 expectedName
+= " ";
2037 expectedName
+= suffix
[i
];
2039 if (expectedName
== buffer
)
2047 DEBUG_LOG("ChatHandler::isValidChatMessage linked item name wasn't found in any localization");
2052 else if (linkedAchievement
)
2054 bool foundName
= false;
2055 for (uint8 i
= 0; i
< MAX_LOCALE
; ++i
)
2057 if (*linkedAchievement
->name
[i
] && strcmp(linkedAchievement
->name
[i
], buffer
) == 0)
2066 // that place should never be reached - if nothing linked has been set in |H
2067 // it will return false before
2074 // no further payload
2077 DEBUG_LOG("ChatHandler::isValidChatMessage got invalid command |%c", commandChar
);
2082 // check if every opened sequence was also closed properly
2083 if (validSequence
!= validSequenceIterator
)
2084 DEBUG_LOG("ChatHandler::isValidChatMessage EOF in active sequence");
2086 return validSequence
== validSequenceIterator
;
2089 // Note: target_guid used only in CHAT_MSG_WHISPER_INFORM mode (in this case channelName ignored)
2090 void ChatHandler::FillMessageData(WorldPacket
* data
, WorldSession
* session
, uint8 type
, uint32 language
, const char* channelName
, ObjectGuid targetGuid
, const char* message
, Unit
* speaker
, const char* addonPrefix
/*= NULL*/)
2092 uint32 messageLength
= (message
? strlen(message
) : 0) + 1;
2094 data
->Initialize(SMSG_MESSAGECHAT
, 100); // guess size
2095 *data
<< uint8(type
);
2096 if ((type
!= CHAT_MSG_CHANNEL
&& type
!= CHAT_MSG_WHISPER
) || language
== LANG_ADDON
)
2097 *data
<< uint32(language
);
2099 *data
<< uint32(LANG_UNIVERSAL
);
2104 case CHAT_MSG_PARTY
:
2105 case CHAT_MSG_PARTY_LEADER
:
2107 case CHAT_MSG_GUILD
:
2108 case CHAT_MSG_OFFICER
:
2110 case CHAT_MSG_WHISPER
:
2111 case CHAT_MSG_CHANNEL
:
2112 case CHAT_MSG_RAID_LEADER
:
2113 case CHAT_MSG_RAID_WARNING
:
2114 case CHAT_MSG_BG_SYSTEM_NEUTRAL
:
2115 case CHAT_MSG_BG_SYSTEM_ALLIANCE
:
2116 case CHAT_MSG_BG_SYSTEM_HORDE
:
2117 case CHAT_MSG_BATTLEGROUND
:
2118 case CHAT_MSG_BATTLEGROUND_LEADER
:
2119 targetGuid
= session
? session
->GetPlayer()->GetObjectGuid() : ObjectGuid();
2121 case CHAT_MSG_MONSTER_SAY
:
2122 case CHAT_MSG_MONSTER_PARTY
:
2123 case CHAT_MSG_MONSTER_YELL
:
2124 case CHAT_MSG_MONSTER_WHISPER
:
2125 case CHAT_MSG_MONSTER_EMOTE
:
2126 case CHAT_MSG_RAID_BOSS_WHISPER
:
2127 case CHAT_MSG_RAID_BOSS_EMOTE
:
2128 case CHAT_MSG_BATTLENET
:
2130 *data
<< ObjectGuid(speaker
->GetObjectGuid());
2131 *data
<< uint32(0); // 2.1.0
2132 *data
<< uint32(strlen(speaker
->GetName()) + 1);
2133 *data
<< speaker
->GetName();
2134 ObjectGuid listener_guid
;
2135 *data
<< listener_guid
;
2136 if (listener_guid
&& !listener_guid
.IsPlayer())
2138 *data
<< uint32(1); // string listener_name_length
2139 *data
<< uint8(0); // string listener_name
2141 *data
<< uint32(messageLength
);
2145 if (type
== CHAT_MSG_RAID_BOSS_WHISPER
|| type
== CHAT_MSG_RAID_BOSS_EMOTE
)
2147 *data
<< float(0.0f
); // Added in 4.2.0, unk
2148 *data
<< uint8(0); // Added in 4.2.0, unk
2153 if (type
!= CHAT_MSG_WHISPER_INFORM
&& type
!= CHAT_MSG_IGNORED
&& type
!= CHAT_MSG_DND
&& type
!= CHAT_MSG_AFK
)
2154 targetGuid
.Clear(); // only for CHAT_MSG_WHISPER_INFORM used original value target_guid
2158 *data
<< ObjectGuid(targetGuid
); // there 0 for BG messages
2159 *data
<< uint32(0); // can be chat msg group or something
2161 if (type
== CHAT_MSG_CHANNEL
)
2163 MANGOS_ASSERT(channelName
);
2164 *data
<< channelName
;
2165 *data
<< ObjectGuid(targetGuid
);
2167 else if (type
== CHAT_MSG_ADDON
)
2169 MANGOS_ASSERT(addonPrefix
);
2170 *data
<< addonPrefix
;
2173 *data
<< ObjectGuid(targetGuid
);
2175 *data
<< uint32(messageLength
);
2177 if (session
!= 0 && type
!= CHAT_MSG_WHISPER_INFORM
&& type
!= CHAT_MSG_DND
&& type
!= CHAT_MSG_AFK
)
2178 *data
<< uint8(session
->GetPlayer()->GetChatTag());
2183 Player
* ChatHandler::getSelectedPlayer()
2188 ObjectGuid guid
= m_session
->GetPlayer()->GetSelectionGuid();
2191 return m_session
->GetPlayer();
2193 return sObjectMgr
.GetPlayer(guid
);
2196 Unit
* ChatHandler::getSelectedUnit()
2201 ObjectGuid guid
= m_session
->GetPlayer()->GetSelectionGuid();
2204 return m_session
->GetPlayer();
2206 // can be selected player at another map
2207 return ObjectAccessor::GetUnit(*m_session
->GetPlayer(), guid
);
2210 Creature
* ChatHandler::getSelectedCreature()
2215 return m_session
->GetPlayer()->GetMap()->GetAnyTypeCreature(m_session
->GetPlayer()->GetSelectionGuid());
2219 * Function skip all whitespaces in args string
2221 * @param args variable pointer to non parsed args string, updated at function call to new position (with skipped white spaces)
2222 * allowed NULL string pointer stored in *args
2224 void ChatHandler::SkipWhiteSpaces(char** args
)
2229 while (isWhiteSpace(**args
))
2234 * Function extract to val arg signed integer value or fail
2236 * @param args variable pointer to non parsed args string, updated at function call to new position (with skipped white spaces)
2237 * @param val return extracted value if function success, in fail case original value unmodified
2238 * @return true if value extraction successful
2240 bool ChatHandler::ExtractInt32(char** args
, int32
& val
)
2242 if (!*args
|| !** args
)
2247 long valRaw
= strtol(*args
, &tail
, 10);
2249 if (tail
!= *args
&& isWhiteSpace(*tail
))
2251 else if (tail
&& *tail
) // some not whitespace symbol
2252 return false; // args not modified and can be re-parsed
2254 if (valRaw
< std::numeric_limits
<int32
>::min() || valRaw
> std::numeric_limits
<int32
>::max())
2257 // value successfully extracted
2258 val
= int32(valRaw
);
2264 * Function extract to val arg optional signed integer value or use default value. Fail if extracted not signed integer.
2266 * @param args variable pointer to non parsed args string, updated at function call to new position (with skipped white spaces)
2267 * @param val return extracted value if function success, in fail case original value unmodified
2268 * @param defVal default value used if no data for extraction in args
2269 * @return true if value extraction successful
2271 bool ChatHandler::ExtractOptInt32(char** args
, int32
& val
, int32 defVal
)
2273 if (!*args
|| !** args
)
2279 return ExtractInt32(args
, val
);
2283 * Function extract to val arg unsigned integer value or fail
2285 * @param args variable pointer to non parsed args string, updated at function call to new position (with skipped white spaces)
2286 * @param val return extracted value if function success, in fail case original value unmodified
2287 * @param base set used base for extracted value format (10 for decimal, 16 for hex, etc), 0 let auto select by system internal function
2288 * @return true if value extraction successful
2290 bool ChatHandler::ExtractUInt32Base(char** args
, uint32
& val
, uint32 base
)
2292 if (!*args
|| !** args
)
2297 unsigned long valRaw
= strtoul(*args
, &tail
, base
);
2299 if (tail
!= *args
&& isWhiteSpace(*tail
))
2301 else if (tail
&& *tail
) // some not whitespace symbol
2302 return false; // args not modified and can be re-parsed
2304 if (valRaw
> std::numeric_limits
<uint32
>::max())
2307 // value successfully extracted
2308 val
= uint32(valRaw
);
2311 SkipWhiteSpaces(args
);
2316 * Function extract to val arg unsigned long value or fail
2318 * @param args variable pointer to non parsed args string, updated at function call to new position (with skipped white spaces)
2319 * @param val return extracted value if function success, in fail case original value unmodified
2320 * @return true if value extraction successful
2322 bool ChatHandler::ExtractUInt64(char** args
, uint64
& val
)
2324 if (!*args
|| !** args
)
2329 unsigned long valRaw
= strtoul(*args
, &tail
, 10);
2331 if (tail
!= *args
&& isWhiteSpace(*tail
))
2333 else if (tail
&& *tail
) // some not whitespace symbol
2334 return false; // args not modified and can be re-parsed
2336 if (valRaw
> std::numeric_limits
<uint64
>::max())
2339 // value successfully extracted
2340 val
= uint64(valRaw
);
2343 SkipWhiteSpaces(args
);
2348 * Function extract to val arg signed long value or fail
2350 * @param args variable pointer to non parsed args string, updated at function call to new position (with skipped white spaces)
2351 * @param val return extracted value if function success, in fail case original value unmodified
2352 * @return true if value extraction successful
2354 bool ChatHandler::ExtractInt64(char** args
, int64
& val
)
2356 if (!*args
|| !** args
)
2361 long valRaw
= strtol(*args
, &tail
, 10);
2363 if (tail
!= *args
&& isWhiteSpace(*tail
))
2365 else if (tail
&& *tail
) // some not whitespace symbol
2366 return false; // args not modified and can be re-parsed
2368 if (valRaw
< std::numeric_limits
<int64
>::min() || valRaw
> std::numeric_limits
<int64
>::max())
2371 // value successfully extracted
2372 val
= int64(valRaw
);
2378 * Function extract to val arg optional unsigned integer value or use default value. Fail if extracted not unsigned integer.
2380 * @param args variable pointer to non parsed args string, updated at function call to new position (with skipped white spaces)
2381 * @param val return extracted value if function success, in fail case original value unmodified
2382 * @param defVal default value used if no data for extraction in args
2383 * @return true if value extraction successful
2385 bool ChatHandler::ExtractOptUInt32(char** args
, uint32
& val
, uint32 defVal
)
2387 if (!*args
|| !** args
)
2393 return ExtractUInt32(args
, val
);
2397 * Function extract to val arg float value or fail
2399 * @param args variable pointer to non parsed args string, updated at function call to new position (with skipped white spaces)
2400 * @param val return extracted value if function success, in fail case original value unmodified
2401 * @return true if value extraction successful
2403 bool ChatHandler::ExtractFloat(char** args
, float& val
)
2405 if (!*args
|| !** args
)
2410 double valRaw
= strtod(*args
, &tail
);
2412 if (tail
!= *args
&& isWhiteSpace(*tail
))
2414 else if (tail
&& *tail
) // some not whitespace symbol
2415 return false; // args not modified and can be re-parsed
2417 // value successfully extracted
2418 val
= float(valRaw
);
2421 SkipWhiteSpaces(args
);
2426 * Function extract to val arg optional float value or use default value. Fail if extracted not float.
2428 * @param args variable pointer to non parsed args string, updated at function call to new position (with skipped white spaces)
2429 * @param val return extracted value if function success, in fail case original value unmodified
2430 * @param defVal default value used if no data for extraction in args
2431 * @return true if value extraction successful
2433 bool ChatHandler::ExtractOptFloat(char** args
, float& val
, float defVal
)
2435 if (!*args
|| !** args
)
2441 return ExtractFloat(args
, val
);
2445 * Function extract name-like string (from non-numeric or special symbol until whitespace)
2447 * @param args variable pointer to non parsed args string, updated at function call to new position (with skipped white spaces)
2448 * @param lit optional explicit literal requirement. function fail if literal is not starting substring of lit.
2449 * Note: function in same way fail if no any literal or literal not fit in this case. Need additional check for select specific fail case
2450 * @return name/number-like string without whitespaces, or NULL if args empty or not appropriate content.
2452 char* ChatHandler::ExtractLiteralArg(char** args
, char const* lit
/*= NULL*/)
2454 if (!*args
|| !** args
)
2459 // reject quoted string or link (|-started text)
2462 // reject quoted string
2463 case '[': case '\'': case '"':
2465 // reject link (|-started text)
2467 // client replace all | by || in raw text
2470 ++head
; // skip one |
2477 int l
= strlen(lit
);
2480 while (head
[largs
] && !isWhiteSpace(head
[largs
]))
2486 int diff
= strncmp(head
, lit
, l
);
2491 if (head
[l
] && !isWhiteSpace(head
[l
]))
2507 SkipWhiteSpaces(args
);
2511 char* name
= strtok(head
, " ");
2513 char* tail
= strtok(NULL
, "");
2515 *args
= tail
? tail
: (char*)""; // *args don't must be NULL
2517 SkipWhiteSpaces(args
);
2523 * Function extract quote-like string (any characters guarded by some special character, in our cases ['")
2525 * @param args variable pointer to non parsed args string, updated at function call to new position (with skipped white spaces)
2526 * @param asis control save quote string wrappers
2527 * @return quote-like string, or NULL if args empty or not appropriate content.
2529 char* ChatHandler::ExtractQuotedArg(char** args
, bool asis
/*= false*/)
2531 if (!*args
|| !** args
)
2534 if (**args
!= '\'' &&** args
!= '"' &&** args
!= '[')
2537 char guard
= (*args
)[0];
2542 char* tail
= (*args
) + 1; // start scan after first quote symbol
2543 char* head
= asis
? *args
: tail
; // start arg
2545 while (*tail
&& *tail
!= guard
)
2548 if (!*tail
|| (tail
[1] && !isWhiteSpace(tail
[1]))) // fail
2551 if (!tail
[1]) // quote is last char in string
2556 else // quote isn't last char
2566 SkipWhiteSpaces(args
);
2572 * Function extract quote-like string or literal if quote not detected
2574 * @param args variable pointer to non parsed args string, updated at function call to new position (with skipped white spaces)
2575 * @param asis control save quote string wrappers
2576 * @return quote/literal string, or NULL if args empty or not appropriate content.
2578 char* ChatHandler::ExtractQuotedOrLiteralArg(char** args
, bool asis
/*= false*/)
2580 char* arg
= ExtractQuotedArg(args
, asis
);
2582 arg
= ExtractLiteralArg(args
);
2587 * Function extract on/off literals as boolean values
2589 * @param args variable pointer to non parsed args string, updated at function call to new position (with skipped white spaces)
2590 * @param val return extracted value if function success, in fail case original value unmodified
2591 * @return true at success
2593 bool ChatHandler::ExtractOnOff(char** args
, bool& value
)
2595 char* arg
= ExtractLiteralArg(args
);
2599 if (strncmp(arg
, "on", 3) == 0)
2601 else if (strncmp(arg
, "off", 4) == 0)
2610 * Function extract shift-link-like string (any characters guarded by | and |h|r with some additional internal structure check)
2612 * @param args variable pointer to non parsed args string, updated at function call to new position (with skipped white spaces)
2614 * @param linkTypes optional NULL-terminated array of link types, shift-link must fit one from link type from array if provided or extraction fail
2616 * @param found_idx if not NULL then at return index in linkTypes that fit shift-link type, if extraction fail then non modified
2618 * @param keyPair if not NULL then pointer to 2-elements array for return start and end pointer for found key
2619 * if extraction fail then non modified
2621 * @param somethingPair then pointer to 2-elements array for return start and end pointer if found.
2622 * if not NULL then shift-link must have data field, if extraction fail then non modified
2624 * @return shift-link-like string, or NULL if args empty or not appropriate content.
2626 char* ChatHandler::ExtractLinkArg(char** args
, char const* const* linkTypes
/*= NULL*/, int* foundIdx
/*= NULL*/, char** keyPair
/*= NULL*/, char** somethingPair
/*= NULL*/)
2628 if (!*args
|| !** args
)
2631 // skip if not linked started or encoded single | (doubled by client)
2632 if ((*args
)[0] != '|' || (*args
)[1] == '|')
2635 // |color|Hlinktype:key:data...|h[name]|h|r
2639 // [name] Shift-click form |color|linkType:key|h[name]|h|r
2641 // [name] Shift-click form |color|linkType:key:something1:...:somethingN|h[name]|h|r
2643 // [name] Shift-click form |linkType:key|h[name]|h|r
2645 // |color|Hlinktype:key:data...|h[name]|h|r
2647 char* tail
= (*args
) + 1; // skip |
2649 if (*tail
!= 'H') // skip color part, some links can not have color part
2651 while (*tail
&& *tail
!= '|')
2657 // |Hlinktype:key:data...|h[name]|h|r
2662 // Hlinktype:key:data...|h[name]|h|r
2667 int linktype_idx
= 0;
2669 if (linkTypes
) // check link type if provided
2671 // check linktypes (its include H in name)
2672 for (; linkTypes
[linktype_idx
]; ++linktype_idx
)
2674 // exactly string with follow : or |
2675 int l
= strlen(linkTypes
[linktype_idx
]);
2676 if (strncmp(tail
, linkTypes
[linktype_idx
], l
) == 0 &&
2677 (tail
[l
] == ':' || tail
[l
] == '|'))
2682 if (!linkTypes
[linktype_idx
]) // NULL terminator in last element
2685 tail
+= strlen(linkTypes
[linktype_idx
]); // skip linktype string
2687 // :key:data...|h[name]|h|r
2694 while (*tail
&& *tail
!= ':') // skip linktype string
2703 // key:data...|h[name]|h|r
2704 char* keyStart
= tail
; // remember key start for return
2705 char* keyEnd
= tail
; // key end for truncate, will updated
2707 while (*tail
&& *tail
!= '|' && *tail
!= ':')
2713 keyEnd
= tail
; // remember key end for truncate
2715 // |h[name]|h|r or :something...|h[name]|h|r
2717 char* somethingStart
= tail
+ 1;
2718 char* somethingEnd
= tail
+ 1; // will updated later if need
2720 if (*tail
== ':' && somethingPair
) // optional data extraction
2722 // :something...|h[name]|h|r
2727 // something|h[name]|h|r or something:something2...|h[name]|h|r
2729 while (*tail
&& *tail
!= '|' && *tail
!= ':')
2735 somethingEnd
= tail
; // remember data end for truncate
2738 // |h[name]|h|r or :something2...|h[name]|h|r
2740 while (*tail
&& (*tail
!= '|' || *(tail
+ 1) != 'h')) // skip ... part if exist
2748 tail
+= 2; // skip |h
2751 if (!*tail
|| *tail
!= '[')
2754 while (*tail
&& (*tail
!= ']' || *(tail
+ 1) != '|')) // skip name part
2757 tail
+= 2; // skip ]|
2760 if (!*tail
|| *tail
!= 'h' || *(tail
+ 1) != '|')
2763 tail
+= 2; // skip h|
2766 if (!*tail
|| *tail
!= 'r' || (*(tail
+ 1) && !isWhiteSpace(*(tail
+ 1))))
2773 if (*tail
) // truncate all link string
2777 *foundIdx
= linktype_idx
;
2781 keyPair
[0] = keyStart
;
2782 keyPair
[1] = keyEnd
;
2787 somethingPair
[0] = somethingStart
;
2788 somethingPair
[1] = somethingEnd
;
2793 SkipWhiteSpaces(args
);
2799 * Function extract name/number/quote/shift-link-like string
2801 * @param args variable pointer to non parsed args string, updated at function call to new position (with skipped white spaces)
2802 * @param asis control save quote string wrappers
2803 * @return extracted arg string, or NULL if args empty or not appropriate content.
2805 char* ChatHandler::ExtractArg(char** args
, bool asis
/*= false*/)
2807 if (!*args
|| !** args
)
2810 char* arg
= ExtractQuotedOrLiteralArg(args
, asis
);
2812 arg
= ExtractLinkArg(args
);
2818 * Function extract name/quote/number/shift-link-like string, and return it if args have more non-whitespace data
2820 * @param args variable pointer to non parsed args string, updated at function call to new position (with skipped white spaces)
2821 * if args have only single arg then args still pointing to this arg (unmodified pointer)
2822 * @return extracted string, or NULL if args empty or not appropriate content or have single arg totally.
2824 char* ChatHandler::ExtractOptNotLastArg(char** args
)
2826 char* arg
= ExtractArg(args
, true);
2829 if (*args
&&** args
)
2832 // optional name not found
2833 *args
= arg
? arg
: (char*)""; // *args don't must be NULL
2839 * Function extract data from shift-link "|color|LINKTYPE:RETURN:SOMETHING1|h[name]|h|r if linkType == LINKTYPE
2840 * It also extract literal/quote if not shift-link in args
2842 * @param args variable pointer to non parsed args string, updated at function call to new position (with skipped white spaces)
2843 * if args have sift link with linkType != LINKTYPE then args still pointing to this arg (unmodified pointer)
2845 * @param linkType shift-link must fit by link type to this arg value or extraction fail
2847 * @param something1 if not NULL then shift-link must have data field and it returned into this arg
2848 * if extraction fail then non modified
2850 * @return extracted key, or NULL if args empty or not appropriate content or not fit to linkType.
2852 char* ChatHandler::ExtractKeyFromLink(char** text
, char const* linkType
, char** something1
/*= NULL*/)
2854 char const* linkTypes
[2];
2855 linkTypes
[0] = linkType
;
2856 linkTypes
[1] = NULL
;
2860 return ExtractKeyFromLink(text
, linkTypes
, &foundIdx
, something1
);
2864 * Function extract data from shift-link "|color|LINKTYPE:RETURN:SOMETHING1|h[name]|h|r if LINKTYPE in linkTypes array
2865 * It also extract literal/quote if not shift-link in args
2867 * @param args variable pointer to non parsed args string, updated at function call to new position (with skipped white spaces)
2868 * if args have sift link with linkType != LINKTYPE then args still pointing to this arg (unmodified pointer)
2870 * @param linkTypes NULL-terminated array of link types, shift-link must fit one from link type from array or extraction fail
2872 * @param found_idx if not NULL then at return index in linkTypes that fit shift-link type, for non-link case return -1
2873 * if extraction fail then non modified
2875 * @param something1 if not NULL then shift-link must have data field and it returned into this arg
2876 * if extraction fail then non modified
2878 * @return extracted key, or NULL if args empty or not appropriate content or not fit to linkType.
2880 char* ChatHandler::ExtractKeyFromLink(char** text
, char const* const* linkTypes
, int* found_idx
, char** something1
/*= NULL*/)
2883 if (!*text
|| !** text
)
2886 // return non link case
2887 char* arg
= ExtractQuotedOrLiteralArg(text
);
2891 *found_idx
= -1; // special index case
2897 char* somethingPair
[2];
2899 arg
= ExtractLinkArg(text
, linkTypes
, found_idx
, keyPair
, something1
? somethingPair
: NULL
);
2903 *keyPair
[1] = '\0'; // truncate key string
2907 *somethingPair
[1] = '\0'; // truncate data string
2908 *something1
= somethingPair
[0];
2915 * Function extract uint32 key from shift-link "|color|LINKTYPE:RETURN|h[name]|h|r if linkType == LINKTYPE
2916 * It also extract direct number if not shift-link in args
2918 * @param args variable pointer to non parsed args string, updated at function call to new position (with skipped white spaces)
2919 * if args have sift link with linkType != LINKTYPE then args still pointing to this arg (unmodified pointer)
2921 * @param linkType shift-link must fit by link type to this arg value or extraction fail
2923 * @param value store result value at success return, not modified at fail
2925 * @return true if extraction succesful
2927 bool ChatHandler::ExtractUint32KeyFromLink(char** text
, char const* linkType
, uint32
& value
)
2929 char* arg
= ExtractKeyFromLink(text
, linkType
);
2933 return ExtractUInt32(&arg
, value
);
2936 GameObject
* ChatHandler::GetGameObjectWithGuid(uint32 lowguid
, uint32 entry
)
2941 Player
* pl
= m_session
->GetPlayer();
2943 return pl
->GetMap()->GetGameObject(ObjectGuid(HIGHGUID_GAMEOBJECT
, entry
, lowguid
));
2948 SPELL_LINK_RAW
= -1, // non-link case
2949 SPELL_LINK_SPELL
= 0,
2950 SPELL_LINK_TALENT
= 1,
2951 SPELL_LINK_ENCHANT
= 2,
2952 SPELL_LINK_TRADE
= 3,
2953 SPELL_LINK_GLYPH
= 4,
2956 static char const* const spellKeys
[] =
2958 "Hspell", // normal spell
2959 "Htalent", // talent spell
2960 "Henchant", // enchanting recipe spell
2961 "Htrade", // profession/skill spell
2966 uint32
ChatHandler::ExtractSpellIdFromLink(char** text
)
2968 // number or [name] Shift-click form |color|Henchant:recipe_spell_id|h[prof_name: recipe_name]|h|r
2969 // number or [name] Shift-click form |color|Hglyph:glyph_slot_id:glyph_prop_id|h[%s]|h|r
2970 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
2971 // number or [name] Shift-click form |color|Htalent:talent_id,rank|h[name]|h|r
2972 // number or [name] Shift-click form |color|Htrade:spell_id,skill_id,max_value,cur_value|h[name]|h|r
2974 char* param1_str
= NULL
;
2975 char* idS
= ExtractKeyFromLink(text
, spellKeys
, &type
, ¶m1_str
);
2980 if (!ExtractUInt32(&idS
, id
))
2985 case SPELL_LINK_RAW
:
2986 case SPELL_LINK_SPELL
:
2987 case SPELL_LINK_ENCHANT
:
2988 case SPELL_LINK_TRADE
:
2990 case SPELL_LINK_TALENT
:
2993 TalentEntry
const* talentEntry
= sTalentStore
.LookupEntry(id
);
2998 if (!ExtractInt32(¶m1_str
, rank
))
3001 if (rank
< 0) // unlearned talent have in shift-link field -1 as rank
3004 return rank
< MAX_TALENT_RANK
? talentEntry
->RankID
[rank
] : 0;
3006 case SPELL_LINK_GLYPH
:
3008 uint32 glyph_prop_id
;
3010 if (!ExtractUInt32(¶m1_str
, glyph_prop_id
))
3013 GlyphPropertiesEntry
const* glyphPropEntry
= sGlyphPropertiesStore
.LookupEntry(glyph_prop_id
);
3014 return glyphPropEntry
? glyphPropEntry
->SpellId
: 0;
3022 GameTele
const* ChatHandler::ExtractGameTeleFromLink(char** text
)
3024 // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r
3025 char* cId
= ExtractKeyFromLink(text
, "Htele");
3029 // id case (explicit or from shift link)
3031 if (ExtractUInt32(&cId
, id
))
3032 return sObjectMgr
.GetGameTele(id
);
3034 return sObjectMgr
.GetGameTele(cId
);
3039 GUID_LINK_RAW
= -1, // non-link case
3040 GUID_LINK_PLAYER
= 0,
3041 GUID_LINK_CREATURE
= 1,
3042 GUID_LINK_GAMEOBJECT
= 2,
3045 static char const* const guidKeys
[] =
3053 ObjectGuid
ChatHandler::ExtractGuidFromLink(char** text
)
3057 // |color|Hcreature:creature_guid|h[name]|h|r
3058 // |color|Hgameobject:go_guid|h[name]|h|r
3059 // |color|Hplayer:name|h[name]|h|r
3060 char* idS
= ExtractKeyFromLink(text
, guidKeys
, &type
);
3062 return ObjectGuid();
3067 case GUID_LINK_PLAYER
:
3069 std::string name
= idS
;
3070 if (!normalizePlayerName(name
))
3071 return ObjectGuid();
3073 if (Player
* player
= sObjectMgr
.GetPlayer(name
.c_str()))
3074 return player
->GetObjectGuid();
3076 return sObjectMgr
.GetPlayerGuidByName(name
);
3078 case GUID_LINK_CREATURE
:
3081 if (!ExtractUInt32(&idS
, lowguid
))
3082 return ObjectGuid();
3084 if (CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
))
3085 return data
->GetObjectGuid(lowguid
);
3087 return ObjectGuid();
3089 case GUID_LINK_GAMEOBJECT
:
3092 if (!ExtractUInt32(&idS
, lowguid
))
3093 return ObjectGuid();
3095 if (GameObjectData
const* data
= sObjectMgr
.GetGOData(lowguid
))
3096 return ObjectGuid(HIGHGUID_GAMEOBJECT
, data
->id
, lowguid
);
3098 return ObjectGuid();
3103 return ObjectGuid();
3106 enum LocationLinkType
3108 LOCATION_LINK_RAW
= -1, // non-link case
3109 LOCATION_LINK_PLAYER
= 0,
3110 LOCATION_LINK_TELE
= 1,
3111 LOCATION_LINK_TAXINODE
= 2,
3112 LOCATION_LINK_CREATURE
= 3,
3113 LOCATION_LINK_GAMEOBJECT
= 4,
3114 LOCATION_LINK_CREATURE_ENTRY
= 5,
3115 LOCATION_LINK_GAMEOBJECT_ENTRY
= 6,
3116 LOCATION_LINK_AREATRIGGER
= 7,
3117 LOCATION_LINK_AREATRIGGER_TARGET
= 8,
3120 static char const* const locationKeys
[] =
3128 "Hgameobject_entry",
3130 "Hareatrigger_target",
3134 bool ChatHandler::ExtractLocationFromLink(char** text
, uint32
& mapid
, float& x
, float& y
, float& z
)
3138 // |color|Hplayer:name|h[name]|h|r
3139 // |color|Htele:id|h[name]|h|r
3140 // |color|Htaxinode:id|h[name]|h|r
3141 // |color|Hcreature:creature_guid|h[name]|h|r
3142 // |color|Hgameobject:go_guid|h[name]|h|r
3143 // |color|Hcreature_entry:creature_id|h[name]|h|r
3144 // |color|Hgameobject_entry:go_id|h[name]|h|r
3145 // |color|Hareatrigger:id|h[name]|h|r
3146 // |color|Hareatrigger_target:id|h[name]|h|r
3147 char* idS
= ExtractKeyFromLink(text
, locationKeys
, &type
);
3153 case LOCATION_LINK_RAW
:
3154 case LOCATION_LINK_PLAYER
:
3156 std::string name
= idS
;
3157 if (!normalizePlayerName(name
))
3160 if (Player
* player
= sObjectMgr
.GetPlayer(name
.c_str()))
3162 mapid
= player
->GetMapId();
3163 x
= player
->GetPositionX();
3164 y
= player
->GetPositionY();
3165 z
= player
->GetPositionZ();
3169 if (ObjectGuid guid
= sObjectMgr
.GetPlayerGuidByName(name
))
3171 // to point where player stay (if loaded)
3174 return Player::LoadPositionFromDB(guid
, mapid
, x
, y
, z
, o
, in_flight
);
3179 case LOCATION_LINK_TELE
:
3182 if (!ExtractUInt32(&idS
, id
))
3185 GameTele
const* tele
= sObjectMgr
.GetGameTele(id
);
3188 mapid
= tele
->mapId
;
3189 x
= tele
->position_x
;
3190 y
= tele
->position_y
;
3191 z
= tele
->position_z
;
3194 case LOCATION_LINK_TAXINODE
:
3197 if (!ExtractUInt32(&idS
, id
))
3200 TaxiNodesEntry
const* node
= sTaxiNodesStore
.LookupEntry(id
);
3203 mapid
= node
->map_id
;
3209 case LOCATION_LINK_CREATURE
:
3212 if (!ExtractUInt32(&idS
, lowguid
))
3215 if (CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
))
3217 mapid
= data
->mapid
;
3226 case LOCATION_LINK_GAMEOBJECT
:
3229 if (!ExtractUInt32(&idS
, lowguid
))
3232 if (GameObjectData
const* data
= sObjectMgr
.GetGOData(lowguid
))
3234 mapid
= data
->mapid
;
3243 case LOCATION_LINK_CREATURE_ENTRY
:
3246 if (!ExtractUInt32(&idS
, id
))
3249 if (ObjectMgr::GetCreatureTemplate(id
))
3251 FindCreatureData
worker(id
, m_session
? m_session
->GetPlayer() : NULL
);
3253 sObjectMgr
.DoCreatureData(worker
);
3255 if (CreatureDataPair
const* dataPair
= worker
.GetResult())
3257 mapid
= dataPair
->second
.mapid
;
3258 x
= dataPair
->second
.posX
;
3259 y
= dataPair
->second
.posY
;
3260 z
= dataPair
->second
.posZ
;
3269 case LOCATION_LINK_GAMEOBJECT_ENTRY
:
3272 if (!ExtractUInt32(&idS
, id
))
3275 if (ObjectMgr::GetGameObjectInfo(id
))
3277 FindGOData
worker(id
, m_session
? m_session
->GetPlayer() : NULL
);
3279 sObjectMgr
.DoGOData(worker
);
3281 if (GameObjectDataPair
const* dataPair
= worker
.GetResult())
3283 mapid
= dataPair
->second
.mapid
;
3284 x
= dataPair
->second
.posX
;
3285 y
= dataPair
->second
.posY
;
3286 z
= dataPair
->second
.posZ
;
3295 case LOCATION_LINK_AREATRIGGER
:
3298 if (!ExtractUInt32(&idS
, id
))
3301 AreaTriggerEntry
const* atEntry
= sAreaTriggerStore
.LookupEntry(id
);
3304 PSendSysMessage(LANG_COMMAND_GOAREATRNOTFOUND
, id
);
3305 SetSentErrorMessage(true);
3309 mapid
= atEntry
->mapid
;
3315 case LOCATION_LINK_AREATRIGGER_TARGET
:
3318 if (!ExtractUInt32(&idS
, id
))
3321 if (!sAreaTriggerStore
.LookupEntry(id
))
3323 PSendSysMessage(LANG_COMMAND_GOAREATRNOTFOUND
, id
);
3324 SetSentErrorMessage(true);
3328 AreaTrigger
const* at
= sObjectMgr
.GetAreaTrigger(id
);
3331 PSendSysMessage(LANG_AREATRIGER_NOT_HAS_TARGET
, id
);
3332 SetSentErrorMessage(true);
3336 mapid
= at
->target_mapId
;
3348 std::string
ChatHandler::ExtractPlayerNameFromLink(char** text
)
3350 // |color|Hplayer:name|h[name]|h|r
3351 char* name_str
= ExtractKeyFromLink(text
, "Hplayer");
3355 std::string name
= name_str
;
3356 if (!normalizePlayerName(name
))
3363 * Function extract at least one from request player data (pointer/guid/name) from args name/shift-link or selected player if no args
3365 * @param args variable pointer to non parsed args string, updated at function call to new position (with skipped white spaces)
3367 * @param player optional arg One from 3 optional args must be provided at least (or more).
3368 * @param player_guid optional arg For function success only one from provided args need get result
3369 * @param player_name optional arg But if early arg get value then all later args will have its (if requested)
3370 * if player_guid requested and not found then name also will not found
3371 * So at success can be returned 2 cases: (player/guid/name) or (guid/name)
3373 * @return true if extraction successful
3375 bool ChatHandler::ExtractPlayerTarget(char** args
, Player
** player
/*= NULL*/, ObjectGuid
* player_guid
/*= NULL*/, std::string
* player_name
/*= NULL*/)
3377 if (*args
&&** args
)
3379 std::string name
= ExtractPlayerNameFromLink(args
);
3382 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3383 SetSentErrorMessage(true);
3387 Player
* pl
= sObjectMgr
.GetPlayer(name
.c_str());
3389 // if allowed player pointer
3393 // if need guid value from DB (in name case for check player existence)
3394 ObjectGuid guid
= !pl
&& (player_guid
|| player_name
) ? sObjectMgr
.GetPlayerGuidByName(name
) : ObjectGuid();
3396 // if allowed player guid (if no then only online players allowed)
3398 *player_guid
= pl
? pl
->GetObjectGuid() : guid
;
3401 *player_name
= pl
|| guid
? name
: "";
3405 Player
* pl
= getSelectedPlayer();
3406 // if allowed player pointer
3409 // if allowed player guid (if no then only online players allowed)
3411 *player_guid
= pl
? pl
->GetObjectGuid() : ObjectGuid();
3414 *player_name
= pl
? pl
->GetName() : "";
3417 // some from req. data must be provided (note: name is empty if player not exist)
3418 if ((!player
|| !*player
) && (!player_guid
|| !*player_guid
) && (!player_name
|| player_name
->empty()))
3420 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3421 SetSentErrorMessage(true);
3428 uint32
ChatHandler::ExtractAccountId(char** args
, std::string
* accountName
/*= NULL*/, Player
** targetIfNullArg
/*= NULL*/)
3430 uint32 account_id
= 0;
3432 ///- Get the account name from the command line
3433 char* account_str
= ExtractLiteralArg(args
);
3437 if (!targetIfNullArg
)
3440 /// only target player different from self allowed (if targetPlayer!=NULL then not console)
3441 Player
* targetPlayer
= getSelectedPlayer();
3445 account_id
= targetPlayer
->GetSession()->GetAccountId();
3448 sAccountMgr
.GetName(account_id
, *accountName
);
3450 if (targetIfNullArg
)
3451 *targetIfNullArg
= targetPlayer
;
3456 std::string account_name
;
3458 if (ExtractUInt32(&account_str
, account_id
))
3460 if (!sAccountMgr
.GetName(account_id
, account_name
))
3462 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST
, account_str
);
3463 SetSentErrorMessage(true);
3469 account_name
= account_str
;
3470 if (!AccountMgr::normalizeString(account_name
))
3472 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST
, account_name
.c_str());
3473 SetSentErrorMessage(true);
3477 account_id
= sAccountMgr
.GetId(account_name
);
3480 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST
, account_name
.c_str());
3481 SetSentErrorMessage(true);
3487 *accountName
= account_name
;
3489 if (targetIfNullArg
)
3490 *targetIfNullArg
= NULL
;
3497 char const* literal
;
3501 static RaceMaskName
const raceMaskNames
[] =
3504 { "human", (1 << (RACE_HUMAN
- 1)) },
3505 { "orc", (1 << (RACE_ORC
- 1)) },
3506 { "dwarf", (1 << (RACE_DWARF
- 1)) },
3507 { "nightelf", (1 << (RACE_NIGHTELF
- 1))},
3508 { "undead", (1 << (RACE_UNDEAD
- 1)) },
3509 { "tauren", (1 << (RACE_TAUREN
- 1)) },
3510 { "gnome", (1 << (RACE_GNOME
- 1)) },
3511 { "troll", (1 << (RACE_TROLL
- 1)) },
3512 { "bloodelf", (1 << (RACE_BLOODELF
- 1))},
3513 { "draenei", (1 << (RACE_DRAENEI
- 1)) },
3516 { "alliance", RACEMASK_ALLIANCE
},
3517 { "horde", RACEMASK_HORDE
},
3518 { "all", RACEMASK_ALL_PLAYABLE
},
3524 bool ChatHandler::ExtractRaceMask(char** text
, uint32
& raceMask
, char const** maskName
/*=NULL*/)
3526 if (ExtractUInt32(text
, raceMask
))
3529 *maskName
= "custom mask";
3533 for (RaceMaskName
const* itr
= raceMaskNames
; itr
->literal
; ++itr
)
3535 if (ExtractLiteralArg(text
, itr
->literal
))
3537 raceMask
= itr
->raceMask
;
3540 *maskName
= itr
->literal
;
3552 std::string
ChatHandler::GetNameLink(Player
* chr
) const
3554 return playerLink(chr
->GetName());
3557 bool ChatHandler::needReportToTarget(Player
* chr
) const
3559 Player
* pl
= m_session
->GetPlayer();
3560 return pl
!= chr
&& pl
->IsVisibleGloballyFor(chr
);
3563 LocaleConstant
ChatHandler::GetSessionDbcLocale() const
3565 return m_session
->GetSessionDbcLocale();
3568 int ChatHandler::GetSessionDbLocaleIndex() const
3570 return m_session
->GetSessionDbLocaleIndex();
3573 const char* CliHandler::GetMangosString(int32 entry
) const
3575 return sObjectMgr
.GetMangosStringForDBCLocale(entry
);
3578 uint32
CliHandler::GetAccountId() const
3583 AccountTypes
CliHandler::GetAccessLevel() const
3585 return m_loginAccessLevel
;
3588 bool CliHandler::isAvailable(ChatCommand
const& cmd
) const
3590 // skip non-console commands in console case
3591 if (!cmd
.AllowConsole
)
3595 return GetAccessLevel() >= (AccountTypes
)cmd
.SecurityLevel
;
3598 void CliHandler::SendSysMessage(const char* str
)
3600 m_print(m_callbackArg
, str
);
3601 m_print(m_callbackArg
, "\r\n");
3604 std::string
CliHandler::GetNameLink() const
3606 return GetMangosString(LANG_CONSOLE_COMMAND
);
3609 bool CliHandler::needReportToTarget(Player
* /*chr*/) const
3614 LocaleConstant
CliHandler::GetSessionDbcLocale() const
3616 return sWorld
.GetDefaultDbcLocale();
3619 int CliHandler::GetSessionDbLocaleIndex() const
3621 return sObjectMgr
.GetDBCLocaleIndex();
3624 // Check/ Output if a NPC or GO (by guid) is part of a pool or game event
3625 template <typename T
>
3626 void ChatHandler::ShowNpcOrGoSpawnInformation(uint32 guid
)
3628 if (uint16 pool_id
= sPoolMgr
.IsPartOfAPool
<T
>(guid
))
3630 uint16 top_pool_id
= sPoolMgr
.IsPartOfTopPool
<Pool
>(pool_id
);
3631 if (!top_pool_id
|| top_pool_id
== pool_id
)
3632 PSendSysMessage(LANG_NPC_GO_INFO_POOL
, pool_id
);
3634 PSendSysMessage(LANG_NPC_GO_INFO_TOP_POOL
, pool_id
, top_pool_id
);
3636 if (int16 event_id
= sGameEventMgr
.GetGameEventId
<Pool
>(top_pool_id
))
3638 GameEventMgr::GameEventDataMap
const& events
= sGameEventMgr
.GetEventMap();
3639 GameEventData
const& eventData
= events
[std::abs(event_id
)];
3642 PSendSysMessage(LANG_NPC_GO_INFO_POOL_GAME_EVENT_S
, top_pool_id
, std::abs(event_id
), eventData
.description
.c_str());
3644 PSendSysMessage(LANG_NPC_GO_INFO_POOL_GAME_EVENT_D
, top_pool_id
, std::abs(event_id
), eventData
.description
.c_str());
3647 else if (int16 event_id
= sGameEventMgr
.GetGameEventId
<T
>(guid
))
3649 GameEventMgr::GameEventDataMap
const& events
= sGameEventMgr
.GetEventMap();
3650 GameEventData
const& eventData
= events
[std::abs(event_id
)];
3653 PSendSysMessage(LANG_NPC_GO_INFO_GAME_EVENT_S
, std::abs(event_id
), eventData
.description
.c_str());
3655 PSendSysMessage(LANG_NPC_GO_INFO_GAME_EVENT_D
, std::abs(event_id
), eventData
.description
.c_str());
3659 // Prepare ShortString for a NPC or GO (by guid) with pool or game event IDs
3660 template <typename T
>
3661 std::string
ChatHandler::PrepareStringNpcOrGoSpawnInformation(uint32 guid
)
3663 std::string str
= "";
3664 if (uint16 pool_id
= sPoolMgr
.IsPartOfAPool
<T
>(guid
))
3666 uint16 top_pool_id
= sPoolMgr
.IsPartOfTopPool
<T
>(guid
);
3667 if (int16 event_id
= sGameEventMgr
.GetGameEventId
<Pool
>(top_pool_id
))
3670 const char* format
= GetMangosString(LANG_NPC_GO_INFO_POOL_EVENT_STRING
);
3671 sprintf(buffer
, format
, pool_id
, event_id
);
3677 const char* format
= GetMangosString(LANG_NPC_GO_INFO_POOL_STRING
);
3678 sprintf(buffer
, format
, pool_id
);
3682 else if (int16 event_id
= sGameEventMgr
.GetGameEventId
<T
>(guid
))
3685 const char* format
= GetMangosString(LANG_NPC_GO_INFO_EVENT_STRING
);
3686 sprintf(buffer
, format
, event_id
);
3693 void ChatHandler::LogCommand(char const* fullcmd
)
3698 Player
* p
= m_session
->GetPlayer();
3699 ObjectGuid sel_guid
= p
->GetSelectionGuid();
3700 sLog
.outCommand(GetAccountId(), "Command: %s [Player: %s (Account: %u) X: %f Y: %f Z: %f Map: %u Selected: %s]",
3701 fullcmd
, p
->GetName(), GetAccountId(), p
->GetPositionX(), p
->GetPositionY(), p
->GetPositionZ(), p
->GetMapId(),
3702 sel_guid
.GetString().c_str());
3704 else // 0 account -> console
3706 sLog
.outCommand(GetAccountId(), "Command: %s [Account: %u from %s]",
3707 fullcmd
, GetAccountId(), GetAccountId() ? "RA-connection" : "Console");
3711 // Instantiate template for helper function
3712 template void ChatHandler::ShowNpcOrGoSpawnInformation
<Creature
>(uint32 guid
);
3713 template void ChatHandler::ShowNpcOrGoSpawnInformation
<GameObject
>(uint32 guid
);
3715 template std::string
ChatHandler::PrepareStringNpcOrGoSpawnInformation
<Creature
>(uint32 guid
);
3716 template std::string
ChatHandler::PrepareStringNpcOrGoSpawnInformation
<GameObject
>(uint32 guid
);