[7297] Fixed profession spells sorting in trainer spell list at client.
[getmangos.git] / src / game / GuildHandler.cpp
blobf71223603a0fd9702db9a1b2d1a808c799d2a913
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 "MapManager.h"
28 #include "GossipDef.h"
29 #include "SocialMgr.h"
31 void WorldSession::HandleGuildQueryOpcode(WorldPacket& recvPacket)
33 CHECK_PACKET_SIZE(recvPacket, 4);
35 uint32 guildId;
36 Guild *guild;
38 //sLog.outDebug("WORLD: Received CMSG_GUILD_QUERY");
40 recvPacket >> guildId;
42 guild = objmgr.GetGuildById(guildId);
43 if(!guild)
45 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
46 return;
49 guild->Query(this);
52 void WorldSession::HandleGuildCreateOpcode(WorldPacket& recvPacket)
54 CHECK_PACKET_SIZE(recvPacket, 1);
56 std::string gname;
58 //sLog.outDebug("WORLD: Received CMSG_GUILD_CREATE");
60 recvPacket >> gname;
62 if(GetPlayer()->GetGuildId())
63 return;
65 Guild *guild = new Guild;
66 if(!guild->create(GetPlayer()->GetGUID(),gname))
68 delete guild;
69 return;
72 objmgr.AddGuild(guild);
75 void WorldSession::HandleGuildInviteOpcode(WorldPacket& recvPacket)
77 CHECK_PACKET_SIZE(recvPacket, 1);
79 std::string Invitedname, plname;
81 //sLog.outDebug("WORLD: Received CMSG_GUILD_INVITE");
83 Player * player = NULL;
85 recvPacket >> Invitedname;
87 if(normalizePlayerName(Invitedname))
88 player = ObjectAccessor::Instance().FindPlayerByName(Invitedname.c_str());
90 if(!player)
92 SendGuildCommandResult(GUILD_INVITE_S, Invitedname, GUILD_PLAYER_NOT_FOUND);
93 return;
96 Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
97 if(!guild)
99 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
100 return;
103 // OK result but not send invite
104 if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
105 return;
107 // not let enemies sign guild charter
108 if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != GetPlayer()->GetTeam())
110 SendGuildCommandResult(GUILD_INVITE_S, Invitedname, GUILD_NOT_ALLIED);
111 return;
114 if(player->GetGuildId())
116 plname = player->GetName();
117 SendGuildCommandResult(GUILD_INVITE_S, plname, ALREADY_IN_GUILD);
118 return;
121 if(player->GetGuildIdInvited())
123 plname = player->GetName();
124 SendGuildCommandResult(GUILD_INVITE_S, plname, ALREADY_INVITED_TO_GUILD);
125 return;
128 if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_INVITE))
130 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
131 return;
134 sLog.outDebug("Player %s Invited %s to Join his Guild", GetPlayer()->GetName(), Invitedname.c_str());
136 player->SetGuildIdInvited(GetPlayer()->GetGuildId());
137 // Put record into guildlog
138 guild->LogGuildEvent(GUILD_EVENT_LOG_INVITE_PLAYER, GetPlayer()->GetGUIDLow(), player->GetGUIDLow(), 0);
140 WorldPacket data(SMSG_GUILD_INVITE, (8+10)); // guess size
141 data << GetPlayer()->GetName();
142 data << guild->GetName();
143 player->GetSession()->SendPacket(&data);
145 //sLog.outDebug("WORLD: Sent (SMSG_GUILD_INVITE)");
148 void WorldSession::HandleGuildRemoveOpcode(WorldPacket& recvPacket)
150 CHECK_PACKET_SIZE(recvPacket, 1);
152 std::string plName;
154 //sLog.outDebug("WORLD: Received CMSG_GUILD_REMOVE");
156 recvPacket >> plName;
158 if(!normalizePlayerName(plName))
159 return;
161 Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
162 if(!guild)
164 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
165 return;
168 if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_REMOVE))
170 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
171 return;
174 uint64 plGuid;
175 MemberSlot* slot = guild->GetMemberSlot(plName, plGuid);
176 if(!slot)
178 SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S);
179 return;
182 if(slot->RankId == GR_GUILDMASTER)
184 SendGuildCommandResult(GUILD_QUIT_S, "", GUILD_LEADER_LEAVE);
185 return;
188 guild->DelMember(plGuid);
189 // Put record into guildlog
190 guild->LogGuildEvent(GUILD_EVENT_LOG_UNINVITE_PLAYER, GetPlayer()->GetGUIDLow(), GUID_LOPART(plGuid), 0);
192 WorldPacket data(SMSG_GUILD_EVENT, (2+20)); // guess size
193 data << (uint8)GE_REMOVED;
194 data << (uint8)2; // strings count
195 data << plName;
196 data << GetPlayer()->GetName();
197 guild->BroadcastPacket(&data);
200 void WorldSession::HandleGuildAcceptOpcode(WorldPacket& /*recvPacket*/)
202 Guild *guild;
203 Player *player = GetPlayer();
205 //sLog.outDebug("WORLD: Received CMSG_GUILD_ACCEPT");
207 guild = objmgr.GetGuildById(player->GetGuildIdInvited());
208 if(!guild || player->GetGuildId())
209 return;
211 // not let enemies sign guild charter
212 if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != objmgr.GetPlayerTeamByGUID(guild->GetLeader()))
213 return;
215 if(!guild->AddMember(GetPlayer()->GetGUID(),guild->GetLowestRank()))
216 return;
217 // Put record into guildlog
218 guild->LogGuildEvent(GUILD_EVENT_LOG_JOIN_GUILD, GetPlayer()->GetGUIDLow(), 0, 0);
220 WorldPacket data(SMSG_GUILD_EVENT, (2+10)); // guess size
221 data << (uint8)GE_JOINED;
222 data << (uint8)1;
223 data << player->GetName();
224 guild->BroadcastPacket(&data);
226 //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)");
229 void WorldSession::HandleGuildDeclineOpcode(WorldPacket& /*recvPacket*/)
231 //sLog.outDebug("WORLD: Received CMSG_GUILD_DECLINE");
233 GetPlayer()->SetGuildIdInvited(0);
234 GetPlayer()->SetInGuild(0);
237 void WorldSession::HandleGuildInfoOpcode(WorldPacket& /*recvPacket*/)
239 Guild *guild;
240 //sLog.outDebug("WORLD: Received CMSG_GUILD_INFO");
242 guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
243 if(!guild)
245 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
246 return;
249 WorldPacket data(SMSG_GUILD_INFO, (5*4 + guild->GetName().size() + 1));
250 data << guild->GetName();
251 data << guild->GetCreatedDay();
252 data << guild->GetCreatedMonth();
253 data << guild->GetCreatedYear();
254 data << guild->GetMemberSize();
255 data << guild->GetMemberSize();
257 SendPacket(&data);
260 void WorldSession::HandleGuildRosterOpcode(WorldPacket& /*recvPacket*/)
262 //sLog.outDebug("WORLD: Received CMSG_GUILD_ROSTER");
264 Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
265 if(!guild)
266 return;
268 guild->Roster(this);
271 void WorldSession::HandleGuildPromoteOpcode(WorldPacket& recvPacket)
273 CHECK_PACKET_SIZE(recvPacket, 1);
275 std::string plName;
277 //sLog.outDebug("WORLD: Received CMSG_GUILD_PROMOTE");
279 recvPacket >> plName;
281 if(!normalizePlayerName(plName))
282 return;
284 Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
285 if(!guild)
287 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
288 return;
290 if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_PROMOTE))
292 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
293 return;
296 uint64 plGuid;
297 MemberSlot* slot = guild->GetMemberSlot(plName, plGuid);
299 if(!slot)
301 SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S);
302 return;
305 if(plGuid == GetPlayer()->GetGUID())
307 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_NAME_INVALID);
308 return;
311 if(slot->RankId < 2 || (slot->RankId-1) < GetPlayer()->GetRank())
312 return;
314 uint32 newRankId = slot->RankId < guild->GetNrRanks() ? slot->RankId-1 : guild->GetNrRanks()-1;
316 guild->ChangeRank(plGuid, newRankId);
317 // Put record into guildlog
318 guild->LogGuildEvent(GUILD_EVENT_LOG_PROMOTE_PLAYER, GetPlayer()->GetGUIDLow(), GUID_LOPART(plGuid), newRankId);
320 WorldPacket data(SMSG_GUILD_EVENT, (2+30)); // guess size
321 data << (uint8)GE_PROMOTION;
322 data << (uint8)3;
323 data << GetPlayer()->GetName();
324 data << plName;
325 data << guild->GetRankName(newRankId);
326 guild->BroadcastPacket(&data);
329 void WorldSession::HandleGuildDemoteOpcode(WorldPacket& recvPacket)
331 CHECK_PACKET_SIZE(recvPacket, 1);
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 if((slot->RankId+1) >= guild->GetNrRanks() || slot->RankId <= GetPlayer()->GetRank())
372 return;
374 guild->ChangeRank(plGuid, (slot->RankId+1));
375 // Put record into guildlog
376 guild->LogGuildEvent(GUILD_EVENT_LOG_DEMOTE_PLAYER, GetPlayer()->GetGUIDLow(), GUID_LOPART(plGuid), slot->RankId);
378 WorldPacket data(SMSG_GUILD_EVENT, (2+30)); // guess size
379 data << (uint8)GE_DEMOTION;
380 data << (uint8)3;
381 data << GetPlayer()->GetName();
382 data << plName;
383 data << guild->GetRankName(slot->RankId);
384 guild->BroadcastPacket(&data);
387 void WorldSession::HandleGuildLeaveOpcode(WorldPacket& /*recvPacket*/)
389 std::string plName;
390 Guild *guild;
392 //sLog.outDebug("WORLD: Received CMSG_GUILD_LEAVE");
394 guild = objmgr.GetGuildById(_player->GetGuildId());
395 if(!guild)
397 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
398 return;
400 if(_player->GetGUID() == guild->GetLeader() && guild->GetMemberSize() > 1)
402 SendGuildCommandResult(GUILD_QUIT_S, "", GUILD_LEADER_LEAVE);
403 return;
406 if(_player->GetGUID() == guild->GetLeader())
408 guild->Disband();
409 return;
412 plName = _player->GetName();
414 guild->DelMember(_player->GetGUID());
415 // Put record into guildlog
416 guild->LogGuildEvent(GUILD_EVENT_LOG_LEAVE_GUILD, _player->GetGUIDLow(), 0, 0);
418 WorldPacket data(SMSG_GUILD_EVENT, (2+10)); // guess size
419 data << (uint8)GE_LEFT;
420 data << (uint8)1;
421 data << plName;
422 guild->BroadcastPacket(&data);
424 //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)");
426 SendGuildCommandResult(GUILD_QUIT_S, guild->GetName(), GUILD_PLAYER_NO_MORE_IN_GUILD);
429 void WorldSession::HandleGuildDisbandOpcode(WorldPacket& /*recvPacket*/)
431 std::string name;
432 Guild *guild;
434 //sLog.outDebug("WORLD: Received CMSG_GUILD_DISBAND");
436 guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
437 if(!guild)
439 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
440 return;
442 if(GetPlayer()->GetGUID() != guild->GetLeader())
444 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
445 return;
448 guild->Disband();
450 //sLog.outDebug("WORLD: Guild Sucefully Disbanded");
453 void WorldSession::HandleGuildLeaderOpcode(WorldPacket& recvPacket)
455 CHECK_PACKET_SIZE(recvPacket, 1);
457 std::string name;
458 Player *oldLeader = GetPlayer();
459 Guild *guild;
461 //sLog.outDebug("WORLD: Received CMSG_GUILD_LEADER");
463 recvPacket >> name;
465 if(!normalizePlayerName(name))
466 return;
468 guild = objmgr.GetGuildById(oldLeader->GetGuildId());
470 if (!guild)
472 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
473 return;
476 if (oldLeader->GetGUID() != guild->GetLeader())
478 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
479 return;
482 uint64 newLeaderGUID;
483 MemberSlot* slot = guild->GetMemberSlot(name, newLeaderGUID);
485 if (!slot)
487 SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_IN_GUILD_S);
488 return;
491 guild->SetLeader(newLeaderGUID);
492 guild->ChangeRank(oldLeader->GetGUID(), GR_OFFICER);
494 WorldPacket data(SMSG_GUILD_EVENT, (2+20)); // guess size
495 data << (uint8)GE_LEADER_CHANGED;
496 data << (uint8)2;
497 data << oldLeader->GetName();
498 data << name.c_str();
499 guild->BroadcastPacket(&data);
501 //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)");
504 void WorldSession::HandleGuildMOTDOpcode(WorldPacket& recvPacket)
506 Guild *guild;
507 std::string MOTD;
509 //sLog.outDebug("WORLD: Received CMSG_GUILD_MOTD");
511 guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
512 if(!guild)
514 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
515 return;
517 if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_SETMOTD))
519 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
520 return;
523 if(!recvPacket.empty())
524 recvPacket >> MOTD;
525 else
526 MOTD = "";
528 guild->SetMOTD(MOTD);
530 WorldPacket data(SMSG_GUILD_EVENT, (2+MOTD.size()+1));
531 data << (uint8)GE_MOTD;
532 data << (uint8)1;
533 data << MOTD;
534 guild->BroadcastPacket(&data);
536 //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)");
539 void WorldSession::HandleGuildSetPublicNoteOpcode(WorldPacket& recvPacket)
541 CHECK_PACKET_SIZE(recvPacket, 1);
543 std::string name,PNOTE;
545 //sLog.outDebug("WORLD: Received CMSG_GUILD_SET_PUBLIC_NOTE");
547 recvPacket >> name;
549 if(!normalizePlayerName(name))
550 return;
552 Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
554 if (!guild)
556 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
557 return;
560 if (!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_EPNOTE))
562 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
563 return;
566 uint64 plGuid;
567 MemberSlot* slot = guild->GetMemberSlot(name, plGuid);
569 if (!slot)
571 SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_IN_GUILD_S);
572 return;
575 recvPacket >> PNOTE;
576 guild->SetPNOTE(plGuid, PNOTE);
578 guild->Roster(this);
581 void WorldSession::HandleGuildSetOfficerNoteOpcode(WorldPacket& recvPacket)
583 CHECK_PACKET_SIZE(recvPacket, 1);
585 std::string plName, OFFNOTE;
587 //sLog.outDebug("WORLD: Received CMSG_GUILD_SET_OFFICER_NOTE");
589 recvPacket >> plName;
591 if (!normalizePlayerName(plName))
592 return;
594 Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
596 if (!guild)
598 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
599 return;
601 if (!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_EOFFNOTE))
603 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
604 return;
607 uint64 plGuid;
608 MemberSlot* slot = guild->GetMemberSlot(plName, plGuid);
610 if (!slot)
612 SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S);
613 return;
616 recvPacket >> OFFNOTE;
617 guild->SetOFFNOTE(plGuid, OFFNOTE);
619 guild->Roster(this);
622 void WorldSession::HandleGuildRankOpcode(WorldPacket& recvPacket)
624 CHECK_PACKET_SIZE(recvPacket, 4+4+1+4*13);
625 //recvPacket.hexlike();
627 Guild *guild;
628 std::string rankname;
629 uint32 rankId;
630 uint32 rights, MoneyPerDay;
631 uint32 BankRights;
632 uint32 BankSlotPerDay;
634 //sLog.outDebug("WORLD: Received CMSG_GUILD_RANK");
636 guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
637 if(!guild)
639 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
640 return;
643 else if(GetPlayer()->GetGUID() != guild->GetLeader())
645 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
646 return;
649 recvPacket >> rankId;
650 recvPacket >> rights;
651 recvPacket >> rankname;
652 recvPacket >> MoneyPerDay;
654 for (int i = 0; i < GUILD_BANK_MAX_TABS; ++i)
656 recvPacket >> BankRights;
657 recvPacket >> BankSlotPerDay;
658 guild->SetBankRightsAndSlots(rankId, uint8(i), uint16(BankRights & 0xFF), uint16(BankSlotPerDay), true);
660 sLog.outDebug("WORLD: Changed RankName to %s , Rights to 0x%.4X", rankname.c_str(), rights);
662 guild->SetBankMoneyPerDay(rankId, MoneyPerDay);
663 guild->SetRankName(rankId, rankname);
665 if(rankId==GR_GUILDMASTER) // prevent loss leader rights
666 rights |= GR_RIGHT_ALL;
668 guild->SetRankRights(rankId, rights);
670 guild->Query(this);
671 guild->Roster(this);
674 void WorldSession::HandleGuildAddRankOpcode(WorldPacket& recvPacket)
676 CHECK_PACKET_SIZE(recvPacket, 1);
678 Guild *guild;
679 std::string rankname;
681 //sLog.outDebug("WORLD: Received CMSG_GUILD_ADD_RANK");
683 guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
684 if(!guild)
686 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
687 return;
690 if(GetPlayer()->GetGUID() != guild->GetLeader())
692 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
693 return;
696 if(guild->GetNrRanks() >= GUILD_MAX_RANKS) // client not let create more 10 than ranks
697 return;
699 recvPacket >> rankname;
701 guild->CreateRank(rankname, GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK);
703 guild->Query(this);
704 guild->Roster(this);
707 void WorldSession::HandleGuildDelRankOpcode(WorldPacket& /*recvPacket*/)
709 Guild *guild;
710 std::string rankname;
712 //sLog.outDebug("WORLD: Received CMSG_GUILD_DEL_RANK");
714 guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
715 if(!guild)
717 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
718 return;
721 else if(GetPlayer()->GetGUID() != guild->GetLeader())
723 SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
724 return;
727 guild->DelRank();
729 guild->Query(this);
730 guild->Roster(this);
733 void WorldSession::SendGuildCommandResult(uint32 typecmd, const std::string& str,uint32 cmdresult)
735 WorldPacket data(SMSG_GUILD_COMMAND_RESULT, (8+str.size()+1));
736 data << typecmd;
737 data << str;
738 data << cmdresult;
739 SendPacket(&data);
741 //sLog.outDebug("WORLD: Sent (SMSG_GUILD_COMMAND_RESULT)");
744 void WorldSession::HandleGuildChangeInfoOpcode(WorldPacket& recvPacket)
746 CHECK_PACKET_SIZE(recvPacket, 1);
748 //sLog.outDebug("WORLD: Received CMSG_GUILD_INFO_TEXT");
750 std::string GINFO;
752 recvPacket >> GINFO;
754 Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
755 if(!guild)
757 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
758 return;
761 if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_MODIFY_GUILD_INFO))
763 SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PERMISSIONS);
764 return;
767 guild->SetGINFO(GINFO);
770 void WorldSession::HandleGuildSaveEmblemOpcode(WorldPacket& recvPacket)
772 CHECK_PACKET_SIZE(recvPacket, 8+4+4+4+4+4);
774 //sLog.outDebug("WORLD: Received MSG_SAVE_GUILD_EMBLEM");
776 uint64 vendorGuid;
778 uint32 EmblemStyle;
779 uint32 EmblemColor;
780 uint32 BorderStyle;
781 uint32 BorderColor;
782 uint32 BackgroundColor;
784 recvPacket >> vendorGuid;
786 Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, vendorGuid,UNIT_NPC_FLAG_TABARDDESIGNER);
787 if (!pCreature)
789 //"That's not an emblem vendor!"
790 SendSaveGuildEmblem(ERR_GUILDEMBLEM_INVALIDVENDOR);
791 sLog.outDebug("WORLD: HandleGuildSaveEmblemOpcode - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(vendorGuid));
792 return;
795 // remove fake death
796 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
797 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
799 recvPacket >> EmblemStyle;
800 recvPacket >> EmblemColor;
801 recvPacket >> BorderStyle;
802 recvPacket >> BorderColor;
803 recvPacket >> BackgroundColor;
805 Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
806 if(!guild)
808 //"You are not part of a guild!";
809 SendSaveGuildEmblem(ERR_GUILDEMBLEM_NOGUILD);
810 return;
813 if (guild->GetLeader() != GetPlayer()->GetGUID())
815 //"Only guild leaders can create emblems."
816 SendSaveGuildEmblem(ERR_GUILDEMBLEM_NOTGUILDMASTER);
817 return;
820 if(GetPlayer()->GetMoney() < 10*GOLD)
822 //"You can't afford to do that."
823 SendSaveGuildEmblem(ERR_GUILDEMBLEM_NOTENOUGHMONEY);
824 return;
827 GetPlayer()->ModifyMoney(-10*GOLD);
828 guild->SetEmblem(EmblemStyle, EmblemColor, BorderStyle, BorderColor, BackgroundColor);
830 //"Guild Emblem saved."
831 SendSaveGuildEmblem(ERR_GUILDEMBLEM_SUCCESS);
833 guild->Query(this);
836 void WorldSession::HandleGuildEventLogOpcode(WorldPacket& /* recvPacket */)
838 // empty
839 sLog.outDebug("WORLD: Received (MSG_GUILD_EVENT_LOG_QUERY)");
840 //recvPacket.hexlike();
842 uint32 GuildId = GetPlayer()->GetGuildId();
843 if (GuildId == 0)
844 return;
846 Guild *pGuild = objmgr.GetGuildById(GuildId);
847 if(!pGuild)
848 return;
850 pGuild->DisplayGuildEventlog(this);
853 /****** GUILD BANK *******/
855 void WorldSession::HandleGuildBankGetMoneyAmount( WorldPacket & /* recv_data */ )
857 sLog.outDebug("WORLD: Received (MSG_GUILD_BANK_MONEY_WITHDRAWN)");
858 //recv_data.hexlike();
860 uint32 GuildId = GetPlayer()->GetGuildId();
861 if (GuildId == 0)
862 return;
864 Guild *pGuild = objmgr.GetGuildById(GuildId);
865 if(!pGuild)
866 return;
868 pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow());
871 void WorldSession::HandleGuildBankGetRights( WorldPacket& /* recv_data */ )
873 sLog.outDebug("WORLD: Received (MSG_GUILD_PERMISSIONS)");
875 uint32 GuildId = GetPlayer()->GetGuildId();
876 if (GuildId == 0)
877 return;
879 Guild *pGuild = objmgr.GetGuildById(GuildId);
880 if(!pGuild)
881 return;
883 uint32 rankId = GetPlayer()->GetRank();
885 WorldPacket data(MSG_GUILD_PERMISSIONS, 4*15+1);
886 data << uint32(rankId); // guild rank id
887 data << uint32(pGuild->GetRankRights(rankId)); // rank rights
888 // money per day left
889 data << uint32(pGuild->GetMemberMoneyWithdrawRem(GetPlayer()->GetGUIDLow()));
890 data << uint8(pGuild->GetPurchasedTabs()); // tabs count
891 for(int i = 0; i < GUILD_BANK_MAX_TABS; ++i)
893 data << uint32(pGuild->GetBankRights(rankId, uint8(i)));
894 data << uint32(pGuild->GetMemberSlotWithdrawRem(GetPlayer()->GetGUIDLow(), uint8(i)));
896 SendPacket(&data);
897 sLog.outDebug("WORLD: Sent (MSG_GUILD_PERMISSIONS)");
900 /* Called when clicking on Guild bank gameobject */
901 void WorldSession::HandleGuildBankQuery( WorldPacket & recv_data )
903 sLog.outDebug("WORLD: Received (CMSG_GUILD_BANKER_ACTIVATE)");
904 CHECK_PACKET_SIZE(recv_data,8+1);
905 uint64 GoGuid;
906 uint8 unk;
907 recv_data >> GoGuid >> unk;
909 if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
910 return;
912 if (uint32 GuildId = GetPlayer()->GetGuildId())
914 if(Guild *pGuild = objmgr.GetGuildById(GuildId))
916 pGuild->DisplayGuildBankTabsInfo(this);
917 return;
921 SendGuildCommandResult(GUILD_BANK_S, "", GUILD_PLAYER_NOT_IN_GUILD);
924 /* Called when opening guild bank tab only (first one) */
925 void WorldSession::HandleGuildBankTabColon( WorldPacket & recv_data )
927 sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_QUERY_TAB)");
928 CHECK_PACKET_SIZE(recv_data,8+1+1);
929 uint64 GoGuid;
930 uint8 TabId,unk1;
931 recv_data >> GoGuid >> TabId >> unk1;
933 if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
934 return;
936 uint32 GuildId = GetPlayer()->GetGuildId();
937 if (GuildId == 0)
938 return;
940 Guild *pGuild = objmgr.GetGuildById(GuildId);
941 if(!pGuild)
942 return;
944 // Let's update the amount of gold the player can withdraw before displaying the content
945 // This is usefull if money withdraw right has changed
946 pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow());
948 pGuild->DisplayGuildBankContent(this, TabId);
951 void WorldSession::HandleGuildBankDeposit( WorldPacket & recv_data )
953 sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_DEPOSIT_MONEY)");
954 CHECK_PACKET_SIZE(recv_data,8+4);
955 uint64 GoGuid;
956 uint32 money;
957 recv_data >> GoGuid >> money;
959 if (!money)
960 return;
962 if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
963 return;
965 uint32 GuildId = GetPlayer()->GetGuildId();
966 if (GuildId == 0)
967 return;
969 Guild *pGuild = objmgr.GetGuildById(GuildId);
970 if(!pGuild)
971 return;
973 if (GetPlayer()->GetMoney() < money)
974 return;
976 CharacterDatabase.BeginTransaction();
978 pGuild->SetBankMoney(pGuild->GetGuildBankMoney()+money);
979 GetPlayer()->ModifyMoney(-int(money));
980 GetPlayer()->SaveDataFieldToDB(); //contains money
982 CharacterDatabase.CommitTransaction();
984 // logging money
985 if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
987 sLog.outCommand(_player->GetSession()->GetAccountId(),"GM %s (Account: %u) deposit money (Amount: %u) to guild bank (Guild ID %u)",
988 _player->GetName(),_player->GetSession()->GetAccountId(),money,GuildId);
991 // log
992 pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_MONEY, uint8(0), GetPlayer()->GetGUIDLow(), money);
994 pGuild->DisplayGuildBankTabsInfo(this);
995 pGuild->DisplayGuildBankContent(this, 0);
996 pGuild->DisplayGuildBankMoneyUpdate();
999 void WorldSession::HandleGuildBankWithdraw( WorldPacket & recv_data )
1001 sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_WITHDRAW_MONEY)");
1002 CHECK_PACKET_SIZE(recv_data,8+4);
1003 uint64 GoGuid;
1004 uint32 money;
1005 recv_data >> GoGuid >> money;
1007 if (!money)
1008 return;
1010 if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
1011 return;
1013 uint32 GuildId = GetPlayer()->GetGuildId();
1014 if (GuildId == 0)
1015 return;
1017 Guild *pGuild = objmgr.GetGuildById(GuildId);
1018 if(!pGuild)
1019 return;
1021 if (pGuild->GetGuildBankMoney()<money) // not enough money in bank
1022 return;
1024 if (!pGuild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_WITHDRAW_GOLD))
1025 return;
1027 CharacterDatabase.BeginTransaction();
1029 if (!pGuild->MemberMoneyWithdraw(money, GetPlayer()->GetGUIDLow()))
1031 CharacterDatabase.RollbackTransaction();
1032 return;
1035 GetPlayer()->ModifyMoney(money);
1036 GetPlayer()->SaveDataFieldToDB(); // contains money
1038 CharacterDatabase.CommitTransaction();
1040 // Log
1041 pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_MONEY, uint8(0), GetPlayer()->GetGUIDLow(), money);
1043 pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow());
1044 pGuild->DisplayGuildBankTabsInfo(this);
1045 pGuild->DisplayGuildBankContent(this, 0);
1046 pGuild->DisplayGuildBankMoneyUpdate();
1049 void WorldSession::HandleGuildBankDepositItem( WorldPacket & recv_data )
1051 sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_SWAP_ITEMS)");
1052 //recv_data.hexlike();
1054 uint64 GoGuid;
1055 uint8 BankToBank;
1057 uint8 BankTab, BankTabSlot, AutoStore, AutoStoreCount, PlayerSlot, PlayerBag, SplitedAmount = 0;
1058 uint8 BankTabDst, BankTabSlotDst, unk2, ToChar = 1;
1059 uint32 ItemEntry, unk1;
1061 CHECK_PACKET_SIZE(recv_data,8+1);
1062 recv_data >> GoGuid >> BankToBank;
1063 if (BankToBank)
1065 // recheck
1066 CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1+1+4+1+1+4+1+1);
1067 recv_data >> BankTabDst;
1068 recv_data >> BankTabSlotDst;
1069 recv_data >> unk1; // always 0
1070 recv_data >> BankTab;
1071 recv_data >> BankTabSlot;
1072 recv_data >> ItemEntry;
1073 recv_data >> unk2; // always 0
1074 recv_data >> SplitedAmount;
1076 if (BankTabSlotDst >= GUILD_BANK_MAX_SLOTS)
1077 return;
1078 if (BankTabDst == BankTab && BankTabSlotDst == BankTabSlot)
1079 return;
1081 else
1083 // recheck
1084 CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1+1+4+1);
1085 recv_data >> BankTab;
1086 recv_data >> BankTabSlot;
1087 recv_data >> ItemEntry;
1088 recv_data >> AutoStore;
1089 if (AutoStore)
1091 // recheck
1092 CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1);
1093 recv_data >> AutoStoreCount;
1095 // recheck
1096 CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1+1);
1097 recv_data >> PlayerBag;
1098 recv_data >> PlayerSlot;
1099 if (!AutoStore)
1101 // recheck
1102 CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1+1);
1103 recv_data >> ToChar;
1104 recv_data >> SplitedAmount;
1107 if (BankTabSlot >= GUILD_BANK_MAX_SLOTS && BankTabSlot != 0xFF)
1108 return;
1111 if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
1112 return;
1114 uint32 GuildId = GetPlayer()->GetGuildId();
1115 if (GuildId == 0)
1116 return;
1118 Guild *pGuild = objmgr.GetGuildById(GuildId);
1119 if(!pGuild)
1120 return;
1122 Player *pl = GetPlayer();
1124 // Bank <-> Bank
1125 if (BankToBank)
1127 // empty operation
1128 if(BankTab==BankTabDst && BankTabSlot==BankTabSlotDst)
1129 return;
1131 Item *pItemSrc = pGuild->GetItem(BankTab, BankTabSlot);
1132 if (!pItemSrc) // may prevent crash
1133 return;
1135 if(SplitedAmount > pItemSrc->GetCount())
1136 return; // cheating?
1137 else if(SplitedAmount == pItemSrc->GetCount())
1138 SplitedAmount = 0; // no split
1140 Item *pItemDst = pGuild->GetItem(BankTabDst, BankTabSlotDst);
1142 if(BankTab!=BankTabDst)
1144 // check dest pos rights (if different tabs)
1145 if(!pGuild->IsMemberHaveRights(pl->GetGUIDLow(), BankTabDst, GUILD_BANK_RIGHT_DEPOSIT_ITEM))
1146 return;
1148 // check source pos rights (if different tabs)
1149 uint32 remRight = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTab);
1150 if(remRight <= 0)
1151 return;
1154 if (SplitedAmount)
1155 { // Bank -> Bank item split (in empty or non empty slot
1156 GuildItemPosCountVec dest;
1157 uint8 msg = pGuild->CanStoreItem(BankTabDst,BankTabSlotDst,dest,SplitedAmount,pItemSrc,false);
1158 if( msg != EQUIP_ERR_OK )
1160 pl->SendEquipError( msg, pItemSrc, NULL );
1161 return;
1164 Item *pNewItem = pItemSrc->CloneItem( SplitedAmount );
1165 if( !pNewItem )
1167 pl->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, pItemSrc, NULL );
1168 return;
1171 CharacterDatabase.BeginTransaction();
1172 pGuild->LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTab, pl->GetGUIDLow(), pItemSrc->GetEntry(), SplitedAmount, BankTabDst);
1174 pl->ItemRemovedQuestCheck( pItemSrc->GetEntry(), SplitedAmount );
1175 pItemSrc->SetCount( pItemSrc->GetCount() - SplitedAmount );
1176 pItemSrc->FSetState(ITEM_CHANGED);
1177 pItemSrc->SaveToDB(); // not in inventory and can be save standalone
1178 pGuild->StoreItem(BankTabDst,dest,pNewItem);
1179 CharacterDatabase.CommitTransaction();
1181 else // non split
1183 GuildItemPosCountVec gDest;
1184 uint8 msg = pGuild->CanStoreItem(BankTabDst,BankTabSlotDst,gDest,pItemSrc->GetCount(),pItemSrc,false);
1185 if( msg == EQUIP_ERR_OK ) // merge to
1187 CharacterDatabase.BeginTransaction();
1188 pGuild->LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTab, pl->GetGUIDLow(), pItemSrc->GetEntry(), pItemSrc->GetCount(), BankTabDst);
1190 pGuild->RemoveItem(BankTab, BankTabSlot);
1191 pGuild->StoreItem(BankTabDst, gDest, pItemSrc);
1192 CharacterDatabase.CommitTransaction();
1194 else // swap
1196 gDest.clear();
1197 uint8 msg = pGuild->CanStoreItem(BankTabDst,BankTabSlotDst,gDest,pItemSrc->GetCount(),pItemSrc,true);
1198 if( msg != EQUIP_ERR_OK )
1200 pl->SendEquipError( msg, pItemSrc, NULL );
1201 return;
1204 GuildItemPosCountVec gSrc;
1205 msg = pGuild->CanStoreItem(BankTab,BankTabSlot,gSrc,pItemDst->GetCount(),pItemDst,true);
1206 if( msg != EQUIP_ERR_OK )
1208 pl->SendEquipError( msg, pItemDst, NULL );
1209 return;
1212 if(BankTab!=BankTabDst)
1214 // check source pos rights (item swapped to src)
1215 if(!pGuild->IsMemberHaveRights(pl->GetGUIDLow(), BankTab, GUILD_BANK_RIGHT_DEPOSIT_ITEM))
1216 return;
1218 // check dest pos rights (item swapped to src)
1219 uint32 remRightDst = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTabDst);
1220 if(remRightDst <= 0)
1221 return;
1224 CharacterDatabase.BeginTransaction();
1225 pGuild->LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTab, pl->GetGUIDLow(), pItemSrc->GetEntry(), pItemSrc->GetCount(), BankTabDst);
1226 pGuild->LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTabDst, pl->GetGUIDLow(), pItemDst->GetEntry(), pItemDst->GetCount(), BankTab);
1228 pGuild->RemoveItem(BankTab, BankTabSlot);
1229 pGuild->RemoveItem(BankTabDst, BankTabSlotDst);
1230 pGuild->StoreItem(BankTab, gSrc, pItemDst);
1231 pGuild->StoreItem(BankTabDst, gDest, pItemSrc);
1232 CharacterDatabase.CommitTransaction();
1235 pGuild->DisplayGuildBankContentUpdate(BankTab,BankTabSlot,BankTab==BankTabDst ? BankTabSlotDst : -1);
1236 if(BankTab!=BankTabDst)
1237 pGuild->DisplayGuildBankContentUpdate(BankTabDst,BankTabSlotDst);
1238 return;
1241 // Player <-> Bank
1243 // char->bank autostore click return BankTabSlot = 255 = NULL_SLOT
1244 // do similar for bank->char
1245 if(AutoStore && ToChar)
1247 PlayerBag = NULL_BAG;
1248 PlayerSlot = NULL_SLOT;
1251 // allow work with inventory only
1252 if(!Player::IsInventoryPos(PlayerBag,PlayerSlot) && !(PlayerBag == NULL_BAG && PlayerSlot == NULL_SLOT) )
1254 _player->SendEquipError( EQUIP_ERR_NONE, NULL, NULL );
1255 return;
1258 Item *pItemBank = pGuild->GetItem(BankTab, BankTabSlot);
1259 Item *pItemChar = GetPlayer()->GetItemByPos(PlayerBag, PlayerSlot);
1260 if (!pItemChar && !pItemBank) // Nothing to do
1261 return;
1263 if (!pItemChar && !ToChar) // Problem to get item from player
1264 return;
1266 if (!pItemBank && ToChar) // Problem to get bank item
1267 return;
1269 // BankToChar swap or char to bank remaining
1271 if (ToChar) // Bank -> Char cases
1273 if(SplitedAmount > pItemBank->GetCount())
1274 return; // cheating?
1275 else if(SplitedAmount == pItemBank->GetCount())
1276 SplitedAmount = 0; // no split
1278 if (SplitedAmount)
1279 { // Bank -> Char split to slot (patly move)
1280 Item *pNewItem = pItemBank->CloneItem( SplitedAmount );
1281 if( !pNewItem )
1283 pl->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, pItemBank, NULL );
1284 return;
1287 ItemPosCountVec dest;
1288 uint8 msg = pl->CanStoreItem(PlayerBag, PlayerSlot, dest, pNewItem, false);
1289 if( msg != EQUIP_ERR_OK )
1291 pl->SendEquipError( msg, pNewItem, NULL );
1292 delete pNewItem;
1293 return;
1296 // check source pos rights (item moved to inventory)
1297 uint32 remRight = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTab);
1298 if(remRight <= 0)
1300 delete pNewItem;
1301 return;
1304 CharacterDatabase.BeginTransaction();
1305 pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), SplitedAmount);
1307 pItemBank->SetCount(pItemBank->GetCount()-SplitedAmount);
1308 pItemBank->FSetState(ITEM_CHANGED);
1309 pItemBank->SaveToDB(); // not in inventory and can be save standalone
1310 pl->MoveItemToInventory(dest,pNewItem,true);
1311 pl->SaveInventoryAndGoldToDB();
1313 pGuild->MemberItemWithdraw(BankTab, pl->GetGUIDLow());
1314 CharacterDatabase.CommitTransaction();
1316 else // Bank -> Char swap with slot (move)
1318 ItemPosCountVec dest;
1319 uint8 msg = pl->CanStoreItem(PlayerBag, PlayerSlot, dest, pItemBank, false);
1320 if( msg == EQUIP_ERR_OK ) // merge case
1322 // check source pos rights (item moved to inventory)
1323 uint32 remRight = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTab);
1324 if(remRight <= 0)
1325 return;
1327 CharacterDatabase.BeginTransaction();
1328 pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), pItemBank->GetCount());
1330 pGuild->RemoveItem(BankTab, BankTabSlot);
1331 pl->MoveItemToInventory(dest,pItemBank,true);
1332 pl->SaveInventoryAndGoldToDB();
1334 pGuild->MemberItemWithdraw(BankTab, pl->GetGUIDLow());
1335 CharacterDatabase.CommitTransaction();
1337 else // Bank <-> Char swap items
1339 // check source pos rights (item swapped to bank)
1340 if(!pGuild->IsMemberHaveRights(pl->GetGUIDLow(), BankTab, GUILD_BANK_RIGHT_DEPOSIT_ITEM))
1341 return;
1343 if(pItemChar)
1345 if(!pItemChar->CanBeTraded())
1347 _player->SendEquipError( EQUIP_ERR_ITEMS_CANT_BE_SWAPPED, pItemChar, NULL );
1348 return;
1352 ItemPosCountVec iDest;
1353 msg = pl->CanStoreItem(PlayerBag, PlayerSlot, iDest, pItemBank, true);
1354 if( msg != EQUIP_ERR_OK )
1356 pl->SendEquipError( msg, pItemBank, NULL );
1357 return;
1360 GuildItemPosCountVec gDest;
1361 if(pItemChar)
1363 msg = pGuild->CanStoreItem(BankTab,BankTabSlot,gDest,pItemChar->GetCount(),pItemChar,true);
1364 if( msg != EQUIP_ERR_OK )
1366 pl->SendEquipError( msg, pItemChar, NULL );
1367 return;
1371 // check source pos rights (item moved to inventory)
1372 uint32 remRight = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTab);
1373 if(remRight <= 0)
1374 return;
1376 if(pItemChar)
1378 // logging item move to bank
1379 if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
1381 sLog.outCommand(_player->GetSession()->GetAccountId(),"GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u )",
1382 _player->GetName(),_player->GetSession()->GetAccountId(),
1383 pItemChar->GetProto()->Name1,pItemChar->GetEntry(),pItemChar->GetCount(),
1384 GuildId);
1388 CharacterDatabase.BeginTransaction();
1389 pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), pItemBank->GetCount());
1390 if(pItemChar)
1391 pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), pItemChar->GetCount());
1393 pGuild->RemoveItem(BankTab, BankTabSlot);
1394 if(pItemChar)
1396 pl->MoveItemFromInventory(PlayerBag, PlayerSlot, true);
1397 pItemChar->DeleteFromInventoryDB();
1400 if(pItemChar)
1401 pGuild->StoreItem(BankTab, gDest, pItemChar);
1402 pl->MoveItemToInventory(iDest,pItemBank,true);
1403 pl->SaveInventoryAndGoldToDB();
1405 pGuild->MemberItemWithdraw(BankTab, pl->GetGUIDLow());
1406 CharacterDatabase.CommitTransaction();
1409 pGuild->DisplayGuildBankContentUpdate(BankTab,BankTabSlot);
1410 return;
1411 } // End "To char" part
1413 // Char -> Bank cases
1415 if(!pItemChar->CanBeTraded())
1417 _player->SendEquipError( EQUIP_ERR_ITEMS_CANT_BE_SWAPPED, pItemChar, NULL );
1418 return;
1421 // check source pos rights (item moved to bank)
1422 if(!pGuild->IsMemberHaveRights(pl->GetGUIDLow(), BankTab, GUILD_BANK_RIGHT_DEPOSIT_ITEM))
1423 return;
1425 if(SplitedAmount > pItemChar->GetCount())
1426 return; // cheating?
1427 else if(SplitedAmount == pItemChar->GetCount())
1428 SplitedAmount = 0; // no split
1430 if (SplitedAmount)
1431 { // Char -> Bank split to empty or non-empty slot (partly move)
1432 GuildItemPosCountVec dest;
1433 uint8 msg = pGuild->CanStoreItem(BankTab,BankTabSlot,dest,SplitedAmount,pItemChar,false);
1434 if( msg != EQUIP_ERR_OK )
1436 pl->SendEquipError( msg, pItemChar, NULL );
1437 return;
1440 Item *pNewItem = pItemChar->CloneItem( SplitedAmount );
1441 if( !pNewItem )
1443 pl->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, pItemChar, NULL );
1444 return;
1447 // logging item move to bank (before items merge
1448 if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
1450 sLog.outCommand(_player->GetSession()->GetAccountId(),"GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u )",
1451 _player->GetName(),_player->GetSession()->GetAccountId(),
1452 pItemChar->GetProto()->Name1,pItemChar->GetEntry(),SplitedAmount,GuildId);
1455 CharacterDatabase.BeginTransaction();
1456 pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), SplitedAmount);
1458 pl->ItemRemovedQuestCheck( pItemChar->GetEntry(), SplitedAmount );
1459 pItemChar->SetCount(pItemChar->GetCount()-SplitedAmount);
1460 pItemChar->SetState(ITEM_CHANGED);
1461 pl->SaveInventoryAndGoldToDB();
1462 pGuild->StoreItem(BankTab, dest, pNewItem);
1463 CharacterDatabase.CommitTransaction();
1465 pGuild->DisplayGuildBankContentUpdate(BankTab,dest);
1467 else // Char -> Bank swap with empty or non-empty (move)
1469 GuildItemPosCountVec dest;
1470 uint8 msg = pGuild->CanStoreItem(BankTab,BankTabSlot,dest,pItemChar->GetCount(),pItemChar,false);
1471 if( msg == EQUIP_ERR_OK ) // merge
1473 // logging item move to bank
1474 if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
1476 sLog.outCommand(_player->GetSession()->GetAccountId(),"GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u )",
1477 _player->GetName(),_player->GetSession()->GetAccountId(),
1478 pItemChar->GetProto()->Name1,pItemChar->GetEntry(),pItemChar->GetCount(),
1479 GuildId);
1482 CharacterDatabase.BeginTransaction();
1483 pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), pItemChar->GetCount());
1485 pl->MoveItemFromInventory(PlayerBag, PlayerSlot, true);
1486 pItemChar->DeleteFromInventoryDB();
1488 pGuild->StoreItem(BankTab,dest,pItemChar);
1489 pl->SaveInventoryAndGoldToDB();
1490 CharacterDatabase.CommitTransaction();
1492 pGuild->DisplayGuildBankContentUpdate(BankTab,dest);
1494 else // Char <-> Bank swap items (posible NULL bank item)
1496 ItemPosCountVec iDest;
1497 if(pItemBank)
1499 msg = pl->CanStoreItem(PlayerBag, PlayerSlot, iDest, pItemBank, true);
1500 if( msg != EQUIP_ERR_OK )
1502 pl->SendEquipError( msg, pItemBank, NULL );
1503 return;
1507 GuildItemPosCountVec gDest;
1508 msg = pGuild->CanStoreItem(BankTab,BankTabSlot,gDest,pItemChar->GetCount(),pItemChar,true);
1509 if( msg != EQUIP_ERR_OK )
1511 pl->SendEquipError( msg, pItemChar, NULL );
1512 return;
1515 if(pItemBank)
1517 // check bank pos rights (item swapped with inventory)
1518 uint32 remRight = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTab);
1519 if(remRight <= 0)
1520 return;
1523 // logging item move to bank
1524 if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
1526 sLog.outCommand(_player->GetSession()->GetAccountId(),"GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u )",
1527 _player->GetName(),_player->GetSession()->GetAccountId(),
1528 pItemChar->GetProto()->Name1,pItemChar->GetEntry(),pItemChar->GetCount(),
1529 GuildId);
1532 CharacterDatabase.BeginTransaction();
1533 if(pItemBank)
1534 pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), pItemBank->GetCount());
1535 pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), pItemChar->GetCount());
1537 pl->MoveItemFromInventory(PlayerBag, PlayerSlot, true);
1538 pItemChar->DeleteFromInventoryDB();
1539 if(pItemBank)
1540 pGuild->RemoveItem(BankTab, BankTabSlot);
1542 pGuild->StoreItem(BankTab,gDest,pItemChar);
1543 if(pItemBank)
1544 pl->MoveItemToInventory(iDest,pItemBank,true);
1545 pl->SaveInventoryAndGoldToDB();
1546 if(pItemBank)
1547 pGuild->MemberItemWithdraw(BankTab, pl->GetGUIDLow());
1548 CharacterDatabase.CommitTransaction();
1550 pGuild->DisplayGuildBankContentUpdate(BankTab,gDest);
1555 void WorldSession::HandleGuildBankBuyTab( WorldPacket & recv_data )
1557 sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_BUY_TAB)");
1558 CHECK_PACKET_SIZE(recv_data, 8+1);
1559 //recv_data.hexlike();
1560 uint64 GoGuid;
1561 uint8 TabId;
1563 recv_data >> GoGuid;
1564 recv_data >> TabId;
1566 if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
1567 return;
1569 uint32 GuildId = GetPlayer()->GetGuildId();
1570 if (GuildId==0)
1571 return;
1573 Guild *pGuild = objmgr.GetGuildById(GuildId);
1574 if(!pGuild)
1575 return;
1577 uint32 TabCost = objmgr.GetGuildBankTabPrice(TabId) * GOLD;
1578 if (!TabCost)
1579 return;
1581 if (pGuild->GetPurchasedTabs() >= GUILD_BANK_MAX_TABS)
1582 return;
1584 if (TabId != pGuild->GetPurchasedTabs()) // purchased_tabs = 0 when buying Tab 0, that is why this check can be made
1586 sLog.outError("Error: trying to buy a tab non contigous to owned ones");
1587 return;
1590 if (GetPlayer()->GetMoney() < TabCost) // Should not happen, this is checked by client
1591 return;
1593 // Go on with creating tab
1594 pGuild->CreateNewBankTab();
1595 GetPlayer()->ModifyMoney(-int(TabCost));
1596 pGuild->SetBankMoneyPerDay(GetPlayer()->GetRank(), WITHDRAW_MONEY_UNLIMITED);
1597 pGuild->SetBankRightsAndSlots(GetPlayer()->GetRank(), TabId, GUILD_BANK_RIGHT_FULL, WITHDRAW_SLOT_UNLIMITED, true);
1598 pGuild->Roster(this);
1599 pGuild->DisplayGuildBankTabsInfo(this);
1602 void WorldSession::HandleGuildBankModifyTab( WorldPacket & recv_data )
1604 sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_UPDATE_TAB)");
1605 //recv_data.hexlike();
1606 CHECK_PACKET_SIZE(recv_data, 8+1+1+1);
1607 uint64 GoGuid;
1608 uint8 TabId;
1609 std::string Name;
1610 std::string IconIndex;
1612 recv_data >> GoGuid;
1613 recv_data >> TabId;
1614 recv_data >> Name;
1615 recv_data >> IconIndex;
1617 if(Name.empty())
1618 return;
1620 if(IconIndex.empty())
1621 return;
1623 if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
1624 return;
1626 uint32 GuildId = GetPlayer()->GetGuildId();
1627 if (GuildId==0)
1628 return;
1630 Guild *pGuild = objmgr.GetGuildById(GuildId);
1631 if(!pGuild)
1632 return;
1634 pGuild->SetGuildBankTabInfo(TabId, Name, IconIndex);
1635 pGuild->DisplayGuildBankTabsInfo(this);
1636 pGuild->DisplayGuildBankContent(this, TabId);
1639 void WorldSession::HandleGuildBankLog( WorldPacket & recv_data )
1641 sLog.outDebug("WORLD: Received (MSG_GUILD_BANK_LOG_QUERY)");
1642 CHECK_PACKET_SIZE(recv_data, 1);
1644 uint32 GuildId = GetPlayer()->GetGuildId();
1645 if (GuildId == 0)
1646 return;
1648 Guild *pGuild = objmgr.GetGuildById(GuildId);
1649 if(!pGuild)
1650 return;
1652 uint8 TabId;
1653 recv_data >> TabId;
1655 pGuild->DisplayGuildBankLogs(this, TabId);
1658 void WorldSession::HandleGuildBankTabText(WorldPacket &recv_data)
1660 sLog.outDebug("WORLD: Received MSG_QUERY_GUILD_BANK_TEXT");
1661 CHECK_PACKET_SIZE(recv_data, 1);
1663 uint32 GuildId = GetPlayer()->GetGuildId();
1664 if (GuildId == 0)
1665 return;
1667 Guild *pGuild = objmgr.GetGuildById(GuildId);
1668 if(!pGuild)
1669 return;
1671 uint8 TabId;
1672 recv_data >> TabId;
1674 pGuild->SendGuildBankTabText(this, TabId);
1677 void WorldSession::HandleGuildBankSetTabText(WorldPacket &recv_data)
1679 sLog.outDebug("WORLD: Received CMSG_SET_GUILD_BANK_TEXT");
1680 CHECK_PACKET_SIZE(recv_data, 1+1);
1682 uint32 GuildId = GetPlayer()->GetGuildId();
1683 if (GuildId == 0)
1684 return;
1686 Guild *pGuild = objmgr.GetGuildById(GuildId);
1687 if(!pGuild)
1688 return;
1690 uint8 TabId;
1691 std::string Text;
1692 recv_data >> TabId;
1693 recv_data >> Text;
1695 pGuild->SetGuildBankTabText(TabId, Text);
1698 void WorldSession::SendSaveGuildEmblem( uint32 msg )
1700 WorldPacket data(MSG_SAVE_GUILD_EMBLEM, 4);
1701 data << uint32(msg); // not part of guild
1702 SendPacket( &data );