aboutsummaryrefslogtreecommitdiff
path: root/src/game/GuildHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/GuildHandler.cpp')
-rw-r--r--src/game/GuildHandler.cpp1815
1 files changed, 1815 insertions, 0 deletions
diff --git a/src/game/GuildHandler.cpp b/src/game/GuildHandler.cpp
new file mode 100644
index 00000000000..a82a45fde40
--- /dev/null
+++ b/src/game/GuildHandler.cpp
@@ -0,0 +1,1815 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Common.h"
+#include "WorldPacket.h"
+#include "WorldSession.h"
+#include "World.h"
+#include "ObjectMgr.h"
+#include "Log.h"
+#include "Opcodes.h"
+#include "Guild.h"
+#include "MapManager.h"
+#include "GossipDef.h"
+#include "SocialMgr.h"
+
+void WorldSession::HandleGuildQueryOpcode(WorldPacket& recvPacket)
+{
+ CHECK_PACKET_SIZE(recvPacket, 4);
+
+ uint32 guildId;
+ Guild *guild;
+
+ //sLog.outDebug("WORLD: Received CMSG_GUILD_QUERY");
+
+ recvPacket >> guildId;
+
+ guild = objmgr.GetGuildById(guildId);
+ if(!guild)
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
+ return;
+ }
+
+ guild->Query(this);
+}
+
+void WorldSession::HandleGuildCreateOpcode(WorldPacket& recvPacket)
+{
+ CHECK_PACKET_SIZE(recvPacket, 1);
+
+ std::string gname;
+
+ //sLog.outDebug("WORLD: Received CMSG_GUILD_CREATE");
+
+ recvPacket >> gname;
+
+ if(GetPlayer()->GetGuildId())
+ return;
+
+ Guild *guild = new Guild;
+ if(!guild->create(GetPlayer()->GetGUID(),gname))
+ {
+ delete guild;
+ return;
+ }
+
+ objmgr.AddGuild(guild);
+}
+
+void WorldSession::HandleGuildInviteOpcode(WorldPacket& recvPacket)
+{
+ CHECK_PACKET_SIZE(recvPacket, 1);
+
+ std::string Invitedname, plname;
+
+ //sLog.outDebug("WORLD: Received CMSG_GUILD_INVITE");
+
+ Player * player = NULL;
+
+ recvPacket >> Invitedname;
+
+ if(normalizePlayerName(Invitedname))
+ player = ObjectAccessor::Instance().FindPlayerByName(Invitedname.c_str());
+
+ if(!player)
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, Invitedname, GUILD_PLAYER_NOT_FOUND);
+ return;
+ }
+
+ Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
+ if(!guild)
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
+ return;
+ }
+
+ // OK result but not send invite
+ if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
+ return;
+
+ // not let enemies sign guild charter
+ if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != GetPlayer()->GetTeam())
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, Invitedname, GUILD_NOT_ALLIED);
+ return;
+ }
+
+ if(player->GetGuildId())
+ {
+ plname = player->GetName();
+ SendGuildCommandResult(GUILD_INVITE_S, plname, ALREADY_IN_GUILD);
+ return;
+ }
+
+ if(player->GetGuildIdInvited())
+ {
+ plname = player->GetName();
+ SendGuildCommandResult(GUILD_INVITE_S, plname, ALREADY_INVITED_TO_GUILD);
+ return;
+ }
+
+ if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_INVITE))
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
+ return;
+ }
+
+ sLog.outDebug("Player %s Invited %s to Join his Guild", GetPlayer()->GetName(), Invitedname.c_str());
+
+ player->SetGuildIdInvited(GetPlayer()->GetGuildId());
+ // Put record into guildlog
+ guild->LogGuildEvent(GUILD_EVENT_LOG_INVITE_PLAYER, GetPlayer()->GetGUIDLow(), player->GetGUIDLow(), 0);
+
+ WorldPacket data(SMSG_GUILD_INVITE, (8+10)); // guess size
+ data << GetPlayer()->GetName();
+ data << guild->GetName();
+ player->GetSession()->SendPacket(&data);
+
+ //sLog.outDebug("WORLD: Sent (SMSG_GUILD_INVITE)");
+}
+
+void WorldSession::HandleGuildRemoveOpcode(WorldPacket& recvPacket)
+{
+ CHECK_PACKET_SIZE(recvPacket, 1);
+
+ std::string plName;
+ uint64 plGuid;
+ uint32 plGuildId;
+ Guild *guild;
+ Player *player;
+
+ //sLog.outDebug("WORLD: Received CMSG_GUILD_REMOVE");
+
+ recvPacket >> plName;
+
+ if(!normalizePlayerName(plName))
+ return;
+
+ player = ObjectAccessor::Instance().FindPlayerByName(plName.c_str());
+ guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
+
+ if(player)
+ {
+ plGuid = player->GetGUID();
+ plGuildId = player->GetGuildId();
+ }
+ else
+ {
+ plGuid = objmgr.GetPlayerGUIDByName(plName);
+ plGuildId = Player::GetGuildIdFromDB(plGuid);
+ }
+
+ if(!guild)
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
+ return;
+ }
+
+ if(!plGuid)
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_FOUND);
+ return;
+ }
+
+ if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_REMOVE))
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
+ return;
+ }
+
+ if(plGuid == guild->GetLeader())
+ {
+ SendGuildCommandResult(GUILD_QUIT_S, "", GUILD_LEADER_LEAVE);
+ return;
+ }
+
+ if(GetPlayer()->GetGuildId() != plGuildId)
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S);
+ return;
+ }
+
+ guild->DelMember(plGuid);
+ // Put record into guildlog
+ guild->LogGuildEvent(GUILD_EVENT_LOG_UNINVITE_PLAYER, GetPlayer()->GetGUIDLow(), GUID_LOPART(plGuid), 0);
+
+ WorldPacket data(SMSG_GUILD_EVENT, (2+20)); // guess size
+ data << (uint8)GE_REMOVED;
+ data << (uint8)2; // strings count
+ data << plName;
+ data << GetPlayer()->GetName();
+ guild->BroadcastPacket(&data);
+}
+
+void WorldSession::HandleGuildAcceptOpcode(WorldPacket& /*recvPacket*/)
+{
+ Guild *guild;
+ Player *player = GetPlayer();
+
+ //sLog.outDebug("WORLD: Received CMSG_GUILD_ACCEPT");
+
+ guild = objmgr.GetGuildById(player->GetGuildIdInvited());
+ if(!guild || player->GetGuildId())
+ return;
+
+ // not let enemies sign guild charter
+ if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != objmgr.GetPlayerTeamByGUID(guild->GetLeader()))
+ return;
+
+ if(!guild->AddMember(GetPlayer()->GetGUID(),guild->GetLowestRank()))
+ return;
+ // Put record into guildlog
+ guild->LogGuildEvent(GUILD_EVENT_LOG_JOIN_GUILD, GetPlayer()->GetGUIDLow(), 0, 0);
+
+ WorldPacket data(SMSG_GUILD_EVENT, (2+10)); // guess size
+ data << (uint8)GE_JOINED;
+ data << (uint8)1;
+ data << player->GetName();
+ guild->BroadcastPacket(&data);
+
+ //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)");
+}
+
+void WorldSession::HandleGuildDeclineOpcode(WorldPacket& /*recvPacket*/)
+{
+ //sLog.outDebug("WORLD: Received CMSG_GUILD_DECLINE");
+
+ GetPlayer()->SetGuildIdInvited(0);
+ GetPlayer()->SetInGuild(0);
+}
+
+void WorldSession::HandleGuildInfoOpcode(WorldPacket& /*recvPacket*/)
+{
+ Guild *guild;
+ //sLog.outDebug("WORLD: Received CMSG_GUILD_INFO");
+
+ guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
+ if(!guild)
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
+ return;
+ }
+
+ WorldPacket data(SMSG_GUILD_INFO, (5*4 + guild->GetName().size() + 1));
+ data << guild->GetName();
+ data << guild->GetCreatedDay();
+ data << guild->GetCreatedMonth();
+ data << guild->GetCreatedYear();
+ data << guild->GetMemberSize();
+ data << guild->GetMemberSize();
+
+ SendPacket(&data);
+}
+
+void WorldSession::HandleGuildRosterOpcode(WorldPacket& /*recvPacket*/)
+{
+ //sLog.outDebug("WORLD: Received CMSG_GUILD_ROSTER");
+
+ Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
+ if(!guild)
+ return;
+
+ guild->Roster(this);
+}
+
+void WorldSession::HandleGuildPromoteOpcode(WorldPacket& recvPacket)
+{
+ CHECK_PACKET_SIZE(recvPacket, 1);
+
+ std::string plName;
+ uint64 plGuid;
+ uint32 plGuildId;
+ uint32 plRankId;
+ Player *player;
+ Guild *guild;
+
+ //sLog.outDebug("WORLD: Received CMSG_GUILD_PROMOTE");
+
+ recvPacket >> plName;
+
+ if(!normalizePlayerName(plName))
+ return;
+
+ player = ObjectAccessor::Instance().FindPlayerByName(plName.c_str());
+ guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
+ if(player)
+ {
+ plGuid = player->GetGUID();
+ plGuildId = player->GetGuildId();
+ plRankId = player->GetRank();
+ }
+ else
+ {
+ plGuid = objmgr.GetPlayerGUIDByName(plName);
+ plGuildId = Player::GetGuildIdFromDB(plGuid);
+ plRankId = Player::GetRankFromDB(plGuid);
+ }
+
+ if(!guild)
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
+ return;
+ }
+ else if(!plGuid)
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_FOUND);
+ return;
+ }
+ else if(plGuid == GetPlayer()->GetGUID())
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_NAME_INVALID);
+ return;
+ }
+ else if(GetPlayer()->GetGuildId() != plGuildId)
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S);
+ return;
+ }
+ else if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_PROMOTE))
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
+ return;
+ }
+ else if((plRankId-1) == 0 || (plRankId-1) < this->GetPlayer()->GetRank())
+ return;
+
+ if(plRankId < 1)
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_INTERNAL);
+ return;
+ }
+
+ uint32 newRankId = plRankId < guild->GetNrRanks() ? plRankId-1 : guild->GetNrRanks()-1;
+
+ guild->ChangeRank(plGuid, newRankId);
+ // Put record into guildlog
+ guild->LogGuildEvent(GUILD_EVENT_LOG_PROMOTE_PLAYER, GetPlayer()->GetGUIDLow(), GUID_LOPART(plGuid), newRankId);
+
+ WorldPacket data(SMSG_GUILD_EVENT, (2+30)); // guess size
+ data << (uint8)GE_PROMOTION;
+ data << (uint8)3;
+ data << GetPlayer()->GetName();
+ data << plName;
+ data << guild->GetRankName(newRankId);
+ guild->BroadcastPacket(&data);
+}
+
+void WorldSession::HandleGuildDemoteOpcode(WorldPacket& recvPacket)
+{
+ CHECK_PACKET_SIZE(recvPacket, 1);
+
+ std::string plName;
+ uint64 plGuid;
+ uint32 plGuildId;
+ uint32 plRankId;
+ Player *player;
+ Guild *guild;
+
+ //sLog.outDebug("WORLD: Received CMSG_GUILD_DEMOTE");
+
+ recvPacket >> plName;
+
+ if(!normalizePlayerName(plName))
+ return;
+
+ player = ObjectAccessor::Instance().FindPlayerByName(plName.c_str());
+ guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
+ if(player)
+ {
+ plGuid = player->GetGUID();
+ plGuildId = player->GetGuildId();
+ plRankId = player->GetRank();
+ }
+ else
+ {
+ plGuid = objmgr.GetPlayerGUIDByName(plName);
+ plGuildId = Player::GetGuildIdFromDB(plGuid);
+ plRankId = Player::GetRankFromDB(plGuid);
+ }
+
+ if(!guild)
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
+ return;
+ }
+
+ if( !plGuid )
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_FOUND);
+ return;
+ }
+
+ if(plGuid == GetPlayer()->GetGUID())
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_NAME_INVALID);
+ return;
+ }
+
+ if(GetPlayer()->GetGuildId() != plGuildId)
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S);
+ return;
+ }
+
+ if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_DEMOTE))
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
+ return;
+ }
+
+ if((plRankId+1) >= guild->GetNrRanks() || plRankId <= this->GetPlayer()->GetRank())
+ return;
+
+ guild->ChangeRank(plGuid, (plRankId+1));
+ // Put record into guildlog
+ guild->LogGuildEvent(GUILD_EVENT_LOG_DEMOTE_PLAYER, GetPlayer()->GetGUIDLow(), GUID_LOPART(plGuid), (plRankId+1));
+
+ WorldPacket data(SMSG_GUILD_EVENT, (2+30)); // guess size
+ data << (uint8)GE_DEMOTION;
+ data << (uint8)3;
+ data << GetPlayer()->GetName();
+ data << plName;
+ data << guild->GetRankName(plRankId+1);
+ guild->BroadcastPacket(&data);
+}
+
+void WorldSession::HandleGuildLeaveOpcode(WorldPacket& /*recvPacket*/)
+{
+ std::string plName;
+ Guild *guild;
+
+ //sLog.outDebug("WORLD: Received CMSG_GUILD_LEAVE");
+
+ guild = objmgr.GetGuildById(_player->GetGuildId());
+ if(!guild)
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
+ return;
+ }
+ if(_player->GetGUID() == guild->GetLeader() && guild->GetMemberSize() > 1)
+ {
+ SendGuildCommandResult(GUILD_QUIT_S, "", GUILD_LEADER_LEAVE);
+ return;
+ }
+
+ if(_player->GetGUID() == guild->GetLeader())
+ {
+ guild->Disband();
+ return;
+ }
+
+ plName = _player->GetName();
+
+ guild->DelMember(_player->GetGUID());
+ // Put record into guildlog
+ guild->LogGuildEvent(GUILD_EVENT_LOG_LEAVE_GUILD, _player->GetGUIDLow(), 0, 0);
+
+ WorldPacket data(SMSG_GUILD_EVENT, (2+10)); // guess size
+ data << (uint8)GE_LEFT;
+ data << (uint8)1;
+ data << plName;
+ guild->BroadcastPacket(&data);
+
+ //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)");
+
+ SendGuildCommandResult(GUILD_QUIT_S, guild->GetName(), GUILD_PLAYER_NO_MORE_IN_GUILD);
+}
+
+void WorldSession::HandleGuildDisbandOpcode(WorldPacket& /*recvPacket*/)
+{
+ std::string name;
+ Guild *guild;
+
+ //sLog.outDebug("WORLD: Received CMSG_GUILD_DISBAND");
+
+ guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
+ if(!guild)
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
+ return;
+ }
+ if(GetPlayer()->GetGUID() != guild->GetLeader())
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
+ return;
+ }
+
+ guild->Disband();
+
+ //sLog.outDebug("WORLD: Guild Sucefully Disbanded");
+}
+
+void WorldSession::HandleGuildLeaderOpcode(WorldPacket& recvPacket)
+{
+ CHECK_PACKET_SIZE(recvPacket, 1);
+
+ std::string name;
+ Player *newLeader;
+ uint64 newLeaderGUID;
+ uint32 newLeaderGuild;
+ Player *oldLeader = GetPlayer();
+ Guild *guild;
+
+ //sLog.outDebug("WORLD: Received CMSG_GUILD_LEADER");
+
+ recvPacket >> name;
+
+ if(!normalizePlayerName(name))
+ return;
+
+ newLeader = ObjectAccessor::Instance().FindPlayerByName(name.c_str());
+ if(newLeader)
+ {
+ newLeaderGUID = newLeader->GetGUID();
+ newLeaderGuild = newLeader->GetGuildId();
+ }
+ else
+ {
+ newLeaderGUID = objmgr.GetPlayerGUIDByName(name);
+ newLeaderGuild = Player::GetGuildIdFromDB(newLeaderGUID);
+ }
+ guild = objmgr.GetGuildById(oldLeader->GetGuildId());
+
+ if(!guild)
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
+ return;
+ }
+ else if(!newLeaderGUID)
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_FOUND);
+ return;
+ }
+ if(oldLeader->GetGuildId() != newLeaderGuild)
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_IN_GUILD_S);
+ return;
+ }
+ if(oldLeader->GetGUID() != guild->GetLeader())
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
+ return;
+ }
+
+ guild->SetLeader(newLeaderGUID);
+ guild->ChangeRank(oldLeader->GetGUID(), GR_OFFICER);
+
+ WorldPacket data(SMSG_GUILD_EVENT, (2+20)); // guess size
+ data << (uint8)GE_LEADER_CHANGED;
+ data << (uint8)2;
+ data << oldLeader->GetName();
+ data << name.c_str();
+ guild->BroadcastPacket(&data);
+
+ //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)");
+}
+
+void WorldSession::HandleGuildMOTDOpcode(WorldPacket& recvPacket)
+{
+ Guild *guild;
+ std::string MOTD;
+
+ //sLog.outDebug("WORLD: Received CMSG_GUILD_MOTD");
+
+ guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
+ if(!guild)
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
+ return;
+ }
+ if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_SETMOTD))
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
+ return;
+ }
+
+ if(!recvPacket.empty())
+ recvPacket >> MOTD;
+ else
+ MOTD = "";
+
+ guild->SetMOTD(MOTD);
+
+ WorldPacket data(SMSG_GUILD_EVENT, (2+MOTD.size()+1));
+ data << (uint8)GE_MOTD;
+ data << (uint8)1;
+ data << MOTD;
+ guild->BroadcastPacket(&data);
+
+ //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)");
+}
+
+void WorldSession::HandleGuildSetPublicNoteOpcode(WorldPacket& recvPacket)
+{
+ CHECK_PACKET_SIZE(recvPacket, 1);
+
+ Guild *guild;
+ Player *player;
+ uint64 plGuid;
+ uint32 plGuildId;
+ std::string name,PNOTE;
+
+ //sLog.outDebug("WORLD: Received CMSG_GUILD_SET_PUBLIC_NOTE");
+
+ recvPacket >> name;
+
+ if(!normalizePlayerName(name))
+ return;
+
+ player = ObjectAccessor::Instance().FindPlayerByName(name.c_str());
+ guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
+ if(player)
+ {
+ plGuid = player->GetGUID();
+ plGuildId = player->GetGuildId();
+ }
+ else
+ {
+ plGuid = objmgr.GetPlayerGUIDByName(name);
+ plGuildId = Player::GetGuildIdFromDB(plGuid);
+ }
+
+ if(!guild)
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
+ return;
+ }
+ else if(!plGuid)
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_FOUND);
+ return;
+ }
+ else if(GetPlayer()->GetGuildId() != plGuildId)
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_IN_GUILD_S);
+ return;
+ }
+ if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_EPNOTE))
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
+ return;
+ }
+
+ recvPacket >> PNOTE;
+ guild->SetPNOTE(plGuid, PNOTE);
+
+ guild->Roster(this);
+}
+
+void WorldSession::HandleGuildSetOfficerNoteOpcode(WorldPacket& recvPacket)
+{
+ CHECK_PACKET_SIZE(recvPacket, 1);
+
+ Guild *guild;
+ Player *player;
+ uint64 plGuid;
+ uint32 plGuildId;
+ std::string plName, OFFNOTE;
+
+ //sLog.outDebug("WORLD: Received CMSG_GUILD_SET_OFFICER_NOTE");
+
+ recvPacket >> plName;
+
+ if(!normalizePlayerName(plName))
+ return;
+
+ player = ObjectAccessor::Instance().FindPlayerByName(plName.c_str());
+ guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
+ if(player)
+ {
+ plGuid = player->GetGUID();
+ plGuildId = player->GetGuildId();
+ }
+ else
+ {
+ plGuid = objmgr.GetPlayerGUIDByName(plName);
+ plGuildId = Player::GetGuildIdFromDB(plGuid);
+ }
+
+ if(!guild)
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
+ return;
+ }
+ else if( !plGuid )
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_FOUND);
+ return;
+ }
+ else if(GetPlayer()->GetGuildId() != plGuildId)
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S);
+ return;
+ }
+ if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_EOFFNOTE))
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
+ return;
+ }
+
+ recvPacket >> OFFNOTE;
+ guild->SetOFFNOTE(plGuid, OFFNOTE);
+
+ guild->Roster(this);
+}
+
+void WorldSession::HandleGuildRankOpcode(WorldPacket& recvPacket)
+{
+ CHECK_PACKET_SIZE(recvPacket, 4+4+1+4*13);
+ //recvPacket.hexlike();
+
+ Guild *guild;
+ std::string rankname;
+ uint32 rankId;
+ uint32 rights, MoneyPerDay;
+ uint32 BankRights;
+ uint32 BankSlotPerDay;
+
+ //sLog.outDebug("WORLD: Received CMSG_GUILD_RANK");
+
+ guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
+ if(!guild)
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
+ return;
+ }
+
+ else if(GetPlayer()->GetGUID() != guild->GetLeader())
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
+ return;
+ }
+
+ recvPacket >> rankId;
+ recvPacket >> rights;
+ recvPacket >> rankname;
+ recvPacket >> MoneyPerDay;
+
+ for (int i = 0; i < GUILD_BANK_MAX_TABS; ++i)
+ {
+ recvPacket >> BankRights;
+ recvPacket >> BankSlotPerDay;
+ guild->SetBankRightsAndSlots(rankId, uint8(i), uint16(BankRights & 0xFF), uint16(BankSlotPerDay), true);
+ }
+ sLog.outDebug("WORLD: Changed RankName to %s , Rights to 0x%.4X", rankname.c_str(), rights);
+
+ guild->SetBankMoneyPerDay(rankId, MoneyPerDay);
+ guild->SetRankName(rankId, rankname);
+
+ if(rankId==GR_GUILDMASTER) // prevent loss leader rights
+ rights |= GR_RIGHT_ALL;
+
+ guild->SetRankRights(rankId, rights);
+
+ guild->Query(this);
+ guild->Roster(this);
+}
+
+void WorldSession::HandleGuildAddRankOpcode(WorldPacket& recvPacket)
+{
+ CHECK_PACKET_SIZE(recvPacket, 1);
+
+ Guild *guild;
+ std::string rankname;
+
+ //sLog.outDebug("WORLD: Received CMSG_GUILD_ADD_RANK");
+
+ guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
+ if(!guild)
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
+ return;
+ }
+
+ if(GetPlayer()->GetGUID() != guild->GetLeader())
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
+ return;
+ }
+
+ if(guild->GetNrRanks() >= GUILD_MAX_RANKS) // client not let create more 10 than ranks
+ return;
+
+ recvPacket >> rankname;
+
+ guild->CreateRank(rankname, GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK);
+
+ guild->Query(this);
+ guild->Roster(this);
+}
+
+void WorldSession::HandleGuildDelRankOpcode(WorldPacket& /*recvPacket*/)
+{
+ Guild *guild;
+ std::string rankname;
+
+ //sLog.outDebug("WORLD: Received CMSG_GUILD_DEL_RANK");
+
+ guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
+ if(!guild)
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
+ return;
+ }
+
+ else if(GetPlayer()->GetGUID() != guild->GetLeader())
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
+ return;
+ }
+
+ guild->DelRank();
+
+ guild->Query(this);
+ guild->Roster(this);
+}
+
+void WorldSession::SendGuildCommandResult(uint32 typecmd,std::string str,uint32 cmdresult)
+{
+ WorldPacket data(SMSG_GUILD_COMMAND_RESULT, (8+str.size()+1));
+ data << typecmd;
+ data << str;
+ data << cmdresult;
+ SendPacket(&data);
+
+ //sLog.outDebug("WORLD: Sent (SMSG_GUILD_COMMAND_RESULT)");
+}
+
+void WorldSession::HandleGuildChangeInfoOpcode(WorldPacket& recvPacket)
+{
+ CHECK_PACKET_SIZE(recvPacket, 1);
+
+ //sLog.outDebug("WORLD: Received CMSG_GUILD_INFO_TEXT");
+
+ std::string GINFO;
+
+ recvPacket >> GINFO;
+
+ Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
+ if(!guild)
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
+ return;
+ }
+
+ if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_MODIFY_GUILD_INFO))
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PERMISSIONS);
+ return;
+ }
+
+ guild->SetGINFO(GINFO);
+}
+
+void WorldSession::HandleGuildSaveEmblemOpcode(WorldPacket& recvPacket)
+{
+ CHECK_PACKET_SIZE(recvPacket, 8+4+4+4+4+4);
+
+ //sLog.outDebug("WORLD: Received MSG_SAVE_GUILD_EMBLEM");
+
+ uint64 vendorGuid;
+
+ uint32 EmblemStyle;
+ uint32 EmblemColor;
+ uint32 BorderStyle;
+ uint32 BorderColor;
+ uint32 BackgroundColor;
+
+ recvPacket >> vendorGuid;
+
+ Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, vendorGuid,UNIT_NPC_FLAG_TABARDDESIGNER);
+ if (!pCreature)
+ {
+ //"That's not an emblem vendor!"
+ SendSaveGuildEmblem(ERR_GUILDEMBLEM_INVALIDVENDOR);
+ sLog.outDebug("WORLD: HandleGuildSaveEmblemOpcode - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(vendorGuid));
+ return;
+ }
+
+ // remove fake death
+ if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
+ GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+
+ recvPacket >> EmblemStyle;
+ recvPacket >> EmblemColor;
+ recvPacket >> BorderStyle;
+ recvPacket >> BorderColor;
+ recvPacket >> BackgroundColor;
+
+ Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
+ if(!guild)
+ {
+ //"You are not part of a guild!";
+ SendSaveGuildEmblem(ERR_GUILDEMBLEM_NOGUILD);
+ return;
+ }
+
+ if (guild->GetLeader() != GetPlayer()->GetGUID())
+ {
+ //"Only guild leaders can create emblems."
+ SendSaveGuildEmblem(ERR_GUILDEMBLEM_NOTGUILDMASTER);
+ return;
+ }
+
+ if(GetPlayer()->GetMoney() < 10*GOLD)
+ {
+ //"You can't afford to do that."
+ SendSaveGuildEmblem(ERR_GUILDEMBLEM_NOTENOUGHMONEY);
+ return;
+ }
+
+ GetPlayer()->ModifyMoney(-10*GOLD);
+ guild->SetEmblem(EmblemStyle, EmblemColor, BorderStyle, BorderColor, BackgroundColor);
+
+ //"Guild Emblem saved."
+ SendSaveGuildEmblem(ERR_GUILDEMBLEM_SUCCESS);
+
+ guild->Query(this);
+}
+
+void WorldSession::HandleGuildEventLogOpcode(WorldPacket& /* recvPacket */)
+{
+ // empty
+ sLog.outDebug("WORLD: Received (MSG_GUILD_EVENT_LOG_QUERY)");
+ //recvPacket.hexlike();
+
+ uint32 GuildId = GetPlayer()->GetGuildId();
+ if (GuildId == 0)
+ return;
+
+ Guild *pGuild = objmgr.GetGuildById(GuildId);
+ if(!pGuild)
+ return;
+
+ pGuild->DisplayGuildEventlog(this);
+}
+
+/****** GUILD BANK *******/
+
+void WorldSession::HandleGuildBankGetMoneyAmount( WorldPacket & /* recv_data */ )
+{
+ sLog.outDebug("WORLD: Received (MSG_GUILD_BANK_MONEY_WITHDRAWN)");
+ //recv_data.hexlike();
+
+ uint32 GuildId = GetPlayer()->GetGuildId();
+ if (GuildId == 0)
+ return;
+
+ Guild *pGuild = objmgr.GetGuildById(GuildId);
+ if(!pGuild)
+ return;
+
+ pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow());
+}
+
+void WorldSession::HandleGuildBankGetRights( WorldPacket& /* recv_data */ )
+{
+ sLog.outDebug("WORLD: Received (MSG_GUILD_PERMISSIONS)");
+
+ uint32 GuildId = GetPlayer()->GetGuildId();
+ if (GuildId == 0)
+ return;
+
+ Guild *pGuild = objmgr.GetGuildById(GuildId);
+ if(!pGuild)
+ return;
+
+ uint32 rankId = GetPlayer()->GetRank();
+
+ WorldPacket data(MSG_GUILD_PERMISSIONS, 4*15+1);
+ data << uint32(rankId); // guild rank id
+ data << uint32(pGuild->GetRankRights(rankId)); // rank rights
+ // money per day left
+ data << uint32(pGuild->GetMemberMoneyWithdrawRem(GetPlayer()->GetGUIDLow()));
+ data << uint8(pGuild->GetPurchasedTabs()); // tabs count
+ for(int i = 0; i < GUILD_BANK_MAX_TABS; ++i)
+ {
+ data << uint32(pGuild->GetBankRights(rankId, uint8(i)));
+ data << uint32(pGuild->GetMemberSlotWithdrawRem(GetPlayer()->GetGUIDLow(), uint8(i)));
+ }
+ SendPacket(&data);
+ sLog.outDebug("WORLD: Sent (MSG_GUILD_PERMISSIONS)");
+}
+
+/* Called when clicking on Guild bank gameobject */
+void WorldSession::HandleGuildBankQuery( WorldPacket & recv_data )
+{
+ sLog.outDebug("WORLD: Received (CMSG_GUILD_BANKER_ACTIVATE)");
+ CHECK_PACKET_SIZE(recv_data,8+1);
+ uint64 GoGuid;
+ uint8 unk;
+ recv_data >> GoGuid >> unk;
+
+ if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
+ return;
+
+ if (uint32 GuildId = GetPlayer()->GetGuildId())
+ {
+ if(Guild *pGuild = objmgr.GetGuildById(GuildId))
+ {
+ pGuild->DisplayGuildBankTabsInfo(this);
+ return;
+ }
+ }
+
+ SendGuildCommandResult(GUILD_BANK_S, "", GUILD_PLAYER_NOT_IN_GUILD);
+}
+
+/* Called when opening guild bank tab only (first one) */
+void WorldSession::HandleGuildBankTabColon( WorldPacket & recv_data )
+{
+ sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_QUERY_TAB)");
+ CHECK_PACKET_SIZE(recv_data,8+1+1);
+ uint64 GoGuid;
+ uint8 TabId,unk1;
+ recv_data >> GoGuid >> TabId >> unk1;
+
+ if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
+ return;
+
+ uint32 GuildId = GetPlayer()->GetGuildId();
+ if (GuildId == 0)
+ return;
+
+ Guild *pGuild = objmgr.GetGuildById(GuildId);
+ if(!pGuild)
+ return;
+
+ // Let's update the amount of gold the player can withdraw before displaying the content
+ // This is usefull if money withdraw right has changed
+ pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow());
+
+ pGuild->DisplayGuildBankContent(this, TabId);
+}
+
+void WorldSession::HandleGuildBankDeposit( WorldPacket & recv_data )
+{
+ sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_DEPOSIT_MONEY)");
+ CHECK_PACKET_SIZE(recv_data,8+4);
+ uint64 GoGuid;
+ uint32 money;
+ recv_data >> GoGuid >> money;
+
+ if (!money)
+ return;
+
+ if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
+ return;
+
+ uint32 GuildId = GetPlayer()->GetGuildId();
+ if (GuildId == 0)
+ return;
+
+ Guild *pGuild = objmgr.GetGuildById(GuildId);
+ if(!pGuild)
+ return;
+
+ if (GetPlayer()->GetMoney() < money)
+ return;
+
+ CharacterDatabase.BeginTransaction();
+
+ pGuild->SetBankMoney(pGuild->GetGuildBankMoney()+money);
+ GetPlayer()->ModifyMoney(-int(money));
+ GetPlayer()->SaveGoldToDB();
+
+ CharacterDatabase.CommitTransaction();
+
+ // logging money
+ if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
+ {
+ sLog.outCommand("GM %s (Account: %u) deposit money (Amount: %u) to guild bank (Guild ID %u)",
+ _player->GetName(),_player->GetSession()->GetAccountId(),money,GuildId);
+ }
+
+ // log
+ pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_MONEY, uint8(0), GetPlayer()->GetGUIDLow(), money);
+
+ pGuild->DisplayGuildBankTabsInfo(this);
+ pGuild->DisplayGuildBankContent(this, 0);
+ pGuild->DisplayGuildBankMoneyUpdate();
+}
+
+void WorldSession::HandleGuildBankWithdraw( WorldPacket & recv_data )
+{
+ sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_WITHDRAW_MONEY)");
+ CHECK_PACKET_SIZE(recv_data,8+4);
+ uint64 GoGuid;
+ uint32 money;
+ recv_data >> GoGuid >> money;
+
+ if (!money)
+ return;
+
+ if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
+ return;
+
+ uint32 GuildId = GetPlayer()->GetGuildId();
+ if (GuildId == 0)
+ return;
+
+ Guild *pGuild = objmgr.GetGuildById(GuildId);
+ if(!pGuild)
+ return;
+
+ if (pGuild->GetGuildBankMoney()<money) // not enough money in bank
+ return;
+
+ if (!pGuild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_WITHDRAW_GOLD))
+ return;
+
+ CharacterDatabase.BeginTransaction();
+
+ if (!pGuild->MemberMoneyWithdraw(money, GetPlayer()->GetGUIDLow()))
+ {
+ CharacterDatabase.RollbackTransaction();
+ return;
+ }
+
+ GetPlayer()->ModifyMoney(money);
+ GetPlayer()->SaveGoldToDB();
+
+ CharacterDatabase.CommitTransaction();
+
+ // Log
+ pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_MONEY, uint8(0), GetPlayer()->GetGUIDLow(), money);
+
+ pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow());
+ pGuild->DisplayGuildBankTabsInfo(this);
+ pGuild->DisplayGuildBankContent(this, 0);
+ pGuild->DisplayGuildBankMoneyUpdate();
+}
+
+void WorldSession::HandleGuildBankDepositItem( WorldPacket & recv_data )
+{
+ sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_SWAP_ITEMS)");
+ //recv_data.hexlike();
+
+ uint64 GoGuid;
+ uint8 BankToBank;
+
+ uint8 BankTab, BankTabSlot, AutoStore, AutoStoreCount, PlayerSlot, PlayerBag, SplitedAmount = 0;
+ uint8 BankTabDst, BankTabSlotDst, unk2, ToChar = 1;
+ uint32 ItemEntry, unk1;
+ bool BankToChar = false;
+
+ CHECK_PACKET_SIZE(recv_data,8+1);
+ recv_data >> GoGuid >> BankToBank;
+ if (BankToBank)
+ {
+ // recheck
+ CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1+1+4+1+1+4+1+1);
+ recv_data >> BankTabDst;
+ recv_data >> BankTabSlotDst;
+ recv_data >> unk1; // always 0
+ recv_data >> BankTab;
+ recv_data >> BankTabSlot;
+ recv_data >> ItemEntry;
+ recv_data >> unk2; // always 0
+ recv_data >> SplitedAmount;
+
+ if (BankTabSlotDst >= GUILD_BANK_MAX_SLOTS)
+ return;
+ if (BankTabDst == BankTab && BankTabSlotDst == BankTabSlot)
+ return;
+ }
+ else
+ {
+ // recheck
+ CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1+1+4+1);
+ recv_data >> BankTab;
+ recv_data >> BankTabSlot;
+ recv_data >> ItemEntry;
+ recv_data >> AutoStore;
+ if (AutoStore)
+ {
+ // recheck
+ CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1);
+ recv_data >> AutoStoreCount;
+ }
+ // recheck
+ CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1+1);
+ recv_data >> PlayerBag;
+ recv_data >> PlayerSlot;
+ if (!AutoStore)
+ {
+ // recheck
+ CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1+1);
+ recv_data >> ToChar;
+ recv_data >> SplitedAmount;
+ }
+
+ if (BankTabSlot >= GUILD_BANK_MAX_SLOTS && BankTabSlot != 0xFF)
+ return;
+ }
+
+ if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
+ return;
+
+ uint32 GuildId = GetPlayer()->GetGuildId();
+ if (GuildId == 0)
+ return;
+
+ Guild *pGuild = objmgr.GetGuildById(GuildId);
+ if(!pGuild)
+ return;
+
+ Player *pl = GetPlayer();
+
+ // Bank <-> Bank
+ if (BankToBank)
+ {
+ // empty operation
+ if(BankTab==BankTabDst && BankTabSlot==BankTabSlotDst)
+ return;
+
+ Item *pItemSrc = pGuild->GetItem(BankTab, BankTabSlot);
+ if (!pItemSrc) // may prevent crash
+ return;
+
+ if(SplitedAmount > pItemSrc->GetCount())
+ return; // cheating?
+ else if(SplitedAmount == pItemSrc->GetCount())
+ SplitedAmount = 0; // no split
+
+ Item *pItemDst = pGuild->GetItem(BankTabDst, BankTabSlotDst);
+
+ if(BankTab!=BankTabDst)
+ {
+ // check dest pos rights (if different tabs)
+ if(!pGuild->IsMemberHaveRights(pl->GetGUIDLow(), BankTabDst, GUILD_BANK_RIGHT_DEPOSIT_ITEM))
+ return;
+
+ // check source pos rights (if different tabs)
+ uint32 remRight = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTab);
+ if(remRight <= 0)
+ return;
+ }
+
+ if (SplitedAmount)
+ { // Bank -> Bank item split (in empty or non empty slot
+ GuildItemPosCountVec dest;
+ uint8 msg = pGuild->CanStoreItem(BankTabDst,BankTabSlotDst,dest,SplitedAmount,pItemSrc,false);
+ if( msg != EQUIP_ERR_OK )
+ {
+ pl->SendEquipError( msg, pItemSrc, NULL );
+ return;
+ }
+
+ Item *pNewItem = pItemSrc->CloneItem( SplitedAmount );
+ if( !pNewItem )
+ {
+ pl->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, pItemSrc, NULL );
+ return;
+ }
+
+ CharacterDatabase.BeginTransaction();
+ pGuild->LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTab, pl->GetGUIDLow(), pItemSrc->GetEntry(), SplitedAmount, BankTabDst);
+
+ pl->ItemRemovedQuestCheck( pItemSrc->GetEntry(), SplitedAmount );
+ pItemSrc->SetCount( pItemSrc->GetCount() - SplitedAmount );
+ pItemSrc->FSetState(ITEM_CHANGED);
+ pItemSrc->SaveToDB(); // not in inventory and can be save standalone
+ pGuild->StoreItem(BankTabDst,dest,pNewItem);
+ CharacterDatabase.CommitTransaction();
+ }
+ else // non split
+ {
+ GuildItemPosCountVec gDest;
+ uint8 msg = pGuild->CanStoreItem(BankTabDst,BankTabSlotDst,gDest,pItemSrc->GetCount(),pItemSrc,false);
+ if( msg == EQUIP_ERR_OK ) // merge to
+ {
+ CharacterDatabase.BeginTransaction();
+ pGuild->LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTab, pl->GetGUIDLow(), pItemSrc->GetEntry(), pItemSrc->GetCount(), BankTabDst);
+
+ pGuild->RemoveItem(BankTab, BankTabSlot);
+ pGuild->StoreItem(BankTabDst, gDest, pItemSrc);
+ CharacterDatabase.CommitTransaction();
+ }
+ else // swap
+ {
+ gDest.clear();
+ uint8 msg = pGuild->CanStoreItem(BankTabDst,BankTabSlotDst,gDest,pItemSrc->GetCount(),pItemSrc,true);
+ if( msg != EQUIP_ERR_OK )
+ {
+ pl->SendEquipError( msg, pItemSrc, NULL );
+ return;
+ }
+
+ GuildItemPosCountVec gSrc;
+ msg = pGuild->CanStoreItem(BankTab,BankTabSlot,gSrc,pItemDst->GetCount(),pItemDst,true);
+ if( msg != EQUIP_ERR_OK )
+ {
+ pl->SendEquipError( msg, pItemDst, NULL );
+ return;
+ }
+
+ if(BankTab!=BankTabDst)
+ {
+ // check source pos rights (item swapped to src)
+ if(!pGuild->IsMemberHaveRights(pl->GetGUIDLow(), BankTab, GUILD_BANK_RIGHT_DEPOSIT_ITEM))
+ return;
+
+ // check dest pos rights (item swapped to src)
+ uint32 remRightDst = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTabDst);
+ if(remRightDst <= 0)
+ return;
+ }
+
+ CharacterDatabase.BeginTransaction();
+ pGuild->LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTab, pl->GetGUIDLow(), pItemSrc->GetEntry(), pItemSrc->GetCount(), BankTabDst);
+ pGuild->LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTabDst, pl->GetGUIDLow(), pItemDst->GetEntry(), pItemDst->GetCount(), BankTab);
+
+ pGuild->RemoveItem(BankTab, BankTabSlot);
+ pGuild->RemoveItem(BankTabDst, BankTabSlotDst);
+ pGuild->StoreItem(BankTab, gSrc, pItemDst);
+ pGuild->StoreItem(BankTabDst, gDest, pItemSrc);
+ CharacterDatabase.CommitTransaction();
+ }
+ }
+ pGuild->DisplayGuildBankContentUpdate(BankTab,BankTabSlot,BankTab==BankTabDst ? BankTabSlotDst : -1);
+ if(BankTab!=BankTabDst)
+ pGuild->DisplayGuildBankContentUpdate(BankTabDst,BankTabSlotDst);
+ return;
+ }
+
+ // Player <-> Bank
+
+ // char->bank autostore click return BankTabSlot = 255 = NULL_SLOT
+ // do similar for bank->char
+ if(AutoStore && ToChar)
+ {
+ PlayerBag = NULL_BAG;
+ PlayerSlot = NULL_SLOT;
+ }
+
+ // allow work with inventory only
+ if(!Player::IsInventoryPos(PlayerBag,PlayerSlot) && !(PlayerBag == NULL_BAG && PlayerSlot == NULL_SLOT) )
+ {
+ _player->SendEquipError( EQUIP_ERR_NONE, NULL, NULL );
+ return;
+ }
+
+ Item *pItemBank = pGuild->GetItem(BankTab, BankTabSlot);
+ Item *pItemChar = GetPlayer()->GetItemByPos(PlayerBag, PlayerSlot);
+ if (!pItemChar && !pItemBank) // Nothing to do
+ return;
+
+ if (!pItemChar && !ToChar) // Problem to get item from player
+ return;
+
+ if (!pItemBank && ToChar) // Problem to get bank item
+ return;
+
+ // BankToChar swap or char to bank remaining
+
+ if (ToChar) // Bank -> Char cases
+ {
+ if(SplitedAmount > pItemBank->GetCount())
+ return; // cheating?
+ else if(SplitedAmount == pItemBank->GetCount())
+ SplitedAmount = 0; // no split
+
+ if (SplitedAmount)
+ { // Bank -> Char split to slot (patly move)
+ Item *pNewItem = pItemBank->CloneItem( SplitedAmount );
+ if( !pNewItem )
+ {
+ pl->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, pItemBank, NULL );
+ return;
+ }
+
+ ItemPosCountVec dest;
+ uint8 msg = pl->CanStoreItem(PlayerBag, PlayerSlot, dest, pNewItem, false);
+ if( msg != EQUIP_ERR_OK )
+ {
+ pl->SendEquipError( msg, pNewItem, NULL );
+ delete pNewItem;
+ return;
+ }
+
+ // check source pos rights (item moved to inventory)
+ uint32 remRight = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTab);
+ if(remRight <= 0)
+ {
+ delete pNewItem;
+ return;
+ }
+
+ CharacterDatabase.BeginTransaction();
+ pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), SplitedAmount);
+
+ pItemBank->SetCount(pItemBank->GetCount()-SplitedAmount);
+ pItemBank->FSetState(ITEM_CHANGED);
+ pItemBank->SaveToDB(); // not in inventory and can be save standalone
+ pl->MoveItemToInventory(dest,pNewItem,true);
+ pl->SaveInventoryAndGoldToDB();
+
+ pGuild->MemberItemWithdraw(BankTab, pl->GetGUIDLow());
+ CharacterDatabase.CommitTransaction();
+ }
+ else // Bank -> Char swap with slot (move)
+ {
+ ItemPosCountVec dest;
+ uint8 msg = pl->CanStoreItem(PlayerBag, PlayerSlot, dest, pItemBank, false);
+ if( msg == EQUIP_ERR_OK ) // merge case
+ {
+ // check source pos rights (item moved to inventory)
+ uint32 remRight = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTab);
+ if(remRight <= 0)
+ return;
+
+ CharacterDatabase.BeginTransaction();
+ pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), pItemBank->GetCount());
+
+ pGuild->RemoveItem(BankTab, BankTabSlot);
+ pl->MoveItemToInventory(dest,pItemBank,true);
+ pl->SaveInventoryAndGoldToDB();
+
+ pGuild->MemberItemWithdraw(BankTab, pl->GetGUIDLow());
+ CharacterDatabase.CommitTransaction();
+ }
+ else // Bank <-> Char swap items
+ {
+ // check source pos rights (item swapped to bank)
+ if(!pGuild->IsMemberHaveRights(pl->GetGUIDLow(), BankTab, GUILD_BANK_RIGHT_DEPOSIT_ITEM))
+ return;
+
+ if(pItemChar)
+ {
+ if(!pItemChar->CanBeTraded())
+ {
+ _player->SendEquipError( EQUIP_ERR_ITEMS_CANT_BE_SWAPPED, pItemChar, NULL );
+ return;
+ }
+ }
+
+ ItemPosCountVec iDest;
+ msg = pl->CanStoreItem(PlayerBag, PlayerSlot, iDest, pItemBank, true);
+ if( msg != EQUIP_ERR_OK )
+ {
+ pl->SendEquipError( msg, pItemBank, NULL );
+ return;
+ }
+
+ GuildItemPosCountVec gDest;
+ if(pItemChar)
+ {
+ msg = pGuild->CanStoreItem(BankTab,BankTabSlot,gDest,pItemChar->GetCount(),pItemChar,true);
+ if( msg != EQUIP_ERR_OK )
+ {
+ pl->SendEquipError( msg, pItemChar, NULL );
+ return;
+ }
+ }
+
+ // check source pos rights (item moved to inventory)
+ uint32 remRight = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTab);
+ if(remRight <= 0)
+ return;
+
+ if(pItemChar)
+ {
+ // logging item move to bank
+ if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
+ {
+ sLog.outCommand("GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u )",
+ _player->GetName(),_player->GetSession()->GetAccountId(),
+ pItemChar->GetProto()->Name1,pItemChar->GetEntry(),pItemChar->GetCount(),
+ GuildId);
+ }
+ }
+
+ CharacterDatabase.BeginTransaction();
+ pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), pItemBank->GetCount());
+ if(pItemChar)
+ pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), pItemChar->GetCount());
+
+ pGuild->RemoveItem(BankTab, BankTabSlot);
+ if(pItemChar)
+ {
+ pl->MoveItemFromInventory(PlayerBag, PlayerSlot, true);
+ pItemChar->DeleteFromInventoryDB();
+ }
+
+ if(pItemChar)
+ pGuild->StoreItem(BankTab, gDest, pItemChar);
+ pl->MoveItemToInventory(iDest,pItemBank,true);
+ pl->SaveInventoryAndGoldToDB();
+
+ pGuild->MemberItemWithdraw(BankTab, pl->GetGUIDLow());
+ CharacterDatabase.CommitTransaction();
+ }
+ }
+ pGuild->DisplayGuildBankContentUpdate(BankTab,BankTabSlot);
+ return;
+ } // End "To char" part
+
+ // Char -> Bank cases
+
+ if(!pItemChar->CanBeTraded())
+ {
+ _player->SendEquipError( EQUIP_ERR_ITEMS_CANT_BE_SWAPPED, pItemChar, NULL );
+ return;
+ }
+
+ // check source pos rights (item moved to bank)
+ if(!pGuild->IsMemberHaveRights(pl->GetGUIDLow(), BankTab, GUILD_BANK_RIGHT_DEPOSIT_ITEM))
+ return;
+
+ if(SplitedAmount > pItemChar->GetCount())
+ return; // cheating?
+ else if(SplitedAmount == pItemChar->GetCount())
+ SplitedAmount = 0; // no split
+
+ if (SplitedAmount)
+ { // Char -> Bank split to empty or non-empty slot (partly move)
+ GuildItemPosCountVec dest;
+ uint8 msg = pGuild->CanStoreItem(BankTab,BankTabSlot,dest,SplitedAmount,pItemChar,false);
+ if( msg != EQUIP_ERR_OK )
+ {
+ pl->SendEquipError( msg, pItemChar, NULL );
+ return;
+ }
+
+ Item *pNewItem = pItemChar->CloneItem( SplitedAmount );
+ if( !pNewItem )
+ {
+ pl->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, pItemChar, NULL );
+ return;
+ }
+
+ // logging item move to bank (before items merge
+ if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
+ {
+ sLog.outCommand("GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u )",
+ _player->GetName(),_player->GetSession()->GetAccountId(),
+ pItemChar->GetProto()->Name1,pItemChar->GetEntry(),SplitedAmount,GuildId);
+ }
+
+ CharacterDatabase.BeginTransaction();
+ pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), SplitedAmount);
+
+ pl->ItemRemovedQuestCheck( pItemChar->GetEntry(), SplitedAmount );
+ pItemChar->SetCount(pItemChar->GetCount()-SplitedAmount);
+ pItemChar->SetState(ITEM_CHANGED);
+ pl->SaveInventoryAndGoldToDB();
+ pGuild->StoreItem(BankTab, dest, pNewItem);
+ CharacterDatabase.CommitTransaction();
+
+ pGuild->DisplayGuildBankContentUpdate(BankTab,dest);
+ }
+ else // Char -> Bank swap with empty or non-empty (move)
+ {
+ GuildItemPosCountVec dest;
+ uint8 msg = pGuild->CanStoreItem(BankTab,BankTabSlot,dest,pItemChar->GetCount(),pItemChar,false);
+ if( msg == EQUIP_ERR_OK ) // merge
+ {
+ // logging item move to bank
+ if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
+ {
+ sLog.outCommand("GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u )",
+ _player->GetName(),_player->GetSession()->GetAccountId(),
+ pItemChar->GetProto()->Name1,pItemChar->GetEntry(),pItemChar->GetCount(),
+ GuildId);
+ }
+
+ CharacterDatabase.BeginTransaction();
+ pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), pItemChar->GetCount());
+
+ pl->MoveItemFromInventory(PlayerBag, PlayerSlot, true);
+ pItemChar->DeleteFromInventoryDB();
+
+ pGuild->StoreItem(BankTab,dest,pItemChar);
+ pl->SaveInventoryAndGoldToDB();
+ CharacterDatabase.CommitTransaction();
+
+ pGuild->DisplayGuildBankContentUpdate(BankTab,dest);
+ }
+ else // Char <-> Bank swap items (posible NULL bank item)
+ {
+ ItemPosCountVec iDest;
+ if(pItemBank)
+ {
+ msg = pl->CanStoreItem(PlayerBag, PlayerSlot, iDest, pItemBank, true);
+ if( msg != EQUIP_ERR_OK )
+ {
+ pl->SendEquipError( msg, pItemBank, NULL );
+ return;
+ }
+ }
+
+ GuildItemPosCountVec gDest;
+ msg = pGuild->CanStoreItem(BankTab,BankTabSlot,gDest,pItemChar->GetCount(),pItemChar,true);
+ if( msg != EQUIP_ERR_OK )
+ {
+ pl->SendEquipError( msg, pItemChar, NULL );
+ return;
+ }
+
+ if(pItemBank)
+ {
+ // check bank pos rights (item swapped with inventory)
+ uint32 remRight = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTab);
+ if(remRight <= 0)
+ return;
+ }
+
+ // logging item move to bank
+ if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
+ {
+ sLog.outCommand("GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u )",
+ _player->GetName(),_player->GetSession()->GetAccountId(),
+ pItemChar->GetProto()->Name1,pItemChar->GetEntry(),pItemChar->GetCount(),
+ GuildId);
+ }
+
+ CharacterDatabase.BeginTransaction();
+ if(pItemBank)
+ pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), pItemBank->GetCount());
+ pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), pItemChar->GetCount());
+
+ pl->MoveItemFromInventory(PlayerBag, PlayerSlot, true);
+ pItemChar->DeleteFromInventoryDB();
+ if(pItemBank)
+ pGuild->RemoveItem(BankTab, BankTabSlot);
+
+ pGuild->StoreItem(BankTab,gDest,pItemChar);
+ if(pItemBank)
+ pl->MoveItemToInventory(iDest,pItemBank,true);
+ pl->SaveInventoryAndGoldToDB();
+ if(pItemBank)
+ pGuild->MemberItemWithdraw(BankTab, pl->GetGUIDLow());
+ CharacterDatabase.CommitTransaction();
+
+ pGuild->DisplayGuildBankContentUpdate(BankTab,gDest);
+ }
+ }
+}
+
+void WorldSession::HandleGuildBankBuyTab( WorldPacket & recv_data )
+{
+ sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_BUY_TAB)");
+ CHECK_PACKET_SIZE(recv_data, 8+1);
+ //recv_data.hexlike();
+ uint64 GoGuid;
+ uint8 TabId;
+
+ recv_data >> GoGuid;
+ recv_data >> TabId;
+
+ if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
+ return;
+
+ uint32 GuildId = GetPlayer()->GetGuildId();
+ if (GuildId==0)
+ return;
+
+ Guild *pGuild = objmgr.GetGuildById(GuildId);
+ if(!pGuild)
+ return;
+
+ uint32 TabCost = objmgr.GetGuildBankTabPrice(TabId) * GOLD;
+ if (!TabCost)
+ return;
+
+ if (pGuild->GetPurchasedTabs() >= GUILD_BANK_MAX_TABS)
+ return;
+
+ if (TabId != pGuild->GetPurchasedTabs()) // purchased_tabs = 0 when buying Tab 0, that is why this check can be made
+ {
+ sLog.outError("Error: trying to buy a tab non contigous to owned ones");
+ return;
+ }
+
+ if (GetPlayer()->GetMoney() < TabCost) // Should not happen, this is checked by client
+ return;
+
+ // Go on with creating tab
+ pGuild->CreateNewBankTab();
+ GetPlayer()->ModifyMoney(-int(TabCost));
+ pGuild->SetBankMoneyPerDay(GetPlayer()->GetRank(), WITHDRAW_MONEY_UNLIMITED);
+ pGuild->SetBankRightsAndSlots(GetPlayer()->GetRank(), TabId, GUILD_BANK_RIGHT_FULL, WITHDRAW_SLOT_UNLIMITED, true);
+ pGuild->Roster(this);
+ pGuild->DisplayGuildBankTabsInfo(this);
+}
+
+void WorldSession::HandleGuildBankModifyTab( WorldPacket & recv_data )
+{
+ sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_UPDATE_TAB)");
+ //recv_data.hexlike();
+ CHECK_PACKET_SIZE(recv_data, 8+1+1+1);
+ uint64 GoGuid;
+ uint8 TabId;
+ std::string Name;
+ std::string IconIndex;
+
+ recv_data >> GoGuid;
+ recv_data >> TabId;
+ recv_data >> Name;
+ recv_data >> IconIndex;
+
+ if(Name.empty())
+ return;
+
+ if(IconIndex.empty())
+ return;
+
+ if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
+ return;
+
+ uint32 GuildId = GetPlayer()->GetGuildId();
+ if (GuildId==0)
+ return;
+
+ Guild *pGuild = objmgr.GetGuildById(GuildId);
+ if(!pGuild)
+ return;
+
+ pGuild->SetGuildBankTabInfo(TabId, Name, IconIndex);
+ pGuild->DisplayGuildBankTabsInfo(this);
+ pGuild->DisplayGuildBankContent(this, TabId);
+}
+
+void WorldSession::HandleGuildBankLog( WorldPacket & recv_data )
+{
+ sLog.outDebug("WORLD: Received (MSG_GUILD_BANK_LOG_QUERY)");
+ CHECK_PACKET_SIZE(recv_data, 1);
+
+ uint32 GuildId = GetPlayer()->GetGuildId();
+ if (GuildId == 0)
+ return;
+
+ Guild *pGuild = objmgr.GetGuildById(GuildId);
+ if(!pGuild)
+ return;
+
+ uint8 TabId;
+ recv_data >> TabId;
+
+ pGuild->DisplayGuildBankLogs(this, TabId);
+}
+
+void WorldSession::HandleGuildBankTabText(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: Received MSG_QUERY_GUILD_BANK_TEXT");
+ CHECK_PACKET_SIZE(recv_data, 1);
+
+ uint32 GuildId = GetPlayer()->GetGuildId();
+ if (GuildId == 0)
+ return;
+
+ Guild *pGuild = objmgr.GetGuildById(GuildId);
+ if(!pGuild)
+ return;
+
+ uint8 TabId;
+ recv_data >> TabId;
+
+ pGuild->SendGuildBankTabText(this, TabId);
+}
+
+void WorldSession::HandleGuildBankSetTabText(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: Received CMSG_SET_GUILD_BANK_TEXT");
+ CHECK_PACKET_SIZE(recv_data, 1+1);
+
+ uint32 GuildId = GetPlayer()->GetGuildId();
+ if (GuildId == 0)
+ return;
+
+ Guild *pGuild = objmgr.GetGuildById(GuildId);
+ if(!pGuild)
+ return;
+
+ uint8 TabId;
+ std::string Text;
+ recv_data >> TabId;
+ recv_data >> Text;
+
+ pGuild->SetGuildBankTabText(TabId, Text);
+}
+
+void WorldSession::SendSaveGuildEmblem( uint32 msg )
+{
+ WorldPacket data(MSG_SAVE_GUILD_EMBLEM, 4);
+ data << uint32(msg); // not part of guild
+ SendPacket( &data );
+}