diff --git a/common/servertalk.h b/common/servertalk.h index 22e021fc8..d7c7bf6f6 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -152,11 +152,13 @@ #define ServerOP_LSRemoteAddr 0x1009 #define ServerOP_LSAccountUpdate 0x100A -#define ServerOP_TaskRequest 0x0300 -#define ServerOP_TaskGrant 0x0301 -#define ServerOP_TaskReject 0x0302 -#define ServerOP_TaskAddPlayer 0x0303 -#define ServerOP_TaskRemovePlayer 0x0304 +#define ServerOP_TaskRequest 0x0300 // zone -> world. Player trying to get task +#define ServerOP_TaskGrant 0x0301 // world -> zone. World verified everything is good +#define ServerOP_TaskReject 0x0302 // world -> zone. Something failed ABORT +#define ServerOP_TaskAddPlayer 0x0303 // bidirectional. /taskaddplayer request zone -> world. success world -> zone +#define ServerOP_TaskRemovePlayer 0x0304 // .. /taskremoveplayer .. +#define ServerOP_TaskZoneCreated 0x0305 // zone -> world. Something didn't go wrong creating the new task! Now World needs to tell other players to join world -> zone response to tell someone to join +#define ServerOP_TaskZoneFailed 0x0306 // zone -> world. Something went wrong above ABORT #define ServerOP_EncapPacket 0x2007 // Packet within a packet #define ServerOP_WorldListUpdate 0x2008 @@ -1335,6 +1337,10 @@ struct UCSServerStatus_Struct { }; // shared task related communications +struct ServerSharedTaskMember_Struct { // used for various things we just need the ID and a name (add, remove, etc) + uint32 id; + char name[64]; +}; // error constants #define TASKJOINOOZ_CAN 0 #define TASKJOINOOZ_NOTASK 1 diff --git a/world/shared_tasks.cpp b/world/shared_tasks.cpp index 1d2468202..c9dc04b3a 100644 --- a/world/shared_tasks.cpp +++ b/world/shared_tasks.cpp @@ -6,6 +6,7 @@ #include "zonelist.h" #include +#include extern ClientList client_list; extern ZSList zoneserver_list; @@ -163,9 +164,70 @@ void SharedTaskManager::HandleTaskRequest(ServerPacket *pack) zoneserver_list.SendPacket(cle_leader->zone(), cle_leader->instance(), reply); safe_delete(reply); + task.Save(); + return; } +/* + * Just sends the ID of the task that was successfully created zone side + * We now need to tell all the other clients to join the task + * We could probably try to find all the clients already in the zone and not + * worry about them here, but it's simpler this way + */ +void SharedTaskManager::HandleTaskZoneCreated(ServerPacket *pack) +{ + if (!pack) + return; + + int id = pack->ReadUInt32(); + + auto task = GetSharedTask(id); + + if (!task) // hmm guess we should tell zone something is broken TODO + return; + + auto leader = task->GetLeader(); + + if (!leader) // hmmm + return; + + // if a zone server isn't in here, we need to send a serialized task state to them -- might not do this way :P + std::unordered_set zones; + zones.insert(leader->cle->Server()); + + // we reuse this, easier this way + auto outpack = new ServerPacket(ServerOP_TaskZoneCreated, sizeof(ServerSharedTaskMember_Struct)); + auto stm = (ServerSharedTaskMember_Struct *)outpack->pBuffer; + stm->id = id; + + ServerPacket *taskpack = nullptr; // if we have, we will create this + + for (auto &&m : task->members) { + if (m.leader) // leader done! + continue; + + if (!m.cle) // hmmm + continue; + + if (!m.cle->Server()) // hmm + continue; + + auto ret = zones.insert(m.cle->Server()); + if (ret.second) { // new zone! send serialized task + if (!taskpack) { // we need to create the serialized packet + } + zoneserver_list.SendPacket(m.cle->zone(), m.cle->instance(), taskpack); + } + + strn0cpy(stm->name, m.name.c_str(), 64); + zoneserver_list.SendPacket(m.cle->zone(), m.cle->instance(), outpack); + } + + safe_delete(outpack); + safe_delete(taskpack); +} + /* * Loads in the tasks and task_activity tables * We limit to shared to save some memory @@ -462,3 +524,7 @@ void SharedTask::SetCLESharedTasks() } } +void SharedTask::Save() const +{ +} + diff --git a/world/shared_tasks.h b/world/shared_tasks.h index 3e50d787c..6d4b1f8d3 100644 --- a/world/shared_tasks.h +++ b/world/shared_tasks.h @@ -31,11 +31,20 @@ public: leader_name = name; } void MemberLeftGame(ClientListEntry *cle); - const std::string &GetLeaderName() const { return leader_name; } + inline const std::string &GetLeaderName() const { return leader_name; } + inline SharedTaskMember *GetLeader() { + auto it = std::find_if(members.begin(), members.end(), [](const SharedTaskMember &m) { return m.leader; }); + if (it != members.end()) + return &(*it); + else + return nullptr; + } void SerializeMembers(SerializeBuffer &buf, bool include_leader = true) const; void SetCLESharedTasks(); + void Save() const; // save to database + private: inline void SetID(int in) { id = in; } inline void SetTaskID(int in) { task_id = in; } @@ -62,8 +71,17 @@ public: bool AppropriateLevel(int id, int level) const; + inline SharedTask *GetSharedTask(int id) { + auto it = tasks.find(id); + if (it != tasks.end()) + return &it->second; + else + return nullptr; + } + // IPC packet processing void HandleTaskRequest(ServerPacket *pack); + void HandleTaskZoneCreated(ServerPacket *pack); void Process(); diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index e66bd797d..295e7c710 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -1356,6 +1356,11 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { shared_tasks.HandleTaskRequest(pack); break; } + case ServerOP_TaskZoneCreated: + { + shared_tasks.HandleTaskZoneCreated(pack); + break; + } default: { Log(Logs::Detail, Logs::World_Server, "Unknown ServerOPcode from zone 0x%04x, size %d", pack->opcode, pack->size); diff --git a/zone/tasks.cpp b/zone/tasks.cpp index 480e49e31..802bf7cd4 100644 --- a/zone/tasks.cpp +++ b/zone/tasks.cpp @@ -3529,9 +3529,16 @@ void ClientTaskState::AcceptNewSharedTask(Client *c, int TaskID, int NPCID, int return; } - // TODO: save state + // TODO: save state -- for the client parse->EventNPC(EVENT_TASK_ACCEPTED, npc, c, buf.c_str(), 0); - // TODO: We need to tell world we are successful so we can tell all the other clients + + auto pack = new ServerPacket(ServerOP_TaskZoneCreated, sizeof(uint32)); // just the ID saying to continue + pack->WriteUInt32(id); + worldserver.SendPacket(pack); + delete pack; + + return; + // there are a few issues we need to solve with this }