[8483] Implement glyph 43361.
[getmangos.git] / src / game / GuildHandler.cpp
blob90741d3af4f572fe52215b50902dd4aaa5e42f3a
1 /*
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
19 #include "Common.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 "GossipDef.h"
28 #include "SocialMgr.h"
30 void WorldSession::HandleGuildQueryOpcode(WorldPacket& recvPacket)
32 uint32 guildId;
33 Guild *guild;
35 //sLog.outDebug("WORLD: Received CMSG_GUILD_QUERY");
37 recvPacket >> guildId;
39 guild = objmgr.GetGuildById(guildId);
40 if(!guild)
42 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
43 return;
46 guild->Query(this);
49 void WorldSession::HandleGuildCreateOpcode(WorldPacket& recvPacket)
51 std::string gname;
53 //sLog.outDebug("WORLD: Received CMSG_GUILD_CREATE");
55 recvPacket >> gname;
57 if(GetPlayer()->GetGuildId())
58 return;
60 Guild *guild = new Guild;
61 if(!guild->Create(GetPlayer(),gname))
63 delete guild;
64 return;
67 objmgr.AddGuild(guild);
70 void WorldSession::HandleGuildInviteOpcode(WorldPacket& recvPacket)
72 std::string Invitedname, plname;
74 //sLog.outDebug("WORLD: Received CMSG_GUILD_INVITE");
76 Player * player = NULL;
78 recvPacket >> Invitedname;
80 if(normalizePlayerName(Invitedname))
81 player = ObjectAccessor::Instance().FindPlayerByName(Invitedname.c_str());
83 if(!player)
85 SendGuildCommandResult(GUILD_INVITE_S, Invitedname, GUILD_PLAYER_NOT_FOUND);
86 return;
89 Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
90 if(!guild)
92 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
93 return;
96 // OK result but not send invite
97 if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
98 return;
100 // not let enemies sign guild charter
101 if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != GetPlayer()->GetTeam())
103 SendGuildCommandResult(GUILD_INVITE_S, Invitedname, GUILD_NOT_ALLIED);
104 return;
107 if(player->GetGuildId())
109 plname = player->GetName();
110 SendGuildCommandResult(GUILD_INVITE_S, plname, ALREADY_IN_GUILD);
111 return;
114 if(player->GetGuildIdInvited())
116 plname = player->GetName();
117 SendGuildCommandResult(GUILD_INVITE_S, plname, ALREADY_INVITED_TO_GUILD);
118 return;
121 if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_INVITE))
123 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
124 return;
127 sLog.outDebug("Player %s Invited %s to Join his Guild", GetPlayer()->GetName(), Invitedname.c_str());
129 player->SetGuildIdInvited(GetPlayer()->GetGuildId());
130 // Put record into guildlog
131 guild->LogGuildEvent(GUILD_EVENT_LOG_INVITE_PLAYER, GetPlayer()->GetGUIDLow(), player->GetGUIDLow(), 0);
133 WorldPacket data(SMSG_GUILD_INVITE, (8+10)); // guess size
134 data << GetPlayer()->GetName();
135 data << guild->GetName();
136 player->GetSession()->SendPacket(&data);
138 //sLog.outDebug("WORLD: Sent (SMSG_GUILD_INVITE)");
141 void WorldSession::HandleGuildRemoveOpcode(WorldPacket& recvPacket)
143 std::string plName;
145 //sLog.outDebug("WORLD: Received CMSG_GUILD_REMOVE");
147 recvPacket >> plName;
149 if(!normalizePlayerName(plName))
150 return;
152 Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
153 if(!guild)
155 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
156 return;
159 if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_REMOVE))
161 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
162 return;
165 uint64 plGuid;
166 MemberSlot* slot = guild->GetMemberSlot(plName, plGuid);
167 if(!slot)
169 SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S);
170 return;
173 if(slot->RankId == GR_GUILDMASTER)
175 SendGuildCommandResult(GUILD_QUIT_S, "", GUILD_LEADER_LEAVE);
176 return;
179 //do not allow to kick player with same or higher rights
180 if(GetPlayer()->GetRank() >= slot->RankId)
182 SendGuildCommandResult(GUILD_QUIT_S, plName, GUILD_RANK_TOO_HIGH_S);
183 return;
186 guild->DelMember(plGuid);
187 // Put record into guildlog
188 guild->LogGuildEvent(GUILD_EVENT_LOG_UNINVITE_PLAYER, GetPlayer()->GetGUIDLow(), GUID_LOPART(plGuid), 0);
190 WorldPacket data(SMSG_GUILD_EVENT, (2+20)); // guess size
191 data << (uint8)GE_REMOVED;
192 data << (uint8)2; // strings count
193 data << plName;
194 data << GetPlayer()->GetName();
195 guild->BroadcastPacket(&data);
198 void WorldSession::HandleGuildAcceptOpcode(WorldPacket& /*recvPacket*/)
200 Guild *guild;
201 Player *player = GetPlayer();
203 //sLog.outDebug("WORLD: Received CMSG_GUILD_ACCEPT");
205 guild = objmgr.GetGuildById(player->GetGuildIdInvited());
206 if(!guild || player->GetGuildId())
207 return;
209 // not let enemies sign guild charter
210 if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != objmgr.GetPlayerTeamByGUID(guild->GetLeader()))
211 return;
213 if(!guild->AddMember(GetPlayer()->GetGUID(),guild->GetLowestRank()))
214 return;
215 // Put record into guildlog
216 guild->LogGuildEvent(GUILD_EVENT_LOG_JOIN_GUILD, GetPlayer()->GetGUIDLow(), 0, 0);
218 WorldPacket data(SMSG_GUILD_EVENT, (2+10)); // guess size
219 data << (uint8)GE_JOINED;
220 data << (uint8)1; // strings count
221 data << player->GetName();
222 guild->BroadcastPacket(&data);
224 //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)");
227 void WorldSession::HandleGuildDeclineOpcode(WorldPacket& /*recvPacket*/)
229 //sLog.outDebug("WORLD: Received CMSG_GUILD_DECLINE");
231 GetPlayer()->SetGuildIdInvited(0);
232 GetPlayer()->SetInGuild(0);
235 void WorldSession::HandleGuildInfoOpcode(WorldPacket& /*recvPacket*/)
237 Guild *guild;
238 //sLog.outDebug("WORLD: Received CMSG_GUILD_INFO");
240 guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
241 if(!guild)
243 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
244 return;
247 WorldPacket data(SMSG_GUILD_INFO, (5*4 + guild->GetName().size() + 1));
248 data << guild->GetName();
249 data << guild->GetCreatedDay();
250 data << guild->GetCreatedMonth();
251 data << guild->GetCreatedYear();
252 data << guild->GetMemberSize();
253 data << guild->GetMemberSize();
255 SendPacket(&data);
258 void WorldSession::HandleGuildRosterOpcode(WorldPacket& /*recvPacket*/)
260 //sLog.outDebug("WORLD: Received CMSG_GUILD_ROSTER");
262 Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
263 if(!guild)
264 return;
266 guild->Roster(this);
269 void WorldSession::HandleGuildPromoteOpcode(WorldPacket& recvPacket)
271 std::string plName;
273 //sLog.outDebug("WORLD: Received CMSG_GUILD_PROMOTE");
275 recvPacket >> plName;
277 if(!normalizePlayerName(plName))
278 return;
280 Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
281 if(!guild)
283 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
284 return;
286 if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_PROMOTE))
288 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
289 return;
292 uint64 plGuid;
293 MemberSlot* slot = guild->GetMemberSlot(plName, plGuid);
295 if(!slot)
297 SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S);
298 return;
301 if(plGuid == GetPlayer()->GetGUID())
303 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_NAME_INVALID);
304 return;
307 //allow to promote only to lower rank than member's rank
308 //guildmaster's rank = 0
309 //GetPlayer()->GetRank() + 1 is highest rank that current player can promote to
310 if(GetPlayer()->GetRank() + 1 >= slot->RankId)
312 SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_RANK_TOO_HIGH_S);
313 return;
316 uint32 newRankId = slot->RankId - 1; //when promoting player, rank is decreased
318 guild->ChangeRank(plGuid, newRankId);
319 // Put record into guildlog
320 guild->LogGuildEvent(GUILD_EVENT_LOG_PROMOTE_PLAYER, GetPlayer()->GetGUIDLow(), GUID_LOPART(plGuid), newRankId);
322 WorldPacket data(SMSG_GUILD_EVENT, (2+30)); // guess size
323 data << (uint8)GE_PROMOTION;
324 data << (uint8)3; // strings count
325 data << GetPlayer()->GetName();
326 data << plName;
327 data << guild->GetRankName(newRankId);
328 guild->BroadcastPacket(&data);
331 void WorldSession::HandleGuildDemoteOpcode(WorldPacket& recvPacket)
333 std::string plName;
335 //sLog.outDebug("WORLD: Received CMSG_GUILD_DEMOTE");
337 recvPacket >> plName;
339 if(!normalizePlayerName(plName))
340 return;
342 Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
344 if(!guild)
346 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
347 return;
350 if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_DEMOTE))
352 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
353 return;
356 uint64 plGuid;
357 MemberSlot* slot = guild->GetMemberSlot(plName, plGuid);
359 if (!slot)
361 SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S);
362 return;
365 if(plGuid == GetPlayer()->GetGUID())
367 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_NAME_INVALID);
368 return;
371 //do not allow to demote same or higher rank
372 if(GetPlayer()->GetRank() >= slot->RankId)
374 SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_RANK_TOO_HIGH_S);
375 return;
378 //do not allow to demote lowest rank
379 if(slot->RankId >= guild->GetLowestRank())
381 SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_ALREADY_LOWEST_RANK_S);
382 return;
385 uint32 newRankId = slot->RankId + 1; //when demoting player, rank is increased
387 guild->ChangeRank(plGuid, newRankId);
388 // Put record into guildlog
389 guild->LogGuildEvent(GUILD_EVENT_LOG_DEMOTE_PLAYER, GetPlayer()->GetGUIDLow(), GUID_LOPART(plGuid), newRankId);
391 WorldPacket data(SMSG_GUILD_EVENT, (2+30)); // guess size
392 data << (uint8)GE_DEMOTION;
393 data << (uint8)3; // strings count
394 data << GetPlayer()->GetName();
395 data << plName;
396 data << guild->GetRankName(slot->RankId);
397 guild->BroadcastPacket(&data);
400 void WorldSession::HandleGuildLeaveOpcode(WorldPacket& /*recvPacket*/)
402 std::string plName;
403 Guild *guild;
405 //sLog.outDebug("WORLD: Received CMSG_GUILD_LEAVE");
407 guild = objmgr.GetGuildById(_player->GetGuildId());
408 if(!guild)
410 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
411 return;
413 if(_player->GetGUID() == guild->GetLeader() && guild->GetMemberSize() > 1)
415 SendGuildCommandResult(GUILD_QUIT_S, "", GUILD_LEADER_LEAVE);
416 return;
419 if(_player->GetGUID() == guild->GetLeader())
421 guild->Disband();
422 return;
425 plName = _player->GetName();
427 guild->DelMember(_player->GetGUID());
428 // Put record into guildlog
429 guild->LogGuildEvent(GUILD_EVENT_LOG_LEAVE_GUILD, _player->GetGUIDLow(), 0, 0);
431 WorldPacket data(SMSG_GUILD_EVENT, (2+10)); // guess size
432 data << (uint8)GE_LEFT;
433 data << (uint8)1; // strings count
434 data << plName;
435 guild->BroadcastPacket(&data);
437 //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)");
439 SendGuildCommandResult(GUILD_QUIT_S, guild->GetName(), GUILD_PLAYER_NO_MORE_IN_GUILD);
442 void WorldSession::HandleGuildDisbandOpcode(WorldPacket& /*recvPacket*/)
444 std::string name;
445 Guild *guild;
447 //sLog.outDebug("WORLD: Received CMSG_GUILD_DISBAND");
449 guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
450 if(!guild)
452 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
453 return;
455 if(GetPlayer()->GetGUID() != guild->GetLeader())
457 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
458 return;
461 guild->Disband();
463 //sLog.outDebug("WORLD: Guild Sucefully Disbanded");
466 void WorldSession::HandleGuildLeaderOpcode(WorldPacket& recvPacket)
468 std::string name;
469 Player *oldLeader = GetPlayer();
470 Guild *guild;
472 //sLog.outDebug("WORLD: Received CMSG_GUILD_LEADER");
474 recvPacket >> name;
476 if(!normalizePlayerName(name))
477 return;
479 guild = objmgr.GetGuildById(oldLeader->GetGuildId());
481 if (!guild)
483 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
484 return;
487 if (oldLeader->GetGUID() != guild->GetLeader())
489 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
490 return;
493 uint64 newLeaderGUID;
494 MemberSlot* slot = guild->GetMemberSlot(name, newLeaderGUID);
496 if (!slot)
498 SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_IN_GUILD_S);
499 return;
502 guild->SetLeader(newLeaderGUID);
503 guild->ChangeRank(oldLeader->GetGUID(), GR_OFFICER);
505 WorldPacket data(SMSG_GUILD_EVENT, (2+20)); // guess size
506 data << (uint8)GE_LEADER_CHANGED;
507 data << (uint8)2; // strings count
508 data << oldLeader->GetName();
509 data << name.c_str();
510 guild->BroadcastPacket(&data);
512 //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)");
515 void WorldSession::HandleGuildMOTDOpcode(WorldPacket& recvPacket)
517 Guild *guild;
518 std::string MOTD;
520 //sLog.outDebug("WORLD: Received CMSG_GUILD_MOTD");
522 guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
523 if(!guild)
525 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
526 return;
528 if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_SETMOTD))
530 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
531 return;
534 if(!recvPacket.empty())
535 recvPacket >> MOTD;
536 else
537 MOTD = "";
539 guild->SetMOTD(MOTD);
541 WorldPacket data(SMSG_GUILD_EVENT, (2+MOTD.size()+1));
542 data << (uint8)GE_MOTD;
543 data << (uint8)1; // strings count
544 data << MOTD;
545 guild->BroadcastPacket(&data);
547 //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)");
550 void WorldSession::HandleGuildSetPublicNoteOpcode(WorldPacket& recvPacket)
552 std::string name,PNOTE;
554 //sLog.outDebug("WORLD: Received CMSG_GUILD_SET_PUBLIC_NOTE");
556 recvPacket >> name;
558 if(!normalizePlayerName(name))
559 return;
561 Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
563 if (!guild)
565 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
566 return;
569 if (!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_EPNOTE))
571 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
572 return;
575 uint64 plGuid;
576 MemberSlot* slot = guild->GetMemberSlot(name, plGuid);
578 if (!slot)
580 SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_IN_GUILD_S);
581 return;
584 recvPacket >> PNOTE;
585 guild->SetPNOTE(plGuid, PNOTE);
587 guild->Roster(this);
590 void WorldSession::HandleGuildSetOfficerNoteOpcode(WorldPacket& recvPacket)
592 std::string plName, OFFNOTE;
594 //sLog.outDebug("WORLD: Received CMSG_GUILD_SET_OFFICER_NOTE");
596 recvPacket >> plName;
598 if (!normalizePlayerName(plName))
599 return;
601 Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
603 if (!guild)
605 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
606 return;
608 if (!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_EOFFNOTE))
610 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
611 return;
614 uint64 plGuid;
615 MemberSlot* slot = guild->GetMemberSlot(plName, plGuid);
617 if (!slot)
619 SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S);
620 return;
623 recvPacket >> OFFNOTE;
624 guild->SetOFFNOTE(plGuid, OFFNOTE);
626 guild->Roster(this);
629 void WorldSession::HandleGuildRankOpcode(WorldPacket& recvPacket)
631 //recvPacket.hexlike();
633 Guild *guild;
634 std::string rankname;
635 uint32 rankId;
636 uint32 rights, MoneyPerDay;
638 //sLog.outDebug("WORLD: Received CMSG_GUILD_RANK");
640 guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
641 if(!guild)
643 recvPacket.rpos(recvPacket.wpos()); // set to end to avoid warnings spam
644 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
645 return;
648 else if(GetPlayer()->GetGUID() != guild->GetLeader())
650 recvPacket.rpos(recvPacket.wpos()); // set to end to avoid warnings spam
651 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
652 return;
655 recvPacket >> rankId;
656 recvPacket >> rights;
657 recvPacket >> rankname;
658 recvPacket >> MoneyPerDay;
660 for (int i = 0; i < GUILD_BANK_MAX_TABS; ++i)
662 uint32 BankRights;
663 uint32 BankSlotPerDay;
665 recvPacket >> BankRights;
666 recvPacket >> BankSlotPerDay;
667 guild->SetBankRightsAndSlots(rankId, uint8(i), uint16(BankRights & 0xFF), uint16(BankSlotPerDay), true);
670 sLog.outDebug("WORLD: Changed RankName to %s , Rights to 0x%.4X", rankname.c_str(), rights);
672 guild->SetBankMoneyPerDay(rankId, MoneyPerDay);
673 guild->SetRankName(rankId, rankname);
675 if (rankId == GR_GUILDMASTER) // prevent loss leader rights
676 rights = GR_RIGHT_ALL;
678 guild->SetRankRights(rankId, rights);
680 guild->Query(this);
681 guild->Roster(); // broadcast for tab rights update
684 void WorldSession::HandleGuildAddRankOpcode(WorldPacket& recvPacket)
686 Guild *guild;
687 std::string rankname;
689 //sLog.outDebug("WORLD: Received CMSG_GUILD_ADD_RANK");
691 guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
692 if(!guild)
694 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
695 return;
698 if(GetPlayer()->GetGUID() != guild->GetLeader())
700 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
701 return;
704 if(guild->GetRanksSize() >= GUILD_RANKS_MAX_COUNT) // client not let create more 10 than ranks
705 return;
707 recvPacket >> rankname;
709 guild->CreateRank(rankname, GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK);
711 guild->Query(this);
712 guild->Roster(); // broadcast for tab rights update
715 void WorldSession::HandleGuildDelRankOpcode(WorldPacket& /*recvPacket*/)
717 Guild *guild;
718 std::string rankname;
720 //sLog.outDebug("WORLD: Received CMSG_GUILD_DEL_RANK");
722 guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
723 if(!guild)
725 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
726 return;
729 else if(GetPlayer()->GetGUID() != guild->GetLeader())
731 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
732 return;
735 guild->DelRank();
737 guild->Query(this);
738 guild->Roster(); // broadcast for tab rights update
741 void WorldSession::SendGuildCommandResult(uint32 typecmd, const std::string& str,uint32 cmdresult)
743 WorldPacket data(SMSG_GUILD_COMMAND_RESULT, (8+str.size()+1));
744 data << typecmd;
745 data << str;
746 data << cmdresult;
747 SendPacket(&data);
749 //sLog.outDebug("WORLD: Sent (SMSG_GUILD_COMMAND_RESULT)");
752 void WorldSession::HandleGuildChangeInfoTextOpcode(WorldPacket& recvPacket)
754 //sLog.outDebug("WORLD: Received CMSG_GUILD_INFO_TEXT");
756 std::string GINFO;
758 recvPacket >> GINFO;
760 Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
761 if(!guild)
763 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
764 return;
767 if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_MODIFY_GUILD_INFO))
769 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PERMISSIONS);
770 return;
773 guild->SetGINFO(GINFO);
776 void WorldSession::HandleSaveGuildEmblemOpcode(WorldPacket& recvPacket)
778 //sLog.outDebug("WORLD: Received MSG_SAVE_GUILD_EMBLEM");
780 uint64 vendorGuid;
782 uint32 EmblemStyle;
783 uint32 EmblemColor;
784 uint32 BorderStyle;
785 uint32 BorderColor;
786 uint32 BackgroundColor;
788 recvPacket >> vendorGuid;
790 Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorGuid,UNIT_NPC_FLAG_TABARDDESIGNER);
791 if (!pCreature)
793 //"That's not an emblem vendor!"
794 SendSaveGuildEmblem(ERR_GUILDEMBLEM_INVALIDVENDOR);
795 sLog.outDebug("WORLD: HandleSaveGuildEmblemOpcode - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(vendorGuid));
796 return;
799 // remove fake death
800 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
801 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
803 recvPacket >> EmblemStyle;
804 recvPacket >> EmblemColor;
805 recvPacket >> BorderStyle;
806 recvPacket >> BorderColor;
807 recvPacket >> BackgroundColor;
809 Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
810 if(!guild)
812 //"You are not part of a guild!";
813 SendSaveGuildEmblem(ERR_GUILDEMBLEM_NOGUILD);
814 return;
817 if (guild->GetLeader() != GetPlayer()->GetGUID())
819 //"Only guild leaders can create emblems."
820 SendSaveGuildEmblem(ERR_GUILDEMBLEM_NOTGUILDMASTER);
821 return;
824 if(GetPlayer()->GetMoney() < 10*GOLD)
826 //"You can't afford to do that."
827 SendSaveGuildEmblem(ERR_GUILDEMBLEM_NOTENOUGHMONEY);
828 return;
831 GetPlayer()->ModifyMoney(-10*GOLD);
832 guild->SetEmblem(EmblemStyle, EmblemColor, BorderStyle, BorderColor, BackgroundColor);
834 //"Guild Emblem saved."
835 SendSaveGuildEmblem(ERR_GUILDEMBLEM_SUCCESS);
837 guild->Query(this);
840 void WorldSession::HandleGuildEventLogQueryOpcode(WorldPacket& /* recvPacket */)
842 // empty
843 sLog.outDebug("WORLD: Received (MSG_GUILD_EVENT_LOG_QUERY)");
844 //recvPacket.hexlike();
846 uint32 GuildId = GetPlayer()->GetGuildId();
847 if (GuildId == 0)
848 return;
850 Guild *pGuild = objmgr.GetGuildById(GuildId);
851 if(!pGuild)
852 return;
854 pGuild->DisplayGuildEventLog(this);
857 /****** GUILD BANK *******/
859 void WorldSession::HandleGuildBankMoneyWithdrawn( WorldPacket & /* recv_data */ )
861 sLog.outDebug("WORLD: Received (MSG_GUILD_BANK_MONEY_WITHDRAWN)");
862 //recv_data.hexlike();
864 uint32 GuildId = GetPlayer()->GetGuildId();
865 if (GuildId == 0)
866 return;
868 Guild *pGuild = objmgr.GetGuildById(GuildId);
869 if(!pGuild)
870 return;
872 pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow());
875 void WorldSession::HandleGuildPermissions( WorldPacket& /* recv_data */ )
877 sLog.outDebug("WORLD: Received (MSG_GUILD_PERMISSIONS)");
879 uint32 GuildId = GetPlayer()->GetGuildId();
880 if (GuildId == 0)
881 return;
883 Guild *pGuild = objmgr.GetGuildById(GuildId);
884 if(!pGuild)
885 return;
887 uint32 rankId = GetPlayer()->GetRank();
889 WorldPacket data(MSG_GUILD_PERMISSIONS, 4*15+1);
890 data << uint32(rankId); // guild rank id
891 data << uint32(pGuild->GetRankRights(rankId)); // rank rights
892 // money per day left
893 data << uint32(pGuild->GetMemberMoneyWithdrawRem(GetPlayer()->GetGUIDLow()));
894 data << uint8(pGuild->GetPurchasedTabs()); // tabs count
895 // why sending all info when not all tabs are purchased???
896 for(int i = 0; i < GUILD_BANK_MAX_TABS; ++i)
898 data << uint32(pGuild->GetBankRights(rankId, uint8(i)));
899 data << uint32(pGuild->GetMemberSlotWithdrawRem(GetPlayer()->GetGUIDLow(), uint8(i)));
901 SendPacket(&data);
902 sLog.outDebug("WORLD: Sent (MSG_GUILD_PERMISSIONS)");
905 /* Called when clicking on Guild bank gameobject */
906 void WorldSession::HandleGuildBankerActivate( WorldPacket & recv_data )
908 sLog.outDebug("WORLD: Received (CMSG_GUILD_BANKER_ACTIVATE)");
909 uint64 GoGuid;
910 uint8 unk;
911 recv_data >> GoGuid >> unk;
913 if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
914 return;
916 if (uint32 GuildId = GetPlayer()->GetGuildId())
918 if(Guild *pGuild = objmgr.GetGuildById(GuildId))
920 pGuild->DisplayGuildBankTabsInfo(this);
921 return;
925 SendGuildCommandResult(GUILD_BANK_S, "", GUILD_PLAYER_NOT_IN_GUILD);
928 /* Called when opening guild bank tab only (first one) */
929 void WorldSession::HandleGuildBankQueryTab( WorldPacket & recv_data )
931 sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_QUERY_TAB)");
932 uint64 GoGuid;
933 uint8 TabId,unk1;
934 recv_data >> GoGuid >> TabId >> unk1;
936 if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
937 return;
939 uint32 GuildId = GetPlayer()->GetGuildId();
940 if (GuildId == 0)
941 return;
943 Guild *pGuild = objmgr.GetGuildById(GuildId);
944 if(!pGuild)
945 return;
947 // Let's update the amount of gold the player can withdraw before displaying the content
948 // This is usefull if money withdraw right has changed
949 pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow());
951 pGuild->DisplayGuildBankContent(this, TabId);
954 void WorldSession::HandleGuildBankDepositMoney( WorldPacket & recv_data )
956 sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_DEPOSIT_MONEY)");
957 uint64 GoGuid;
958 uint32 money;
959 recv_data >> GoGuid >> money;
961 if (!money)
962 return;
964 if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
965 return;
967 uint32 GuildId = GetPlayer()->GetGuildId();
968 if (GuildId == 0)
969 return;
971 Guild *pGuild = objmgr.GetGuildById(GuildId);
972 if(!pGuild)
973 return;
975 if (GetPlayer()->GetMoney() < money)
976 return;
978 CharacterDatabase.BeginTransaction();
980 pGuild->SetBankMoney(pGuild->GetGuildBankMoney()+money);
981 GetPlayer()->ModifyMoney(-int(money));
982 GetPlayer()->SaveGoldToDB();
984 CharacterDatabase.CommitTransaction();
986 // logging money
987 if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
989 sLog.outCommand(_player->GetSession()->GetAccountId(),"GM %s (Account: %u) deposit money (Amount: %u) to guild bank (Guild ID %u)",
990 _player->GetName(),_player->GetSession()->GetAccountId(),money,GuildId);
993 // log
994 pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_MONEY, uint8(0), GetPlayer()->GetGUIDLow(), money);
996 pGuild->DisplayGuildBankTabsInfo(this);
997 pGuild->DisplayGuildBankContent(this, 0);
998 pGuild->DisplayGuildBankMoneyUpdate();
1001 void WorldSession::HandleGuildBankWithdrawMoney( WorldPacket & recv_data )
1003 sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_WITHDRAW_MONEY)");
1004 uint64 GoGuid;
1005 uint32 money;
1006 recv_data >> GoGuid >> money;
1008 if (!money)
1009 return;
1011 if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
1012 return;
1014 uint32 GuildId = GetPlayer()->GetGuildId();
1015 if (GuildId == 0)
1016 return;
1018 Guild *pGuild = objmgr.GetGuildById(GuildId);
1019 if(!pGuild)
1020 return;
1022 if (pGuild->GetGuildBankMoney()<money) // not enough money in bank
1023 return;
1025 if (!pGuild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_WITHDRAW_GOLD))
1026 return;
1028 CharacterDatabase.BeginTransaction();
1030 if (!pGuild->MemberMoneyWithdraw(money, GetPlayer()->GetGUIDLow()))
1032 CharacterDatabase.RollbackTransaction();
1033 return;
1036 GetPlayer()->ModifyMoney(money);
1037 GetPlayer()->SaveGoldToDB();
1039 CharacterDatabase.CommitTransaction();
1041 // Log
1042 pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_MONEY, uint8(0), GetPlayer()->GetGUIDLow(), money);
1044 pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow());
1045 pGuild->DisplayGuildBankTabsInfo(this);
1046 pGuild->DisplayGuildBankContent(this, 0);
1047 pGuild->DisplayGuildBankMoneyUpdate();
1050 void WorldSession::HandleGuildBankSwapItems( WorldPacket & recv_data )
1052 sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_SWAP_ITEMS)");
1053 //recv_data.hexlike();
1055 uint64 GoGuid;
1056 uint8 BankToBank;
1058 uint8 BankTab, BankTabSlot, AutoStore;
1059 uint8 PlayerSlot = NULL_SLOT;
1060 uint8 PlayerBag = NULL_BAG;
1061 uint8 BankTabDst, BankTabSlotDst, unk2;
1062 uint8 ToChar = 1;
1063 uint32 ItemEntry, unk1;
1064 uint32 AutoStoreCount = 0;
1065 uint32 SplitedAmount = 0;
1067 recv_data >> GoGuid >> BankToBank;
1068 if (BankToBank)
1070 recv_data >> BankTabDst;
1071 recv_data >> BankTabSlotDst;
1072 recv_data >> unk1; // always 0
1073 recv_data >> BankTab;
1074 recv_data >> BankTabSlot;
1075 recv_data >> ItemEntry;
1076 recv_data >> unk2; // always 0
1077 recv_data >> SplitedAmount;
1079 if (BankTabSlotDst >= GUILD_BANK_MAX_SLOTS || (BankTabDst == BankTab && BankTabSlotDst == BankTabSlot))
1081 recv_data.rpos(recv_data.wpos()); // prevent additional spam at rejected packet
1082 return;
1085 else
1087 recv_data >> BankTab;
1088 recv_data >> BankTabSlot;
1089 recv_data >> ItemEntry;
1090 recv_data >> AutoStore;
1091 if (AutoStore)
1093 recv_data >> AutoStoreCount;
1094 recv_data.read_skip<uint8>(); // ToChar (?), always and expected to be 1 (autostore only triggered in guild->ToChar)
1095 recv_data.read_skip<uint32>(); // unknown, always 0
1097 else
1099 recv_data >> PlayerBag;
1100 recv_data >> PlayerSlot;
1101 recv_data >> ToChar;
1102 recv_data >> SplitedAmount;
1105 if (BankTabSlot >= GUILD_BANK_MAX_SLOTS && BankTabSlot != 0xFF)
1107 recv_data.rpos(recv_data.wpos()); // prevent additional spam at rejected packet
1108 return;
1112 if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
1113 return;
1115 uint32 GuildId = GetPlayer()->GetGuildId();
1116 if (GuildId == 0)
1117 return;
1119 Guild *pGuild = objmgr.GetGuildById(GuildId);
1120 if(!pGuild)
1121 return;
1123 Player *pl = GetPlayer();
1125 // Bank <-> Bank
1126 if (BankToBank)
1128 pGuild->SwapItems(pl, BankTab, BankTabSlot, BankTabDst, BankTabSlotDst, SplitedAmount);
1129 return;
1132 // Player <-> Bank
1134 // allow work with inventory only
1135 if(!Player::IsInventoryPos(PlayerBag,PlayerSlot) && !(PlayerBag == NULL_BAG && PlayerSlot == NULL_SLOT) )
1137 _player->SendEquipError( EQUIP_ERR_NONE, NULL, NULL );
1138 return;
1141 // BankToChar swap or char to bank remaining
1142 if (ToChar) // Bank -> Char cases
1143 pGuild->MoveFromBankToChar(pl, BankTab, BankTabSlot, PlayerBag, PlayerSlot, SplitedAmount);
1144 else // Char -> Bank cases
1145 pGuild->MoveFromCharToBank(pl, PlayerBag, PlayerSlot, BankTab, BankTabSlot, SplitedAmount);
1148 void WorldSession::HandleGuildBankBuyTab( WorldPacket & recv_data )
1150 sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_BUY_TAB)");
1151 //recv_data.hexlike();
1152 uint64 GoGuid;
1153 uint8 TabId;
1155 recv_data >> GoGuid;
1156 recv_data >> TabId;
1158 if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
1159 return;
1161 uint32 GuildId = GetPlayer()->GetGuildId();
1162 if (GuildId==0)
1163 return;
1165 Guild *pGuild = objmgr.GetGuildById(GuildId);
1166 if(!pGuild)
1167 return;
1169 uint32 TabCost = GetGuildBankTabPrice(TabId) * GOLD;
1170 if (!TabCost)
1171 return;
1173 if (pGuild->GetPurchasedTabs() >= GUILD_BANK_MAX_TABS)
1174 return;
1176 if (TabId != pGuild->GetPurchasedTabs()) // m_PurchasedTabs = 0 when buying Tab 0, that is why this check can be made
1178 sLog.outError("Error: trying to buy a tab non contigous to owned ones");
1179 return;
1182 if (GetPlayer()->GetMoney() < TabCost) // Should not happen, this is checked by client
1183 return;
1185 // Go on with creating tab
1186 pGuild->CreateNewBankTab();
1187 GetPlayer()->ModifyMoney(-int(TabCost));
1188 pGuild->SetBankMoneyPerDay(GetPlayer()->GetRank(), WITHDRAW_MONEY_UNLIMITED);
1189 pGuild->SetBankRightsAndSlots(GetPlayer()->GetRank(), TabId, GUILD_BANK_RIGHT_FULL, WITHDRAW_SLOT_UNLIMITED, true);
1190 pGuild->Roster(); // broadcast for tab rights update
1191 pGuild->DisplayGuildBankTabsInfo(this);
1194 void WorldSession::HandleGuildBankUpdateTab( WorldPacket & recv_data )
1196 sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_UPDATE_TAB)");
1197 //recv_data.hexlike();
1198 uint64 GoGuid;
1199 uint8 TabId;
1200 std::string Name;
1201 std::string IconIndex;
1203 recv_data >> GoGuid;
1204 recv_data >> TabId;
1205 recv_data >> Name;
1206 recv_data >> IconIndex;
1208 if(Name.empty())
1209 return;
1211 if(IconIndex.empty())
1212 return;
1214 if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
1215 return;
1217 uint32 GuildId = GetPlayer()->GetGuildId();
1218 if (GuildId==0)
1219 return;
1221 Guild *pGuild = objmgr.GetGuildById(GuildId);
1222 if(!pGuild)
1223 return;
1225 pGuild->SetGuildBankTabInfo(TabId, Name, IconIndex);
1226 pGuild->DisplayGuildBankTabsInfo(this);
1227 pGuild->DisplayGuildBankContent(this, TabId);
1230 void WorldSession::HandleGuildBankLogQuery( WorldPacket & recv_data )
1232 sLog.outDebug("WORLD: Received (MSG_GUILD_BANK_LOG_QUERY)");
1234 uint32 GuildId = GetPlayer()->GetGuildId();
1235 if (GuildId == 0)
1236 return;
1238 Guild *pGuild = objmgr.GetGuildById(GuildId);
1239 if(!pGuild)
1240 return;
1242 uint8 TabId;
1243 recv_data >> TabId;
1245 pGuild->DisplayGuildBankLogs(this, TabId);
1248 void WorldSession::HandleQueryGuildBankTabText(WorldPacket &recv_data)
1250 sLog.outDebug("WORLD: Received MSG_QUERY_GUILD_BANK_TEXT");
1252 uint32 GuildId = GetPlayer()->GetGuildId();
1253 if (GuildId == 0)
1254 return;
1256 Guild *pGuild = objmgr.GetGuildById(GuildId);
1257 if(!pGuild)
1258 return;
1260 uint8 TabId;
1261 recv_data >> TabId;
1263 pGuild->SendGuildBankTabText(this, TabId);
1266 void WorldSession::HandleSetGuildBankTabText(WorldPacket &recv_data)
1268 sLog.outDebug("WORLD: Received CMSG_SET_GUILD_BANK_TEXT");
1269 uint32 GuildId = GetPlayer()->GetGuildId();
1270 if (GuildId == 0)
1271 return;
1273 Guild *pGuild = objmgr.GetGuildById(GuildId);
1274 if(!pGuild)
1275 return;
1277 uint8 TabId;
1278 std::string Text;
1279 recv_data >> TabId;
1280 recv_data >> Text;
1282 pGuild->SetGuildBankTabText(TabId, Text);
1285 void WorldSession::SendSaveGuildEmblem( uint32 msg )
1287 WorldPacket data(MSG_SAVE_GUILD_EMBLEM, 4);
1288 data << uint32(msg); // not part of guild
1289 SendPacket( &data );