mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-19 20:41:33 +00:00
161 lines
4.2 KiB
C++
161 lines
4.2 KiB
C++
#include "shared_tasks.h"
|
|
#include "clientlist.h"
|
|
#include "cliententry.h"
|
|
#include "zonelist.h"
|
|
|
|
extern ClientList client_list;
|
|
extern ZSList zoneserver_list;
|
|
|
|
void SharedTaskManager::HandleTaskRequest(ServerPacket *pack)
|
|
{
|
|
if (!pack)
|
|
return;
|
|
|
|
char tmp_str[64] = { 0 };
|
|
int task_id = pack->ReadUInt32();
|
|
pack->ReadString(tmp_str);
|
|
std::string leader_name = tmp_str;
|
|
int missing_count = pack->ReadUInt32();
|
|
std::vector<std::string> missing_players;
|
|
for (int i = 0; i < missing_count; ++i) {
|
|
pack->ReadString(tmp_str);
|
|
missing_players.push_back(tmp_str);
|
|
}
|
|
|
|
int id = GetNextID();
|
|
auto ret = tasks.insert({id, {id, task_id}});
|
|
if (!ret.second) {
|
|
auto pc = client_list.FindCharacter(leader_name.c_str());
|
|
if (pc) {
|
|
auto pack = new ServerPacket(ServerOP_TaskReject, leader_name.size() + 1 + 4);
|
|
pack->WriteUInt32(0); // string ID or just generic fail message
|
|
pack->WriteString(leader_name.c_str());
|
|
zoneserver_list.SendPacket(pc->zone(), pc->instance(), pack);
|
|
safe_delete(pack);
|
|
} // oh well
|
|
}
|
|
|
|
auto &task = ret.first->second;
|
|
task.AddMember(leader_name, true);
|
|
|
|
if (missing_players.empty()) {
|
|
// send instant success to leader
|
|
auto pc = client_list.FindCharacter(leader_name.c_str());
|
|
if (pc) {
|
|
SerializeBuffer buf(10);
|
|
buf.WriteInt32(id); // task's ID
|
|
buf.WriteString(leader_name); // leader's name
|
|
|
|
auto pack = new ServerPacket(ServerOP_TaskGrant, buf);
|
|
zoneserver_list.SendPacket(pc->zone(), pc->instance(), pack);
|
|
safe_delete(pack);
|
|
} else { // well fuck
|
|
tasks.erase(ret.first);
|
|
}
|
|
return;
|
|
}
|
|
|
|
task.SetMissingCount(missing_count);
|
|
for (auto &&name : missing_players) {
|
|
// look up CLEs by name, tell them we need to know if they can be added
|
|
auto pc = client_list.FindCharacter(name.c_str());
|
|
if (pc) {
|
|
SerializeBuffer buf(10);
|
|
buf.WriteInt32(id);
|
|
buf.WriteInt32(task_id);
|
|
buf.WriteString(name);
|
|
|
|
auto pack = new ServerPacket(ServerOP_TaskRequest, buf);
|
|
zoneserver_list.SendPacket(pc->zone(), pc->instance(), pack);
|
|
safe_delete(pack);
|
|
} else { // asked for a toon we couldn't find ABORT!
|
|
auto pc = client_list.FindCharacter(leader_name.c_str());
|
|
if (pc) {
|
|
auto pack = new ServerPacket(ServerOP_TaskReject, leader_name.size() + 1 + 4);
|
|
pack->WriteUInt32(0); // string ID or just generic fail message
|
|
pack->WriteString(leader_name.c_str());
|
|
zoneserver_list.SendPacket(pc->zone(), pc->instance(), pack);
|
|
safe_delete(pack);
|
|
} // oh well
|
|
tasks.erase(ret.first);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void SharedTaskManager::HandleTaskRequestReply(ServerPacket *pack)
|
|
{
|
|
if (!pack)
|
|
return;
|
|
|
|
int id = pack->ReadUInt32();
|
|
|
|
char name[64] = { 0 };
|
|
pack->ReadString(name);
|
|
|
|
int status = pack->ReadUInt32();
|
|
|
|
auto it = tasks.find(id);
|
|
if (it == tasks.end()) {
|
|
// task already errored and no longer existed, we can ignore
|
|
return;
|
|
}
|
|
|
|
auto &task = it->second;
|
|
|
|
if (status != TASKJOINOOZ_CAN) {
|
|
// TODO: forward to leader
|
|
return;
|
|
}
|
|
|
|
if (!task.DecrementMissingCount())
|
|
tasks.erase(it);
|
|
}
|
|
|
|
/*
|
|
* This is called once during boot of world
|
|
* We need to load next_id, clean up expired tasks (?), and populate the map
|
|
*/
|
|
bool SharedTaskManager::LoadSharedTaskState()
|
|
{
|
|
// clean up expired tasks ... We may not want to do this if world crashes and has to be restarted
|
|
// May need to wait to do it to cleanly inform existing zones to clean up expired tasks
|
|
|
|
// Load existing tasks. We may not want to actually do this here and wait for a client to log in
|
|
// But the crash case may actually dictate we should :P
|
|
|
|
// set next_id to highest used ID + 1
|
|
return true;
|
|
}
|
|
|
|
int SharedTaskManger::GetNextID()
|
|
{
|
|
next_id++;
|
|
// let's not be extra clever here ...
|
|
while (tasks.count(next_id) != 0)
|
|
next_id++;
|
|
|
|
return next_id;
|
|
}
|
|
|
|
bool SharedTask::DecrementMissingCount()
|
|
{
|
|
--missing_count;
|
|
if (missing_count == 0) {
|
|
auto pc = client_list.FindCharacter(leader_name.c_str());
|
|
if (pc) {
|
|
SerializeBuffer buf(10);
|
|
buf.WriteInt32(id); // task's ID
|
|
buf.WriteString(leader_name); // leader's name
|
|
|
|
auto pack = new ServerPacket(ServerOP_TaskGrant, buf);
|
|
zoneserver_list.SendPacket(pc->zone(), pc->instance(), pack);
|
|
safe_delete(pack);
|
|
} else {
|
|
return false; // error, please clean us up
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|