[1130] Database Query Audit is now at 90 percent with this commit.
[mangos-git.git] / src / game / Chat.cpp
blobe27d241d166d4b672231d6f4a4830ef5f4d849f1
1 /*
2 * Copyright (C) 2005,2006 MaNGOS <http://www.mangosproject.org/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "Common.h"
20 #include "Database/DatabaseEnv.h"
21 #include "WorldPacket.h"
22 #include "WorldSession.h"
23 #include "Opcodes.h"
24 #include "Log.h"
25 #include "World.h"
26 #include "ObjectMgr.h"
27 #include "Player.h"
28 #include "UpdateMask.h"
29 #include "Chat.h"
30 #include "MapManager.h"
31 #include "Policies/SingletonImp.h"
33 INSTANTIATE_SINGLETON_1( ChatHandler );
35 ChatHandler::ChatHandler()
40 ChatHandler::~ChatHandler()
45 ChatCommand * ChatHandler::getCommandTable()
48 static bool first_call = true;
50 static ChatCommand modifyCommandTable[] =
52 { "hp", 1, &ChatHandler::HandleModifyHPCommand, "", NULL },
53 { "mana", 1, &ChatHandler::HandleModifyManaCommand, "", NULL },
54 { "rage", 1, &ChatHandler::HandleModifyRageCommand, "", NULL },
55 { "energy", 1, &ChatHandler::HandleModifyEnergyCommand, "", NULL },
56 { "gold", 1, &ChatHandler::HandleModifyGoldCommand, "", NULL },
57 { "level", 1, &ChatHandler::HandleModifyLevelCommand, "", NULL },
58 { "speed", 1, &ChatHandler::HandleModifySpeedCommand, "", NULL },
59 { "swim", 1, &ChatHandler::HandleModifySwimCommand, "", NULL },
60 { "scale", 1, &ChatHandler::HandleModifyScaleCommand, "", NULL },
61 { "bit", 1, &ChatHandler::HandleModifyBitCommand, "", NULL },
62 { "bwalk", 1, &ChatHandler::HandleModifyBWalkCommand, "", NULL },
63 { "aspeed", 1, &ChatHandler::HandleModifyASpedCommand, "", NULL },
64 { "faction", 1, &ChatHandler::HandleModifyFactionCommand, "", NULL },
65 { "spell", 1, &ChatHandler::HandleModifySpellCommand, "", NULL },
66 { NULL, 0, NULL, "", NULL }
69 static ChatCommand debugCommandTable[] =
71 { "inarc", 1, &ChatHandler::HandleDebugInArcCommand, "", NULL },
72 { NULL, 0, NULL, "", NULL }
75 static ChatCommand commandTable[] =
77 { "acct", 0, &ChatHandler::HandleAcctCommand, "", NULL },
78 { "addmove", 2, &ChatHandler::HandleAddMoveCommand, "", NULL },
79 { "addspirit", 3, &ChatHandler::HandleAddSpiritCommand, "", NULL },
80 { "anim", 3, &ChatHandler::HandleAnimCommand, "", NULL },
81 { "announce", 1, &ChatHandler::HandleAnnounceCommand, "", NULL },
82 { "go", 3, &ChatHandler::HandleGoCommand, "", NULL },
83 { "goname", 1, &ChatHandler::HandleGonameCommand, "", NULL },
84 { "namego", 1, &ChatHandler::HandleNamegoCommand, "", NULL },
85 { "aura", 3, &ChatHandler::HandleAuraCommand, "", NULL },
86 { "changelevel", 2, &ChatHandler::HandleChangeLevelCommand, "", NULL },
87 { "commands", 0, &ChatHandler::HandleCommandsCommand, "", NULL },
88 { "delete", 2, &ChatHandler::HandleDeleteCommand, "", NULL },
89 { "demorph", 2, &ChatHandler::HandleDeMorphCommand, "", NULL },
90 { "die", 3, &ChatHandler::HandleDieCommand, "", NULL },
91 { "revive", 3, &ChatHandler::HandleReviveCommand, "", NULL },
92 { "dismount", 0, &ChatHandler::HandleDismountCommand, "", NULL },
93 { "displayid", 2, &ChatHandler::HandleDisplayIdCommand, "", NULL },
94 { "factionid", 2, &ChatHandler::HandleFactionIdCommand, "", NULL },
95 { "gmlist", 0, &ChatHandler::HandleGMListCommand, "", NULL },
96 { "gmoff", 1, &ChatHandler::HandleGMOffCommand, "", NULL },
97 { "gmon", 1, &ChatHandler::HandleGMOnCommand, "", NULL },
98 { "gps", 1, &ChatHandler::HandleGPSCommand, "", NULL },
99 { "guid", 2, &ChatHandler::HandleGUIDCommand, "", NULL },
100 { "help", 0, &ChatHandler::HandleHelpCommand, "", NULL },
101 { "info", 0, &ChatHandler::HandleInfoCommand, "", NULL },
102 { "npcinfo", 3, &ChatHandler::HandleNpcInfoCommand, "", NULL },
103 { "npcinfoset", 3, &ChatHandler::HandleNpcInfoSetCommand, "", NULL },
104 { "item", 2, &ChatHandler::HandleItemCommand, "", NULL },
105 { "itemrmv", 2, &ChatHandler::HandleItemRemoveCommand, "", NULL },
106 { "itemmove", 2, &ChatHandler::HandleItemMoveCommand, "", NULL },
107 { "kick", 1, &ChatHandler::HandleNYICommand, "", NULL },
108 { "learn", 3, &ChatHandler::HandleLearnCommand, "", NULL },
109 { "unlearn", 3, &ChatHandler::HandleUnLearnCommand, "", NULL },
110 { "learnsk", 3, &ChatHandler::HandleLearnSkillCommand, "", NULL },
111 { "unlearnsk", 3, &ChatHandler::HandleUnLearnSkillCommand, "", NULL },
112 { "modify", 1, NULL, "", modifyCommandTable },
113 { "debug", 1, NULL, "", debugCommandTable },
114 { "morph", 3, &ChatHandler::HandleMorphCommand, "", NULL },
115 { "name", 2, &ChatHandler::HandleNameCommand, "", NULL },
116 { "subname", 2, &ChatHandler::HandleSubNameCommand, "", NULL },
117 { "npcflag", 2, &ChatHandler::HandleNPCFlagCommand, "", NULL },
118 { "cdist", 1, &ChatHandler::HandleCreatureDistanceCommand, "", NULL },
119 { "object", 3, &ChatHandler::HandleObjectCommand, "", NULL },
120 { "gameobject", 3, &ChatHandler::HandleGameObjectCommand, "", NULL },
121 { "addgo", 3, &ChatHandler::HandleGameObjectCommand, "", NULL },
122 { "prog", 2, &ChatHandler::HandleProgCommand, "", NULL },
123 { "random", 2, &ChatHandler::HandleRandomCommand, "", NULL },
124 { "recall", 1, &ChatHandler::HandleRecallCommand, "", NULL },
125 { "run", 2, &ChatHandler::HandleRunCommand, "", NULL },
126 { "save", 0, &ChatHandler::HandleSaveCommand, "", NULL },
127 { "security", 3, &ChatHandler::HandleSecurityCommand, "", NULL },
128 { "AddSpawn", 2, &ChatHandler::HandleSpawnCommand, "", NULL },
129 { "standstate", 3, &ChatHandler::HandleStandStateCommand, "", NULL },
130 { "start", 0, &ChatHandler::HandleStartCommand, "", NULL },
131 { "taxicheat", 1, &ChatHandler::HandleTaxiCheatCommand, "", NULL },
132 { "worldport", 3, &ChatHandler::HandleWorldPortCommand, "", NULL },
133 { "addweapon", 3, &ChatHandler::HandleAddWeaponCommand, "", NULL },
134 { "allowmove", 3, &ChatHandler::HandleAllowMovementCommand, "", NULL },
135 { "addgrave", 3, &ChatHandler::HandleAddGraveCommand, "", NULL },
136 { "addsh", 3, &ChatHandler::HandleAddSHCommand, "", NULL },
137 { "transport", 3, &ChatHandler::HandleSpawnTransportCommand, "", NULL },
138 { "explorecheat",3, &ChatHandler::HandleExploreCheatCommand, "", NULL },
139 { "hover", 3, &ChatHandler::HandleHoverCommand, "", NULL },
140 { "levelup", 3, &ChatHandler::HandleLevelUpCommand, "", NULL },
141 { "emote", 3, &ChatHandler::HandleEmoteCommand, "", NULL },
142 { "showarea", 3, &ChatHandler::HandleShowAreaCommand, "", NULL },
143 { "hidearea", 3, &ChatHandler::HandleHideAreaCommand, "", NULL },
144 { "addspw", 2, &ChatHandler::HandleAddSpwCommand, "", NULL },
145 { "additem", 3, &ChatHandler::HandleAddItemCommand, "", NULL },
146 { "createguild", 3, &ChatHandler::HandleCreateGuildCommand, "", NULL },
147 { "showhonor", 0, &ChatHandler::HandleShowHonor, "", NULL },
148 { "update", 3, &ChatHandler::HandleUpdate, "", NULL },
149 { "bank", 3, &ChatHandler::HandleBankCommand, "", NULL },
150 { "wchange", 3, &ChatHandler::HandleChangeWeather, "", NULL },
151 { "reload", 3, &ChatHandler::HandleReloadCommand, "", NULL },
152 { "loadscripts", 3, &ChatHandler::HandleLoadScriptsCommand, "", NULL },
153 //! Development Commands
154 { "set32value", 3, &ChatHandler::HandleSet32Value, "", NULL },
155 { "Set32Bit", 3, &ChatHandler::HandleSet32Value, "", NULL },
156 { "Mod32Value", 3, &ChatHandler::HandleMod32Value, "", NULL },
158 { NULL, 0, NULL, "", NULL }
161 if(first_call)
163 for(uint32 i = 0; commandTable[i].Name != NULL; i++)
165 QueryResult *result = sDatabase.PQuery("SELECT `security`,`help` FROM `commands` WHERE `name` = '%s';", commandTable[i].Name);
167 if (result)
169 commandTable[i].SecurityLevel = (uint16)(*result)[1].GetUInt16();
170 commandTable[i].Help = (*result)[1].GetString();
171 delete result;
173 if(commandTable[i].ChildCommands != NULL)
175 ChatCommand *ptable = commandTable[i].ChildCommands;
176 for(uint32 j = 0; ptable[j].Name != NULL; j++)
178 QueryResult *result = sDatabase.PQuery("SELECT `security`,`help` FROM `commands` WHERE `name` = '%s %s';", commandTable[i].Name, ptable[j].Name);
180 if (result)
182 ptable[i].SecurityLevel = (uint16)(*result)[1].GetUInt16();
183 ptable[i].Help = (*result)[1].GetString();
184 delete result;
190 first_call = false;
193 return commandTable;
196 bool ChatHandler::hasStringAbbr(const char* s1, const char* s2)
198 for(;;)
200 if( !*s2 )
201 return true;
202 else if( !*s1 )
203 return false;
204 else if( tolower( *s1 ) != tolower( *s2 ) )
205 return false;
206 s1++; s2++;
210 void ChatHandler::SendMultilineMessage(const char *str)
212 char buf[256];
213 WorldPacket data;
215 const char* line = str;
216 const char* pos = line;
217 while((pos = strchr(line, '\n')) != NULL)
219 strncpy(buf, line, pos-line);
220 buf[pos-line]=0;
222 FillSystemMessageData(&data, m_session, buf);
223 m_session->SendPacket(&data);
225 line = pos+1;
228 FillSystemMessageData(&data, m_session, line);
229 m_session->SendPacket(&data);
232 bool ChatHandler::ExecuteCommandInTable(ChatCommand *table, const char* text)
234 std::string cmd = "";
236 while (*text != ' ' && *text != '\0')
238 cmd += *text;
239 text++;
242 while (*text == ' ') text++;
244 if(!cmd.length())
245 return false;
247 for(uint32 i = 0; table[i].Name != NULL; i++)
249 if(!hasStringAbbr(table[i].Name, cmd.c_str()))
250 continue;
252 if(m_session->GetSecurity() < table[i].SecurityLevel)
253 continue;
255 if(table[i].ChildCommands != NULL)
257 if(!ExecuteCommandInTable(table[i].ChildCommands, text))
259 if(table[i].Help != "")
260 SendMultilineMessage(table[i].Help.c_str());
261 else
263 WorldPacket data;
264 FillSystemMessageData(&data, m_session, "There is no such subcommand.");
265 m_session->SendPacket(&data);
269 return true;
272 if(!(this->*(table[i].Handler))(text))
274 if(table[i].Help != "")
275 SendMultilineMessage(table[i].Help.c_str());
276 else
278 WorldPacket data;
279 FillSystemMessageData(&data, m_session, "Incorrect syntax.");
280 m_session->SendPacket(&data);
284 return true;
287 return false;
290 int ChatHandler::ParseCommands(const char* text, WorldSession *session)
292 m_session = session;
294 ASSERT(text);
295 ASSERT(*text);
297 if(m_session->GetSecurity() == 0)
298 return 0;
300 if(text[0] != '!' && text[0] != '.')
301 return 0;
303 text++;
305 if(!ExecuteCommandInTable(getCommandTable(), text))
307 WorldPacket data;
308 FillSystemMessageData(&data, m_session, "There is no such command.");
309 m_session->SendPacket(&data);
311 return 1;
314 void ChatHandler::FillMessageData( WorldPacket *data, WorldSession* session, uint32 type, uint32 language, const char *channelName, const char *message ) const
317 uint32 messageLength = strlen((char*)message) + 1;
318 uint8 afk = 0;
319 uint64 guid = 0;
321 data->Initialize(SMSG_MESSAGECHAT);
322 *data << (uint8)type;
323 *data << language;
325 if (type == CHAT_MSG_CHANNEL)
327 ASSERT(channelName);
328 *data << channelName;
331 if (type == CHAT_MSG_SAY || type == CHAT_MSG_CHANNEL || type == CHAT_MSG_WHISPER ||
332 type == CHAT_MSG_YELL || type == CHAT_MSG_PARTY || type == CHAT_MSG_GUILD ||
333 type == CHAT_MSG_OFFICER)
335 guid = session ? session->GetPlayer()->GetGUID() : 0;
337 else if (type == CHAT_MSG_WHISPER_INFORM)
340 guid = uint32(channelName);
343 *data << guid;
345 if (type == CHAT_MSG_SAY || type == CHAT_MSG_YELL || type == CHAT_MSG_PARTY)
346 *data << guid;
348 *data << messageLength;
349 *data << message;
351 if(type == CHAT_MSG_AFK && session != 0)
352 afk = session->GetPlayer()->ToggleAFK();
354 *data << afk;
357 void ChatHandler::SpawnCreature(WorldSession *session, const char* name, uint32 displayId, uint32 npcFlags, uint32 factionId, uint32 level)
360 Temp. disabled (c) Phantomas
361 WorldPacket data;
363 Player *chr = session->GetPlayer();
364 float x = chr->GetPositionX();
365 float y = chr->GetPositionY();
366 float z = chr->GetPositionZ();
367 float o = chr->GetOrientation();
369 Creature* pCreature = new Creature();
371 pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), name, chr->GetMapId(), x, y, z, o, objmgr.AddCreatureTemplate(pCreature->GetName(), displayId));
372 pCreature->SetZoneId(chr->GetZoneId());
373 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, objmgr.AddCreatureTemplate(pCreature->GetName(), displayId));
374 pCreature->SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);
375 pCreature->SetUInt32Value(UNIT_FIELD_DISPLAYID, displayId);
376 pCreature->SetUInt32Value(UNIT_NPC_FLAGS , npcFlags);
377 pCreature->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE , factionId);
378 pCreature->SetUInt32Value(UNIT_FIELD_HEALTH, 28 + 30*level);
379 pCreature->SetUInt32Value(UNIT_FIELD_MAXHEALTH, 28 + 30*level);
380 pCreature->SetUInt32Value(UNIT_FIELD_LEVEL , level);
382 pCreature->SetFloatValue(UNIT_FIELD_COMBATREACH , 1.5f);
383 pCreature->SetFloatValue(UNIT_FIELD_MAXDAMAGE , 5.0f);
384 pCreature->SetFloatValue(UNIT_FIELD_MINDAMAGE , 8.0f);
385 pCreature->SetUInt32Value(UNIT_FIELD_BASEATTACKTIME, 1900);
386 pCreature->SetUInt32Value(UNIT_FIELD_BASEATTACKTIME+1, 2000);
387 pCreature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 2.0f);
388 pCreature->AIM_Initialize();
389 sLog.outError("AddObject at Chat.cpp");
391 MapManager::Instance().GetMap(pCreature->GetMapId())->Add(pCreature);
392 pCreature->SaveToDB();
396 Player * ChatHandler::getSelectedChar(WorldSession *client)
398 uint64 guid;
399 Player *chr;
401 guid = client->GetPlayer()->GetSelection();
402 if (guid == 0)
403 chr = client->GetPlayer();
404 else
405 chr = objmgr.GetPlayer(guid);
407 return chr;
410 char const *fmtstring( char const *format, ... )
412 va_list argptr;
413 #define MAX_FMT_STRING 32000
414 static char temp_buffer[MAX_FMT_STRING];
415 static char string[MAX_FMT_STRING];
416 static int index = 0;
417 char *buf;
418 int len;
420 va_start (argptr, format);
421 vsprintf (temp_buffer, format, argptr);
422 va_end (argptr);
424 if ((len = strlen(temp_buffer)) >= MAX_FMT_STRING)
426 return "ERROR";
429 if (len + index >= MAX_FMT_STRING-1)
431 index = 0;
434 buf = &string[index];
435 memcpy( buf, temp_buffer, len+1 );
437 index += len + 1;
439 return buf;