OregonCore  revision 3611e8a-git
Your Favourite TBC server
QueryHandler.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the OregonCore Project. See AUTHORS file for Copyright information
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2 of the License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "Common.h"
19 #include "Language.h"
20 #include "Database/DatabaseEnv.h"
21 #include "Database/DatabaseImpl.h"
22 #include "WorldPacket.h"
23 #include "WorldSession.h"
24 #include "Opcodes.h"
25 #include "Log.h"
26 #include "World.h"
27 #include "ObjectMgr.h"
28 #include "Player.h"
29 #include "UpdateMask.h"
30 #include "NPCHandler.h"
31 #include "ObjectAccessor.h"
32 #include "MapManager.h"
33 
35 {
36  if (!p)
37  return;
38  // guess size
39  WorldPacket data(SMSG_NAME_QUERY_RESPONSE, (8 + 1 + 4 + 4 + 4 + 10));
40  data << p->GetGUID(); // player guid
41  data << p->GetName(); // played name
42  data << uint8(0); // realm name for cross realm BG usage
43  data << uint32(p->getRace());
44  data << uint32(p->getGender());
45  data << uint32(p->getClass());
46  if (DeclinedName const* names = p->GetDeclinedNames())
47  {
48  data << uint8(1); // is declined
49  for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
50  data << names->name[i];
51  }
52  else
53  data << uint8(0); // is not declined
54 
55  SendPacket(&data);
56 }
57 
59 {
62  // ------- Query Without Declined Names --------
63  // 0 1 2
64  "SELECT guid, name, SUBSTRING(data, LENGTH(SUBSTRING_INDEX(data, ' ', '%u'))+2, LENGTH(SUBSTRING_INDEX(data, ' ', '%u')) - LENGTH(SUBSTRING_INDEX(data, ' ', '%u'))-1) "
65  "FROM characters WHERE guid = '%u'"
66  :
67  // --------- Query With Declined Names ---------
68  // 0 1 2
69  "SELECT characters.guid, name, SUBSTRING(data, LENGTH(SUBSTRING_INDEX(data, ' ', '%u'))+2, LENGTH(SUBSTRING_INDEX(data, ' ', '%u')) - LENGTH(SUBSTRING_INDEX(data, ' ', '%u'))-1), "
70  // 3 4 5 6 7
71  "genitive, dative, accusative, instrumental, prepositional "
72  "FROM characters LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid WHERE characters.guid = '%u'",
74 }
75 
77 {
78  if (!result)
79  return;
80 
81  WorldSession* session = sWorld.FindSession(accountId);
82  if (!session)
83  return;
84 
85  Field* fields = result->Fetch();
86  uint32 guid = fields[0].GetUInt32();
87  std::string name = fields[1].GetCppString();
88  uint32 field = 0;
89  if (name == "")
91  else
92  field = fields[2].GetUInt32();
93 
94  // guess size
95  WorldPacket data(SMSG_NAME_QUERY_RESPONSE, (8 + 1 + 4 + 4 + 4 + 10));
96  data << MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER);
97  data << name;
98  data << (uint8)0;
99  data << (uint32)(field & 0xFF);
100  data << (uint32)((field >> 16) & 0xFF);
101  data << (uint32)((field >> 8) & 0xFF);
102 
103  // if the first declined name field (3) is empty, the rest must be too
104  if (sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) && fields[3].GetCppString() != "")
105  {
106  data << uint8(1); // is declined
107  for (int i = 3; i < MAX_DECLINED_NAME_CASES + 3; ++i)
108  data << fields[i].GetCppString();
109  }
110  else
111  data << uint8(0); // is not declined
112 
113  session->SendPacket(&data);
114 }
115 
117 {
118  uint64 guid;
119 
120  recv_data >> guid;
121 
122  Player* pChar = sObjectMgr.GetPlayer(guid);
123 
124  if (pChar)
125  SendNameQueryOpcode(pChar);
126  else
128 }
129 
131 {
133  data << uint32(time(NULL));
134  data << uint32(0);
135  SendPacket(&data);
136 }
137 
138 // Only _static_ data send in this packet !!!
140 {
141  uint32 entry;
142  recv_data >> entry;
143  uint64 guid;
144  recv_data >> guid;
145 
146  CreatureInfo const* ci = sObjectMgr.GetCreatureTemplate(entry);
147  if (ci)
148  {
149 
150  std::string Name, SubName;
151  Name = ci->Name;
152  SubName = ci->SubName;
153 
154  int loc_idx = GetSessionDbLocaleIndex();
155  if (loc_idx >= 0)
156  {
157  CreatureLocale const* cl = sObjectMgr.GetCreatureLocale(entry);
158  if (cl)
159  {
160  if (cl->Name.size() > uint32(loc_idx) && !cl->Name[loc_idx].empty())
161  Name = cl->Name[loc_idx];
162  if (cl->SubName.size() > uint32(loc_idx) && !cl->SubName[loc_idx].empty())
163  SubName = cl->SubName[loc_idx];
164  }
165  }
166  sLog.outDetail("WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name, entry);
167  // guess size
169  data << uint32(entry); // creature entry
170  data << Name;
171  data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty
172  data << SubName;
173  data << ci->IconName; // "Directions" for guard, string for Icons 2.3.0
174  data << uint32(ci->type_flags); // flags
175  data << uint32(ci->type); // CreatureType.dbc
176  data << uint32(ci->family); // CreatureFamily.dbc
177  data << uint32(ci->rank); // Creature Rank (elite, boss, etc)
178  data << uint32(0); // unknown wdbFeild11
179  data << uint32(ci->PetSpellDataId); // Id from CreatureSpellData.dbc wdbField12
180  data << (uint32)ci->modelid1; // modelid1
181  data << (uint32)ci->modelid2; // modelid2
182  data << (uint32)ci->modelid3; // modelid3
183  data << (uint32)ci->modelid4; // modelid4
184  data << (float)1.0f; // unk
185  data << (float)1.0f; // unk
186  data << uint8(ci->RacialLeader);
187  SendPacket(&data);
188  sLog.outDebug("WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE");
189  }
190  else
191  {
192  sLog.outDebug("WORLD: CMSG_CREATURE_QUERY - NO CREATURE INFO! (GUID: %u, ENTRY: %u)",
193  GUID_LOPART(guid), entry);
195  data << uint32(entry | 0x80000000);
196  SendPacket(&data);
197  sLog.outDebug("WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE");
198  }
199 }
200 
201 // Only _static_ data send in this packet !!!
203 {
204  uint32 entryID;
205  recv_data >> entryID;
206  uint64 guid;
207  recv_data >> guid;
208 
209  const GameObjectInfo* info = sObjectMgr.GetGameObjectInfo(entryID);
210  if (info)
211  {
212  std::string Name;
213  std::string CastBarCaption;
214 
215  Name = info->name;
216  CastBarCaption = info->castBarCaption;
217 
218  int loc_idx = GetSessionDbLocaleIndex();
219  if (loc_idx >= 0)
220  {
221  GameObjectLocale const* gl = sObjectMgr.GetGameObjectLocale(entryID);
222  if (gl)
223  {
224  if (gl->Name.size() > uint32(loc_idx) && !gl->Name[loc_idx].empty())
225  Name = gl->Name[loc_idx];
226  if (gl->CastBarCaption.size() > uint32(loc_idx) && !gl->CastBarCaption[loc_idx].empty())
227  CastBarCaption = gl->CastBarCaption[loc_idx];
228  }
229  }
230  sLog.outDetail("WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u. ", info->name, entryID);
232  data << uint32(entryID);
233  data << uint32(info->type);
234  data << uint32(info->displayId);
235  data << Name;
236  data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4
237  data << uint8(0); // 2.0.3, string
238  data << CastBarCaption; // 2.0.3, string. Text will appear in Cast Bar when using GO (ex: "Collecting")
239  data << uint8(0); // 2.0.3, string
240  data.append(info->raw.data, 24);
241  data << float(info->size); // go size
242  SendPacket(&data);
243  sLog.outDebug("WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE");
244  }
245  else
246  {
247  sLog.outDebug("WORLD: CMSG_GAMEOBJECT_QUERY - Missing gameobject info for (GUID: %u, ENTRY: %u)",
248  GUID_LOPART(guid), entryID);
250  data << uint32(entryID | 0x80000000);
251  SendPacket(&data);
252  sLog.outDebug("WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE");
253  }
254 }
255 
257 {
258  sLog.outDetail("WORLD: Received MSG_CORPSE_QUERY");
259 
260  Corpse* corpse = GetPlayer()->GetCorpse();
261 
262  if (!corpse)
263  {
264  WorldPacket data(MSG_CORPSE_QUERY, 1);
265  data << uint8(0); // corpse not found
266  SendPacket(&data);
267  return;
268  }
269 
270  int32 mapid = corpse->GetMapId();
271  float x = corpse->GetPositionX();
272  float y = corpse->GetPositionY();
273  float z = corpse->GetPositionZ();
274  int32 corpsemapid = mapid;
275 
276  // if corpse at different map
277  if (uint32(mapid) != _player->GetMapId())
278  {
279  // search entrance map for proper show entrance
280  if (MapEntry const* corpseMapEntry = sMapStore.LookupEntry(mapid))
281  {
282  if (corpseMapEntry->IsDungeon() && corpseMapEntry->entrance_map >= 0)
283  {
284  // if corpse map have entrance
285  if (Map const* entranceMap = MapManager::Instance().CreateBaseMap(corpseMapEntry->entrance_map))
286  {
287  mapid = corpseMapEntry->entrance_map;
288  x = corpseMapEntry->entrance_x;
289  y = corpseMapEntry->entrance_y;
290  z = entranceMap->GetHeight(x, y, MAX_HEIGHT);
291  }
292  }
293  }
294  }
295 
296  WorldPacket data(MSG_CORPSE_QUERY, 1 + (5 * 4));
297  data << uint8(1); // corpse found
298  data << int32(mapid);
299  data << float(x);
300  data << float(y);
301  data << float(z);
302  data << int32(corpsemapid);
303  SendPacket(&data);
304 }
305 
307 {
308  uint32 textID;
309  uint64 guid;
310 
311  recv_data >> textID;
312  sLog.outDetail("WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID);
313 
314  recv_data >> guid;
316 
317  GossipText const* pGossip = sObjectMgr.GetGossipText(textID);
318 
319  WorldPacket data(SMSG_NPC_TEXT_UPDATE, 100); // guess size
320  data << textID;
321 
322  if (!pGossip)
323  {
324  for (uint32 i = 0; i < 8; ++i)
325  {
326  data << float(0);
327  data << "Greetings $N";
328  data << "Greetings $N";
329  data << uint32(0);
330  data << uint32(0);
331  data << uint32(0);
332  data << uint32(0);
333  data << uint32(0);
334  data << uint32(0);
335  data << uint32(0);
336  }
337  }
338  else
339  {
340  std::string Text_0[8], Text_1[8];
341  for (int i = 0; i < 8; ++i)
342  {
343  Text_0[i] = pGossip->Options[i].Text_0;
344  Text_1[i] = pGossip->Options[i].Text_1;
345  }
346 
347  int loc_idx = GetSessionDbLocaleIndex();
348  if (loc_idx >= 0)
349  {
350  NpcTextLocale const* nl = sObjectMgr.GetNpcTextLocale(textID);
351  if (nl)
352  {
353  for (int i = 0; i < 8; ++i)
354  {
355  if (nl->Text_0[i].size() > uint32(loc_idx) && !nl->Text_0[i][loc_idx].empty())
356  Text_0[i] = nl->Text_0[i][loc_idx];
357  if (nl->Text_1[i].size() > uint32(loc_idx) && !nl->Text_1[i][loc_idx].empty())
358  Text_1[i] = nl->Text_1[i][loc_idx];
359  }
360  }
361  }
362 
363  for (int i = 0; i < 8; ++i)
364  {
365  data << pGossip->Options[i].Probability;
366 
367  if (Text_0[i].empty())
368  data << Text_1[i];
369  else
370  data << Text_0[i];
371 
372  if (Text_1[i].empty())
373  data << Text_0[i];
374  else
375  data << Text_1[i];
376 
377  data << pGossip->Options[i].Language;
378 
379  for (int j = 0; j < 3; ++j)
380  {
381  data << pGossip->Options[i].Emotes[j]._Delay;
382  data << pGossip->Options[i].Emotes[j]._Emote;
383  }
384  }
385  }
386 
387  SendPacket(&data);
388 
389  sLog.outDebug("WORLD: Sent SMSG_NPC_TEXT_UPDATE");
390 }
391 
393 {
394  sLog.outDetail("WORLD: Received CMSG_PAGE_TEXT_QUERY");
395  recv_data.hexlike();
396 
397  uint32 pageID;
398  recv_data >> pageID;
399  recv_data.read_skip<uint64>(); // guid
400 
401  while (pageID)
402  {
403  PageText const* pPage = sPageTextStore.LookupEntry<PageText>(pageID);
404  // guess size
406  data << pageID;
407 
408  if (!pPage)
409  {
410  data << "Item page missing.";
411  data << uint32(0);
412  pageID = 0;
413  }
414  else
415  {
416  std::string Text = pPage->Text;
417 
418  int loc_idx = GetSessionDbLocaleIndex();
419  if (loc_idx >= 0)
420  {
421  PageTextLocale const* pl = sObjectMgr.GetPageTextLocale(pageID);
422  if (pl)
423  {
424  if (pl->Text.size() > uint32(loc_idx) && !pl->Text[loc_idx].empty())
425  Text = pl->Text[loc_idx];
426  }
427  }
428 
429  data << Text;
430  data << uint32(pPage->Next_Page);
431  pageID = pPage->Next_Page;
432  }
433  SendPacket(&data);
434 
435  sLog.outDebug("WORLD: Sent SMSG_PAGE_TEXT_QUERY_RESPONSE");
436  }
437 }
438 
DeclinedName const * GetDeclinedNames() const
Definition: Player.h:2660
std::vector< std::vector< std::string > > Text_0
Definition: NPCHandler.h:77
Definition: Corpse.h:48
void read_skip()
Definition: ByteBuffer.h:276
#define GUID_LOPART(x)
Definition: ObjectGuid.h:110
uint32 Next_Page
Definition: NPCHandler.h:33
std::string Text_1
Definition: NPCHandler.h:52
uint32 rank
Definition: Creature.h:155
char * Name
Definition: Creature.h:138
void HandleGameObjectQueryOpcode(WorldPacket &recvPacket)
SQLStorage sPageTextStore
uint32 modelid4
Definition: Creature.h:137
Definition: Field.h:24
static void SendNameQueryOpcodeFromDBCallBack(QueryResult_AutoPtr result, uint32 accountId)
#define sLog
Log class singleton.
Definition: Log.h:187
std::vector< std::string > CastBarCaption
Definition: GameObject.h:523
bool RacialLeader
Definition: Creature.h:193
ACE_INT32 int32
Definition: Define.h:67
uint32 displayId
Definition: GameObject.h:40
std::string Text_0
Definition: NPCHandler.h:51
uint32 GetAccountId() const
Definition: WorldSession.h:100
Player * GetPlayer() const
Definition: WorldSession.h:104
#define MAX_DECLINED_NAME_CASES
Definition: Unit.h:704
uint32 modelid1
Definition: Creature.h:134
#define sObjectMgr
Definition: ObjectMgr.h:1285
void SendPacket(WorldPacket const *packet)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
Map const * CreateBaseMap(uint32 id) const
Definition: MapManager.h:41
char * castBarCaption
Definition: GameObject.h:42
char * IconName
Definition: Creature.h:140
void SendNameQueryOpcodeFromDB(uint64 guid)
char * SubName
Definition: Creature.h:139
ACE_UINT8 uint8
Definition: Define.h:73
std::string GetCppString() const
Definition: Field.h:52
uint32 type
Definition: Creature.h:173
float GetPositionY() const
Definition: Position.h:98
#define MAKE_NEW_GUID(l, e, h)
Definition: ObjectGuid.h:80
void SendNameQueryOpcode(Player *p)
GossipTextOption Options[8]
Definition: NPCHandler.h:61
float GetPositionZ() const
Definition: Position.h:99
void HandlePageQueryOpcode(WorldPacket &recvPacket)
bool AsyncPQuery(Class *object, void(Class::*method)(QueryResult_AutoPtr), const char *format,...) ATTR_PRINTF(4
Definition: DatabaseImpl.h:128
std::vector< std::string > Text
Definition: NPCHandler.h:66
uint32 GetMapId() const
Definition: Object.h:585
Corpse * GetCorpse() const
Definition: Player.cpp:4386
const char * GetOregonString(int32 entry) const
Definition: Map.h:266
uint32 PetSpellDataId
Definition: Creature.h:185
void SetUInt64Value(uint16 index, const uint64 &value)
Definition: Object.cpp:798
void hexlike() const
Definition: ByteBuffer.h:451
uint32 modelid3
Definition: Creature.h:136
QEmote Emotes[3]
Definition: NPCHandler.h:55
const char * GetName() const
Definition: Object.h:692
ACE_UINT64 uint64
Definition: Define.h:70
void HandleCorpseQueryOpcode(WorldPacket &recvPacket)
T const * LookupEntry(uint32 id) const
Definition: SQLStorage.h:52
uint32 modelid2
Definition: Creature.h:135
uint8 getRace() const
Definition: Unit.h:1037
void append(const std::string &str)
Definition: ByteBuffer.h:358
Player * _player
Definition: WorldSession.h:729
ACE_Refcounted_Auto_Ptr< QueryResult, ACE_Null_Mutex > QueryResult_AutoPtr
Definition: QueryResult.h:113
int GetSessionDbLocaleIndex() const
Definition: WorldSession.h:237
uint32 _Delay
Definition: NPCHandler.h:46
void HandleQueryTimeOpcode(WorldPacket &recvPacket)
void HandleNpcTextQueryOpcode(WorldPacket &recvPacket)
uint8 getGender() const
Definition: Unit.h:1041
uint8 getClass() const
Definition: Unit.h:1039
std::vector< std::string > Name
Definition: Creature.h:242
uint32 _Emote
Definition: NPCHandler.h:45
#define sWorld
Definition: World.h:860
DatabaseType CharacterDatabase
Accessor to the character database.
Definition: Main.cpp:54
uint32 type_flags
Definition: Creature.h:174
ACE_UINT32 uint32
Definition: Define.h:71
float GetPositionX() const
Definition: Position.h:97
#define MAX_HEIGHT
Definition: Map.h:258
std::vector< std::vector< std::string > > Text_1
Definition: NPCHandler.h:78
struct GameObjectInfo::@59::@90 raw
CreatureFamily family
Definition: Creature.h:165
std::vector< std::string > Name
Definition: GameObject.h:522
Definition: Player.h:922
std::vector< std::string > SubName
Definition: Creature.h:243
void HandleNameQueryOpcode(WorldPacket &recvPacket)
char * Text
Definition: NPCHandler.h:31
void HandleCreatureQueryOpcode(WorldPacket &recvPacket)
const uint64 & GetGUID() const
Definition: Object.h:156