Updated Copyright year to 2013
[getmangos.git] / src / game / PetitionsHandler.cpp
blob51589bfa19301d41a84b361d8c815ec419fd9cd1
1 /*
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
19 #include "Common.h"
20 #include "Language.h"
21 #include "WorldPacket.h"
22 #include "WorldSession.h"
23 #include "World.h"
24 #include "ObjectMgr.h"
25 #include "Log.h"
26 #include "Opcodes.h"
27 #include "Guild.h"
28 #include "GuildMgr.h"
29 #include "ArenaTeam.h"
30 #include "GossipDef.h"
31 #include "SocialMgr.h"
33 /*enum PetitionType // dbc data
35 PETITION_TYPE_GUILD = 1,
36 PETITION_TYPE_ARENA_TEAM = 3
37 };*/
39 // Charters ID in item_template
40 #define GUILD_CHARTER 5863
41 #define GUILD_CHARTER_COST 1000 // 10 S
42 #define CHARTER_DISPLAY_ID 16161
44 void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recv_data)
46 DEBUG_LOG("Received opcode CMSG_PETITION_BUY");
47 recv_data.hexlike();
49 ObjectGuid guidNPC;
50 std::string name;
52 recv_data >> guidNPC; // NPC GUID
53 recv_data.read_skip<uint32>(); // 0
54 recv_data.read_skip<uint64>(); // 0
55 recv_data >> name; // name
56 recv_data.read_skip<std::string>(); // some string
57 recv_data.read_skip<uint32>(); // 0
58 recv_data.read_skip<uint32>(); // 0
59 recv_data.read_skip<uint32>(); // 0
60 recv_data.read_skip<uint32>(); // 0
61 recv_data.read_skip<uint32>(); // 0
62 recv_data.read_skip<uint32>(); // 0
63 recv_data.read_skip<uint32>(); // 0
64 recv_data.read_skip<uint16>(); // 0
65 recv_data.read_skip<uint32>(); // 0
66 recv_data.read_skip<uint32>(); // 0
67 recv_data.read_skip<uint32>(); // 0
69 for (int i = 0; i < 10; ++i)
70 recv_data.read_skip<std::string>();
72 recv_data.read_skip<uint32>(); // client index
73 recv_data.read_skip<uint32>(); // 0
75 DEBUG_LOG("Petitioner %s tried sell petition: name %s", guidNPC.GetString().c_str(), name.c_str());
77 // prevent cheating
78 Creature* pCreature = GetPlayer()->GetNPCIfCanInteractWith(guidNPC, UNIT_NPC_FLAG_PETITIONER);
79 if (!pCreature)
81 DEBUG_LOG("WORLD: HandlePetitionBuyOpcode - %s not found or you can't interact with him.", guidNPC.GetString().c_str());
82 return;
85 // remove fake death
86 if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
87 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
89 if (!pCreature->isTabardDesigner())
91 sLog.outError("WORLD: HandlePetitionBuyOpcode - unsupported npc type, npc: %s", guidNPC.GetString().c_str());
92 return;
95 if (sGuildMgr.GetGuildByName(name))
97 SendGuildCommandResult(GUILD_CREATE_S, name, ERR_GUILD_NAME_EXISTS_S);
98 return;
100 if (sObjectMgr.IsReservedName(name) || !ObjectMgr::IsValidCharterName(name))
102 SendGuildCommandResult(GUILD_CREATE_S, name, ERR_GUILD_NAME_INVALID);
103 return;
106 ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(GUILD_CHARTER);
107 if (!pProto)
109 _player->SendBuyError(BUY_ERR_CANT_FIND_ITEM, NULL, GUILD_CHARTER, 0);
110 return;
113 if (_player->GetMoney() < GUILD_CHARTER_COST)
115 // player hasn't got enough money
116 _player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, GUILD_CHARTER, 0);
117 return;
120 ItemPosCountVec dest;
121 InventoryResult msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, GUILD_CHARTER, pProto->BuyCount);
122 if (msg != EQUIP_ERR_OK)
124 _player->SendEquipError(msg, NULL, NULL, GUILD_CHARTER);
125 return;
128 _player->ModifyMoney(-(int64)GUILD_CHARTER_COST);
129 Item* charter = _player->StoreNewItem(dest, GUILD_CHARTER, true);
130 if (!charter)
131 return;
133 charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1, charter->GetGUIDLow());
134 // ITEM_FIELD_ENCHANTMENT_1_1 is guild/arenateam id
135 // ITEM_FIELD_ENCHANTMENT_1_1+1 is current signatures count (showed on item)
136 charter->SetState(ITEM_CHANGED, _player);
137 _player->SendNewItem(charter, 1, true, false);
139 // a petition is invalid, if both the owner and the type matches
140 // we checked above, if this player is in an arenateam, so this must be data corruption
141 QueryResult* result = CharacterDatabase.PQuery("SELECT petitionguid FROM petition WHERE ownerguid = '%u'", _player->GetGUIDLow());
143 std::ostringstream ssInvalidPetitionGUIDs;
145 if (result)
149 Field* fields = result->Fetch();
150 ssInvalidPetitionGUIDs << "'" << fields[0].GetUInt32() << "' , ";
152 while (result->NextRow());
154 delete result;
157 // delete petitions with the same guid as this one
158 ssInvalidPetitionGUIDs << "'" << charter->GetGUIDLow() << "'";
160 DEBUG_LOG("Invalid petition GUIDs: %s", ssInvalidPetitionGUIDs.str().c_str());
161 CharacterDatabase.escape_string(name);
162 CharacterDatabase.BeginTransaction();
163 CharacterDatabase.PExecute("DELETE FROM petition WHERE petitionguid IN ( %s )", ssInvalidPetitionGUIDs.str().c_str());
164 CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE petitionguid IN ( %s )", ssInvalidPetitionGUIDs.str().c_str());
165 CharacterDatabase.PExecute("INSERT INTO petition (ownerguid, petitionguid, name) VALUES ('%u', '%u', '%s')",
166 _player->GetGUIDLow(), charter->GetGUIDLow(), name.c_str());
167 CharacterDatabase.CommitTransaction();
170 void WorldSession::HandlePetitionShowSignOpcode(WorldPacket& recv_data)
172 // ok
173 DEBUG_LOG("Received opcode CMSG_PETITION_SHOW_SIGNATURES");
174 // recv_data.hexlike();
176 uint8 signs = 0;
177 ObjectGuid petitionguid;
178 recv_data >> petitionguid; // petition guid
180 // solve (possible) some strange compile problems with explicit use GUID_LOPART(petitionguid) at some GCC versions (wrong code optimization in compiler?)
181 uint32 petitionguid_low = petitionguid.GetCounter();
183 QueryResult* result = CharacterDatabase.PQuery("SELECT 1 FROM petition WHERE petitionguid = '%u'", petitionguid_low);
184 if (!result)
186 sLog.outError("any petition on server...");
187 return;
189 delete result;
191 // if has guild => error, return;
192 if (_player->GetGuildId())
193 return;
195 result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", petitionguid_low);
197 // result==NULL also correct in case no sign yet
198 if (result)
199 signs = (uint8)result->GetRowCount();
201 DEBUG_LOG("CMSG_PETITION_SHOW_SIGNATURES petition: %s", petitionguid.GetString().c_str());
203 WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8 + 8 + 4 + 1 + signs * 12));
204 data << petitionguid; // petition guid
205 data << _player->GetObjectGuid(); // owner guid
206 data << uint32(petitionguid_low); // guild guid (in mangos always same as GUID_LOPART(petitionguid)
207 data << uint8(signs); // sign's count
209 for (uint8 i = 1; i <= signs; ++i)
211 Field* fields2 = result->Fetch();
212 ObjectGuid signerGuid = ObjectGuid(HIGHGUID_PLAYER, fields2[0].GetUInt32());
214 data << signerGuid; // Player GUID
215 data << uint32(0); // there 0 ...
217 result->NextRow();
219 delete result;
220 SendPacket(&data);
223 void WorldSession::HandlePetitionQueryOpcode(WorldPacket& recv_data)
225 DEBUG_LOG("Received opcode CMSG_PETITION_QUERY");
226 // recv_data.hexlike();
228 uint32 guildguid;
229 ObjectGuid petitionguid;
230 recv_data >> guildguid; // in mangos always same as GUID_LOPART(petitionguid)
231 recv_data >> petitionguid; // petition guid
232 DEBUG_LOG("CMSG_PETITION_QUERY Petition %s Guild GUID %u", petitionguid.GetString().c_str(), guildguid);
234 SendPetitionQueryOpcode(petitionguid);
237 void WorldSession::SendPetitionQueryOpcode(ObjectGuid petitionguid)
239 uint32 petitionLowGuid = petitionguid.GetCounter();
241 ObjectGuid ownerGuid;
242 std::string name = "NO_NAME_FOR_GUID";
243 uint8 signs = 0;
245 QueryResult* result = CharacterDatabase.PQuery(
246 "SELECT ownerguid, name, "
247 " (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs "
248 "FROM petition WHERE petitionguid = '%u'", petitionLowGuid, petitionLowGuid);
250 if (result)
252 Field* fields = result->Fetch();
253 ownerGuid = ObjectGuid(HIGHGUID_PLAYER, fields[0].GetUInt32());
254 name = fields[1].GetCppString();
255 signs = fields[2].GetUInt8();
256 delete result;
258 else
260 DEBUG_LOG("CMSG_PETITION_QUERY failed for petition (GUID: %u)", petitionLowGuid);
261 return;
264 WorldPacket data(SMSG_PETITION_QUERY_RESPONSE, (4 + 8 + name.size() + 1 + 1 + 4 * 12 + 2 + 10));
265 data << uint32(petitionLowGuid); // guild/team guid (in mangos always same as GUID_LOPART(petition guid)
266 data << ObjectGuid(ownerGuid); // charter owner guid
267 data << name; // name (guild/arena team)
268 data << uint8(0); // some string
269 data << uint32(4);
270 data << uint32(4);
271 data << uint32(0); // bypass client - side limitation, a different value is needed here for each petition
272 data << uint32(0); // 5
273 data << uint32(0); // 6
274 data << uint32(0); // 7
275 data << uint32(0); // 8
276 data << uint16(0); // 9 2 bytes field
277 data << uint32(0); // 10
278 data << uint32(0); // 11
279 data << uint32(0); // 13 count of next strings?
281 for (int i = 0; i < 10; ++i)
282 data << uint8(0); // some string
284 data << uint32(0); // 14
285 data << uint32(0); // 15 0 - guild, 1 - arena team
287 SendPacket(&data);
290 void WorldSession::HandlePetitionRenameOpcode(WorldPacket& recv_data)
292 DEBUG_LOG("Received opcode MSG_PETITION_RENAME"); // ok
293 // recv_data.hexlike();
295 ObjectGuid petitionGuid;
296 std::string newname;
298 recv_data >> petitionGuid; // guid
299 recv_data >> newname; // new name
301 Item* item = _player->GetItemByGuid(petitionGuid);
302 if (!item)
303 return;
305 QueryResult* result = CharacterDatabase.PQuery("SELECT 1 FROM petition WHERE petitionguid = '%u'", petitionGuid.GetCounter());
306 if (!result)
308 DEBUG_LOG("CMSG_PETITION_QUERY failed for petition: %s", petitionGuid.GetString().c_str());
309 return;
311 delete result;
313 if (sGuildMgr.GetGuildByName(newname))
315 SendGuildCommandResult(GUILD_CREATE_S, newname, ERR_GUILD_NAME_EXISTS_S);
316 return;
318 if (sObjectMgr.IsReservedName(newname) || !ObjectMgr::IsValidCharterName(newname))
320 SendGuildCommandResult(GUILD_CREATE_S, newname, ERR_GUILD_NAME_INVALID);
321 return;
324 std::string db_newname = newname;
325 CharacterDatabase.escape_string(db_newname);
326 CharacterDatabase.PExecute("UPDATE petition SET name = '%s' WHERE petitionguid = '%u'",
327 db_newname.c_str(), petitionGuid.GetCounter());
329 DEBUG_LOG("Petition %s renamed to '%s'", petitionGuid.GetString().c_str(), newname.c_str());
331 WorldPacket data(MSG_PETITION_RENAME, 8 + newname.size() + 1);
332 data << petitionGuid;
333 data << newname;
334 SendPacket(&data);
337 void WorldSession::HandlePetitionSignOpcode(WorldPacket& recv_data)
339 DEBUG_LOG("Received opcode CMSG_PETITION_SIGN"); // ok
340 // recv_data.hexlike();
342 Field* fields;
343 ObjectGuid petitionGuid;
344 uint8 unk;
345 recv_data >> petitionGuid; // petition guid
346 recv_data >> unk;
348 uint32 petitionLowGuid = petitionGuid.GetCounter();
350 QueryResult* result = CharacterDatabase.PQuery(
351 "SELECT ownerguid, "
352 " (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs "
353 "FROM petition WHERE petitionguid = '%u'", petitionLowGuid, petitionLowGuid);
355 if (!result)
357 sLog.outError("any petition on server...");
358 return;
361 fields = result->Fetch();
362 uint32 ownerLowGuid = fields[0].GetUInt32();
363 ObjectGuid ownerGuid = ObjectGuid(HIGHGUID_PLAYER, ownerLowGuid);
364 uint8 signs = fields[1].GetUInt8();
366 delete result;
368 if (ownerGuid == _player->GetObjectGuid())
369 return;
371 // not let enemies sign guild charter
372 if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GUILD) &&
373 GetPlayer()->GetTeam() != sObjectMgr.GetPlayerTeamByGUID(ownerGuid))
375 SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_NOT_ALLIED);
376 return;
379 if (_player->GetGuildId() || _player->GetGuildIdInvited())
381 // close at signer side
382 _player->SendPetitionSignResult(petitionGuid, _player, PETITION_SIGN_ALREADY_IN_GUILD);
383 return;
386 if (++signs > 4) // client signs maximum
388 // close at signer side
389 _player->SendPetitionSignResult(petitionGuid, _player, PETITION_SIGN_PETITION_FULL);
390 return;
393 // client doesn't allow to sign petition two times by one character, but not check sign by another character from same account
394 // not allow sign another player from already sign player account
395 result = CharacterDatabase.PQuery("SELECT playerguid, petitionguid FROM petition_sign WHERE player_account = '%u'", GetAccountId());
397 if (result)
399 fields = result->Fetch();
400 ObjectGuid playerGuid = ObjectGuid(HIGHGUID_PLAYER, fields[0].GetUInt32());
401 uint32 otherPetition = fields[1].GetUInt32();
402 delete result;
403 if (otherPetition == petitionGuid.GetCounter())
405 // close at signer side
406 _player->SendPetitionSignResult(petitionGuid, _player, PETITION_SIGN_ALREADY_SIGNED);
408 // update for owner if online
409 if (Player* owner = sObjectMgr.GetPlayer(ownerGuid))
410 owner->SendPetitionSignResult(petitionGuid, _player, PETITION_SIGN_ALREADY_SIGNED);
411 return;
413 else if (playerGuid == _player->GetObjectGuid())
415 // close at signer side
416 _player->SendPetitionSignResult(petitionGuid, _player, PETITION_SIGN_ALREADY_SIGNED_OTHER);
418 // update for owner if online
419 if (Player* owner = sObjectMgr.GetPlayer(ownerGuid))
420 owner->SendPetitionSignResult(petitionGuid, _player, PETITION_SIGN_ALREADY_SIGNED_OTHER);
421 return;
425 CharacterDatabase.PExecute("INSERT INTO petition_sign (ownerguid,petitionguid, playerguid, player_account) VALUES ('%u', '%u', '%u','%u')",
426 ownerLowGuid, petitionLowGuid, _player->GetGUIDLow(), GetAccountId());
428 DEBUG_LOG("PETITION SIGN: %s by %s", petitionGuid.GetString().c_str(), _player->GetGuidStr().c_str());
430 // close at signer side
431 _player->SendPetitionSignResult(petitionGuid, _player, PETITION_SIGN_OK);
433 // update signs count on charter, required testing...
434 // Item *item = _player->GetItemByGuid(petitionguid));
435 // if(item)
436 // item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1+1, signs);
438 // update for owner if online
439 if (Player* owner = sObjectMgr.GetPlayer(ownerGuid))
440 owner->SendPetitionSignResult(petitionGuid, _player, PETITION_SIGN_OK);
443 void WorldSession::HandlePetitionDeclineOpcode(WorldPacket& recv_data)
445 DEBUG_LOG("Received opcode MSG_PETITION_DECLINE"); // ok
446 // recv_data.hexlike();
448 ObjectGuid petitionGuid;
449 recv_data >> petitionGuid; // petition guid
451 DEBUG_LOG("Petition %s declined by %s", petitionGuid.GetString().c_str(), _player->GetGuidStr().c_str());
453 uint32 petitionLowGuid = petitionGuid.GetCounter();
455 QueryResult* result = CharacterDatabase.PQuery("SELECT ownerguid FROM petition WHERE petitionguid = '%u'", petitionLowGuid);
456 if (!result)
457 return;
459 Field* fields = result->Fetch();
460 ObjectGuid ownerguid = ObjectGuid(HIGHGUID_PLAYER, fields[0].GetUInt32());
461 delete result;
463 if (Player* owner = sObjectMgr.GetPlayer(ownerguid)) // petition owner online
465 WorldPacket data(MSG_PETITION_DECLINE, 8);
466 data << _player->GetObjectGuid();
467 owner->GetSession()->SendPacket(&data);
471 void WorldSession::HandleOfferPetitionOpcode(WorldPacket& recv_data)
473 DEBUG_LOG("Received opcode CMSG_OFFER_PETITION"); // ok
474 // recv_data.hexlike();
476 ObjectGuid petitionGuid;
477 ObjectGuid playerGuid;
478 uint32 junk;
479 recv_data >> junk; // this is not petition type!
480 recv_data >> petitionGuid; // petition guid
481 recv_data >> playerGuid; // player guid
483 Player* player = ObjectAccessor::FindPlayer(playerGuid);
484 if (!player)
485 return;
487 /// Get petition type and check
488 QueryResult* result = CharacterDatabase.PQuery("SELECT 1 FROM petition WHERE petitionguid = '%u'", petitionGuid.GetCounter());
489 if (!result)
490 return;
491 delete result;
493 DEBUG_LOG("OFFER PETITION: petition %s to %s", petitionGuid.GetString().c_str(), playerGuid.GetString().c_str());
495 if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != player->GetTeam())
497 SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_NOT_ALLIED);
498 return;
501 if (player->GetGuildId())
503 SendGuildCommandResult(GUILD_INVITE_S, _player->GetName(), ERR_ALREADY_IN_GUILD_S);
504 return;
507 if (player->GetGuildIdInvited())
509 SendGuildCommandResult(GUILD_INVITE_S, _player->GetName(), ERR_ALREADY_INVITED_TO_GUILD_S);
510 return;
513 /// Get petition signs count
514 uint8 signs = 0;
515 result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", petitionGuid.GetCounter());
516 // result==NULL also correct charter without signs
517 if (result)
518 signs = (uint8)result->GetRowCount();
520 /// Send response
521 WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8 + 8 + 4 + signs + signs * 12));
522 data << petitionGuid; // petition guid
523 data << _player->GetObjectGuid(); // owner guid
524 data << uint32(petitionGuid.GetCounter()); // guild guid (in mangos always same as low part of petition guid)
525 data << uint8(signs); // sign's count
527 for (uint8 i = 1; i <= signs; ++i)
529 Field* fields2 = result->Fetch();
530 ObjectGuid signerGuid = ObjectGuid(HIGHGUID_PLAYER, fields2[0].GetUInt32());
532 data << signerGuid; // Player GUID
533 data << uint32(0); // there 0 ...
535 result->NextRow();
538 delete result;
539 player->GetSession()->SendPacket(&data);
542 void WorldSession::HandleTurnInPetitionOpcode(WorldPacket& recv_data)
544 DEBUG_LOG("Received opcode CMSG_TURN_IN_PETITION"); // ok
545 // recv_data.hexlike();
547 ObjectGuid petitionGuid;
549 recv_data >> petitionGuid;
551 DEBUG_LOG("Petition %s turned in by %s", petitionGuid.GetString().c_str(), _player->GetGuidStr().c_str());
553 /// Collect petition info data
554 ObjectGuid ownerGuid;
555 std::string name;
557 // data
558 QueryResult* result = CharacterDatabase.PQuery("SELECT ownerguid, name FROM petition WHERE petitionguid = '%u'", petitionGuid.GetCounter());
559 if (result)
561 Field* fields = result->Fetch();
562 ownerGuid = ObjectGuid(HIGHGUID_PLAYER, fields[0].GetUInt32());
563 name = fields[1].GetCppString();
564 delete result;
566 else
568 sLog.outError("CMSG_TURN_IN_PETITION: petition table not have data for guid %u!", petitionGuid.GetCounter());
569 return;
572 if (_player->GetGuildId())
574 _player->SendPetitionTurnInResult(PETITION_TURN_ALREADY_IN_GUILD); // already in guild
575 return;
578 if (_player->GetObjectGuid() != ownerGuid)
579 return;
581 // signs
582 result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", petitionGuid.GetCounter());
583 uint8 signs = result ? (uint8)result->GetRowCount() : 0;
585 uint32 count = sWorld.getConfig(CONFIG_UINT32_MIN_PETITION_SIGNS);
586 if (signs < count)
588 _player->SendPetitionTurnInResult(PETITION_TURN_NEED_MORE_SIGNATURES); // need more signatures...
589 delete result;
590 return;
593 if (sGuildMgr.GetGuildByName(name))
595 _player->SendPetitionTurnInResult(PETITION_TURN_GUILD_NAME_INVALID);
596 delete result;
597 return;
600 // and at last charter item check
601 Item* item = _player->GetItemByGuid(petitionGuid);
602 if (!item)
604 delete result;
605 return;
608 // OK!
610 // delete charter item
611 _player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
613 Guild* guild = new Guild;
614 if (!guild->Create(_player, name))
616 delete guild;
617 delete result;
618 return;
621 // register guild and add guildmaster
622 sGuildMgr.AddGuild(guild);
624 // add members
625 for (uint8 i = 0; i < signs; ++i)
627 Field* fields = result->Fetch();
629 ObjectGuid signGuid = ObjectGuid(HIGHGUID_PLAYER, fields[0].GetUInt32());
630 if (!signGuid)
631 continue;
633 guild->AddMember(signGuid, guild->GetLowestRank());
634 result->NextRow();
637 delete result;
639 CharacterDatabase.BeginTransaction();
640 CharacterDatabase.PExecute("DELETE FROM petition WHERE petitionguid = '%u'", petitionGuid.GetCounter());
641 CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE petitionguid = '%u'", petitionGuid.GetCounter());
642 CharacterDatabase.CommitTransaction();
644 // created
645 DEBUG_LOG("TURN IN PETITION %s", petitionGuid.GetString().c_str());
647 _player->SendPetitionTurnInResult(PETITION_TURN_OK);
650 void WorldSession::HandlePetitionShowListOpcode(WorldPacket& recv_data)
652 DEBUG_LOG("Received CMSG_PETITION_SHOWLIST");
653 // recv_data.hexlike();
655 ObjectGuid guid;
656 recv_data >> guid;
658 SendPetitionShowList(guid);
661 void WorldSession::SendPetitionShowList(ObjectGuid guid)
663 Creature* pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_PETITIONER);
664 if (!pCreature)
666 DEBUG_LOG("WORLD: HandlePetitionShowListOpcode - %s not found or you can't interact with him.", guid.GetString().c_str());
667 return;
670 // remove fake death
671 if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
672 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
674 // only guild petitions currently used
675 if (!pCreature->isTabardDesigner())
677 DEBUG_LOG("WORLD: HandlePetitionShowListOpcode - %s is not supported npc type.", guid.GetString().c_str());
678 return;
681 WorldPacket data(SMSG_PETITION_SHOWLIST, 8 + 1 + 4 * 6);
682 data << guid; // npc guid
683 data << uint32(1); // index
684 data << uint32(GUILD_CHARTER); // charter entry
685 data << uint32(CHARTER_DISPLAY_ID); // charter display id
686 data << uint32(GUILD_CHARTER_COST); // charter cost
687 data << uint32(0); // unknown
688 data << uint32(4); // required signs
690 // for(uint8 i = 0; i < count; ++i)
692 // data << uint32(i); // index
693 // data << uint32(GUILD_CHARTER); // charter entry
694 // data << uint32(CHARTER_DISPLAY_ID); // charter display id
695 // data << uint32(GUILD_CHARTER_COST+i); // charter cost
696 // data << uint32(0); // unknown
697 // data << uint32(9); // required signs
699 SendPacket(&data);
700 DEBUG_LOG("Sent SMSG_PETITION_SHOWLIST");