#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 #include 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 excluded_zones; std::list 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 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 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 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 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 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 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 = 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_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 = 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.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 = 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_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 = ClientList::Instance()->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 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); } }