/*
EQ2Emulator: Everquest II Server Emulator
Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net)
This file is part of EQ2Emulator.
EQ2Emulator is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
EQ2Emulator is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with EQ2Emulator. If not, see .
*/
#include
#include
#include
#include "Guild.h"
#include "../Player.h"
#include "../client.h"
#include "../World.h"
#include "../zoneserver.h"
#include "../WorldDatabase.h"
#include "../../common/Log.h"
extern ConfigReader configReader;
extern ZoneList zone_list;
extern WorldDatabase database;
extern World world;
/***************************************************************************************************************************************************
* GUILD
***************************************************************************************************************************************************/
Guild::Guild() {
id = 0;
memset(name, 0, sizeof(name));
level = 1;
formed_date = 0;
memset(motd, 0, sizeof(motd));
exp_current = 111;
exp_to_next_level = 2521;
recruiting_min_level = 1;
recruiting_play_style = GUILD_RECRUITING_PLAYSTYLE_NONE;
recruiting_flags.Put(GUILD_RECRUITING_FLAG_TRAINING, 0);
recruiting_flags.Put(GUILD_RECRUITING_FLAG_FIGHTERS, 0);
recruiting_flags.Put(GUILD_RECRUITING_FLAG_PRIESTS, 0);
recruiting_flags.Put(GUILD_RECRUITING_FLAG_SCOUTS, 0);
recruiting_flags.Put(GUILD_RECRUITING_FLAG_MAGES, 0);
recruiting_flags.Put(GUILD_RECRUITING_FLAG_TRADESKILLERS, 0);
recruiting_desc_tags.Put(0, GUILD_RECRUITING_DESC_TAG_NONE);
recruiting_desc_tags.Put(1, GUILD_RECRUITING_DESC_TAG_NONE);
recruiting_desc_tags.Put(2, GUILD_RECRUITING_DESC_TAG_NONE);
recruiting_desc_tags.Put(3, GUILD_RECRUITING_DESC_TAG_NONE);
banks[0].name = "Bank 1";
banks[1].name = "Bank 2";
banks[2].name = "Bank 3";
banks[3].name = "Bank 4";
save_needed = false;
member_save_needed = false;
events_save_needed = false;
ranks_save_needed = false;
event_filters_save_needed = false;
points_history_save_needed = false;
recruiting_save_needed = false;
mMembers.SetName("Guild::members");
}
Guild::~Guild() {
map::iterator guild_member_itr;
mMembers.writelock(__FUNCTION__, __LINE__);
for (guild_member_itr = members.begin(); guild_member_itr != members.end(); guild_member_itr++) {
deque::iterator point_history_itr;
for (point_history_itr = guild_member_itr->second->point_history.begin(); point_history_itr != guild_member_itr->second->point_history.end(); point_history_itr++)
safe_delete(*point_history_itr);
safe_delete_array(guild_member_itr->second->recruiter_picture_data);
safe_delete(guild_member_itr->second);
}
mMembers.releasewritelock(__FUNCTION__, __LINE__);
deque::iterator guild_events_itr;
for (guild_events_itr = guild_events.begin(); guild_events_itr != guild_events.end(); guild_events_itr++)
safe_delete(*guild_events_itr);
MutexMap*>::iterator permissions_itr = permissions.begin();
while (permissions_itr.Next())
safe_delete(permissions_itr.second);
MutexMap*>::iterator filter_itr = event_filters.begin();
while (filter_itr.Next())
safe_delete(filter_itr.second);
for (int32 i = 0; i < 4; i++) {
deque::iterator bank_event_itr;
for (bank_event_itr = banks[i].events.begin(); bank_event_itr != banks[i].events.end(); bank_event_itr++)
safe_delete(*bank_event_itr);
}
}
void Guild::SetName(const char* name, bool send_packet) {
assert(name);
strncpy(this->name, name, sizeof(this->name));
if (send_packet) {
LogWrite(GUILD__DEBUG, 1, "Guilds", "Setting Guild Name to '%s'...", name);
SendGuildUpdate();
save_needed = true;
}
}
void Guild::SetLevel(int8 level, bool send_packet) {
this->level = level;
if (send_packet) {
LogWrite(GUILD__DEBUG, 1, "Guilds", "Setting Guild Level to %i...", level);
SendGuildUpdate();
save_needed = true;
}
}
void Guild::SetMOTD(const char *motd, bool send_packet) {
assert(motd);
strncpy(this->motd, motd, sizeof(this->motd));
if (send_packet) {
LogWrite(GUILD__DEBUG, 1, "Guilds", "Setting Guild MOTD text:\n'%s'", motd);
SendGuildUpdate();
save_needed = true;
}
}
void Guild::SetEXPCurrent(int64 exp, bool send_packet) {
exp_current = exp;
if (send_packet) {
LogWrite(GUILD__DEBUG, 1, "Guilds", "Setting Guild Current XP to %u", exp);
SendGuildUpdate();
save_needed = true;
}
}
void Guild::AddEXPCurrent(sint64 exp, bool send_packet) {
bool ret = false;
char message[128];
char adjective[16];
if (exp > 0 && level < GUILD_MAX_LEVEL) {
exp_current += exp;
if (exp_current >= exp_to_next_level) {
LogWrite(MISC__TODO, 1, "TODO", "Do we know what guild is leveling here yet?");
LogWrite(GUILD__DEBUG, 0, "Guilds", "Guild Level UP! New Level: %i (current XP: %ul)", level, exp_current);
int64 left_over = exp_current - exp_to_next_level;
level++;
exp_to_next_level *= 2;
exp_current = left_over;
AddNewGuildEvent(GUILD_EVENT_GUILD_LEVEL_UP, "The guild gained a level and is now level %u.", Timer::GetUnixTimeStamp(), true, level);
SendMessageToGuild(GUILD_EVENT_GUILD_LEVEL_UP, "The guild gained a level and is now level %u.", level);
if (level % 10 == 0) {
if (level == 10)
strncpy(adjective, "bold", sizeof(adjective));
else if (level == 20)
strncpy(adjective, "daring", sizeof(adjective));
else if (level == 30)
strncpy(adjective, "gallant", sizeof(adjective));
else if (level == 40)
strncpy(adjective, "noble", sizeof(adjective));
else if (level == 50)
strncpy(adjective, "heroic", sizeof(adjective));
else if (level == 60)
strncpy(adjective, "lordly", sizeof(adjective));
else if (level == 70)
strncpy(adjective, "legendary", sizeof(adjective));
else if (level == 80)
strncpy(adjective, "epic", sizeof(adjective));
else
strncpy(adjective, "too uber for cheerios", sizeof(adjective) - 1);
sprintf(message, "The %s guild <%s> has attained level %u", adjective, name, level);
zone_list.HandleGlobalAnnouncement(message);
}
}
save_needed = true;
ret = true;
}
else if (exp < 0) {
}
if (ret && send_packet)
SendGuildUpdate();
}
void Guild::SetEXPToNextLevel(int64 exp, bool send_packet) {
exp_to_next_level = exp;
if (send_packet) {
LogWrite(GUILD__DEBUG, 1, "Guilds", "Guild XP to next level: %ul", exp_to_next_level);
SendGuildUpdate();
save_needed = true;
}
}
void Guild::SetRecruitingShortDesc(const char* new_desc, bool send_packet) {
assert(new_desc);
recruiting_short_desc = string(new_desc);
if (send_packet) {
LogWrite(GUILD__DEBUG, 1, "Guilds", "Set Guild Recruiting short desc:\n%s", recruiting_short_desc.c_str());
SendGuildUpdate();
recruiting_save_needed = true;
}
}
void Guild::SetRecruitingFullDesc(const char* new_desc, bool send_packet) {
assert(new_desc);
recruiting_full_desc = string(new_desc);
if (send_packet) {
LogWrite(GUILD__DEBUG, 1, "Guilds", "Set Guild Recruiting full desc:\n%s", recruiting_full_desc.c_str());
SendGuildUpdate();
recruiting_save_needed = true;
}
}
void Guild::SetRecruitingMinLevel(int8 new_level, bool send_packet) {
recruiting_min_level = new_level;
if (send_packet) {
LogWrite(GUILD__DEBUG, 1, "Guilds", "Set Guild Recruiting min_level: %i", recruiting_min_level);
SendGuildUpdate();
recruiting_save_needed = true;
}
}
void Guild::SetRecruitingPlayStyle(int8 new_play_style, bool send_packet) {
recruiting_play_style = new_play_style;
if (send_packet) {
LogWrite(GUILD__DEBUG, 1, "Guilds", "Set Guild Recruiting play style: %i", recruiting_play_style);
SendGuildUpdate();
recruiting_save_needed = true;
}
}
bool Guild::SetRecruitingDescTag(int8 index, int8 tag, bool send_packet) {
bool ret = false;
if (index <= 3) {
recruiting_desc_tags.Put(index, tag);
ret = true;
}
if (ret && send_packet) {
LogWrite(GUILD__DEBUG, 1, "Guilds", "Set Guild Recruiting descriptive tag index: %i, tag: %i", index, tag);
SendGuildUpdate();
recruiting_save_needed = true;
}
return ret;
}
int8 Guild::GetRecruitingDescTag(int8 index) {
int8 ret = 0;
if (index <= 3)
ret = recruiting_desc_tags.Get(index);
LogWrite(GUILD__DEBUG, 1, "Guilds", "Get Guild Recruiting descriptive tag index: %i, value: %i", index, ret);
return ret;
}
bool Guild::SetPermission(int8 rank, int8 permission, int8 value, bool send_packet) {
bool ret = false;
if (value == 0 || value == 1) {
if (permissions.count(rank) == 0)
permissions.Put(rank, new MutexMap);
permissions.Get(rank)->Put(permission, value);
ret = true;
}
if (ret && send_packet) {
LogWrite(GUILD__DEBUG, 1, "Guilds", "Set Guild Permissions - Rank: %i, Permission: %i, Value: %i", rank, permission, value);
SendGuildUpdate();
ranks_save_needed = true;
}
return ret;
}
int8 Guild::GetPermission(int8 rank, int8 permission) {
int8 ret = 0;
if (permissions.count(rank) > 0 && permissions.Get(rank)->count(permission) > 0)
ret = permissions.Get(rank)->Get(permission);
LogWrite(GUILD__DEBUG, 1, "Guilds", "Get Guild Permissions - Rank: %i, Permission: %i, Value: %i", rank, permission, ret);
return ret;
}
bool Guild::SetEventFilter(int8 event_id, int8 category, int8 value, bool send_packet) {
bool ret = false;
if ((category == GUILD_EVENT_FILTER_CATEGORY_RETAIN_HISTORY || category == GUILD_EVENT_FILTER_CATEGORY_BROADCAST) && (value == 0 || value == 1)) {
if (event_filters.count(event_id) == 0)
event_filters.Put(event_id, new MutexMap);
event_filters.Get(event_id)->Put(category, value);
ret = true;
}
if (ret && send_packet) {
LogWrite(GUILD__DEBUG, 1, "Guilds", "Set Guild Event Filter - EventID: %i, Category: %i, Value: %i", event_id, category, value);
SendGuildUpdate();
event_filters_save_needed = true;
}
return ret;
}
int8 Guild::GetEventFilter(int8 event_id, int8 category) {
int8 ret = 0;
if (event_filters.count(event_id) > 0 && event_filters.Get(event_id)->count(category) > 0) {
ret = event_filters.Get(event_id)->Get(category);
LogWrite(GUILD__DEBUG, 1, "Guilds", "Get Guild Event Filter - EventID: %i, Category: %i, Value: %i", event_id, category, ret);
}
return ret;
}
int32 Guild::GetNumUniqueAccounts() {
map::iterator itr;
map accounts;
mMembers.readlock(__FUNCTION__, __LINE__);
if (members.size() > 0) {
for (itr = members.begin(); itr != members.end(); itr++) {
if (accounts.count(itr->second->account_id) == 0)
accounts[itr->second->account_id] = true;
}
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
LogWrite(GUILD__DEBUG, 1, "Guilds", "Found %i Unique Account(s) in Guild", accounts.size());
return accounts.size();
}
int32 Guild::GetNumRecruiters() {
map::iterator itr;
int32 ret = 0;
mMembers.readlock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
if (itr->second->recruiter_id > 0 && (itr->second->member_flags & GUILD_MEMBER_FLAGS_RECRUITING_FOR_GUILD))
ret++;
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
LogWrite(GUILD__DEBUG, 1, "Guilds", "Found %i Recruiter(s) in Guild", ret);
return ret;
}
int32 Guild::GetNextRecruiterID() {
map::iterator itr;
map tmp;
int32 i, ret = 0;
mMembers.readlock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
if (itr->second->recruiter_id > 0)
tmp[itr->second->recruiter_id] = true;
}
for (i = 1; i < 0xFFFFFFFF; i++) {
if (tmp.count(i) == 0) {
ret = i;
break;
}
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
LogWrite(GUILD__DEBUG, 1, "Guilds", "Next Guild Recruiter ID: %i", ret);
return ret;
}
int64 Guild::GetNextEventID() {
GuildEvent *ge;
int64 ret = 1;
if (guild_events.size() > 0) {
ge = guild_events.front();
ret = ge->event_id + 1;
}
LogWrite(GUILD__DEBUG, 1, "Guilds", "Next Guild Event ID: %i", ret);
return ret;
}
GuildMember * Guild::GetGuildMemberOnline(Client *client) {
map::iterator itr;
GuildMember *ret = 0;
assert(client);
mMembers.readlock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
if (itr->second->character_id == client->GetCharacterID()) {
ret = itr->second;
break;
}
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
LogWrite(GUILD__DEBUG, 3, "Guilds", "Guild Member Online: %s", ret->name);
return ret;
}
GuildMember * Guild::GetGuildMember(Player *player) {
assert(player);
LogWrite(MISC__TODO, 1, "TODO", "Figure out how to log this in %s: %i", __FUNCTION__, __LINE__);
return GetGuildMember(player->GetCharacterID());
}
GuildMember * Guild::GetGuildMember(int32 character_id) {
GuildMember *ret = 0;
mMembers.readlock(__FUNCTION__, __LINE__);
if (members.count(character_id) > 0)
ret = members[character_id];
mMembers.releasereadlock(__FUNCTION__, __LINE__);
LogWrite(GUILD__DEBUG, 1, "Guilds", "%s: %i", __FUNCTION__, character_id);
return ret;
}
GuildMember * Guild::GetGuildMember(const char *player_name) {
map::iterator itr;
GuildMember *ret = 0;
assert(player_name);
mMembers.readlock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
if (!strncmp(player_name, itr->second->name, sizeof(itr->second->name))) {
ret = itr->second;
break;
}
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
LogWrite(GUILD__DEBUG, 1, "Guilds", "%s: %s", __FUNCTION__, player_name);
return ret;
}
vector * Guild::GetGuildRecruiters() {
map::iterator itr;
vector *ret = 0;
mMembers.readlock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
if (itr->second->recruiter_id > 0 && (itr->second->member_flags & GUILD_MEMBER_FLAGS_RECRUITING_FOR_GUILD)) {
if (!ret)
ret = new vector;
ret->push_back(itr->second);
LogWrite(GUILD__DEBUG, 1, "Guilds", "Get Guild Recruiter '%s' (%i)", itr->second->name, itr->second->recruiter_id);
}
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
return ret;
}
GuildEvent * Guild::GetGuildEvent(int64 event_id) {
deque::iterator itr;
GuildEvent* ret = 0;
for (itr = guild_events.begin(); itr != guild_events.end(); itr++) {
if ((*itr)->event_id == event_id) {
ret = *itr;
break;
}
}
LogWrite(GUILD__DEBUG, 1, "Guilds", "Get Guild Event: %s (%lli)", ret->description.c_str(), ret->event_id);
return ret;
}
bool Guild::SetRankName(int8 rank, const char *name, bool send_packet) {
assert(name);
ranks.Put(rank, string(name));
if (send_packet) {
LogWrite(GUILD__DEBUG, 0, "Guilds", "Set Guild Rank Name: %s (%i)", name, rank);
SendGuildUpdate();
ranks_save_needed = true;
}
return true;
}
const char * Guild::GetRankName(int8 rank) {
if (ranks.count(rank) > 0) {
LogWrite(GUILD__DEBUG, 0, "Guilds", "Get Guild Rank Name: %s (%i)", ranks.Get(rank).c_str(), rank);
return ranks.Get(rank).c_str();
}
return 0;
}
bool Guild::SetRecruitingFlag(int8 flag, int8 value, bool send_packet) {
bool ret = false;
if (recruiting_flags.count(flag) > 0 && (value == 0 || value == 1)) {
recruiting_flags.Put(flag, value);
ret = true;
}
if (ret && send_packet) {
LogWrite(GUILD__DEBUG, 0, "Guilds", "Set Guild Recruiting Flag: %i, Value: %i", flag, value);
SendGuildUpdate();
recruiting_save_needed = true;
}
return ret;
}
int8 Guild::GetRecruitingFlag(int8 flag) {
int8 value = 0;
if (recruiting_flags.count(flag) > 0)
value = recruiting_flags.Get(flag);
LogWrite(GUILD__DEBUG, 0, "Guilds", "Get Guild Recruiting Flag: %i, Value: %i", flag, value);
return value;
}
bool Guild::SetGuildRecruiter(Client* client, const char* name, bool value, bool send_packet) {
GuildMember *gm;
const char *awarder_name;
assert(client);
assert(name);
if (!(gm = GetGuildMember(name)))
return false;
awarder_name = client->GetPlayer()->GetName();
if (value) {
gm->recruiter_id = GetNextRecruiterID();
AddNewGuildEvent(GUILD_EVENT_BECOMES_RECRUITER, "%s awarded %s Guild Recruiting Permission.", Timer::GetUnixTimeStamp(), true, awarder_name, name);
SendMessageToGuild(GUILD_EVENT_BECOMES_RECRUITER, "%s awarded %s Guild Recruiting Permission.", awarder_name, name);
LogWrite(GUILD__DEBUG, 0, "Guilds", "%s makes %s a guild recruiter.", awarder_name, name);
}
else {
gm->recruiter_id = 0;
AddNewGuildEvent(GUILD_EVENT_NO_LONGER_RECRUITER, "%s revoked %s's Guild Recruiting Permission.", Timer::GetUnixTimeStamp(), true, awarder_name, name);
SendMessageToGuild(GUILD_EVENT_NO_LONGER_RECRUITER, "%s revoked %s's Guild Recruiting Permission.", awarder_name, name);
LogWrite(GUILD__DEBUG, 0, "Guilds", "%s removes %s from guild recruiters.", awarder_name, name);
}
if (send_packet) {
SendGuildMember(gm);
member_save_needed = true;
}
return true;
}
bool Guild::SetGuildRecruiterDescription(Client *client, const char *description, bool send_packet) {
GuildMember *gm;
assert(client);
assert(description);
if (!(gm = GetGuildMember(client->GetPlayer())))
return false;
gm->recruiter_description = string(description);
if (send_packet) {
LogWrite(GUILD__DEBUG, 0, "Guilds", "Set guild recruiter description:\n%s", gm->recruiter_description.c_str());
SendGuildRecruiterInfo(client, client->GetPlayer());
member_save_needed = true;
}
return true;
}
bool Guild::ToggleGuildRecruiterAdventureClass(Client *client, bool send_packet) {
GuildMember *gm;
assert(client);
if (!(gm = GetGuildMember(client->GetPlayer())))
return false;
gm->recruiting_show_adventure_class = (gm->recruiting_show_adventure_class == 0 ? 1 : 0);
if (send_packet) {
LogWrite(GUILD__DEBUG, 0, "Guilds", "Toggle guild recruiter adventure class = %i", gm->recruiting_show_adventure_class);
SendGuildRecruiterInfo(client, client->GetPlayer());
}
return true;
}
bool Guild::SetGuildMemberNote(const char *name, const char *note, bool send_packet) {
GuildMember *gm;
assert(name);
assert(note);
if (!(gm = GetGuildMember(name)))
return false;
gm->note = string(note);
if (send_packet) {
LogWrite(GUILD__DEBUG, 0, "Guilds", "Set guild member note:\n%s", gm->note.c_str());
SendGuildMember(gm);
member_save_needed = true;
}
return true;
}
bool Guild::SetGuildOfficerNote(const char *name, const char *note, bool send_packet) {
GuildMember *gm;
assert(name);
assert(note);
if (!(gm = GetGuildMember(name)))
return false;
gm->officer_note = string(note);
if (send_packet) {
LogWrite(GUILD__DEBUG, 0, "Guilds", "Set guild officer note:\n%s", gm->officer_note.c_str());
SendGuildMember(gm);
member_save_needed = true;
}
return true;
}
bool Guild::AddNewGuildMember(Client *client, const char *invited_by, int8 rank) {
Player *player;
GuildMember *gm;
assert(client);
player = client->GetPlayer();
assert(player);
if (members.count(player->GetCharacterID()) == 0 && !player->GetGuild()) {
gm = new GuildMember;
gm->account_id = player->GetZone()->GetClientBySpawn(player)->GetAccountID();
gm->character_id = player->GetCharacterID();
strncpy(gm->name, player->GetName(), sizeof(gm->name));
gm->guild_status = 0;
gm->points = 0.0;
gm->adventure_class = player->GetAdventureClass();
gm->adventure_level = player->GetLevel();
gm->tradeskill_class = player->GetTradeskillClass();
gm->tradeskill_level = player->GetTSLevel();
gm->rank = rank;
gm->zone = string(player->GetZone()->GetZoneDescription());
gm->join_date = Timer::GetUnixTimeStamp();
gm->last_login_date = gm->join_date;
gm->recruiter_id = 0;
gm->member_flags = GUILD_MEMBER_FLAGS_NOTIFY_LOGINS;
gm->recruiting_show_adventure_class = 1;
gm->recruiter_picture_data_size = 0;
gm->recruiter_picture_data = 0;
mMembers.writelock(__FUNCTION__, __LINE__);
members[player->GetCharacterID()] = gm;
mMembers.releasewritelock(__FUNCTION__, __LINE__);
player->SetGuild(this);
string subtitle;
subtitle.append("<").append(GetName()).append(">");
player->SetSubTitle(subtitle.c_str());
if (invited_by)
client->SimpleMessage(CHANNEL_COLOR_WHITE, "You accept the invite into the guild.");
else {
client->SimpleMessage(CHANNEL_COLOR_WHITE, "You have formed the guild.");
LogWrite(GUILD__DEBUG, 0, "Guilds", "New Guild formed: %s", GetName());
}
client->PlaySound("ui_joined");
SendGuildUpdate(client);
SendGuildMember(gm);
SendGuildMOTD(client);
SendGuildEventList(client);
SendGuildBankEventList(client);
SendAllGuildEvents(client);
SendGuildMemberList(client);
if(client->GetVersion() > 546)
client->GetCurrentZone()->SendUpdateTitles(client->GetPlayer());
if (invited_by) {
AddNewGuildEvent(GUILD_EVENT_MEMBER_JOINS, "%s has accepted %s's invitation to join %s.", Timer::GetUnixTimeStamp(), true, player->GetName(), invited_by, GetName());
SendMessageToGuild(GUILD_EVENT_MEMBER_JOINS, "%s has accepted %s's invitation to join %s.", player->GetName(), invited_by, GetName());
LogWrite(GUILD__DEBUG, 0, "Guilds", "%s invited %s to join guild: %s", invited_by, player->GetName(), GetName());
}
member_save_needed = true;
}
return true;
}
bool Guild::AddGuildMember(GuildMember *guild_member) {
assert(guild_member);
mMembers.writelock(__FUNCTION__, __LINE__);
assert(members.count(guild_member->character_id) == 0);
members[guild_member->character_id] = guild_member;
mMembers.releasewritelock(__FUNCTION__, __LINE__);
// spammy
LogWrite(GUILD__DEBUG, 5, "Guilds", "Added Player: %s (%i) to Guild: %s", guild_member->name, guild_member->character_id, GetName());
return true;
}
void Guild::RemoveGuildMember(int32 character_id, bool send_packet) {
GuildMember *gm = 0;
Client *client;
mMembers.writelock(__FUNCTION__, __LINE__);
if (members.count(character_id) > 0) {
gm = members[character_id];
members.erase(gm->character_id);
}
mMembers.releasewritelock(__FUNCTION__, __LINE__);
if (gm) {
LogWrite(GUILD__DEBUG, 0, "Guilds", "Remove Player: %s (%i) from Guild: %s", members[character_id]->name, character_id, GetName());
if ((client = zone_list.GetClientByCharID(character_id))) {
client->GetPlayer()->SetGuild(0);
client->GetPlayer()->SetSubTitle("");
client->GetCurrentZone()->SendUpdateTitles(client->GetPlayer());
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "You were removed from the guild.");
}
database.DeleteGuildMember(this, gm->character_id);
if (send_packet) {
SendGuildMemberLeave(gm->character_id);
SendGuildUpdate();
SendGuildMemberList();
}
AddNewGuildEvent(GUILD_EVENT_MEMBER_LEAVES, "%s left the guild.", Timer::GetUnixTimeStamp(), true, gm->name);
SendMessageToGuild(GUILD_EVENT_MEMBER_LEAVES, "%s left the guild.", gm->name);
safe_delete_array(gm->recruiter_picture_data);
safe_delete(gm);
}
}
void Guild::RemoveAllGuildMembers() {
map::iterator itr;
Client *client;
mMembers.writelock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
if ((client = zone_list.GetClientByCharID(itr->second->character_id))) {
client->GetPlayer()->SetGuild(0);
client->GetPlayer()->SetSubTitle("");
}
safe_delete(itr->second);
}
members.clear();
mMembers.releasewritelock(__FUNCTION__, __LINE__);
LogWrite(GUILD__DEBUG, 0, "Guilds", "Removed ALL members from Guild: %s", GetName());
}
bool Guild::DemoteGuildMember(Client *client, const char *name, bool send_packet) {
GuildMember *gm;
const char *demoter_name;
bool ret = false;
assert(client);
assert(name);
mMembers.readlock(__FUNCTION__, __LINE__);
if ((gm = GetGuildMember(name)) && gm->rank != GUILD_RANK_RECRUIT) {
demoter_name = client->GetPlayer()->GetName();
gm->rank++;
AddNewGuildEvent(GUILD_EVENT_MEMBER_DEMOTED, "%s has demoted %s to %s.", Timer::GetUnixTimeStamp(), true, demoter_name, name, ranks.Get(gm->rank).c_str());
SendMessageToGuild(GUILD_EVENT_MEMBER_DEMOTED, "%s has demoted %s to %s.", demoter_name, name, ranks.Get(gm->rank).c_str());
LogWrite(GUILD__DEBUG, 0, "Guilds", "%s demoted %s to %s in Guild: %s", demoter_name, name, ranks.Get(gm->rank).c_str(), GetName());
ret = true;
if (send_packet) {
SendGuildMember(gm);
SendGuildMemberList();
member_save_needed = true;
}
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
return ret;
}
bool Guild::PromoteGuildMember(Client *client, const char *name, bool send_packet) {
GuildMember *gm;
const char *promoter_name;
bool ret = false;
assert(client);
assert(name);
mMembers.readlock(__FUNCTION__, __LINE__);
if ((gm = GetGuildMember(name)) && gm->rank != GUILD_RANK_LEADER) {
promoter_name = client->GetPlayer()->GetName();
gm->rank--;
AddNewGuildEvent(GUILD_EVENT_MEMBER_PROMOTED, "%s has promoted %s to %s.", Timer::GetUnixTimeStamp(), true, promoter_name, name, ranks.Get(gm->rank).c_str());
SendMessageToGuild(GUILD_EVENT_MEMBER_PROMOTED, "%s has promoted %s to %s.", promoter_name, name, ranks.Get(gm->rank).c_str());
LogWrite(GUILD__DEBUG, 0, "Guilds", "%s promoted %s to %s in Guild: %s", promoter_name, name, ranks.Get(gm->rank).c_str(), GetName());
if (send_packet) {
SendGuildMember(gm);
SendGuildMemberList();
member_save_needed = true;
}
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
return ret;
}
bool Guild::KickGuildMember(Client *client, const char *name, bool send_packet) {
GuildMember *gm;
Client *kicked_client;
const char *kicker_name;
assert(client);
assert(name);
if (!(gm = GetGuildMember(name)))
return false;
kicker_name = client->GetPlayer()->GetName();
if (!strncmp(kicker_name, gm->name, sizeof(gm->name))) {
AddNewGuildEvent(GUILD_EVENT_MEMBER_LEAVES, "%s left the guild.", Timer::GetUnixTimeStamp(), true, gm->name);
SendMessageToGuild(GUILD_EVENT_MEMBER_LEAVES, "%s left the guild.", gm->name);
LogWrite(GUILD__DEBUG, 0, "Guilds", "Player: %s has left guild: %s", gm->name, GetName());
}
else {
AddNewGuildEvent(GUILD_EVENT_MEMBER_LEAVES, "%s kicked %s from the guild.", Timer::GetUnixTimeStamp(), true, kicker_name, gm->name);
SendMessageToGuild(GUILD_EVENT_MEMBER_LEAVES, "%s kicked %s from the guild.", kicker_name, gm->name);
LogWrite(GUILD__DEBUG, 0, "Guilds", "Player: %s was kicked from guild: %s by %s.", gm->name, GetName(), kicker_name);
}
if ((kicked_client = zone_list.GetClientByCharID(gm->character_id))) {
kicked_client->GetPlayer()->SetGuild(0);
kicked_client->GetPlayer()->SetSubTitle("");
if (!strncmp(client->GetPlayer()->GetName(), gm->name, sizeof(gm->name)))
kicked_client->SimpleMessage(CHANNEL_COLOR_YELLOW, "You left the guild.");
else
kicked_client->Message(CHANNEL_COLOR_YELLOW, "You were kicked from the guild by %s.", kicker_name);
}
mMembers.writelock(__FUNCTION__, __LINE__);
members.erase(gm->character_id);
mMembers.releasewritelock(__FUNCTION__, __LINE__);
database.DeleteGuildMember(this, gm->character_id);
if (send_packet) {
SendGuildMemberLeave(gm->character_id);
SendGuildUpdate();
SendGuildMemberList();
}
safe_delete_array(gm->recruiter_picture_data);
safe_delete(gm);
return true;
}
bool Guild::InvitePlayer(Client *client, const char *name, bool send_packet) {
Client *client_invite;
Player *player_invite;
PacketStruct *packet;
assert(client);
assert(name);
if (!(client_invite = zone_list.GetClientByCharName(string(name)))) {
client->Message(CHANNEL_COLOR_WHITE, "%s couldn't be found.", name);
LogWrite(GUILD__WARNING, 0, "Guilds", "Attempted to invite %s to guild %s: Player Not Found", name, GetName());
return false;
}
player_invite = client_invite->GetPlayer();
if (player_invite->GetGuild()) {
client->Message(CHANNEL_COLOR_WHITE, "%s is already in a guild.", player_invite->GetName());
LogWrite(GUILD__WARNING, 0, "Guilds", "Attempted to invite %s to guild %s: Already in a guild", player_invite->GetName(), GetName());
return false;
}
if (client_invite->GetPendingGuildInvite()->guild) {
client->Message(CHANNEL_COLOR_WHITE, "%s is already considering joining a guild.", player_invite->GetName());
LogWrite(GUILD__WARNING, 0, "Guilds", "Attempted to invite %s to guild %s: Pending Invite elsewhere", player_invite->GetName(), GetName());
return false;
}
if (!(packet = configReader.getStruct("WS_ReceiveOffer", client_invite->GetVersion())))
return false;
packet->setDataByName("type", 2);
packet->setMediumStringByName("name", client->GetPlayer()->GetName());
packet->setDataByName("unknown2", 1);
packet->setMediumStringByName("guild_name", GetName());
client_invite->QueuePacket(packet->serialize());
client->Message(CHANNEL_COLOR_WHITE, "You have invited %s to join %s.", player_invite->GetName(), GetName());
LogWrite(GUILD__DEBUG, 0, "Guilds", "%s invited %s to guild %s", client->GetPlayer()->GetName(), player_invite->GetName(), GetName());
client_invite->SetPendingGuildInvite(this, client->GetPlayer());
safe_delete(packet);
return true;
}
bool Guild::AddPointsToAll(Client *client, float points, const char *comment, bool send_packet) {
map::iterator itr;
vector character_ids;
GuildMember *gm;
Client *client_to;
assert(client);
mMembers.readlock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
gm = itr->second;
if (!permissions.Get(gm->rank)->Get(GUILD_PERMISSIONS_RECEIVE_POINTS)) {
LogWrite(GUILD__DEBUG, 0, "Guilds", "PlayerID: %i not allowed to receive points! Skipping...", gm->character_id);
continue;
}
gm->points += points;
character_ids.push_back(gm->character_id);
AddPointHistory(gm, Timer::GetUnixTimeStamp(), client->GetPlayer()->GetName(), points, comment);
if ((client_to = zone_list.GetClientByCharID(gm->character_id)))
{
client_to->Message(CHANNEL_COLOR_GUILD_MSGS, "%s increased your guild member points by %.1f.", client->GetPlayer()->GetName(), points);
LogWrite(GUILD__DEBUG, 0, "Guilds", "Guild: %s", GetName());
LogWrite(GUILD__DEBUG, 0, "Guilds", "\tAwarded By: %s +%.1f pts to Player: %s", client->GetPlayer()->GetName(), points, gm->name);
}
LogWrite(MISC__TODO, 1, "TODO", "Comment that this is temporary?\n%s, %s, %i", __FILE__, __FUNCTION__, __LINE__);
SendGuildMember(gm); //tmp
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
client->Message(CHANNEL_COLOR_GUILD_MSGS, "Points modified for %u guild members.", character_ids.size());
if (send_packet) {
LogWrite(GUILD__DEBUG, 0, "Guilds", "%s modified points for %u members. Reason: %s", client->GetPlayer()->GetName(), character_ids.size(), points, comment);
SendGuildModification(points, &character_ids);
member_save_needed = true;
points_history_save_needed = true;
}
return true;
}
bool Guild::AddPointsToAllOnline(Client *client, float points, const char *comment, bool send_packet) {
map::iterator itr;
vector character_ids;
GuildMember *gm;
Client *client_to;
assert(client);
mMembers.readlock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
gm = itr->second;
if (!(client_to = zone_list.GetClientByCharID(gm->character_id))) {
LogWrite(GUILD__DEBUG, 0, "Guilds", "PlayerID: %i not online to receive points! Skipping...", gm->character_id);
continue;
}
if (!permissions.Get(gm->rank)->Get(GUILD_PERMISSIONS_RECEIVE_POINTS)) {
LogWrite(GUILD__DEBUG, 0, "Guilds", "PlayerID: %i not allowed to receive points! Skipping...", gm->character_id);
continue;
}
gm->points += points;
character_ids.push_back(gm->character_id);
AddPointHistory(gm, Timer::GetUnixTimeStamp(), client->GetPlayer()->GetName(), points, comment);
client_to->Message(CHANNEL_COLOR_GUILD_MSGS, "%s increased your guild member points by %.1f.", client->GetPlayer()->GetName(), points);
LogWrite(GUILD__DEBUG, 0, "Guilds", "Guild: %s", GetName());
LogWrite(GUILD__DEBUG, 0, "Guilds", "\tAwarded By: %s +%.1f pts to Player: %s", client->GetPlayer()->GetName(), points, gm->name);
LogWrite(MISC__TODO, 1, "TODO", "Comment that this is temporary?\n%s, %s, %i", __FILE__, __FUNCTION__, __LINE__);
SendGuildMember(gm); //tmp
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
client->Message(CHANNEL_COLOR_GUILD_MSGS, "Points modified for %u guild members.", character_ids.size());
if (send_packet) {
LogWrite(GUILD__DEBUG, 0, "Guilds", "%s modified points for %u members. Reason: %s", client->GetPlayer()->GetName(), character_ids.size(), points, comment);
SendGuildModification(points, &character_ids);
member_save_needed = true;
points_history_save_needed = true;
}
return true;
}
bool Guild::AddPointsToGroup(Client *client, float points, const char *comment, bool send_packet) {
deque::iterator itr;
deque* group_members;
vector character_ids;
GroupMemberInfo *gmi;
GuildMember *gm;
assert(client);
if (!client->GetPlayer()->GetGroupMemberInfo()) {
client->SimpleMessage(CHANNEL_COLOR_GUILD_MSGS, "Cannot assign points because you aren't in a group.");
LogWrite(GUILD__DEBUG, 0, "Guilds", "%s tried to assign points for group and failed: Not in a group", client->GetPlayer()->GetName());
return false;
}
mMembers.readlock(__FUNCTION__, __LINE__);
world.GetGroupManager()->GroupLock(__FUNCTION__, __LINE__);
group_members = world.GetGroupManager()->GetGroupMembers(client->GetPlayer()->GetGroupMemberInfo()->group_id);
for (itr = group_members->begin(); itr != group_members->end(); itr++) {
gmi = *itr;
if (!gmi->client)
continue;
if (gmi->client->GetPlayer()->GetGuild() != this) {
LogWrite(GUILD__DEBUG, 0, "Guilds", "PlayerID: %i not in guild to receive group points! Skipping...", gmi->client->GetPlayer()->GetCharacterID());
continue;
}
if (!(gm = members[gmi->client->GetCharacterID()]) || !permissions.Get(gm->rank)->Get(GUILD_PERMISSIONS_RECEIVE_POINTS)) {
LogWrite(GUILD__DEBUG, 0, "Guilds", "PlayerID: %i not allowed to receive points! Skipping...", gm->character_id);
continue;
}
gm->points += points;
character_ids.push_back(gm->character_id);
AddPointHistory(gm, Timer::GetUnixTimeStamp(), client->GetPlayer()->GetName(), points, comment);
gmi->client->Message(CHANNEL_COLOR_GUILD_MSGS, "%s increased your guild member points by %.1f.", client->GetPlayer()->GetName(), points);
LogWrite(GUILD__DEBUG, 0, "Guilds", "Guild: %s", GetName());
LogWrite(GUILD__DEBUG, 0, "Guilds", "\tAwarded By: %s +%.1f pts to Player: %s", client->GetPlayer()->GetName(), points, gm->name);
LogWrite(MISC__TODO, 1, "TODO", "Comment that this is temporary?\n%s, %s, %i", __FILE__, __FUNCTION__, __LINE__);
SendGuildMember(gm); //tmp
}
world.GetGroupManager()->ReleaseGroupLock(__FUNCTION__, __LINE__);
mMembers.releasereadlock(__FUNCTION__, __LINE__);
client->Message(CHANNEL_COLOR_GUILD_MSGS, "Points modified for %u guild members.", character_ids.size());
if (send_packet) {
LogWrite(GUILD__DEBUG, 0, "Guilds", "%s modified points for %u members. Reason: %s", client->GetPlayer()->GetName(), character_ids.size(), points, comment);
SendGuildModification(points, &character_ids);
member_save_needed = true;
points_history_save_needed = true;
}
return true;
}
bool Guild::AddPointsToRaid(Client *client, float points, const char *comment, bool send_packet) {
assert(client);
LogWrite(MISC__TODO, 1, "TODO", "Implement Raiding\n%s, %s, %i", __FILE__, __FUNCTION__, __LINE__);
client->SimpleMessage(CHANNEL_COLOR_GUILD_MSGS, "Cannot assign points because you aren't in a raid.");
return false;
}
bool Guild::AddPointsToGuildMember(Client *client, float points, const char *name, const char *comment, bool send_packet) {
vector character_ids;
GuildMember *gm;
Client *client_to;
assert(client);
assert(name);
if (!(gm = GetGuildMember(name)))
return false;
mMembers.readlock(__FUNCTION__, __LINE__);
if (!permissions.Get(gm->rank)->Get(GUILD_PERMISSIONS_RECEIVE_POINTS)) {
mMembers.releasereadlock(__FUNCTION__, __LINE__);
LogWrite(GUILD__DEBUG, 0, "Guilds", "PlayerID: %i not allowed to receive points! Skipping...", gm->character_id);
client->Message(CHANNEL_COLOR_GUILD_MSGS, "%s does not have permission to receive guild points.", gm->name);
return false;
}
gm->points += points;
character_ids.push_back(gm->character_id);
if ((client_to = zone_list.GetClientByCharID(gm->character_id))) {
client_to->Message(CHANNEL_COLOR_GUILD_MSGS, "%s increased your guild member points by %.1f.", client->GetPlayer()->GetName(), points);
LogWrite(GUILD__DEBUG, 0, "Guilds", "Guild: %s", GetName());
LogWrite(GUILD__DEBUG, 0, "Guilds", "\tAwarded By: %s +%.1f pts to Player: %s", client->GetPlayer()->GetName(), points, gm->name);
}
LogWrite(GUILD__DEBUG, 0, "Guilds", "%s modified points for 1 guild member. Reason: %s", client->GetPlayer()->GetName(), comment);
client->SimpleMessage(CHANNEL_COLOR_GUILD_MSGS, "Points modified for 1 guild member.");
AddPointHistory(gm, Timer::GetUnixTimeStamp(), client->GetPlayer()->GetName(), points, comment);
if (send_packet) {
LogWrite(MISC__TODO, 1, "TODO", "Comment that this is temporary?\n%s, %s, %i", __FILE__, __FUNCTION__, __LINE__);
SendGuildMember(gm); //tmp
SendGuildModification(points, &character_ids);
member_save_needed = true;
points_history_save_needed = true;
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
return true;
}
bool Guild::AddPointHistory(GuildMember *guild_member, int32 date, const char *modified_by, float points, const char *comment, bool new_point_history) {
LogWrite(MISC__TODO, 1, "TODO", "JA: decide to put logging here rather than in all AddPoints functions\n%s, %s, %i", __FILE__, __FUNCTION__, __LINE__);
PointHistory *ph, *ph_delete;
deque *ph_list;
assert(guild_member);
assert(modified_by);
ph = new PointHistory;
ph->date = date;
ph->modified_by = string(modified_by);
ph->points = points;
if (comment)
ph->comment = string(comment);
ph->saved_needed = new_point_history;
mMembers.readlock(__FUNCTION__, __LINE__);
ph_list = &guild_member->point_history;
if (ph_list->size() == GUILD_MAX_POINT_HISTORY) {
ph_delete = ph_list->back();
database.DeleteGuildPointHistory(this, guild_member->character_id, ph_delete);
safe_delete(ph_delete);
ph_list->pop_back();
}
ph_list->push_front(ph);
mMembers.releasereadlock(__FUNCTION__, __LINE__);
return true;
}
void Guild::ViewGuildMemberPoints(Client *client, const char * name) {
deque *ph_list;
deque::iterator itr;
PointHistory *ph;
GuildMember *gm;
PacketStruct *packet;
int32 i;
assert(client);
assert(name);
if (!(gm = GetGuildMember(name)))
return;
if (!(packet = configReader.getStruct("WS_RequestGuildEventDetails", client->GetVersion())))
return;
mMembers.readlock(__FUNCTION__, __LINE__);
ph_list = &gm->point_history;
i = 0;
packet->setDataByName("account_id", client->GetAccountID());
packet->setDataByName("character_id", client->GetCharacterID());
packet->setDataByName("guild_id", id);
packet->setArrayLengthByName("num_events", ph_list->size());
// this log entry may be excessive... test it out.
LogWrite(GUILD__DEBUG, 0, "Guilds", "account_id: %i, character_id: %i, guild_id: %i, num_events: %i", client->GetAccountID(), client->GetCharacterID(), id, ph_list->size());
for (itr = ph_list->begin(); itr != ph_list->end(); itr++) {
ph = *itr;
packet->setArrayDataByName("date", ph->date, i);
packet->setArrayDataByName("modified_by", ph->modified_by.c_str(), i);
packet->setArrayDataByName("comment", ph->comment.c_str(), i);
packet->setArrayDataByName("points", ph->points, i);
// this log entry may be excessive... test it out.
LogWrite(GUILD__DEBUG, 0, "Guilds", "date: %i, modified_by: %i, comment: %i, points: %.1f", ph->date, ph->modified_by.c_str(), ph->comment.c_str(), ph->points);
i++;
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
//DumpPacket(packet->serialize());
client->QueuePacket(packet->serialize());
safe_delete(packet);
}
bool Guild::ChangeMemberFlag(Client *client, int8 member_flag, int8 value, bool send_packet) {
GuildMember *gm;
bool ret = false;
assert (client);
if (!(gm = GetGuildMemberOnline(client)))
return false;
mMembers.readlock(__FUNCTION__, __LINE__);
switch (member_flag) {
case GUILD_MEMBER_FLAGS_RECRUITING_FOR_GUILD: {
if (value > 0 && !(gm->member_flags & GUILD_MEMBER_FLAGS_RECRUITING_FOR_GUILD)) {
gm->member_flags += GUILD_MEMBER_FLAGS_RECRUITING_FOR_GUILD;
ret = true;
}
else if (value == 0 && gm->member_flags & GUILD_MEMBER_FLAGS_RECRUITING_FOR_GUILD) {
gm->member_flags -= GUILD_MEMBER_FLAGS_RECRUITING_FOR_GUILD;
ret = true;
}
break;
}
case GUILD_MEMBER_FLAGS_NOTIFY_LOGINS: {
if (value > 0 && !(gm->member_flags & GUILD_MEMBER_FLAGS_NOTIFY_LOGINS)) {
gm->member_flags += GUILD_MEMBER_FLAGS_NOTIFY_LOGINS;
client->SimpleMessage(CHANNEL_COLOR_GUILD_MSGS, "Guild online notifications are now enabled.");
ret = true;
}
else if (value == 0 && gm->member_flags & GUILD_MEMBER_FLAGS_NOTIFY_LOGINS) {
gm->member_flags -= GUILD_MEMBER_FLAGS_NOTIFY_LOGINS;
client->SimpleMessage(CHANNEL_COLOR_GUILD_MSGS, "Guild online notifications are now disabled.");
ret = true;
}
break;
}
case GUILD_MEMBER_FLAGS_DONT_GENERATE_EVENTS: {
if (value > 1 && !(gm->member_flags & GUILD_MEMBER_FLAGS_DONT_GENERATE_EVENTS)) {
gm->member_flags += GUILD_MEMBER_FLAGS_DONT_GENERATE_EVENTS;
client->SimpleMessage(CHANNEL_COLOR_GUILD_MSGS, "Guild events are now disabled for this character.");
ret = true;
}
else if (value == 0 && gm->member_flags & GUILD_MEMBER_FLAGS_DONT_GENERATE_EVENTS) {
gm->member_flags -= GUILD_MEMBER_FLAGS_DONT_GENERATE_EVENTS;
client->SimpleMessage(CHANNEL_COLOR_GUILD_MSGS, "Guild events are now enabled for this character.");
ret = true;
}
break;
}
default:
break;
}
if (ret && send_packet) {
LogWrite(GUILD__DEBUG, 0, "Guilds", "Guild Member Flag '%i' changed to %i", member_flag, value);
member_save_needed = true;
SendGuildMember(client, gm);
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
return ret;
}
bool Guild::UpdateGuildStatus(Player *player ,int32 Status) {
GuildMember *gm;
assert(player);
assert(members.count(player->GetCharacterID()) > 0);
mMembers.readlock(__FUNCTION__, __LINE__);
gm = members[player->GetCharacterID()];
gm->guild_status += Status;
mMembers.releasereadlock(__FUNCTION__, __LINE__);
member_save_needed = true;
return true;
}
bool Guild::UpdateGuildMemberInfo(Player *player) {
GuildMember *gm;
assert(player);
assert(members.count(player->GetCharacterID()) > 0);
LogWrite(GUILD__DEBUG, 0, "Guilds", "Updating Guild Member Info for Player: %i", player->GetCharacterID());
mMembers.readlock(__FUNCTION__, __LINE__);
gm = members[player->GetCharacterID()];
gm->adventure_class = player->GetAdventureClass();
gm->adventure_level = player->GetLevel();
gm->tradeskill_class = player->GetTradeskillClass();
gm->tradeskill_level = player->GetTSLevel();
gm->zone = string(player->GetZone()->GetZoneDescription());
gm->last_login_date = database.GetCharacterTimeStamp(player->GetCharacterID());
mMembers.releasereadlock(__FUNCTION__, __LINE__);
return true;
}
void Guild::AddGuildEvent(int64 event_id, int32 type, const char *description, int32 date, int8 locked) {
LogWrite(GUILD__DEBUG, 3, "Guilds", "Guild: %s", GetName());
LogWrite(GUILD__DEBUG, 3, "Guilds", "Add Guild Event: %lli, %i, %s", event_id, type, string(description).c_str());
GuildEvent *ge;
assert(description);
assert(event_filters.Get(type)->Get(GUILD_EVENT_FILTER_CATEGORY_RETAIN_HISTORY));
assert(guild_events.size() < GUILD_MAX_EVENTS);
ge = new GuildEvent;
ge->event_id = event_id;
ge->type = type;
ge->description = string(description);
ge->date = date;
ge->locked = locked;
ge->save_needed = false;
guild_events.push_back(ge);
}
void Guild::AddNewGuildEvent(int32 type, const char *description, int32 date, bool send_packet, ...) {
deque::reverse_iterator itr;
GuildEvent *ge, *current_ge;
char buffer[4096];
va_list argptr;
assert(description);
va_start(argptr, send_packet);
vsnprintf(buffer, sizeof(buffer), description, argptr);
va_end(argptr);
ge = new GuildEvent;
ge->event_id = GetNextEventID();
ge->type = type;
ge->description = string(buffer);
ge->date = date;
ge->locked = 0;
if (!event_filters.Get(type)->Get(GUILD_EVENT_FILTER_CATEGORY_RETAIN_HISTORY)) {
database.SaveHiddenGuildEvent(this, ge);
return;
}
if (guild_events.size() == GUILD_MAX_EVENTS) {
for (itr = guild_events.rbegin(); itr != guild_events.rend(); itr++) {
current_ge = *itr;
if (current_ge->locked == 0) {
database.ArchiveGuildEvent(this, current_ge);
safe_delete(current_ge);
guild_events.erase(--itr.base());
guild_events.push_front(ge);
break;
}
}
}
else
guild_events.push_front(ge);
if (send_packet) {
LogWrite(GUILD__DEBUG, 0, "Guilds", "Some Add New Guild Event thing happened, not sure what...");
SendNewGuildEvent(ge);
ge->save_needed = true;
events_save_needed = true;
}
}
bool Guild::LockGuildEvent(int64 event_id, bool lock, bool send_packet) {
bool ret = false;
GuildEvent* ge = GetGuildEvent(event_id);
if (ge) {
if (lock) {
ge->locked = 1;
if (send_packet)
SendGuildEventAction(GUILD_EVENT_ACTION_LOCK, ge);
}
else {
ge->locked = 0;
if (send_packet)
SendGuildEventAction(GUILD_EVENT_ACTION_UNLOCK, ge);
}
ret = true;
}
if (ret && send_packet) {
LogWrite(GUILD__DEBUG, 0, "Guilds", "Toggle guild event lock, EventID: %lli, value: %i", event_id, lock);
ge->save_needed = true;
events_save_needed = true;
}
return ret;
}
bool Guild::DeleteGuildEvent(int64 event_id, bool send_packet) {
bool ret = false;
deque::iterator itr;
for (itr = guild_events.begin(); itr != guild_events.end(); itr++) {
GuildEvent* ge = *itr;
if (ge->event_id == event_id) {
if (send_packet)
SendGuildEventAction(GUILD_EVENT_ACTION_DELETE, ge);
database.DeleteGuildEvent(this, ge->event_id);
safe_delete(ge);
guild_events.erase(itr);
ret = true;
break;
}
}
LogWrite(GUILD__DEBUG, 0, "Guilds", "Delete guild event, EventID: %lli", event_id);
return ret;
}
int32 Guild::GetPermissionsPacketValue(int8 rank, int32 start, int32 end) {
int32 ret = 0;
for (int32 i = start; i <= end; i++) {
if (permissions.count(rank) > 0 && permissions.Get(rank)->count(i) > 0 && permissions.Get(rank)->Get(i)) {
if (i >= 0 && i <= 31)
ret += (int32)pow(2.0, (double)i);
else if (i >= 32 && i <= 63)
ret += (int32)pow(2.0, (double)(i - 32));
}
}
return ret;
}
int32 Guild::GetEventFilterPacketValue(int8 category, int32 start, int32 end) {
int32 ret = 0;
for (int32 i = start; i <= end; i++) {
if (event_filters.count(i) > 0 && event_filters.Get(i)->count(category) > 0 && event_filters.Get(i)->Get(category)) {
if (i >= 0 && i <= 31)
ret += (int32)pow(2.0, (double)i);
else if (i >= 32 && i <= 63)
ret += (int32)pow(2.0, (double)(i - 32));
else if (i >= 64 && i <= 95)
ret += (int32)pow(2.0, (double)(i - 64));
}
}
return ret;
}
int8 Guild::GetRecruitingLookingForPacketValue() {
int8 ret = 0;
MutexMap::iterator itr = recruiting_flags.begin();
while (itr.Next()) {
if (itr.second)
ret += (int8)pow(2.0, (double)itr.first);
}
return ret;
}
void Guild::SendGuildMOTD(Client* client) {
if (client && strlen(motd) > 0)
client->Message(CHANNEL_COLOR_GUILD_MOTD, "Guild MOTD: %s", motd);
LogWrite(GUILD__DEBUG, 1, "Guilds", "Sent guild MOTD.\n'%s'", motd);
}
void Guild::SendGuildEventList() {
map::iterator itr;
Client *client;
mMembers.readlock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
if ((client = zone_list.GetClientByCharID(itr->second->character_id)))
SendGuildEventList(client);
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
LogWrite(GUILD__DEBUG, 1, "Guilds", "Sent guild Event List (%s).", __FUNCTION__);
}
void Guild::SendGuildEventList(Client* client) {
if (client) {
PacketStruct* packet = configReader.getStruct("WS_GuildEventList", client->GetVersion());
if (packet) {
packet->setDataByName("account_id", client->GetAccountID());
packet->setArrayLengthByName("num_events", guild_events.size());
deque::iterator itr;
int32 i = 0;
for (itr = guild_events.begin(); itr != guild_events.end(); itr++) {
packet->setArrayDataByName("event_id", (*itr)->event_id, i);
packet->setArrayDataByName("locked", (*itr)->locked, i);
i++;
}
client->QueuePacket(packet->serialize());
//DumpPacket(packet->serialize());
safe_delete(packet);
}
}
LogWrite(GUILD__DEBUG, 1, "Guilds", "Sent guild Event List (%s).", __FUNCTION__);
}
void Guild::SendGuildEventDetails() {
map::iterator itr;
Client *client;
mMembers.readlock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
if ((client = zone_list.GetClientByCharID(itr->second->character_id)))
SendGuildEventDetails(client);
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
LogWrite(GUILD__DEBUG, 1, "Guilds", "Sent guild Event Details (%s).", __FUNCTION__);
}
void Guild::SendGuildEventDetails(Client* client) {
if (client) {
PacketStruct* packet = configReader.getStruct("WS_GuildEventDetails", client->GetVersion());
if (packet) {
deque::iterator itr;
int32 i = 0;
for (itr = guild_events.begin(); itr != guild_events.end(); itr++) {
packet->setArrayDataByName("event_id", (*itr)->event_id, i);
i++;
}
client->QueuePacket(packet->serialize());
safe_delete(packet);
}
}
LogWrite(GUILD__DEBUG, 1, "Guilds", "Sent guild Event Details (%s).", __FUNCTION__);
}
void Guild::SendAllGuildEvents() {
map::iterator itr;
Client *client;
mMembers.readlock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
if ((client = zone_list.GetClientByCharID(itr->second->character_id)))
SendAllGuildEvents(client);
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
LogWrite(GUILD__DEBUG, 0, "Guilds", "Sent ALL guild Events (%s).", __FUNCTION__);
}
void Guild::SendAllGuildEvents(Client* client) {
if (client) {
deque::iterator itr;
for (itr = guild_events.begin(); itr != guild_events.end(); itr++)
SendOldGuildEvent(client, *itr);
}
LogWrite(GUILD__DEBUG, 0, "Guilds", "Sent ALL guild Events (%s).", __FUNCTION__);
}
void Guild::SendOldGuildEvent(Client* client, GuildEvent* guild_event) {
if (client && guild_event) {
PacketStruct* packet = configReader.getStruct("WS_RequestGuildInfo", client->GetVersion());
if (packet) {
packet->setDataByName("account_id", client->GetAccountID());
packet->setDataByName("event_id", guild_event->event_id);
packet->setDataByName("date", guild_event->date);
packet->setDataByName("type", guild_event->type);
packet->setMediumStringByName("description", guild_event->description.c_str());
client->QueuePacket(packet->serialize());
safe_delete(packet);
}
}
LogWrite(GUILD__DEBUG, 3, "Guilds", "Sent OLD guild Events.");
}
void Guild::SendNewGuildEvent(GuildEvent* guild_event) {
map::iterator itr;
Client *client;
assert (guild_event);
mMembers.readlock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
if ((client = zone_list.GetClientByCharID(itr->second->character_id)))
SendNewGuildEvent(client, guild_event);
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
LogWrite(GUILD__DEBUG, 0, "Guilds", "Sent NEW guild Events. (%s)", __FUNCTION__);
}
void Guild::SendNewGuildEvent(Client* client, GuildEvent* guild_event) {
if (client && guild_event) {
PacketStruct* packet = configReader.getStruct("WS_GuildEventAdd", client->GetVersion());
if (packet) {
packet->setDataByName("account_id", client->GetAccountID());
packet->setDataByName("event_id", guild_event->event_id);
packet->setDataByName("type", guild_event->type);
packet->setDataByName("date", guild_event->date);
packet->setDataByName("description", guild_event->description.c_str());
//DumpPacket(packet->serialize());
client->QueuePacket(packet->serialize());
safe_delete(packet);
}
}
LogWrite(GUILD__DEBUG, 0, "Guilds", "Sent NEW guild Events. (%s)", __FUNCTION__);
}
void Guild::SendGuildEventAction(int8 action, GuildEvent* guild_event) {
map::iterator itr;
Client *client;
assert(guild_event);
mMembers.readlock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
if ((client = zone_list.GetClientByCharID(itr->second->character_id)))
SendGuildEventAction(client, action, guild_event);
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
LogWrite(GUILD__DEBUG, 1, "Guilds", "Sent guild events Action. (%s)", __FUNCTION__);
}
void Guild::SendGuildEventAction(Client* client, int8 action, GuildEvent* guild_event) {
if (guild_event) {
PacketStruct* packet = configReader.getStruct("WS_GuildEventAction", client->GetVersion());
if (packet) {
packet->setDataByName("account_id", client->GetAccountID());
packet->setDataByName("event_id", guild_event->event_id);
packet->setDataByName("action", action);
client->QueuePacket(packet->serialize());
safe_delete(packet);
}
}
LogWrite(GUILD__DEBUG, 1, "Guilds", "Sent guild events Action. (%s)", __FUNCTION__);
}
void Guild::SendGuildBankEventList() {
map::iterator itr;
Client *client;
mMembers.readlock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
if ((client = zone_list.GetClientByCharID(itr->second->character_id)))
SendGuildBankEventList(client);
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
LogWrite(GUILD__DEBUG, 1, "Guilds", "Sent guild bank events list. (%s)", __FUNCTION__);
}
void Guild::SendGuildBankEventList(Client* client) {
if (client) {
for (int32 i = 0; i < 4; i++) {
PacketStruct* packet = configReader.getStruct("WS_GuildBankEventList", client->GetVersion());
if (packet) {
packet->setDataByName("account_id", client->GetAccountID());
packet->setDataByName("bank_number", i);
packet->setArrayLengthByName("num_events", banks[i].events.size());
deque::iterator itr;
for (itr = banks[i].events.begin(); itr != banks[i].events.end(); itr++)
packet->setArrayDataByName("event_id", (*itr)->event_id, i);
//DumpPacket(packet->serialize());
client->QueuePacket(packet->serialize());
safe_delete(packet);
}
}
}
LogWrite(GUILD__DEBUG, 1, "Guilds", "Sent guild bank events list. (%s)", __FUNCTION__);
}
void Guild::SendGuildUpdate() {
map::iterator itr;
Client *client;
LogWrite(GUILD__DEBUG, 1, "Guilds", "SendGuildUpdate to all guild member clients online... (%s)", __FUNCTION__);
mMembers.readlock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
if ((client = zone_list.GetClientByCharID(itr->second->character_id)))
SendGuildUpdate(client);
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
}
void Guild::SendGuildUpdate(Client* client) {
if (client) {
LogWrite(GUILD__DEBUG, 1, "Guilds", "SendGuildUpdate to client online... (%s)", __FUNCTION__);
PacketStruct* packet = configReader.getStruct("WS_GuildUpdate", client->GetVersion());
if (packet) {
packet->setMediumStringByName("guild_name", GetName());
packet->setMediumStringByName("guild_motd", motd);
packet->setDataByName("guild_id", id);
packet->setDataByName("guild_level", level);
packet->setDataByName("unknown", 1);
packet->setDataByName("formed_date", formed_date);
packet->setDataByName("unique_accounts", GetNumUniqueAccounts());
packet->setDataByName("num_members", members.size());
packet->setDataByName("exp_current", exp_current);
packet->setDataByName("exp_to_next_level", exp_to_next_level);
packet->setDataByName("event_filter_retain1", GetEventFilterPacketValue(GUILD_EVENT_FILTER_CATEGORY_RETAIN_HISTORY, 0, 31));
packet->setDataByName("event_filter_retain2", GetEventFilterPacketValue(GUILD_EVENT_FILTER_CATEGORY_RETAIN_HISTORY, 32, 63));
packet->setDataByName("event_filter_retain3", GetEventFilterPacketValue(GUILD_EVENT_FILTER_CATEGORY_RETAIN_HISTORY, 63, 92));
packet->setDataByName("event_filter_retain4", 0);
packet->setDataByName("event_filter_broadcast1", GetEventFilterPacketValue(GUILD_EVENT_FILTER_CATEGORY_BROADCAST, 0, 31));
packet->setDataByName("event_filter_broadcast2", GetEventFilterPacketValue(GUILD_EVENT_FILTER_CATEGORY_BROADCAST, 32, 63));
packet->setDataByName("event_filter_broadcast3", GetEventFilterPacketValue(GUILD_EVENT_FILTER_CATEGORY_BROADCAST, 64, 92));
packet->setDataByName("event_filter_broadcast4", 0);
packet->setDataByName("recruiting_looking_for", GetRecruitingLookingForPacketValue());
packet->setDataByName("recruiting_desc_tag1", GetRecruitingDescTag(0));
packet->setDataByName("recruiting_desc_tag2", GetRecruitingDescTag(1));
packet->setDataByName("recruiting_desc_tag3", GetRecruitingDescTag(2));
packet->setDataByName("recruiting_desc_tag4", GetRecruitingDescTag(3));
packet->setDataByName("recruiting_playstyle", recruiting_play_style);
packet->setDataByName("recruiting_min_level", recruiting_min_level);
packet->setMediumStringByName("recuiting_short_description", recruiting_short_desc.c_str());
packet->setMediumStringByName("recruiting_full_description", recruiting_full_desc.c_str());
packet->setMediumStringByName("rank0_name", ranks.Get(GUILD_RANK_LEADER).c_str());
packet->setDataByName("rank0_permissions1", GetPermissionsPacketValue(GUILD_RANK_LEADER, 0, 31));
packet->setDataByName("rank0_permissions2", GetPermissionsPacketValue(GUILD_RANK_LEADER, 32, 44));
packet->setDataByName("rank0_permissions_unused", 0);
packet->setMediumStringByName("rank1_name", ranks.Get(GUILD_RANK_SENIOR_OFFICER).c_str());
packet->setDataByName("rank1_permissions1", GetPermissionsPacketValue(GUILD_RANK_SENIOR_OFFICER, 0, 31));
packet->setDataByName("rank1_permissions2", GetPermissionsPacketValue(GUILD_RANK_SENIOR_OFFICER, 32, 44));
packet->setDataByName("rank1_permissions_unused", 0);
packet->setMediumStringByName("rank2_name", ranks.Get(GUILD_RANK_OFFICER).c_str());
packet->setDataByName("rank2_permissions1", GetPermissionsPacketValue(GUILD_RANK_OFFICER, 0, 31));
packet->setDataByName("rank2_permissions2", GetPermissionsPacketValue(GUILD_RANK_OFFICER, 32, 44));
packet->setDataByName("rank2_permissions_unused", 0);
packet->setMediumStringByName("rank3_name", ranks.Get(GUILD_RANK_SENIOR_MEMBER).c_str());
packet->setDataByName("rank3_permissions1", GetPermissionsPacketValue(GUILD_RANK_SENIOR_MEMBER, 0, 31));
packet->setDataByName("rank3_permissions2", GetPermissionsPacketValue(GUILD_RANK_SENIOR_MEMBER, 32, 44));
packet->setDataByName("rank3_permissions_unused", 0);
packet->setMediumStringByName("rank4_name", ranks.Get(GUILD_RANK_MEMBER).c_str());
packet->setDataByName("rank4_permissions1", GetPermissionsPacketValue(GUILD_RANK_MEMBER, 0, 31));
packet->setDataByName("rank4_permissions2", GetPermissionsPacketValue(GUILD_RANK_MEMBER, 32, 44));
packet->setDataByName("rank4_permissions_unused", 0);
packet->setMediumStringByName("rank5_name", ranks.Get(GUILD_RANK_JUNIOR_MEMBER).c_str());
packet->setDataByName("rank5_permissions1", GetPermissionsPacketValue(GUILD_RANK_JUNIOR_MEMBER, 0, 31));
packet->setDataByName("rank5_permissions2", GetPermissionsPacketValue(GUILD_RANK_JUNIOR_MEMBER, 32, 44));
packet->setDataByName("rank5_permissions_unused", 0);
packet->setMediumStringByName("rank6_name", ranks.Get(GUILD_RANK_INITIATE).c_str());
packet->setDataByName("rank6_permissions1", GetPermissionsPacketValue(GUILD_RANK_INITIATE, 0, 31));
packet->setDataByName("rank6_permissions2", GetPermissionsPacketValue(GUILD_RANK_INITIATE, 32, 44));
packet->setDataByName("rank6_permissions_unused", 0);
packet->setMediumStringByName("rank7_name", ranks.Get(GUILD_RANK_RECRUIT).c_str());
packet->setDataByName("rank7_permissions1", GetPermissionsPacketValue(GUILD_RANK_RECRUIT, 0, 31));
packet->setDataByName("rank7_permissions2", GetPermissionsPacketValue(GUILD_RANK_RECRUIT, 32, 44));
packet->setDataByName("rank7_permissions_unused", 0);
packet->setMediumStringByName("bank1_name", banks[0].name.c_str());
packet->setMediumStringByName("bank2_name", banks[1].name.c_str());
packet->setMediumStringByName("bank3_name", banks[2].name.c_str());
packet->setMediumStringByName("bank4_name", banks[3].name.c_str());
//DumpPacket(packet->serialize());
client->QueuePacket(packet->serialize());
safe_delete(packet);
}
}
}
void Guild::SendGuildMemberList() {
map::iterator itr;
Client *client;
mMembers.readlock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
if ((client = zone_list.GetClientByCharID(itr->second->character_id)))
SendGuildMemberList(client);
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
LogWrite(GUILD__DEBUG, 1, "Guilds", "Sent guild member list to all clients.");
}
void Guild::SendGuildMemberList(Client* client) {
map::iterator itr;
GuildMember *gm;
if (client) {
LogWrite(GUILD__DEBUG, 1, "Guilds", "Sent guild member list to a client.");
PacketStruct* packet = configReader.getStruct("WS_GuildMembershipResponse", client->GetVersion());
if (packet) {
packet->setDataByName("guild_id", id);
packet->setDataByName("character_id_to", client->GetCharacterID());
mMembers.readlock(__FUNCTION__, __LINE__);
packet->setArrayLengthByName("num_members", members.size());
int32 i = 0;
for (itr = members.begin(); itr != members.end(); itr++) {
gm = itr->second;
packet->setArrayDataByName("account_id", gm->account_id, i);
packet->setArrayDataByName("character_id", gm->character_id, i);
packet->setArrayDataByName("name", gm->name, i);
packet->setArrayDataByName("unknown2", 0, i);
packet->setArrayDataByName("unknown3", 1, i);
packet->setArrayDataByName("adventure_class", gm->adventure_class, i);
packet->setArrayDataByName("adventure_level", gm->adventure_level, i);
packet->setArrayDataByName("tradeskill_class", gm->tradeskill_class, i);
packet->setArrayDataByName("tradeskill_level", gm->tradeskill_level, i);
packet->setArrayDataByName("rank", gm->rank, i);
packet->setArrayDataByName("member_flags", gm->member_flags, i);
packet->setArrayDataByName("join_date", gm->join_date, i);
packet->setArrayDataByName("guild_status", gm->guild_status, i);
packet->setArrayDataByName("last_login", gm->last_login_date, i);
packet->setArrayDataByName("recruiter_id", gm->recruiter_id, i);
packet->setArrayDataByName("points", gm->points, i);
if (zone_list.GetClientByCharID(gm->character_id))
packet->setArrayDataByName("zone", gm->zone.c_str(), i);
packet->setArrayDataByName("note", gm->note.c_str(), i);
packet->setArrayDataByName("officer_note", gm->officer_note.c_str(), i);
i++;
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
//DumpPacket(packet->serialize());
client->QueuePacket(packet->serialize());
safe_delete(packet);
}
}
}
void Guild::SendGuildMember(Player* player, bool include_zone) {
map::iterator itr;
Client *client;
GuildMember *gm;
assert(player);
mMembers.readlock(__FUNCTION__, __LINE__);
if (members.count(player->GetCharacterID()) > 0) {
gm = members[player->GetCharacterID()];
for (itr = members.begin(); itr != members.end(); itr++) {
if ((client = zone_list.GetClientByCharID(itr->second->character_id)))
SendGuildMember(client, gm, include_zone);
}
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
LogWrite(GUILD__DEBUG, 1, "Guilds", "Sent guild member.");
}
void Guild::SendGuildMember(GuildMember* gm, bool include_zone) {
map::iterator itr;
Client *client;
assert(gm);
mMembers.readlock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
if ((client = zone_list.GetClientByCharID(itr->second->character_id)))
SendGuildMember(client, gm, include_zone);
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
LogWrite(GUILD__DEBUG, 1, "Guilds", "Sent guild member.");
}
void Guild::SendGuildMember(Client* client, GuildMember* gm, bool include_zone) {
if (client && gm) {
PacketStruct* packet = configReader.getStruct("WS_JoinGuildNotify", client->GetVersion());
if (packet) {
packet->setDataByName("guild_id", id);
packet->setDataByName("character_id", gm->character_id);
packet->setDataByName("account_id", gm->account_id);
packet->setMediumStringByName("name", gm->name);
packet->setDataByName("unknown2", 0);
packet->setDataByName("unknown3", 1);
packet->setDataByName("adventure_class", gm->adventure_class);
packet->setDataByName("adventure_level", gm->adventure_level);
packet->setDataByName("tradeskill_class", gm->tradeskill_class);
packet->setDataByName("tradeskill_level", gm->tradeskill_level);
packet->setDataByName("rank", gm->rank);
packet->setDataByName("member_flags", gm->member_flags);
packet->setDataByName("join_date", gm->join_date);
packet->setDataByName("guild_status", gm->guild_status);
packet->setDataByName("last_login", gm->last_login_date);
packet->setDataByName("recruiter_id", gm->recruiter_id);
packet->setDataByName("points", gm->points);
packet->setMediumStringByName("note", gm->note.c_str());
packet->setMediumStringByName("officer_note", gm->officer_note.c_str());
if (include_zone && zone_list.GetClientByCharID(gm->character_id)) {
packet->setMediumStringByName("zone", gm->zone.c_str());
//DumpPacket(packet->serialize());
}
client->QueuePacket(packet->serialize());
safe_delete(packet);
}
}
LogWrite(GUILD__DEBUG, 1, "Guilds", "Sent guild member to a client.");
}
void Guild::SendGuildModification(float points, vector* character_ids) {
map::iterator itr;
Client *client;
if (character_ids) {
mMembers.readlock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
if ((client = zone_list.GetClientByCharID(itr->second->character_id)))
SendGuildModification(client, points, character_ids);
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
}
LogWrite(GUILD__DEBUG, 1, "Guilds", "Sent guild modification to all clients.");
}
void Guild::SendGuildModification(Client* client, float points, vector* character_ids) {
if (client && character_ids) {
PacketStruct* packet = configReader.getStruct("WS_ModifyGuild", client->GetVersion());
if (packet) {
packet->setDataByName("guild_id", id);
packet->setDataByName("unknown2", 0xFFFFFFFF);
packet->setDataByName("points", points);
packet->setArrayLengthByName("num_character_ids", character_ids->size());
for (int32 i = 0; i < character_ids->size(); i++)
packet->setArrayDataByName("character_id", character_ids->at(i), i);
client->QueuePacket(packet->serialize());
safe_delete(packet);
}
}
LogWrite(GUILD__DEBUG, 1, "Guilds", "Sent guild modification to a client.");
}
void Guild::GuildMemberLogin(Client *client, bool first_login) {
map::iterator itr;
Client *client_to;
char buf[128];
assert(client);
UpdateGuildMemberInfo(client->GetPlayer());
if (first_login)
SendGuildMOTD(client);
SendGuildUpdate(client);
if (first_login)
SendGuildMember(client->GetPlayer(), false);
SendGuildRecruiterInfo(client, client->GetPlayer());
SendGuildEventList(client);
SendGuildBankEventList(client);
SendGuildMember(client->GetPlayer());
SendGuildEventDetails(client);
uchar blah5[] = {/*0xFF,0x09,0x01,*/0x01,0x00,0x00,0x00,0x00,0x00,0x00};
uchar blah6[] = {/*0xFF,0x09,0x01,*/0x01,0x00,0x00,0x00,0x01,0x00,0x00};
uchar blah7[] = {/*0xFF,0x09,0x01,*/0x01,0x00,0x00,0x00,0x02,0x00,0x00};
uchar blah8[] = {/*0xFF,0x09,0x01,*/0x01,0x00,0x00,0x00,0x03,0x00,0x00};
//DumpPacket(blah5, sizeof(blah5));
//DumpPacket(blah6, sizeof(blah6));
//DumpPacket(blah7, sizeof(blah7));
//DumpPacket(blah8, sizeof(blah8));
client->QueuePacket(new EQ2Packet(OP_RequestGuildBankEventDetailsMs, blah5, sizeof(blah5)));
client->QueuePacket(new EQ2Packet(OP_RequestGuildBankEventDetailsMs, blah6, sizeof(blah6)));
client->QueuePacket(new EQ2Packet(OP_RequestGuildBankEventDetailsMs, blah7, sizeof(blah7)));
client->QueuePacket(new EQ2Packet(OP_RequestGuildBankEventDetailsMs, blah8, sizeof(blah8)));
if (first_login)
SendAllGuildEvents(client);
SendGuildMemberList(client);
if (first_login) {
snprintf(buf, sizeof(buf), "Guildmate: %s has logged in", client->GetPlayer()->GetName());
mMembers.readlock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
if ((client_to = zone_list.GetClientByCharID(itr->second->character_id)))
client_to->SimpleMessage(CHANNEL_GUILD_MEMBER_ONLINE, buf);
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
}
if (first_login){
uchar blah1[] = {/*0xFF,0x09,0x01,*/0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uchar blah2[] = {/*0xFF,0x09,0x01,*/0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00};
uchar blah3[] = {/*0xFF,0x09,0x01,*/0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00};
uchar blah4[] = {/*0xFF,0x09,0x01,*/0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00};
//DumpPacket(blah1, sizeof(blah1));
//DumpPacket(blah2, sizeof(blah2));
//DumpPacket(blah3, sizeof(blah3));
//DumpPacket(blah4, sizeof(blah4));
client->QueuePacket(new EQ2Packet(OP_GuildBankUpdateMsg, blah1, sizeof(blah1)));
client->QueuePacket(new EQ2Packet(OP_GuildBankUpdateMsg, blah2, sizeof(blah2)));
client->QueuePacket(new EQ2Packet(OP_GuildBankUpdateMsg, blah3, sizeof(blah3)));
client->QueuePacket(new EQ2Packet(OP_GuildBankUpdateMsg, blah4, sizeof(blah4)));
}
LogWrite(GUILD__DEBUG, 0, "Guilds", "Guild Member logged in.");
}
void Guild::GuildMemberLogoff(Player *player) {
map::iterator itr;
GuildMember *gm;
Client *client;
char buf[128];
assert(player);
mMembers.readlock(__FUNCTION__, __LINE__);
if ((gm = GetGuildMember(player))) {
snprintf(buf, sizeof(buf), "Guildmate: %s has logged out", player->GetName());
gm->zone.clear();
for (itr = members.begin(); itr != members.end(); itr++) {
if ((client = zone_list.GetClientByCharID(itr->second->character_id))) {
SendGuildMember(client, gm, false);
client->SimpleMessage(CHANNEL_GUILD_MEMBER_ONLINE, buf);
}
}
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
LogWrite(GUILD__DEBUG, 0, "Guilds", "Guild Member logged out.");
}
void Guild::SendGuildMemberLeave(int32 character_id) {
map::iterator itr;
Client *client;
mMembers.readlock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
if ((client = zone_list.GetClientByCharID(itr->second->character_id)))
SendGuildMemberLeave(client, character_id);
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
LogWrite(GUILD__DEBUG, 1, "Guilds", "Sent guild member left the guild to all clients.");
}
void Guild::SendGuildMemberLeave(Client* client, int32 character_id) {
PacketStruct* packet = configReader.getStruct("WS_LeaveGuildNotify", client->GetVersion());
if (packet) {
packet->setDataByName("guild_id", id);
packet->setDataByName("character_id", character_id);
client->QueuePacket(packet->serialize());
safe_delete(packet);
}
LogWrite(GUILD__DEBUG, 1, "Guilds", "Sent guild member left the guild to a client.");
}
void Guild::SendGuildRecruitingDetails(Client* client) {
if (client) {
LogWrite(GUILD__DEBUG, 1, "Guilds", "Sent guild recruiting details to a client.");
PacketStruct* packet = configReader.getStruct("WS_GuildRecruitingDetails", client->GetVersion());
if (packet) {
vector* recruiters = GetGuildRecruiters();
vector::iterator itr;
packet->setDataByName("guild_id", id);
packet->setDataByName("recruiting_full_description", recruiting_full_desc.c_str());
if (recruiters) {
int32 i = 0;
packet->setArrayLengthByName("num_recruiters", recruiters->size());
for (itr = recruiters->begin(); itr != recruiters->end(); itr++) {
GuildMember* gm = *itr;
packet->setArrayDataByName("adventure_class", gm->adventure_class, i);
packet->setArrayDataByName("adventure_level", gm->adventure_level, i);
packet->setArrayDataByName("tradeskill_class", gm->tradeskill_class, i);
packet->setArrayDataByName("tradeskill_level", gm->tradeskill_level, i);
packet->setArrayDataByName("show_adventure_class", gm->recruiting_show_adventure_class, i);
packet->setArrayDataByName("unknown2", 4, i);
packet->setArrayDataByName("unknown3", 2, i);
packet->setSubArrayLengthByName("num_bytes", gm->recruiter_picture_data_size, i);
if (gm->recruiter_picture_data_size > 0) {
for (int16 j = 0; j < gm->recruiter_picture_data_size; j++)
packet->setSubArrayDataByName("picture_byte", gm->recruiter_picture_data[j], i, j);
}
packet->setArrayDataByName("char_name", gm->name, i);
packet->setArrayDataByName("recruiter_description", gm->recruiter_description.c_str(), i);
i++;
}
safe_delete(recruiters);
}
//DumpPacket(packet->serialize());
client->QueuePacket(packet->serialize());
safe_delete(packet);
}
}
}
void Guild::SendGuildRecruitingImages(Client* client) {
if (client) {
LogWrite(GUILD__DEBUG, 1, "Guilds", "Sent guild recruiting images to a client.");
PacketStruct* packet = configReader.getStruct("WS_GuildRecruitingImage", client->GetVersion());
if (packet) {
vector* recruiters = GetGuildRecruiters();
packet->setDataByName("guild_id", id);
if (recruiters && recruiters->size() > 0) {
GuildMember* gm = recruiters->at(0);
packet->setArrayLengthByName("num_bytes", gm->recruiter_picture_data_size);
if (gm->recruiter_picture_data_size > 0) {
for (int16 i = 0; i < gm->recruiter_picture_data_size; i++)
packet->setArrayDataByName("picture_byte", gm->recruiter_picture_data[i], i);
}
safe_delete(recruiters);
}
client->QueuePacket(packet->serialize());
safe_delete(packet);
}
}
}
void Guild::SendGuildRecruiterInfo(Client* client, Player* player) {
if (client && player) {
LogWrite(GUILD__DEBUG, 1, "Guilds", "Sent guild recruiter info to a client.");
GuildMember* gm = GetGuildMember(player);
if (gm) {
PacketStruct* packet = configReader.getStruct("WS_GuildRecruitingMemberInfo", client->GetVersion());
if (packet) {
packet->setDataByName("character_id", gm->character_id);
packet->setDataByName("unknown", 1);
packet->setDataByName("adventure_class", gm->adventure_class);
packet->setDataByName("adventure_level", gm->adventure_level);
packet->setDataByName("tradeskill_class", gm->tradeskill_class);
packet->setDataByName("tradeskill_level", gm->tradeskill_level);
packet->setDataByName("show_adventure_class", gm->recruiting_show_adventure_class);
packet->setDataByName("unknown3", 0);
// hack!
gm->recruiter_picture_data_size = 0;
packet->setArrayLengthByName("num_bytes", gm->recruiter_picture_data_size);
if (gm->recruiter_picture_data_size > 0) {
for (int16 i = 0; i < gm->recruiter_picture_data_size; i++)
packet->setArrayDataByName("picture_byte", gm->recruiter_picture_data[i], i);
}
packet->setMediumStringByName("recruiter_name", gm->name);
packet->setMediumStringByName("recruiter_description", gm->recruiter_description.c_str());
//DumpPacket(packet->serialize());
client->QueuePacket(packet->serialize());
safe_delete(packet);
}
}
}
}
void Guild::HandleGuildSay(Client* sender, const char* message) {
map::iterator itr;
GuildMember *gm;
Client *client;
assert(sender);
assert(message);
if (!(gm = GetGuildMemberOnline(sender)))
return;
if (!permissions.Get(gm->rank)->Get(GUILD_PERMISSIONS_SPEAK_IN_GUILD_CHAT)) {
sender->SimpleMessage(CHANNEL_COLOR_WHITE, "You do not have permission to speak in guild chat.");
return;
}
mMembers.readlock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
if (!(client = zone_list.GetClientByCharID(itr->second->character_id)))
continue;
if (permissions.Get(itr->second->rank)->Get(GUILD_PERMISSIONS_SEE_GUILD_CHAT))
client->GetCurrentZone()->HandleChatMessage(client, sender->GetPlayer(), client->GetPlayer()->GetName(), CHANNEL_GUILD, message, 0, 0, false);
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
LogWrite(GUILD__DEBUG, 0, "Guilds", "Guild Say");
}
void Guild::HandleOfficerSay(Client* sender, const char* message) {
map::iterator itr;
GuildMember *gm;
Client *client;
assert(sender);
assert(message);
if (!(gm = GetGuildMemberOnline(sender)))
return;
if (!permissions.Get(gm->rank)->Get(GUILD_PERMISSIONS_SPEAK_IN_OFFICER_CHAT)) {
sender->SimpleMessage(CHANNEL_COLOR_WHITE, "You do not have permission to speak in officer chat.");
return;
}
mMembers.readlock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
if (!(client = zone_list.GetClientByCharID(itr->second->character_id)))
continue;
if (permissions.Get(itr->second->rank)->Get(GUILD_PERMISSIONS_SEE_OFFICER_CHAT))
client->GetCurrentZone()->HandleChatMessage(client, sender->GetPlayer(), client->GetPlayer()->GetName(), CHANNEL_OFFICER, message, 0, 0, false);
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
LogWrite(GUILD__DEBUG, 0, "Guilds", "Officer Say");
}
void Guild::SendMessageToGuild(int8 event_type, const char* message, ...) {
map::iterator itr;
Client *client;
va_list argptr;
char buffer[4096];
va_start(argptr, message);
vsnprintf(buffer, sizeof(buffer), message, argptr);
va_end(argptr);
mMembers.readlock(__FUNCTION__, __LINE__);
for (itr = members.begin(); itr != members.end(); itr++) {
if (!(client = zone_list.GetClientByCharID(itr->second->character_id)))
continue;
if (event_filters.Get(itr->second->rank)->Get(GUILD_EVENT_FILTER_CATEGORY_BROADCAST))
client->SimpleMessage(CHANNEL_COLOR_GUILD_EVENT, buffer);
}
mMembers.releasereadlock(__FUNCTION__, __LINE__);
LogWrite(GUILD__DEBUG, 0, "Guilds", "Sent message to entire guild.");
}
string Guild::GetEpicMobDeathMessage(const char* player_name, const char* mob_name) {
char message[256];
int8 choice;
assert(player_name);
assert(mob_name);
choice = (rand() % 5) + 1;
if (choice == 1)
snprintf(message, sizeof(message), "%s was slain by %s in a thunderous engagement!", mob_name, player_name);
else if (choice == 2)
snprintf(message, sizeof(message), "%s was slain by %s in a titanic struggle!", mob_name, player_name);
else if (choice == 3)
snprintf(message, sizeof(message), "%s was slain by %s's heroic might!", mob_name, player_name);
else if (choice == 4)
snprintf(message, sizeof(message), "%s slew %s in an earth shaking battle!", player_name, mob_name);
else
snprintf(message, sizeof(message), "%s slew %s in a heroic clash!", player_name, mob_name);
LogWrite(GUILD__DEBUG, 0, "Guilds", "Guild Epic Mob Death message sent.");
return string(message);
}
/***************************************************************************************************************************************************************
* GUILDLIST
***************************************************************************************************************************************************************/
GuildList::GuildList() {
}
GuildList::~GuildList() {
MutexMap::iterator itr = guild_list.begin();
while (itr.Next())
safe_delete(itr.second);
}
bool GuildList::AddGuild(Guild* guild) {
bool ret = false;
if (guild && guild_list.count(guild->GetID()) == 0) {
guild_list.Put(guild->GetID(), guild);
ret = true;
}
return ret;
}
Guild* GuildList::GetGuild(int32 guild_id) {
Guild* ret = 0;
if (guild_list.count(guild_id) > 0)
ret = guild_list.Get(guild_id);
return ret;
}
Guild* GuildList::GetGuild(const char* guild_name) {
Guild* ret = 0;
MutexMap::iterator itr = guild_list.begin();
while (itr.Next()) {
if (strncasecmp(itr.second->GetName(), guild_name, strlen(guild_name)) == 0) {
ret = itr.second;
break;
}
}
return ret;
}
bool GuildList::RemoveGuild(Guild* guild, bool delete_data) {
bool ret = false;
if (guild && guild_list.count(guild->GetID()) > 0) {
guild_list.erase(guild->GetID(), false, delete_data);
ret = true;
}
return ret;
}
bool GuildList::RemoveGuild(int32 guild_id, bool delete_data) {
bool ret = false;
if (guild_list.count(guild_id) > 0) {
guild_list.erase(guild_id, false, delete_data);
ret = true;
}
return ret;
}