#include #include "lfguild.h" #include "database.h" #include "worldserver.h" #include "../common/eqemu_logsys.h" #include "../common/string_util.h" #include "../common/packet_dump.h" #include "../common/rulesys.h" extern WorldServer *worldserver; extern Database database; PlayerLookingForGuild::PlayerLookingForGuild(char *Name, char *Comments, uint32 Level, uint32 Class, uint32 AACount, uint32 Timezone, uint32 TimePosted) { this->Name = Name; this->Comments = Comments; this->Level = Level; this->Class = Class; this->AACount = AACount; this->TimeZone = Timezone; this->TimePosted = TimePosted; } GuildLookingForPlayers::GuildLookingForPlayers(char *Name, char *Comments, uint32 FromLevel, uint32 ToLevel, uint32 Classes, uint32 AACount, uint32 Timezone, uint32 TimePosted) { this->Name = Name; this->Comments = Comments; this->FromLevel = FromLevel; this->ToLevel = ToLevel; this->Classes = Classes; this->AACount = AACount; this->TimeZone = Timezone; this->TimePosted = TimePosted; } bool LFGuildManager::LoadDatabase() { std::string query = "SELECT `type`,`name`,`comment`, " "`fromlevel`, `tolevel`, `classes`, " "`aacount`, `timezone`, `timeposted` FROM `lfguild`"; auto results = database.QueryDatabase(query); if (!results.Success()) { return false; } for (auto row = results.begin(); row != results.end(); ++row) { uint32 type = atoul(row[0]); if(type == 0) { PlayerLookingForGuild p(row[1], row[2], atoul(row[3]), atoul(row[5]), atoul(row[6]), atoul(row[7]), atoul(row[8])); Players.push_back(p); continue; } GuildLookingForPlayers g(row[1], row[2], atoul(row[3]), atoul(row[4]), atoul(row[5]), atoul(row[6]), atoul(row[7]), atoul(row[8])); Guilds.push_back(g); } return true; } void LFGuildManager::HandlePacket(ServerPacket *pack) { char From[64]; pack->SetReadPosition(0); uint32 FromZoneID = pack->ReadUInt32(); uint32 FromInstanceID = pack->ReadUInt32(); pack->ReadString(From); pack->ReadSkipBytes(4); uint32 SubType = pack->ReadUInt32(); switch(SubType) { case QSG_LFGuild_PlayerMatches: { uint32 FromLevel = pack->ReadUInt32(); uint32 ToLevel = pack->ReadUInt32(); uint32 MinAA = pack->ReadUInt32(); uint32 TimeZone = pack->ReadUInt32(); uint32 Classes = pack->ReadUInt32(); SendPlayerMatches(FromZoneID, FromInstanceID, From, FromLevel, ToLevel, MinAA, TimeZone, Classes); break; } case QSG_LFGuild_UpdatePlayerInfo: { char Comments[257]; uint32 Class = pack->ReadUInt32(); uint32 Level = pack->ReadUInt32(); uint32 AAPoints = pack->ReadUInt32(); pack->ReadString(Comments); uint32 Toggle = pack->ReadUInt32(); uint32 TimeZone = pack->ReadUInt32(); TogglePlayer(FromZoneID, FromInstanceID, From, Class, Level, AAPoints, Comments, Toggle, TimeZone); break; } case QSG_LFGuild_RequestPlayerInfo: { SendPlayerStatus(FromZoneID, FromInstanceID, From); break; } case QSG_LFGuild_UpdateGuildInfo: { char GuildName[33], Comments[257]; pack->ReadString(GuildName); pack->ReadString(Comments); uint32 FromLevel = pack->ReadUInt32(); uint32 ToLevel = pack->ReadUInt32(); uint32 Classes = pack->ReadUInt32(); uint32 AACount = pack->ReadUInt32(); uint32 Toggle = pack->ReadUInt32(); uint32 TimeZone = pack->ReadUInt32(); ToggleGuild(FromZoneID, FromInstanceID, From, GuildName, Comments, FromLevel, ToLevel, Classes, AACount, Toggle, TimeZone); break; } case QSG_LFGuild_GuildMatches: { uint32 Level = pack->ReadUInt32(); uint32 AAPoints = pack->ReadUInt32(); uint32 TimeZone = pack->ReadUInt32(); uint32 Class = pack->ReadUInt32(); SendGuildMatches(FromZoneID, FromInstanceID, From, Level, AAPoints, TimeZone, Class); break; } case QSG_LFGuild_RequestGuildInfo: { char GuildName[33]; pack->ReadString(GuildName); SendGuildStatus(FromZoneID, FromInstanceID, From, GuildName); break; } default: break; } } void LFGuildManager::SendPlayerMatches(uint32 FromZoneID, uint32 FromInstanceID, char *From, uint32 FromLevel, uint32 ToLevel, uint32 MinAA, uint32 TimeZone, uint32 Classes) { std::list::iterator it; std::list Matches; uint32 PacketSize = strlen(From) + 21, NumberOfMatches = 0; for(it = Players.begin(); it != Players.end(); ++it) { uint32 bitmask = 1 << (*it).Class ; if(((*it).Level >= FromLevel) && ((*it).Level <= ToLevel) && ((*it).AACount >= MinAA) && (bitmask & Classes) && ((TimeZone == 0xFFFFFFFF) || (TimeZone == (*it).TimeZone))) { ++NumberOfMatches; Matches.push_back(*it); PacketSize += (*it).Name.length() + (*it).Comments.length() + 18; } } auto pack = new ServerPacket(ServerOP_QueryServGeneric, PacketSize); pack->WriteUInt32(FromZoneID); pack->WriteUInt32(FromInstanceID); pack->WriteString(From); pack->WriteUInt32(QSG_LFGuild); pack->WriteUInt32(QSG_LFGuild_PlayerMatches); pack->WriteUInt32(NumberOfMatches); for(it = Matches.begin(); it != Matches.end(); ++it) { pack->WriteString((*it).Name.c_str()); pack->WriteString((*it).Comments.c_str()); pack->WriteUInt32((*it).Level); pack->WriteUInt32((*it).Class); pack->WriteUInt32((*it).AACount); pack->WriteUInt32((*it).TimeZone); } worldserver->SendPacket(pack); safe_delete(pack); } void LFGuildManager::SendGuildMatches(uint32 FromZoneID, uint32 FromInstanceID, char *From, uint32 Level, uint32 AAPoints, uint32 TimeZone, uint32 Class) { std::list::iterator it; std::list Matches; uint32 bitmask = 1 << Class ; uint32 PacketSize = strlen(From) + 21, NumberOfMatches = 0; for(it = Guilds.begin(); it != Guilds.end(); ++it) { if((Level >= (*it).FromLevel) && (Level <= (*it).ToLevel) && (AAPoints >= (*it).AACount) && (bitmask & (*it).Classes) && (((*it).TimeZone == 0xFFFFFFFF) || (TimeZone == 0xFFFFFFFF) || (TimeZone == (*it).TimeZone))) { ++NumberOfMatches; Matches.push_back(*it); PacketSize += (*it).Name.length() + (*it).Comments.length() + 6; } } auto pack = new ServerPacket(ServerOP_QueryServGeneric, PacketSize); pack->WriteUInt32(FromZoneID); pack->WriteUInt32(FromInstanceID); pack->WriteString(From); pack->WriteUInt32(QSG_LFGuild); pack->WriteUInt32(QSG_LFGuild_GuildMatches); pack->WriteUInt32(NumberOfMatches); for(it = Matches.begin(); it != Matches.end(); ++it) { pack->WriteString((*it).Name.c_str()); pack->WriteUInt32((*it).TimeZone); pack->WriteString((*it).Comments.c_str()); } worldserver->SendPacket(pack); safe_delete(pack); } void LFGuildManager::TogglePlayer(uint32 FromZoneID, uint32 FromInstanceID, char *From, uint32 Class, uint32 Level, uint32 AAPoints, char *Comments, uint32 Toggle, uint32 TimeZone) { for(auto it = Players.begin(); it != Players.end(); ++it) if(!strcasecmp((*it).Name.c_str(), From)) { Players.erase(it); break; } std::string query = StringFormat("DELETE FROM `lfguild` WHERE `type` = 0 AND `name` = '%s'", From); auto results = database.QueryDatabase(query); uint32 Now = time(nullptr); if(Toggle == 1) { PlayerLookingForGuild p(From, Comments, Level, Class, AAPoints, TimeZone, Now); Players.push_back(p); query = StringFormat("INSERT INTO `lfguild` " "(`type`, `name`, `comment`, `fromlevel`, `tolevel`, " "`classes`, `aacount`, `timezone`, `timeposted`) " "VALUES (0, '%s', '%s', %u, 0, %u, %u, %u, %u)", From, Comments, Level, Class, AAPoints, TimeZone, Now); auto results = database.QueryDatabase(query); } auto pack = new ServerPacket(ServerOP_QueryServGeneric, strlen(From) + strlen(Comments) + 30); pack->WriteUInt32(FromZoneID); pack->WriteUInt32(FromInstanceID); pack->WriteString(From); pack->WriteUInt32(QSG_LFGuild); pack->WriteUInt32(QSG_LFGuild_RequestPlayerInfo); pack->WriteString(Comments); pack->WriteUInt32(TimeZone); pack->WriteUInt32(Now); pack->WriteUInt32(Toggle); worldserver->SendPacket(pack); safe_delete(pack); } void LFGuildManager::ToggleGuild(uint32 FromZoneID, uint32 FromInstanceID, char *From, char* GuildName, char *Comments, uint32 FromLevel, uint32 ToLevel, uint32 Classes, uint32 AACount, uint32 Toggle, uint32 TimeZone) { for(auto it = Guilds.begin(); it != Guilds.end(); ++it) if(!strcasecmp((*it).Name.c_str(), GuildName)) { Guilds.erase(it); break; } std::string query = StringFormat("DELETE FROM `lfguild` WHERE `type` = 1 AND `name` = '%s'", GuildName); auto results = database.QueryDatabase(query); uint32 Now = time(nullptr); if(Toggle == 1) { GuildLookingForPlayers g(GuildName, Comments, FromLevel, ToLevel, Classes, AACount, TimeZone, Now); Guilds.push_back(g); query = StringFormat("INSERT INTO `lfguild` " "(`type`, `name`, `comment`, `fromlevel`, `tolevel`, " "`classes`, `aacount`, `timezone`, `timeposted`) " "VALUES (1, '%s', '%s', %u, %u, %u, %u, %u, %u)", GuildName, Comments, FromLevel, ToLevel, Classes, AACount, TimeZone, Now); auto results = database.QueryDatabase(query); } auto pack = new ServerPacket(ServerOP_LFGuildUpdate, strlen(GuildName) + strlen(Comments) + 30); pack->WriteString(GuildName); pack->WriteString(Comments); pack->WriteUInt32(FromLevel); pack->WriteUInt32(ToLevel); pack->WriteUInt32(Classes); pack->WriteUInt32(AACount); pack->WriteUInt32(TimeZone); pack->WriteUInt32(Now); pack->WriteUInt32(Toggle); worldserver->SendPacket(pack); safe_delete(pack); } void LFGuildManager::ExpireEntries() { for(auto it = Players.begin(); it != Players.end(); ++it) { if((*it).TimePosted + 604800 > (uint32)time(nullptr)) continue; std::string query = StringFormat("DELETE from `lfguild` WHERE `type` = 0 AND `name` = '%s'", (*it).Name.c_str()); auto results = database.QueryDatabase(query); if(!results.Success()) it = Players.erase(it); } for(auto it2 = Guilds.begin(); it2 != Guilds.end(); ++it2) { if((*it2).TimePosted + 2592000 > time(nullptr)) continue; std::string query = StringFormat("DELETE from `lfguild` WHERE `type` = 1 AND `name` = '%s'", (*it2).Name.c_str()); auto results = database.QueryDatabase(query); if(!results.Success()) it2 = Guilds.erase(it2); } } void LFGuildManager::SendPlayerStatus(uint32 FromZoneID, uint32 FromInstanceID, char *From) { std::list::iterator it; for(it = Players.begin(); it != Players.end(); ++it) { if(!strcasecmp((*it).Name.c_str(), From)) { auto pack = new ServerPacket(ServerOP_QueryServGeneric, strlen(From) + (*it).Comments.length() + 30); pack->WriteUInt32(FromZoneID); pack->WriteUInt32(FromInstanceID); pack->WriteString(From); pack->WriteUInt32(QSG_LFGuild); pack->WriteUInt32(QSG_LFGuild_RequestPlayerInfo); pack->WriteString((*it).Comments.c_str()); pack->WriteUInt32((*it).TimeZone); pack->WriteUInt32((*it).TimePosted); pack->WriteUInt32(1); worldserver->SendPacket(pack); safe_delete(pack); break; } } } void LFGuildManager::SendGuildStatus(uint32 FromZoneID, uint32 FromInstanceID, char *From, char *GuildName) { std::list::iterator it; for(it = Guilds.begin(); it != Guilds.end(); ++it) { if(!strcasecmp((*it).Name.c_str(), GuildName)) { auto pack = new ServerPacket(ServerOP_QueryServGeneric, strlen(From) + (*it).Comments.length() + 42); pack->WriteUInt32(FromZoneID); pack->WriteUInt32(FromInstanceID); pack->WriteString(From); pack->WriteUInt32(QSG_LFGuild); pack->WriteUInt32(QSG_LFGuild_RequestGuildInfo); pack->WriteString((*it).Comments.c_str()); pack->WriteUInt32((*it).FromLevel); pack->WriteUInt32((*it).ToLevel); pack->WriteUInt32((*it).Classes); pack->WriteUInt32((*it).AACount); pack->WriteUInt32((*it).TimeZone); pack->WriteUInt32((*it).TimePosted); worldserver->SendPacket(pack); safe_delete(pack); break; } } }