2 * Copyright (C) 2005-2010 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 "WorldPacket.h"
22 #include "WorldSession.h"
24 #include "ObjectMgr.h"
25 #include "ObjectGuid.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
39 // Charters ID in item_template
40 #define GUILD_CHARTER 5863
41 #define GUILD_CHARTER_COST 1000 // 10 S
42 #define ARENA_TEAM_CHARTER_2v2 23560
43 #define ARENA_TEAM_CHARTER_2v2_COST 800000 // 80 G
44 #define ARENA_TEAM_CHARTER_3v3 23561
45 #define ARENA_TEAM_CHARTER_3v3_COST 1200000 // 120 G
46 #define ARENA_TEAM_CHARTER_5v5 23562
47 #define ARENA_TEAM_CHARTER_5v5_COST 2000000 // 200 G
48 #define CHARTER_DISPLAY_ID 16161
50 void WorldSession::HandlePetitionBuyOpcode(WorldPacket
& recv_data
)
52 sLog
.outDebug("Received opcode CMSG_PETITION_BUY");
56 uint32 clientIndex
; // 1 for guild and arenaslot+1 for arenas in client
59 recv_data
>> guidNPC
; // NPC GUID
60 recv_data
.read_skip
<uint32
>(); // 0
61 recv_data
.read_skip
<uint64
>(); // 0
62 recv_data
>> name
; // name
63 recv_data
.read_skip
<std::string
>(); // some string
64 recv_data
.read_skip
<uint32
>(); // 0
65 recv_data
.read_skip
<uint32
>(); // 0
66 recv_data
.read_skip
<uint32
>(); // 0
67 recv_data
.read_skip
<uint32
>(); // 0
68 recv_data
.read_skip
<uint32
>(); // 0
69 recv_data
.read_skip
<uint32
>(); // 0
70 recv_data
.read_skip
<uint32
>(); // 0
71 recv_data
.read_skip
<uint16
>(); // 0
72 recv_data
.read_skip
<uint32
>(); // 0
73 recv_data
.read_skip
<uint32
>(); // 0
74 recv_data
.read_skip
<uint32
>(); // 0
76 for (int i
= 0; i
< 10; ++i
)
77 recv_data
.read_skip
<std::string
>();
79 recv_data
>> clientIndex
; // index
80 recv_data
.read_skip
<uint32
>(); // 0
82 sLog
.outDebug("Petitioner with GUID %u tried sell petition: name %s", GUID_LOPART(guidNPC
), name
.c_str());
85 Creature
*pCreature
= GetPlayer()->GetNPCIfCanInteractWith(guidNPC
,UNIT_NPC_FLAG_PETITIONER
);
88 sLog
.outDebug("WORLD: HandlePetitionBuyOpcode - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(guidNPC
));
93 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
94 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
99 if(pCreature
->isTabardDesigner())
101 // if tabard designer, then trying to buy a guild charter.
102 // do not let if already in guild.
103 if(_player
->GetGuildId())
106 charterid
= GUILD_CHARTER
;
107 cost
= GUILD_CHARTER_COST
;
112 // TODO: find correct opcode
113 if(_player
->getLevel() < sWorld
.getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL
))
115 SendNotification(LANG_ARENA_ONE_TOOLOW
, sWorld
.getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL
));
119 switch(clientIndex
) // arenaSlot+1 as received from client (1 from 3 case)
122 charterid
= ARENA_TEAM_CHARTER_2v2
;
123 cost
= ARENA_TEAM_CHARTER_2v2_COST
;
127 charterid
= ARENA_TEAM_CHARTER_3v3
;
128 cost
= ARENA_TEAM_CHARTER_3v3_COST
;
132 charterid
= ARENA_TEAM_CHARTER_5v5
;
133 cost
= ARENA_TEAM_CHARTER_5v5_COST
;
137 sLog
.outDebug("unknown selection at buy arena petition: %u", clientIndex
);
141 if(_player
->GetArenaTeamId(clientIndex
- 1)) // arenaSlot+1 as received from client
143 SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S
, name
, "", ERR_ALREADY_IN_ARENA_TEAM
);
150 if(sObjectMgr
.GetGuildByName(name
))
152 SendGuildCommandResult(GUILD_CREATE_S
, name
, ERR_GUILD_NAME_EXISTS_S
);
155 if(sObjectMgr
.IsReservedName(name
) || !ObjectMgr::IsValidCharterName(name
))
157 SendGuildCommandResult(GUILD_CREATE_S
, name
, ERR_GUILD_NAME_INVALID
);
163 if(sObjectMgr
.GetArenaTeamByName(name
))
165 SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S
, name
, "", ERR_ARENA_TEAM_NAME_EXISTS_S
);
168 if(sObjectMgr
.IsReservedName(name
) || !ObjectMgr::IsValidCharterName(name
))
170 SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S
, name
, "", ERR_ARENA_TEAM_NAME_INVALID
);
175 ItemPrototype
const *pProto
= ObjectMgr::GetItemPrototype(charterid
);
178 _player
->SendBuyError(BUY_ERR_CANT_FIND_ITEM
, NULL
, charterid
, 0);
182 if(_player
->GetMoney() < cost
)
183 { //player hasn't got enough money
184 _player
->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY
, pCreature
, charterid
, 0);
188 ItemPosCountVec dest
;
189 uint8 msg
= _player
->CanStoreNewItem(NULL_BAG
, NULL_SLOT
, dest
, charterid
, pProto
->BuyCount
);
190 if(msg
!= EQUIP_ERR_OK
)
192 _player
->SendBuyError(msg
, pCreature
, charterid
, 0);
196 _player
->ModifyMoney(-(int32
)cost
);
197 Item
*charter
= _player
->StoreNewItem(dest
, charterid
, true);
201 charter
->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1
, charter
->GetGUIDLow());
202 // ITEM_FIELD_ENCHANTMENT_1_1 is guild/arenateam id
203 // ITEM_FIELD_ENCHANTMENT_1_1+1 is current signatures count (showed on item)
204 charter
->SetState(ITEM_CHANGED
, _player
);
205 _player
->SendNewItem(charter
, 1, true, false);
207 // a petition is invalid, if both the owner and the type matches
208 // we checked above, if this player is in an arenateam, so this must be data corruption
209 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT petitionguid FROM petition WHERE ownerguid = '%u' AND type = '%u'", _player
->GetGUIDLow(), type
);
211 std::ostringstream ssInvalidPetitionGUIDs
;
217 Field
*fields
= result
->Fetch();
218 ssInvalidPetitionGUIDs
<< "'" << fields
[0].GetUInt32() << "' , ";
219 } while (result
->NextRow());
224 // delete petitions with the same guid as this one
225 ssInvalidPetitionGUIDs
<< "'" << charter
->GetGUIDLow() << "'";
227 sLog
.outDebug("Invalid petition GUIDs: %s", ssInvalidPetitionGUIDs
.str().c_str());
228 CharacterDatabase
.escape_string(name
);
229 CharacterDatabase
.BeginTransaction();
230 CharacterDatabase
.PExecute("DELETE FROM petition WHERE petitionguid IN ( %s )", ssInvalidPetitionGUIDs
.str().c_str());
231 CharacterDatabase
.PExecute("DELETE FROM petition_sign WHERE petitionguid IN ( %s )", ssInvalidPetitionGUIDs
.str().c_str());
232 CharacterDatabase
.PExecute("INSERT INTO petition (ownerguid, petitionguid, name, type) VALUES ('%u', '%u', '%s', '%u')",
233 _player
->GetGUIDLow(), charter
->GetGUIDLow(), name
.c_str(), type
);
234 CharacterDatabase
.CommitTransaction();
237 void WorldSession::HandlePetitionShowSignOpcode(WorldPacket
& recv_data
)
240 sLog
.outDebug("Received opcode CMSG_PETITION_SHOW_SIGNATURES");
241 //recv_data.hexlike();
245 recv_data
>> petitionguid
; // petition guid
247 // solve (possible) some strange compile problems with explicit use GUID_LOPART(petitionguid) at some GCC versions (wrong code optimization in compiler?)
248 uint32 petitionguid_low
= GUID_LOPART(petitionguid
);
250 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", petitionguid_low
);
253 sLog
.outError("any petition on server...");
256 Field
*fields
= result
->Fetch();
257 uint32 type
= fields
[0].GetUInt32();
260 // if guild petition and has guild => error, return;
261 if(type
== 9 && _player
->GetGuildId())
264 result
= CharacterDatabase
.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", petitionguid_low
);
266 // result==NULL also correct in case no sign yet
268 signs
= (uint8
)result
->GetRowCount();
270 sLog
.outDebug("CMSG_PETITION_SHOW_SIGNATURES petition entry: '%u'", petitionguid_low
);
272 WorldPacket
data(SMSG_PETITION_SHOW_SIGNATURES
, (8+8+4+1+signs
*12));
273 data
<< uint64(petitionguid
); // petition guid
274 data
<< uint64(_player
->GetGUID()); // owner guid
275 data
<< uint32(petitionguid_low
); // guild guid (in mangos always same as GUID_LOPART(petitionguid)
276 data
<< uint8(signs
); // sign's count
278 for(uint8 i
= 1; i
<= signs
; ++i
)
280 Field
*fields2
= result
->Fetch();
281 uint64 plguid
= fields2
[0].GetUInt64();
283 data
<< uint64(plguid
); // Player GUID
284 data
<< uint32(0); // there 0 ...
292 void WorldSession::HandlePetitionQueryOpcode(WorldPacket
& recv_data
)
294 sLog
.outDebug("Received opcode CMSG_PETITION_QUERY"); // ok
295 //recv_data.hexlike();
299 recv_data
>> guildguid
; // in mangos always same as GUID_LOPART(petitionguid)
300 recv_data
>> petitionguid
; // petition guid
301 sLog
.outDebug("CMSG_PETITION_QUERY Petition GUID %u Guild GUID %u", GUID_LOPART(petitionguid
), guildguid
);
303 SendPetitionQueryOpcode(petitionguid
);
306 void WorldSession::SendPetitionQueryOpcode(uint64 petitionguid
)
308 uint64 ownerguid
= 0;
310 std::string name
= "NO_NAME_FOR_GUID";
313 QueryResult
*result
= CharacterDatabase
.PQuery(
314 "SELECT ownerguid, name, "
315 " (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs, "
317 "FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid
), GUID_LOPART(petitionguid
));
321 Field
* fields
= result
->Fetch();
322 ownerguid
= MAKE_NEW_GUID(fields
[0].GetUInt32(), 0, HIGHGUID_PLAYER
);
323 name
= fields
[1].GetCppString();
324 signs
= fields
[2].GetUInt8();
325 type
= fields
[3].GetUInt32();
330 sLog
.outDebug("CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionguid
));
334 WorldPacket
data(SMSG_PETITION_QUERY_RESPONSE
, (4+8+name
.size()+1+1+4*12+2+10));
335 data
<< uint32(GUID_LOPART(petitionguid
)); // guild/team guid (in mangos always same as GUID_LOPART(petition guid)
336 data
<< uint64(ownerguid
); // charter owner guid
337 data
<< name
; // name (guild/arena team)
338 data
<< uint8(0); // some string
343 data
<< uint32(0); // bypass client - side limitation, a different value is needed here for each petition
347 data
<< uint32(type
-1);
348 data
<< uint32(type
-1);
349 data
<< uint32(type
); // bypass client - side limitation, a different value is needed here for each petition
351 data
<< uint32(0); // 5
352 data
<< uint32(0); // 6
353 data
<< uint32(0); // 7
354 data
<< uint32(0); // 8
355 data
<< uint16(0); // 9 2 bytes field
356 data
<< uint32(0); // 10
357 data
<< uint32(0); // 11
358 data
<< uint32(0); // 13 count of next strings?
360 for(int i
= 0; i
< 10; ++i
)
361 data
<< uint8(0); // some string
363 data
<< uint32(0); // 14
366 data
<< uint32(0); // 15 0 - guild, 1 - arena team
373 void WorldSession::HandlePetitionRenameOpcode(WorldPacket
& recv_data
)
375 sLog
.outDebug("Received opcode MSG_PETITION_RENAME"); // ok
376 //recv_data.hexlike();
382 recv_data
>> petitionguid
; // guid
383 recv_data
>> newname
; // new name
385 Item
*item
= _player
->GetItemByGuid(petitionguid
);
389 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid
));
393 Field
* fields
= result
->Fetch();
394 type
= fields
[0].GetUInt32();
399 sLog
.outDebug("CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionguid
));
405 if(sObjectMgr
.GetGuildByName(newname
))
407 SendGuildCommandResult(GUILD_CREATE_S
, newname
, ERR_GUILD_NAME_EXISTS_S
);
410 if(sObjectMgr
.IsReservedName(newname
) || !ObjectMgr::IsValidCharterName(newname
))
412 SendGuildCommandResult(GUILD_CREATE_S
, newname
, ERR_GUILD_NAME_INVALID
);
418 if(sObjectMgr
.GetArenaTeamByName(newname
))
420 SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S
, newname
, "", ERR_ARENA_TEAM_NAME_EXISTS_S
);
423 if(sObjectMgr
.IsReservedName(newname
) || !ObjectMgr::IsValidCharterName(newname
))
425 SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S
, newname
, "", ERR_ARENA_TEAM_NAME_INVALID
);
430 std::string db_newname
= newname
;
431 CharacterDatabase
.escape_string(db_newname
);
432 CharacterDatabase
.PExecute("UPDATE petition SET name = '%s' WHERE petitionguid = '%u'",
433 db_newname
.c_str(), GUID_LOPART(petitionguid
));
435 sLog
.outDebug("Petition (GUID: %u) renamed to '%s'", GUID_LOPART(petitionguid
), newname
.c_str());
437 WorldPacket
data(MSG_PETITION_RENAME
, (8+newname
.size()+1));
438 data
<< uint64(petitionguid
);
443 void WorldSession::HandlePetitionSignOpcode(WorldPacket
& recv_data
)
445 sLog
.outDebug("Received opcode CMSG_PETITION_SIGN"); // ok
446 //recv_data.hexlike();
451 recv_data
>> petitionguid
; // petition guid
454 QueryResult
*result
= CharacterDatabase
.PQuery(
456 " (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs, "
458 "FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid
), GUID_LOPART(petitionguid
));
462 sLog
.outError("any petition on server...");
466 fields
= result
->Fetch();
467 uint64 ownerguid
= MAKE_NEW_GUID(fields
[0].GetUInt32(), 0, HIGHGUID_PLAYER
);
468 uint8 signs
= fields
[1].GetUInt8();
469 uint32 type
= fields
[2].GetUInt32();
473 uint32 plguidlo
= _player
->GetGUIDLow();
474 if(GUID_LOPART(ownerguid
) == plguidlo
)
477 // not let enemies sign guild charter
478 if(!sWorld
.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GUILD
) && GetPlayer()->GetTeam() != sObjectMgr
.GetPlayerTeamByGUID(ownerguid
))
481 SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS
, "", "", ERR_ARENA_TEAM_NOT_ALLIED
);
483 SendGuildCommandResult(GUILD_CREATE_S
, "", ERR_GUILD_NOT_ALLIED
);
489 if(_player
->getLevel() < sWorld
.getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL
))
491 SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S
, "", _player
->GetName(), ERR_ARENA_TEAM_TARGET_TOO_LOW_S
);
495 uint8 slot
= ArenaTeam::GetSlotByType(type
);
496 if(slot
>= MAX_ARENA_SLOT
)
499 if(_player
->GetArenaTeamId(slot
))
501 SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS
, "", _player
->GetName(), ERR_ALREADY_IN_ARENA_TEAM_S
);
505 if(_player
->GetArenaTeamIdInvited())
507 SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS
, "", _player
->GetName(), ERR_ALREADY_INVITED_TO_ARENA_TEAM_S
);
513 if(_player
->GetGuildId())
515 SendGuildCommandResult(GUILD_INVITE_S
, _player
->GetName(), ERR_ALREADY_IN_GUILD_S
);
518 if(_player
->GetGuildIdInvited())
520 SendGuildCommandResult(GUILD_INVITE_S
, _player
->GetName(), ERR_ALREADY_INVITED_TO_GUILD_S
);
525 if(++signs
> type
) // client signs maximum
528 //client doesn't allow to sign petition two times by one character, but not check sign by another character from same account
529 //not allow sign another player from already sign player account
530 result
= CharacterDatabase
.PQuery("SELECT playerguid FROM petition_sign WHERE player_account = '%u' AND petitionguid = '%u'", GetAccountId(), GUID_LOPART(petitionguid
));
535 WorldPacket
data(SMSG_PETITION_SIGN_RESULTS
, (8+8+4));
536 data
<< uint64(petitionguid
);
537 data
<< uint64(_player
->GetGUID());
538 data
<< uint32(PETITION_SIGN_ALREADY_SIGNED
);
540 // close at signer side
543 // update for owner if online
544 if(Player
*owner
= sObjectMgr
.GetPlayer(ownerguid
))
545 owner
->GetSession()->SendPacket(&data
);
549 CharacterDatabase
.PExecute("INSERT INTO petition_sign (ownerguid,petitionguid, playerguid, player_account) VALUES ('%u', '%u', '%u','%u')", GUID_LOPART(ownerguid
),GUID_LOPART(petitionguid
), plguidlo
,GetAccountId());
551 sLog
.outDebug("PETITION SIGN: GUID %u by player: %s (GUID: %u Account: %u)", GUID_LOPART(petitionguid
), _player
->GetName(),plguidlo
,GetAccountId());
553 WorldPacket
data(SMSG_PETITION_SIGN_RESULTS
, (8+8+4));
554 data
<< uint64(petitionguid
);
555 data
<< uint64(_player
->GetGUID());
556 data
<< uint32(PETITION_SIGN_OK
);
558 // close at signer side
561 // update signs count on charter, required testing...
562 //Item *item = _player->GetItemByGuid(petitionguid));
564 // item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1+1, signs);
566 // update for owner if online
567 if(Player
*owner
= sObjectMgr
.GetPlayer(ownerguid
))
568 owner
->GetSession()->SendPacket(&data
);
571 void WorldSession::HandlePetitionDeclineOpcode(WorldPacket
& recv_data
)
573 sLog
.outDebug("Received opcode MSG_PETITION_DECLINE"); // ok
574 //recv_data.hexlike();
578 recv_data
>> petitionguid
; // petition guid
579 sLog
.outDebug("Petition %u declined by %u", GUID_LOPART(petitionguid
), _player
->GetGUIDLow());
581 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT ownerguid FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid
));
585 Field
*fields
= result
->Fetch();
586 ownerguid
= MAKE_NEW_GUID(fields
[0].GetUInt32(), 0, HIGHGUID_PLAYER
);
589 Player
*owner
= sObjectMgr
.GetPlayer(ownerguid
);
590 if(owner
) // petition owner online
592 WorldPacket
data(MSG_PETITION_DECLINE
, 8);
593 data
<< uint64(_player
->GetGUID());
594 owner
->GetSession()->SendPacket(&data
);
598 void WorldSession::HandleOfferPetitionOpcode(WorldPacket
& recv_data
)
600 sLog
.outDebug("Received opcode CMSG_OFFER_PETITION"); // ok
601 //recv_data.hexlike();
604 uint64 petitionguid
, plguid
;
607 recv_data
>> junk
; // this is not petition type!
608 recv_data
>> petitionguid
; // petition guid
609 recv_data
>> plguid
; // player guid
611 player
= ObjectAccessor::FindPlayer(plguid
);
615 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid
));
619 Field
*fields
= result
->Fetch();
620 type
= fields
[0].GetUInt32();
623 sLog
.outDebug("OFFER PETITION: type %u, GUID1 %u, to player id: %u", type
, GUID_LOPART(petitionguid
), GUID_LOPART(plguid
));
625 if (!sWorld
.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GUILD
) && GetPlayer()->GetTeam() != player
->GetTeam() )
628 SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS
, "", "", ERR_ARENA_TEAM_NOT_ALLIED
);
630 SendGuildCommandResult(GUILD_CREATE_S
, "", ERR_GUILD_NOT_ALLIED
);
636 if(player
->getLevel() < sWorld
.getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL
))
638 // player is too low level to join an arena team
639 SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S
, player
->GetName(), "", ERR_ARENA_TEAM_TARGET_TOO_LOW_S
);
643 uint8 slot
= ArenaTeam::GetSlotByType(type
);
644 if(slot
>= MAX_ARENA_SLOT
)
647 if(player
->GetArenaTeamId(slot
))
649 // player is already in an arena team
650 SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S
, player
->GetName(), "", ERR_ALREADY_IN_ARENA_TEAM_S
);
654 if(player
->GetArenaTeamIdInvited())
656 SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS
, "", _player
->GetName(), ERR_ALREADY_INVITED_TO_ARENA_TEAM_S
);
662 if(player
->GetGuildId())
664 SendGuildCommandResult(GUILD_INVITE_S
, _player
->GetName(), ERR_ALREADY_IN_GUILD_S
);
668 if(player
->GetGuildIdInvited())
670 SendGuildCommandResult(GUILD_INVITE_S
, _player
->GetName(), ERR_ALREADY_INVITED_TO_GUILD_S
);
675 result
= CharacterDatabase
.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid
));
676 // result==NULL also correct charter without signs
678 signs
= (uint8
)result
->GetRowCount();
680 WorldPacket
data(SMSG_PETITION_SHOW_SIGNATURES
, (8+8+4+signs
+signs
*12));
681 data
<< uint64(petitionguid
); // petition guid
682 data
<< uint64(_player
->GetGUID()); // owner guid
683 data
<< uint32(GUID_LOPART(petitionguid
)); // guild guid (in mangos always same as GUID_LOPART(petition guid)
684 data
<< uint8(signs
); // sign's count
686 for(uint8 i
= 1; i
<= signs
; ++i
)
688 Field
*fields2
= result
->Fetch();
689 plguid
= fields2
[0].GetUInt64();
691 data
<< uint64(plguid
); // Player GUID
692 data
<< uint32(0); // there 0 ...
698 player
->GetSession()->SendPacket(&data
);
701 void WorldSession::HandleTurnInPetitionOpcode(WorldPacket
& recv_data
)
703 sLog
.outDebug("Received opcode CMSG_TURN_IN_PETITION"); // ok
704 //recv_data.hexlike();
713 recv_data
>> petitionguid
;
715 sLog
.outDebug("Petition %u turned in by %u", GUID_LOPART(petitionguid
), _player
->GetGUIDLow());
718 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT ownerguid, name, type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid
));
721 Field
*fields
= result
->Fetch();
722 ownerguidlo
= fields
[0].GetUInt32();
723 name
= fields
[1].GetCppString();
724 type
= fields
[2].GetUInt32();
729 sLog
.outError("petition table has broken data!");
735 if(_player
->GetGuildId())
737 data
.Initialize(SMSG_TURN_IN_PETITION_RESULTS
, 4);
738 data
<< uint32(PETITION_TURN_ALREADY_IN_GUILD
); // already in guild
739 _player
->GetSession()->SendPacket(&data
);
745 uint8 slot
= ArenaTeam::GetSlotByType(type
);
746 if(slot
>= MAX_ARENA_SLOT
)
749 if(_player
->GetArenaTeamId(slot
))
751 //data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4);
752 //data << (uint32)PETITION_TURN_ALREADY_IN_GUILD; // already in guild
753 //_player->GetSession()->SendPacket(&data);
754 SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S
, name
, "", ERR_ALREADY_IN_ARENA_TEAM
);
759 if(_player
->GetGUIDLow() != ownerguidlo
)
764 result
= CharacterDatabase
.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid
));
766 signs
= (uint8
)result
->GetRowCount();
771 //if(signs < sWorld.getConfig(CONFIG_UINT32_MIN_PETITION_SIGNS))
773 count
= sWorld
.getConfig(CONFIG_UINT32_MIN_PETITION_SIGNS
);
778 data
.Initialize(SMSG_TURN_IN_PETITION_RESULTS
, 4);
779 data
<< uint32(PETITION_TURN_NEED_MORE_SIGNATURES
); // need more signatures...
787 if(sObjectMgr
.GetGuildByName(name
))
789 SendGuildCommandResult(GUILD_CREATE_S
, name
, ERR_GUILD_NAME_EXISTS_S
);
796 if(sObjectMgr
.GetArenaTeamByName(name
))
798 SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S
, name
, "", ERR_ARENA_TEAM_NAME_EXISTS_S
);
804 // and at last charter item check
805 Item
*item
= _player
->GetItemByGuid(petitionguid
);
814 // delete charter item
815 _player
->DestroyItem(item
->GetBagSlot(), item
->GetSlot(), true);
817 if(type
== 9) // create guild
819 Guild
* guild
= new Guild
;
820 if(!guild
->Create(_player
, name
))
827 // register guild and add guildmaster
828 sObjectMgr
.AddGuild(guild
);
831 for(uint8 i
= 0; i
< signs
; ++i
)
833 Field
* fields
= result
->Fetch();
834 guild
->AddMember(fields
[0].GetUInt64(), guild
->GetLowestRank());
838 else // or arena team
840 ArenaTeam
* at
= new ArenaTeam
;
841 if(!at
->Create(_player
->GetGUID(), type
, name
))
843 sLog
.outError("PetitionsHandler: arena team create failed.");
849 uint32 icon
, iconcolor
, border
, bordercolor
, backgroud
;
850 recv_data
>> backgroud
>> icon
>> iconcolor
>> border
>> bordercolor
;
852 at
->SetEmblem(backgroud
, icon
, iconcolor
, border
, bordercolor
);
854 // register team and add captain
855 sObjectMgr
.AddArenaTeam(at
);
856 sLog
.outDebug("PetitonsHandler: arena team added to objmrg");
859 for(uint8 i
= 0; i
< signs
; ++i
)
861 Field
* fields
= result
->Fetch();
862 uint64 memberGUID
= fields
[0].GetUInt64();
863 sLog
.outDebug("PetitionsHandler: adding arena member %u", GUID_LOPART(memberGUID
));
864 at
->AddMember(memberGUID
);
871 CharacterDatabase
.BeginTransaction();
872 CharacterDatabase
.PExecute("DELETE FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid
));
873 CharacterDatabase
.PExecute("DELETE FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid
));
874 CharacterDatabase
.CommitTransaction();
877 sLog
.outDebug("TURN IN PETITION GUID %u", GUID_LOPART(petitionguid
));
879 data
.Initialize(SMSG_TURN_IN_PETITION_RESULTS
, 4);
880 data
<< uint32(PETITION_TURN_OK
);
884 void WorldSession::HandlePetitionShowListOpcode(WorldPacket
& recv_data
)
886 sLog
.outDebug("Received CMSG_PETITION_SHOWLIST"); // ok
887 //recv_data.hexlike();
892 SendPetitionShowList(guid
);
895 void WorldSession::SendPetitionShowList(uint64 guid
)
897 Creature
*pCreature
= GetPlayer()->GetNPCIfCanInteractWith(guid
, UNIT_NPC_FLAG_PETITIONER
);
900 sLog
.outDebug("WORLD: HandlePetitionShowListOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid
)));
905 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
906 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
909 if(pCreature
->isTabardDesigner())
914 WorldPacket
data(SMSG_PETITION_SHOWLIST
, 8+1+4*6);
915 data
<< uint64(guid
); // npc guid
916 data
<< uint8(count
); // count
919 data
<< uint32(1); // index
920 data
<< uint32(GUILD_CHARTER
); // charter entry
921 data
<< uint32(CHARTER_DISPLAY_ID
); // charter display id
922 data
<< uint32(GUILD_CHARTER_COST
); // charter cost
923 data
<< uint32(0); // unknown
924 data
<< uint32(9); // required signs?
929 data
<< uint32(1); // index
930 data
<< uint32(ARENA_TEAM_CHARTER_2v2
); // charter entry
931 data
<< uint32(CHARTER_DISPLAY_ID
); // charter display id
932 data
<< uint32(ARENA_TEAM_CHARTER_2v2_COST
); // charter cost
933 data
<< uint32(2); // unknown
934 data
<< uint32(2); // required signs?
936 data
<< uint32(2); // index
937 data
<< uint32(ARENA_TEAM_CHARTER_3v3
); // charter entry
938 data
<< uint32(CHARTER_DISPLAY_ID
); // charter display id
939 data
<< uint32(ARENA_TEAM_CHARTER_3v3_COST
); // charter cost
940 data
<< uint32(3); // unknown
941 data
<< uint32(3); // required signs?
943 data
<< uint32(3); // index
944 data
<< uint32(ARENA_TEAM_CHARTER_5v5
); // charter entry
945 data
<< uint32(CHARTER_DISPLAY_ID
); // charter display id
946 data
<< uint32(ARENA_TEAM_CHARTER_5v5_COST
); // charter cost
947 data
<< uint32(5); // unknown
948 data
<< uint32(5); // required signs?
950 //for(uint8 i = 0; i < count; ++i)
952 // data << uint32(i); // index
953 // data << uint32(GUILD_CHARTER); // charter entry
954 // data << uint32(CHARTER_DISPLAY_ID); // charter display id
955 // data << uint32(GUILD_CHARTER_COST+i); // charter cost
956 // data << uint32(0); // unknown
957 // data << uint32(9); // required signs?
960 sLog
.outDebug("Sent SMSG_PETITION_SHOWLIST");