Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
Guild.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "AccountMgr.h"
7#include "CalendarMgr.h"
8#include "Chat.h"
9#include "Config.h"
10#include "DatabaseEnv.h"
11#include "Guild.h"
12#include "GuildFinderMgr.h"
13#include "GuildMgr.h"
14#include "Language.h"
15#include "Log.h"
16#include "Opcodes.h"
17#include "ScriptMgr.h"
18#include "SocialMgr.h"
19
20#define MAX_GUILD_BANK_TAB_TEXT_LEN 500
21#define EMBLEM_PRICE 10 * GOLD
22
24{
25 switch (event)
26 {
27 case GE_PROMOTION:
28 return "Member promotion";
29 case GE_DEMOTION:
30 return "Member demotion";
31 case GE_MOTD:
32 return "Guild MOTD";
33 case GE_JOINED:
34 return "Member joined";
35 case GE_LEFT:
36 return "Member left";
37 case GE_REMOVED:
38 return "Member removed";
39 case GE_LEADER_IS:
40 return "Leader is";
42 return "Leader changed";
43 case GE_DISBANDED:
44 return "Guild disbanded";
45 case GE_TABARDCHANGE:
46 return "Tabard change";
47 case GE_RANK_UPDATED:
48 return "Rank updated";
49 case GE_RANK_DELETED:
50 return "Rank deleted";
51 case GE_SIGNED_ON:
52 return "Member signed on";
53 case GE_SIGNED_OFF:
54 return "Member signed off";
56 return "Bank bag slots changed";
58 return "Bank tab purchased";
60 return "Bank tab updated";
62 return "Bank money set";
64 return "Bank money changed";
66 return "Bank tab text changed";
67 default:
68 break;
69 }
70 return "<None>";
71}
72
74{
75 switch (tabId)
76 {
77 case 0: return 100;
78 case 1: return 250;
79 case 2: return 500;
80 case 3: return 1000;
81 case 4: return 2500;
82 case 5: return 5000;
83 default: return 0;
84 }
85}
86
87void Guild::SendCommandResult(WorldSession* session, GuildCommandType type, GuildCommandError errCode, std::string const& param)
88{
89 WorldPacket data(SMSG_GUILD_COMMAND_RESULT, 8 + param.size() + 1);
90 data << uint32(type);
91 data << uint32(errCode);
92
93 data.WriteBits(param.size(), 8);
94 data.FlushBits();
95 data.WriteString(param);
96
97 session->SendPacket(&data);
98
99 SF_LOG_DEBUG("guild", "SMSG_GUILD_COMMAND_RESULT [%s]: Type: %u, code: %u, param: %s", session->GetPlayerInfo().c_str(), type, errCode, param.c_str());
100}
101
103{
105 data << uint32(errCode);
106 session->SendPacket(&data);
107
108 SF_LOG_DEBUG("guild", "MSG_SAVE_GUILD_EMBLEM [%s] Code: %u", session->GetPlayerInfo().c_str(), errCode);
109}
110
111// LogHolder
113{
114 // Cleanup
115 for (GuildLog::iterator itr = m_log.begin(); itr != m_log.end(); ++itr)
116 delete (*itr);
117}
118
119// Adds event loaded from database to collection
121{
123 m_nextGUID = entry->GetGUID();
124 m_log.push_front(entry);
125}
126
127// Adds new event happened in game.
128// If maximum number of events is reached, oldest event is removed from collection.
130{
131 // Check max records limit
132 if (m_log.size() >= m_maxRecords)
133 {
134 LogEntry* oldEntry = m_log.front();
135 delete oldEntry;
136 m_log.pop_front();
137 }
138 // Add event to list
139 m_log.push_back(entry);
140 // Save to DB
141 entry->SaveToDB(trans);
142}
143
144// Writes information about all events into packet.
146{
147 ByteBuffer buffer;
148 data.WriteBits(m_log.size(), 21);
149 for (GuildLog::const_iterator itr = m_log.begin(); itr != m_log.end(); ++itr)
150 (*itr)->WritePacket(data, buffer);
151
152 data.FlushBits();
153 data.append(buffer);
154}
155
157{
158 // Next guid was not initialized. It means there are no records for this holder in DB yet.
159 // Start from the beginning.
161 m_nextGUID = 0;
162 else
164 return m_nextGUID;
165}
166
167// EventLogEntry
169{
170 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_EVENTLOG);
171 stmt->setUInt32(0, m_guildId);
172 stmt->setUInt32(1, m_guid);
173 CharacterDatabase.ExecuteOrAppend(trans, stmt);
174
175 uint8 index = 0;
176 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_EVENTLOG);
177 stmt->setUInt32(index, m_guildId);
178 stmt->setUInt32(++index, m_guid);
179 stmt->setUInt8(++index, uint8(m_eventType));
180 stmt->setUInt32(++index, m_playerGuid1);
181 stmt->setUInt32(++index, m_playerGuid2);
182 stmt->setUInt8(++index, m_newRank);
183 stmt->setUInt64(++index, m_timestamp);
184 CharacterDatabase.ExecuteOrAppend(trans, stmt);
185}
186
188{
191
192 data.WriteGuidMask(PlayerGUID, 6, 1);
193 data.WriteGuidMask(OtherGUID, 5, 1, 3, 0, 4);
194 data.WriteGuidMask(PlayerGUID, 4);
195 data.WriteGuidMask(OtherGUID, 7);
196 data.WriteGuidMask(PlayerGUID, 0, 2, 7, 3, 5);
197 data.WriteGuidMask(OtherGUID, 2, 6);
198
199 content.WriteGuidBytes(PlayerGUID, 5, 4);
200 content.WriteGuidBytes(OtherGUID, 6);
201 content.WriteGuidBytes(PlayerGUID, 2);
202 content.WriteGuidBytes(OtherGUID, 4);
203
204 // Event type
205 content << uint8(m_eventType);
206
207 content.WriteGuidBytes(OtherGUID, 0);
208 content.WriteGuidBytes(PlayerGUID, 7, 3);
209 content.WriteGuidBytes(OtherGUID, 5, 2);
210 content.WriteGuidBytes(PlayerGUID, 0);
211
212 // Event timestamp
213 content << uint32(::time(NULL) - m_timestamp);
214
215 content.WriteGuidBytes(PlayerGUID, 1, 6);
216 content.WriteGuidBytes(OtherGUID, 7, 1);
217
218 // New Rank
219 content << uint8(m_newRank);
220
221 content.WriteGuidBytes(OtherGUID, 3);
222}
223
224// BankEventLogEntry
226{
227 uint8 index = 0;
228
230 stmt->setUInt32(index, m_guildId);
231 stmt->setUInt32(++index, m_guid);
232 stmt->setUInt8(++index, m_bankTabId);
233 CharacterDatabase.ExecuteOrAppend(trans, stmt);
234
235 index = 0;
236 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_EVENTLOG);
237 stmt->setUInt32(index, m_guildId);
238 stmt->setUInt32(++index, m_guid);
239 stmt->setUInt8(++index, m_bankTabId);
240 stmt->setUInt8(++index, uint8(m_eventType));
241 stmt->setUInt32(++index, m_playerGuid);
242 stmt->setUInt32(++index, m_itemOrMoney);
243 stmt->setUInt16(++index, m_itemStackCount);
244 stmt->setUInt8(++index, m_destTabId);
245 stmt->setUInt64(++index, m_timestamp);
246 CharacterDatabase.ExecuteOrAppend(trans, stmt);
247}
248
250{
252 ObjectGuid unkGuid = 0;
253
256
258
259 bool hasStack = (hasItem && m_itemStackCount > 1) || itemMoved;
260
261 data.WriteBit(IsMoneyEvent());
262 data.WriteBit(logGuid[0]);
263 data.WriteBit(logGuid[2]);
264 data.WriteBit(logGuid[3]);
265 data.WriteBit(logGuid[6]);
266 data.WriteBit(logGuid[5]);
267 data.WriteBit(logGuid[4]);
268 data.WriteBit(hasStack);
269 data.WriteBit(hasItem);
270 data.WriteBit(logGuid[7]);
271 data.WriteBit(logGuid[1]);
272 data.WriteBit(itemMoved);
273
274 content.WriteByteSeq(logGuid[1]);
275 content.WriteByteSeq(logGuid[7]);
276
277 if (itemMoved)
278 content << uint8(m_destTabId);
279
280 content.WriteByteSeq(logGuid[2]);
281 content << uint32(time(NULL) - m_timestamp);
282 content << uint8(m_eventType);
283 content.WriteByteSeq(logGuid[0]);
284 content.WriteByteSeq(logGuid[4]);
285
286 if (hasItem)
287 content << uint32(m_itemOrMoney);
288
289 if (IsMoneyEvent())
290 content << uint64(m_itemOrMoney);
291
292 content.WriteByteSeq(logGuid[6]);
293
294 if (hasStack)
295 content << uint32(m_itemStackCount);
296
297 content.WriteByteSeq(logGuid[5]);
298 content.WriteByteSeq(logGuid[3]);
299}
300
302{
303 uint8 index = 0;
304 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_NEWS);
305 stmt->setUInt32(index, m_guildId);
306 stmt->setUInt32(++index, GetGUID());
307 stmt->setUInt8(++index, GetType());
308 stmt->setUInt32(++index, GetPlayerGuid());
309 stmt->setUInt32(++index, GetFlags());
310 stmt->setUInt32(++index, GetValue());
311 stmt->setUInt64(++index, GetTimestamp());
312 CharacterDatabase.ExecuteOrAppend(trans, stmt);
313}
314
316{
317 ObjectGuid guid = GetPlayerGuid();
318
319 data.WriteBit(guid[3]);
320 data.WriteBits(0, 24); // Not yet implemented used for guild achievements
321 data.WriteBit(guid[4]);
322 data.WriteBit(guid[5]);
323 data.WriteBit(guid[6]);
324 data.WriteBit(guid[0]);
325 data.WriteBit(guid[7]);
326 data.WriteBit(guid[2]);
327 data.WriteBit(guid[1]);
328
329 data.FlushBits();
330
331 data.WriteByteSeq(guid[2]);
332 data << uint32(GetValue());
333 data.WriteByteSeq(guid[1]);
334 data.WriteByteSeq(guid[7]);
335 data.WriteByteSeq(guid[4]);
336 data.WriteByteSeq(guid[3]);
337 data.WriteByteSeq(guid[5]);
338 data << uint32(0);
339 data << uint32(GetType());
340 data << uint32(GetFlags()); // 1 sticky
341 data.WriteByteSeq(guid[6]);
343 data << uint32(GetGUID());
344 data.WriteByteSeq(guid[0]);
345}
346
347// RankInfo
349{
350 m_rankId = fields[1].GetUInt8();
351 m_name = fields[2].GetString();
352 m_rights = fields[3].GetUInt32();
353 m_bankMoneyPerDay = fields[4].GetUInt32();
354 if (m_rankId == GR_GUILDMASTER) // Prevent loss of leader rights
356}
357
359{
360 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_RANK);
361 stmt->setUInt32(0, m_guildId);
362 stmt->setUInt8(1, m_rankId);
363 stmt->setString(2, m_name);
364 stmt->setUInt32(3, m_rights);
366 CharacterDatabase.ExecuteOrAppend(trans, stmt);
367}
368
369void Guild::RankInfo::CreateMissingTabsIfNeeded(uint8 tabs, SQLTransaction& trans, bool logOnCreate /* = false */)
370{
371 for (uint8 i = 0; i < tabs; ++i)
372 {
374 if (rightsAndSlots.GetTabId() == i)
375 continue;
376
377 rightsAndSlots.SetTabId(i);
379 rightsAndSlots.SetGuildMasterValues();
380
381 if (logOnCreate)
382 SF_LOG_ERROR("guild", "Guild %u has broken Tab %u for rank %u. Created default tab.", m_guildId, i, m_rankId);
383
385 stmt->setUInt32(0, m_guildId);
386 stmt->setUInt8(1, i);
387 stmt->setUInt8(2, m_rankId);
388 stmt->setUInt8(3, rightsAndSlots.GetRights());
389 stmt->setUInt32(4, rightsAndSlots.GetSlots());
390 trans->Append(stmt);
391 }
392}
393
394void Guild::RankInfo::SetName(std::string const& name)
395{
396 if (m_name == name)
397 return;
398
399 m_name = name;
400
402 stmt->setString(0, m_name);
403 stmt->setUInt8(1, m_rankId);
404 stmt->setUInt32(2, m_guildId);
405 CharacterDatabase.Execute(stmt);
406}
407
409{
410 if (m_rankId == GR_GUILDMASTER) // Prevent loss of leader rights
411 rights = GR_RIGHT_ALL;
412
413 if (m_rights == rights)
414 return;
415
416 m_rights = rights;
417
419 stmt->setUInt32(0, m_rights);
420 stmt->setUInt8(1, m_rankId);
421 stmt->setUInt32(2, m_guildId);
422 CharacterDatabase.Execute(stmt);
423}
424
426{
427 if (m_rankId == GR_GUILDMASTER) // Prevent loss of leader rights
429
430 if (m_bankMoneyPerDay == money)
431 return;
432
433 m_bankMoneyPerDay = money;
434
436 stmt->setUInt32(0, money);
437 stmt->setUInt8(1, m_rankId);
438 stmt->setUInt32(2, m_guildId);
439 CharacterDatabase.Execute(stmt);
440}
441
443{
444 if (m_rankId == GR_GUILDMASTER) // Prevent loss of leader rights
445 rightsAndSlots.SetGuildMasterValues();
446
447 GuildBankRightsAndSlots& guildBR = m_bankTabRightsAndSlots[rightsAndSlots.GetTabId()];
448 guildBR = rightsAndSlots;
449
450 if (saveToDB)
451 {
453 stmt->setUInt32(0, m_guildId);
454 stmt->setUInt8(1, guildBR.GetTabId());
455 stmt->setUInt8(2, m_rankId);
456 stmt->setUInt8(3, guildBR.GetRights());
457 stmt->setUInt32(4, guildBR.GetSlots());
458 CharacterDatabase.Execute(stmt);
459 }
460}
461
462// BankTab
464{
465 m_name = fields[2].GetString();
466 m_icon = fields[3].GetString();
467 m_text = fields[4].GetString();
468}
469
471{
472 uint8 slotId = fields[13].GetUInt8();
473 uint32 itemGuid = fields[14].GetUInt32();
474 uint32 itemEntry = fields[15].GetUInt32();
475 if (slotId >= GUILD_BANK_MAX_SLOTS)
476 {
477 SF_LOG_ERROR("guild", "Invalid slot for item (GUID: %u, id: %u) in guild bank, skipped.", itemGuid, itemEntry);
478 return false;
479 }
480
481 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemEntry);
482 if (!proto)
483 {
484 SF_LOG_ERROR("guild", "Unknown item (GUID: %u, id: %u) in guild bank, skipped.", itemGuid, itemEntry);
485 return false;
486 }
487
488 Item* pItem = NewItemOrBag(proto);
489 if (!pItem->LoadFromDB(itemGuid, 0, fields, itemEntry))
490 {
491 SF_LOG_ERROR("guild", "Item (GUID %u, id: %u) not found in item_instance, deleting from guild bank!", itemGuid, itemEntry);
492
494 stmt->setUInt32(0, m_guildId);
495 stmt->setUInt8(1, m_tabId);
496 stmt->setUInt8(2, slotId);
497 CharacterDatabase.Execute(stmt);
498
499 delete pItem;
500 return false;
501 }
502
503 pItem->AddToWorld();
504 m_items[slotId] = pItem;
505 return true;
506}
507
508// Deletes contents of the tab from the world (and from DB if necessary)
509void Guild::BankTab::Delete(SQLTransaction& trans, bool removeItemsFromDB)
510{
511 for (uint8 slotId = 0; slotId < GUILD_BANK_MAX_SLOTS; ++slotId)
512 if (Item* pItem = m_items[slotId])
513 {
514 pItem->RemoveFromWorld();
515 if (removeItemsFromDB)
516 pItem->DeleteFromDB(trans);
517 delete pItem;
518 pItem = NULL;
519 }
520}
521
522void Guild::BankTab::SetInfo(std::string const& name, std::string const& icon)
523{
524 if (m_name == name && m_icon == icon)
525 return;
526
527 m_name = name;
528 m_icon = icon;
529
531 stmt->setString(0, m_name);
532 stmt->setString(1, m_icon);
533 stmt->setUInt32(2, m_guildId);
534 stmt->setUInt8(3, m_tabId);
535 CharacterDatabase.Execute(stmt);
536}
537
538void Guild::BankTab::SetText(std::string const& text)
539{
540 if (m_text == text)
541 return;
542
543 m_text = text;
544 utf8truncate(m_text, MAX_GUILD_BANK_TAB_TEXT_LEN); // DB and client size limitation
545
547 stmt->setString(0, m_text);
548 stmt->setUInt32(1, m_guildId);
549 stmt->setUInt8(2, m_tabId);
550 CharacterDatabase.Execute(stmt);
551}
552
553// Sets/removes contents of specified slot.
554// If pItem == NULL contents are removed.
556{
557 if (slotId >= GUILD_BANK_MAX_SLOTS)
558 return false;
559
560 m_items[slotId] = item;
561
563 stmt->setUInt32(0, m_guildId);
564 stmt->setUInt8(1, m_tabId);
565 stmt->setUInt8(2, slotId);
566 CharacterDatabase.ExecuteOrAppend(trans, stmt);
567
568 if (item)
569 {
570 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_ITEM);
571 stmt->setUInt32(0, m_guildId);
572 stmt->setUInt8(1, m_tabId);
573 stmt->setUInt8(2, slotId);
574 stmt->setUInt32(3, item->GetGUIDLow());
575 CharacterDatabase.ExecuteOrAppend(trans, stmt);
576
579 item->FSetState(ITEM_NEW);
580 item->SaveToDB(trans); // Not in inventory and can be saved standalone
581 }
582 return true;
583}
584
585void Guild::BankTab::SendText(Guild const* guild, WorldSession* session) const
586{
588 data << uint32(m_tabId);
589
590 data.WriteBits(m_text.length(), 14);
591 data.FlushBits();
592
593 data.WriteString(m_text);
594
595 if (session)
596 {
597 SF_LOG_DEBUG("guild", "SMSG_GUILD_BANK_QUERY_TEXT_RESULT [%s]: Tabid: %u, Text: %s", session->GetPlayerInfo().c_str(), m_tabId, m_text.c_str());
598 session->SendPacket(&data);
599 }
600 else
601 {
602 SF_LOG_DEBUG("guild", "SMSG_GUILD_BANK_QUERY_TEXT_RESULT [Broadcast]: Tabid: %u, Text: %s", m_tabId, m_text.c_str());
603 guild->BroadcastPacket(&data);
604 }
605}
606
607// Member
609{
611 m_name = player->GetName();
612 m_level = player->getLevel();
613 m_class = player->getClass();
614 m_zoneId = player->GetZoneId();
615 m_accountId = player->GetSession()->GetAccountId();
617}
618
619void Guild::Member::SetStats(uint32 virtualRealmID, std::string const& name, uint8 level, uint8 _class, uint32 zoneId, uint32 accountId, uint32 reputation)
620{
621 m_memberVRealm = virtualRealmID;
622 m_name = name;
623 m_level = level;
624 m_class = _class;
625 m_zoneId = zoneId;
626 m_accountId = accountId;
627 m_totalReputation = reputation;
628}
629
630void Guild::Member::SetPublicNote(std::string const& publicNote)
631{
632 if (m_publicNote == publicNote)
633 return;
634
635 m_publicNote = publicNote;
636
638 stmt->setString(0, publicNote);
639 stmt->setUInt32(1, GUID_LOPART(m_guid));
640 CharacterDatabase.Execute(stmt);
641}
642
643void Guild::Member::SetOfficerNote(std::string const& officerNote)
644{
645 if (m_officerNote == officerNote)
646 return;
647
648 m_officerNote = officerNote;
649
651 stmt->setString(0, officerNote);
652 stmt->setUInt32(1, GUID_LOPART(m_guid));
653 CharacterDatabase.Execute(stmt);
654}
655
657{
658 m_rankId = newRank;
659
660 // Update rank information in player's field, if he is online.
661 if (Player* player = FindPlayer())
662 player->SetRank(newRank);
663
665 stmt->setUInt8(0, newRank);
666 stmt->setUInt32(1, GUID_LOPART(m_guid));
667 CharacterDatabase.Execute(stmt);
668}
669
671{
672 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_MEMBER);
673 stmt->setUInt32(0, m_guildId);
674 stmt->setUInt32(1, GUID_LOPART(m_guid));
675 stmt->setUInt8(2, m_rankId);
676 stmt->setString(3, m_publicNote);
677 stmt->setString(4, m_officerNote);
678 CharacterDatabase.ExecuteOrAppend(trans, stmt);
679}
680
681// Loads member's data from database.
682// If member has broken fields (level, class) returns false.
683// In this case member has to be removed from guild.
685{
686 m_publicNote = fields[3].GetString();
687 m_officerNote = fields[4].GetString();
688
689 for (uint8 i = 0; i <= GUILD_BANK_MAX_TABS; ++i)
690 m_bankWithdraw[i] = fields[5 + i].GetUInt32();
691
692 SetStats(fields[20].GetUInt32(),
693 fields[14].GetString(),
694 fields[15].GetUInt8(), // characters.level
695 fields[16].GetUInt8(), // characters.class
696 fields[17].GetUInt16(), // characters.zone
697 fields[18].GetUInt32(), // characters.account
698 0);
699 m_logoutTime = fields[19].GetUInt32(); // characters.logout_time
700 m_totalActivity = 0;
701 m_weekActivity = 0;
703
704 if (!CheckStats())
705 return false;
706
707 if (!m_zoneId)
708 {
709 SF_LOG_ERROR("guild", "Player (GUID: %u) has broken zone-data", GUID_LOPART(m_guid));
711 }
712 ResetFlags();
713 return true;
714}
715
716// Validate player fields. Returns false if corrupted fields are found.
718{
719 if (m_level < 1)
720 {
721 SF_LOG_ERROR("guild", "Player (GUID: %u) has a broken data in field `characters`.`level`, deleting him from guild!", GUID_LOPART(m_guid));
722 return false;
723 }
724
725 if (m_class < CLASS_WARRIOR || m_class >= MAX_CLASSES)
726 {
727 SF_LOG_ERROR("guild", "Player (GUID: %u) has a broken data in field `characters`.`class`, deleting him from guild!", GUID_LOPART(m_guid));
728 return false;
729 }
730 return true;
731}
732
733// Decreases amount of money/slots left for today.
734// If (tabId == GUILD_BANK_MAX_TABS) decrease money amount.
735// Otherwise decrease remaining items amount for specified tab.
737{
738 m_bankWithdraw[tabId] += amount;
739
741 stmt->setUInt32(0, GUID_LOPART(m_guid));
742 for (uint8 i = 0; i <= GUILD_BANK_MAX_TABS;)
743 {
744 uint32 withdraw = m_bankWithdraw[i++];
745 stmt->setUInt32(i, withdraw);
746 }
747
748 CharacterDatabase.ExecuteOrAppend(trans, stmt);
749}
750
751void Guild::Member::ResetValues(bool weekly /* = false*/)
752{
753 for (uint8 tabId = 0; tabId <= GUILD_BANK_MAX_TABS; ++tabId)
754 m_bankWithdraw[tabId] = 0;
755
756 if (weekly)
757 {
758 m_weekActivity = 0;
760 }
761}
762
763// Get amount of money/slots left for today.
764// If (tabId == GUILD_BANK_MAX_TABS) return money amount.
765// Otherwise return remaining items amount for specified tab.
767{
768 // Guild master has unlimited amount.
771
772 return m_bankWithdraw[tabId];
773}
774
775// EmblemInfo
780
782{
783 m_style = fields[3].GetUInt8();
784 m_color = fields[4].GetUInt8();
785 m_borderStyle = fields[5].GetUInt8();
786 m_borderColor = fields[6].GetUInt8();
787 m_backgroundColor = fields[7].GetUInt8();
788}
789
791{
792 data << uint32(m_style);
793 data << uint32(m_color);
794 data << uint32(m_borderStyle);
795 data << uint32(m_borderColor);
796 data << uint32(m_backgroundColor);
797}
798
799void EmblemInfo::SaveToDB(uint32 guildId) const
800{
802 stmt->setUInt32(0, m_style);
803 stmt->setUInt32(1, m_color);
804 stmt->setUInt32(2, m_borderStyle);
805 stmt->setUInt32(3, m_borderColor);
807 stmt->setUInt32(5, guildId);
808 CharacterDatabase.Execute(stmt);
809}
810
811// MoveItemData
813{
815 if (splitedAmount > m_pItem->GetCount())
816 return false;
817 if (splitedAmount == m_pItem->GetCount())
818 splitedAmount = 0;
819 return true;
820}
821
822bool Guild::MoveItemData::CanStore(Item* pItem, bool swap, bool sendError)
823{
824 m_vec.clear();
825 InventoryResult msg = CanStore(pItem, swap);
826 if (sendError && msg != EQUIP_ERR_OK)
827 m_pPlayer->SendEquipError(msg, pItem);
828 return (msg == EQUIP_ERR_OK);
829}
830
832{
834 m_pClonedItem = m_pItem->CloneItem(count);
835 if (!m_pClonedItem)
836 {
838 return false;
839 }
840 return true;
841}
842
844{
845 ASSERT(pFrom->GetItem());
846
847 sScriptMgr->OnGuildItemMove(m_pGuild, m_pPlayer, pFrom->GetItem(),
848 pFrom->IsBank(), pFrom->GetContainer(), pFrom->GetSlotId(),
850}
851
853{
854 for (ItemPosCountVec::const_iterator itr = m_vec.begin(); itr != m_vec.end(); ++itr)
855 ids.insert(uint8(itr->pos));
856}
857
858// PlayerMoveItemData
860{
861 m_pItem = m_pPlayer->GetItemByPos(m_container, m_slotId);
862 if (m_pItem)
863 {
864 // Anti-WPE protection. Do not move non-empty bags to bank.
865 if (m_pItem->IsNotEmptyBag())
866 {
868 m_pItem = NULL;
869 }
870 // Bound items cannot be put into bank.
871 else if (!m_pItem->CanBeTraded())
872 {
873 m_pPlayer->SendEquipError(EQUIP_ERR_CANT_SWAP, m_pItem);
874 m_pItem = NULL;
875 }
876 }
877 return (m_pItem != NULL);
878}
879
881{
882 if (splitedAmount)
883 {
884 m_pItem->SetCount(m_pItem->GetCount() - splitedAmount);
885 m_pItem->SetState(ITEM_CHANGED, m_pPlayer);
886 m_pPlayer->SaveInventoryAndGoldToDB(trans);
887 }
888 else
889 {
890 m_pPlayer->MoveItemFromInventory(m_container, m_slotId, true);
891 m_pItem->DeleteFromInventoryDB(trans);
892 m_pItem = NULL;
893 }
894}
895
897{
898 ASSERT(pItem);
899 m_pPlayer->MoveItemToInventory(m_vec, pItem, true);
900 m_pPlayer->SaveInventoryAndGoldToDB(trans);
901 return pItem;
902}
903
905{
906 ASSERT(pFrom);
907 // Bank -> Char
908 m_pGuild->_LogBankEvent(trans, GUILD_BANK_LOG_WITHDRAW_ITEM, pFrom->GetContainer(), m_pPlayer->GetGUIDLow(),
909 pFrom->GetItem()->GetEntry(), count);
910}
911
913{
914 return m_pPlayer->CanStoreItem(m_container, m_slotId, m_vec, pItem, swap);
915}
916
917// BankMoveItemData
919{
920 m_pItem = m_pGuild->_GetItem(m_container, m_slotId);
921 return (m_pItem != NULL);
922}
923
925{
926 ASSERT(pOther);
927 // Do not check rights if item is being swapped within the same bank tab
928 if (pOther->IsBank() && pOther->GetContainer() == m_container)
929 return true;
930 return m_pGuild->_MemberHasTabRights(m_pPlayer->GetGUID(), m_container, GUILD_BANK_RIGHT_DEPOSIT_ITEM);
931}
932
934{
935 ASSERT(pOther);
936 // Do not check rights if item is being swapped within the same bank tab
937 if (pOther->IsBank() && pOther->GetContainer() == m_container)
938 return true;
939
940 int32 slots = 0;
941 if (Member const* member = m_pGuild->GetMember(m_pPlayer->GetGUID()))
942 slots = m_pGuild->_GetMemberRemainingSlots(member, m_container);
943
944 return slots != 0;
945}
946
948{
950 if (splitedAmount)
951 {
952 m_pItem->SetCount(m_pItem->GetCount() - splitedAmount);
953 m_pItem->FSetState(ITEM_CHANGED);
954 m_pItem->SaveToDB(trans);
955 }
956 else
957 {
958 m_pGuild->_RemoveItem(trans, m_container, m_slotId);
959 m_pItem = NULL;
960 }
961 // Decrease amount of player's remaining items (if item is moved to different tab or to player)
962 if (!pOther->IsBank() || pOther->GetContainer() != m_container)
963 m_pGuild->_UpdateMemberWithdrawSlots(trans, m_pPlayer->GetGUID(), m_container);
964}
965
967{
968 if (!pItem)
969 return NULL;
970
971 BankTab* pTab = m_pGuild->GetBankTab(m_container);
972 if (!pTab)
973 return NULL;
974
975 Item* pLastItem = pItem;
976 for (ItemPosCountVec::const_iterator itr = m_vec.begin(); itr != m_vec.end(); )
977 {
978 ItemPosCount pos(*itr);
979 ++itr;
980
981 SF_LOG_DEBUG("guild", "GUILD STORAGE: StoreItem tab = %u, slot = %u, item = %u, count = %u",
982 m_container, m_slotId, pItem->GetEntry(), pItem->GetCount());
983 pLastItem = _StoreItem(trans, pTab, pItem, pos, itr != m_vec.end());
984 }
985 return pLastItem;
986}
987
989{
990 ASSERT(pFrom->GetItem());
991 if (pFrom->IsBank())
992 // Bank -> Bank
993 m_pGuild->_LogBankEvent(trans, GUILD_BANK_LOG_MOVE_ITEM, pFrom->GetContainer(), m_pPlayer->GetGUIDLow(),
994 pFrom->GetItem()->GetEntry(), count, m_container);
995 else
996 // Char -> Bank
997 m_pGuild->_LogBankEvent(trans, GUILD_BANK_LOG_DEPOSIT_ITEM, m_container, m_pPlayer->GetGUIDLow(),
998 pFrom->GetItem()->GetEntry(), count);
999}
1000
1002{
1004 if (!pFrom->IsBank() && m_pPlayer->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
1005 {
1006 sLog->outCommand(m_pPlayer->GetSession()->GetAccountId(),
1007 "GM %s (Guid: %u) (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank named: %s (Guild ID: %u)",
1008 m_pPlayer->GetName().c_str(), m_pPlayer->GetGUIDLow(), m_pPlayer->GetSession()->GetAccountId(),
1009 pFrom->GetItem()->GetTemplate()->Name1.c_str(), pFrom->GetItem()->GetEntry(), pFrom->GetItem()->GetCount(),
1010 m_pGuild->GetName().c_str(), m_pGuild->GetId());
1011 }
1012}
1013
1015{
1016 uint8 slotId = uint8(pos.pos);
1017 uint32 count = pos.count;
1018 if (Item* pItemDest = pTab->GetItem(slotId))
1019 {
1020 pItemDest->SetCount(pItemDest->GetCount() + count);
1021 pItemDest->FSetState(ITEM_CHANGED);
1022 pItemDest->SaveToDB(trans);
1023 if (!clone)
1024 {
1025 pItem->RemoveFromWorld();
1026 pItem->DeleteFromDB(trans);
1027 delete pItem;
1028 }
1029 return pItemDest;
1030 }
1031
1032 if (clone)
1033 pItem = pItem->CloneItem(count);
1034 else
1035 pItem->SetCount(count);
1036
1037 if (pItem && pTab->SetItem(trans, slotId, pItem))
1038 return pItem;
1039
1040 return NULL;
1041}
1042
1043// Tries to reserve space for source item.
1044// If item in destination slot exists it must be the item of the same entry
1045// and stack must have enough space to take at least one item.
1046// Returns false if destination item specified and it cannot be used to reserve space.
1047bool Guild::BankMoveItemData::_ReserveSpace(uint8 slotId, Item* pItem, Item* pItemDest, uint32& count)
1048{
1049 uint32 requiredSpace = pItem->GetMaxStackCount();
1050 if (pItemDest)
1051 {
1052 // Make sure source and destination items match and destination item has space for more stacks.
1053 if (pItemDest->GetEntry() != pItem->GetEntry() || pItemDest->GetCount() >= pItem->GetMaxStackCount())
1054 return false;
1055 requiredSpace -= pItemDest->GetCount();
1056 }
1057 // Let's not be greedy, reserve only required space
1058 requiredSpace = std::min(requiredSpace, count);
1059
1060 // Reserve space
1061 ItemPosCount pos(slotId, requiredSpace);
1062 if (!pos.isContainedIn(m_vec))
1063 {
1064 m_vec.push_back(pos);
1065 count -= requiredSpace;
1066 }
1067 return true;
1068}
1069
1070void Guild::BankMoveItemData::CanStoreItemInTab(Item* pItem, uint8 skipSlotId, bool merge, uint32& count)
1071{
1072 for (uint8 slotId = 0; (slotId < GUILD_BANK_MAX_SLOTS) && (count > 0); ++slotId)
1073 {
1074 // Skip slot already processed in CanStore (when destination slot was specified)
1075 if (slotId == skipSlotId)
1076 continue;
1077
1078 Item* pItemDest = m_pGuild->_GetItem(m_container, slotId);
1079 if (pItemDest == pItem)
1080 pItemDest = NULL;
1081
1082 // If merge skip empty, if not merge skip non-empty
1083 if ((pItemDest != NULL) != merge)
1084 continue;
1085
1086 _ReserveSpace(slotId, pItem, pItemDest, count);
1087 }
1088}
1089
1091{
1092 SF_LOG_DEBUG("guild", "GUILD STORAGE: CanStore() tab = %u, slot = %u, item = %u, count = %u",
1093 m_container, m_slotId, pItem->GetEntry(), pItem->GetCount());
1094
1095 uint32 count = pItem->GetCount();
1096 // Soulbound items cannot be moved
1097 if (pItem->IsSoulBound())
1099
1100 // Make sure destination bank tab exists
1101 if (m_container >= m_pGuild->_GetPurchasedTabsSize())
1103
1104 // Slot explicitely specified. Check it.
1105 if (m_slotId != NULL_SLOT)
1106 {
1107 Item* pItemDest = m_pGuild->_GetItem(m_container, m_slotId);
1108 // Ignore swapped item (this slot will be empty after move)
1109 if ((pItemDest == pItem) || swap)
1110 pItemDest = NULL;
1111
1112 if (!_ReserveSpace(m_slotId, pItem, pItemDest, count))
1113 return EQUIP_ERR_CANT_STACK;
1114
1115 if (count == 0)
1116 return EQUIP_ERR_OK;
1117 }
1118
1119 // Slot was not specified or it has not enough space for all the items in stack
1120 // Search for stacks to merge with
1121 if (pItem->GetMaxStackCount() > 1)
1122 {
1123 CanStoreItemInTab(pItem, m_slotId, true, count);
1124 if (count == 0)
1125 return EQUIP_ERR_OK;
1126 }
1127
1128 // Search free slot for item
1129 CanStoreItemInTab(pItem, m_slotId, false, count);
1130 if (count == 0)
1131 return EQUIP_ERR_OK;
1132
1133 return EQUIP_ERR_BANK_FULL;
1134}
1135
1136// Guild
1138 m_id(0),
1139 m_leaderGuid(0),
1140 m_createdDate(0),
1142 m_bankMoney(0),
1143 m_eventLog(NULL),
1144 m_newsLog(NULL),
1145 m_achievementMgr(this),
1146 _level(1),
1147 _experience(0),
1149{
1150 memset(&m_bankEventLog, 0, (GUILD_BANK_MAX_TABS + 1) * sizeof(LogHolder*));
1151}
1152
1154{
1155 SQLTransaction temp(NULL);
1156 _DeleteBankItems(temp);
1157
1158 // Cleanup
1159 delete m_eventLog;
1160 m_eventLog = NULL;
1161 delete m_newsLog;
1162 m_newsLog = NULL;
1163
1164 for (uint8 tabId = 0; tabId <= GUILD_BANK_MAX_TABS; ++tabId)
1165 {
1166 delete m_bankEventLog[tabId];
1167 m_bankEventLog[tabId] = NULL;
1168 }
1169
1170 for (Members::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
1171 {
1172 delete itr->second;
1173 itr->second = NULL;
1174 }
1175}
1176
1177// Creates new guild with default data and saves it to database.
1178bool Guild::Create(Player* pLeader, std::string const& name)
1179{
1180 // Check if guild with such name already exists
1181 if (sGuildMgr->GetGuildByName(name))
1182 return false;
1183
1184 WorldSession* pLeaderSession = pLeader->GetSession();
1185 if (!pLeaderSession)
1186 return false;
1187
1188 m_id = sGuildMgr->GenerateGuildId();
1189 m_leaderGuid = pLeader->GetGUID();
1190 m_name = name;
1191 m_info = "";
1192 m_motd = "No message set.";
1193 m_bankMoney = 0;
1194 m_createdDate = ::time(NULL);
1195 _level = 1;
1196 _experience = 0;
1197 _todayExperience = 0;
1199
1200 SF_LOG_DEBUG("guild", "GUILD: creating guild [%s] for leader %s (%u)",
1201 name.c_str(), pLeader->GetName().c_str(), GUID_LOPART(m_leaderGuid));
1202
1203 SQLTransaction trans = CharacterDatabase.BeginTransaction();
1204
1205 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_MEMBERS);
1206 stmt->setUInt32(0, m_id);
1207 trans->Append(stmt);
1208
1209 uint8 index = 0;
1210 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD);
1211 stmt->setUInt32(index, m_id);
1212 stmt->setString(++index, name);
1213 stmt->setUInt32(++index, GUID_LOPART(m_leaderGuid));
1214 stmt->setString(++index, m_info);
1215 stmt->setString(++index, m_motd);
1216 stmt->setUInt64(++index, uint32(m_createdDate));
1217 stmt->setUInt32(++index, m_emblemInfo.GetStyle());
1218 stmt->setUInt32(++index, m_emblemInfo.GetColor());
1219 stmt->setUInt32(++index, m_emblemInfo.GetBorderStyle());
1220 stmt->setUInt32(++index, m_emblemInfo.GetBorderColor());
1221 stmt->setUInt32(++index, m_emblemInfo.GetBackgroundColor());
1222 stmt->setUInt64(++index, m_bankMoney);
1223 trans->Append(stmt);
1224
1225 CharacterDatabase.CommitTransaction(trans);
1226 _CreateDefaultGuildRanks(pLeaderSession->GetSessionDbLocaleIndex()); // Create default ranks
1227 bool ret = AddMember(m_leaderGuid, GR_GUILDMASTER); // Add guildmaster
1228
1229 if (ret)
1230 {
1232 sScriptMgr->OnGuildCreate(this, pLeader, name);
1233 }
1234
1235 return ret;
1236}
1237
1238// Disbands guild and deletes all related data from database
1240{
1241 // Call scripts before guild data removed from database
1242 sScriptMgr->OnGuildDisband(this);
1243
1245 // Remove all members
1246 while (!m_members.empty())
1247 {
1248 Members::const_iterator itr = m_members.begin();
1249 DeleteMember(itr->second->GetGUID(), true);
1250 }
1251
1252 SQLTransaction trans = CharacterDatabase.BeginTransaction();
1253
1254 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD);
1255 stmt->setUInt32(0, m_id);
1256 trans->Append(stmt);
1257
1258 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_RANKS);
1259 stmt->setUInt32(0, m_id);
1260 trans->Append(stmt);
1261
1262 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_TABS);
1263 stmt->setUInt32(0, m_id);
1264 trans->Append(stmt);
1265
1266 // Free bank tab used memory and delete items stored in them
1267 _DeleteBankItems(trans, true);
1268
1269 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_ITEMS);
1270 stmt->setUInt32(0, m_id);
1271 trans->Append(stmt);
1272
1273 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_RIGHTS);
1274 stmt->setUInt32(0, m_id);
1275 trans->Append(stmt);
1276
1277 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_EVENTLOGS);
1278 stmt->setUInt32(0, m_id);
1279 trans->Append(stmt);
1280
1281 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_EVENTLOGS);
1282 stmt->setUInt32(0, m_id);
1283 trans->Append(stmt);
1284
1285 CharacterDatabase.CommitTransaction(trans);
1286
1287 sGuildFinderMgr->DeleteGuild(m_id);
1288
1289 sGuildMgr->RemoveGuild(m_id);
1290}
1291
1293{
1294 SQLTransaction trans = CharacterDatabase.BeginTransaction();
1295
1297 stmt->setUInt32(0, GetLevel());
1298 stmt->setUInt64(1, GetExperience());
1299 stmt->setUInt64(2, GetTodayExperience());
1300 stmt->setUInt32(3, GetId());
1301 trans->Append(stmt);
1302
1303 m_achievementMgr.SaveToDB(trans);
1304
1305 CharacterDatabase.CommitTransaction(trans);
1306}
1307
1308void Guild::UpdateMemberData(Player* player, uint8 dataid, uint32 value)
1309{
1310 if (Member* member = GetMember(player->GetGUID()))
1311 {
1312 switch (dataid)
1313 {
1315 member->SetZoneId(value);
1316 break;
1318 member->SetAchievementPoints(value);
1319 break;
1321 member->SetLevel(value);
1322 break;
1323 default:
1324 SF_LOG_ERROR("guild", "Guild::UpdateMemberData: Called with incorrect DATAID %u (value %u)", dataid, value);
1325 return;
1326 }
1327 //HandleRoster();
1328 }
1329}
1330
1331void Guild::OnPlayerStatusChange(Player* player, uint32 flag, bool state)
1332{
1333 if (Member* member = GetMember(player->GetGUID()))
1334 {
1335 if (state)
1336 member->AddFlag(flag);
1337 else member->RemFlag(flag);
1338 }
1339}
1340
1341bool Guild::SetName(std::string const& name)
1342{
1343 if (m_name == name || name.empty() || name.length() > 24 || sObjectMgr->IsReservedName(name) || !ObjectMgr::IsValidCharterName(name))
1344 return false;
1345
1346 m_name = name;
1347 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_NAME);
1348 stmt->setString(0, m_name);
1349 stmt->setUInt32(1, GetId());
1350 CharacterDatabase.Execute(stmt);
1351
1352 ObjectGuid guid = GetGUID();
1353 WorldPacket data(SMSG_GUILD_RENAMED, name.length() + 8 + 1);
1354 data.WriteGuidMask(guid, 0, 7, 3, 1, 5, 6);
1355 data.WriteBits(name.length(), 7);
1356 data.WriteGuidMask(guid, 2, 4);
1357 data.FlushBits();
1358
1359 data.WriteString(name);
1360 data.WriteGuidBytes(guid, 3, 2, 6, 7, 5, 0, 1, 4);
1361
1362 BroadcastPacket(&data);
1363 return true;
1364}
1365
1366void Guild::HandleRoster(WorldSession* session /*= NULL*/)
1367{
1368 ByteBuffer memberData(100);
1369 // Guess size
1370
1371 WorldPacket data(SMSG_GUILD_ROSTER, 100);
1372
1373 data.WriteBits(m_members.size(), 17);
1374 data.WriteBits(m_motd.length(), 10);
1375
1376 for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
1377 {
1378 Member* member = itr->second;
1379 size_t pubNoteLength = member->GetPublicNote().length();
1380 size_t offNoteLength = member->GetOfficerNote().length();
1381
1382 ObjectGuid guid = member->GetGUID();
1383 data.WriteBits(offNoteLength, 8);
1384 data.WriteBit(guid[5]);
1385 data.WriteBit(0); // Can Scroll of Ressurect
1386 data.WriteBits(pubNoteLength, 8);
1387 data.WriteBit(guid[7]);
1388 data.WriteBit(guid[0]);
1389 data.WriteBit(guid[6]);
1390 data.WriteBits(member->GetName().length(), 6);
1391 data.WriteBit(0); // Has Authenticator
1392 data.WriteBit(guid[3]);
1393 data.WriteBit(guid[4]);
1394 data.WriteBit(guid[1]);
1395 data.WriteBit(guid[2]);
1396
1397 memberData << uint8(member->GetClass());
1398 memberData << uint32(member->GetTotalReputation());
1399 memberData.WriteString(member->GetName());
1400 memberData.WriteByteSeq(guid[0]);
1401
1402 // for (2 professions)
1403 memberData << uint32(0) << uint32(0) << uint32(0);
1404 memberData << uint32(0) << uint32(0) << uint32(0);
1405
1406 memberData << uint8(member->GetLevel());
1407 memberData << uint8(member->GetFlags());
1408 memberData << uint32(member->GetZoneId());
1409 memberData << uint32(sWorld->getIntConfig(WorldIntConfigs::CONFIG_GUILD_WEEKLY_REP_CAP) - member->GetWeekReputation());
1410 memberData.WriteByteSeq(guid[3]);
1411 memberData << uint64(member->GetTotalActivity());
1412 memberData.WriteString(member->GetOfficerNote());
1413 memberData << float(member->IsOnline() ? 0.0f : float(::time(NULL) - member->GetLogoutTime()) / float(DAY));
1414 memberData << uint8(0); // Gender
1415 memberData << uint32(member->GetRankId());
1416 memberData << uint32(member->GetVirtualRealm());
1417 memberData.WriteByteSeq(guid[5]);
1418 memberData.WriteByteSeq(guid[7]);
1419 memberData.WriteString(member->GetPublicNote());
1420 memberData.WriteByteSeq(guid[4]);
1421 memberData << uint64(member->GetWeekActivity());
1422 memberData << uint32(member->GetAchievementPoints());
1423 memberData.WriteByteSeq(guid[6]);
1424 memberData.WriteByteSeq(guid[1]);
1425 memberData.WriteByteSeq(guid[2]);
1426 }
1427
1428 data.WriteBits(m_info.length(), 11);
1429
1430 data.FlushBits();
1431 data.append(memberData);
1432
1433 data << uint32(m_accountsNumber);
1435 data.WriteString(m_info);
1437 data.WriteString(m_motd);
1438 data << uint32(0);
1439
1440 if (session)
1441 {
1442 SF_LOG_DEBUG("guild", "SMSG_GUILD_ROSTER [%s]", session->GetPlayerInfo().c_str());
1443 session->SendPacket(&data);
1444 }
1445 else
1446 {
1447 SF_LOG_DEBUG("guild", "SMSG_GUILD_ROSTER [Broadcast]");
1448 BroadcastPacket(&data);
1449 }
1450}
1451
1453{
1454 ObjectGuid guid = GetGUID();
1455
1456 WorldPacket data(SMSG_GUILD_QUERY_RESPONSE, 8 * 32 + 200); // Guess size
1457
1458 data.WriteBit(guid[5]);
1459 data.WriteBit(1); // HasData
1460
1461 // if (hasData)
1462 {
1463 data.WriteBits(_GetRanksSize(), 21);
1464 data.WriteBit(guid[5]);
1465 data.WriteBit(guid[1]);
1466 data.WriteBit(guid[4]);
1467 data.WriteBit(guid[7]);
1468
1469 for (uint8 i = 0; i < _GetRanksSize(); i++)
1470 data.WriteBits(m_ranks[i].GetName().length(), 7);
1471
1472 data.WriteBit(guid[3]);
1473 data.WriteBit(guid[2]);
1474 data.WriteBit(guid[0]);
1475 data.WriteBit(guid[6]);
1476 data.WriteBits(m_name.length(), 7);
1477 }
1478
1479 data.WriteBit(guid[3]);
1480 data.WriteBit(guid[7]);
1481 data.WriteBit(guid[2]);
1482 data.WriteBit(guid[1]);
1483 data.WriteBit(guid[0]);
1484 data.WriteBit(guid[4]);
1485 data.WriteBit(guid[6]);
1486
1487 data.FlushBits();
1488
1489 //if (hasData)
1490 {
1491 data << uint32(m_emblemInfo.GetBorderStyle());
1492 data << uint32(m_emblemInfo.GetStyle());
1493
1494 data.WriteByteSeq(guid[2]);
1495 data.WriteByteSeq(guid[7]);
1496
1497 data << uint32(m_emblemInfo.GetColor());
1498 data << uint32(realmID);
1499
1500 for (uint8 i = 0; i < _GetRanksSize(); i++)
1501 {
1502 data << uint32(i);
1503 data << uint32(m_ranks[i].GetId());
1504 data.WriteString(m_ranks[i].GetName());
1505 }
1506
1507 data.WriteString(m_name);
1508 data << uint32(m_emblemInfo.GetBorderColor());
1509
1510 data.WriteByteSeq(guid[5]);
1511 data.WriteByteSeq(guid[4]);
1512
1513 data << uint32(m_emblemInfo.GetBackgroundColor());
1514
1515 data.WriteByteSeq(guid[1]);
1516 data.WriteByteSeq(guid[6]);
1517 data.WriteByteSeq(guid[0]);
1518 data.WriteByteSeq(guid[3]);
1519 }
1520
1521 data.WriteByteSeq(guid[2]);
1522 data.WriteByteSeq(guid[6]);
1523 data.WriteByteSeq(guid[4]);
1524 data.WriteByteSeq(guid[0]);
1525 data.WriteByteSeq(guid[7]);
1526 data.WriteByteSeq(guid[3]);
1527 data.WriteByteSeq(guid[5]);
1528 data.WriteByteSeq(guid[1]);
1529
1530 session->SendPacket(&data);
1531 SF_LOG_DEBUG("guild", "SMSG_GUILD_QUERY_RESPONSE [%s]", session->GetPlayerInfo().c_str());
1532}
1533
1535{
1536 WorldPacket data(SMSG_GUILD_RANKS, 100);
1537
1538 data.WriteBits(_GetRanksSize(), 17);
1539
1540 for (uint8 i = 0; i < _GetRanksSize(); i++)
1541 data.WriteBits(m_ranks[i].GetName().length(), 7);
1542
1543 data.FlushBits();
1544
1545 for (uint8 i = 0; i < _GetRanksSize(); i++)
1546 {
1547 RankInfo const* rankInfo = GetRankInfo(i);
1548
1549 data << uint32(i);
1550 data << uint32(rankInfo->GetBankMoneyPerDay());
1551
1552 for (uint8 j = 0; j < GUILD_BANK_MAX_TABS; ++j)
1553 {
1554 data << uint32(rankInfo->GetBankTabSlotsPerDay(j));
1555 data << uint32(rankInfo->GetBankTabRights(j));
1556 }
1557
1558 data.WriteString(rankInfo->GetName());
1559 data << uint32(rankInfo->GetId());
1560 data << uint32(rankInfo->GetRights());
1561 }
1562
1563 session->SendPacket(&data);
1564 SF_LOG_DEBUG("guild", "SMSG_GUILD_RANKS [%s]", session->GetPlayerInfo().c_str());
1565}
1566
1567void Guild::HandleSetMOTD(WorldSession* session, std::string const& motd)
1568{
1569 if (m_motd == motd)
1570 return;
1571
1572 // Player must have rights to set MOTD
1573 if (!_HasRankRight(session->GetPlayer(), GR_RIGHT_SETMOTD))
1575 else
1576 {
1577 m_motd = motd;
1578
1579 sScriptMgr->OnGuildMOTDChanged(this, motd);
1580
1581 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_MOTD);
1582 stmt->setString(0, motd);
1583 stmt->setUInt32(1, m_id);
1584 CharacterDatabase.Execute(stmt);
1585
1586 _BroadcastEvent(GE_MOTD, 0, motd.c_str());
1587 }
1588}
1589
1590void Guild::HandleSetInfo(WorldSession* session, std::string const& info)
1591{
1592 if (m_info == info)
1593 return;
1594
1595 // Player must have rights to set guild's info
1597 {
1598 m_info = info;
1599
1600 sScriptMgr->OnGuildInfoChanged(this, info);
1601
1602 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_INFO);
1603 stmt->setString(0, info);
1604 stmt->setUInt32(1, m_id);
1605 CharacterDatabase.Execute(stmt);
1606 }
1607}
1608
1609void Guild::HandleSetEmblem(WorldSession* session, const EmblemInfo& emblemInfo)
1610{
1611 Player* player = session->GetPlayer();
1612 if (!_IsLeader(player))
1613 SendSaveEmblemResult(session, ERR_GUILDEMBLEM_NOTGUILDMASTER); // "Only guild leaders can create emblems."
1614 else if (!player->HasEnoughMoney(uint64(EMBLEM_PRICE)))
1615 SendSaveEmblemResult(session, ERR_GUILDEMBLEM_NOTENOUGHMONEY); // "You can't afford to do that."
1616 else
1617 {
1618 player->ModifyMoney(-int64(EMBLEM_PRICE));
1619
1620 m_emblemInfo = emblemInfo;
1621 m_emblemInfo.SaveToDB(m_id);
1622
1623 SendSaveEmblemResult(session, ERR_GUILDEMBLEM_SUCCESS); // "Guild Emblem saved."
1624
1625 HandleQuery(session);
1626 }
1627}
1628
1629void Guild::_SendSetNewGuildMaster(Member const* guildMaster, Member const* newGuildMaster, bool replace) const
1630{
1631 ObjectGuid gumGuid = guildMaster->GetGUID();
1632 ObjectGuid newGumGuid = newGuildMaster->GetGUID();
1633
1634 WorldPacket data(SMSG_GUILD_SET_GUILD_MASTER, guildMaster->GetName().size() + newGuildMaster->GetName().size() + 2 * 8);
1635 data.WriteGuidMask(newGumGuid, 4, 2, 7);
1636 data.WriteBit(gumGuid[4]);
1637 data.WriteBits(guildMaster->GetName().size(), 6);
1638 data.WriteBit(gumGuid[0]);
1639 data.WriteGuidMask(newGumGuid, 6, 3);
1640 data.WriteBit(replace);
1641 data.WriteGuidMask(newGumGuid, 1, 0);
1642 data.WriteGuidMask(gumGuid, 1, 7, 3, 6, 2);
1643 data.WriteBits(newGuildMaster->GetName().size(), 6);
1644 data.WriteBit(gumGuid[5]);
1645 data.WriteBit(newGumGuid[5]);
1646 data.FlushBits();
1647
1648 data.WriteGuidBytes(newGumGuid, 5, 6);
1649 data.WriteString(guildMaster->GetName());
1650 data.WriteString(newGuildMaster->GetName());
1651 data.WriteGuidBytes(newGumGuid, 3, 4);
1652 data << (int32)realmID;
1653 data.WriteByteSeq(gumGuid[6]);
1654 data.WriteByteSeq(newGumGuid[0]);
1655 data.WriteByteSeq(gumGuid[5]);
1656 data.WriteGuidBytes(newGumGuid, 2, 7);
1657 data.WriteGuidBytes(gumGuid, 7, 4);
1658 data << (int32)realmID;
1659 data.WriteByteSeq(newGumGuid[1]);
1660 data.WriteGuidBytes(gumGuid, 2, 1, 3, 0);
1661
1662 BroadcastPacket(&data);
1663}
1664
1665void Guild::_SendRemovePlayerFromGuild(ObjectGuid removedGuid, std::string const& removedName, Player const* remover) const
1666{
1667 ObjectGuid removerGuid = remover ? remover->GetGUID() : 0;
1668 WorldPacket data(SMSG_GUILD_EVENT_PLAYER_LEFT, 8 + 4 + 1 + 1 + removedName.length() + (remover ? (8 + 4 + 1 + 1 + remover->GetName().length()) : 0));
1669 data.WriteGuidMask(removedGuid, 2);
1670 data.WriteBits(removedName.length(), 6);
1671 data.WriteGuidMask(removedGuid, 6, 5);
1672 data.WriteBit(remover != nullptr);
1673
1674 if (remover)
1675 {
1676 data.WriteBit(0); // Remover name denoted
1677 data.WriteBit(0); // Fake bit
1678 data.WriteBits(remover->GetName().length(), 6);
1679
1680 data.WriteGuidMask(removerGuid, 1, 3, 4, 2, 5, 7, 6, 0);
1681 data.WriteBit(0);
1682 }
1683
1684 data.WriteGuidMask(removedGuid, 1, 0, 3, 4, 7);
1685 data.FlushBits();
1686
1687 if (remover)
1688 {
1689 data.WriteGuidBytes(removerGuid, 1, 3, 5, 2, 0, 4, 6, 7);
1690 data.WriteString(remover->GetName());
1691 data << (int32)0;
1692 }
1693
1694 data.WriteString(removedName);
1695 data.WriteGuidBytes(removedGuid, 1);
1696 data << (int32)0;
1697 data.WriteGuidBytes(removedGuid, 0, 4, 2, 3, 6, 5, 7);
1698
1699 BroadcastPacket(&data);
1700}
1701
1702
1703void Guild::HandleSetNewGuildMaster(WorldSession* session, std::string const& name)
1704{
1705 Player* player = session->GetPlayer();
1706 // Only the guild master can throne a new guild master
1707 if (!_IsLeader(player))
1709 // Old GM must be a guild member
1710 else if (Member* oldGuildMaster = GetMember(player->GetGUID()))
1711 {
1712 // Same for the new one
1713 if (Member* newGuildMaster = GetMember(name))
1714 {
1715 _SetLeaderGUID(newGuildMaster);
1716 oldGuildMaster->ChangeRank(GR_INITIATE);
1717 _BroadcastEvent(GE_LEADER_CHANGED, 0, player->GetName().c_str(), name.c_str());
1718 }
1719 }
1720}
1721
1723{
1724 Player* player = session->GetPlayer();
1725
1726 if (Member* newGuildMaster = GetMember(player->GetGUID()))
1727 {
1728 if (newGuildMaster->GetRankId() > GR_MEMBER) // 3 ranks down from gum is the requirements
1729 {
1731 return;
1732 }
1733
1734 if (Member* oldGuildMaster = GetMember(m_leaderGuid))
1735 {
1736 if (oldGuildMaster->GetLogoutTime() > uint64(time(NULL) - (DAY * 90)))
1737 {
1739 return;
1740 }
1741
1742 _SetLeaderGUID(newGuildMaster);
1743 oldGuildMaster->ChangeRank(_GetLowestRankId());
1744 _SendSetNewGuildMaster(oldGuildMaster, newGuildMaster, true);
1745 }
1746 }
1747}
1748
1749void Guild::HandleSetBankTabInfo(WorldSession* session, uint8 tabId, std::string const& name, std::string const& icon)
1750{
1751 BankTab* tab = GetBankTab(tabId);
1752 if (!tab)
1753 {
1754 SF_LOG_ERROR("guild", "Guild::HandleSetBankTabInfo: Player %s trying to change bank tab info from unexisting tab %d.",
1755 session->GetPlayerInfo().c_str(), tabId);
1756 return;
1757 }
1758
1760 {
1761 SF_LOG_ERROR("guild", "Guild::HandleSetBankTabInfo: Player %s is trying to modify bank tab info but doesn't have permission!",
1762 session->GetPlayerInfo().c_str());
1763 return;
1764 }
1765
1766 tab->SetInfo(name, icon);
1767
1768 WorldPacket data(SMSG_GUILD_EVENT_BANK_TAB_MODIFIED, 2 + 4 + name.size() + icon.size());
1769 data.WriteBits(icon.size(), 9);
1770 data.WriteBits(name.size(), 7);
1771 data.FlushBits();
1772
1773 data.WriteString(name);
1774 data << uint32(tabId);
1775 data.WriteString(icon);
1776
1777 BroadcastPacket(&data);
1778}
1779
1780void Guild::HandleSetMemberNote(WorldSession* session, std::string const& note, uint64 guid, bool isPublic)
1781{
1782 // Player must have rights to set public/officer note
1783 if (session && !_HasRankRight(session->GetPlayer(), isPublic ? GR_RIGHT_EPNOTE : GR_RIGHT_EOFFNOTE))
1784 {
1786 }
1787 else if (Member* member = GetMember(guid))
1788 {
1789 if (isPublic)
1790 member->SetPublicNote(note);
1791 else
1792 member->SetOfficerNote(note);
1793
1794 ObjectGuid memberGuid = member->GetGUID();
1795
1796 WorldPacket data(SMSG_GUILD_MEMBER_UPDATE_NOTE, 1 + 1 + 1 + 8 + note.length());
1797
1798 data.WriteBit(memberGuid[2]);
1799 data.WriteBits(note.length(), 8);
1800 data.WriteBit(isPublic);
1801 data.WriteBit(memberGuid[5]);
1802 data.WriteBit(memberGuid[0]);
1803 data.WriteBit(memberGuid[4]);
1804 data.WriteBit(memberGuid[3]);
1805 data.WriteBit(memberGuid[1]);
1806 data.WriteBit(memberGuid[6]);
1807 data.WriteBit(memberGuid[7]);
1808 data.FlushBits();
1809
1810 data.WriteByteSeq(memberGuid[7]);
1811 data.WriteByteSeq(memberGuid[5]);
1812 data.WriteByteSeq(memberGuid[0]);
1813 data.WriteByteSeq(memberGuid[1]);
1814 data.WriteString(note);
1815 data.WriteByteSeq(memberGuid[3]);
1816 data.WriteByteSeq(memberGuid[6]);
1817 data.WriteByteSeq(memberGuid[4]);
1818 data.WriteByteSeq(memberGuid[2]);
1819
1820 if (session)
1821 {
1822 SF_LOG_DEBUG("guild", "SMSG_GUILD_MEMBER_UPDATE_NOTE [%s]", session->GetPlayerInfo().c_str());
1823 session->SendPacket(&data);
1824 }
1825 else
1826 {
1827 SF_LOG_DEBUG("guild", "SMSG_GUILD_MEMBER_UPDATE_NOTE [Broadcast]");
1828 BroadcastPacket(&data);
1829 }
1830 }
1831}
1832
1833void Guild::HandleSetRankInfo(WorldSession* session, uint8 rankId, std::string const& name, uint32 rights, uint32 moneyPerDay, const GuildBankRightsAndSlotsVec& rightsAndSlots)
1834{
1835 // Only leader can modify ranks
1836 if (!_IsLeader(session->GetPlayer()))
1838 else if (RankInfo* rankInfo = GetRankInfo(rankId))
1839 {
1840 SF_LOG_DEBUG("guild", "Changed RankName to '%s', rights to 0x%08X", name.c_str(), rights);
1841
1842 rankInfo->SetName(name);
1843 rankInfo->SetRights(rights);
1844 _SetRankBankMoneyPerDay(rankId, moneyPerDay);
1845
1846 for (GuildBankRightsAndSlotsVec::const_iterator itr = rightsAndSlots.begin(); itr != rightsAndSlots.end(); ++itr)
1847 _SetRankBankTabRightsAndSlots(rankId, *itr);
1848
1849 char aux[4];
1850 snprintf(aux, sizeof(aux), "%u", rankId);
1852 }
1853}
1854
1856{
1857 Player* player = session->GetPlayer();
1858 if (!player)
1859 return;
1860
1861 Member const* member = GetMember(player->GetGUID());
1862 if (!member)
1863 return;
1864
1866 return;
1867
1868 if (tabId != _GetPurchasedTabsSize())
1869 return;
1870
1871 // Do not get money for bank tabs that the GM bought, we had to buy them already.
1872 // This is just a speedup check, GetGuildBankTabPrice will return 0.
1873 if (tabId < GUILD_BANK_MAX_TABS - 2) // 7th tab is actually the 6th
1874 {
1875 uint32 tabCost = _GetGuildBankTabPrice(tabId) * GOLD;
1876 if (!tabCost)
1877 return;
1878
1879 if (!player->HasEnoughMoney(uint64(tabCost))) // Should not happen, this is checked by client
1880 return;
1881
1882 player->ModifyMoney(-int64(tabCost));
1883 }
1884
1886
1888 BroadcastPacket(&data);
1889
1890 SendPermissions(session);
1891}
1892
1893void Guild::HandleInviteMember(WorldSession* session, std::string const& name)
1894{
1895 Player* pInvitee = sObjectAccessor->FindPlayerByName(name);
1896 if (!pInvitee)
1897 {
1899 return;
1900 }
1901
1902 Player* player = session->GetPlayer();
1903 // Do not show invitations from ignored players
1904 if (pInvitee->GetSocial()->HasIgnore(player->GetGUIDLow()))
1905 return;
1906
1907 if (!sWorld->GetBoolConfig(WorldBoolConfigs::CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && pInvitee->GetTeam() != player->GetTeam())
1908 {
1910 return;
1911 }
1912
1913 // Invited player cannot be in another guild
1914 if (pInvitee->GetGuildId())
1915 {
1917 return;
1918 }
1919
1920 // Invited player cannot be invited
1921 if (pInvitee->GetGuildIdInvited())
1922 {
1924 return;
1925 }
1926
1927 // Inviting player must have rights to invite
1928 if (!_HasRankRight(player, GR_RIGHT_INVITE))
1929 {
1931 return;
1932 }
1933
1935
1936 SF_LOG_DEBUG("guild", "Player %s invited %s to join his Guild", player->GetName().c_str(), name.c_str());
1937
1938 // Auto decline invite
1940 {
1941 player->SendDeclineGuildInvitation(pInvitee->GetName(), true);
1942 return;
1943 }
1944
1945 pInvitee->SetGuildIdInvited(m_id);
1946 pInvitee->SetLastGuildInviterGUID(player->GetGUID());
1947
1949
1950 ObjectGuid oldGuildGuid = MAKE_NEW_GUID(pInvitee->GetGuildId(), 0, pInvitee->GetGuildId() ? uint32(HIGHGUID_GUILD) : 0);
1951 ObjectGuid newGuildGuid = GetGUID();
1952
1953 WorldPacket data(SMSG_GUILD_INVITE, 100);
1954 data.WriteBit(newGuildGuid[4]);
1955 data.WriteBits(m_name.length(), 7);
1956 data.WriteBit(oldGuildGuid[4]);
1957 data.WriteBit(newGuildGuid[6]);
1958 data.WriteBit(oldGuildGuid[2]);
1959 data.WriteBit(oldGuildGuid[1]);
1960 data.WriteBit(oldGuildGuid[5]);
1961 data.WriteBit(oldGuildGuid[7]);
1962 data.WriteBit(newGuildGuid[0]);
1963 data.WriteBit(oldGuildGuid[3]);
1964 data.WriteBit(newGuildGuid[5]);
1965 data.WriteBit(oldGuildGuid[6]);
1966 data.WriteBits(player->GetName().length(), 6);
1967 data.WriteBit(newGuildGuid[1]);
1968 data.WriteBit(newGuildGuid[3]);
1969 data.WriteBit(oldGuildGuid[0]);
1970 data.WriteBit(newGuildGuid[7]);
1971 data.WriteBits(pInvitee->GetGuildName().length(), 7);
1972 data.WriteBit(newGuildGuid[2]);
1973
1974 data.FlushBits();
1975
1976 data.WriteByteSeq(newGuildGuid[1]);
1977 data << uint32(m_emblemInfo.GetBackgroundColor());
1978 data.WriteByteSeq(newGuildGuid[4]);
1979 data.WriteString(player->GetName());
1980 data << uint32(m_emblemInfo.GetBorderStyle());
1981 data.WriteByteSeq(oldGuildGuid[7]);
1982 data.WriteByteSeq(newGuildGuid[0]);
1983 data.WriteByteSeq(newGuildGuid[2]);
1984 data << uint32(m_emblemInfo.GetColor());
1985 data.WriteByteSeq(oldGuildGuid[2]);
1986 data.WriteByteSeq(oldGuildGuid[5]);
1987 data << uint32(GetLevel());
1988 data << uint32(pInvitee->GetGuildId() ? realmID : 0);
1989 data.WriteByteSeq(newGuildGuid[7]);
1990 data.WriteByteSeq(newGuildGuid[3]);
1991 data.WriteByteSeq(oldGuildGuid[4]);
1992 data << uint32(m_emblemInfo.GetBorderColor());
1993 data.WriteString(m_name);
1994 data << uint32(realmID);
1995 data << uint32(m_emblemInfo.GetStyle());
1996 data.WriteByteSeq(oldGuildGuid[0]);
1997 data.WriteString(pInvitee->GetGuildName());
1998 data.WriteByteSeq(newGuildGuid[5]);
1999 data << uint32(realmID);
2000 data.WriteByteSeq(oldGuildGuid[1]);
2001 data.WriteByteSeq(newGuildGuid[6]);
2002 data.WriteByteSeq(oldGuildGuid[3]);
2003 data.WriteByteSeq(oldGuildGuid[6]);
2004
2005 pInvitee->GetSession()->SendPacket(&data);
2006 SF_LOG_DEBUG("guild", "SMSG_GUILD_INVITE [%s]", pInvitee->GetName().c_str());
2007}
2008
2010{
2011 Player* player = session->GetPlayer();
2013 player->GetTeam() != sObjectMgr->GetPlayerTeamByGUID(GetLeaderGUID()))
2014 return;
2015
2016 AddMember(player->GetGUID());
2017}
2018
2020{
2021 Player* player = session->GetPlayer();
2022 bool disband = false;
2023
2024 // If leader is leaving
2025 if (_IsLeader(player))
2026 {
2027 if (m_members.size() > 1)
2028 // Leader cannot leave if he is not the last member
2032 else
2033 {
2034 // Guild is disbanded if leader leaves.
2035 Disband();
2036 disband = true;
2037 }
2038 }
2039 else
2040 {
2041 _SendRemovePlayerFromGuild(player->GetGUID(), player->GetName(), nullptr);
2042 DeleteMember(player->GetGUID(), false, false);
2043
2045 }
2046
2047 sCalendarMgr->RemovePlayerGuildEventsAndSignups(player->GetGUID(), GetId());
2048
2049 if (disband)
2050 delete this;
2051}
2052
2054{
2055 Player* player = session->GetPlayer();
2056
2057 // Player must have rights to remove members
2058 if (!_HasRankRight(player, GR_RIGHT_REMOVE))
2060 else if (Member* member = GetMember(guid))
2061 {
2062 // Guild masters cannot be removed
2063 if (member->IsRank(GR_GUILDMASTER))
2065 // Do not allow to remove player with the same rank or higher
2066 else
2067 {
2068 std::string name = member->GetName();
2069 Member const* memberMe = GetMember(player->GetGUID());
2070
2071 if (!memberMe || member->IsRankNotLower(memberMe->GetRankId()))
2073 else
2074 {
2075 _SendRemovePlayerFromGuild(guid, name, player);
2076 // After call to DeleteMember pointer to member becomes invalid
2077 DeleteMember(guid, false, true);
2079 }
2080 }
2081 }
2082}
2083
2084void Guild::HandleUpdateMemberRank(WorldSession* session, uint64 guid, bool demote)
2085{
2086 Player* player = session->GetPlayer();
2088 // Player must have rights to promote
2089 if (!_HasRankRight(player, demote ? GR_RIGHT_DEMOTE : GR_RIGHT_PROMOTE))
2091 // Promoted player must be a member of guild
2092 else if (Member* member = GetMember(guid))
2093 {
2094 std::string name = member->GetName();
2095 // Player cannot promote himself
2096 if (member->IsSamePlayer(player->GetGUID()))
2097 {
2099 return;
2100 }
2101
2102 Member const* memberMe = GetMember(player->GetGUID());
2103 uint8 rankId = memberMe->GetRankId();
2104 if (demote)
2105 {
2106 // Player can demote only lower rank members
2107 if (member->IsRankNotLower(rankId))
2108 {
2109 SendCommandResult(session, type, ERR_GUILD_RANK_TOO_HIGH_S, name);
2110 return;
2111 }
2112 // Lowest rank cannot be demoted
2113 if (member->GetRankId() >= _GetLowestRankId())
2114 {
2115 SendCommandResult(session, type, ERR_GUILD_RANK_TOO_LOW_S, name);
2116 return;
2117 }
2118 }
2119 else
2120 {
2121 // Allow to promote only to lower rank than member's rank
2122 // member->GetRankId() + 1 is the highest rank that current player can promote to
2123 if (member->IsRankNotLower(rankId + 1))
2124 {
2125 SendCommandResult(session, type, ERR_GUILD_RANK_TOO_HIGH_S, name);
2126 return;
2127 }
2128 }
2129
2130 uint32 newRankId = member->GetRankId() + (demote ? 1 : -1);
2131 member->ChangeRank(newRankId);
2132 _LogEvent(demote ? GUILD_EVENT_LOG_DEMOTE_PLAYER : GUILD_EVENT_LOG_PROMOTE_PLAYER, player->GetGUIDLow(), GUID_LOPART(member->GetGUID()), newRankId);
2133 _BroadcastEvent(demote ? GE_DEMOTION : GE_PROMOTION, 0, player->GetName().c_str(), name.c_str(), _GetRankName(newRankId).c_str());
2134 }
2135}
2136
2137void Guild::HandleSetMemberRank(WorldSession* session, uint64 targetGuid, uint64 setterGuid, uint32 rank)
2138{
2139 Player* player = session->GetPlayer();
2140 Member* member = GetMember(targetGuid);
2143
2144 if (!IsMember(targetGuid))
2145 return;
2146
2147 if (rank > member->GetRankId())
2148 {
2149 rights = GR_RIGHT_DEMOTE;
2150 type = GUILD_COMMAND_DEMOTE;
2151 }
2152
2153 // Promoted player must be a member of guild
2154 if (!_HasRankRight(player, rights))
2155 {
2157 return;
2158 }
2159
2160 // Player cannot promote himself
2161 if (member->IsSamePlayer(player->GetGUID()))
2162 {
2164 return;
2165 }
2166
2167 SendGuildRanksUpdate(setterGuid, targetGuid, rank);
2168}
2169
2170void Guild::HandleAddNewRank(WorldSession* session, std::string const& name)
2171{
2172 uint8 size = _GetRanksSize();
2173 if (size >= GUILD_RANKS_MAX_COUNT)
2174 return;
2175
2176 // Only leader can add new rank
2177 if (_IsLeader(session->GetPlayer()))
2180}
2181
2183{
2184 // Cannot remove rank if total count is minimum allowed by the client or is not leader
2185 if (_GetRanksSize() <= GUILD_RANKS_MIN_COUNT || rankId >= _GetRanksSize() || !_IsLeader(session->GetPlayer()))
2186 return;
2187
2188 // Delete bank rights for rank
2190 stmt->setUInt32(0, m_id);
2191 stmt->setUInt8(1, rankId);
2192 CharacterDatabase.Execute(stmt);
2193 // Delete rank
2194 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_RANK);
2195 stmt->setUInt32(0, m_id);
2196 stmt->setUInt8(1, rankId);
2197 CharacterDatabase.Execute(stmt);
2198
2199 m_ranks.erase(m_ranks.begin() + rankId);
2200
2202}
2203
2204void Guild::HandleMemberDepositMoney(WorldSession* session, uint64 amount, bool cashFlow /*=false*/)
2205{
2206 Player* player = session->GetPlayer();
2207
2208 // Call script after validation and before money transfer.
2209 sScriptMgr->OnGuildMemberDepositMoney(this, player, amount);
2210
2211 SQLTransaction trans = CharacterDatabase.BeginTransaction();
2212 _ModifyBankMoney(trans, amount, true);
2213 if (!cashFlow)
2214 {
2215 player->ModifyMoney(-int64(amount));
2216 player->SaveGoldToDB(trans);
2217 }
2218
2220 CharacterDatabase.CommitTransaction(trans);
2221
2223 data << m_bankMoney;
2224 BroadcastPacket(&data);
2225
2227 {
2228 sLog->outCommand(player->GetSession()->GetAccountId(),
2229 "GM %s (Account: %u) deposit money (Amount: " UI64FMTD ") to guild bank (Guild ID %u)",
2230 player->GetName().c_str(), player->GetSession()->GetAccountId(), amount, m_id);
2231 }
2232}
2233
2234bool Guild::HandleMemberWithdrawMoney(WorldSession* session, uint64 amount, bool repair)
2235{
2236 // clamp amount to MAX_MONEY_AMOUNT, Players can't hold more than that anyway
2237 amount = std::min(amount, uint64(MAX_MONEY_AMOUNT));
2238
2239 if (m_bankMoney < amount) // Not enough money in bank
2240 return false;
2241
2242 Player* player = session->GetPlayer();
2243
2244 Member* member = GetMember(player->GetGUID());
2245 if (!member)
2246 return false;
2247
2248 if (uint64(_GetMemberRemainingMoney(member)) < amount) // Check if we have enough slot/money today
2249 return false;
2250
2251 // Call script after validation and before money transfer.
2252 sScriptMgr->OnGuildMemberWitdrawMoney(this, player, amount, repair);
2253
2254 SQLTransaction trans = CharacterDatabase.BeginTransaction();
2255 // Add money to player (if required)
2256 if (!repair)
2257 {
2258 if (!player->ModifyMoney(amount))
2259 return false;
2260
2261 player->SaveGoldToDB(trans);
2262 }
2263
2264 // Update remaining money amount
2265 member->UpdateBankWithdrawValue(trans, GUILD_BANK_MAX_TABS, amount);
2266 // Remove money from bank
2267 _ModifyBankMoney(trans, amount, false);
2268
2269 // Log guild bank event
2271 CharacterDatabase.CommitTransaction(trans);
2272
2274 data << m_bankMoney;
2275 BroadcastPacket(&data);
2276
2277 return true;
2278}
2279
2281{
2282 Player* player = session->GetPlayer();
2283 if (Member* member = GetMember(player->GetGUID()))
2284 {
2285 member->SetStats(player);
2286 member->UpdateLogoutTime();
2287 member->ResetFlags();
2288 }
2289 _BroadcastEvent(GE_SIGNED_OFF, player->GetGUID(), player->GetName().c_str());
2290
2291 SaveToDB();
2292}
2293
2295{
2296 // Only leader can disband guild
2297 if (_IsLeader(session->GetPlayer()))
2298 {
2299 Disband();
2300 SF_LOG_DEBUG("guild", "Guild Successfully Disbanded");
2301 delete this;
2302 }
2303}
2304
2306{
2307 Player* player = session->GetPlayer();
2308 Group* group = player->GetGroup();
2309
2310 // Make sure player is a member of the guild and that he is in a group.
2311 if (!IsMember(player->GetGUID()) || !group)
2312 return;
2313
2315
2316 data << uint32(0); // Needed guild members
2317 data << float(0.f); // Guild XP multiplier
2318 data << uint32(0); // Current guild members
2319 data.WriteBit(player->GetMap()->GetOwnerGuildId(player->GetTeam()) == GetId()); // Is guild group
2320
2321 session->SendPacket(&data);
2322 SF_LOG_DEBUG("guild", "SMSG_GUILD_PARTY_STATE_RESPONSE [%s]", session->GetPlayerInfo().c_str());
2323}
2324
2326{
2327 WorldPacket data(SMSG_GUILD_EVENT_LOG_QUERY_RESULT, 3 + m_eventLog->GetSize() * (1 + 9 + 9 + 4 + 4));
2328 m_eventLog->WritePacket(data);
2329 session->SendPacket(&data);
2330 SF_LOG_DEBUG("guild", "SMSG_GUILD_EVENT_LOG_QUERY_RESULT [%s]", session->GetPlayerInfo().c_str());
2331}
2332
2334{
2335 uint32 size = m_newsLog->GetSize();
2336 GuildLog* logs = m_newsLog->GetGuildLog();
2337
2338 if (!logs)
2339 return;
2340
2341 WorldPacket data(SMSG_GUILD_NEWS_UPDATE, (21 + size * (26 + 8)) / 8 + (8 + 6 * 4) * size);
2342 data.WriteBits(size, 19);
2343
2344 for (GuildLog::const_iterator itr = logs->begin(); itr != logs->end(); ++itr)
2345 {
2346 ObjectGuid guid = ((NewsLogEntry*)(*itr))->GetPlayerGuid();
2347
2348 data.WriteBit(guid[3]);
2349 data.WriteBits(0, 24); // Not yet implemented used for guild achievements
2350 data.WriteBit(guid[4]);
2351 data.WriteBit(guid[5]);
2352 data.WriteBit(guid[6]);
2353 data.WriteBit(guid[0]);
2354 data.WriteBit(guid[7]);
2355 data.WriteBit(guid[2]);
2356 data.WriteBit(guid[1]);
2357 }
2358
2359 data.FlushBits();
2360
2361 for (GuildLog::const_iterator itr = logs->begin(); itr != logs->end(); ++itr)
2362 {
2363 NewsLogEntry* news = (NewsLogEntry*)(*itr);
2364 ObjectGuid guid = news->GetPlayerGuid();
2365
2366 data.WriteByteSeq(guid[2]);
2367 data << uint32(news->GetValue());
2368 data.WriteByteSeq(guid[1]);
2369 data.WriteByteSeq(guid[7]);
2370 data.WriteByteSeq(guid[4]);
2371 data.WriteByteSeq(guid[3]);
2372 data.WriteByteSeq(guid[5]);
2373 data << uint32(0);
2374 data << uint32(news->GetType());
2375 data << uint32(news->GetFlags()); // 1 sticky
2376 data.WriteByteSeq(guid[6]);
2377 data.AppendPackedTime(news->GetTimestamp());
2378 data << uint32(news->GetGUID());
2379 data.WriteByteSeq(guid[0]);
2380 }
2381
2382 session->SendPacket(&data);
2383 SF_LOG_DEBUG("guild", "SMSG_GUILD_NEWS_UPDATE [%s]", session->GetPlayerInfo().c_str());
2384}
2385
2386void Guild::SendBankLog(WorldSession* session, uint8 tabId) const
2387{
2388 // GUILD_BANK_MAX_TABS send by client for money log
2389 if (tabId < _GetPurchasedTabsSize() || tabId == GUILD_BANK_MAX_TABS)
2390 {
2391 LogHolder const* log = m_bankEventLog[tabId];
2392 WorldPacket data(SMSG_GUILD_BANK_LOG_QUERY_RESULT, log->GetSize() * (4 * 4 + 1) + 1 + 1);
2393 data << uint32(tabId);
2394 data.WriteBit(GetLevel() >= 5 && tabId == GUILD_BANK_MAX_TABS); // has Cash Flow perk
2395 log->WritePacket(data);
2396 if (GetLevel() >= 5 && tabId == GUILD_BANK_MAX_TABS)
2397 data << uint64(0);
2398 session->SendPacket(&data);
2399 SF_LOG_DEBUG("guild", "SMSG_GUILD_BANK_LOG_QUERY_RESULT [%s] TabId: %u", session->GetPlayerInfo().c_str(), tabId);
2400 }
2401}
2402
2403void Guild::SendBankTabText(WorldSession* session, uint8 tabId) const
2404{
2405 if (BankTab const* tab = GetBankTab(tabId))
2406 tab->SendText(this, session);
2407}
2408
2410{
2411 Member const* member = GetMember(session->GetPlayer()->GetGUID());
2412 if (!member)
2413 return;
2414
2415 uint8 rankId = member->GetRankId();
2416
2418 data << uint32(rankId);
2419 data << uint32(_GetRankBankMoneyPerDay(rankId));
2420 data << uint32(_GetPurchasedTabsSize());
2421 data << uint32(_GetRankRights(rankId));
2422
2424 data.FlushBits();
2425
2426 for (uint8 tabId = 0; tabId < GUILD_BANK_MAX_TABS; ++tabId)
2427 {
2428 data << uint32(_GetMemberRemainingSlots(member, tabId));
2429 data << uint32(_GetRankBankTabRights(rankId, tabId));
2430 }
2431
2432 session->SendPacket(&data);
2433 SF_LOG_DEBUG("guild", "SMSG_GUILD_PERMISSIONS_QUERY_RESULTS [%s] Rank: %u", session->GetPlayerInfo().c_str(), rankId);
2434}
2435
2437{
2438 Member const* member = GetMember(session->GetPlayer()->GetGUID());
2439 if (!member)
2440 return;
2441
2442 int32 amount = _GetMemberRemainingMoney(member);
2444 data << int64(amount);
2445 session->SendPacket(&data);
2446 SF_LOG_DEBUG("guild", "SMSG_GUILD_BANK_MONEY_WITHDRAWN [%s] Money: %u", session->GetPlayerInfo().c_str(), amount);
2447}
2448
2450{
2451 Player* player = session->GetPlayer();
2452 Member* member = GetMember(player->GetGUID());
2453 if (!member)
2454 return;
2455
2456 /*
2457 Login sequence:
2458 SMSG_GUILD_EVENT - GE_MOTD
2459 SMSG_GUILD_RANKS
2460 SMSG_GUILD_EVENT - GE_SIGNED_ON
2461 -- learn perks
2462 SMSG_GUILD_REPUTATION_WEEKLY_CAP
2463 SMSG_GUILD_ACHIEVEMENT_DATA
2464 SMSG_GUILD_MEMBER_DAILY_RESET // bank withdrawal reset
2465 */
2466
2467 WorldPacket data(SMSG_GUILD_EVENT, 1 + 1 + m_motd.size() + 1);
2468 data << uint8(GE_MOTD);
2469 data << uint8(1);
2470 data << m_motd;
2471 session->SendPacket(&data);
2472
2473 SF_LOG_DEBUG("guild", "SMSG_GUILD_EVENT [%s] MOTD", session->GetPlayerInfo().c_str());
2474
2475 SendGuildRankInfo(session);
2476 _BroadcastEvent(GE_SIGNED_ON, player->GetGUID(), player->GetName().c_str());
2477
2478 // Send to self separately, player is not in world yet and is not found by _BroadcastEvent
2479 data.Initialize(SMSG_GUILD_EVENT, 1 + 1 + player->GetName().size() + 8);
2480 data << uint8(GE_SIGNED_ON);
2481 data << uint8(1);
2482 data << player->GetName();
2483 data << uint64(player->GetGUID());
2484 session->SendPacket(&data);
2485
2486 data.Initialize(SMSG_GUILD_MEMBER_DAILY_RESET, 0); // tells the client to request bank withdrawal limit
2487 session->SendPacket(&data);
2488
2490 return;
2491
2492 for (uint32 i = 0; i < sGuildPerkSpellsStore.GetNumRows(); ++i)
2493 if (GuildPerkSpellsEntry const* entry = sGuildPerkSpellsStore.LookupEntry(i))
2494 if (entry->Level <= GetLevel())
2495 player->learnSpell(entry->SpellId, true);
2496
2498
2499 m_achievementMgr.SendAllAchievementData(player);
2500
2501 member->SetStats(player);
2503}
2504
2505// Loading methods
2507{
2508 m_id = fields[0].GetUInt32();
2509 m_name = fields[1].GetString();
2510 m_leaderGuid = MAKE_NEW_GUID(fields[2].GetUInt32(), 0, HIGHGUID_PLAYER);
2511 m_emblemInfo.LoadFromDB(fields);
2512 m_info = fields[8].GetString();
2513 m_motd = fields[9].GetString();
2514 m_createdDate = time_t(fields[10].GetUInt32());
2515 m_bankMoney = fields[11].GetUInt64();
2516 _level = fields[12].GetUInt32();
2517 _experience = fields[13].GetUInt64();
2518 _todayExperience = fields[14].GetUInt64();
2519
2520 uint8 purchasedTabs = uint8(fields[15].GetUInt64());
2521 if (purchasedTabs > GUILD_BANK_MAX_TABS)
2522 purchasedTabs = GUILD_BANK_MAX_TABS;
2523
2524 m_bankTabs.resize(purchasedTabs);
2525 for (uint8 i = 0; i < purchasedTabs; ++i)
2526 m_bankTabs[i] = new BankTab(m_id, i);
2527
2529 return true;
2530}
2531
2533{
2534 RankInfo rankInfo(m_id);
2535
2536 rankInfo.LoadFromDB(fields);
2537
2538 m_ranks.push_back(rankInfo);
2539}
2540
2542{
2543 uint32 lowguid = fields[1].GetUInt32();
2544 Member* member = new Member(m_id, MAKE_NEW_GUID(lowguid, 0, HIGHGUID_PLAYER), fields[2].GetUInt8());
2545 if (!member->LoadFromDB(fields))
2546 {
2547 _DeleteMemberFromDB(lowguid);
2548 delete member;
2549 return false;
2550 }
2551 m_members[lowguid] = member;
2552 return true;
2553}
2554
2556{
2557 // tabId rights slots
2558 GuildBankRightsAndSlots rightsAndSlots(fields[1].GetUInt8(), fields[3].GetUInt8(), fields[4].GetUInt32());
2559 // rankId
2560 _SetRankBankTabRightsAndSlots(fields[2].GetUInt8(), rightsAndSlots, false);
2561}
2562
2564{
2565 if (m_eventLog->CanInsert())
2566 {
2567 m_eventLog->LoadEvent(new EventLogEntry(
2568 m_id, // guild id
2569 fields[1].GetUInt32(), // guid
2570 time_t(fields[6].GetUInt32()), // timestamp
2571 GuildEventLogTypes(fields[2].GetUInt8()), // event type
2572 fields[3].GetUInt32(), // player guid 1
2573 fields[4].GetUInt32(), // player guid 2
2574 fields[5].GetUInt8())); // rank
2575 return true;
2576 }
2577 return false;
2578}
2579
2581{
2582 uint8 dbTabId = fields[1].GetUInt8();
2583 bool isMoneyTab = (dbTabId == GUILD_BANK_MONEY_LOGS_TAB);
2584 if (dbTabId < _GetPurchasedTabsSize() || isMoneyTab)
2585 {
2586 uint8 tabId = isMoneyTab ? uint8(GUILD_BANK_MAX_TABS) : dbTabId;
2587 LogHolder* pLog = m_bankEventLog[tabId];
2588 if (pLog->CanInsert())
2589 {
2590 uint32 guid = fields[2].GetUInt32();
2591 GuildBankEventLogTypes eventType = GuildBankEventLogTypes(fields[3].GetUInt8());
2592 if (BankEventLogEntry::IsMoneyEvent(eventType))
2593 {
2594 if (!isMoneyTab)
2595 {
2596 SF_LOG_ERROR("guild", "GuildBankEventLog ERROR: MoneyEvent(LogGuid: %u, Guild: %u) does not belong to money tab (%u), ignoring...", guid, m_id, dbTabId);
2597 return false;
2598 }
2599 }
2600 else if (isMoneyTab)
2601 {
2602 SF_LOG_ERROR("guild", "GuildBankEventLog ERROR: non-money event (LogGuid: %u, Guild: %u) belongs to money tab, ignoring...", guid, m_id);
2603 return false;
2604 }
2605 pLog->LoadEvent(new BankEventLogEntry(
2606 m_id, // guild id
2607 guid, // guid
2608 time_t(fields[8].GetUInt32()), // timestamp
2609 dbTabId, // tab id
2610 eventType, // event type
2611 fields[4].GetUInt32(), // player guid
2612 fields[5].GetUInt32(), // item or money
2613 fields[6].GetUInt16(), // itam stack count
2614 fields[7].GetUInt8())); // dest tab id
2615 }
2616 }
2617 return true;
2618}
2619
2621{
2622 if (!m_newsLog->CanInsert())
2623 return;
2624
2625 m_newsLog->LoadEvent(new NewsLogEntry(
2626 m_id, // guild id
2627 fields[1].GetUInt32(), // guid
2628 fields[6].GetUInt32(), // timestamp //64 bits?
2629 GuildNews(fields[2].GetUInt8()), // type
2630 fields[3].GetUInt32(), // player guid
2631 fields[4].GetUInt32(), // Flags
2632 fields[5].GetUInt32())); // value
2633}
2634
2636{
2637 uint8 tabId = fields[1].GetUInt8();
2638 if (tabId >= _GetPurchasedTabsSize())
2639 SF_LOG_ERROR("guild", "Invalid tab (tabId: %u) in guild bank, skipped.", tabId);
2640 else
2641 m_bankTabs[tabId]->LoadFromDB(fields);
2642}
2643
2645{
2646 uint8 tabId = fields[12].GetUInt8();
2647 if (tabId >= _GetPurchasedTabsSize())
2648 {
2649 SF_LOG_ERROR("guild", "Invalid tab for item (GUID: %u, id: #%u) in guild bank, skipped.",
2650 fields[14].GetUInt32(), fields[15].GetUInt32());
2651 return false;
2652 }
2653 return m_bankTabs[tabId]->LoadItemFromDB(fields);
2654}
2655
2656// Validates guild data loaded from database. Returns false if guild should be deleted.
2658{
2659 // Validate ranks data
2660 // GUILD RANKS represent a sequence starting from 0 = GUILD_MASTER (ALL PRIVILEGES) to max 9 (lowest privileges).
2661 // The lower rank id is considered higher rank - so promotion does rank-- and demotion does rank++
2662 // Between ranks in sequence cannot be gaps - so 0, 1, 2, 4 is impossible
2663 // Min ranks count is 2 and max is 10.
2664 bool broken_ranks = false;
2665 uint8 ranks = _GetRanksSize();
2666 if (ranks < GUILD_RANKS_MIN_COUNT || ranks > GUILD_RANKS_MAX_COUNT)
2667 {
2668 SF_LOG_ERROR("guild", "Guild %u has invalid number of ranks, creating new...", m_id);
2669 broken_ranks = true;
2670 }
2671 else
2672 {
2673 for (uint8 rankId = 0; rankId < ranks; ++rankId)
2674 {
2675 RankInfo* rankInfo = GetRankInfo(rankId);
2676 if (rankInfo->GetId() != rankId)
2677 {
2678 SF_LOG_ERROR("guild", "Guild %u has broken rank id %u, creating default set of ranks...", m_id, rankId);
2679 broken_ranks = true;
2680 }
2681 else
2682 {
2683 SQLTransaction trans = CharacterDatabase.BeginTransaction();
2684 rankInfo->CreateMissingTabsIfNeeded(_GetPurchasedTabsSize(), trans, true);
2685 CharacterDatabase.CommitTransaction(trans);
2686 }
2687 }
2688 }
2689
2690 if (broken_ranks)
2691 {
2692 m_ranks.clear();
2694 }
2695
2696 // Validate members' data
2697 for (Members::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
2698 if (itr->second->GetRankId() > _GetRanksSize())
2699 itr->second->ChangeRank(_GetLowestRankId());
2700
2701 // Repair the structure of the guild.
2702 // If the guildmaster doesn't exist or isn't member of the guild
2703 // attempt to promote another member.
2704 Member* pLeader = GetMember(m_leaderGuid);
2705 if (!pLeader)
2706 {
2708 // If no more members left, disband guild
2709 if (m_members.empty())
2710 {
2711 Disband();
2712 return false;
2713 }
2714 }
2715 else if (!pLeader->IsRank(GR_GUILDMASTER))
2716 _SetLeaderGUID(pLeader);
2717
2718 // Check config if multiple guildmasters are allowed
2719 if (!sConfigMgr->GetBoolDefault("Guild.AllowMultipleGuildMaster", 0))
2720 for (Members::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
2721 if (itr->second->GetRankId() == GR_GUILDMASTER && !itr->second->IsSamePlayer(m_leaderGuid))
2722 itr->second->ChangeRank(GR_OFFICER);
2723
2725 return true;
2726}
2727
2728// Broadcasts
2729void Guild::BroadcastToGuild(WorldSession* session, bool officerOnly, std::string const& msg, Language language) const
2730{
2731 if (session && session->GetPlayer() && _HasRankRight(session->GetPlayer(), officerOnly ? GR_RIGHT_OFFCHATSPEAK : GR_RIGHT_GCHATSPEAK))
2732 {
2733 WorldPacket data;
2734 ChatHandler::BuildChatPacket(data, officerOnly ? ChatMsg::CHAT_MSG_OFFICER : ChatMsg::CHAT_MSG_GUILD, language, session->GetPlayer(), NULL, msg);
2735 for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
2736 if (Player* player = itr->second->FindPlayer())
2737 if (player->GetSession() && _HasRankRight(player, officerOnly ? GR_RIGHT_OFFCHATLISTEN : GR_RIGHT_GCHATLISTEN) &&
2738 !player->GetSocial()->HasIgnore(session->GetPlayer()->GetGUIDLow()))
2739 player->GetSession()->SendPacket(&data);
2740 }
2741}
2742
2743void Guild::BroadcastAddonToGuild(WorldSession* session, bool officerOnly, std::string const& msg, std::string const& prefix) const
2744{
2745 if (session && session->GetPlayer() && _HasRankRight(session->GetPlayer(), officerOnly ? GR_RIGHT_OFFCHATSPEAK : GR_RIGHT_GCHATSPEAK))
2746 {
2747 WorldPacket data;
2749 for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
2750 if (Player* player = itr->second->FindPlayer())
2751 if (player->GetSession() && _HasRankRight(player, officerOnly ? GR_RIGHT_OFFCHATLISTEN : GR_RIGHT_GCHATLISTEN) &&
2752 !player->GetSocial()->HasIgnore(session->GetPlayer()->GetGUIDLow()) &&
2753 player->GetSession()->IsAddonRegistered(prefix))
2754 player->GetSession()->SendPacket(&data);
2755 }
2756}
2757
2759{
2760 for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
2761 if (itr->second->IsRank(rankId))
2762 if (Player* player = itr->second->FindPlayer())
2763 player->GetSession()->SendPacket(packet);
2764}
2765
2767{
2768 for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
2769 if (Player* player = itr->second->FindPlayer())
2770 player->GetSession()->SendPacket(packet);
2771}
2772
2773void Guild::MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 maxLevel, uint32 minRank)
2774{
2775 uint32 count = 0;
2776
2777 ByteBuffer inviteeData;
2779 data.WriteBits(count, 23); // count placeholder
2780
2781 for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
2782 {
2783 // not sure if needed, maybe client checks it as well
2784 if (count >= CALENDAR_MAX_INVITES)
2785 {
2786 if (Player* player = session->GetPlayer())
2787 sCalendarMgr->SendCalendarCommandResult(player->GetGUID(), CALENDAR_ERROR_INVITES_EXCEEDED);
2788 return;
2789 }
2790
2791 Member* member = itr->second;
2792 uint32 level = Player::GetLevelFromDB(member->GetGUID());
2793
2794 if (member->GetGUID() != session->GetPlayer()->GetGUID() && level >= minLevel && level <= maxLevel && member->IsRankNotLower(minRank))
2795 {
2796 ObjectGuid guid = member->GetGUID();
2797 data.WriteBit(guid[1]);
2798 data.WriteBit(guid[7]);
2799 data.WriteBit(guid[5]);
2800 data.WriteBit(guid[0]);
2801 data.WriteBit(guid[4]);
2802 data.WriteBit(guid[3]);
2803 data.WriteBit(guid[6]);
2804 data.WriteBit(guid[2]);
2805
2806 inviteeData << uint8(level);
2807 inviteeData.WriteByteSeq(guid[3]);
2808 inviteeData.WriteByteSeq(guid[5]);
2809 inviteeData.WriteByteSeq(guid[4]);
2810 inviteeData.WriteByteSeq(guid[6]);
2811 inviteeData.WriteByteSeq(guid[7]);
2812 inviteeData.WriteByteSeq(guid[0]);
2813 inviteeData.WriteByteSeq(guid[2]);
2814 inviteeData.WriteByteSeq(guid[1]);
2815
2816 ++count;
2817 }
2818 }
2819
2820 data.FlushBits();
2821 data.PutBits(0, count, 23);
2822 data.append(inviteeData);
2823
2824 session->SendPacket(&data);
2825}
2826
2827// Members handling
2829{
2830 Player* player = ObjectAccessor::FindPlayer(guid);
2831 // Player cannot be in guild
2832 if (player)
2833 {
2834 if (player->GetGuildId() != 0)
2835 return false;
2836 }
2837 else if (Player::GetGuildIdFromDB(guid) != 0)
2838 return false;
2839
2840 // Remove all player signs from another petitions
2841 // This will be prevent attempt to join many guilds and corrupt guild data integrity
2842 Player::RemovePetitionsAndSigns(guid, 4); // 4 - GUILD_CHARTER_TYPE
2843
2844 uint32 lowguid = GUID_LOPART(guid);
2845
2846 // If rank was not passed, assign lowest possible rank
2847 if (rankId == GUILD_RANK_NONE)
2848 rankId = _GetLowestRankId();
2849
2850 Member* member = new Member(m_id, guid, rankId);
2851 std::string name;
2852 if (player)
2853 {
2854 m_members[lowguid] = member;
2855 player->SetInGuild(m_id);
2856 player->SetGuildIdInvited(0);
2857 player->SetRank(rankId);
2858 player->SetGuildLevel(GetLevel());
2859 SendLoginInfo(player->GetSession());
2860 name = player->GetName();
2861 }
2862 else
2863 {
2864 member->ResetFlags();
2865
2866 bool ok = false;
2867 // Player must exist
2869 stmt->setUInt32(0, lowguid);
2870 if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
2871 {
2872 Field* fields = result->Fetch();
2873 name = fields[0].GetString();
2874 member->SetStats(
2875 fields[5].GetUInt32(),
2876 name,
2877 fields[1].GetUInt8(),
2878 fields[2].GetUInt8(),
2879 fields[3].GetUInt16(),
2880 fields[4].GetUInt32(),
2881 0);
2882
2883 ok = member->CheckStats();
2884 }
2885
2886 if (!ok)
2887 {
2888 delete member;
2889 return false;
2890 }
2891 m_members[lowguid] = member;
2892 }
2893
2894 SQLTransaction trans(NULL);
2895 member->SaveToDB(trans);
2896
2899 _BroadcastEvent(GE_JOINED, guid, name.c_str());
2900 sGuildFinderMgr->RemoveAllMembershipRequestsFromPlayer(lowguid);
2901
2902 // Call scripts if member was succesfully added (and stored to database)
2903 sScriptMgr->OnGuildAddMember(this, player, rankId);
2904
2905 return true;
2906}
2907
2908void Guild::DeleteMember(uint64 guid, bool isDisbanding, bool isKicked, bool canDeleteGuild)
2909{
2910 uint32 lowguid = GUID_LOPART(guid);
2911 Player* player = ObjectAccessor::FindPlayer(guid);
2912
2913 // Guild master can be deleted when loading guild and guid doesn't exist in characters table
2914 // or when he is removed from guild by gm command
2915 if (m_leaderGuid == guid && !isDisbanding)
2916 {
2917 Member* oldLeader = NULL;
2918 Member* newLeader = NULL;
2919 for (Guild::Members::iterator i = m_members.begin(); i != m_members.end(); ++i)
2920 {
2921 if (i->first == lowguid)
2922 oldLeader = i->second;
2923 else if (!newLeader || newLeader->GetRankId() > i->second->GetRankId())
2924 newLeader = i->second;
2925 }
2926
2927 if (!newLeader)
2928 {
2929 Disband();
2930 if (canDeleteGuild)
2931 delete this;
2932 return;
2933 }
2934
2935 _SetLeaderGUID(newLeader);
2936
2937 // If player not online data in data field will be loaded from guild tabs no need to update it !!
2938 if (Player* newLeaderPlayer = newLeader->FindPlayer())
2939 newLeaderPlayer->SetRank(GR_GUILDMASTER);
2940
2941 // If leader does not exist (at guild loading with deleted leader) do not send broadcasts
2942 if (oldLeader)
2943 {
2944 _BroadcastEvent(GE_LEADER_CHANGED, 0, oldLeader->GetName().c_str(), newLeader->GetName().c_str());
2945 _BroadcastEvent(GE_LEFT, guid, oldLeader->GetName().c_str());
2946 }
2947 }
2948 // Call script on remove before member is actually removed from guild (and database)
2949 sScriptMgr->OnGuildRemoveMember(this, player, isDisbanding, isKicked);
2950
2951 if (Member* member = GetMember(guid))
2952 delete member;
2953 m_members.erase(lowguid);
2954
2955 // If player not online data in data field will be loaded from guild tabs no need to update it !!
2956 if (player)
2957 {
2958 player->SetInGuild(0);
2959 player->SetRank(0);
2960 player->SetGuildLevel(0);
2961
2962 for (uint32 i = 0; i < sGuildPerkSpellsStore.GetNumRows(); ++i)
2963 if (GuildPerkSpellsEntry const* entry = sGuildPerkSpellsStore.LookupEntry(i))
2964 if (entry->Level <= GetLevel())
2965 player->removeSpell(entry->SpellId, false, false);
2966 }
2967
2968 _DeleteMemberFromDB(lowguid);
2969 if (!isDisbanding)
2971}
2972
2974{
2975 if (newRank <= _GetLowestRankId()) // Validate rank (allow only existing ranks)
2976 if (Member* member = GetMember(guid))
2977 {
2978 member->ChangeRank(newRank);
2979 return true;
2980 }
2981 return false;
2982}
2983
2984bool Guild::IsMember(uint64 guid) const
2985{
2986 Members::const_iterator itr = m_members.find(GUID_LOPART(guid));
2987 return itr != m_members.end();
2988}
2989
2990// Bank (items move)
2991void Guild::SwapItems(Player* player, uint8 tabId, uint8 slotId, uint8 destTabId, uint8 destSlotId, uint32 splitedAmount)
2992{
2993 if (tabId >= _GetPurchasedTabsSize() || slotId >= GUILD_BANK_MAX_SLOTS ||
2994 destTabId >= _GetPurchasedTabsSize() || destSlotId >= GUILD_BANK_MAX_SLOTS)
2995 return;
2996
2997 if (tabId == destTabId && slotId == destSlotId)
2998 return;
2999
3000 BankMoveItemData from(this, player, tabId, slotId);
3001 BankMoveItemData to(this, player, destTabId, destSlotId);
3002 _MoveItems(&from, &to, splitedAmount);
3003}
3004
3005void Guild::SwapItemsWithInventory(Player* player, bool toChar, uint8 tabId, uint8 slotId, uint8 playerBag, uint8 playerSlotId, uint32 splitedAmount)
3006{
3007 if ((slotId >= GUILD_BANK_MAX_SLOTS && slotId != NULL_SLOT) || tabId >= _GetPurchasedTabsSize())
3008 return;
3009
3010 BankMoveItemData bankData(this, player, tabId, slotId);
3011 PlayerMoveItemData charData(this, player, playerBag, playerSlotId);
3012 if (toChar)
3013 _MoveItems(&bankData, &charData, splitedAmount);
3014 else
3015 _MoveItems(&charData, &bankData, splitedAmount);
3016}
3017
3018// Bank tabs
3019void Guild::SetBankTabText(uint8 tabId, std::string const& text)
3020{
3021 if (BankTab* pTab = GetBankTab(tabId))
3022 {
3023 pTab->SetText(text);
3024 pTab->SendText(this, NULL);
3025 }
3026}
3027
3028// Private methods
3036
3038{
3039 uint8 tabId = _GetPurchasedTabsSize(); // Next free id
3040 m_bankTabs.push_back(new BankTab(m_id, tabId));
3041
3042 SQLTransaction trans = CharacterDatabase.BeginTransaction();
3043
3044 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_TAB);
3045 stmt->setUInt32(0, m_id);
3046 stmt->setUInt8(1, tabId);
3047 trans->Append(stmt);
3048
3049 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_TAB);
3050 stmt->setUInt32(0, m_id);
3051 stmt->setUInt8(1, tabId);
3052 trans->Append(stmt);
3053
3054 ++tabId;
3055 for (Ranks::iterator itr = m_ranks.begin(); itr != m_ranks.end(); ++itr)
3056 (*itr).CreateMissingTabsIfNeeded(tabId, trans, false);
3057
3058 CharacterDatabase.CommitTransaction(trans);
3059}
3060
3062{
3063 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_RANKS);
3064 stmt->setUInt32(0, m_id);
3065 CharacterDatabase.Execute(stmt);
3066
3067 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_RIGHTS);
3068 stmt->setUInt32(0, m_id);
3069 CharacterDatabase.Execute(stmt);
3070
3071 _CreateRank(sObjectMgr->GetSkyFireString(LANG_GUILD_MASTER, loc), GR_RIGHT_ALL);
3072 _CreateRank(sObjectMgr->GetSkyFireString(LANG_GUILD_OFFICER, loc), GR_RIGHT_ALL);
3076}
3077
3078bool Guild::_CreateRank(std::string const& name, uint32 rights)
3079{
3080 uint8 newRankId = _GetRanksSize();
3081 if (newRankId >= GUILD_RANKS_MAX_COUNT)
3082 return false;
3083
3084 // Ranks represent sequence 0, 1, 2, ... where 0 means guildmaster
3085 RankInfo info(m_id, newRankId, name, rights, 0);
3086 m_ranks.push_back(info);
3087
3088 SQLTransaction trans = CharacterDatabase.BeginTransaction();
3090 info.SaveToDB(trans);
3091 CharacterDatabase.CommitTransaction(trans);
3092
3093 return true;
3094}
3095
3096// Updates the number of accounts that are in the guild
3097// Player may have many characters in the guild, but with the same account
3099{
3100 // We use a set to be sure each element will be unique
3101 std::set<uint32> accountsIdSet;
3102 for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
3103 accountsIdSet.insert(itr->second->GetAccountId());
3104
3105 m_accountsNumber = accountsIdSet.size();
3106}
3107
3108// Detects if player is the guild master.
3109// Check both leader guid and player's rank (otherwise multiple feature with
3110// multiple guild masters won't work)
3111bool Guild::_IsLeader(Player* player) const
3112{
3113 if (player->GetGUID() == m_leaderGuid)
3114 return true;
3115 if (const Member* member = GetMember(player->GetGUID()))
3116 return member->IsRank(GR_GUILDMASTER);
3117 return false;
3118}
3119
3120void Guild::_DeleteBankItems(SQLTransaction& trans, bool removeItemsFromDB)
3121{
3122 for (uint8 tabId = 0; tabId < _GetPurchasedTabsSize(); ++tabId)
3123 {
3124 m_bankTabs[tabId]->Delete(trans, removeItemsFromDB);
3125 delete m_bankTabs[tabId];
3126 m_bankTabs[tabId] = NULL;
3127 }
3128 m_bankTabs.clear();
3129}
3130
3131bool Guild::_ModifyBankMoney(SQLTransaction& trans, uint64 amount, bool add)
3132{
3133 if (add)
3134 m_bankMoney += amount;
3135 else
3136 {
3137 // Check if there is enough money in bank.
3138 if (m_bankMoney < amount)
3139 return false;
3140 m_bankMoney -= amount;
3141 }
3142
3144 stmt->setUInt64(0, m_bankMoney);
3145 stmt->setUInt32(1, m_id);
3146 trans->Append(stmt);
3147 return true;
3148}
3149
3151{
3152 if (!pLeader)
3153 return;
3154
3155 m_leaderGuid = pLeader->GetGUID();
3156 pLeader->ChangeRank(GR_GUILDMASTER);
3157
3158 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_LEADER);
3160 stmt->setUInt32(1, m_id);
3161 CharacterDatabase.Execute(stmt);
3162}
3163
3165{
3166 if (RankInfo* rankInfo = GetRankInfo(rankId))
3167 rankInfo->SetBankMoneyPerDay(moneyPerDay);
3168}
3169
3170void Guild::_SetRankBankTabRightsAndSlots(uint8 rankId, GuildBankRightsAndSlots rightsAndSlots, bool saveToDB)
3171{
3172 if (rightsAndSlots.GetTabId() >= _GetPurchasedTabsSize())
3173 return;
3174
3175 if (RankInfo* rankInfo = GetRankInfo(rankId))
3176 rankInfo->SetBankTabSlotsAndRights(rightsAndSlots, saveToDB);
3177}
3178
3179inline std::string Guild::_GetRankName(uint8 rankId) const
3180{
3181 if (const RankInfo* rankInfo = GetRankInfo(rankId))
3182 return rankInfo->GetName();
3183 return "<unknown>";
3184}
3185
3187{
3188 if (const RankInfo* rankInfo = GetRankInfo(rankId))
3189 return rankInfo->GetRights();
3190 return 0;
3191}
3192
3194{
3195 if (const RankInfo* rankInfo = GetRankInfo(rankId))
3196 return rankInfo->GetBankMoneyPerDay();
3197 return 0;
3198}
3199
3201{
3202 if (tabId < _GetPurchasedTabsSize())
3203 if (const RankInfo* rankInfo = GetRankInfo(rankId))
3204 return rankInfo->GetBankTabSlotsPerDay(tabId);
3205 return 0;
3206}
3207
3209{
3210 if (const RankInfo* rankInfo = GetRankInfo(rankId))
3211 return rankInfo->GetBankTabRights(tabId);
3212 return 0;
3213}
3214
3215inline int32 Guild::_GetMemberRemainingSlots(Member const* member, uint8 tabId) const
3216{
3217 if (member)
3218 {
3219 uint8 rankId = member->GetRankId();
3220 if (rankId == GR_GUILDMASTER)
3222 if ((_GetRankBankTabRights(rankId, tabId) & GUILD_BANK_RIGHT_VIEW_TAB) != 0)
3223 {
3224 int32 remaining = _GetRankBankTabSlotsPerDay(rankId, tabId) - member->GetBankWithdrawValue(tabId);
3225 if (remaining > 0)
3226 return remaining;
3227 }
3228 }
3229 return 0;
3230}
3231
3233{
3234 if (member)
3235 {
3236 uint8 rankId = member->GetRankId();
3237 if (rankId == GR_GUILDMASTER)
3239
3241 {
3243 if (remaining > 0)
3244 return remaining;
3245 }
3246 }
3247 return 0;
3248}
3249
3251{
3252 if (Member* member = GetMember(guid))
3253 {
3254 uint8 rankId = member->GetRankId();
3255 if (rankId != GR_GUILDMASTER
3256 && member->GetBankWithdrawValue(tabId) < _GetRankBankTabSlotsPerDay(rankId, tabId))
3257 member->UpdateBankWithdrawValue(trans, tabId, 1);
3258 }
3259}
3260
3261inline bool Guild::_MemberHasTabRights(uint64 guid, uint8 tabId, uint32 rights) const
3262{
3263 if (const Member* member = GetMember(guid))
3264 {
3265 // Leader always has full rights
3266 if (member->IsRank(GR_GUILDMASTER) || m_leaderGuid == guid)
3267 return true;
3268 return (_GetRankBankTabRights(member->GetRankId(), tabId) & rights) == rights;
3269 }
3270 return false;
3271}
3272
3273// Add new event log record
3274inline void Guild::_LogEvent(GuildEventLogTypes eventType, uint32 playerGuid1, uint32 playerGuid2, uint8 newRank)
3275{
3276 SQLTransaction trans = CharacterDatabase.BeginTransaction();
3277 m_eventLog->AddEvent(trans, new EventLogEntry(m_id, m_eventLog->GetNextGUID(), eventType, playerGuid1, playerGuid2, newRank));
3278 CharacterDatabase.CommitTransaction(trans);
3279
3280 sScriptMgr->OnGuildEvent(this, uint8(eventType), playerGuid1, playerGuid2, newRank);
3281}
3282
3283// Add new bank event log record
3284void Guild::_LogBankEvent(SQLTransaction& trans, GuildBankEventLogTypes eventType, uint8 tabId, uint32 lowguid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId)
3285{
3286 if (tabId > GUILD_BANK_MAX_TABS)
3287 return;
3288
3289 // not logging moves within the same tab
3290 if (eventType == GUILD_BANK_LOG_MOVE_ITEM && tabId == destTabId)
3291 return;
3292
3293 uint8 dbTabId = tabId;
3294 if (BankEventLogEntry::IsMoneyEvent(eventType))
3295 {
3296 tabId = GUILD_BANK_MAX_TABS;
3297 dbTabId = GUILD_BANK_MONEY_LOGS_TAB;
3298 }
3299 LogHolder* pLog = m_bankEventLog[tabId];
3300 pLog->AddEvent(trans, new BankEventLogEntry(m_id, pLog->GetNextGUID(), eventType, dbTabId, lowguid, itemOrMoney, itemStackCount, destTabId));
3301
3302 sScriptMgr->OnGuildBankEvent(this, uint8(eventType), tabId, lowguid, itemOrMoney, itemStackCount, destTabId);
3303}
3304
3305inline Item* Guild::_GetItem(uint8 tabId, uint8 slotId) const
3306{
3307 if (const BankTab* tab = GetBankTab(tabId))
3308 return tab->GetItem(slotId);
3309 return NULL;
3310}
3311
3312inline void Guild::_RemoveItem(SQLTransaction& trans, uint8 tabId, uint8 slotId)
3313{
3314 if (BankTab* pTab = GetBankTab(tabId))
3315 pTab->SetItem(trans, slotId, NULL);
3316}
3317
3318void Guild::_MoveItems(MoveItemData* pSrc, MoveItemData* pDest, uint32 splitedAmount)
3319{
3320 // 1. Initialize source item
3321 if (!pSrc->InitItem())
3322 return; // No source item
3323
3324 // 2. Check source item
3325 if (!pSrc->CheckItem(splitedAmount))
3326 return; // Source item or splited amount is invalid
3327 /*
3328 if (pItemSrc->GetCount() == 0)
3329 {
3330 SF_LOG_FATAL("guild", "Guild::SwapItems: Player %s(GUIDLow: %u) tried to move item %u from tab %u slot %u to tab %u slot %u, but item %u has a stack of zero!",
3331 player->GetName(), player->GetGUIDLow(), pItemSrc->GetEntry(), tabId, slotId, destTabId, destSlotId, pItemSrc->GetEntry());
3332 //return; // Commented out for now, uncomment when it's verified that this causes a crash!!
3333 }
3334 // */
3335
3336 // 3. Check destination rights
3337 if (!pDest->HasStoreRights(pSrc))
3338 return; // Player has no rights to store item in destination
3339
3340 // 4. Check source withdraw rights
3341 if (!pSrc->HasWithdrawRights(pDest))
3342 return; // Player has no rights to withdraw items from source
3343
3344 // 5. Check split
3345 if (splitedAmount)
3346 {
3347 // 5.1. Clone source item
3348 if (!pSrc->CloneItem(splitedAmount))
3349 return; // Item could not be cloned
3350
3351 // 5.2. Move splited item to destination
3352 _DoItemsMove(pSrc, pDest, true, splitedAmount);
3353 }
3354 else // 6. No split
3355 {
3356 // 6.1. Try to merge items in destination (pDest->GetItem() == NULL)
3357 if (!_DoItemsMove(pSrc, pDest, false)) // Item could not be merged
3358 {
3359 // 6.2. Try to swap items
3360 // 6.2.1. Initialize destination item
3361 if (!pDest->InitItem())
3362 return;
3363
3364 // 6.2.2. Check rights to store item in source (opposite direction)
3365 if (!pSrc->HasStoreRights(pDest))
3366 return; // Player has no rights to store item in source (opposite direction)
3367
3368 if (!pDest->HasWithdrawRights(pSrc))
3369 return; // Player has no rights to withdraw item from destination (opposite direction)
3370
3371 // 6.2.3. Swap items (pDest->GetItem() != NULL)
3372 _DoItemsMove(pSrc, pDest, true);
3373 }
3374 }
3375 // 7. Send changes
3376 _SendBankContentUpdate(pSrc, pDest);
3377}
3378
3379bool Guild::_DoItemsMove(MoveItemData* pSrc, MoveItemData* pDest, bool sendError, uint32 splitedAmount)
3380{
3381 Item* pDestItem = pDest->GetItem();
3382 bool swap = (pDestItem != NULL);
3383
3384 Item* pSrcItem = pSrc->GetItem(splitedAmount);
3385 // 1. Can store source item in destination
3386 if (!pDest->CanStore(pSrcItem, swap, sendError))
3387 return false;
3388
3389 // 2. Can store destination item in source
3390 if (swap)
3391 if (!pSrc->CanStore(pDestItem, true, true))
3392 return false;
3393
3394 // GM LOG (@todo move to scripts)
3395 pDest->LogAction(pSrc);
3396 if (swap)
3397 pSrc->LogAction(pDest);
3398
3399 SQLTransaction trans = CharacterDatabase.BeginTransaction();
3400 // 3. Log bank events
3401 pDest->LogBankEvent(trans, pSrc, pSrcItem->GetCount());
3402 if (swap)
3403 pSrc->LogBankEvent(trans, pDest, pDestItem->GetCount());
3404
3405 // 4. Remove item from source
3406 pSrc->RemoveItem(trans, pDest, splitedAmount);
3407
3408 // 5. Remove item from destination
3409 if (swap)
3410 pDest->RemoveItem(trans, pSrc);
3411
3412 // 6. Store item in destination
3413 pDest->StoreItem(trans, pSrcItem);
3414
3415 // 7. Store item in source
3416 if (swap)
3417 pSrc->StoreItem(trans, pDestItem);
3418
3419 CharacterDatabase.CommitTransaction(trans);
3420 return true;
3421}
3422
3424{
3425 ASSERT(pSrc->IsBank() || pDest->IsBank());
3426
3427 uint8 tabId = 0;
3428 SlotIds slots;
3429 if (pSrc->IsBank()) // B ->
3430 {
3431 tabId = pSrc->GetContainer();
3432 slots.insert(pSrc->GetSlotId());
3433 if (pDest->IsBank()) // B -> B
3434 {
3435 // Same tab - add destination slots to collection
3436 if (pDest->GetContainer() == pSrc->GetContainer())
3437 pDest->CopySlots(slots);
3438 else // Different tabs - send second message
3439 {
3440 SlotIds destSlots;
3441 pDest->CopySlots(destSlots);
3442 _SendBankContentUpdate(pDest->GetContainer(), destSlots);
3443 }
3444 }
3445 }
3446 else if (pDest->IsBank()) // C -> B
3447 {
3448 tabId = pDest->GetContainer();
3449 pDest->CopySlots(slots);
3450 }
3451
3452 _SendBankContentUpdate(tabId, slots);
3453}
3454
3456{
3457 if (BankTab const* tab = GetBankTab(tabId))
3458 {
3459 ByteBuffer tabData;
3460
3461 WorldPacket data(SMSG_GUILD_BANK_LIST, 500); // guess size
3462 data << uint32(tabId);
3463 data << uint64(m_bankMoney);
3464
3465 size_t pos = data.wpos();
3466 data << uint32(0); // item withdrawal limit placeholder
3467
3468 data.WriteBit(0); // not a full update
3469 data.WriteBits(0, 21); // tab count (doesn't need to be sent here)
3470 data.WriteBits(slots.size(), 18); // item count
3471
3472 for (SlotIds::const_iterator itr = slots.begin(); itr != slots.end(); ++itr)
3473 {
3474 Item const* tabItem = tab->GetItem(*itr);
3475
3476 tabData << uint32(0);
3477 tabData << uint32(0);
3478
3479 uint32 enchants = 0;
3480
3481 if (tabItem)
3482 for (uint32 ench = 0; ench < MAX_ENCHANTMENT_SLOT; ++ench)
3483 if (uint32 enchantId = tabItem->GetEnchantmentId(EnchantmentSlot(ench)))
3484 {
3485 tabData << uint32(enchantId);
3486 tabData << uint32(ench);
3487 ++enchants;
3488 }
3489
3490 data.WriteBit(0); // Locked
3491 data.WriteBits(enchants, 21);
3492
3493 tabData << uint32(0);
3494 tabData << uint32(0); // Size size - mods
3495 tabData << uint32(tabItem ? tabItem->GetEntry() : 0); // ITEM_FIELD_STACK_COUNT
3496 tabData << uint32(tabItem ? abs(tabItem->GetSpellCharges()) : 0); // Spell charges
3497 tabData << uint32(tabItem ? tabItem->GetCount() : 0);
3498 tabData << uint32(*itr);
3499 tabData << uint32(tabItem ? tabItem->GetItemRandomPropertyId() : 0);
3500 tabData << uint32(tabItem ? tabItem->GetItemSuffixFactor() : 0); // SuffixFactor
3501 }
3502
3503 data.FlushBits();
3504
3505 if (!tabData.empty())
3506 data.append(tabData);
3507
3508 for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
3509 if (_MemberHasTabRights(itr->second->GetGUID(), tabId, GUILD_BANK_RIGHT_VIEW_TAB))
3510 if (Player* player = itr->second->FindPlayer())
3511 {
3512 data.put<uint32>(pos, uint32(_GetMemberRemainingSlots(itr->second, tabId)));
3513 player->GetSession()->SendPacket(&data);
3514 }
3515
3516 SF_LOG_DEBUG("guild", "WORLD: Sent (SMSG_GUILD_BANK_LIST)");
3517 }
3518}
3519
3520void Guild::_BroadcastEvent(GuildEvents guildEvent, uint64 guid, const char* param1, const char* param2, const char* param3) const
3521{
3522 uint8 count = !param3 ? (!param2 ? (!param1 ? 0 : 1) : 2) : 3;
3523
3524 WorldPacket data(SMSG_GUILD_EVENT, 1 + 1 + count + (guid ? 8 : 0));
3525 data << uint8(guildEvent);
3526 data << uint8(count);
3527
3528 if (param3)
3529 data << param1 << param2 << param3;
3530 else if (param2)
3531 data << param1 << param2;
3532 else if (param1)
3533 data << param1;
3534
3535 if (guid)
3536 data << uint64(guid);
3537
3538 BroadcastPacket(&data);
3539
3540 if (sLog->ShouldLog("guild", LogLevel::LOG_LEVEL_DEBUG))
3541 SF_LOG_DEBUG("guild", "SMSG_GUILD_EVENT [Broadcast] Event: %s (%u)", _GetGuildEventString(guildEvent).c_str(), guildEvent);
3542}
3543
3544void Guild::SendBankList(WorldSession* session, uint8 tabId, bool withContent, bool withTabInfo) const
3545{
3546 Member const* member = GetMember(session->GetPlayer()->GetGUID());
3547 if (!member) // Shouldn't happen, just in case
3548 return;
3549
3550 ByteBuffer tabData;
3552 data << uint32(tabId);
3553 data << uint64(m_bankMoney);
3554 data << uint32(_GetMemberRemainingSlots(member, tabId));
3555 data.WriteBit(withContent && withTabInfo);
3556
3557 uint32 itemCount = 0;
3558 if (withContent && _MemberHasTabRights(session->GetPlayer()->GetGUID(), tabId, GUILD_BANK_RIGHT_VIEW_TAB))
3559 if (BankTab const* tab = GetBankTab(tabId))
3560 for (uint8 slotId = 0; slotId < GUILD_BANK_MAX_SLOTS; ++slotId)
3561 if (tab->GetItem(slotId))
3562 ++itemCount;
3563
3564 data.WriteBits(withTabInfo ? _GetPurchasedTabsSize() : 0, 21);
3565 data.WriteBits(itemCount, 18);
3566
3567 if (withTabInfo)
3568 {
3569 for (uint8 i = 0; i < _GetPurchasedTabsSize(); ++i)
3570 {
3571 data.WriteBits(m_bankTabs[i]->GetIcon().length(), 9);
3572 data.WriteBits(m_bankTabs[i]->GetName().length(), 7);
3573 }
3574 }
3575
3576 if (withContent && _MemberHasTabRights(session->GetPlayer()->GetGUID(), tabId, GUILD_BANK_RIGHT_VIEW_TAB))
3577 {
3578 if (BankTab const* tab = GetBankTab(tabId))
3579 {
3580 for (uint8 slotId = 0; slotId < GUILD_BANK_MAX_SLOTS; ++slotId)
3581 {
3582 if (Item* tabItem = tab->GetItem(slotId))
3583 {
3584 tabData << uint32(0);
3585 tabData << uint32(0);
3586
3587 uint32 enchants = 0;
3588 for (uint32 ench = 0; ench < MAX_ENCHANTMENT_SLOT; ++ench)
3589 {
3590 if (uint32 enchantId = tabItem->GetEnchantmentId(EnchantmentSlot(ench)))
3591 {
3592 tabData << uint32(enchantId);
3593 tabData << uint32(ench);
3594 ++enchants;
3595 }
3596 }
3597
3598 data.WriteBit(0); // Locked
3599 data.WriteBits(enchants, 21);
3600
3601 tabData << uint32(0);
3602 tabData << uint32(0); // Size size - mods
3603 tabData << uint32(tabItem->GetEntry()); // ITEM_FIELD_STACK_COUNT
3604 tabData << uint32(abs(tabItem->GetSpellCharges())); // Spell charges
3605 tabData << uint32(tabItem->GetCount());
3606 tabData << uint32(slotId);
3607 tabData << uint32(tabItem->GetItemRandomPropertyId());
3608 tabData << uint32(tabItem->GetItemSuffixFactor()); // SuffixFactor
3609 }
3610 }
3611 }
3612 }
3613
3614 data.FlushBits();
3615
3616 if (!tabData.empty())
3617 data.append(tabData);
3618
3619 if (withTabInfo)
3620 {
3621 for (uint8 i = 0; i < _GetPurchasedTabsSize(); ++i)
3622 {
3623 data << uint32(i);
3624 data.WriteString(m_bankTabs[i]->GetIcon());
3625 data.WriteString(m_bankTabs[i]->GetName());
3626 }
3627 }
3628
3629 session->SendPacket(&data);
3630
3631 SF_LOG_DEBUG("guild", "WORLD: Sent (SMSG_GUILD_BANK_LIST)");
3632}
3633
3634void Guild::SendGuildRanksUpdate(uint64 setterGuid, uint64 targetGuid, uint32 rank)
3635{
3636 ObjectGuid tarGuid = targetGuid;
3637 ObjectGuid setGuid = setterGuid;
3638
3639 Member* member = GetMember(targetGuid);
3640 ASSERT(member);
3641
3643 data.WriteBit(tarGuid[5]);
3644 data.WriteBit(tarGuid[6]);
3645 data.WriteBit(setGuid[0]);
3646 data.WriteBit(setGuid[1]);
3647 data.WriteBit(tarGuid[3]);
3648 data.WriteBit(setGuid[4]);
3649 data.WriteBit(tarGuid[2]);
3650 data.WriteBit(setGuid[6]);
3651 data.WriteBit(setGuid[3]);
3652 data.WriteBit(setGuid[7]);
3653 data.WriteBit(tarGuid[4]);
3654 data.WriteBit(tarGuid[0]);
3655 data.WriteBit(tarGuid[1]);
3656 data.WriteBit(setGuid[2]);
3657 data.WriteBit(tarGuid[7]);
3658 data.WriteBit(rank < member->GetRankId()); // 1 == higher, 0 = lower?
3659 data.WriteBit(setGuid[5]);
3660
3661 data.FlushBits();
3662
3663 data.WriteByteSeq(tarGuid[2]);
3664 data.WriteByteSeq(setGuid[1]);
3665 data.WriteByteSeq(tarGuid[6]);
3666 data.WriteByteSeq(tarGuid[1]);
3667 data.WriteByteSeq(tarGuid[5]);
3668 data.WriteByteSeq(setGuid[0]);
3669 data << uint32(rank);
3670 data.WriteByteSeq(setGuid[3]);
3671 data.WriteByteSeq(setGuid[7]);
3672 data.WriteByteSeq(tarGuid[7]);
3673 data.WriteByteSeq(setGuid[2]);
3674 data.WriteByteSeq(tarGuid[3]);
3675 data.WriteByteSeq(tarGuid[4]);
3676 data.WriteByteSeq(setGuid[6]);
3677 data.WriteByteSeq(setGuid[5]);
3678 data.WriteByteSeq(tarGuid[0]);
3679 data.WriteByteSeq(setGuid[4]);
3680 BroadcastPacket(&data);
3681
3682 member->ChangeRank(rank);
3683
3684 SF_LOG_DEBUG("network", "SMSG_GUILD_RANKS_UPDATE [Broadcast] Target: %u, Issuer: %u, RankId: %u",
3685 GUID_LOPART(targetGuid), GUID_LOPART(setterGuid), rank);
3686}
3687
3688void Guild::GiveXP(uint32 xp, Player* source)
3689{
3691 return;
3692
3694
3696 xp = 0; // SMSG_GUILD_XP_GAIN is always sent, even for no gains
3697
3699 xp = std::min(xp, sWorld->getIntConfig(WorldIntConfigs::CONFIG_GUILD_DAILY_XP_CAP) - uint32(_todayExperience));
3700
3702 data << uint64(xp);
3703 source->GetSession()->SendPacket(&data);
3704
3705 _experience += xp;
3706 _todayExperience += xp;
3707
3708 if (!xp)
3709 return;
3710
3711 uint32 oldLevel = GetLevel();
3712
3713 // Ding, mon!
3714 while (GetExperience() >= sGuildMgr->GetXPForGuildLevel(GetLevel()) && GetLevel() < sWorld->getIntConfig(WorldIntConfigs::CONFIG_GUILD_MAX_LEVEL))
3715 {
3716 _experience -= sGuildMgr->GetXPForGuildLevel(GetLevel());
3717 ++_level;
3718
3719 // Find all guild perks to learn
3720 std::vector<uint32> perksToLearn;
3721 for (uint32 i = 0; i < sGuildPerkSpellsStore.GetNumRows(); ++i)
3722 if (GuildPerkSpellsEntry const* entry = sGuildPerkSpellsStore.LookupEntry(i))
3723 if (entry->Level > oldLevel && entry->Level <= GetLevel())
3724 perksToLearn.push_back(entry->SpellId);
3725
3726 // Notify all online players that guild level changed and learn perks
3727 for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
3728 {
3729 if (Player* player = itr->second->FindPlayer())
3730 {
3731 player->SetGuildLevel(GetLevel());
3732 for (size_t i = 0; i < perksToLearn.size(); ++i)
3733 player->learnSpell(perksToLearn[i], true);
3734 }
3735 }
3736
3739
3740 ++oldLevel;
3741 }
3742}
3743
3744void Guild::SendGuildXP(WorldSession* session /* = NULL */) const
3745{
3746 Member const* member = GetMember(session->GetGuidLow());
3747
3748 WorldPacket data(SMSG_GUILD_XP, 32);
3749 data << uint64(GetExperience());
3750 data << uint64(member ? member->GetWeekActivity() : 0);
3751 data << uint64(member ? member->GetTotalActivity() : 0);
3752 data << uint64(sGuildMgr->GetXPForGuildLevel(GetLevel()) - GetExperience()); // XP missing for next level
3753 session->SendPacket(&data);
3754}
3755
3757{
3758 uint32 cap = sWorld->getIntConfig(WorldIntConfigs::CONFIG_GUILD_WEEKLY_REP_CAP) - reputation;
3760 data << uint32(cap);
3761 session->SendPacket(&data);
3762 SF_LOG_DEBUG("guild", "SMSG_GUILD_REPUTATION_WEEKLY_CAP [%s]: Left: %u",
3763 session->GetPlayerInfo().c_str(), cap);
3764}
3765
3766void Guild::ResetTimes(bool weekly)
3767{
3768 _todayExperience = 0;
3769 for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
3770 {
3771 itr->second->ResetValues(weekly);
3772 if (Player* player = itr->second->FindPlayer())
3773 {
3774 //SendGuildXP(player->GetSession());
3775 WorldPacket data(SMSG_GUILD_MEMBER_DAILY_RESET, 0); // tells the client to request bank withdrawal limit
3776 player->GetSession()->SendPacket(&data);
3777 }
3778 }
3779}
3780
3781void Guild::AddGuildNews(uint8 type, uint64 guid, uint32 flags, uint32 value)
3782{
3783 uint32 lowGuid = GUID_LOPART(guid);
3784 NewsLogEntry* news = new NewsLogEntry(m_id, m_newsLog->GetNextGUID(), GuildNews(type), lowGuid, flags, value);
3785
3786 SQLTransaction trans = CharacterDatabase.BeginTransaction();
3787 m_newsLog->AddEvent(trans, news);
3788 CharacterDatabase.CommitTransaction(trans);
3789
3790 WorldPacket data(SMSG_GUILD_NEWS_UPDATE, 7 + 32);
3791 data.WriteBits(1, 19); // size, we are only sending 1 news here
3792 ByteBuffer buffer;
3793 news->WritePacket(data, buffer);
3794
3795 BroadcastPacket(&data);
3796}
3797
3798bool Guild::HasAchieved(uint32 achievementId) const
3799{
3800 return m_achievementMgr.HasAchieved(achievementId);
3801}
3802
3803void Guild::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit* unit, Player* player)
3804{
3805 m_achievementMgr.UpdateAchievementCriteria(type, miscValue1, miscValue2, miscValue3, unit, player);
3806}
3807
3808void Guild::HandleNewsSetSticky(WorldSession* session, uint32 newsId, bool sticky)
3809{
3810 GuildLog* logs = m_newsLog->GetGuildLog();
3811 GuildLog::iterator itr = logs->begin();
3812 while (itr != logs->end() && (*itr)->GetGUID() != newsId)
3813 ++itr;
3814
3815 if (itr == logs->end())
3816 {
3817 SF_LOG_DEBUG("guild", "HandleNewsSetSticky: [%s] requested unknown newsId %u - Sticky: %u",
3818 session->GetPlayerInfo().c_str(), newsId, sticky);
3819 return;
3820 }
3821
3822 NewsLogEntry* news = (NewsLogEntry*)(*itr);
3823 news->SetSticky(sticky);
3824
3825 SF_LOG_DEBUG("guild", "HandleNewsSetSticky: [%s] chenged newsId %u sticky to %u",
3826 session->GetPlayerInfo().c_str(), newsId, sticky);
3827
3828 WorldPacket data(SMSG_GUILD_NEWS_UPDATE, 7 + 32);
3829 data.WriteBits(1, 19);
3830 ByteBuffer buffer;
3831 news->WritePacket(data, buffer);
3832 session->SendPacket(&data);
3833}
3834
3835void Guild::HandleSetBankTabNote(WorldSession* session, uint32 tabId, std::string const& note)
3836{
3837 BankTab* bankTab = GetBankTab(tabId);
3838 if (!bankTab)
3839 {
3840 SF_LOG_ERROR("guild", "Guild::HandleSetBankTabNote: Player %s is trying to modify bank tab note for non existing tab %d.",
3841 session->GetPlayerInfo().c_str(), tabId);
3842 return;
3843 }
3844
3846 {
3847 SF_LOG_ERROR("guild", "Guild::HandleSetBankTabNote: Player %s is trying to modify a bank tab note but doesn't have permission!",
3848 session->GetPlayerInfo().c_str());
3849 return;
3850 }
3851
3852 bankTab->SetText(note);
3853
3855 data << tabId;
3856 BroadcastPacket(&data);
3857}
@ LOG_LEVEL_DEBUG
Definition Appender.h:19
Item * NewItemOrBag(ItemTemplate const *proto)
Definition Bag.h:53
#define sCalendarMgr
@ CALENDAR_ERROR_INVITES_EXCEEDED
Definition CalendarMgr.h:91
#define CALENDAR_MAX_INVITES
@ CHAR_INS_GUILD_MEMBER
@ CHAR_UPD_GUILD_MOTD
@ CHAR_DEL_GUILD_BANK_TABS
@ CHAR_UPD_GUILD_BANK_TAB_TEXT
@ CHAR_INS_GUILD_NEWS
@ CHAR_DEL_GUILD
@ CHAR_DEL_GUILD_BANK_RIGHTS
@ CHAR_UPD_GUILD_RANK_NAME
@ CHAR_UPD_GUILD_NAME
@ CHAR_INS_GUILD_EVENTLOG
@ CHAR_UPD_GUILD_EMBLEM_INFO
@ CHAR_DEL_GUILD_BANK_EVENTLOGS
@ CHAR_DEL_GUILD_BANK_RIGHTS_FOR_RANK
@ CHAR_DEL_NONEXISTENT_GUILD_BANK_ITEM
@ CHAR_UPD_GUILD_MEMBER_RANK
@ CHAR_INS_GUILD_RANK
@ CHAR_INS_GUILD
@ CHAR_UPD_GUILD_RANK_BANK_MONEY
@ CHAR_UPD_GUILD_LEADER
@ CHAR_UPD_GUILD_RANK_RIGHTS
@ CHAR_UPD_GUILD_MEMBER_PNOTE
@ CHAR_INS_GUILD_BANK_TAB
@ CHAR_SEL_CHAR_DATA_FOR_GUILD
@ CHAR_UPD_GUILD_BANK_MONEY
@ CHAR_DEL_GUILD_BANK_TAB
@ CHAR_DEL_GUILD_MEMBERS
@ CHAR_UPD_GUILD_MEMBER_OFFNOTE
@ CHAR_DEL_GUILD_BANK_EVENTLOG
@ CHAR_DEL_GUILD_BANK_ITEMS
@ CHAR_DEL_GUILD_BANK_ITEM
@ CHAR_DEL_GUILD_EVENTLOG
@ CHAR_UPD_GUILD_INFO
@ CHAR_DEL_GUILD_EVENTLOGS
@ CHAR_INS_GUILD_BANK_EVENTLOG
@ CHAR_DEL_GUILD_RANKS
@ CHAR_UPD_GUILD_EXPERIENCE
@ CHAR_DEL_GUILD_RANK
@ CHAR_INS_GUILD_BANK_ITEM
@ CHAR_UPD_GUILD_BANK_TAB_INFO
@ CHAR_INS_GUILD_MEMBER_WITHDRAW
@ CHAR_INS_GUILD_BANK_RIGHT
LocaleConstant
Definition Common.h:138
#define DEFAULT_LOCALE
Definition Common.h:154
@ DAY
Definition Common.h:121
#define sConfigMgr
Definition Config.h:64
AchievementCriteriaTypes
Definition DBCEnums.h:170
@ ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL
Definition DBCEnums.h:272
DBCStorage< GuildPerkSpellsEntry > sGuildPerkSpellsStore(GuildPerkSpellsfmt)
std::int32_t int32
Definition Define.h:73
#define UI64FMTD
Definition Define.h:64
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::int8_t int8
Definition Define.h:75
std::uint64_t uint64
Definition Define.h:76
std::int64_t int64
Definition Define.h:72
std::uint16_t uint16
Definition Define.h:78
#define ASSERT
Definition Errors.h:29
uint32 _GetGuildBankTabPrice(uint8 tabId)
Definition Guild.cpp:73
#define MAX_GUILD_BANK_TAB_TEXT_LEN
Definition Guild.cpp:20
#define EMBLEM_PRICE
Definition Guild.cpp:21
std::string _GetGuildEventString(GuildEvents event)
Definition Guild.cpp:23
GuildEvents
Definition Guild.h:135
@ GE_LEFT
Definition Guild.h:140
@ GE_FOUNDER
Definition Guild.h:150
@ GE_LEADER_IS
Definition Guild.h:142
@ GE_RANK_CREATED
Definition Guild.h:147
@ GE_TABARDCHANGE
Definition Guild.h:145
@ GE_REMOVED
Definition Guild.h:141
@ GE_JOINED
Definition Guild.h:139
@ GE_RANK_DELETED
Definition Guild.h:148
@ GE_GUILDBANKBAGSLOTS_CHANGED
Definition Guild.h:153
@ GE_PROMOTION
Definition Guild.h:136
@ GE_BANK_TAB_UPDATED
Definition Guild.h:155
@ GE_BANK_MONEY_SET
Definition Guild.h:156
@ GE_DISBANDED
Definition Guild.h:144
@ GE_BANK_TEXT_CHANGED
Definition Guild.h:158
@ GE_SIGNED_OFF
Definition Guild.h:152
@ GE_MOTD
Definition Guild.h:138
@ GE_BANK_TAB_PURCHASED
Definition Guild.h:154
@ GE_LEADER_CHANGED
Definition Guild.h:143
@ GE_SIGNED_ON
Definition Guild.h:151
@ GE_DEMOTION
Definition Guild.h:137
@ GE_RANK_UPDATED
Definition Guild.h:146
@ GE_BANK_MONEY_CHANGED
Definition Guild.h:157
@ GUILD_EXPERIENCE_UNCAPPED_LEVEL
Definition Guild.h:30
@ GUILD_RANKS_MIN_COUNT
Definition Guild.h:24
@ GUILD_EVENT_LOG_GUID_UNDEFINED
Definition Guild.h:29
@ GUILD_WITHDRAW_SLOT_UNLIMITED
Definition Guild.h:28
@ GUILD_BANK_MONEY_LOGS_TAB
Definition Guild.h:23
@ GUILD_WITHDRAW_MONEY_UNLIMITED
Definition Guild.h:27
@ GUILD_BANK_MAX_SLOTS
Definition Guild.h:22
@ GUILD_RANKS_MAX_COUNT
Definition Guild.h:25
@ GUILD_BANK_MAX_TABS
Definition Guild.h:21
@ GUILD_RANK_NONE
Definition Guild.h:26
@ GUILDMEMBER_STATUS_ONLINE
Definition Guild.h:232
@ GUILD_BANK_RIGHT_VIEW_TAB
Definition Guild.h:187
@ GUILD_BANK_RIGHT_DEPOSIT_ITEM
Definition Guild.h:191
std::set< uint8 > SlotIds
Definition Guild.h:321
GuildCommandType
Definition Guild.h:79
@ GUILD_COMMAND_CHANGE_LEADER
Definition Guild.h:87
@ GUILD_COMMAND_INVITE
Definition Guild.h:81
@ GUILD_COMMAND_QUIT
Definition Guild.h:82
@ GUILD_COMMAND_PROMOTE
Definition Guild.h:84
@ GUILD_COMMAND_DEMOTE
Definition Guild.h:85
@ GUILD_COMMAND_PUBLIC_NOTE
Definition Guild.h:92
@ GUILD_COMMAND_CHANGE_RANK
Definition Guild.h:91
@ GUILD_COMMAND_REMOVE
Definition Guild.h:86
@ GUILD_COMMAND_EDIT_MOTD
Definition Guild.h:88
GuildCommandError
Definition Guild.h:99
@ ERR_GUILD_PERMISSIONS
Definition Guild.h:109
@ ERR_GUILD_UNDELETABLE_DUE_TO_LEVEL
Definition Guild.h:129
@ ERR_ALREADY_IN_GUILD_S
Definition Guild.h:103
@ ERR_GUILD_LEADER_LEAVE
Definition Guild.h:108
@ ERR_GUILD_COMMAND_SUCCESS
Definition Guild.h:100
@ ERR_GUILD_NOT_ALLIED
Definition Guild.h:113
@ ERR_GUILD_PLAYER_NOT_FOUND_S
Definition Guild.h:112
@ ERR_GUILD_RANK_TOO_LOW_S
Definition Guild.h:115
@ ERR_GUILD_RANK_TOO_HIGH_S
Definition Guild.h:114
@ ERR_ALREADY_INVITED_TO_GUILD_S
Definition Guild.h:105
@ ERR_GUILD_NAME_INVALID
Definition Guild.h:106
@ GR_MEMBER
Definition Guild.h:47
@ GR_GUILDMASTER
Definition Guild.h:44
@ GR_INITIATE
Definition Guild.h:48
@ GR_OFFICER
Definition Guild.h:45
GuildNews
Definition Guild.h:239
@ GUILD_NEWS_LEVEL_UP
Definition Guild.h:246
GuildBankEventLogTypes
Definition Guild.h:196
@ GUILD_BANK_LOG_MOVE_ITEM
Definition Guild.h:199
@ GUILD_BANK_LOG_WITHDRAW_ITEM
Definition Guild.h:198
@ GUILD_BANK_LOG_DEPOSIT_MONEY
Definition Guild.h:200
@ GUILD_BANK_LOG_DEPOSIT_ITEM
Definition Guild.h:197
@ GUILD_BANK_LOG_WITHDRAW_MONEY
Definition Guild.h:201
@ GUILD_BANK_LOG_CASH_FLOW_DEPOSIT
Definition Guild.h:206
@ GUILD_BANK_LOG_REPAIR_MONEY
Definition Guild.h:202
@ GUILD_BANK_LOG_MOVE_ITEM2
Definition Guild.h:203
GuildRankRights
Definition Guild.h:54
@ GR_RIGHT_EOFFNOTE
Definition Guild.h:67
@ GR_RIGHT_GCHATSPEAK
Definition Guild.h:57
@ GR_RIGHT_OFFCHATSPEAK
Definition Guild.h:59
@ GR_RIGHT_ALL
Definition Guild.h:75
@ GR_RIGHT_MODIFY_BANK_TAB
Definition Guild.h:74
@ GR_RIGHT_EPNOTE
Definition Guild.h:65
@ GR_RIGHT_OFFCHATLISTEN
Definition Guild.h:58
@ GR_RIGHT_GCHATLISTEN
Definition Guild.h:56
@ GR_RIGHT_SETMOTD
Definition Guild.h:64
@ GR_RIGHT_MODIFY_GUILD_INFO
Definition Guild.h:68
@ GR_RIGHT_WITHDRAW_REPAIR
Definition Guild.h:70
@ GR_RIGHT_REMOVE
Definition Guild.h:61
@ GR_RIGHT_WITHDRAW_GOLD
Definition Guild.h:71
@ GR_RIGHT_INVITE
Definition Guild.h:60
@ GR_RIGHT_DEMOTE
Definition Guild.h:63
@ GR_RIGHT_PROMOTE
Definition Guild.h:62
std::vector< GuildBankRightsAndSlots > GuildBankRightsAndSlotsVec
Definition Guild.h:319
@ GUILD_MEMBER_DATA_LEVEL
Definition Guild.h:38
@ GUILD_MEMBER_DATA_ACHIEVEMENT_POINTS
Definition Guild.h:37
@ GUILD_MEMBER_DATA_ZONEID
Definition Guild.h:36
GuildEmblemError
Definition Guild.h:220
@ ERR_GUILDEMBLEM_NOTGUILDMASTER
Definition Guild.h:224
@ ERR_GUILDEMBLEM_NOTENOUGHMONEY
Definition Guild.h:225
@ ERR_GUILDEMBLEM_SUCCESS
Definition Guild.h:221
GuildEventLogTypes
Definition Guild.h:210
@ GUILD_EVENT_LOG_LEAVE_GUILD
Definition Guild.h:216
@ GUILD_EVENT_LOG_PROMOTE_PLAYER
Definition Guild.h:213
@ GUILD_EVENT_LOG_UNINVITE_PLAYER
Definition Guild.h:215
@ GUILD_EVENT_LOG_INVITE_PLAYER
Definition Guild.h:211
@ GUILD_EVENT_LOG_DEMOTE_PLAYER
Definition Guild.h:214
@ GUILD_EVENT_LOG_JOIN_GUILD
Definition Guild.h:212
#define sGuildFinderMgr
#define sGuildMgr
Definition GuildMgr.h:53
EnchantmentSlot
Definition Item.h:149
@ MAX_ENCHANTMENT_SLOT
Definition Item.h:165
InventoryResult
Definition Item.h:27
@ EQUIP_ERR_DESTROY_NONEMPTY_BAG
Definition Item.h:59
@ EQUIP_ERR_BANK_FULL
Definition Item.h:79
@ EQUIP_ERR_WRONG_BAG_TYPE
Definition Item.h:43
@ EQUIP_ERR_DROP_BOUND_ITEM
Definition Item.h:52
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition Item.h:51
@ EQUIP_ERR_OK
Definition Item.h:28
@ EQUIP_ERR_CANT_SWAP
Definition Item.h:49
@ EQUIP_ERR_CANT_STACK
Definition Item.h:47
@ ITEM_CHANGED
Definition Item.h:192
@ ITEM_NEW
Definition Item.h:193
@ LANG_GUILD_MASTER
Definition Language.h:756
@ LANG_GUILD_VETERAN
Definition Language.h:758
@ LANG_GUILD_OFFICER
Definition Language.h:757
@ LANG_GUILD_INITIATE
Definition Language.h:760
@ LANG_GUILD_MEMBER
Definition Language.h:759
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
#define sLog
Definition Log.h:106
#define sObjectAccessor
uint32 GUID_LOPART(uint64 x)
@ HIGHGUID_GUILD
@ HIGHGUID_PLAYER
uint64 MAKE_NEW_GUID(uint32 l, uint32 e, uint32 h)
#define sObjectMgr
Definition ObjectMgr.h:1617
@ PLAYER_FLAGS_AUTO_DECLINE_GUILD
Definition Player.h:564
#define MAX_MONEY_AMOUNT
Definition Player.h:927
Skyfire::AutoPtr< PreparedResultSet, Skyfire::Mutex > PreparedQueryResult
Definition QueryResult.h:94
#define sScriptMgr
Definition ScriptMgr.h:764
Language
#define MAX_CLASSES
@ GOLD
Skyfire::AutoPtr< Transaction, Skyfire::Mutex > SQLTransaction
Definition Transaction.h:42
@ NULL_SLOT
Definition Unit.h:337
@ ITEM_FIELD_CONTAINED_IN
@ ITEM_FIELD_OWNER
@ PLAYER_FIELD_PLAYER_FLAGS
void utf8truncate(std::string &utf8str, size_t len)
Definition Util.cpp:284
void WriteGuidBytes(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:264
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void put(size_t pos, T value)
Definition ByteBuffer.h:233
void WriteGuidMask(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:248
void WriteString(std::string const &str)
Definition ByteBuffer.h:578
void append(T value)
Definition ByteBuffer.h:147
void PutBits(size_t pos, T value, uint32 bitCount)
Definition ByteBuffer.h:283
size_t wpos() const
Definition ByteBuffer.h:483
void WriteBits(T value, size_t bits)
Definition ByteBuffer.h:192
void AppendPackedTime(time_t time)
Definition ByteBuffer.h:700
bool empty() const
Definition ByteBuffer.h:610
void WriteByteSeq(uint8 b)
Definition ByteBuffer.h:227
void FlushBits()
Definition ByteBuffer.h:154
static size_t BuildChatPacket(WorldPacket &data, ChatMsg chatType, Language language, ObjectGuid senderGUID, ObjectGuid receiverGUID, std::string const &message, uint8 chatTag, std::string const &senderName="", std::string const &receiverName="", uint32 achievementId=0, bool gmMessage=false, std::string const &channelName="", std::string const &addonPrefix="")
Definition Chat.cpp:580
uint32 m_style
Definition Guild.h:284
uint32 m_backgroundColor
Definition Guild.h:288
void LoadFromDB(Field *fields)
Definition Guild.cpp:781
uint32 m_borderColor
Definition Guild.h:287
void ReadPacket(WorldPacket &recv)
Definition Guild.cpp:776
uint32 m_borderStyle
Definition Guild.h:286
void WritePacket(WorldPacket &data) const
Definition Guild.cpp:790
uint32 m_color
Definition Guild.h:285
void SaveToDB(uint32 guildId) const
Definition Guild.cpp:799
Definition Field.h:16
uint8 GetUInt8() const
Definition Field.h:26
std::string GetString() const
Definition Field.h:228
uint64 GetUInt64() const
Definition Field.h:141
uint32 GetUInt32() const
Definition Field.h:105
Definition Group.h:147
Definition Guild.h:470
uint64 m_itemOrMoney
Definition Guild.h:500
GuildBankEventLogTypes m_eventType
Definition Guild.h:497
void WritePacket(WorldPacket &data, ByteBuffer &content) const
Definition Guild.cpp:249
void SaveToDB(SQLTransaction &trans) const
Definition Guild.cpp:225
static bool IsMoneyEvent(GuildBankEventLogTypes eventType)
Definition Guild.h:472
uint8 m_destTabId
Definition Guild.h:502
uint32 m_playerGuid
Definition Guild.h:499
uint8 m_bankTabId
Definition Guild.h:498
uint16 m_itemStackCount
Definition Guild.h:501
void LogAction(MoveItemData *pFrom) const
Definition Guild.cpp:1001
bool _ReserveSpace(uint8 slotId, Item *pItem, Item *pItemDest, uint32 &count)
Definition Guild.cpp:1047
Item * StoreItem(SQLTransaction &trans, Item *pItem)
Definition Guild.cpp:966
bool HasStoreRights(MoveItemData *pOther) const
Definition Guild.cpp:924
void CanStoreItemInTab(Item *pItem, uint8 skipSlotId, bool merge, uint32 &count)
Definition Guild.cpp:1070
void LogBankEvent(SQLTransaction &trans, MoveItemData *pFrom, uint32 count) const
Definition Guild.cpp:988
Item * _StoreItem(SQLTransaction &trans, BankTab *pTab, Item *pItem, ItemPosCount &pos, bool clone) const
Definition Guild.cpp:1014
InventoryResult CanStore(Item *pItem, bool swap)
Definition Guild.cpp:1090
bool HasWithdrawRights(MoveItemData *pOther) const
Definition Guild.cpp:933
void RemoveItem(SQLTransaction &trans, MoveItemData *pOther, uint32 splitedAmount)
Definition Guild.cpp:947
void LoadFromDB(Field *fields)
Definition Guild.cpp:463
Item * m_items[GUILD_BANK_MAX_SLOTS]
Definition Guild.h:647
std::string m_icon
Definition Guild.h:649
void Delete(SQLTransaction &trans, bool removeItemsFromDB=false)
Definition Guild.cpp:509
void SetInfo(std::string const &name, std::string const &icon)
Definition Guild.cpp:522
std::string m_name
Definition Guild.h:648
Item * GetItem(uint8 slotId) const
Definition Guild.h:640
bool LoadItemFromDB(Field *fields)
Definition Guild.cpp:470
bool SetItem(SQLTransaction &trans, uint8 slotId, Item *item)
Definition Guild.cpp:555
uint8 m_tabId
Definition Guild.h:645
uint32 m_guildId
Definition Guild.h:644
void SetText(std::string const &text)
Definition Guild.cpp:538
void SendText(Guild const *guild, WorldSession *session) const
Definition Guild.cpp:585
std::string m_text
Definition Guild.h:650
Definition Guild.h:448
GuildEventLogTypes m_eventType
Definition Guild.h:462
void SaveToDB(SQLTransaction &trans) const
Definition Guild.cpp:168
void WritePacket(WorldPacket &data, ByteBuffer &content) const
Definition Guild.cpp:187
uint8 m_newRank
Definition Guild.h:465
uint32 m_playerGuid1
Definition Guild.h:463
uint32 m_playerGuid2
Definition Guild.h:464
Definition Guild.h:428
uint32 GetGUID() const
Definition Guild.h:434
uint64 GetTimestamp() const
Definition Guild.h:435
uint32 m_guildId
Definition Guild.h:441
uint32 m_guid
Definition Guild.h:442
uint64 m_timestamp
Definition Guild.h:443
virtual void SaveToDB(SQLTransaction &trans) const =0
bool CanInsert() const
Definition Guild.h:550
void WritePacket(WorldPacket &data) const
Definition Guild.cpp:145
uint8 GetSize() const
Definition Guild.h:548
uint32 m_maxRecords
Definition Guild.h:562
uint32 m_nextGUID
Definition Guild.h:563
void AddEvent(SQLTransaction &trans, LogEntry *entry)
Definition Guild.cpp:129
GuildLog m_log
Definition Guild.h:561
void LoadEvent(LogEntry *entry)
Definition Guild.cpp:120
uint32 GetNextGUID()
Definition Guild.cpp:156
std::string GetOfficerNote() const
Definition Guild.h:375
std::string const & GetName() const
Definition Guild.h:370
uint64 GetGUID() const
Definition Guild.h:368
uint32 GetVirtualRealm() const
Definition Guild.h:369
uint32 m_guildId
Definition Guild.h:402
bool IsRankNotLower(uint8 rankId) const
Definition Guild.h:392
bool IsRank(uint8 rankId) const
Definition Guild.h:391
uint32 m_weekReputation
Definition Guild.h:423
bool IsSamePlayer(uint64 guid) const
Definition Guild.h:393
void ChangeRank(uint8 newRank)
Definition Guild.cpp:656
uint8 GetClass() const
Definition Guild.h:376
uint32 GetTotalReputation() const
Definition Guild.h:383
uint8 GetFlags() const
Definition Guild.h:378
std::string m_name
Definition Guild.h:406
int32 GetBankWithdrawValue(uint8 tabId) const
Definition Guild.cpp:766
std::string GetPublicNote() const
Definition Guild.h:374
uint32 m_memberVRealm
Definition Guild.h:405
void SetOfficerNote(std::string const &officerNote)
Definition Guild.cpp:643
uint64 m_logoutTime
Definition Guild.h:411
uint8 m_class
Definition Guild.h:409
uint8 GetLevel() const
Definition Guild.h:377
uint32 m_achievementPoints
Definition Guild.h:419
uint64 GetWeekActivity() const
Definition Guild.h:382
bool LoadFromDB(Field *fields)
Definition Guild.cpp:684
uint64 m_weekActivity
Definition Guild.h:421
bool CheckStats() const
Definition Guild.cpp:717
int32 m_bankWithdraw[GUILD_BANK_MAX_TABS+1]
Definition Guild.h:418
void SaveToDB(SQLTransaction &trans) const
Definition Guild.cpp:670
uint64 GetTotalActivity() const
Definition Guild.h:381
void SetPublicNote(std::string const &publicNote)
Definition Guild.cpp:630
void AddFlag(uint8 var)
Definition Guild.h:361
uint32 m_totalReputation
Definition Guild.h:422
uint64 m_totalActivity
Definition Guild.h:420
uint32 GetZoneId() const
Definition Guild.h:379
void ResetFlags()
Definition Guild.h:363
uint32 m_zoneId
Definition Guild.h:407
uint8 m_rankId
Definition Guild.h:414
uint8 GetRankId() const
Definition Guild.h:372
uint32 m_accountId
Definition Guild.h:412
uint8 m_level
Definition Guild.h:408
std::string m_officerNote
Definition Guild.h:416
std::string m_publicNote
Definition Guild.h:415
uint32 GetWeekReputation() const
Definition Guild.h:384
uint32 GetAchievementPoints() const
Definition Guild.h:380
bool IsOnline() const
Definition Guild.h:386
void ResetValues(bool weekly=false)
Definition Guild.cpp:751
Player * FindPlayer() const
Definition Guild.h:399
uint64 m_guid
Definition Guild.h:404
uint64 GetLogoutTime() const
Definition Guild.h:373
void SetStats(Player *player)
Definition Guild.cpp:608
void UpdateBankWithdrawValue(SQLTransaction &trans, uint8 tabId, uint32 amount)
Definition Guild.cpp:736
Item * m_pClonedItem
Definition Guild.h:697
MoveItemData(Guild *guild, Player *player, uint8 container, uint8 slotId)
Definition Guild.h:657
ItemPosCountVec m_vec
Definition Guild.h:698
Player * m_pPlayer
Definition Guild.h:693
virtual void LogAction(MoveItemData *pFrom) const
Definition Guild.cpp:843
virtual void RemoveItem(SQLTransaction &trans, MoveItemData *pOther, uint32 splitedAmount=0)=0
Item * GetItem(bool isCloned=false) const
Definition Guild.h:685
Guild * m_pGuild
Definition Guild.h:692
uint8 GetSlotId() const
Definition Guild.h:687
uint8 GetContainer() const
Definition Guild.h:686
virtual bool CheckItem(uint32 &splitedAmount)
Definition Guild.cpp:812
virtual void LogBankEvent(SQLTransaction &trans, MoveItemData *pFrom, uint32 count) const =0
virtual bool HasWithdrawRights(MoveItemData *) const
Definition Guild.h:669
virtual bool HasStoreRights(MoveItemData *) const
Definition Guild.h:667
void CopySlots(SlotIds &ids) const
Definition Guild.cpp:852
virtual Item * StoreItem(SQLTransaction &trans, Item *pItem)=0
virtual bool IsBank() const =0
bool CloneItem(uint32 count)
Definition Guild.cpp:831
virtual bool InitItem()=0
bool CanStore(Item *pItem, bool swap, bool sendError)
Definition Guild.cpp:822
Definition Guild.h:507
uint32 GetFlags() const
Definition Guild.h:520
uint64 GetPlayerGuid() const
Definition Guild.h:518
GuildNews GetType() const
Definition Guild.h:517
void WritePacket(WorldPacket &data, ByteBuffer &content) const
Definition Guild.cpp:315
void SetSticky(bool sticky)
Definition Guild.h:521
void SaveToDB(SQLTransaction &trans) const
Definition Guild.cpp:301
uint32 GetValue() const
Definition Guild.h:519
void RemoveItem(SQLTransaction &trans, MoveItemData *pOther, uint32 splitedAmount=0)
Definition Guild.cpp:880
InventoryResult CanStore(Item *pItem, bool swap)
Definition Guild.cpp:912
Item * StoreItem(SQLTransaction &trans, Item *pItem)
Definition Guild.cpp:896
void LogBankEvent(SQLTransaction &trans, MoveItemData *pFrom, uint32 count) const
Definition Guild.cpp:904
uint32 m_rights
Definition Guild.h:607
uint8 GetId() const
Definition Guild.h:578
void SetBankMoneyPerDay(uint32 money)
Definition Guild.cpp:425
void CreateMissingTabsIfNeeded(uint8 ranks, SQLTransaction &trans, bool logOnCreate=false)
Definition Guild.cpp:369
std::string const & GetName() const
Definition Guild.h:580
uint32 GetRights() const
Definition Guild.h:583
int8 GetBankTabRights(uint8 tabId) const
Definition Guild.h:590
uint32 m_bankMoneyPerDay
Definition Guild.h:608
int32 GetBankTabSlotsPerDay(uint8 tabId) const
Definition Guild.h:595
void SetName(std::string const &name)
Definition Guild.cpp:394
uint32 m_guildId
Definition Guild.h:604
void SetRights(uint32 rights)
Definition Guild.cpp:408
void SaveToDB(SQLTransaction &trans) const
Definition Guild.cpp:358
std::string m_name
Definition Guild.h:606
void SetBankTabSlotsAndRights(GuildBankRightsAndSlots rightsAndSlots, bool saveToDB)
Definition Guild.cpp:442
uint8 m_rankId
Definition Guild.h:605
int32 GetBankMoneyPerDay() const
Definition Guild.h:586
GuildBankRightsAndSlots m_bankTabRightsAndSlots[GUILD_BANK_MAX_TABS]
Definition Guild.h:609
void LoadFromDB(Field *fields)
Definition Guild.cpp:348
int32 GetSlots() const
Definition Guild.h:310
void SetGuildMasterValues()
Definition Guild.h:299
int8 GetRights() const
Definition Guild.h:311
int8 GetTabId() const
Definition Guild.h:309
void SetTabId(uint8 _tabId)
Definition Guild.h:305
std::string _GetRankName(uint8 rankId) const
Definition Guild.cpp:3179
void SendGuildReputationWeeklyCap(WorldSession *session, uint32 reputation) const
Definition Guild.cpp:3756
int8 _GetRankBankTabRights(uint8 rankId, uint8 tabId) const
Definition Guild.cpp:3208
void SwapItemsWithInventory(Player *player, bool toChar, uint8 tabId, uint8 slotId, uint8 playerBag, uint8 playerSlotId, uint32 splitedAmount)
Definition Guild.cpp:3005
LogHolder * m_eventLog
Definition Guild.h:887
void HandleAddNewRank(WorldSession *session, std::string const &name)
Definition Guild.cpp:2170
void HandleRemoveMember(WorldSession *session, uint64 guid)
Definition Guild.cpp:2053
int32 _GetMemberRemainingSlots(Member const *member, uint8 tabId) const
Definition Guild.cpp:3215
void _SetRankBankTabRightsAndSlots(uint8 rankId, GuildBankRightsAndSlots rightsAndSlots, bool saveToDB=true)
Definition Guild.cpp:3170
uint64 m_leaderGuid
Definition Guild.h:873
void _BroadcastEvent(GuildEvents guildEvent, uint64 guid, const char *param1=NULL, const char *param2=NULL, const char *param3=NULL) const
Definition Guild.cpp:3520
bool Create(Player *pLeader, std::string const &name)
Definition Guild.cpp:1178
uint64 m_bankMoney
Definition Guild.h:880
int32 _GetMemberRemainingMoney(Member const *member) const
Definition Guild.cpp:3232
int32 _GetRankBankTabSlotsPerDay(uint8 rankId, uint8 tabId) const
Definition Guild.cpp:3200
void _SetRankBankMoneyPerDay(uint8 rankId, uint32 moneyPerDay)
Definition Guild.cpp:3164
uint32 m_id
Definition Guild.h:871
void HandleSetBankTabNote(WorldSession *session, uint32 tabId, std::string const &note)
Definition Guild.cpp:3835
void LoadBankRightFromDB(Field *fields)
Definition Guild.cpp:2555
bool _CreateRank(std::string const &name, uint32 rights)
Definition Guild.cpp:3078
uint32 _GetRankRights(uint8 rankId) const
Definition Guild.cpp:3186
static void SendCommandResult(WorldSession *session, GuildCommandType type, GuildCommandError errCode, std::string const &param="")
Definition Guild.cpp:87
void SwapItems(Player *player, uint8 tabId, uint8 slotId, uint8 destTabId, uint8 destSlotId, uint32 splitedAmount)
Definition Guild.cpp:2991
void SetBankTabText(uint8 tabId, std::string const &text)
Definition Guild.cpp:3019
~Guild()
Definition Guild.cpp:1153
uint64 GetExperience() const
Definition Guild.h:859
void _SendRemovePlayerFromGuild(ObjectGuid removedGuid, std::string const &removedName, Player const *remover) const
Definition Guild.cpp:1665
Guild()
Definition Guild.cpp:1137
AchievementMgr< Guild > m_achievementMgr
Definition Guild.h:890
bool LoadMemberFromDB(Field *fields)
Definition Guild.cpp:2541
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit *unit, Player *player)
Definition Guild.cpp:3803
void OnPlayerStatusChange(Player *player, uint32 flag, bool state)
Definition Guild.cpp:1331
void HandleLeaveMember(WorldSession *session)
Definition Guild.cpp:2019
void HandleRemoveRank(WorldSession *session, uint8 rankId)
Definition Guild.cpp:2182
void SendPermissions(WorldSession *session) const
Definition Guild.cpp:2409
void UpdateMemberData(Player *player, uint8 dataid, uint32 value)
Definition Guild.cpp:1308
bool ChangeMemberRank(uint64 guid, uint8 newRank)
Definition Guild.cpp:2973
void HandleQuery(WorldSession *session)
Definition Guild.cpp:1452
bool HasAchieved(uint32 achievementId) const
Definition Guild.cpp:3798
uint32 m_accountsNumber
Definition Guild.h:879
uint8 GetLevel() const
Definition Guild.h:857
void HandleSetInfo(WorldSession *session, std::string const &info)
Definition Guild.cpp:1590
time_t m_createdDate
Definition Guild.h:876
void GiveXP(uint32 xp, Player *source)
Definition Guild.cpp:3688
void BroadcastPacket(WorldPacket *packet) const
Definition Guild.cpp:2766
void SendEventLog(WorldSession *session) const
Definition Guild.cpp:2325
void _DeleteMemberFromDB(uint32 lowguid) const
Definition Guild.h:935
void HandleSetRankInfo(WorldSession *session, uint8 rankId, std::string const &name, uint32 rights, uint32 moneyPerDay, GuildBankRightsAndSlotsVec const &rightsAndSlots)
Definition Guild.cpp:1833
void SendGuildXP(WorldSession *session=NULL) const
Definition Guild.cpp:3744
BankTabs m_bankTabs
Definition Guild.h:884
uint8 _GetPurchasedTabsSize() const
Definition Guild.h:910
bool LoadBankItemFromDB(Field *fields)
Definition Guild.cpp:2644
void SendGuildRanksUpdate(uint64 setterGuid, uint64 targetGuid, uint32 rank)
Definition Guild.cpp:3634
void LoadGuildNewsLogFromDB(Field *fields)
Definition Guild.cpp:2620
bool LoadFromDB(Field *fields)
Definition Guild.cpp:2506
uint32 GetId() const
Definition Guild.h:757
uint64 GetLeaderGUID() const
Definition Guild.h:759
void SendLoginInfo(WorldSession *session)
Definition Guild.cpp:2449
std::string m_name
Definition Guild.h:872
void SendBankList(WorldSession *session, uint8 tabId, bool withContent, bool withTabInfo) const
Definition Guild.cpp:3544
bool _MemberHasTabRights(uint64 guid, uint8 tabId, uint32 rights) const
Definition Guild.cpp:3261
void SaveToDB()
Definition Guild.cpp:1292
void HandleInviteMember(WorldSession *session, std::string const &name)
Definition Guild.cpp:1893
std::string const & GetName() const
Definition Guild.h:760
uint8 _level
Definition Guild.h:892
int32 _GetRankBankMoneyPerDay(uint8 rankId) const
Definition Guild.cpp:3193
bool HandleMemberWithdrawMoney(WorldSession *session, uint64 amount, bool repair=false)
Definition Guild.cpp:2234
void _CreateNewBankTab()
Definition Guild.cpp:3037
void ResetTimes(bool weekly)
Definition Guild.cpp:3766
LogHolder * m_bankEventLog[GUILD_BANK_MAX_TABS+1]
Definition Guild.h:888
uint64 _experience
Definition Guild.h:893
void _UpdateAccountsNumber()
Definition Guild.cpp:3098
void BroadcastPacketToRank(WorldPacket *packet, uint8 rankId) const
Definition Guild.cpp:2758
void _LogEvent(GuildEventLogTypes eventType, uint32 playerGuid1, uint32 playerGuid2=0, uint8 newRank=0)
Definition Guild.cpp:3274
void HandleSetNewGuildMaster(WorldSession *session, std::string const &name)
Definition Guild.cpp:1703
bool LoadEventLogFromDB(Field *fields)
Definition Guild.cpp:2563
void HandleMemberLogout(WorldSession *session)
Definition Guild.cpp:2280
void BroadcastAddonToGuild(WorldSession *session, bool officerOnly, std::string const &msg, std::string const &prefix) const
Definition Guild.cpp:2743
void HandleMemberDepositMoney(WorldSession *session, uint64 amount, bool cashFlow=false)
Definition Guild.cpp:2204
void HandleSetBankTabInfo(WorldSession *session, uint8 tabId, std::string const &name, std::string const &icon)
Definition Guild.cpp:1749
void _UpdateMemberWithdrawSlots(SQLTransaction &trans, uint64 guid, uint8 tabId)
Definition Guild.cpp:3250
void SendGuildRankInfo(WorldSession *session) const
Definition Guild.cpp:1534
bool _IsLeader(Player *player) const
Definition Guild.cpp:3111
bool LoadBankEventLogFromDB(Field *fields)
Definition Guild.cpp:2580
void HandleSetMemberNote(WorldSession *session, std::string const &note, uint64 guid, bool isPublic)
Definition Guild.cpp:1780
std::string m_motd
Definition Guild.h:874
Ranks m_ranks
Definition Guild.h:882
void HandleDisband(WorldSession *session)
Definition Guild.cpp:2294
bool AddMember(uint64 guid, uint8 rankId=GUILD_RANK_NONE)
Definition Guild.cpp:2828
static void SendSaveEmblemResult(WorldSession *session, GuildEmblemError errCode)
Definition Guild.cpp:102
std::list< LogEntry * > GuildLog
Definition Guild.h:540
void SendBankTabText(WorldSession *session, uint8 tabId) const
Definition Guild.cpp:2403
uint8 _GetRanksSize() const
Definition Guild.h:897
BankTab * GetBankTab(uint8 tabId)
Definition Guild.h:911
void HandleReplaceGuildMaster(WorldSession *session)
Definition Guild.cpp:1722
void _CreateLogHolders()
Definition Guild.cpp:3029
const Member * GetMember(uint64 guid) const
Definition Guild.h:914
Members m_members
Definition Guild.h:883
const RankInfo * GetRankInfo(uint8 rankId) const
Definition Guild.h:898
void Disband()
Definition Guild.cpp:1239
void SendNewsUpdate(WorldSession *session)
Definition Guild.cpp:2333
uint64 GetGUID() const
Definition Guild.h:758
void HandleRoster(WorldSession *session=NULL)
Definition Guild.cpp:1366
bool _DoItemsMove(MoveItemData *pSrc, MoveItemData *pDest, bool sendError, uint32 splitedAmount=0)
Definition Guild.cpp:3379
void AddGuildNews(uint8 type, uint64 guid, uint32 flags, uint32 value)
Definition Guild.cpp:3781
void _SendBankContentUpdate(MoveItemData *pSrc, MoveItemData *pDest) const
Definition Guild.cpp:3423
void _SendSetNewGuildMaster(Member const *guildMaster, Member const *newGuildMaster, bool replace) const
Definition Guild.cpp:1629
uint64 _todayExperience
Definition Guild.h:894
void HandleUpdateMemberRank(WorldSession *session, uint64 guid, bool demote)
Definition Guild.cpp:2084
EmblemInfo m_emblemInfo
Definition Guild.h:878
bool SetName(std::string const &name)
Definition Guild.cpp:1341
uint64 GetTodayExperience() const
Definition Guild.h:860
void HandleSetMOTD(WorldSession *session, std::string const &motd)
Definition Guild.cpp:1567
void HandleGuildPartyRequest(WorldSession *session)
Definition Guild.cpp:2305
void HandleNewsSetSticky(WorldSession *session, uint32 newsId, bool sticky)
Definition Guild.cpp:3808
void HandleAcceptMember(WorldSession *session)
Definition Guild.cpp:2009
void MassInviteToEvent(WorldSession *session, uint32 minLevel, uint32 maxLevel, uint32 minRank)
Definition Guild.cpp:2773
std::string m_info
Definition Guild.h:875
Item * _GetItem(uint8 tabId, uint8 slotId) const
Definition Guild.cpp:3305
void DeleteMember(uint64 guid, bool isDisbanding=false, bool isKicked=false, bool canDeleteGuild=false)
Definition Guild.cpp:2908
void SendMoneyInfo(WorldSession *session) const
Definition Guild.cpp:2436
void SendBankLog(WorldSession *session, uint8 tabId) const
Definition Guild.cpp:2386
void _LogBankEvent(SQLTransaction &trans, GuildBankEventLogTypes eventType, uint8 tabId, uint32 playerGuid, uint32 itemOrMoney, uint16 itemStackCount=0, uint8 destTabId=0)
Definition Guild.cpp:3284
void HandleSetMemberRank(WorldSession *session, uint64 guid, uint64 setterGuid, uint32 rank)
Definition Guild.cpp:2137
void HandleSetEmblem(WorldSession *session, const EmblemInfo &emblemInfo)
Definition Guild.cpp:1609
bool _ModifyBankMoney(SQLTransaction &trans, uint64 amount, bool add)
Definition Guild.cpp:3131
void LoadBankTabFromDB(Field *fields)
Definition Guild.cpp:2635
bool IsMember(uint64 guid) const
Definition Guild.cpp:2984
uint8 _GetLowestRankId() const
Definition Guild.h:908
void _MoveItems(MoveItemData *pSrc, MoveItemData *pDest, uint32 splitedAmount)
Definition Guild.cpp:3318
bool Validate()
Definition Guild.cpp:2657
void HandleBuyBankTab(WorldSession *session, uint8 tabId)
Definition Guild.cpp:1855
void _CreateDefaultGuildRanks(LocaleConstant loc)
Definition Guild.cpp:3061
void _DeleteBankItems(SQLTransaction &trans, bool removeItemsFromDB=false)
Definition Guild.cpp:3120
void _RemoveItem(SQLTransaction &trans, uint8 tabId, uint8 slotId)
Definition Guild.cpp:3312
bool _HasRankRight(Player const *player, uint32 right) const
Definition Guild.h:900
LogHolder * m_newsLog
Definition Guild.h:889
void BroadcastToGuild(WorldSession *session, bool officerOnly, std::string const &msg, Language language=Language::LANG_UNIVERSAL) const
Definition Guild.cpp:2729
void LoadRankFromDB(Field *fields)
Definition Guild.cpp:2532
void _SetLeaderGUID(Member *pLeader)
Definition Guild.cpp:3150
Definition Item.h:202
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition Item.h:287
int32 GetSpellCharges(uint8 index=0) const
Definition Item.h:298
Item * CloneItem(uint32 count, Player const *player=NULL) const
Definition Item.cpp:1039
virtual void SaveToDB(SQLTransaction &trans)
Definition Item.cpp:305
void SetCount(uint32 value)
Definition Item.h:259
int32 GetItemRandomPropertyId() const
Definition Item.h:278
ItemTemplate const * GetTemplate() const
Definition Item.cpp:528
bool IsSoulBound() const
Definition Item.h:218
uint32 GetItemSuffixFactor() const
Definition Item.h:279
virtual bool LoadFromDB(uint32 guid, uint64 owner_guid, Field *fields, uint32 entry)
Definition Item.cpp:405
void FSetState(ItemUpdateState state)
Definition Item.h:311
uint32 GetCount() const
Definition Item.h:258
uint32 GetMaxStackCount() const
Definition Item.h:260
static void DeleteFromDB(SQLTransaction &trans, uint32 itemGuid)
Definition Item.cpp:499
virtual uint32 GetOwnerGuildId(uint32=TEAM_OTHER) const
Definition Map.h:451
static Player * FindPlayer(uint64)
uint64 GetGUID() const
Definition Object.h:119
uint32 GetGUIDLow() const
Definition Object.h:120
uint32 GetEntry() const
Definition Object.h:125
virtual void AddToWorld()
Definition Object.cpp:148
bool HasFlag(uint16 index, uint32 flag) const
Definition Object.cpp:1309
virtual void RemoveFromWorld()
Definition Object.cpp:161
void SetUInt64Value(uint16 index, uint64 value)
Definition Object.cpp:1079
static bool IsValidCharterName(std::string const &name)
static uint32 GetGuildIdFromDB(uint64 guid)
Definition Player.cpp:8020
uint32 GetTeam() const
Definition Player.h:2527
void SetInGuild(uint32 guildId)
Definition Player.cpp:8009
bool ModifyMoney(int64 amount, bool sendError=true)
Definition Player.cpp:18342
void SetGuildIdInvited(uint32 GuildId)
Definition Player.h:2287
uint32 GetGuildId() const
Definition Player.h:2291
static uint32 GetLevelFromDB(uint64 guid)
Definition Player.cpp:8086
WorldSession * GetSession() const
Definition Player.h:2417
int GetGuildIdInvited() const
Definition Player.h:2298
static uint32 GetZoneIdFromDB(uint64 guid)
Definition Player.cpp:8040
void SendDeclineGuildInvitation(std::string declinerName, bool autoDecline=false)
Definition Player.cpp:23874
Group * GetGroup()
Definition Player.h:2972
void removeSpell(uint32 spell_id, bool disabled=false, bool learn_low_rank=true)
Definition Player.cpp:4073
uint32 GetAchievementPoints() const
Definition Player.cpp:21008
void learnSpell(uint32 spell_id, bool dependent)
Definition Player.cpp:4021
std::string GetGuildName()
Definition Player.cpp:21986
void SetRank(uint8 rankId)
Definition Player.h:2271
void SetLastGuildInviterGUID(uint64 guid)
Definition Player.h:2299
static void RemovePetitionsAndSigns(uint64 guid, uint32 type)
Definition Player.cpp:16445
PlayerSocial * GetSocial()
Definition Player.h:1346
void SetGuildLevel(uint32 level)
Definition Player.h:2279
void SaveGoldToDB(SQLTransaction &trans)
Definition Player.cpp:14616
bool HasEnoughMoney(uint64 amount) const
Definition Player.h:1950
bool HasIgnore(uint32 ignore_guid)
void setString(const uint8 index, const std::string &value)
void setUInt16(const uint8 index, const uint16 value)
void setUInt64(const uint8 index, const uint64 value)
void setUInt32(const uint8 index, const uint32 value)
void setUInt8(const uint8 index, const uint8 value)
Definition Unit.h:1367
uint32 getVirtualRealm() const
Definition Unit.h:1555
uint8 getClass() const
Definition Unit.h:1543
uint8 getLevel() const
Definition Unit.h:1528
Map * GetMap() const
Definition Object.h:740
std::string const & GetName() const
Definition Object.h:664
uint32 GetZoneId() const
Definition Object.cpp:1597
void Initialize(Opcodes opcode, size_t newres=200)
Definition WorldPacket.h:31
Player session in the World.
uint32 GetGuidLow() const
Get player guid if available. Use for logging purposes only.
LocaleConstant GetSessionDbLocaleIndex() const
std::string GetPlayerInfo() const
Player * GetPlayer() const
bool HasPermission(uint32 permissionId)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
uint32 GetAccountId() const
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
Definition Main.cpp:41
@ SMSG_GUILD_SET_GUILD_MASTER
Definition Opcodes.h:713
@ SMSG_GUILD_ROSTER
Definition Opcodes.h:712
@ SMSG_GUILD_RANKS_UPDATE
Definition Opcodes.h:708
@ SMSG_GUILD_QUERY_RESPONSE
Definition Opcodes.h:706
@ SMSG_GUILD_BANK_LIST
Definition Opcodes.h:682
@ SMSG_GUILD_EVENT_BANK_MONEY_CHANGED
Definition Opcodes.h:692
@ SMSG_GUILD_EVENT_BANK_TAB_ADDED
Definition Opcodes.h:693
@ SMSG_GUILD_PARTY_STATE_RESPONSE
Definition Opcodes.h:704
@ SMSG_GUILD_NEWS_UPDATE
Definition Opcodes.h:703
@ MSG_SAVE_GUILD_EMBLEM
Definition Opcodes.h:501
@ SMSG_GUILD_RANKS
Definition Opcodes.h:707
@ SMSG_GUILD_EVENT_LOG_QUERY_RESULT
Definition Opcodes.h:696
@ SMSG_CALENDAR_EVENT_INITIAL_INVITE
Definition Opcodes.h:576
@ SMSG_GUILD_EVENT
Definition Opcodes.h:691
@ SMSG_GUILD_REPUTATION_WEEKLY_CAP
Definition Opcodes.h:710
@ SMSG_GUILD_RENAMED
Definition Opcodes.h:709
@ SMSG_GUILD_BANK_LOG_QUERY_RESULT
Definition Opcodes.h:683
@ SMSG_GUILD_MEMBER_UPDATE_NOTE
Definition Opcodes.h:702
@ SMSG_GUILD_XP
Definition Opcodes.h:714
@ SMSG_GUILD_COMMAND_RESULT
Definition Opcodes.h:687
@ SMSG_GUILD_PERMISSIONS_QUERY_RESULTS
Definition Opcodes.h:705
@ SMSG_GUILD_XP_GAIN
Definition Opcodes.h:715
@ SMSG_GUILD_INVITE
Definition Opcodes.h:698
@ SMSG_GUILD_BANK_QUERY_TEXT_RESULT
Definition Opcodes.h:685
@ SMSG_GUILD_MEMBER_DAILY_RESET
Definition Opcodes.h:701
@ SMSG_GUILD_EVENT_BANK_TAB_TEXT_CHANGED
Definition Opcodes.h:695
@ SMSG_GUILD_BANK_MONEY_WITHDRAWN
Definition Opcodes.h:684
@ SMSG_GUILD_EVENT_BANK_TAB_MODIFIED
Definition Opcodes.h:694
@ SMSG_GUILD_EVENT_PLAYER_LEFT
Definition Opcodes.h:697
#define sWorld
Definition World.h:910
uint32 realmID
Id of the realm.
Definition Main.cpp:73
@ CONFIG_GUILD_WEEKLY_REP_CAP
Definition World.h:349
@ CONFIG_GUILD_EVENT_LOG_COUNT
Definition World.h:316
@ CONFIG_GUILD_NEWS_LOG_COUNT
Definition World.h:315
@ CONFIG_GUILD_BANK_EVENT_LOG_COUNT
Definition World.h:317
@ CONFIG_GUILD_UNDELETABLE_LEVEL
Definition World.h:347
@ CONFIG_GUILD_DAILY_XP_CAP
Definition World.h:348
@ CONFIG_GUILD_MAX_LEVEL
Definition World.h:346
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD
Definition World.h:99
@ CONFIG_GUILD_LEVELING_ENABLED
Definition World.h:161
@ RBAC_PERM_LOG_GM_TRADE
Definition RBAC.h:51
uint32 count
Definition Player.h:775
bool isContainedIn(std::vector< ItemPosCount > const &vec) const
Definition Player.cpp:20254
uint16 pos
Definition Player.h:774
std::string Name1