eqemu-server/world/adventure_manager.cpp
Alex King dc261bb203
[Code] ZSList Global to Singleton Cleanup (#4940)
* [Code] ZSList Global to Singleton Cleanup

* Final

* Post merge fixes

---------

Co-authored-by: Chris Miles <akkadius1@gmail.com>
2025-06-25 15:16:44 -05:00

2158 lines
56 KiB
C++

#include "../common/global_define.h"
#include "../common/misc_functions.h"
#include "../common/strings.h"
#include "../common/servertalk.h"
#include "../common/rulesys.h"
#include "../common/random.h"
#include "adventure.h"
#include "adventure_manager.h"
#include "worlddb.h"
#include "zonelist.h"
#include "clientlist.h"
#include "cliententry.h"
#include "../common/zone_store.h"
#include <sstream>
#include <stdio.h>
extern ClientList client_list;
AdventureManager::AdventureManager()
{
process_timer = new Timer(500);
save_timer = new Timer(90000);
leaderboard_info_timer = new Timer(180000);
}
AdventureManager::~AdventureManager()
{
safe_delete(process_timer);
safe_delete(save_timer);
safe_delete(leaderboard_info_timer);
for (auto &elem : adventure_templates)
delete elem.second;
}
void AdventureManager::Process()
{
if(process_timer->Check())
{
auto iter = adventure_list.begin();
while(iter != adventure_list.end())
{
if(!(*iter)->Process())
{
Adventure *adv = (*iter);
iter = adventure_list.erase(iter);
GetAdventureData(adv);
delete adv;
continue;
}
++iter;
}
}
if(leaderboard_info_timer->Check())
{
LoadLeaderboardInfo();
}
if(save_timer->Check())
{
Save();
}
}
void AdventureManager::CalculateAdventureRequestReply(const char *data)
{
ServerAdventureRequest_Struct *sar = (ServerAdventureRequest_Struct*)data;
ClientListEntry *leader = ClientList::Instance()->FindCharacter(sar->leader);
if(!leader)
{
return;
}
/**
* This block checks to see if we actually have any adventures for the requested theme.
*/
auto adv_list_iter = adventure_entries.find(sar->template_id);
if(adv_list_iter == adventure_entries.end())
{
auto pack = new ServerPacket(ServerOP_AdventureRequestDeny, sizeof(ServerAdventureRequestDeny_Struct));
ServerAdventureRequestDeny_Struct *deny = (ServerAdventureRequestDeny_Struct*)pack->pBuffer;
strcpy(deny->leader, sar->leader);
strcpy(deny->reason, "There are currently no adventures set for this theme.");
ZSList::Instance()->SendPacket(leader->zone(), leader->instance(), pack);
delete pack;
return;
}
/**
* This block checks to see if our requested group has anyone with an "Active" adventure
* Active being in progress, finished adventures that are still waiting to expire do not count
* Though they will count against you for which new adventure you can get.
*/
auto iter = adventure_list.begin();
while(iter != adventure_list.end())
{
Adventure* current = (*iter);
if(current->IsActive())
{
for(int i = 0; i < sar->member_count; ++i)
{
if(current->PlayerExists((data + sizeof(ServerAdventureRequest_Struct) + (64 * i))))
{
auto pack = new ServerPacket(ServerOP_AdventureRequestDeny,
sizeof(ServerAdventureRequestDeny_Struct));
ServerAdventureRequestDeny_Struct *deny = (ServerAdventureRequestDeny_Struct*)pack->pBuffer;
strcpy(deny->leader, sar->leader);
std::stringstream ss(std::stringstream::out | std::stringstream::in);
ss << (data + sizeof(ServerAdventureRequest_Struct) + (64 * i)) << " is already apart of an active adventure.";
strcpy(deny->reason, ss.str().c_str());
ZSList::Instance()->SendPacket(leader->zone(), leader->instance(), pack);
delete pack;
return;
}
}
}
++iter;
}
/**
* Now we need to get every available adventure for our selected theme and exclude ones we can't use.
* ie. the ones that would cause overlap issues for new adventures with the old unexpired adventures.
*/
std::list<AdventureZones> excluded_zones;
std::list<AdventureZoneIn> excluded_zone_ins;
for(int i = 0; i < sar->member_count; ++i)
{
int finished_adventures_count;
Adventure **finished_adventures = GetFinishedAdventures((data + sizeof(ServerAdventureRequest_Struct) + (64 * i)), finished_adventures_count);
for(int i = 0; i < finished_adventures_count; ++i)
{
if(!IsInExcludedZoneList(excluded_zones, finished_adventures[i]->GetTemplate()->zone, finished_adventures[i]->GetTemplate()->zone_version))
{
AdventureZones adv;
adv.zone = finished_adventures[i]->GetTemplate()->zone;
adv.version = finished_adventures[i]->GetTemplate()->zone_version;
excluded_zones.push_back(adv);
}
if(!IsInExcludedZoneInList(excluded_zone_ins, finished_adventures[i]->GetTemplate()->zone_in_zone_id,
finished_adventures[i]->GetTemplate()->zone_in_object_id))
{
AdventureZoneIn adv;
adv.door_id = finished_adventures[i]->GetTemplate()->zone_in_object_id;
adv.zone_id = finished_adventures[i]->GetTemplate()->zone_in_zone_id;
excluded_zone_ins.push_back(adv);
}
}
safe_delete_array(finished_adventures);
}
std::list<AdventureTemplate*> eligible_adventures = adventure_entries[sar->template_id];
/**
* Remove zones from eligible zones based on their difficulty and type.
* ie only use difficult zones for difficult, collect for collect, etc.
*/
auto ea_iter = eligible_adventures.begin();
while(ea_iter != eligible_adventures.end())
{
if((*ea_iter)->is_hard != ((sar->risk == 2) ? true : false))
{
ea_iter = eligible_adventures.erase(ea_iter);
continue;
}
if(sar->type != 0 && sar->type != (*ea_iter)->type)
{
ea_iter = eligible_adventures.erase(ea_iter);
continue;
}
++ea_iter;
}
/**
* Get levels for this group.
*/
int valid_count = 0;
int avg_level = 0;
int min_level = 40000;
int max_level = 0;
for(int i = 0; i < sar->member_count; ++i)
{
ClientListEntry *current = ClientList::Instance()->FindCharacter((data + sizeof(ServerAdventureRequest_Struct) + (64 * i)));
if(current)
{
int lvl = current->level();
if(lvl != 0)
{
avg_level += lvl;
valid_count++;
if(lvl < min_level)
{
min_level = lvl;
}
if(lvl > max_level)
{
max_level = lvl;
}
}
else
{
if(database.GetCharacterLevel((data + sizeof(ServerAdventureRequest_Struct) + (64 * i)), lvl))
{
avg_level += lvl;
valid_count++;
if(lvl < min_level)
{
min_level = lvl;
}
if(lvl > max_level)
{
max_level = lvl;
}
}
}
}
else
{
int lvl = 0;
if(database.GetCharacterLevel((data + sizeof(ServerAdventureRequest_Struct) + (64 * i)), lvl))
{
avg_level += lvl;
valid_count++;
if(lvl < min_level)
{
min_level = lvl;
}
if(lvl > max_level)
{
max_level = lvl;
}
}
}
}
if(valid_count == 0)
{
auto pack = new ServerPacket(ServerOP_AdventureRequestDeny, sizeof(ServerAdventureRequestDeny_Struct));
ServerAdventureRequestDeny_Struct *deny = (ServerAdventureRequestDeny_Struct*)pack->pBuffer;
strcpy(deny->leader, sar->leader);
strcpy(deny->reason, "The number of found players for this adventure was zero.");
ZSList::Instance()->SendPacket(leader->zone(), leader->instance(), pack);
delete pack;
return;
}
avg_level = avg_level / valid_count;
if(max_level - min_level > RuleI(Adventure, MaxLevelRange))
{
auto pack = new ServerPacket(ServerOP_AdventureRequestDeny, sizeof(ServerAdventureRequestDeny_Struct));
ServerAdventureRequestDeny_Struct *deny = (ServerAdventureRequestDeny_Struct*)pack->pBuffer;
strcpy(deny->leader, sar->leader);
std::stringstream ss(std::stringstream::out | std::stringstream::in);
ss << "The maximum level range for this adventure is " << RuleI(Adventure, MaxLevelRange);
ss << " but the level range calculated was " << (max_level - min_level) << ".";
strcpy(deny->reason, ss.str().c_str());
ZSList::Instance()->SendPacket(leader->zone(), leader->instance(), pack);
delete pack;
return;
}
/**
* Remove the zones from our eligible zones based on the exclusion above
*/
auto ez_iter = excluded_zones.begin();
while(ez_iter != excluded_zones.end())
{
auto ea_iter = eligible_adventures.begin();
while(ea_iter != eligible_adventures.end())
{
if((*ez_iter).zone.compare((*ea_iter)->zone) == 0 && (*ez_iter).version == (*ea_iter)->zone_version)
{
ea_iter = eligible_adventures.erase(ea_iter);
continue;
}
++ea_iter;
}
++ez_iter;
}
auto ezi_iter = excluded_zone_ins.begin();
while(ezi_iter != excluded_zone_ins.end())
{
auto ea_iter = eligible_adventures.begin();
while(ea_iter != eligible_adventures.end())
{
if((*ezi_iter).zone_id == (*ea_iter)->zone_in_zone_id && (*ezi_iter).door_id == (*ea_iter)->zone_in_object_id)
{
ea_iter = eligible_adventures.erase(ea_iter);
continue;
}
++ea_iter;
}
++ezi_iter;
}
/**
* Remove Zones based on level
*/
ea_iter = eligible_adventures.begin();
while(ea_iter != eligible_adventures.end())
{
if((*ea_iter)->min_level > avg_level)
{
ea_iter = eligible_adventures.erase(ea_iter);
continue;
}
if((*ea_iter)->max_level < avg_level)
{
ea_iter = eligible_adventures.erase(ea_iter);
continue;
}
++ea_iter;
}
if(eligible_adventures.size() > 0)
{
ea_iter = eligible_adventures.begin();
int c_index = EQ::Random::Instance()->Int(0, (eligible_adventures.size()-1));
for(int i = 0; i < c_index; ++i)
{
++ea_iter;
}
auto pack = new ServerPacket(ServerOP_AdventureRequestAccept,
sizeof(ServerAdventureRequestAccept_Struct) + (sar->member_count * 64));
ServerAdventureRequestAccept_Struct *sra = (ServerAdventureRequestAccept_Struct*)pack->pBuffer;
strcpy(sra->leader, sar->leader);
strcpy(sra->text, (*ea_iter)->text);
sra->theme = sar->template_id;
sra->id = (*ea_iter)->id;
sra->member_count = sar->member_count;
memcpy((pack->pBuffer + sizeof(ServerAdventureRequestAccept_Struct)), (data + sizeof(ServerAdventureRequest_Struct)), (sar->member_count * 64));
ZSList::Instance()->SendPacket(leader->zone(), leader->instance(), pack);
delete pack;
return;
}
else
{
auto pack = new ServerPacket(ServerOP_AdventureRequestDeny, sizeof(ServerAdventureRequestDeny_Struct));
ServerAdventureRequestDeny_Struct *deny = (ServerAdventureRequestDeny_Struct*)pack->pBuffer;
strcpy(deny->leader, sar->leader);
strcpy(deny->reason, "The number of adventures returned was zero.");
ZSList::Instance()->SendPacket(leader->zone(), leader->instance(), pack);
delete pack;
return;
}
}
void AdventureManager::TryAdventureCreate(const char *data)
{
ServerAdventureRequestCreate_Struct *src = (ServerAdventureRequestCreate_Struct*)data;
ClientListEntry *leader = ClientList::Instance()->FindCharacter(src->leader);
if(!leader)
{
return;
}
AdventureTemplate *adv_template = GetAdventureTemplate(src->theme, src->id);
if(!adv_template)
{
auto pack = new ServerPacket(ServerOP_AdventureCreateDeny, 64);
strcpy((char*)pack->pBuffer, src->leader);
ZSList::Instance()->SendPacket(leader->zone(), leader->instance(), pack);
delete pack;
return;
}
auto adv = new Adventure(adv_template);
if(!adv->CreateInstance())
{
auto pack = new ServerPacket(ServerOP_AdventureCreateDeny, 64);
strcpy((char*)pack->pBuffer, src->leader);
ZSList::Instance()->SendPacket(leader->zone(), leader->instance(), pack);
delete pack;
delete adv;
return;
}
for(int i = 0; i < src->member_count; ++i)
{
Adventure *a = GetActiveAdventure((data + sizeof(ServerAdventureRequestCreate_Struct) + (64 * i)));
if(a)
{
auto pack = new ServerPacket(ServerOP_AdventureCreateDeny, 64);
strcpy((char*)pack->pBuffer, src->leader);
ZSList::Instance()->SendPacket(leader->zone(), leader->instance(), pack);
delete pack;
delete adv;
return;
}
adv->AddPlayer((data + sizeof(ServerAdventureRequestCreate_Struct) + (64 * i)));
}
//Need to send adventure data to zone server for each client.
for(int i = 0; i < src->member_count; ++i)
{
ClientListEntry *player = ClientList::Instance()->FindCharacter((data + sizeof(ServerAdventureRequestCreate_Struct) + (64 * i)));
if(player)
{
int f_count = 0;
Adventure** finished_adventures = GetFinishedAdventures((data + sizeof(ServerAdventureRequestCreate_Struct) + (64 * i)), f_count);
auto pack = new ServerPacket(ServerOP_AdventureData,
sizeof(ServerSendAdventureData_Struct) +
(sizeof(ServerFinishedAdventures_Struct) * f_count));
ServerSendAdventureData_Struct *sca = (ServerSendAdventureData_Struct*)pack->pBuffer;
strcpy(sca->player, (data + sizeof(ServerAdventureRequestCreate_Struct) + (64 * i)));
strcpy(sca->text, adv_template->text);
sca->time_left = adv_template->zone_in_time;
sca->time_to_enter = adv_template->zone_in_time;
sca->risk = adv_template->is_hard ? 1 : 0;
sca->x = adv_template->zone_in_x;
sca->y = adv_template->zone_in_y;
sca->zone_in_id = adv_template->zone_in_zone_id;
sca->zone_in_object = adv_template->zone_in_object_id;
sca->instance_id = adv->GetInstanceID();
sca->count = 0;
sca->total = adv_template->type_count;
sca->finished_adventures = f_count;
for(int f = 0; f < f_count; ++f)
{
ServerFinishedAdventures_Struct *sfa = (ServerFinishedAdventures_Struct*)(pack->pBuffer
+ sizeof(ServerSendAdventureData_Struct)
+ (sizeof(ServerFinishedAdventures_Struct) * f));
sfa->zone_in_id = finished_adventures[f]->GetTemplate()->zone_in_zone_id;
sfa->zone_in_object = finished_adventures[f]->GetTemplate()->zone_in_object_id;
}
ZSList::Instance()->SendPacket(player->zone(), player->instance(), pack);
safe_delete_array(finished_adventures);
delete pack;
}
}
adventure_list.push_back(adv);
}
void AdventureManager::GetAdventureData(Adventure *adv)
{
std::list<std::string> player_list = adv->GetPlayers();
auto iter = player_list.begin();
while(iter != player_list.end())
{
GetAdventureData((*iter).c_str());
++iter;
}
}
void AdventureManager::GetAdventureData(const char *name)
{
ClientListEntry *player = ClientList::Instance()->FindCharacter(name);
if(player)
{
int f_count = 0;
Adventure** finished_adventures = GetFinishedAdventures(name, f_count);
Adventure *current = GetActiveAdventure(name);
auto pack =
new ServerPacket(ServerOP_AdventureData, sizeof(ServerSendAdventureData_Struct) +
(sizeof(ServerFinishedAdventures_Struct) * f_count));
ServerSendAdventureData_Struct *sca = (ServerSendAdventureData_Struct*)pack->pBuffer;
if(current)
{
const AdventureTemplate *adv_template = current->GetTemplate();
strcpy(sca->player, name);
strcpy(sca->text, adv_template->text);
sca->risk = adv_template->is_hard ? 1 : 0;
sca->x = adv_template->zone_in_x;
sca->y = adv_template->zone_in_y;
sca->zone_in_id = adv_template->zone_in_zone_id;
sca->zone_in_object = adv_template->zone_in_object_id;
sca->count = current->GetCount();
sca->total = adv_template->type_count;
sca->time_left = current->GetRemainingTime();
if(current->GetStatus() == AS_WaitingForZoneIn)
{
sca->time_to_enter = sca->time_left;
}
}
else
{
//We have no mission and no finished missions
//Delete our stuff and return instead of sending a blank packet.
if(f_count == 0)
{
delete pack;
auto pack = new ServerPacket(ServerOP_AdventureDataClear, 64);
strcpy((char*)pack->pBuffer, name);
ZSList::Instance()->SendPacket(player->zone(), player->instance(), pack);
delete pack;
delete[] finished_adventures;
return;
}
}
sca->finished_adventures = f_count;
for(int i = 0; i < f_count; ++i)
{
ServerFinishedAdventures_Struct *sfa = (ServerFinishedAdventures_Struct*)(pack->pBuffer
+ sizeof(ServerSendAdventureData_Struct)
+ (sizeof(ServerFinishedAdventures_Struct) * i));
sfa->zone_in_id = finished_adventures[i]->GetTemplate()->zone_in_zone_id;
sfa->zone_in_object = finished_adventures[i]->GetTemplate()->zone_in_object_id;
}
ZSList::Instance()->SendPacket(player->zone(), player->instance(), pack);
safe_delete_array(finished_adventures);
delete pack;
delete[] finished_adventures;
}
}
bool AdventureManager::IsInExcludedZoneList(std::list<AdventureZones> excluded_zones, std::string zone_name, int version)
{
auto iter = excluded_zones.begin();
while(iter != excluded_zones.end())
{
if(((*iter).zone.compare(zone_name) == 0) && ((*iter).version == version))
{
return true;
}
++iter;
}
return false;
}
bool AdventureManager::IsInExcludedZoneInList(std::list<AdventureZoneIn> excluded_zone_ins, int zone_id, int door_object)
{
auto iter = excluded_zone_ins.begin();
while(iter != excluded_zone_ins.end())
{
if(((*iter).zone_id == zone_id) && ((*iter).door_id == door_object))
{
return true;
}
++iter;
}
return false;
}
Adventure **AdventureManager::GetFinishedAdventures(const char *player, int &count)
{
Adventure **ret = nullptr;
count = 0;
auto iter = adventure_list.begin();
while(iter != adventure_list.end())
{
if((*iter)->PlayerExists(player))
{
if(!(*iter)->IsActive())
{
if(ret)
{
auto t = new Adventure *[count + 1];
for(int i = 0; i < count; i++)
{
t[i] = ret[i];
}
t[count] = (*iter);
delete[] ret;
ret = t;
}
else
{
ret = new Adventure*[1];
ret[0] = (*iter);
}
count++;
}
}
++iter;
}
return ret;
}
Adventure *AdventureManager::GetActiveAdventure(const char *player)
{
auto iter = adventure_list.begin();
while(iter != adventure_list.end())
{
if((*iter)->PlayerExists(player) && (*iter)->IsActive())
{
return (*iter);
}
++iter;
}
return nullptr;
}
AdventureTemplate *AdventureManager::GetAdventureTemplate(int theme, int id)
{
auto iter = adventure_entries.find(theme);
if(iter == adventure_entries.end())
{
return nullptr;
}
auto l_iter = (*iter).second.begin();
while(l_iter != (*iter).second.end())
{
if((*l_iter)->id == id)
{
return (*l_iter);
}
++l_iter;
}
return nullptr;
}
AdventureTemplate *AdventureManager::GetAdventureTemplate(int id)
{
auto iter = adventure_templates.find(id);
if(iter == adventure_templates.end())
{
return nullptr;
}
return iter->second;
}
bool AdventureManager::LoadAdventureTemplates()
{
std::string query =
SQL (
SELECT
id,
zone,
zone_version,
is_hard,
min_level,
max_level,
type,
type_data,
type_count,
assa_x,
assa_y,
assa_z,
assa_h,
text,
duration,
zone_in_time,
win_points,
lose_points,
theme,
zone_in_zone_id,
zone_in_x,
zone_in_y,
zone_in_object_id,
dest_x,
dest_y,
dest_z,
dest_h,
graveyard_zone_id,
graveyard_x,
graveyard_y,
graveyard_z,
graveyard_radius
FROM
adventure_template
)
;
auto results = content_db.QueryDatabase(query);
if (!results.Success()) {
return false;
}
for (auto row = results.begin(); row != results.end(); ++row) {
auto adventure_template = new AdventureTemplate;
adventure_template->id = Strings::ToInt(row[0]);
strcpy(adventure_template->zone, row[1]);
adventure_template->zone_version = Strings::ToInt(row[2]);
adventure_template->is_hard = Strings::ToInt(row[3]);
adventure_template->min_level = Strings::ToInt(row[4]);
adventure_template->max_level = Strings::ToInt(row[5]);
adventure_template->type = Strings::ToInt(row[6]);
adventure_template->type_data = Strings::ToInt(row[7]);
adventure_template->type_count = Strings::ToInt(row[8]);
adventure_template->assa_x = Strings::ToFloat(row[9]);
adventure_template->assa_y = Strings::ToFloat(row[10]);
adventure_template->assa_z = Strings::ToFloat(row[11]);
adventure_template->assa_h = Strings::ToFloat(row[12]);
strn0cpy(adventure_template->text, row[13], sizeof(adventure_template->text));
adventure_template->duration = Strings::ToInt(row[14]);
adventure_template->zone_in_time = Strings::ToInt(row[15]);
adventure_template->win_points = Strings::ToInt(row[16]);
adventure_template->lose_points = Strings::ToInt(row[17]);
adventure_template->theme = Strings::ToInt(row[18]);
adventure_template->zone_in_zone_id = Strings::ToInt(row[19]);
adventure_template->zone_in_x = Strings::ToFloat(row[20]);
adventure_template->zone_in_y = Strings::ToFloat(row[21]);
adventure_template->zone_in_object_id = Strings::ToInt(row[22]);
adventure_template->dest_x = Strings::ToFloat(row[23]);
adventure_template->dest_y = Strings::ToFloat(row[24]);
adventure_template->dest_z = Strings::ToFloat(row[25]);
adventure_template->dest_h = Strings::ToFloat(row[26]);
adventure_template->graveyard_zone_id = Strings::ToInt(row[27]);
adventure_template->graveyard_x = Strings::ToFloat(row[28]);
adventure_template->graveyard_y = Strings::ToFloat(row[29]);
adventure_template->graveyard_z = Strings::ToFloat(row[30]);
adventure_template->graveyard_radius = Strings::ToFloat(row[31]);
adventure_templates[adventure_template->id] = adventure_template;
}
return true;
}
bool AdventureManager::LoadAdventureEntries()
{
std::string query = "SELECT id, template_id FROM adventure_template_entry";
auto results = content_db.QueryDatabase(query);
if (!results.Success())
{
return false;
}
for (auto row = results.begin(); row != results.end(); ++row)
{
int id = Strings::ToInt(row[0]);
int template_id = Strings::ToInt(row[1]);
AdventureTemplate* tid = nullptr;
auto t_iter = adventure_templates.find(template_id);
if(t_iter == adventure_templates.end())
continue;
tid = adventure_templates[template_id];
std::list<AdventureTemplate*> temp;
auto iter = adventure_entries.find(id);
if(iter != adventure_entries.end())
temp = adventure_entries[id];
temp.push_back(tid);
adventure_entries[id] = temp;
}
return true;
}
void AdventureManager::PlayerClickedDoor(const char *player, int zone_id, int door_id)
{
auto iter = adventure_list.begin();
while(iter != adventure_list.end())
{
const AdventureTemplate *t = (*iter)->GetTemplate();
if(t->zone_in_zone_id == zone_id && t->zone_in_object_id == door_id)
{
if((*iter)->PlayerExists(player))
{
ClientListEntry *pc = ClientList::Instance()->FindCharacter(player);
if(pc)
{
auto pack =
new ServerPacket(ServerOP_AdventureClickDoorReply,
sizeof(ServerPlayerClickedAdventureDoorReply_Struct));
ServerPlayerClickedAdventureDoorReply_Struct *sr = (ServerPlayerClickedAdventureDoorReply_Struct*)pack->pBuffer;
strcpy(sr->player, player);
sr->zone_id = ZoneID(t->zone);
sr->instance_id = (*iter)->GetInstanceID();
sr->x = t->dest_x;
sr->y = t->dest_y;
sr->z = t->dest_z;
sr->h = t->dest_h;
if((*iter)->GetStatus() == AS_WaitingForZoneIn)
{
(*iter)->SetStatus(AS_WaitingForPrimaryEndTime);
}
ZSList::Instance()->SendPacket(pc->zone(), pc->instance(), pack);
safe_delete(pack);
}
return;
}
}
++iter;
}
ClientListEntry *pc = ClientList::Instance()->FindCharacter(player);
if(pc)
{
auto pack = new ServerPacket(ServerOP_AdventureClickDoorError, 64);
strcpy((char*)pack->pBuffer, player);
ZSList::Instance()->SendPacket(pc->zone(), pc->instance(), pack);
safe_delete(pack);
}
}
void AdventureManager::LeaveAdventure(const char *name)
{
ClientListEntry *pc = ClientList::Instance()->FindCharacter(name);
if(pc)
{
Adventure *current = GetActiveAdventure(name);
if(current)
{
if(pc->instance() != 0 && pc->instance() == current->GetInstanceID())
{
auto pack = new ServerPacket(ServerOP_AdventureLeaveDeny, 64);
strcpy((char*)pack->pBuffer, name);
ZSList::Instance()->SendPacket(pc->zone(), pc->instance(), pack);
safe_delete(pack);
}
else
{
if(current->GetStatus() != AS_WaitingForZoneIn)
{
database.UpdateAdventureStatsEntry(database.GetCharacterID(name), current->GetTemplate()->theme, false);
}
current->RemovePlayer(name);
auto pack = new ServerPacket(ServerOP_AdventureLeaveReply, 64);
strcpy((char*)pack->pBuffer, name);
ZSList::Instance()->SendPacket(pc->zone(), pc->instance(), pack);
safe_delete(pack);
}
}
else
{
auto pack = new ServerPacket(ServerOP_AdventureLeaveReply, 64);
strcpy((char*)pack->pBuffer, name);
ZSList::Instance()->SendPacket(pc->zone(), pc->instance(), pack);
safe_delete(pack);
}
}
}
void AdventureManager::IncrementCount(uint16 instance_id)
{
auto iter = adventure_list.begin();
Adventure *current = nullptr;
while(iter != adventure_list.end())
{
if((*iter)->GetInstanceID() == instance_id)
{
current = (*iter);
break;
}
++iter;
}
if(current)
{
current->IncrementCount();
std::list<std::string> slist = current->GetPlayers();
auto siter = slist.begin();
auto pack = new ServerPacket(ServerOP_AdventureCountUpdate, sizeof(ServerAdventureCountUpdate_Struct));
ServerAdventureCountUpdate_Struct *ac = (ServerAdventureCountUpdate_Struct*)pack->pBuffer;
ac->count = current->GetCount();
ac->total = current->GetTemplate()->type_count;
while(siter != slist.end())
{
ClientListEntry *pc = ClientList::Instance()->FindCharacter((*siter).c_str());
if(pc)
{
memset(ac->player, 0, 64);
strcpy(ac->player, (*siter).c_str());
ZSList::Instance()->SendPacket(pc->zone(), pc->instance(), pack);
}
++siter;
}
delete pack;
}
}
void AdventureManager::IncrementAssassinationCount(uint16 instance_id)
{
auto iter = adventure_list.begin();
Adventure *current = nullptr;
while(iter != adventure_list.end())
{
if((*iter)->GetInstanceID() == instance_id)
{
current = (*iter);
break;
}
++iter;
}
if(current)
{
current->IncrementAssassinationCount();
}
}
void AdventureManager::GetZoneData(uint16 instance_id)
{
auto iter = adventure_list.begin();
Adventure *current = nullptr;
while(iter != adventure_list.end())
{
if((*iter)->GetInstanceID() == instance_id)
{
current = (*iter);
break;
}
++iter;
}
if(current)
{
auto pack = new ServerPacket(ServerOP_AdventureZoneData, sizeof(ServerZoneAdventureDataReply_Struct));
ServerZoneAdventureDataReply_Struct *zd = (ServerZoneAdventureDataReply_Struct*)pack->pBuffer;
const AdventureTemplate* temp = current->GetTemplate();
zd->instance_id = instance_id;
zd->count = current->GetCount();
zd->total = temp->type_count;
zd->type = temp->type;
zd->data_id = temp->type_data;
zd->assa_count = current->GetAssassinationCount();
zd->assa_x = temp->assa_x;
zd->assa_y = temp->assa_y;
zd->assa_z = temp->assa_z;
zd->assa_h = temp->assa_h;
zd->dest_x = temp->dest_x;
zd->dest_y = temp->dest_y;
zd->dest_z = temp->dest_z;
zd->dest_h = temp->dest_h;
ZSList::Instance()->SendPacket(0, instance_id, pack);
delete pack;
}
}
// Sort the leaderboard by wins.
bool pred_sort_by_win_count(const LeaderboardInfo &lbi1, const LeaderboardInfo &lbi2)
{
return lbi1.wins > lbi2.wins;
}
// Sort the leaderboard by win percentage.
bool pred_sort_by_win_percentage(const LeaderboardInfo &lbi1, const LeaderboardInfo &lbi2)
{
int per1 = 10000;
int per2 = 10000;
if(lbi1.wins + lbi1.losses != 0)
{
per1 = (lbi1.wins * 10000 / (lbi1.wins + lbi1.losses));
}
if(lbi2.wins + lbi2.losses != 0)
{
per1 = (lbi2.wins * 10000 / (lbi2.wins + lbi2.losses));
}
return per1 > per2;
}
// Sort the leaderboard by wins(guk).
bool pred_sort_by_win_count_guk(const LeaderboardInfo &lbi1, const LeaderboardInfo &lbi2)
{
return lbi1.guk_wins > lbi2.guk_wins;
}
// Sort the leaderboard by win percentage(guk).
bool pred_sort_by_win_percentage_guk(const LeaderboardInfo &lbi1, const LeaderboardInfo &lbi2)
{
int per1 = 10000;
int per2 = 10000;
if(lbi1.guk_wins + lbi1.guk_losses != 0)
{
per1 = (lbi1.guk_wins * 10000 / (lbi1.guk_wins + lbi1.guk_losses));
}
if(lbi2.guk_wins + lbi2.guk_losses != 0)
{
per1 = (lbi2.guk_wins * 10000 / (lbi2.guk_wins + lbi2.guk_losses));
}
return per1 > per2;
}
// Sort the leaderboard by wins(mir).
bool pred_sort_by_win_count_mir(const LeaderboardInfo &lbi1, const LeaderboardInfo &lbi2)
{
return lbi1.mir_wins > lbi2.mir_wins;
}
// Sort the leaderboard by win percentage(mir).
bool pred_sort_by_win_percentage_mir(const LeaderboardInfo &lbi1, const LeaderboardInfo &lbi2)
{
int per1 = 10000;
int per2 = 10000;
if(lbi1.mir_wins + lbi1.mir_losses != 0)
{
per1 = (lbi1.mir_wins * 10000 / (lbi1.mir_wins + lbi1.mir_losses));
}
if(lbi2.mir_wins + lbi2.mir_losses != 0)
{
per1 = (lbi2.mir_wins * 10000 / (lbi2.mir_wins + lbi2.mir_losses));
}
return per1 > per2;
}
// Sort the leaderboard by wins(mmc).
bool pred_sort_by_win_count_mmc(const LeaderboardInfo &lbi1, const LeaderboardInfo &lbi2)
{
return lbi1.mmc_wins > lbi2.mmc_wins;
}
// Sort the leaderboard by win percentage(mmc).
bool pred_sort_by_win_percentage_mmc(const LeaderboardInfo &lbi1, const LeaderboardInfo &lbi2)
{
int per1 = 10000;
int per2 = 10000;
if(lbi1.mmc_wins + lbi1.mmc_losses != 0)
{
per1 = (lbi1.mmc_wins * 10000 / (lbi1.mmc_wins + lbi1.mmc_losses));
}
if(lbi2.mmc_wins + lbi2.mmc_losses != 0)
{
per1 = (lbi2.mmc_wins * 10000 / (lbi2.mmc_wins + lbi2.mmc_losses));
}
return per1 > per2;
}
// Sort the leaderboard by wins(ruj).
bool pred_sort_by_win_count_ruj(const LeaderboardInfo &lbi1, const LeaderboardInfo &lbi2)
{
return lbi1.ruj_wins > lbi2.ruj_wins;
}
// Sort the leaderboard by win percentage(ruj).
bool pred_sort_by_win_percentage_ruj(const LeaderboardInfo &lbi1, const LeaderboardInfo &lbi2)
{
int per1 = 10000;
int per2 = 10000;
if(lbi1.ruj_wins + lbi1.ruj_losses != 0)
{
per1 = (lbi1.ruj_wins * 10000 / (lbi1.ruj_wins + lbi1.ruj_losses));
}
if(lbi2.ruj_wins + lbi2.ruj_losses != 0)
{
per1 = (lbi2.ruj_wins * 10000 / (lbi2.ruj_wins + lbi2.ruj_losses));
}
return per1 > per2;
}
// Sort the leaderboard by wins(tak).
bool pred_sort_by_win_count_tak(const LeaderboardInfo &lbi1, const LeaderboardInfo &lbi2)
{
return lbi1.tak_wins > lbi2.tak_wins;
}
// Sort the leaderboard by win percentage(tak).
bool pred_sort_by_win_percentage_tak(const LeaderboardInfo &lbi1, const LeaderboardInfo &lbi2)
{
int per1 = 10000;
int per2 = 10000;
if(lbi1.tak_wins + lbi1.tak_losses != 0)
{
per1 = (lbi1.tak_wins * 10000 / (lbi1.tak_wins + lbi1.tak_losses));
}
if(lbi2.tak_wins + lbi2.tak_losses != 0)
{
per1 = (lbi2.tak_wins * 10000 / (lbi2.tak_wins + lbi2.tak_losses));
}
return per1 > per2;
}
void AdventureManager::LoadLeaderboardInfo()
{
leaderboard_info_wins.clear();
leaderboard_info_percentage.clear();
leaderboard_info_wins_guk.clear();
leaderboard_info_percentage_guk.clear();
leaderboard_info_wins_mir.clear();
leaderboard_info_percentage_mir.clear();
leaderboard_info_wins_mmc.clear();
leaderboard_info_percentage_mmc.clear();
leaderboard_info_wins_ruj.clear();
leaderboard_info_percentage_ruj.clear();
leaderboard_info_wins_tak.clear();
leaderboard_info_percentage_tak.clear();
std::string query = "SELECT ch.name, ch.id, adv_stats.* FROM adventure_stats "
"AS adv_stats LEFT JOIN `character_data` AS ch ON adv_stats.player_id = ch.id;";
auto results = database.QueryDatabase(query);
if(!results.Success()) {
return;
}
for (auto row = results.begin(); row != results.end(); ++row)
{
if(!row[0])
continue;
LeaderboardInfo lbi;
lbi.name = row[0];
lbi.wins = Strings::ToInt(row[3]);
lbi.guk_wins = Strings::ToInt(row[3]);
lbi.wins += Strings::ToInt(row[4]);
lbi.mir_wins = Strings::ToInt(row[4]);
lbi.wins += Strings::ToInt(row[5]);
lbi.mmc_wins = Strings::ToInt(row[5]);
lbi.wins += Strings::ToInt(row[6]);
lbi.ruj_wins = Strings::ToInt(row[6]);
lbi.wins += Strings::ToInt(row[7]);
lbi.tak_wins = Strings::ToInt(row[7]);
lbi.losses = Strings::ToInt(row[8]);
lbi.guk_losses = Strings::ToInt(row[8]);
lbi.losses += Strings::ToInt(row[9]);
lbi.mir_losses = Strings::ToInt(row[9]);
lbi.losses += Strings::ToInt(row[10]);
lbi.mmc_losses = Strings::ToInt(row[10]);
lbi.losses += Strings::ToInt(row[11]);
lbi.ruj_losses = Strings::ToInt(row[11]);
lbi.losses += Strings::ToInt(row[12]);
lbi.tak_losses = Strings::ToInt(row[12]);
leaderboard_info_wins.push_back(lbi);
leaderboard_info_percentage.push_back(lbi);
leaderboard_info_wins_guk.push_back(lbi);
leaderboard_info_percentage_guk.push_back(lbi);
leaderboard_info_wins_mir.push_back(lbi);
leaderboard_info_percentage_mir.push_back(lbi);
leaderboard_info_wins_mmc.push_back(lbi);
leaderboard_info_percentage_mmc.push_back(lbi);
leaderboard_info_wins_ruj.push_back(lbi);
leaderboard_info_percentage_ruj.push_back(lbi);
leaderboard_info_wins_tak.push_back(lbi);
leaderboard_info_percentage_tak.push_back(lbi);
leaderboard_sorted_wins = false;
leaderboard_sorted_percentage = false;
leaderboard_sorted_wins_guk = false;
leaderboard_sorted_percentage_guk = false;
leaderboard_sorted_wins_mir = false;
leaderboard_sorted_percentage_mir = false;
leaderboard_sorted_wins_mmc = false;
leaderboard_sorted_percentage_mmc = false;
leaderboard_sorted_wins_ruj = false;
leaderboard_sorted_percentage_ruj = false;
leaderboard_sorted_wins_tak = false;
leaderboard_sorted_percentage_tak = false;
}
};
void AdventureManager::DoLeaderboardRequest(const char* player, uint8 type)
{
switch(type)
{
case 1:
if(!leaderboard_sorted_wins)
{
leaderboard_info_wins.sort(pred_sort_by_win_count);
leaderboard_sorted_wins = true;
}
DoLeaderboardRequestWins(player);
break;
case 2:
if(!leaderboard_sorted_percentage)
{
leaderboard_info_percentage.sort(pred_sort_by_win_percentage);
leaderboard_sorted_percentage = true;
}
DoLeaderboardRequestPercentage(player);
break;
case 3:
if(!leaderboard_sorted_wins_guk)
{
leaderboard_info_wins_guk.sort(pred_sort_by_win_count_guk);
leaderboard_sorted_wins_guk = true;
}
DoLeaderboardRequestWinsGuk(player);
break;
case 4:
if(!leaderboard_sorted_percentage_guk)
{
leaderboard_info_percentage_guk.sort(pred_sort_by_win_percentage_guk);
leaderboard_sorted_percentage_guk = true;
}
DoLeaderboardRequestPercentageGuk(player);
break;
case 5:
if(!leaderboard_sorted_wins_mir)
{
leaderboard_info_wins_mir.sort(pred_sort_by_win_count_mir);
leaderboard_sorted_wins_mir = true;
}
DoLeaderboardRequestWinsMir(player);
break;
case 6:
if(!leaderboard_sorted_percentage_mir)
{
leaderboard_info_percentage_mir.sort(pred_sort_by_win_percentage_mir);
leaderboard_sorted_percentage_mir = true;
}
DoLeaderboardRequestPercentageMir(player);
break;
case 7:
if(!leaderboard_sorted_wins_mmc)
{
leaderboard_info_wins_mmc.sort(pred_sort_by_win_count_mmc);
leaderboard_sorted_wins_mmc = true;
}
DoLeaderboardRequestWinsMmc(player);
break;
case 8:
if(!leaderboard_sorted_percentage_mmc)
{
leaderboard_info_percentage_mmc.sort(pred_sort_by_win_percentage_mmc);
leaderboard_sorted_percentage_mmc = true;
}
DoLeaderboardRequestPercentageMmc(player);
break;
case 9:
if(!leaderboard_sorted_wins_ruj)
{
leaderboard_info_wins_ruj.sort(pred_sort_by_win_count_ruj);
leaderboard_sorted_wins_ruj = true;
}
DoLeaderboardRequestWinsRuj(player);
break;
case 10:
if(!leaderboard_sorted_percentage_ruj)
{
leaderboard_info_percentage_ruj.sort(pred_sort_by_win_percentage_ruj);
leaderboard_sorted_percentage_ruj = true;
}
DoLeaderboardRequestPercentageRuj(player);
break;
case 11:
if(!leaderboard_sorted_wins_tak)
{
leaderboard_info_wins_tak.sort(pred_sort_by_win_count_tak);
leaderboard_sorted_wins_tak = true;
}
DoLeaderboardRequestWinsTak(player);
break;
case 12:
if(!leaderboard_sorted_percentage_tak)
{
leaderboard_info_percentage_tak.sort(pred_sort_by_win_percentage_tak);
leaderboard_sorted_percentage_tak = true;
}
DoLeaderboardRequestPercentageTak(player);
break;
}
}
void AdventureManager::DoLeaderboardRequestWins(const char* player)
{
ClientListEntry *pc = ClientList::Instance()->FindCharacter(player);
if(pc)
{
auto pack = new ServerPacket(ServerOP_AdventureLeaderboard, 64 + sizeof(AdventureLeaderboard_Struct));
AdventureLeaderboard_Struct *al = (AdventureLeaderboard_Struct*)(pack->pBuffer + 64);
strcpy((char*)pack->pBuffer, player);
int place = -1;
int our_successes = 0;
int our_failures = 0;
int i = 0;
auto iter = leaderboard_info_wins.begin();
while(i < 100 && iter != leaderboard_info_wins.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.wins;
our_failures = li.losses;
}
al->entries[i].success = li.wins;
al->entries[i].failure = li.losses;
strcpy(al->entries[i].name, li.name.c_str());
i++;
++iter;
}
if(place == -1 && iter != leaderboard_info_wins.end())
{
while(iter != leaderboard_info_wins.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.wins;
our_failures = li.losses;
break;
}
i++;
++iter;
}
}
if(place == -1)
{
al->our_rank = leaderboard_info_wins.size() + 1;
al->success = 0;
al->failure = 0;
}
else
{
al->our_rank = place;
al->success = our_successes;
al->failure = our_failures;
}
ZSList::Instance()->SendPacket(pc->zone(), pc->instance(), pack);
delete pack;
}
}
void AdventureManager::DoLeaderboardRequestPercentage(const char* player)
{
ClientListEntry *pc = ClientList::Instance()->FindCharacter(player);
if(pc)
{
auto pack = new ServerPacket(ServerOP_AdventureLeaderboard, 64 + sizeof(AdventureLeaderboard_Struct));
AdventureLeaderboard_Struct *al = (AdventureLeaderboard_Struct*)(pack->pBuffer + 64);
strcpy((char*)pack->pBuffer, player);
int place = -1;
int our_successes = 0;
int our_failures = 0;
int i = 0;
auto iter = leaderboard_info_percentage.begin();
while(i < 100 && iter != leaderboard_info_percentage.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.wins;
our_failures = li.losses;
}
al->entries[i].success = li.wins;
al->entries[i].failure = li.losses;
strcpy(al->entries[i].name, li.name.c_str());
i++;
++iter;
}
if(place == -1 && iter != leaderboard_info_percentage.end())
{
while(iter != leaderboard_info_percentage.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.wins;
our_failures = li.losses;
break;
}
i++;
++iter;
}
}
if(place == -1)
{
al->our_rank = leaderboard_info_percentage.size() + 1;
al->success = 0;
al->failure = 0;
}
else
{
al->our_rank = place;
al->success = our_successes;
al->failure = our_failures;
}
ZSList::Instance()->SendPacket(pc->zone(), pc->instance(), pack);
delete pack;
}
}
void AdventureManager::DoLeaderboardRequestWinsGuk(const char* player)
{
ClientListEntry *pc = ClientList::Instance()->FindCharacter(player);
if(pc)
{
auto pack = new ServerPacket(ServerOP_AdventureLeaderboard, 64 + sizeof(AdventureLeaderboard_Struct));
AdventureLeaderboard_Struct *al = (AdventureLeaderboard_Struct*)(pack->pBuffer + 64);
strcpy((char*)pack->pBuffer, player);
int place = -1;
int our_successes = 0;
int our_failures = 0;
int i = 0;
auto iter = leaderboard_info_wins_guk.begin();
while(i < 100 && iter != leaderboard_info_wins_guk.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.guk_wins;
our_failures = li.guk_losses;
}
al->entries[i].success = li.guk_wins;
al->entries[i].failure = li.guk_losses;
strcpy(al->entries[i].name, li.name.c_str());
i++;
++iter;
}
if(place == -1 && iter != leaderboard_info_wins_guk.end())
{
while(iter != leaderboard_info_wins_guk.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.guk_wins;
our_failures = li.guk_losses;
break;
}
i++;
++iter;
}
}
if(place == -1)
{
al->our_rank = leaderboard_info_wins_guk.size() + 1;
al->success = 0;
al->failure = 0;
}
else
{
al->our_rank = place;
al->success = our_successes;
al->failure = our_failures;
}
ZSList::Instance()->SendPacket(pc->zone(), pc->instance(), pack);
delete pack;
}
}
void AdventureManager::DoLeaderboardRequestPercentageGuk(const char* player)
{
ClientListEntry *pc = ClientList::Instance()->FindCharacter(player);
if(pc)
{
auto pack = new ServerPacket(ServerOP_AdventureLeaderboard, 64 + sizeof(AdventureLeaderboard_Struct));
AdventureLeaderboard_Struct *al = (AdventureLeaderboard_Struct*)(pack->pBuffer + 64);
strcpy((char*)pack->pBuffer, player);
int place = -1;
int our_successes = 0;
int our_failures = 0;
int i = 0;
auto iter = leaderboard_info_percentage_guk.begin();
while(i < 100 && iter != leaderboard_info_percentage_guk.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.guk_wins;
our_failures = li.guk_losses;
}
al->entries[i].success = li.guk_wins;
al->entries[i].failure = li.guk_losses;
strcpy(al->entries[i].name, li.name.c_str());
i++;
++iter;
}
if(place == -1 && iter != leaderboard_info_percentage_guk.end())
{
while(iter != leaderboard_info_percentage_guk.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.guk_wins;
our_failures = li.guk_losses;
break;
}
i++;
++iter;
}
}
if(place == -1)
{
al->our_rank = leaderboard_info_percentage_guk.size() + 1;
al->success = 0;
al->failure = 0;
}
else
{
al->our_rank = place;
al->success = our_successes;
al->failure = our_failures;
}
ZSList::Instance()->SendPacket(pc->zone(), pc->instance(), pack);
delete pack;
}
}
void AdventureManager::DoLeaderboardRequestWinsMir(const char* player)
{
ClientListEntry *pc = ClientList::Instance()->FindCharacter(player);
if(pc)
{
auto pack = new ServerPacket(ServerOP_AdventureLeaderboard, 64 + sizeof(AdventureLeaderboard_Struct));
AdventureLeaderboard_Struct *al = (AdventureLeaderboard_Struct*)(pack->pBuffer + 64);
strcpy((char*)pack->pBuffer, player);
int place = -1;
int our_successes = 0;
int our_failures = 0;
int i = 0;
auto iter = leaderboard_info_wins_mir.begin();
while(i < 100 && iter != leaderboard_info_wins_mir.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.mir_wins;
our_failures = li.mir_losses;
}
al->entries[i].success = li.mir_wins;
al->entries[i].failure = li.mir_losses;
strcpy(al->entries[i].name, li.name.c_str());
i++;
++iter;
}
if(place == -1 && iter != leaderboard_info_wins_mir.end())
{
while(iter != leaderboard_info_wins_mir.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.mir_wins;
our_failures = li.mir_losses;
break;
}
i++;
++iter;
}
}
if(place == -1)
{
al->our_rank = leaderboard_info_wins_mir.size() + 1;
al->success = 0;
al->failure = 0;
}
else
{
al->our_rank = place;
al->success = our_successes;
al->failure = our_failures;
}
ZSList::Instance()->SendPacket(pc->zone(), pc->instance(), pack);
delete pack;
}
}
void AdventureManager::DoLeaderboardRequestPercentageMir(const char* player)
{
ClientListEntry *pc = ClientList::Instance()->FindCharacter(player);
if(pc)
{
auto pack = new ServerPacket(ServerOP_AdventureLeaderboard, 64 + sizeof(AdventureLeaderboard_Struct));
AdventureLeaderboard_Struct *al = (AdventureLeaderboard_Struct*)(pack->pBuffer + 64);
strcpy((char*)pack->pBuffer, player);
int place = -1;
int our_successes = 0;
int our_failures = 0;
int i = 0;
auto iter = leaderboard_info_percentage_mir.begin();
while(i < 100 && iter != leaderboard_info_percentage_mir.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.mir_wins;
our_failures = li.mir_losses;
}
al->entries[i].success = li.mir_wins;
al->entries[i].failure = li.mir_losses;
strcpy(al->entries[i].name, li.name.c_str());
i++;
++iter;
}
if(place == -1 && iter != leaderboard_info_percentage_mir.end())
{
while(iter != leaderboard_info_percentage_mir.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.mir_wins;
our_failures = li.mir_losses;
break;
}
i++;
++iter;
}
}
if(place == -1)
{
al->our_rank = leaderboard_info_percentage_mir.size() + 1;
al->success = 0;
al->failure = 0;
}
else
{
al->our_rank = place;
al->success = our_successes;
al->failure = our_failures;
}
ZSList::Instance()->SendPacket(pc->zone(), pc->instance(), pack);
delete pack;
}
}
void AdventureManager::DoLeaderboardRequestWinsMmc(const char* player)
{
ClientListEntry *pc = ClientList::Instance()->FindCharacter(player);
if(pc)
{
auto pack = new ServerPacket(ServerOP_AdventureLeaderboard, 64 + sizeof(AdventureLeaderboard_Struct));
AdventureLeaderboard_Struct *al = (AdventureLeaderboard_Struct*)(pack->pBuffer + 64);
strcpy((char*)pack->pBuffer, player);
int place = -1;
int our_successes = 0;
int our_failures = 0;
int i = 0;
auto iter = leaderboard_info_wins_mmc.begin();
while(i < 100 && iter != leaderboard_info_wins_mmc.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.mmc_wins;
our_failures = li.mmc_losses;
}
al->entries[i].success = li.mmc_wins;
al->entries[i].failure = li.mmc_losses;
strcpy(al->entries[i].name, li.name.c_str());
i++;
++iter;
}
if(place == -1 && iter != leaderboard_info_wins_mmc.end())
{
while(iter != leaderboard_info_wins_mmc.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.mmc_wins;
our_failures = li.mmc_losses;
break;
}
i++;
++iter;
}
}
if(place == -1)
{
al->our_rank = leaderboard_info_wins_mmc.size() + 1;
al->success = 0;
al->failure = 0;
}
else
{
al->our_rank = place;
al->success = our_successes;
al->failure = our_failures;
}
ZSList::Instance()->SendPacket(pc->zone(), pc->instance(), pack);
delete pack;
}
}
void AdventureManager::DoLeaderboardRequestPercentageMmc(const char* player)
{
ClientListEntry *pc = ClientList::Instance()->FindCharacter(player);
if(pc)
{
auto pack = new ServerPacket(ServerOP_AdventureLeaderboard, 64 + sizeof(AdventureLeaderboard_Struct));
AdventureLeaderboard_Struct *al = (AdventureLeaderboard_Struct*)(pack->pBuffer + 64);
strcpy((char*)pack->pBuffer, player);
int place = -1;
int our_successes = 0;
int our_failures = 0;
int i = 0;
auto iter = leaderboard_info_percentage_mmc.begin();
while(i < 100 && iter != leaderboard_info_percentage_mmc.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.mmc_wins;
our_failures = li.mmc_losses;
}
al->entries[i].success = li.mmc_wins;
al->entries[i].failure = li.mmc_losses;
strcpy(al->entries[i].name, li.name.c_str());
i++;
++iter;
}
if(place == -1 && iter != leaderboard_info_percentage_mmc.end())
{
while(iter != leaderboard_info_percentage_mmc.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.mmc_wins;
our_failures = li.mmc_losses;
break;
}
i++;
++iter;
}
}
if(place == -1)
{
al->our_rank = leaderboard_info_percentage_mmc.size() + 1;
al->success = 0;
al->failure = 0;
}
else
{
al->our_rank = place;
al->success = our_successes;
al->failure = our_failures;
}
ZSList::Instance()->SendPacket(pc->zone(), pc->instance(), pack);
delete pack;
}
}
void AdventureManager::DoLeaderboardRequestWinsRuj(const char* player)
{
ClientListEntry *pc = ClientList::Instance()->FindCharacter(player);
if(pc)
{
auto pack = new ServerPacket(ServerOP_AdventureLeaderboard, 64 + sizeof(AdventureLeaderboard_Struct));
AdventureLeaderboard_Struct *al = (AdventureLeaderboard_Struct*)(pack->pBuffer + 64);
strcpy((char*)pack->pBuffer, player);
int place = -1;
int our_successes = 0;
int our_failures = 0;
int i = 0;
auto iter = leaderboard_info_wins_ruj.begin();
while(i < 100 && iter != leaderboard_info_wins_ruj.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.ruj_wins;
our_failures = li.ruj_losses;
}
al->entries[i].success = li.ruj_wins;
al->entries[i].failure = li.ruj_losses;
strcpy(al->entries[i].name, li.name.c_str());
i++;
++iter;
}
if(place == -1 && iter != leaderboard_info_wins_ruj.end())
{
while(iter != leaderboard_info_wins_ruj.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.ruj_wins;
our_failures = li.ruj_losses;
break;
}
i++;
++iter;
}
}
if(place == -1)
{
al->our_rank = leaderboard_info_wins_ruj.size() + 1;
al->success = 0;
al->failure = 0;
}
else
{
al->our_rank = place;
al->success = our_successes;
al->failure = our_failures;
}
ZSList::Instance()->SendPacket(pc->zone(), pc->instance(), pack);
delete pack;
}
}
void AdventureManager::DoLeaderboardRequestPercentageRuj(const char* player)
{
ClientListEntry *pc = client_list.FindCharacter(player);
if(pc)
{
auto pack = new ServerPacket(ServerOP_AdventureLeaderboard, 64 + sizeof(AdventureLeaderboard_Struct));
AdventureLeaderboard_Struct *al = (AdventureLeaderboard_Struct*)(pack->pBuffer + 64);
strcpy((char*)pack->pBuffer, player);
int place = -1;
int our_successes = 0;
int our_failures = 0;
int i = 0;
auto iter = leaderboard_info_percentage_ruj.begin();
while(i < 100 && iter != leaderboard_info_percentage_ruj.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.ruj_wins;
our_failures = li.ruj_losses;
}
al->entries[i].success = li.ruj_wins;
al->entries[i].failure = li.ruj_losses;
strcpy(al->entries[i].name, li.name.c_str());
i++;
++iter;
}
if(place == -1 && iter != leaderboard_info_percentage_ruj.end())
{
while(iter != leaderboard_info_percentage_ruj.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.ruj_wins;
our_failures = li.ruj_losses;
break;
}
i++;
++iter;
}
}
if(place == -1)
{
al->our_rank = leaderboard_info_percentage_ruj.size() + 1;
al->success = 0;
al->failure = 0;
}
else
{
al->our_rank = place;
al->success = our_successes;
al->failure = our_failures;
}
ZSList::Instance()->SendPacket(pc->zone(), pc->instance(), pack);
delete pack;
}
}
void AdventureManager::DoLeaderboardRequestWinsTak(const char* player)
{
ClientListEntry *pc = client_list.FindCharacter(player);
if(pc)
{
auto pack = new ServerPacket(ServerOP_AdventureLeaderboard, 64 + sizeof(AdventureLeaderboard_Struct));
AdventureLeaderboard_Struct *al = (AdventureLeaderboard_Struct*)(pack->pBuffer + 64);
strcpy((char*)pack->pBuffer, player);
int place = -1;
int our_successes = 0;
int our_failures = 0;
int i = 0;
auto iter = leaderboard_info_wins_ruj.begin();
while(i < 100 && iter != leaderboard_info_wins_ruj.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.tak_wins;
our_failures = li.tak_losses;
}
al->entries[i].success = li.tak_wins;
al->entries[i].failure = li.tak_losses;
strcpy(al->entries[i].name, li.name.c_str());
i++;
++iter;
}
if(place == -1 && iter != leaderboard_info_wins_ruj.end())
{
while(iter != leaderboard_info_wins_ruj.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.tak_wins;
our_failures = li.tak_losses;
break;
}
i++;
++iter;
}
}
if(place == -1)
{
al->our_rank = leaderboard_info_wins_ruj.size() + 1;
al->success = 0;
al->failure = 0;
}
else
{
al->our_rank = place;
al->success = our_successes;
al->failure = our_failures;
}
ZSList::Instance()->SendPacket(pc->zone(), pc->instance(), pack);
delete pack;
}
}
void AdventureManager::DoLeaderboardRequestPercentageTak(const char* player)
{
ClientListEntry *pc = client_list.FindCharacter(player);
if(pc)
{
auto pack = new ServerPacket(ServerOP_AdventureLeaderboard, 64 + sizeof(AdventureLeaderboard_Struct));
AdventureLeaderboard_Struct *al = (AdventureLeaderboard_Struct*)(pack->pBuffer + 64);
strcpy((char*)pack->pBuffer, player);
int place = -1;
int our_successes = 0;
int our_failures = 0;
int i = 0;
auto iter = leaderboard_info_percentage_tak.begin();
while(i < 100 && iter != leaderboard_info_percentage_tak.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.tak_wins;
our_failures = li.tak_losses;
}
al->entries[i].success = li.tak_wins;
al->entries[i].failure = li.tak_losses;
strcpy(al->entries[i].name, li.name.c_str());
i++;
++iter;
}
if(place == -1 && iter != leaderboard_info_percentage_tak.end())
{
while(iter != leaderboard_info_percentage_tak.end())
{
LeaderboardInfo li = (*iter);
if(li.name.compare(player) == 0)
{
place = i;
our_successes = li.tak_wins;
our_failures = li.tak_losses;
break;
}
i++;
++iter;
}
}
if(place == -1)
{
al->our_rank = leaderboard_info_percentage_tak.size() + 1;
al->success = 0;
al->failure = 0;
}
else
{
al->our_rank = place;
al->success = our_successes;
al->failure = our_failures;
}
ZSList::Instance()->SendPacket(pc->zone(), pc->instance(), pack);
delete pack;
}
}
bool AdventureManager::PopFinishedEvent(const char *name, AdventureFinishEvent &fe)
{
auto iter = finished_list.begin();
while(iter != finished_list.end())
{
if((*iter).name.compare(name) == 0)
{
fe.name = (*iter).name;
fe.points = (*iter).points;
fe.theme = (*iter).theme;
fe.win = (*iter).win;
finished_list.erase(iter);
Save();
return true;
}
++iter;
}
return false;
}
void AdventureManager::SendAdventureFinish(AdventureFinishEvent fe)
{
ClientListEntry *pc = client_list.FindCharacter(fe.name.c_str());
if(pc)
{
auto pack = new ServerPacket(ServerOP_AdventureFinish, sizeof(ServerAdventureFinish_Struct));
ServerAdventureFinish_Struct *af = (ServerAdventureFinish_Struct*)pack->pBuffer;
strcpy(af->player, fe.name.c_str());
af->theme = fe.theme;
af->win = fe.win;
af->points = fe.points;
ZSList::Instance()->SendPacket(pc->zone(), pc->instance(), pack);
delete pack;
}
}
void AdventureManager::Save()
{
//disabled for now
return;
std::stringstream ss(std::stringstream::in | std::stringstream::out);
int number_of_elements = adventure_list.size();
ss.write((const char*)&number_of_elements, sizeof(int));
char null_term = 0;
auto a_iter = adventure_list.begin();
while(a_iter != adventure_list.end())
{
int cur = (*a_iter)->GetCount();
ss.write((const char*)&cur, sizeof(int));
cur = (*a_iter)->GetAssassinationCount();
ss.write((const char*)&cur, sizeof(int));
cur = (*a_iter)->GetTemplate()->id;
ss.write((const char*)&cur, sizeof(int));
cur = (int)(*a_iter)->GetStatus();
ss.write((const char*)&cur, sizeof(int));
cur = (*a_iter)->GetInstanceID();
ss.write((const char*)&cur, sizeof(int));
cur = (*a_iter)->GetRemainingTime();
ss.write((const char*)&cur, sizeof(int));
std::list<std::string> players = (*a_iter)->GetPlayers();
cur = players.size();
ss.write((const char*)&cur, sizeof(int));
auto s_iter = players.begin();
while(s_iter != players.end())
{
ss.write((const char*)(*s_iter).c_str(), (*s_iter).size());
ss.write((const char*)&null_term, sizeof(char));
s_iter++;
}
a_iter++;
}
number_of_elements = finished_list.size();
ss.write((const char*)&number_of_elements, sizeof(int));
auto f_iter = finished_list.begin();
while(f_iter != finished_list.end())
{
ss.write((const char*)&(*f_iter).win, sizeof(bool));
ss.write((const char*)&(*f_iter).points, sizeof(int));
ss.write((const char*)&(*f_iter).theme, sizeof(int));
ss.write((const char*)(*f_iter).name.c_str(), (*f_iter).name.size());
ss.write((const char*)&null_term, sizeof(char));
f_iter++;
}
FILE *f = fopen("adventure_state.dat", "w");
if(f)
{
fwrite(ss.str().c_str(), ss.str().size(), 1, f);
fclose(f);
}
}