2 * Copyright (C) 2005-2009 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 "ObjectDefines.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
49 void WorldSession::HandlePetitionBuyOpcode(WorldPacket
& recv_data
)
51 sLog
.outDebug("Received opcode CMSG_PETITION_BUY");
55 uint32 clientIndex
; // 1 for guild and arenaslot+1 for arenas in client
58 recv_data
>> guidNPC
; // NPC GUID
59 recv_data
.read_skip
<uint32
>(); // 0
60 recv_data
.read_skip
<uint64
>(); // 0
61 recv_data
>> name
; // name
62 recv_data
.read_skip
<std::string
>(); // some string
63 recv_data
.read_skip
<uint32
>(); // 0
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
<uint16
>(); // 0
71 recv_data
.read_skip
<uint32
>(); // 0
72 recv_data
.read_skip
<uint32
>(); // 0
73 recv_data
.read_skip
<uint32
>(); // 0
75 for (int i
= 0; i
< 10; ++i
)
76 recv_data
.read_skip
<std::string
>();
78 recv_data
>> clientIndex
; // index
79 recv_data
.read_skip
<uint32
>(); // 0
81 sLog
.outDebug("Petitioner with GUID %u tried sell petition: name %s", GUID_LOPART(guidNPC
), name
.c_str());
84 Creature
*pCreature
= GetPlayer()->GetNPCIfCanInteractWith(guidNPC
,UNIT_NPC_FLAG_PETITIONER
);
87 sLog
.outDebug("WORLD: HandlePetitionBuyOpcode - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(guidNPC
));
92 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
93 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
98 if(pCreature
->isTabardDesigner())
100 // if tabard designer, then trying to buy a guild charter.
101 // do not let if already in guild.
102 if(_player
->GetGuildId())
105 charterid
= GUILD_CHARTER
;
106 cost
= GUILD_CHARTER_COST
;
111 // TODO: find correct opcode
112 if(_player
->getLevel() < sWorld
.getConfig(CONFIG_MAX_PLAYER_LEVEL
))
114 SendNotification(LANG_ARENA_ONE_TOOLOW
, sWorld
.getConfig(CONFIG_MAX_PLAYER_LEVEL
));
118 switch(clientIndex
) // arenaSlot+1 as received from client (1 from 3 case)
121 charterid
= ARENA_TEAM_CHARTER_2v2
;
122 cost
= ARENA_TEAM_CHARTER_2v2_COST
;
126 charterid
= ARENA_TEAM_CHARTER_3v3
;
127 cost
= ARENA_TEAM_CHARTER_3v3_COST
;
131 charterid
= ARENA_TEAM_CHARTER_5v5
;
132 cost
= ARENA_TEAM_CHARTER_5v5_COST
;
136 sLog
.outDebug("unknown selection at buy arena petition: %u", clientIndex
);
140 if(_player
->GetArenaTeamId(clientIndex
- 1)) // arenaSlot+1 as received from client
142 SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S
, name
, "", ERR_ALREADY_IN_ARENA_TEAM
);
149 if(sObjectMgr
.GetGuildByName(name
))
151 SendGuildCommandResult(GUILD_CREATE_S
, name
, GUILD_NAME_EXISTS
);
154 if(sObjectMgr
.IsReservedName(name
) || !ObjectMgr::IsValidCharterName(name
))
156 SendGuildCommandResult(GUILD_CREATE_S
, name
, GUILD_NAME_INVALID
);
162 if(sObjectMgr
.GetArenaTeamByName(name
))
164 SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S
, name
, "", ERR_ARENA_TEAM_NAME_EXISTS_S
);
167 if(sObjectMgr
.IsReservedName(name
) || !ObjectMgr::IsValidCharterName(name
))
169 SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S
, name
, "", ERR_ARENA_TEAM_NAME_INVALID
);
174 ItemPrototype
const *pProto
= ObjectMgr::GetItemPrototype(charterid
);
177 _player
->SendBuyError(BUY_ERR_CANT_FIND_ITEM
, NULL
, charterid
, 0);
181 if(_player
->GetMoney() < cost
)
182 { //player hasn't got enough money
183 _player
->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY
, pCreature
, charterid
, 0);
187 ItemPosCountVec dest
;
188 uint8 msg
= _player
->CanStoreNewItem(NULL_BAG
, NULL_SLOT
, dest
, charterid
, pProto
->BuyCount
);
189 if(msg
!= EQUIP_ERR_OK
)
191 _player
->SendBuyError(msg
, pCreature
, charterid
, 0);
195 _player
->ModifyMoney(-(int32
)cost
);
196 Item
*charter
= _player
->StoreNewItem(dest
, charterid
, true);
200 charter
->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1
, charter
->GetGUIDLow());
201 // ITEM_FIELD_ENCHANTMENT_1_1 is guild/arenateam id
202 // ITEM_FIELD_ENCHANTMENT_1_1+1 is current signatures count (showed on item)
203 charter
->SetState(ITEM_CHANGED
, _player
);
204 _player
->SendNewItem(charter
, 1, true, false);
206 // a petition is invalid, if both the owner and the type matches
207 // we checked above, if this player is in an arenateam, so this must be
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
= 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
<< petitionguid
; // petition guid
274 data
<< _player
->GetGUID(); // owner guid
275 data
<< petitionguid_low
; // guild guid (in mangos always same as GUID_LOPART(petitionguid)
276 data
<< 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
<< 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
, GUILD_NAME_EXISTS
);
410 if(sObjectMgr
.IsReservedName(newname
) || !ObjectMgr::IsValidCharterName(newname
))
412 SendGuildCommandResult(GUILD_CREATE_S
, newname
, 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());
436 WorldPacket
data(MSG_PETITION_RENAME
, (8+newname
.size()+1));
437 data
<< petitionguid
;
442 void WorldSession::HandlePetitionSignOpcode(WorldPacket
& recv_data
)
444 sLog
.outDebug("Received opcode CMSG_PETITION_SIGN"); // ok
445 //recv_data.hexlike();
450 recv_data
>> petitionguid
; // petition guid
453 QueryResult
*result
= CharacterDatabase
.PQuery(
455 " (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs, "
457 "FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid
), GUID_LOPART(petitionguid
));
461 sLog
.outError("any petition on server...");
465 fields
= result
->Fetch();
466 uint64 ownerguid
= MAKE_NEW_GUID(fields
[0].GetUInt32(), 0, HIGHGUID_PLAYER
);
467 uint8 signs
= fields
[1].GetUInt8();
468 uint32 type
= fields
[2].GetUInt32();
472 uint32 plguidlo
= _player
->GetGUIDLow();
473 if(GUID_LOPART(ownerguid
) == plguidlo
)
476 // not let enemies sign guild charter
477 if(!sWorld
.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD
) && GetPlayer()->GetTeam() != sObjectMgr
.GetPlayerTeamByGUID(ownerguid
))
480 SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS
, "", "", ERR_ARENA_TEAM_NOT_ALLIED
);
482 SendGuildCommandResult(GUILD_CREATE_S
, "", GUILD_NOT_ALLIED
);
488 if(_player
->getLevel() < sWorld
.getConfig(CONFIG_MAX_PLAYER_LEVEL
))
490 SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S
, "", _player
->GetName(), ERR_ARENA_TEAM_PLAYER_TO_LOW
);
494 uint8 slot
= ArenaTeam::GetSlotByType(type
);
495 if(slot
>= MAX_ARENA_SLOT
)
498 if(_player
->GetArenaTeamId(slot
))
500 SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS
, "", _player
->GetName(), ERR_ALREADY_IN_ARENA_TEAM_S
);
504 if(_player
->GetArenaTeamIdInvited())
506 SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS
, "", _player
->GetName(), ERR_ALREADY_INVITED_TO_ARENA_TEAM_S
);
512 if(_player
->GetGuildId())
514 SendGuildCommandResult(GUILD_INVITE_S
, _player
->GetName(), ALREADY_IN_GUILD
);
517 if(_player
->GetGuildIdInvited())
519 SendGuildCommandResult(GUILD_INVITE_S
, _player
->GetName(), ALREADY_INVITED_TO_GUILD
);
524 if(++signs
> type
) // client signs maximum
527 //client doesn't allow to sign petition two times by one character, but not check sign by another character from same account
528 //not allow sign another player from already sign player account
529 result
= CharacterDatabase
.PQuery("SELECT playerguid FROM petition_sign WHERE player_account = '%u' AND petitionguid = '%u'", GetAccountId(), GUID_LOPART(petitionguid
));
534 WorldPacket
data(SMSG_PETITION_SIGN_RESULTS
, (8+8+4));
535 data
<< petitionguid
;
536 data
<< _player
->GetGUID();
537 data
<< (uint32
)PETITION_SIGN_ALREADY_SIGNED
;
539 // close at signer side
542 // update for owner if online
543 if(Player
*owner
= sObjectMgr
.GetPlayer(ownerguid
))
544 owner
->GetSession()->SendPacket(&data
);
548 CharacterDatabase
.PExecute("INSERT INTO petition_sign (ownerguid,petitionguid, playerguid, player_account) VALUES ('%u', '%u', '%u','%u')", GUID_LOPART(ownerguid
),GUID_LOPART(petitionguid
), plguidlo
,GetAccountId());
550 sLog
.outDebug("PETITION SIGN: GUID %u by player: %s (GUID: %u Account: %u)", GUID_LOPART(petitionguid
), _player
->GetName(),plguidlo
,GetAccountId());
552 WorldPacket
data(SMSG_PETITION_SIGN_RESULTS
, (8+8+4));
553 data
<< petitionguid
;
554 data
<< _player
->GetGUID();
555 data
<< (uint32
)PETITION_SIGN_OK
;
557 // close at signer side
560 // update signs count on charter, required testing...
561 //Item *item = _player->GetItemByGuid(petitionguid));
563 // item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1+1, signs);
565 // update for owner if online
566 if(Player
*owner
= sObjectMgr
.GetPlayer(ownerguid
))
567 owner
->GetSession()->SendPacket(&data
);
570 void WorldSession::HandlePetitionDeclineOpcode(WorldPacket
& recv_data
)
572 sLog
.outDebug("Received opcode MSG_PETITION_DECLINE"); // ok
573 //recv_data.hexlike();
577 recv_data
>> petitionguid
; // petition guid
578 sLog
.outDebug("Petition %u declined by %u", GUID_LOPART(petitionguid
), _player
->GetGUIDLow());
580 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT ownerguid FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid
));
584 Field
*fields
= result
->Fetch();
585 ownerguid
= MAKE_NEW_GUID(fields
[0].GetUInt32(), 0, HIGHGUID_PLAYER
);
588 Player
*owner
= sObjectMgr
.GetPlayer(ownerguid
);
589 if(owner
) // petition owner online
591 WorldPacket
data(MSG_PETITION_DECLINE
, 8);
592 data
<< _player
->GetGUID();
593 owner
->GetSession()->SendPacket(&data
);
597 void WorldSession::HandleOfferPetitionOpcode(WorldPacket
& recv_data
)
599 sLog
.outDebug("Received opcode CMSG_OFFER_PETITION"); // ok
600 //recv_data.hexlike();
603 uint64 petitionguid
, plguid
;
606 recv_data
>> junk
; // this is not petition type!
607 recv_data
>> petitionguid
; // petition guid
608 recv_data
>> plguid
; // player guid
610 player
= ObjectAccessor::FindPlayer(plguid
);
614 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid
));
618 Field
*fields
= result
->Fetch();
619 type
= fields
[0].GetUInt32();
622 sLog
.outDebug("OFFER PETITION: type %u, GUID1 %u, to player id: %u", type
, GUID_LOPART(petitionguid
), GUID_LOPART(plguid
));
624 if (!sWorld
.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD
) && GetPlayer()->GetTeam() != player
->GetTeam() )
627 SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS
, "", "", ERR_ARENA_TEAM_NOT_ALLIED
);
629 SendGuildCommandResult(GUILD_CREATE_S
, "", GUILD_NOT_ALLIED
);
635 if(player
->getLevel() < sWorld
.getConfig(CONFIG_MAX_PLAYER_LEVEL
))
637 // player is too low level to join an arena team
638 SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S
, player
->GetName(), "", ERR_ARENA_TEAM_PLAYER_TO_LOW
);
642 uint8 slot
= ArenaTeam::GetSlotByType(type
);
643 if(slot
>= MAX_ARENA_SLOT
)
646 if(player
->GetArenaTeamId(slot
))
648 // player is already in an arena team
649 SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S
, player
->GetName(), "", ERR_ALREADY_IN_ARENA_TEAM_S
);
653 if(player
->GetArenaTeamIdInvited())
655 SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS
, "", _player
->GetName(), ERR_ALREADY_INVITED_TO_ARENA_TEAM_S
);
661 if(player
->GetGuildId())
663 SendGuildCommandResult(GUILD_INVITE_S
, _player
->GetName(), ALREADY_IN_GUILD
);
667 if(player
->GetGuildIdInvited())
669 SendGuildCommandResult(GUILD_INVITE_S
, _player
->GetName(), ALREADY_INVITED_TO_GUILD
);
674 result
= CharacterDatabase
.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid
));
675 // result==NULL also correct charter without signs
677 signs
= result
->GetRowCount();
679 WorldPacket
data(SMSG_PETITION_SHOW_SIGNATURES
, (8+8+4+signs
+signs
*12));
680 data
<< petitionguid
; // petition guid
681 data
<< _player
->GetGUID(); // owner guid
682 data
<< GUID_LOPART(petitionguid
); // guild guid (in mangos always same as GUID_LOPART(petition guid)
683 data
<< signs
; // sign's count
685 for(uint8 i
= 1; i
<= signs
; ++i
)
687 Field
*fields2
= result
->Fetch();
688 plguid
= fields2
[0].GetUInt64();
690 data
<< plguid
; // Player GUID
691 data
<< (uint32
)0; // there 0 ...
697 player
->GetSession()->SendPacket(&data
);
700 void WorldSession::HandleTurnInPetitionOpcode(WorldPacket
& recv_data
)
702 sLog
.outDebug("Received opcode CMSG_TURN_IN_PETITION"); // ok
703 //recv_data.hexlike();
712 recv_data
>> petitionguid
;
714 sLog
.outDebug("Petition %u turned in by %u", GUID_LOPART(petitionguid
), _player
->GetGUIDLow());
717 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT ownerguid, name, type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid
));
720 Field
*fields
= result
->Fetch();
721 ownerguidlo
= fields
[0].GetUInt32();
722 name
= fields
[1].GetCppString();
723 type
= fields
[2].GetUInt32();
728 sLog
.outError("petition table has broken data!");
734 if(_player
->GetGuildId())
736 data
.Initialize(SMSG_TURN_IN_PETITION_RESULTS
, 4);
737 data
<< (uint32
)PETITION_TURN_ALREADY_IN_GUILD
; // already in guild
738 _player
->GetSession()->SendPacket(&data
);
744 uint8 slot
= ArenaTeam::GetSlotByType(type
);
745 if(slot
>= MAX_ARENA_SLOT
)
748 if(_player
->GetArenaTeamId(slot
))
750 //data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4);
751 //data << (uint32)PETITION_TURN_ALREADY_IN_GUILD; // already in guild
752 //_player->GetSession()->SendPacket(&data);
753 SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S
, name
, "", ERR_ALREADY_IN_ARENA_TEAM
);
758 if(_player
->GetGUIDLow() != ownerguidlo
)
763 result
= CharacterDatabase
.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid
));
765 signs
= result
->GetRowCount();
770 //if(signs < sWorld.getConfig(CONFIG_MIN_PETITION_SIGNS))
772 count
= sWorld
.getConfig(CONFIG_MIN_PETITION_SIGNS
);
777 data
.Initialize(SMSG_TURN_IN_PETITION_RESULTS
, 4);
778 data
<< (uint32
)PETITION_TURN_NEED_MORE_SIGNATURES
; // need more signatures...
786 if(sObjectMgr
.GetGuildByName(name
))
788 SendGuildCommandResult(GUILD_CREATE_S
, name
, GUILD_NAME_EXISTS
);
795 if(sObjectMgr
.GetArenaTeamByName(name
))
797 SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S
, name
, "", ERR_ARENA_TEAM_NAME_EXISTS_S
);
803 // and at last charter item check
804 Item
*item
= _player
->GetItemByGuid(petitionguid
);
813 // delete charter item
814 _player
->DestroyItem(item
->GetBagSlot(),item
->GetSlot(), true);
816 if(type
== 9) // create guild
818 Guild
* guild
= new Guild
;
819 if(!guild
->Create(_player
, name
))
826 // register guild and add guildmaster
827 sObjectMgr
.AddGuild(guild
);
830 for(uint8 i
= 0; i
< signs
; ++i
)
832 Field
* fields
= result
->Fetch();
833 guild
->AddMember(fields
[0].GetUInt64(), guild
->GetLowestRank());
837 else // or arena team
839 ArenaTeam
* at
= new ArenaTeam
;
840 if(!at
->Create(_player
->GetGUID(), type
, name
))
842 sLog
.outError("PetitionsHandler: arena team create failed.");
848 uint32 icon
, iconcolor
, border
, bordercolor
, backgroud
;
849 recv_data
>> backgroud
>> icon
>> iconcolor
>> border
>> bordercolor
;
851 at
->SetEmblem(backgroud
, icon
, iconcolor
, border
, bordercolor
);
853 // register team and add captain
854 sObjectMgr
.AddArenaTeam(at
);
855 sLog
.outDebug("PetitonsHandler: arena team added to objmrg");
858 for(uint8 i
= 0; i
< signs
; ++i
)
860 Field
* fields
= result
->Fetch();
861 uint64 memberGUID
= fields
[0].GetUInt64();
862 sLog
.outDebug("PetitionsHandler: adding arena member %u", GUID_LOPART(memberGUID
));
863 at
->AddMember(memberGUID
);
870 CharacterDatabase
.BeginTransaction();
871 CharacterDatabase
.PExecute("DELETE FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid
));
872 CharacterDatabase
.PExecute("DELETE FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid
));
873 CharacterDatabase
.CommitTransaction();
876 sLog
.outDebug("TURN IN PETITION GUID %u", GUID_LOPART(petitionguid
));
878 data
.Initialize(SMSG_TURN_IN_PETITION_RESULTS
, 4);
879 data
<< (uint32
)PETITION_TURN_OK
;
883 void WorldSession::HandlePetitionShowListOpcode(WorldPacket
& recv_data
)
885 sLog
.outDebug("Received CMSG_PETITION_SHOWLIST"); // ok
886 //recv_data.hexlike();
891 SendPetitionShowList(guid
);
894 void WorldSession::SendPetitionShowList(uint64 guid
)
896 Creature
*pCreature
= GetPlayer()->GetNPCIfCanInteractWith(guid
, UNIT_NPC_FLAG_PETITIONER
);
899 sLog
.outDebug("WORLD: HandlePetitionShowListOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid
)));
904 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
905 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
908 if(pCreature
->isTabardDesigner())
913 WorldPacket
data(SMSG_PETITION_SHOWLIST
, 8+1+4*6);
914 data
<< guid
; // npc guid
915 data
<< count
; // count
918 data
<< uint32(1); // index
919 data
<< uint32(GUILD_CHARTER
); // charter entry
920 data
<< uint32(16161); // charter display id
921 data
<< uint32(GUILD_CHARTER_COST
); // charter cost
922 data
<< uint32(0); // unknown
923 data
<< uint32(9); // required signs?
928 data
<< uint32(1); // index
929 data
<< uint32(ARENA_TEAM_CHARTER_2v2
); // charter entry
930 data
<< uint32(16161); // charter display id
931 data
<< uint32(ARENA_TEAM_CHARTER_2v2_COST
); // charter cost
932 data
<< uint32(2); // unknown
933 data
<< uint32(2); // required signs?
935 data
<< uint32(2); // index
936 data
<< uint32(ARENA_TEAM_CHARTER_3v3
); // charter entry
937 data
<< uint32(16161); // charter display id
938 data
<< uint32(ARENA_TEAM_CHARTER_3v3_COST
); // charter cost
939 data
<< uint32(3); // unknown
940 data
<< uint32(3); // required signs?
942 data
<< uint32(3); // index
943 data
<< uint32(ARENA_TEAM_CHARTER_5v5
); // charter entry
944 data
<< uint32(16161); // charter display id
945 data
<< uint32(ARENA_TEAM_CHARTER_5v5_COST
); // charter cost
946 data
<< uint32(5); // unknown
947 data
<< uint32(5); // required signs?
949 //for(uint8 i = 0; i < count; ++i)
951 // data << uint32(i); // index
952 // data << uint32(GUILD_CHARTER); // charter entry
953 // data << uint32(16161); // charter display id
954 // data << uint32(GUILD_CHARTER_COST+i); // charter cost
955 // data << uint32(0); // unknown
956 // data << uint32(9); // required signs?
959 sLog
.outDebug("Sent SMSG_PETITION_SHOWLIST");