OregonCore  revision 3611e8a-git
Your Favourite TBC server
PetitionsHandler.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 "WorldPacket.h"
21 #include "WorldSession.h"
22 #include "World.h"
23 #include "ObjectMgr.h"
24 #include "Log.h"
25 #include "Opcodes.h"
26 #include "Guild.h"
27 #include "ArenaTeam.h"
28 #include "MapManager.h"
29 
30 #define CHARTER_DISPLAY_ID 16161
31 
32 /*enum PetitionType // dbc data
33 {
34  PETITION_TYPE_GUILD = 1,
35  PETITION_TYPE_ARENA_TEAM = 3
36 };*/
37 
38 // Charters ID in item_template
40 {
41  GUILD_CHARTER = 5863,
45 };
46 
48 {
53 };
54 
56 {
61 };
62 
64 {
65  sLog.outDebug("Received opcode CMSG_PETITION_BUY");
66 
67  uint64 guidNPC;
68  uint32 clientIndex; // 1 for guild and arenaslot+1 for arenas in client
69  uint64 unk1, unk3, unk4, unk5, unk6, unk7;
70  uint32 unk2, unk10;
71  std::string name;
72  uint16 unk8;
73  uint8 unk9;
74  recv_data >> guidNPC; // NPC GUID
75  recv_data >> unk1; // 0
76  recv_data >> unk2; // 0
77  recv_data >> name; // name
78  recv_data >> unk3; // 0
79  recv_data >> unk4; // 0
80  recv_data >> unk5; // 0
81  recv_data >> unk6; // 0
82  recv_data >> unk7; // 0
83  recv_data >> unk8; // 0
84  recv_data >> unk9; // 0
85  recv_data >> clientIndex; // index
86  recv_data >> unk10; // 0
87  sLog.outDebug("Petitioner with GUID %u tried sell petition: name %s", GUID_LOPART(guidNPC), name.c_str());
88 
89  // prevent cheating
91  if (!pCreature)
92  {
93  sLog.outDebug("WORLD: HandlePetitionBuyOpcode - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(guidNPC));
94  return;
95  }
96 
97  // remove fake death
98  if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
100 
101  uint32 charterid = 0;
102  uint32 cost = 0;
103  uint32 type = 0;
104  if (pCreature->isTabardDesigner())
105  {
106  // if tabard designer, then trying to buy a guild charter.
107  // do not let if already in guild.
108  if (_player->GetGuildId())
109  return;
110 
111  charterid = GUILD_CHARTER;
112  cost = GUILD_CHARTER_COST;
113  type = GUILD_CHARTER_TYPE;
114  }
115  else
116  {
117  // @todo find correct opcode
118  if (_player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
119  {
121  return;
122  }
123 
124  switch (clientIndex) // arenaSlot+1 as received from client (1 from 3 case)
125  {
126  case 1:
127  charterid = ARENA_TEAM_CHARTER_2v2;
130  break;
131  case 2:
132  charterid = ARENA_TEAM_CHARTER_3v3;
135  break;
136  case 3:
137  charterid = ARENA_TEAM_CHARTER_5v5;
140  break;
141  default:
142  sLog.outDebug("unknown selection at buy arena petition: %u", clientIndex);
143  return;
144  }
145 
146  if (_player->GetArenaTeamId(clientIndex - 1)) // arenaSlot+1 as received from client
147  {
149  return;
150  }
151  }
152 
153  if (type == GUILD_CHARTER_TYPE)
154  {
155  if (sObjectMgr.GetGuildByName(name))
156  {
158  return;
159  }
160  if (sObjectMgr.IsReservedName(name) || !ObjectMgr::IsValidCharterName(name))
161  {
163  return;
164  }
165  }
166  else
167  {
168  if (sObjectMgr.GetArenaTeamByName(name))
169  {
171  return;
172  }
173  if (sObjectMgr.IsReservedName(name) || !ObjectMgr::IsValidCharterName(name))
174  {
176  return;
177  }
178  }
179 
180  ItemTemplate const* pProto = sObjectMgr.GetItemTemplate(charterid);
181  if (!pProto)
182  {
183  _player->SendBuyError(BUY_ERR_CANT_FIND_ITEM, NULL, charterid, 0);
184  return;
185  }
186 
187  if (_player->GetMoney() < cost)
188  {
189  //player hasn't got enough money
190  _player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, charterid, 0);
191  return;
192  }
193 
194  ItemPosCountVec dest;
195  uint8 msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, charterid, pProto->BuyCount);
196  if (msg != EQUIP_ERR_OK)
197  {
198  _player->SendBuyError(msg, pCreature, charterid, 0);
199  return;
200  }
201 
202  _player->ModifyMoney(-(int32)cost);
203  Item* charter = _player->StoreNewItem(dest, charterid, true);
204  if (!charter)
205  return;
206 
207  charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT, charter->GetGUIDLow());
208  // ITEM_FIELD_ENCHANTMENT is guild/arenateam id
209  // ITEM_FIELD_ENCHANTMENT+1 is current signatures count (showed on item)
210  charter->SetState(ITEM_CHANGED, _player);
211  _player->SendNewItem(charter, 1, true, false);
212 
213  // a petition is invalid, if both the owner and the type matches
214  // we checked above, if this player is in an arenateam, so this must be
215  // datacorruption
216  QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT petitionguid FROM petition WHERE ownerguid = '%u' AND type = '%u'", _player->GetGUIDLow(), type);
217 
218  std::ostringstream ssInvalidPetitionGUIDs;
219 
220  if (result)
221  {
222  do
223  {
224  Field* fields = result->Fetch();
225  ssInvalidPetitionGUIDs << "'" << fields[0].GetUInt32() << "' , ";
226  }
227  while (result->NextRow());
228  }
229 
230  // delete petitions with the same guid as this one
231  ssInvalidPetitionGUIDs << "'" << charter->GetGUIDLow() << "'";
232 
233  sLog.outDebug("Invalid petition GUIDs: %s", ssInvalidPetitionGUIDs.str().c_str());
236  CharacterDatabase.PExecute("DELETE FROM petition WHERE petitionguid IN (%s)", ssInvalidPetitionGUIDs.str().c_str());
237  CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE petitionguid IN (%s)", ssInvalidPetitionGUIDs.str().c_str());
238  CharacterDatabase.PExecute("INSERT INTO petition (ownerguid, petitionguid, name, type) VALUES ('%u', '%u', '%s', '%u')",
239  _player->GetGUIDLow(), charter->GetGUIDLow(), name.c_str(), type);
241 }
242 
244 {
245  // ok
246  sLog.outDebug("Received opcode CMSG_PETITION_SHOW_SIGNATURES");
247 
248  uint8 signs = 0;
249  uint64 petitionguid;
250  recv_data >> petitionguid; // petition guid
251 
252  // solve (possible) some strange compile problems with explicit use GUID_LOPART(petitionguid) at some GCC versions (wrong code optimization in compiler?)
253  uint32 petitionguid_low = GUID_LOPART(petitionguid);
254 
255  QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", petitionguid_low);
256  if (!result)
257  {
258  sLog.outError("Tried to sign petition guid " UI64FMTD " but it didn't exist!", petitionguid);
259  return;
260  }
261  Field* fields = result->Fetch();
262  uint32 type = fields[0].GetUInt32();
263 
264  // if guild petition and has guild => error, return;
265  if (type == GUILD_CHARTER_TYPE && _player->GetGuildId())
266  return;
267 
268  result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", petitionguid_low);
269 
270  // result == NULL also correct in case no sign yet
271  if (result)
272  signs = result->GetRowCount();
273 
274  sLog.outDebug("CMSG_PETITION_SHOW_SIGNATURES petition entry: '%u'", petitionguid_low);
275 
276  WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8 + 8 + 4 + 1 + signs * 12));
277  data << petitionguid; // petition guid
278  data << _player->GetGUID(); // owner guid
279  data << petitionguid_low; // guild guid (in Oregon always same as GUID_LOPART(petitionguid)
280  data << signs; // sign's count
281 
282  for (uint8 i = 1; i <= signs; ++i)
283  {
284  Field* fields = result->Fetch();
285  uint64 plguid = fields[0].GetUInt64();
286 
287  data << plguid; // Player GUID
288  data << (uint32)0; // there 0 ...
289 
290  result->NextRow();
291  }
292  SendPacket(&data);
293 }
294 
296 {
297  sLog.outDebug("Received opcode CMSG_PETITION_QUERY");
298 
299  uint32 guildguid;
300  uint64 petitionguid;
301  recv_data >> guildguid; // in Oregon always same as GUID_LOPART(petitionguid)
302  recv_data >> petitionguid; // petition guid
303  sLog.outDebug("CMSG_PETITION_QUERY Petition GUID %u Guild GUID %u", GUID_LOPART(petitionguid), guildguid);
304 
305  SendPetitionQueryOpcode(petitionguid);
306 }
307 
309 {
310  uint64 ownerguid = 0;
311  uint32 type;
312  std::string name = "NO_NAME_FOR_GUID";
313  // uint8 signs = 0;
314 
316  "SELECT ownerguid, name, "
317  // " (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs, "
318  " type "
319  "FROM petition WHERE petitionguid = '%u'", /*GUID_LOPART(petitionguid),*/ GUID_LOPART(petitionguid));
320 
321  if (result)
322  {
323  Field* fields = result->Fetch();
324  ownerguid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
325  name = fields[1].GetCppString();
326  // signs = fields[2].GetUInt8();
327  type = fields[2].GetUInt32();
328  }
329  else
330  {
331  sLog.outDebug("CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionguid));
332  return;
333  }
334 
335  WorldPacket data(SMSG_PETITION_QUERY_RESPONSE, (4 + 8 + name.size() + 1 + 1 + 4 * 13));
336  data << GUID_LOPART(petitionguid); // guild/team guid (in Oregon always same as GUID_LOPART(petition guid)
337  data << ownerguid; // charter owner guid
338  data << name; // name (guild/arena team)
339  data << uint8(0); // 1
340  if (type == GUILD_CHARTER_TYPE)
341  {
342  data << uint32(9);
343  data << uint32(9);
344  data << uint32(0); // bypass client - side limitation, a different value is needed here for each petition
345  }
346  else
347  {
348  data << type - 1;
349  data << type - 1;
350  data << type; // bypass client - side limitation, a different value is needed here for each petition
351  }
352  data << uint32(0); // 5
353  data << uint32(0); // 6
354  data << uint32(0); // 7
355  data << uint32(0); // 8
356  data << uint16(0); // 9 2 bytes field
357  data << uint32(0); // 10
358  data << uint32(0); // 11
359  data << uint32(0); // 13 count of next strings?
360  data << uint32(0); // 14
361 
362  if (type == GUILD_CHARTER_TYPE)
363  data << uint32(0); // 15 0 - guild, 1 - arena team
364  else
365  data << uint32(1);
366 
367  SendPacket(&data);
368 }
369 
371 {
372  sLog.outDebug("Received opcode MSG_PETITION_RENAME");
373 
374  uint64 petitionguid;
375  uint32 type;
376  std::string newname;
377 
378  recv_data >> petitionguid; // guid
379  recv_data >> newname; // new name
380 
381  Item* item = _player->GetItemByGuid(petitionguid);
382  if (!item)
383  return;
384 
385  QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
386 
387  if (result)
388  {
389  Field* fields = result->Fetch();
390  type = fields[0].GetUInt32();
391  }
392  else
393  {
394  sLog.outDebug("CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionguid));
395  return;
396  }
397 
398  if (type == GUILD_CHARTER_TYPE)
399  {
400  if (sObjectMgr.GetGuildByName(newname))
401  {
403  return;
404  }
405  if (sObjectMgr.IsReservedName(newname) || !ObjectMgr::IsValidCharterName(newname))
406  {
408  return;
409  }
410  }
411  else
412  {
413  if (sObjectMgr.GetArenaTeamByName(newname))
414  {
416  return;
417  }
418  if (sObjectMgr.IsReservedName(newname) || !ObjectMgr::IsValidCharterName(newname))
419  {
421  return;
422  }
423  }
424 
425  std::string db_newname = newname;
426  CharacterDatabase.escape_string(db_newname);
427  CharacterDatabase.PExecute("UPDATE petition SET name = '%s' WHERE petitionguid = '%u'",
428  db_newname.c_str(), GUID_LOPART(petitionguid));
429 
430  sLog.outDebug("Petition (GUID: %u) renamed to '%s'", GUID_LOPART(petitionguid), newname.c_str());
431  WorldPacket data(MSG_PETITION_RENAME, (8 + newname.size() + 1));
432  data << petitionguid;
433  data << newname;
434  SendPacket(&data);
435 }
436 
438 {
439  sLog.outDebug("Received opcode CMSG_PETITION_SIGN");
440 
441  Field* fields;
442  uint64 petitionguid;
443  uint8 unk;
444  recv_data >> petitionguid; // petition guid
445  recv_data >> unk;
446 
448  "SELECT ownerguid, "
449  " (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs, "
450  " type "
451  "FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid), GUID_LOPART(petitionguid));
452 
453  if (!result)
454  {
455  sLog.outError("Tried to view signs of petition guid " UI64FMTD " but it didn't exist!", petitionguid);
456  return;
457  }
458 
459  fields = result->Fetch();
460  uint64 ownerguid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
461  uint8 signs = fields[1].GetUInt8();
462  uint32 type = fields[2].GetUInt32();
463 
464  uint32 plguidlo = _player->GetGUIDLow();
465  if (GUID_LOPART(ownerguid) == plguidlo)
466  return;
467 
468  // not let enemies sign guild charter
469  if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != sObjectMgr.GetPlayerTeamByGUID(ownerguid))
470  {
471  if (type != 9)
473  else
475  return;
476  }
477 
478  if (type != 9)
479  {
480  if (_player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
481  {
483  return;
484  }
485 
486  uint8 slot = ArenaTeam::GetSlotByType(type);
487  if (slot >= MAX_ARENA_SLOT)
488  return;
489 
490  if (_player->GetArenaTeamId(slot))
491  {
493  return;
494  }
495 
497  {
499  return;
500  }
501  }
502  else
503  {
504  if (_player->GetGuildId())
505  {
507  return;
508  }
509  if (_player->GetGuildIdInvited())
510  {
512  return;
513  }
514  }
515 
516  if (++signs > type) // client signs maximum
517  return;
518 
519  //client doesn't allow to sign petition two times by one character, but not check sign by another character from same account
520  //not allow sign another player from already sign player account
521  result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE player_account = '%u' AND petitionguid = '%u'", GetAccountId(), GUID_LOPART(petitionguid));
522 
523  if (result)
524  {
525  WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8 + 8 + 4));
526  data << petitionguid;
527  data << _player->GetGUID();
529 
530  // close at signer side
531  SendPacket(&data);
532 
533  // update for owner if online
534  if (Player* owner = sObjectMgr.GetPlayer(ownerguid))
535  owner->GetSession()->SendPacket(&data);
536  return;
537  }
538 
539  CharacterDatabase.PExecute("INSERT INTO petition_sign (ownerguid,petitionguid, playerguid, player_account) VALUES ('%u', '%u', '%u','%u')", GUID_LOPART(ownerguid), GUID_LOPART(petitionguid), plguidlo, GetAccountId());
540 
541  sLog.outDebug("PETITION SIGN: GUID %u by player: %s (GUID: %u Account: %u)", GUID_LOPART(petitionguid), _player->GetName(), plguidlo, GetAccountId());
542 
543  WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8 + 8 + 4));
544  data << petitionguid;
545  data << _player->GetGUID();
546  data << (uint32)PETITION_SIGN_OK;
547 
548  // close at signer side
549  SendPacket(&data);
550 
551  // update signs count on charter, required testing...
552  //Item* item = _player->GetItemByGuid(petitionguid));
553  //if (item)
554  // item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT+1, signs);
555 
556  // update for owner if online
557  if (Player* owner = sObjectMgr.GetPlayer(ownerguid))
558  owner->GetSession()->SendPacket(&data);
559 }
560 
562 {
563  sLog.outDebug("Received opcode MSG_PETITION_DECLINE");
564 
565  uint64 petitionguid;
566  uint64 ownerguid;
567  recv_data >> petitionguid; // petition guid
568  sLog.outDebug("Petition %u declined by %u", GUID_LOPART(petitionguid), _player->GetGUIDLow());
569 
570  QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT ownerguid FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
571  if (!result)
572  return;
573 
574  Field* fields = result->Fetch();
575  ownerguid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
576 
577  Player* owner = sObjectMgr.GetPlayer(ownerguid);
578  if (owner) // petition owner online
579  {
581  data << _player->GetGUID();
582  owner->GetSession()->SendPacket(&data);
583  }
584 }
585 
587 {
588  sLog.outDebug("Received opcode CMSG_OFFER_PETITION");
589 
590  uint8 signs = 0;
591  uint64 petitionguid, plguid;
592  uint32 type, junk;
593  Player* player;
594  recv_data >> junk; // this is not petition type!
595  recv_data >> petitionguid; // petition guid
596  recv_data >> plguid; // player guid
597 
598  player = ObjectAccessor::FindPlayer(plguid);
599  if (!player)
600  return;
601 
602  QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
603  if (!result)
604  return;
605 
606  Field* fields = result->Fetch();
607  type = fields[0].GetUInt32();
608 
609  sLog.outDebug("OFFER PETITION: type %u, GUID1 %u, to player id: %u", type, GUID_LOPART(petitionguid), GUID_LOPART(plguid));
610 
611  if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != player->GetTeam())
612  {
613  if (type != 9)
615  else
617  return;
618  }
619 
620  if (type != GUILD_CHARTER_TYPE)
621  {
622  if (player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
623  {
624  // player is too low level to join an arena team
626  return;
627  }
628 
629  uint8 slot = ArenaTeam::GetSlotByType(type);
630  if (slot >= MAX_ARENA_SLOT)
631  return;
632 
633  if (player->GetArenaTeamId(slot))
634  {
635  // player is already in an arena team
637  return;
638  }
639 
640  if (player->GetArenaTeamIdInvited())
641  {
643  return;
644  }
645  }
646  else
647  {
648  if (player->GetGuildId())
649  {
651  return;
652  }
653 
654  if (player->GetGuildIdInvited())
655  {
657  return;
658  }
659  }
660 
661  result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
662  // result == NULL also correct charter without signs
663  if (result)
664  signs = result->GetRowCount();
665 
666  WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8 + 8 + 4 + signs + signs * 12));
667  data << petitionguid; // petition guid
668  data << _player->GetGUID(); // owner guid
669  data << GUID_LOPART(petitionguid); // guild guid (in Oregon always same as GUID_LOPART(petition guid)
670  data << signs; // sign's count
671 
672  for (uint8 i = 1; i <= signs; ++i)
673  {
674  Field* fields = result->Fetch();
675  uint64 plguid = fields[0].GetUInt64();
676 
677  data << plguid; // Player GUID
678  data << (uint32)0; // there 0 ...
679 
680  result->NextRow();
681  }
682 
683  player->GetSession()->SendPacket(&data);
684 }
685 
687 {
688  sLog.outDebug("Received opcode CMSG_TURN_IN_PETITION");
689 
690  WorldPacket data;
691  uint64 petitionguid;
692 
693  uint32 ownerguidlo;
694  uint32 type;
695  std::string name;
696 
697  recv_data >> petitionguid;
698 
699  sLog.outDebug("Petition %u turned in by %u", GUID_LOPART(petitionguid), _player->GetGUIDLow());
700 
701  // data
702  QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT ownerguid, name, type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
703  if (result)
704  {
705  Field* fields = result->Fetch();
706  ownerguidlo = fields[0].GetUInt32();
707  name = fields[1].GetCppString();
708  type = fields[2].GetUInt32();
709  }
710  else
711  {
712  sLog.outError("petition table has broken data!");
713  return;
714  }
715 
716  if (type == GUILD_CHARTER_TYPE)
717  {
718  if (_player->GetGuildId())
719  {
721  data << (uint32)PETITION_TURN_ALREADY_IN_GUILD; // already in guild
722  _player->GetSession()->SendPacket(&data);
723  return;
724  }
725  }
726  else
727  {
728  uint8 slot = ArenaTeam::GetSlotByType(type);
729  if (slot >= MAX_ARENA_SLOT)
730  return;
731 
732  if (_player->GetArenaTeamId(slot))
733  {
734  //data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4);
735  //data << (uint32)PETITION_TURN_ALREADY_IN_GUILD; // already in guild
736  //_player->GetSession()->SendPacket(&data);
738  return;
739  }
740  }
741 
742  if (_player->GetGUIDLow() != ownerguidlo)
743  return;
744 
745  // signs
746  uint8 signs;
747  result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
748  if (result)
749  signs = result->GetRowCount();
750  else
751  signs = 0;
752 
753  uint32 count;
754  //if (signs < sWorld.getConfig(CONFIG_MIN_PETITION_SIGNS))
755  if (type == GUILD_CHARTER_TYPE)
756  count = sWorld.getConfig(CONFIG_MIN_PETITION_SIGNS);
757  else
758  count = type - 1;
759  if (signs < count)
760  {
762  data << (uint32)PETITION_TURN_NEED_MORE_SIGNATURES; // need more signatures...
763  SendPacket(&data);
764  return;
765  }
766 
767  if (type == GUILD_CHARTER_TYPE)
768  {
769  if (sObjectMgr.GetGuildByName(name))
770  {
772  return;
773  }
774  }
775  else
776  {
777  if (sObjectMgr.GetArenaTeamByName(name))
778  {
780  return;
781  }
782  }
783 
784  // and at last charter item check
785  Item* item = _player->GetItemByGuid(petitionguid);
786  if (!item)
787  return;
788 
789  // OK!
790 
791  // delete charter item
792  _player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
793 
794  if (type == GUILD_CHARTER_TYPE) // create guild
795  {
796  Guild* guild = new Guild;
797  if (!guild->Create(_player, name))
798  {
799  delete guild;
800  return;
801  }
802 
803  // register guild and add guildmaster
804  sObjectMgr.AddGuild(guild);
805 
806  // add members
807  for (uint8 i = 0; i < signs; ++i)
808  {
809  Field* fields = result->Fetch();
810  guild->AddMember(fields[0].GetUInt64(), guild->GetLowestRank());
811  result->NextRow();
812  }
813  }
814  else // or arena team
815  {
816  ArenaTeam* at = new ArenaTeam;
817  if (!at->Create(_player->GetGUID(), type, name))
818  {
819  sLog.outError("PetitionsHandler: arena team create failed.");
820  delete at;
821  return;
822  }
823 
824  uint32 icon, iconcolor, border, bordercolor, backgroud;
825  recv_data >> backgroud >> icon >> iconcolor >> border >> bordercolor;
826 
827  at->SetEmblem(backgroud, icon, iconcolor, border, bordercolor);
828 
829  // register team and add captain
830  sObjectMgr.AddArenaTeam(at);
831  sLog.outDebug("PetitonsHandler: arena team added to objmrg");
832 
833  // add members
834  for (uint8 i = 0; i < signs; ++i)
835  {
836  Field* fields = result->Fetch();
837  uint64 memberGUID = fields[0].GetUInt64();
838  sLog.outDebug("PetitionsHandler: adding arena member %u", GUID_LOPART(memberGUID));
839  at->AddMember(memberGUID);
840  result->NextRow();
841  }
842  }
843 
845  CharacterDatabase.PExecute("DELETE FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
846  CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
848 
849  // created
850  sLog.outDebug("TURN IN PETITION GUID %u", GUID_LOPART(petitionguid));
851 
853  data << (uint32)PETITION_TURN_OK;
854  SendPacket(&data);
855 }
856 
858 {
859  sLog.outDebug("Received CMSG_PETITION_SHOWLIST"); // ok
860  //recv_data.hexlike();
861 
862  uint64 guid;
863  recv_data >> guid;
864 
865  SendPetitionShowList(guid);
866 }
867 
869 {
871  if (!pCreature)
872  {
873  sLog.outDebug("WORLD: HandlePetitionShowListOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
874  return;
875  }
876 
877  // remove fake death
878  if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
880 
881  uint8 count = 0;
882  if (pCreature->isTabardDesigner())
883  count = 1;
884  else
885  count = 3;
886 
887  WorldPacket data(SMSG_PETITION_SHOWLIST, 8 + 1 + 4 * 6);
888  data << guid; // npc guid
889  data << count; // count
890  if (count == 1)
891  {
892  data << uint32(1); // index
893  data << uint32(GUILD_CHARTER); // charter entry
894  data << uint32(CHARTER_DISPLAY_ID); // charter display id
895  data << uint32(GUILD_CHARTER_COST); // charter cost
896  data << uint32(0); // unknown
897  data << uint32(9); // required signs?
898  }
899  else
900  {
901  // 2v2
902  data << uint32(1); // index
903  data << uint32(ARENA_TEAM_CHARTER_2v2); // charter entry
904  data << uint32(CHARTER_DISPLAY_ID); // charter display id
905  data << uint32(ARENA_TEAM_CHARTER_2v2_COST); // charter cost
906  data << uint32(2); // unknown
907  data << uint32(2); // required signs?
908  // 3v3
909  data << uint32(2); // index
910  data << uint32(ARENA_TEAM_CHARTER_3v3); // charter entry
911  data << uint32(CHARTER_DISPLAY_ID); // charter display id
912  data << uint32(ARENA_TEAM_CHARTER_3v3_COST); // charter cost
913  data << uint32(3); // unknown
914  data << uint32(3); // required signs?
915  // 5v5
916  data << uint32(3); // index
917  data << uint32(ARENA_TEAM_CHARTER_5v5); // charter entry
918  data << uint32(CHARTER_DISPLAY_ID); // charter display id
919  data << uint32(ARENA_TEAM_CHARTER_5v5_COST); // charter cost
920  data << uint32(5); // unknown
921  data << uint32(5); // required signs?
922  }
923  //for (uint8 i = 0; i < count; ++i)
924  //{
925  // data << uint32(i); // index
926  // data << uint32(GUILD_CHARTER); // charter entry
927  // data << uint32(CHARTER_DISPLAY_ID); // charter display id
928  // data << uint32(GUILD_CHARTER_COST+i); // charter cost
929  // data << uint32(0); // unknown
930  // data << uint32(9); // required signs?
931  //}
932  SendPacket(&data);
933  sLog.outDebug("Sent SMSG_PETITION_SHOWLIST");
934 }
935 
void HandleOfferPetitionOpcode(WorldPacket &recv_data)
void SendNotification(const char *format,...) ATTR_PRINTF(2
void SendPetitionQueryOpcode(uint64 petitionguid)
void SetState(ItemUpdateState state, Player *forplayer=NULL)
Definition: Item.cpp:661
#define GUID_LOPART(x)
Definition: ObjectGuid.h:110
bool AddMember(const uint64 &playerGuid)
Definition: ArenaTeam.cpp:90
uint32 GetLowestRank() const
Definition: Guild.h:337
void SendGuildCommandResult(uint32 typecmd, const std::string &str, uint32 cmdresult)
void HandlePetitionSignOpcode(WorldPacket &recv_data)
bool BeginTransaction()
Definition: Database.cpp:533
static uint8 GetSlotByType(uint32 type)
Definition: ArenaTeam.cpp:502
QueryResult_AutoPtr PQuery(const char *format,...) ATTR_PRINTF(2
Definition: Database.cpp:400
Definition: Field.h:24
void RemoveSpellsCausingAura(AuraType auraType)
Definition: Unit.cpp:648
#define sLog
Log class singleton.
Definition: Log.h:187
void SetUInt32Value(uint16 index, uint32 value)
Definition: Object.cpp:779
ACE_INT32 int32
Definition: Define.h:67
void HandlePetitionBuyOpcode(WorldPacket &recv_data)
unsigned long escape_string(char *to, const char *from, unsigned long length)
Definition: Database.cpp:212
void Initialize(uint16 opcode, size_t newres=200)
Definition: WorldPacket.h:37
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false)
Definition: Player.cpp:12144
uint32 GetAccountId() const
Definition: WorldSession.h:100
Player * GetPlayer() const
Definition: WorldSession.h:104
uint32 GetGUIDLow() const
Definition: Object.h:160
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0)
Definition: Player.cpp:10277
void HandleTurnInPetitionOpcode(WorldPacket &recv_data)
#define sObjectMgr
Definition: ObjectMgr.h:1285
void SendPacket(WorldPacket const *packet)
bool CommitTransaction()
Definition: Database.cpp:551
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition: Player.cpp:10724
uint8 CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=NULL) const
Definition: Player.h:1147
bool isTabardDesigner() const
Definition: Unit.h:1276
static bool IsValidCharterName(const std::string &name)
Definition: ObjectMgr.cpp:6600
void SetEmblem(uint32 backgroundColor, uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor)
Definition: ArenaTeam.cpp:417
ACE_UINT8 uint8
Definition: Define.h:73
#define UI64FMTD
Definition: Common.h:149
void HandlePetitionDeclineOpcode(WorldPacket &recv_data)
Definition: Unit.h:297
std::string GetCppString() const
Definition: Field.h:52
void HandlePetitionQueryOpcode(WorldPacket &recv_data)
int GetGuildIdInvited()
Definition: Player.h:1847
#define MAKE_NEW_GUID(l, e, h)
Definition: ObjectGuid.h:80
Definition: Item.h:196
static Player * FindPlayer(uint64, bool force=false)
void HandlePetitionShowListOpcode(WorldPacket &recvPacket)
void SendPetitionShowList(uint64 guid)
void HandlePetitionShowSignOpcode(WorldPacket &recv_data)
bool PExecute(const char *format,...) ATTR_PRINTF(2
Definition: Database.cpp:441
CharterTypes
uint32 GetGuildId()
Definition: Player.h:1837
#define CHARTER_DISPLAY_ID
uint8 GetSlot() const
Definition: Item.h:266
void SendBuyError(uint8 msg, Creature *pCreature, uint32 item, uint32 param)
Definition: Player.cpp:11597
const char * GetName() const
Definition: Object.h:692
void SendArenaTeamCommandResult(uint32 team_action, const std::string &team, const std::string &player, uint32 error_id)
std::vector< ItemPosCount > ItemPosCountVec
Definition: Player.h:605
ACE_UINT64 uint64
Definition: Define.h:70
uint32 GetArenaTeamId(uint8 slot)
Definition: Player.h:1862
Player * _player
Definition: WorldSession.h:729
ACE_Refcounted_Auto_Ptr< QueryResult, ACE_Null_Mutex > QueryResult_AutoPtr
Definition: QueryResult.h:113
uint32 GetMoney()
Definition: Player.h:1524
CharterCosts
uint32 GetArenaTeamIdInvited()
Definition: Player.h:1875
bool AddMember(uint64 plGuid, uint32 plRank)
Definition: Guild.cpp:121
uint32 GetTeam() const
Definition: Player.h:2075
Creature * GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask)
Definition: Player.cpp:2191
WorldSession * GetSession() const
Definition: Player.h:1959
#define sWorld
Definition: World.h:860
CharterItemIDs
DatabaseType CharacterDatabase
Accessor to the character database.
Definition: Main.cpp:54
ACE_UINT16 uint16
Definition: Define.h:72
void ModifyMoney(int32 d)
Definition: Player.h:1528
ACE_UINT32 uint32
Definition: Define.h:71
Definition: Guild.h:265
uint8 GetBagSlot() const
Definition: Item.cpp:728
uint32 getLevel() const
Definition: Unit.h:1029
Definition: Player.h:922
bool Create(Player *leader, std::string gname)
Definition: Guild.cpp:61
void HandlePetitionRenameOpcode(WorldPacket &recv_data)
Item * GetItemByGuid(uint64 guid) const
Definition: Player.cpp:8583
#define MAX_ARENA_SLOT
Definition: ArenaTeam.h:111
bool Create(uint64 captainGuid, uint32 type, std::string arenaTeamName)
Definition: ArenaTeam.cpp:56
const uint64 & GetGUID() const
Definition: Object.h:156