root/trunk/src/game/GuildHandler.cpp @ 213

Revision 177, 53.0 kB (checked in by yumileroy, 17 years ago)

[svn] * Avoid access to bag item prototype for getting bag size, use related item
update field instead as more fast source. source mangos.
* Further reduce of DB access in guild handlers.
* Multi-locale DBC extracting - source Foks

*** Devs not responsible if all your player items drop to the ground and get eaten by ants or rabbits.. or some kind of wierd ant-rabbits..

Original author: KingPin?
Date: 2008-11-06 08:20:26-06:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
4 * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "Common.h"
22#include "WorldPacket.h"
23#include "WorldSession.h"
24#include "World.h"
25#include "ObjectMgr.h"
26#include "Log.h"
27#include "Opcodes.h"
28#include "Guild.h"
29#include "MapManager.h"
30#include "GossipDef.h"
31#include "SocialMgr.h"
32
33void WorldSession::HandleGuildQueryOpcode(WorldPacket& recvPacket)
34{
35    CHECK_PACKET_SIZE(recvPacket, 4);
36
37    uint32 guildId;
38    Guild *guild;
39
40    //sLog.outDebug("WORLD: Received CMSG_GUILD_QUERY");
41
42    recvPacket >> guildId;
43
44    guild = objmgr.GetGuildById(guildId);
45    if(!guild)
46    {
47        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
48        return;
49    }
50
51    guild->Query(this);
52}
53
54void WorldSession::HandleGuildCreateOpcode(WorldPacket& recvPacket)
55{
56    CHECK_PACKET_SIZE(recvPacket, 1);
57
58    std::string gname;
59
60    //sLog.outDebug("WORLD: Received CMSG_GUILD_CREATE");
61
62    recvPacket >> gname;
63
64    if(GetPlayer()->GetGuildId())
65        return;
66
67    Guild *guild = new Guild;
68    if(!guild->create(GetPlayer()->GetGUID(),gname))
69    {
70        delete guild;
71        return;
72    }
73
74    objmgr.AddGuild(guild);
75}
76
77void WorldSession::HandleGuildInviteOpcode(WorldPacket& recvPacket)
78{
79    CHECK_PACKET_SIZE(recvPacket, 1);
80
81    std::string Invitedname, plname;
82
83    //sLog.outDebug("WORLD: Received CMSG_GUILD_INVITE");
84
85    Player * player = NULL;
86
87    recvPacket >> Invitedname;
88
89    if(normalizePlayerName(Invitedname))
90        player = ObjectAccessor::Instance().FindPlayerByName(Invitedname.c_str());
91
92    if(!player)
93    {
94        SendGuildCommandResult(GUILD_INVITE_S, Invitedname, GUILD_PLAYER_NOT_FOUND);
95        return;
96    }
97
98    Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
99    if(!guild)
100    {
101        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
102        return;
103    }
104
105    // OK result but not send invite
106    if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
107        return;
108
109    // not let enemies sign guild charter
110    if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != GetPlayer()->GetTeam())
111    {
112        SendGuildCommandResult(GUILD_INVITE_S, Invitedname, GUILD_NOT_ALLIED);
113        return;
114    }
115
116    if(player->GetGuildId())
117    {
118        plname = player->GetName();
119        SendGuildCommandResult(GUILD_INVITE_S, plname, ALREADY_IN_GUILD);
120        return;
121    }
122
123    if(player->GetGuildIdInvited())
124    {
125        plname = player->GetName();
126        SendGuildCommandResult(GUILD_INVITE_S, plname, ALREADY_INVITED_TO_GUILD);
127        return;
128    }
129
130    if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_INVITE))
131    {
132        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
133        return;
134    }
135
136    sLog.outDebug("Player %s Invited %s to Join his Guild", GetPlayer()->GetName(), Invitedname.c_str());
137
138    player->SetGuildIdInvited(GetPlayer()->GetGuildId());
139    // Put record into guildlog
140    guild->LogGuildEvent(GUILD_EVENT_LOG_INVITE_PLAYER, GetPlayer()->GetGUIDLow(), player->GetGUIDLow(), 0);
141
142    WorldPacket data(SMSG_GUILD_INVITE, (8+10));            // guess size
143    data << GetPlayer()->GetName();
144    data << guild->GetName();
145    player->GetSession()->SendPacket(&data);
146
147    //sLog.outDebug("WORLD: Sent (SMSG_GUILD_INVITE)");
148}
149
150void WorldSession::HandleGuildRemoveOpcode(WorldPacket& recvPacket)
151{
152    CHECK_PACKET_SIZE(recvPacket, 1);
153
154    std::string plName;
155
156    //sLog.outDebug("WORLD: Received CMSG_GUILD_REMOVE");
157
158    recvPacket >> plName;
159
160    if(!normalizePlayerName(plName))
161        return;
162
163    Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
164    if(!guild)
165    {
166        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
167        return;
168    }
169   
170    if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_REMOVE))
171    {
172        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
173        return;
174    }
175   
176    uint64 plGuid = objmgr.GetPlayerGUIDByName(plName);
177
178    if(!plGuid)
179    {
180        SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_FOUND);
181        return;
182    }
183
184    if(plGuid == guild->GetLeader())
185    {
186        SendGuildCommandResult(GUILD_QUIT_S, "", GUILD_LEADER_LEAVE);
187        return;
188    }
189
190    if(!guild->IsMember(GUID_LOPART(plGuid)))
191    {
192        SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S);
193        return;
194    }
195
196    guild->DelMember(plGuid);
197    // Put record into guildlog
198    guild->LogGuildEvent(GUILD_EVENT_LOG_UNINVITE_PLAYER, GetPlayer()->GetGUIDLow(), GUID_LOPART(plGuid), 0);
199
200    WorldPacket data(SMSG_GUILD_EVENT, (2+20));             // guess size
201    data << (uint8)GE_REMOVED;
202    data << (uint8)2;                                       // strings count
203    data << plName;
204    data << GetPlayer()->GetName();
205    guild->BroadcastPacket(&data);
206}
207
208void WorldSession::HandleGuildAcceptOpcode(WorldPacket& /*recvPacket*/)
209{
210    Guild *guild;
211    Player *player = GetPlayer();
212
213    //sLog.outDebug("WORLD: Received CMSG_GUILD_ACCEPT");
214
215    guild = objmgr.GetGuildById(player->GetGuildIdInvited());
216    if(!guild || player->GetGuildId())
217        return;
218
219    // not let enemies sign guild charter
220    if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != objmgr.GetPlayerTeamByGUID(guild->GetLeader()))
221        return;
222
223    if(!guild->AddMember(GetPlayer()->GetGUID(),guild->GetLowestRank()))
224        return;
225    // Put record into guildlog
226    guild->LogGuildEvent(GUILD_EVENT_LOG_JOIN_GUILD, GetPlayer()->GetGUIDLow(), 0, 0);
227
228    WorldPacket data(SMSG_GUILD_EVENT, (2+10));             // guess size
229    data << (uint8)GE_JOINED;
230    data << (uint8)1;
231    data << player->GetName();
232    guild->BroadcastPacket(&data);
233
234    //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)");
235}
236
237void WorldSession::HandleGuildDeclineOpcode(WorldPacket& /*recvPacket*/)
238{
239    //sLog.outDebug("WORLD: Received CMSG_GUILD_DECLINE");
240
241    GetPlayer()->SetGuildIdInvited(0);
242    GetPlayer()->SetInGuild(0);
243}
244
245void WorldSession::HandleGuildInfoOpcode(WorldPacket& /*recvPacket*/)
246{
247    Guild *guild;
248    //sLog.outDebug("WORLD: Received CMSG_GUILD_INFO");
249
250    guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
251    if(!guild)
252    {
253        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
254        return;
255    }
256
257    WorldPacket data(SMSG_GUILD_INFO, (5*4 + guild->GetName().size() + 1));
258    data << guild->GetName();
259    data << guild->GetCreatedDay();
260    data << guild->GetCreatedMonth();
261    data << guild->GetCreatedYear();
262    data << guild->GetMemberSize();
263    data << guild->GetMemberSize();
264
265    SendPacket(&data);
266}
267
268void WorldSession::HandleGuildRosterOpcode(WorldPacket& /*recvPacket*/)
269{
270    //sLog.outDebug("WORLD: Received CMSG_GUILD_ROSTER");
271
272    Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
273    if(!guild)
274        return;
275
276    guild->Roster(this);
277}
278
279void WorldSession::HandleGuildPromoteOpcode(WorldPacket& recvPacket)
280{
281    CHECK_PACKET_SIZE(recvPacket, 1);
282
283    std::string plName;
284
285    //sLog.outDebug("WORLD: Received CMSG_GUILD_PROMOTE");
286
287    recvPacket >> plName;
288
289    if(!normalizePlayerName(plName))
290        return;
291       
292    Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
293    if(!guild)
294    {
295        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
296        return;
297    }
298    if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_PROMOTE))
299    {
300        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
301        return;
302    }
303   
304    uint64 plGuid = objmgr.GetPlayerGUIDByName(plName);
305   
306    if(!plGuid)
307    {
308        SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_FOUND);
309        return;
310    }
311    else if(plGuid == GetPlayer()->GetGUID())
312    {
313        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_NAME_INVALID);
314        return;
315    }
316   
317    int32 plRankId = guild->GetRank(GUID_LOPART(plGuid));
318    if(plRankId == -1)
319    {
320        SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S);
321        return;
322    }
323    if(plRankId < 2 || (plRankId-1) < GetPlayer()->GetRank())
324        return;
325
326    uint32 newRankId = plRankId < guild->GetNrRanks() ? plRankId-1 : guild->GetNrRanks()-1;
327
328    guild->ChangeRank(plGuid, newRankId);
329    // Put record into guildlog
330    guild->LogGuildEvent(GUILD_EVENT_LOG_PROMOTE_PLAYER, GetPlayer()->GetGUIDLow(), GUID_LOPART(plGuid), newRankId);
331
332    WorldPacket data(SMSG_GUILD_EVENT, (2+30));             // guess size
333    data << (uint8)GE_PROMOTION;
334    data << (uint8)3;
335    data << GetPlayer()->GetName();
336    data << plName;
337    data << guild->GetRankName(newRankId);
338    guild->BroadcastPacket(&data);
339}
340
341void WorldSession::HandleGuildDemoteOpcode(WorldPacket& recvPacket)
342{
343    CHECK_PACKET_SIZE(recvPacket, 1);
344
345    std::string plName;
346
347    //sLog.outDebug("WORLD: Received CMSG_GUILD_DEMOTE");
348
349    recvPacket >> plName;
350
351    if(!normalizePlayerName(plName))
352        return;
353
354    Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
355
356    if(!guild)
357    {
358        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
359        return;
360    }
361   
362    if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_DEMOTE))
363    {
364        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
365        return;
366    }
367   
368    uint64 plGuid = objmgr.GetPlayerGUIDByName(plName);
369
370    if( !plGuid )
371    {
372        SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_FOUND);
373        return;
374    }
375
376    if(plGuid == GetPlayer()->GetGUID())
377    {
378        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_NAME_INVALID);
379        return;
380    }
381
382    int32 plRankId = guild->GetRank(GUID_LOPART(plGuid));
383    if(plRankId == -1)
384    {
385        SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S);
386        return;
387    }
388
389    if((plRankId+1) >= guild->GetNrRanks() || plRankId <= this->GetPlayer()->GetRank())
390        return;
391
392    guild->ChangeRank(plGuid, (plRankId+1));
393    // Put record into guildlog
394    guild->LogGuildEvent(GUILD_EVENT_LOG_DEMOTE_PLAYER, GetPlayer()->GetGUIDLow(), GUID_LOPART(plGuid), (plRankId+1));
395
396    WorldPacket data(SMSG_GUILD_EVENT, (2+30));             // guess size
397    data << (uint8)GE_DEMOTION;
398    data << (uint8)3;
399    data << GetPlayer()->GetName();
400    data << plName;
401    data << guild->GetRankName(plRankId+1);
402    guild->BroadcastPacket(&data);
403}
404
405void WorldSession::HandleGuildLeaveOpcode(WorldPacket& /*recvPacket*/)
406{
407    std::string plName;
408    Guild *guild;
409
410    //sLog.outDebug("WORLD: Received CMSG_GUILD_LEAVE");
411
412    guild = objmgr.GetGuildById(_player->GetGuildId());
413    if(!guild)
414    {
415        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
416        return;
417    }
418    if(_player->GetGUID() == guild->GetLeader() && guild->GetMemberSize() > 1)
419    {
420        SendGuildCommandResult(GUILD_QUIT_S, "", GUILD_LEADER_LEAVE);
421        return;
422    }
423
424    if(_player->GetGUID() == guild->GetLeader())
425    {
426        guild->Disband();
427        return;
428    }
429
430    plName = _player->GetName();
431
432    guild->DelMember(_player->GetGUID());
433    // Put record into guildlog
434    guild->LogGuildEvent(GUILD_EVENT_LOG_LEAVE_GUILD, _player->GetGUIDLow(), 0, 0);
435
436    WorldPacket data(SMSG_GUILD_EVENT, (2+10));             // guess size
437    data << (uint8)GE_LEFT;
438    data << (uint8)1;
439    data << plName;
440    guild->BroadcastPacket(&data);
441
442    //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)");
443
444    SendGuildCommandResult(GUILD_QUIT_S, guild->GetName(), GUILD_PLAYER_NO_MORE_IN_GUILD);
445}
446
447void WorldSession::HandleGuildDisbandOpcode(WorldPacket& /*recvPacket*/)
448{
449    std::string name;
450    Guild *guild;
451
452    //sLog.outDebug("WORLD: Received CMSG_GUILD_DISBAND");
453
454    guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
455    if(!guild)
456    {
457        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
458        return;
459    }
460    if(GetPlayer()->GetGUID() != guild->GetLeader())
461    {
462        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
463        return;
464    }
465
466    guild->Disband();
467
468    //sLog.outDebug("WORLD: Guild Sucefully Disbanded");
469}
470
471void WorldSession::HandleGuildLeaderOpcode(WorldPacket& recvPacket)
472{
473    CHECK_PACKET_SIZE(recvPacket, 1);
474
475    std::string name;
476    Player *oldLeader = GetPlayer();
477    Guild *guild;
478
479    //sLog.outDebug("WORLD: Received CMSG_GUILD_LEADER");
480
481    recvPacket >> name;
482
483    if(!normalizePlayerName(name))
484        return;
485       
486    guild = objmgr.GetGuildById(oldLeader->GetGuildId());
487   
488    if (!guild)
489    {
490        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
491        return;
492    }
493   
494    if( oldLeader->GetGUID() != guild->GetLeader())
495    {
496        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
497        return;
498    }
499
500    uint64 newLeaderGUID = objmgr.GetPlayerGUIDByName(name);
501    if (!newLeaderGUID)
502    {
503        SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_FOUND);
504        return;
505    }
506    if(!guild->IsMember(GUID_LOPART(newLeaderGUID)))
507    {
508        SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_IN_GUILD_S);
509        return;
510    }
511
512    guild->SetLeader(newLeaderGUID);
513    guild->ChangeRank(oldLeader->GetGUID(), GR_OFFICER);
514
515    WorldPacket data(SMSG_GUILD_EVENT, (2+20));             // guess size
516    data << (uint8)GE_LEADER_CHANGED;
517    data << (uint8)2;
518    data << oldLeader->GetName();
519    data << name.c_str();
520    guild->BroadcastPacket(&data);
521
522    //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)");
523}
524
525void WorldSession::HandleGuildMOTDOpcode(WorldPacket& recvPacket)
526{
527    Guild *guild;
528    std::string MOTD;
529
530    //sLog.outDebug("WORLD: Received CMSG_GUILD_MOTD");
531
532    guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
533    if(!guild)
534    {
535        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
536        return;
537    }
538    if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_SETMOTD))
539    {
540        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
541        return;
542    }
543
544    if(!recvPacket.empty())
545        recvPacket >> MOTD;
546    else
547        MOTD = "";
548
549    guild->SetMOTD(MOTD);
550
551    WorldPacket data(SMSG_GUILD_EVENT, (2+MOTD.size()+1));
552    data << (uint8)GE_MOTD;
553    data << (uint8)1;
554    data << MOTD;
555    guild->BroadcastPacket(&data);
556
557    //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)");
558}
559
560void WorldSession::HandleGuildSetPublicNoteOpcode(WorldPacket& recvPacket)
561{
562    CHECK_PACKET_SIZE(recvPacket, 1);
563
564    std::string name,PNOTE;
565
566    //sLog.outDebug("WORLD: Received CMSG_GUILD_SET_PUBLIC_NOTE");
567
568    recvPacket >> name;
569
570    if(!normalizePlayerName(name))
571        return;
572
573    Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
574    if (!guild)
575    {
576        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
577        return;
578    }
579   
580    if (!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_EPNOTE))
581    {
582        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
583        return;
584    }
585   
586    uint64 plGuid = objmgr.GetPlayerGUIDByName(name);
587
588    if (!plGuid)
589    {
590        SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_FOUND);
591        return;
592    }
593   
594    if (!guild->IsMember(GUID_LOPART(plGuid)))
595    {
596        SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_IN_GUILD_S);
597        return;
598    }
599
600    recvPacket >> PNOTE;
601    guild->SetPNOTE(plGuid, PNOTE);
602
603    guild->Roster(this);
604}
605
606void WorldSession::HandleGuildSetOfficerNoteOpcode(WorldPacket& recvPacket)
607{
608    CHECK_PACKET_SIZE(recvPacket, 1);
609
610    std::string plName, OFFNOTE;
611
612    //sLog.outDebug("WORLD: Received CMSG_GUILD_SET_OFFICER_NOTE");
613
614    recvPacket >> plName;
615
616    if(!normalizePlayerName(plName))
617        return;
618
619    Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
620    if (!guild)
621    {
622        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
623        return;
624    }
625    if (!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_EOFFNOTE))
626    {
627        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
628        return;
629    }
630   
631    uint64 plGuid = objmgr.GetPlayerGUIDByName(plName);
632
633    if (!plGuid)
634    {
635        SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_FOUND);
636        return;
637    }
638   
639    if (!guild->IsMember(GUID_LOPART(plGuid)))
640    {
641        SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S);
642        return;
643    }
644
645    recvPacket >> OFFNOTE;
646    guild->SetOFFNOTE(plGuid, OFFNOTE);
647
648    guild->Roster(this);
649}
650
651void WorldSession::HandleGuildRankOpcode(WorldPacket& recvPacket)
652{
653    CHECK_PACKET_SIZE(recvPacket, 4+4+1+4*13);
654    //recvPacket.hexlike();
655
656    Guild *guild;
657    std::string rankname;
658    uint32 rankId;
659    uint32 rights, MoneyPerDay;
660    uint32 BankRights;
661    uint32 BankSlotPerDay;
662
663    //sLog.outDebug("WORLD: Received CMSG_GUILD_RANK");
664
665    guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
666    if(!guild)
667    {
668        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
669        return;
670    }
671
672    else if(GetPlayer()->GetGUID() != guild->GetLeader())
673    {
674        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
675        return;
676    }
677
678    recvPacket >> rankId;
679    recvPacket >> rights;
680    recvPacket >> rankname;
681    recvPacket >> MoneyPerDay;
682
683    for (int i = 0; i < GUILD_BANK_MAX_TABS; ++i)
684    {
685        recvPacket >> BankRights;
686        recvPacket >> BankSlotPerDay;
687        guild->SetBankRightsAndSlots(rankId, uint8(i), uint16(BankRights & 0xFF), uint16(BankSlotPerDay), true);
688    }
689    sLog.outDebug("WORLD: Changed RankName to %s , Rights to 0x%.4X", rankname.c_str(), rights);
690
691    guild->SetBankMoneyPerDay(rankId, MoneyPerDay);
692    guild->SetRankName(rankId, rankname);
693
694    if(rankId==GR_GUILDMASTER)                              // prevent loss leader rights
695        rights |= GR_RIGHT_ALL;
696
697    guild->SetRankRights(rankId, rights);
698
699    guild->Query(this);
700    guild->Roster(this);
701}
702
703void WorldSession::HandleGuildAddRankOpcode(WorldPacket& recvPacket)
704{
705    CHECK_PACKET_SIZE(recvPacket, 1);
706
707    Guild *guild;
708    std::string rankname;
709
710    //sLog.outDebug("WORLD: Received CMSG_GUILD_ADD_RANK");
711
712    guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
713    if(!guild)
714    {
715        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
716        return;
717    }
718
719    if(GetPlayer()->GetGUID() != guild->GetLeader())
720    {
721        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
722        return;
723    }
724
725    if(guild->GetNrRanks() >= GUILD_MAX_RANKS)              // client not let create more 10 than ranks
726        return;
727
728    recvPacket >> rankname;
729
730    guild->CreateRank(rankname, GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK);
731
732    guild->Query(this);
733    guild->Roster(this);
734}
735
736void WorldSession::HandleGuildDelRankOpcode(WorldPacket& /*recvPacket*/)
737{
738    Guild *guild;
739    std::string rankname;
740
741    //sLog.outDebug("WORLD: Received CMSG_GUILD_DEL_RANK");
742
743    guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
744    if(!guild)
745    {
746        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
747        return;
748    }
749
750    else if(GetPlayer()->GetGUID() != guild->GetLeader())
751    {
752        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
753        return;
754    }
755
756    guild->DelRank();
757
758    guild->Query(this);
759    guild->Roster(this);
760}
761
762void WorldSession::SendGuildCommandResult(uint32 typecmd,std::string str,uint32 cmdresult)
763{
764    WorldPacket data(SMSG_GUILD_COMMAND_RESULT, (8+str.size()+1));
765    data << typecmd;
766    data << str;
767    data << cmdresult;
768    SendPacket(&data);
769
770    //sLog.outDebug("WORLD: Sent (SMSG_GUILD_COMMAND_RESULT)");
771}
772
773void WorldSession::HandleGuildChangeInfoOpcode(WorldPacket& recvPacket)
774{
775    CHECK_PACKET_SIZE(recvPacket, 1);
776
777    //sLog.outDebug("WORLD: Received CMSG_GUILD_INFO_TEXT");
778
779    std::string GINFO;
780
781    recvPacket >> GINFO;
782
783    Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
784    if(!guild)
785    {
786        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
787        return;
788    }
789
790    if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_MODIFY_GUILD_INFO))
791    {
792        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PERMISSIONS);
793        return;
794    }
795
796    guild->SetGINFO(GINFO);
797}
798
799void WorldSession::HandleGuildSaveEmblemOpcode(WorldPacket& recvPacket)
800{
801    CHECK_PACKET_SIZE(recvPacket, 8+4+4+4+4+4);
802
803    //sLog.outDebug("WORLD: Received MSG_SAVE_GUILD_EMBLEM");
804
805    uint64 vendorGuid;
806
807    uint32 EmblemStyle;
808    uint32 EmblemColor;
809    uint32 BorderStyle;
810    uint32 BorderColor;
811    uint32 BackgroundColor;
812
813    recvPacket >> vendorGuid;
814
815    Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, vendorGuid,UNIT_NPC_FLAG_TABARDDESIGNER);
816    if (!pCreature)
817    {
818        //"That's not an emblem vendor!"
819        SendSaveGuildEmblem(ERR_GUILDEMBLEM_INVALIDVENDOR);
820        sLog.outDebug("WORLD: HandleGuildSaveEmblemOpcode - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(vendorGuid));
821        return;
822    }
823
824    // remove fake death
825    if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
826        GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
827
828    recvPacket >> EmblemStyle;
829    recvPacket >> EmblemColor;
830    recvPacket >> BorderStyle;
831    recvPacket >> BorderColor;
832    recvPacket >> BackgroundColor;
833
834    Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
835    if(!guild)
836    {
837        //"You are not part of a guild!";
838        SendSaveGuildEmblem(ERR_GUILDEMBLEM_NOGUILD);
839        return;
840    }
841
842    if (guild->GetLeader() != GetPlayer()->GetGUID())
843    {
844        //"Only guild leaders can create emblems."
845        SendSaveGuildEmblem(ERR_GUILDEMBLEM_NOTGUILDMASTER);
846        return;
847    }
848
849    if(GetPlayer()->GetMoney() < 10*GOLD)
850    {
851        //"You can't afford to do that."
852        SendSaveGuildEmblem(ERR_GUILDEMBLEM_NOTENOUGHMONEY);
853        return;
854    }
855
856    GetPlayer()->ModifyMoney(-10*GOLD);
857    guild->SetEmblem(EmblemStyle, EmblemColor, BorderStyle, BorderColor, BackgroundColor);
858
859    //"Guild Emblem saved."
860    SendSaveGuildEmblem(ERR_GUILDEMBLEM_SUCCESS);
861
862    guild->Query(this);
863}
864
865void WorldSession::HandleGuildEventLogOpcode(WorldPacket& /* recvPacket */)
866{
867                                                            // empty
868    sLog.outDebug("WORLD: Received (MSG_GUILD_EVENT_LOG_QUERY)");
869    //recvPacket.hexlike();
870
871    uint32 GuildId = GetPlayer()->GetGuildId();
872    if (GuildId == 0)
873        return;
874
875    Guild *pGuild = objmgr.GetGuildById(GuildId);
876    if(!pGuild)
877        return;
878
879    pGuild->DisplayGuildEventlog(this);
880}
881
882/******  GUILD BANK  *******/
883
884void WorldSession::HandleGuildBankGetMoneyAmount( WorldPacket & /* recv_data */ )
885{
886    sLog.outDebug("WORLD: Received (MSG_GUILD_BANK_MONEY_WITHDRAWN)");
887    //recv_data.hexlike();
888
889    uint32 GuildId = GetPlayer()->GetGuildId();
890    if (GuildId == 0)
891        return;
892
893    Guild *pGuild = objmgr.GetGuildById(GuildId);
894    if(!pGuild)
895        return;
896
897    pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow());
898}
899
900void WorldSession::HandleGuildBankGetRights( WorldPacket& /* recv_data */ )
901{
902    sLog.outDebug("WORLD: Received (MSG_GUILD_PERMISSIONS)");
903
904    uint32 GuildId = GetPlayer()->GetGuildId();
905    if (GuildId == 0)
906        return;
907
908    Guild *pGuild = objmgr.GetGuildById(GuildId);
909    if(!pGuild)
910        return;
911
912    uint32 rankId = GetPlayer()->GetRank();
913
914    WorldPacket data(MSG_GUILD_PERMISSIONS, 4*15+1);
915    data << uint32(rankId);                                 // guild rank id
916    data << uint32(pGuild->GetRankRights(rankId));          // rank rights
917                                                            // money per day left
918    data << uint32(pGuild->GetMemberMoneyWithdrawRem(GetPlayer()->GetGUIDLow()));
919    data << uint8(pGuild->GetPurchasedTabs());              // tabs count
920    for(int i = 0; i < GUILD_BANK_MAX_TABS; ++i)
921    {
922        data << uint32(pGuild->GetBankRights(rankId, uint8(i)));
923        data << uint32(pGuild->GetMemberSlotWithdrawRem(GetPlayer()->GetGUIDLow(), uint8(i)));
924    }
925    SendPacket(&data);
926    sLog.outDebug("WORLD: Sent (MSG_GUILD_PERMISSIONS)");
927}
928
929/* Called when clicking on Guild bank gameobject */
930void WorldSession::HandleGuildBankQuery( WorldPacket & recv_data )
931{
932    sLog.outDebug("WORLD: Received (CMSG_GUILD_BANKER_ACTIVATE)");
933    CHECK_PACKET_SIZE(recv_data,8+1);
934    uint64 GoGuid;
935    uint8  unk;
936    recv_data >> GoGuid >> unk;
937
938    if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
939        return;
940
941    if (uint32 GuildId = GetPlayer()->GetGuildId())
942    {
943        if(Guild *pGuild = objmgr.GetGuildById(GuildId))
944        {
945            pGuild->DisplayGuildBankTabsInfo(this);
946            return;
947        }
948    }
949
950    SendGuildCommandResult(GUILD_BANK_S, "", GUILD_PLAYER_NOT_IN_GUILD);
951}
952
953/* Called when opening guild bank tab only (first one) */
954void WorldSession::HandleGuildBankTabColon( WorldPacket & recv_data )
955{
956    sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_QUERY_TAB)");
957    CHECK_PACKET_SIZE(recv_data,8+1+1);
958    uint64 GoGuid;
959    uint8 TabId,unk1;
960    recv_data >> GoGuid >> TabId >> unk1;
961
962    if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
963        return;
964
965    uint32 GuildId = GetPlayer()->GetGuildId();
966    if (GuildId == 0)
967        return;
968
969    Guild *pGuild = objmgr.GetGuildById(GuildId);
970    if(!pGuild)
971        return;
972
973    // Let's update the amount of gold the player can withdraw before displaying the content
974    // This is usefull if money withdraw right has changed
975    pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow());
976
977    pGuild->DisplayGuildBankContent(this, TabId);
978}
979
980void WorldSession::HandleGuildBankDeposit( WorldPacket & recv_data )
981{
982    sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_DEPOSIT_MONEY)");
983    CHECK_PACKET_SIZE(recv_data,8+4);
984    uint64 GoGuid;
985    uint32 money;
986    recv_data >> GoGuid >> money;
987
988    if (!money)
989        return;
990
991    if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
992        return;
993
994    uint32 GuildId = GetPlayer()->GetGuildId();
995    if (GuildId == 0)
996        return;
997
998    Guild *pGuild = objmgr.GetGuildById(GuildId);
999    if(!pGuild)
1000        return;
1001
1002    if (GetPlayer()->GetMoney() < money)
1003        return;
1004
1005    CharacterDatabase.BeginTransaction();
1006
1007    pGuild->SetBankMoney(pGuild->GetGuildBankMoney()+money);
1008    GetPlayer()->ModifyMoney(-int(money));
1009    GetPlayer()->SaveGoldToDB();
1010
1011    CharacterDatabase.CommitTransaction();
1012
1013    // logging money
1014    if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
1015    {
1016        sLog.outCommand("GM %s (Account: %u) deposit money (Amount: %u) to guild bank (Guild ID %u)",
1017            _player->GetName(),_player->GetSession()->GetAccountId(),money,GuildId);
1018    }
1019
1020    // log
1021    pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_MONEY, uint8(0), GetPlayer()->GetGUIDLow(), money);
1022
1023    pGuild->DisplayGuildBankTabsInfo(this);
1024    pGuild->DisplayGuildBankContent(this, 0);
1025    pGuild->DisplayGuildBankMoneyUpdate();
1026}
1027
1028void WorldSession::HandleGuildBankWithdraw( WorldPacket & recv_data )
1029{
1030    sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_WITHDRAW_MONEY)");
1031    CHECK_PACKET_SIZE(recv_data,8+4);
1032    uint64 GoGuid;
1033    uint32 money;
1034    recv_data >> GoGuid >> money;
1035
1036    if (!money)
1037        return;
1038
1039    if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
1040        return;
1041
1042    uint32 GuildId = GetPlayer()->GetGuildId();
1043    if (GuildId == 0)
1044        return;
1045
1046    Guild *pGuild = objmgr.GetGuildById(GuildId);
1047    if(!pGuild)
1048        return;
1049
1050    if (pGuild->GetGuildBankMoney()<money)                  // not enough money in bank
1051        return;
1052
1053    if (!pGuild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_WITHDRAW_GOLD))
1054        return;
1055
1056    CharacterDatabase.BeginTransaction();
1057
1058    if (!pGuild->MemberMoneyWithdraw(money, GetPlayer()->GetGUIDLow()))
1059    {
1060        CharacterDatabase.RollbackTransaction();
1061        return;
1062    }
1063
1064    GetPlayer()->ModifyMoney(money);
1065    GetPlayer()->SaveGoldToDB();
1066
1067    CharacterDatabase.CommitTransaction();
1068
1069    // Log
1070    pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_MONEY, uint8(0), GetPlayer()->GetGUIDLow(), money);
1071
1072    pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow());
1073    pGuild->DisplayGuildBankTabsInfo(this);
1074    pGuild->DisplayGuildBankContent(this, 0);
1075    pGuild->DisplayGuildBankMoneyUpdate();
1076}
1077
1078void WorldSession::HandleGuildBankDepositItem( WorldPacket & recv_data )
1079{
1080    sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_SWAP_ITEMS)");
1081    //recv_data.hexlike();
1082
1083    uint64 GoGuid;
1084    uint8 BankToBank;
1085
1086    uint8 BankTab, BankTabSlot, AutoStore, AutoStoreCount, PlayerSlot, PlayerBag, SplitedAmount = 0;
1087    uint8 BankTabDst, BankTabSlotDst, unk2, ToChar = 1;
1088    uint32 ItemEntry, unk1;
1089    bool BankToChar = false;
1090
1091    CHECK_PACKET_SIZE(recv_data,8+1);
1092    recv_data >> GoGuid >> BankToBank;
1093    if (BankToBank)
1094    {
1095        // recheck
1096        CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1+1+4+1+1+4+1+1);
1097        recv_data >> BankTabDst;
1098        recv_data >> BankTabSlotDst;
1099        recv_data >> unk1;                                  // always 0
1100        recv_data >> BankTab;
1101        recv_data >> BankTabSlot;
1102        recv_data >> ItemEntry;
1103        recv_data >> unk2;                                  // always 0
1104        recv_data >> SplitedAmount;
1105
1106        if (BankTabSlotDst >= GUILD_BANK_MAX_SLOTS)
1107            return;
1108        if (BankTabDst == BankTab && BankTabSlotDst == BankTabSlot)
1109            return;
1110    }
1111    else
1112    {
1113        // recheck
1114        CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1+1+4+1);
1115        recv_data >> BankTab;
1116        recv_data >> BankTabSlot;
1117        recv_data >> ItemEntry;
1118        recv_data >> AutoStore;
1119        if (AutoStore)
1120        {
1121            // recheck
1122            CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1);
1123            recv_data >> AutoStoreCount;
1124        }
1125        // recheck
1126        CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1+1);
1127        recv_data >> PlayerBag;
1128        recv_data >> PlayerSlot;
1129        if (!AutoStore)
1130        {
1131            // recheck
1132            CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1+1);
1133            recv_data >> ToChar;
1134            recv_data >> SplitedAmount;
1135        }
1136
1137        if (BankTabSlot >= GUILD_BANK_MAX_SLOTS && BankTabSlot != 0xFF)
1138            return;
1139    }
1140
1141    if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
1142        return;
1143
1144    uint32 GuildId = GetPlayer()->GetGuildId();
1145    if (GuildId == 0)
1146        return;
1147
1148    Guild *pGuild = objmgr.GetGuildById(GuildId);
1149    if(!pGuild)
1150        return;
1151
1152    Player *pl = GetPlayer();
1153
1154    // Bank <-> Bank
1155    if (BankToBank)
1156    {
1157        // empty operation
1158        if(BankTab==BankTabDst && BankTabSlot==BankTabSlotDst)
1159            return;
1160
1161        Item *pItemSrc = pGuild->GetItem(BankTab, BankTabSlot);
1162        if (!pItemSrc)                                      // may prevent crash
1163            return;
1164
1165        if(SplitedAmount > pItemSrc->GetCount())
1166            return;                                         // cheating?
1167        else if(SplitedAmount == pItemSrc->GetCount())
1168            SplitedAmount = 0;                              // no split
1169
1170        Item *pItemDst = pGuild->GetItem(BankTabDst, BankTabSlotDst);
1171
1172        if(BankTab!=BankTabDst)
1173        {
1174            // check dest pos rights (if different tabs)
1175            if(!pGuild->IsMemberHaveRights(pl->GetGUIDLow(), BankTabDst, GUILD_BANK_RIGHT_DEPOSIT_ITEM))
1176                return;
1177
1178            // check source pos rights (if different tabs)
1179            uint32 remRight = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTab);
1180            if(remRight <= 0)
1181                return;
1182        }
1183
1184        if (SplitedAmount)
1185        {                                                   // Bank -> Bank item split (in empty or non empty slot
1186            GuildItemPosCountVec dest;
1187            uint8 msg = pGuild->CanStoreItem(BankTabDst,BankTabSlotDst,dest,SplitedAmount,pItemSrc,false);
1188            if( msg != EQUIP_ERR_OK )
1189            {
1190                pl->SendEquipError( msg, pItemSrc, NULL );
1191                return;
1192            }
1193
1194            Item *pNewItem = pItemSrc->CloneItem( SplitedAmount );
1195            if( !pNewItem )
1196            {
1197                pl->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, pItemSrc, NULL );
1198                return;
1199            }
1200
1201            CharacterDatabase.BeginTransaction();
1202            pGuild->LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTab, pl->GetGUIDLow(), pItemSrc->GetEntry(), SplitedAmount, BankTabDst);
1203
1204            pl->ItemRemovedQuestCheck( pItemSrc->GetEntry(), SplitedAmount );
1205            pItemSrc->SetCount( pItemSrc->GetCount() - SplitedAmount );
1206            pItemSrc->FSetState(ITEM_CHANGED);
1207            pItemSrc->SaveToDB();                           // not in inventory and can be save standalone
1208            pGuild->StoreItem(BankTabDst,dest,pNewItem);
1209            CharacterDatabase.CommitTransaction();
1210        }
1211        else                                                // non split
1212        {
1213            GuildItemPosCountVec gDest;
1214            uint8 msg = pGuild->CanStoreItem(BankTabDst,BankTabSlotDst,gDest,pItemSrc->GetCount(),pItemSrc,false);
1215            if( msg == EQUIP_ERR_OK )                       // merge to
1216            {
1217                CharacterDatabase.BeginTransaction();
1218                pGuild->LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTab,    pl->GetGUIDLow(), pItemSrc->GetEntry(), pItemSrc->GetCount(), BankTabDst);
1219
1220                pGuild->RemoveItem(BankTab, BankTabSlot);
1221                pGuild->StoreItem(BankTabDst, gDest, pItemSrc);
1222                CharacterDatabase.CommitTransaction();
1223            }
1224            else                                            // swap
1225            {
1226                gDest.clear();
1227                uint8 msg = pGuild->CanStoreItem(BankTabDst,BankTabSlotDst,gDest,pItemSrc->GetCount(),pItemSrc,true);
1228                if( msg != EQUIP_ERR_OK )
1229                {
1230                    pl->SendEquipError( msg, pItemSrc, NULL );
1231                    return;
1232                }
1233
1234                GuildItemPosCountVec gSrc;
1235                msg = pGuild->CanStoreItem(BankTab,BankTabSlot,gSrc,pItemDst->GetCount(),pItemDst,true);
1236                if( msg != EQUIP_ERR_OK )
1237                {
1238                    pl->SendEquipError( msg, pItemDst, NULL );
1239                    return;
1240                }
1241
1242                if(BankTab!=BankTabDst)
1243                {
1244                    // check source pos rights (item swapped to src)
1245                    if(!pGuild->IsMemberHaveRights(pl->GetGUIDLow(), BankTab, GUILD_BANK_RIGHT_DEPOSIT_ITEM))
1246                        return;
1247
1248                    // check dest pos rights (item swapped to src)
1249                    uint32 remRightDst = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTabDst);
1250                    if(remRightDst <= 0)
1251                        return;
1252                }
1253
1254                CharacterDatabase.BeginTransaction();
1255                pGuild->LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTab,    pl->GetGUIDLow(), pItemSrc->GetEntry(), pItemSrc->GetCount(), BankTabDst);
1256                pGuild->LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTabDst, pl->GetGUIDLow(), pItemDst->GetEntry(), pItemDst->GetCount(), BankTab);
1257
1258                pGuild->RemoveItem(BankTab, BankTabSlot);
1259                pGuild->RemoveItem(BankTabDst, BankTabSlotDst);
1260                pGuild->StoreItem(BankTab, gSrc, pItemDst);
1261                pGuild->StoreItem(BankTabDst, gDest, pItemSrc);
1262                CharacterDatabase.CommitTransaction();
1263            }
1264        }
1265        pGuild->DisplayGuildBankContentUpdate(BankTab,BankTabSlot,BankTab==BankTabDst ? BankTabSlotDst : -1);
1266        if(BankTab!=BankTabDst)
1267            pGuild->DisplayGuildBankContentUpdate(BankTabDst,BankTabSlotDst);
1268        return;
1269    }
1270
1271    // Player <-> Bank
1272
1273    // char->bank autostore click return BankTabSlot = 255 = NULL_SLOT
1274    // do similar for bank->char
1275    if(AutoStore && ToChar)
1276    {
1277        PlayerBag = NULL_BAG;
1278        PlayerSlot = NULL_SLOT;
1279    }
1280
1281    // allow work with inventory only
1282    if(!Player::IsInventoryPos(PlayerBag,PlayerSlot) && !(PlayerBag == NULL_BAG && PlayerSlot == NULL_SLOT) )
1283    {
1284        _player->SendEquipError( EQUIP_ERR_NONE, NULL, NULL );
1285        return;
1286    }
1287
1288    Item *pItemBank = pGuild->GetItem(BankTab, BankTabSlot);
1289    Item *pItemChar = GetPlayer()->GetItemByPos(PlayerBag, PlayerSlot);
1290    if (!pItemChar && !pItemBank)                           // Nothing to do
1291        return;
1292
1293    if (!pItemChar && !ToChar)                              // Problem to get item from player
1294        return;
1295
1296    if (!pItemBank && ToChar)                               // Problem to get bank item
1297        return;
1298
1299    // BankToChar swap or char to bank remaining
1300
1301    if (ToChar)                                             // Bank -> Char cases
1302    {
1303        if(SplitedAmount > pItemBank->GetCount())
1304            return;                                         // cheating?
1305        else if(SplitedAmount == pItemBank->GetCount())
1306            SplitedAmount = 0;                              // no split
1307
1308        if (SplitedAmount)
1309        {                                                   // Bank -> Char split to slot (patly move)
1310            Item *pNewItem = pItemBank->CloneItem( SplitedAmount );
1311            if( !pNewItem )
1312            {
1313                pl->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, pItemBank, NULL );
1314                return;
1315            }
1316
1317            ItemPosCountVec dest;
1318            uint8 msg = pl->CanStoreItem(PlayerBag, PlayerSlot, dest, pNewItem, false);
1319            if( msg != EQUIP_ERR_OK )
1320            {
1321                pl->SendEquipError( msg, pNewItem, NULL );
1322                delete pNewItem;
1323                return;
1324            }
1325
1326            // check source pos rights (item moved to inventory)
1327            uint32 remRight = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTab);
1328            if(remRight <= 0)
1329            {
1330                delete pNewItem;
1331                return;
1332            }
1333
1334            CharacterDatabase.BeginTransaction();
1335            pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), SplitedAmount);
1336
1337            pItemBank->SetCount(pItemBank->GetCount()-SplitedAmount);
1338            pItemBank->FSetState(ITEM_CHANGED);
1339            pItemBank->SaveToDB();                          // not in inventory and can be save standalone
1340            pl->MoveItemToInventory(dest,pNewItem,true);
1341            pl->SaveInventoryAndGoldToDB();
1342
1343            pGuild->MemberItemWithdraw(BankTab, pl->GetGUIDLow());
1344            CharacterDatabase.CommitTransaction();
1345        }
1346        else                                                // Bank -> Char swap with slot (move)
1347        {
1348            ItemPosCountVec dest;
1349            uint8 msg = pl->CanStoreItem(PlayerBag, PlayerSlot, dest, pItemBank, false);
1350            if( msg == EQUIP_ERR_OK )                       // merge case
1351            {
1352                // check source pos rights (item moved to inventory)
1353                uint32 remRight = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTab);
1354                if(remRight <= 0)
1355                    return;
1356
1357                CharacterDatabase.BeginTransaction();
1358                pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), pItemBank->GetCount());
1359
1360                pGuild->RemoveItem(BankTab, BankTabSlot);
1361                pl->MoveItemToInventory(dest,pItemBank,true);
1362                pl->SaveInventoryAndGoldToDB();
1363
1364                pGuild->MemberItemWithdraw(BankTab, pl->GetGUIDLow());
1365                CharacterDatabase.CommitTransaction();
1366            }
1367            else                                            // Bank <-> Char swap items
1368            {
1369                // check source pos rights (item swapped to bank)
1370                if(!pGuild->IsMemberHaveRights(pl->GetGUIDLow(), BankTab, GUILD_BANK_RIGHT_DEPOSIT_ITEM))
1371                    return;
1372
1373                if(pItemChar)
1374                {
1375                    if(!pItemChar->CanBeTraded())
1376                    {
1377                        _player->SendEquipError( EQUIP_ERR_ITEMS_CANT_BE_SWAPPED, pItemChar, NULL );
1378                        return;
1379                    }
1380                }
1381
1382                ItemPosCountVec iDest;
1383                msg = pl->CanStoreItem(PlayerBag, PlayerSlot, iDest, pItemBank, true);
1384                if( msg != EQUIP_ERR_OK )
1385                {
1386                    pl->SendEquipError( msg, pItemBank, NULL );
1387                    return;
1388                }
1389
1390                GuildItemPosCountVec gDest;
1391                if(pItemChar)
1392                {
1393                    msg = pGuild->CanStoreItem(BankTab,BankTabSlot,gDest,pItemChar->GetCount(),pItemChar,true);
1394                    if( msg != EQUIP_ERR_OK )
1395                    {
1396                        pl->SendEquipError( msg, pItemChar, NULL );
1397                        return;
1398                    }
1399                }
1400
1401                // check source pos rights (item moved to inventory)
1402                uint32 remRight = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTab);
1403                if(remRight <= 0)
1404                    return;
1405
1406                if(pItemChar)
1407                {
1408                    // logging item move to bank
1409                    if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
1410                    {
1411                        sLog.outCommand("GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u )",
1412                            _player->GetName(),_player->GetSession()->GetAccountId(),
1413                            pItemChar->GetProto()->Name1,pItemChar->GetEntry(),pItemChar->GetCount(),
1414                            GuildId);
1415                    }
1416                }
1417
1418                CharacterDatabase.BeginTransaction();
1419                pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), pItemBank->GetCount());
1420                if(pItemChar)
1421                    pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), pItemChar->GetCount());
1422
1423                pGuild->RemoveItem(BankTab, BankTabSlot);
1424                if(pItemChar)
1425                {
1426                    pl->MoveItemFromInventory(PlayerBag, PlayerSlot, true);
1427                    pItemChar->DeleteFromInventoryDB();
1428                }
1429
1430                if(pItemChar)
1431                    pGuild->StoreItem(BankTab, gDest, pItemChar);
1432                pl->MoveItemToInventory(iDest,pItemBank,true);
1433                pl->SaveInventoryAndGoldToDB();
1434
1435                pGuild->MemberItemWithdraw(BankTab, pl->GetGUIDLow());
1436                CharacterDatabase.CommitTransaction();
1437            }
1438        }
1439        pGuild->DisplayGuildBankContentUpdate(BankTab,BankTabSlot);
1440        return;
1441    }                                                       // End "To char" part
1442
1443    // Char -> Bank cases
1444
1445    if(!pItemChar->CanBeTraded())
1446    {
1447        _player->SendEquipError( EQUIP_ERR_ITEMS_CANT_BE_SWAPPED, pItemChar, NULL );
1448        return;
1449    }
1450
1451    // check source pos rights (item moved to bank)
1452    if(!pGuild->IsMemberHaveRights(pl->GetGUIDLow(), BankTab, GUILD_BANK_RIGHT_DEPOSIT_ITEM))
1453        return;
1454
1455    if(SplitedAmount > pItemChar->GetCount())
1456        return;                                             // cheating?
1457    else if(SplitedAmount == pItemChar->GetCount())
1458        SplitedAmount = 0;                                  // no split
1459
1460    if (SplitedAmount)
1461    {                                                       // Char -> Bank split to empty or non-empty slot (partly move)
1462        GuildItemPosCountVec dest;
1463        uint8 msg = pGuild->CanStoreItem(BankTab,BankTabSlot,dest,SplitedAmount,pItemChar,false);
1464        if( msg != EQUIP_ERR_OK )
1465        {
1466            pl->SendEquipError( msg, pItemChar, NULL );
1467            return;
1468        }
1469
1470        Item *pNewItem = pItemChar->CloneItem( SplitedAmount );
1471        if( !pNewItem )
1472        {
1473            pl->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, pItemChar, NULL );
1474            return;
1475        }
1476
1477        // logging item move to bank (before items merge
1478        if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
1479        {
1480            sLog.outCommand("GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u )",
1481                _player->GetName(),_player->GetSession()->GetAccountId(),
1482                pItemChar->GetProto()->Name1,pItemChar->GetEntry(),SplitedAmount,GuildId);
1483        }
1484
1485        CharacterDatabase.BeginTransaction();
1486        pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), SplitedAmount);
1487
1488        pl->ItemRemovedQuestCheck( pItemChar->GetEntry(), SplitedAmount );
1489        pItemChar->SetCount(pItemChar->GetCount()-SplitedAmount);
1490        pItemChar->SetState(ITEM_CHANGED);
1491        pl->SaveInventoryAndGoldToDB();
1492        pGuild->StoreItem(BankTab, dest, pNewItem);
1493        CharacterDatabase.CommitTransaction();
1494
1495        pGuild->DisplayGuildBankContentUpdate(BankTab,dest);
1496    }
1497    else                                                    // Char -> Bank swap with empty or non-empty (move)
1498    {
1499        GuildItemPosCountVec dest;
1500        uint8 msg = pGuild->CanStoreItem(BankTab,BankTabSlot,dest,pItemChar->GetCount(),pItemChar,false);
1501        if( msg == EQUIP_ERR_OK )                           // merge
1502        {
1503            // logging item move to bank
1504            if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
1505            {
1506                sLog.outCommand("GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u )",
1507                    _player->GetName(),_player->GetSession()->GetAccountId(),
1508                    pItemChar->GetProto()->Name1,pItemChar->GetEntry(),pItemChar->GetCount(),
1509                    GuildId);
1510            }
1511
1512            CharacterDatabase.BeginTransaction();
1513            pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), pItemChar->GetCount());
1514
1515            pl->MoveItemFromInventory(PlayerBag, PlayerSlot, true);
1516            pItemChar->DeleteFromInventoryDB();
1517
1518            pGuild->StoreItem(BankTab,dest,pItemChar);
1519            pl->SaveInventoryAndGoldToDB();
1520            CharacterDatabase.CommitTransaction();
1521
1522            pGuild->DisplayGuildBankContentUpdate(BankTab,dest);
1523        }
1524        else                                                // Char <-> Bank swap items (posible NULL bank item)
1525        {
1526            ItemPosCountVec iDest;
1527            if(pItemBank)
1528            {
1529                msg = pl->CanStoreItem(PlayerBag, PlayerSlot, iDest, pItemBank, true);
1530                if( msg != EQUIP_ERR_OK )
1531                {
1532                    pl->SendEquipError( msg, pItemBank, NULL );
1533                    return;
1534                }
1535            }
1536
1537            GuildItemPosCountVec gDest;
1538            msg = pGuild->CanStoreItem(BankTab,BankTabSlot,gDest,pItemChar->GetCount(),pItemChar,true);
1539            if( msg != EQUIP_ERR_OK )
1540            {
1541                pl->SendEquipError( msg, pItemChar, NULL );
1542                return;
1543            }
1544
1545            if(pItemBank)
1546            {
1547                // check bank pos rights (item swapped with inventory)
1548                uint32 remRight = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTab);
1549                if(remRight <= 0)
1550                    return;
1551            }
1552
1553            // logging item move to bank
1554            if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
1555            {
1556                sLog.outCommand("GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u )",
1557                    _player->GetName(),_player->GetSession()->GetAccountId(),
1558                    pItemChar->GetProto()->Name1,pItemChar->GetEntry(),pItemChar->GetCount(),
1559                    GuildId);
1560            }
1561
1562            CharacterDatabase.BeginTransaction();
1563            if(pItemBank)
1564                pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), pItemBank->GetCount());
1565            pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), pItemChar->GetCount());
1566
1567            pl->MoveItemFromInventory(PlayerBag, PlayerSlot, true);
1568            pItemChar->DeleteFromInventoryDB();
1569            if(pItemBank)
1570                pGuild->RemoveItem(BankTab, BankTabSlot);
1571
1572            pGuild->StoreItem(BankTab,gDest,pItemChar);
1573            if(pItemBank)
1574                pl->MoveItemToInventory(iDest,pItemBank,true);
1575            pl->SaveInventoryAndGoldToDB();
1576            if(pItemBank)
1577                pGuild->MemberItemWithdraw(BankTab, pl->GetGUIDLow());
1578            CharacterDatabase.CommitTransaction();
1579
1580            pGuild->DisplayGuildBankContentUpdate(BankTab,gDest);
1581        }
1582    }
1583}
1584
1585void WorldSession::HandleGuildBankBuyTab( WorldPacket & recv_data )
1586{
1587    sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_BUY_TAB)");
1588    CHECK_PACKET_SIZE(recv_data, 8+1);
1589    //recv_data.hexlike();
1590    uint64 GoGuid;
1591    uint8 TabId;
1592
1593    recv_data >> GoGuid;
1594    recv_data >> TabId;
1595
1596    if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
1597        return;
1598
1599    uint32 GuildId = GetPlayer()->GetGuildId();
1600    if (GuildId==0)
1601        return;
1602
1603    Guild *pGuild = objmgr.GetGuildById(GuildId);
1604    if(!pGuild)
1605        return;
1606
1607    uint32 TabCost = objmgr.GetGuildBankTabPrice(TabId) * GOLD;
1608    if (!TabCost)
1609        return;
1610
1611    if (pGuild->GetPurchasedTabs() >= GUILD_BANK_MAX_TABS)
1612        return;
1613
1614    if (TabId != pGuild->GetPurchasedTabs())                // purchased_tabs = 0 when buying Tab 0, that is why this check can be made
1615    {
1616        sLog.outError("Error: trying to buy a tab non contigous to owned ones");
1617        return;
1618    }
1619
1620    if (GetPlayer()->GetMoney() < TabCost)                  // Should not happen, this is checked by client
1621        return;
1622
1623    // Go on with creating tab
1624    pGuild->CreateNewBankTab();
1625    GetPlayer()->ModifyMoney(-int(TabCost));
1626    pGuild->SetBankMoneyPerDay(GetPlayer()->GetRank(), WITHDRAW_MONEY_UNLIMITED);
1627    pGuild->SetBankRightsAndSlots(GetPlayer()->GetRank(), TabId, GUILD_BANK_RIGHT_FULL, WITHDRAW_SLOT_UNLIMITED, true);
1628    pGuild->Roster(this);
1629    pGuild->DisplayGuildBankTabsInfo(this);
1630}
1631
1632void WorldSession::HandleGuildBankModifyTab( WorldPacket & recv_data )
1633{
1634    sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_UPDATE_TAB)");
1635    //recv_data.hexlike();
1636    CHECK_PACKET_SIZE(recv_data, 8+1+1+1);
1637    uint64 GoGuid;
1638    uint8 TabId;
1639    std::string Name;
1640    std::string IconIndex;
1641
1642    recv_data >> GoGuid;
1643    recv_data >> TabId;
1644    recv_data >> Name;
1645    recv_data >> IconIndex;
1646
1647    if(Name.empty())
1648        return;
1649
1650    if(IconIndex.empty())
1651        return;
1652
1653    if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
1654        return;
1655
1656    uint32 GuildId = GetPlayer()->GetGuildId();
1657    if (GuildId==0)
1658        return;
1659
1660    Guild *pGuild = objmgr.GetGuildById(GuildId);
1661    if(!pGuild)
1662        return;
1663
1664    pGuild->SetGuildBankTabInfo(TabId, Name, IconIndex);
1665    pGuild->DisplayGuildBankTabsInfo(this);
1666    pGuild->DisplayGuildBankContent(this, TabId);
1667}
1668
1669void WorldSession::HandleGuildBankLog( WorldPacket & recv_data )
1670{
1671    sLog.outDebug("WORLD: Received (MSG_GUILD_BANK_LOG_QUERY)");
1672    CHECK_PACKET_SIZE(recv_data, 1);
1673
1674    uint32 GuildId = GetPlayer()->GetGuildId();
1675    if (GuildId == 0)
1676        return;
1677
1678    Guild *pGuild = objmgr.GetGuildById(GuildId);
1679    if(!pGuild)
1680        return;
1681
1682    uint8 TabId;
1683    recv_data >> TabId;
1684
1685    pGuild->DisplayGuildBankLogs(this, TabId);
1686}
1687
1688void WorldSession::HandleGuildBankTabText(WorldPacket &recv_data)
1689{
1690    sLog.outDebug("WORLD: Received MSG_QUERY_GUILD_BANK_TEXT");
1691    CHECK_PACKET_SIZE(recv_data, 1);
1692
1693    uint32 GuildId = GetPlayer()->GetGuildId();
1694    if (GuildId == 0)
1695        return;
1696
1697    Guild *pGuild = objmgr.GetGuildById(GuildId);
1698    if(!pGuild)
1699        return;
1700
1701    uint8 TabId;
1702    recv_data >> TabId;
1703
1704    pGuild->SendGuildBankTabText(this, TabId);
1705}
1706
1707void WorldSession::HandleGuildBankSetTabText(WorldPacket &recv_data)
1708{
1709    sLog.outDebug("WORLD: Received CMSG_SET_GUILD_BANK_TEXT");
1710    CHECK_PACKET_SIZE(recv_data, 1+1);
1711
1712    uint32 GuildId = GetPlayer()->GetGuildId();
1713    if (GuildId == 0)
1714        return;
1715
1716    Guild *pGuild = objmgr.GetGuildById(GuildId);
1717    if(!pGuild)
1718        return;
1719
1720    uint8 TabId;
1721    std::string Text;
1722    recv_data >> TabId;
1723    recv_data >> Text;
1724
1725    pGuild->SetGuildBankTabText(TabId, Text);
1726}
1727
1728void WorldSession::SendSaveGuildEmblem( uint32 msg )
1729{
1730    WorldPacket data(MSG_SAVE_GUILD_EMBLEM, 4);
1731    data << uint32(msg);                                    // not part of guild
1732    SendPacket( &data );
1733}
Note: See TracBrowser for help on using the browser.