mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-31 13:16:39 +00:00
World should verify the full task to simplify things
This commit is contained in:
+1
-1
@@ -1036,7 +1036,6 @@ public:
|
||||
inline void ProcessTaskProximities(float X, float Y, float Z) { if(taskstate) taskstate->ProcessTaskProximities(this, X, Y, Z); }
|
||||
inline void AssignTask(int TaskID, int NPCID, bool enforce_level_requirement = false) { if (taskstate) taskstate->AcceptNewTask(this, TaskID, NPCID, enforce_level_requirement); }
|
||||
inline void AssignSharedTask(int TaskID, int NPCID, int id) { if (taskstate) taskstate->AcceptNewSharedTask(this, TaskID, NPCID, id); }
|
||||
inline void HandleCanJoinSharedTask(int TaskID, int id) { if (taskstate) taskstate->HandleCanJoinSharedTask(this, TaskID, id); }
|
||||
inline int ActiveSpeakTask(int NPCID) { if(taskstate) return taskstate->ActiveSpeakTask(NPCID); else return 0; }
|
||||
inline int ActiveSpeakActivity(int NPCID, int TaskID) { if(taskstate) return taskstate->ActiveSpeakActivity(NPCID, TaskID); else return 0; }
|
||||
inline void FailTask(int TaskID) { if(taskstate) taskstate->FailTask(this, TaskID); }
|
||||
@@ -1054,6 +1053,7 @@ public:
|
||||
inline int ActiveTasksInSet(int TaskSet) { return (taskstate ? taskstate->ActiveTasksInSet(TaskSet) :0); }
|
||||
inline int CompletedTasksInSet(int TaskSet) { return (taskstate ? taskstate->CompletedTasksInSet(TaskSet) :0); }
|
||||
inline int GetTaskLockoutExpire(int id) { return 0; } // stub
|
||||
inline int GetTaskLockoutTimeLeft(int id) { return 0; } // stub
|
||||
|
||||
inline void SetPendingTask(int id, int task_master_id) { pending_task.id = id; pending_task.task_master_id = task_master_id; }
|
||||
inline bool HasPendingTask() const { return pending_task.id != 0; }
|
||||
|
||||
+53
-103
@@ -3405,14 +3405,13 @@ void ClientTaskState::PendSharedTask(Client *c, int TaskID, int NPCID, bool enfo
|
||||
return;
|
||||
|
||||
if (task->replay_group) {
|
||||
auto expires = c->GetTaskLockoutExpire(task->replay_group);
|
||||
if (expires) {
|
||||
auto diff = expires - Timer::GetCurrentTime();
|
||||
std::string days = std::to_string(diff / 86400);
|
||||
diff = diff % 86400;
|
||||
std::string hours = std::to_string(diff / 3600);
|
||||
diff = diff % 3600;
|
||||
std::string minutes = std::to_string(diff / 60);
|
||||
auto expires = c->GetTaskLockoutTimeLeft(task->replay_group);
|
||||
if (expires > 0) {
|
||||
std::string days = std::to_string(expires / 86400);
|
||||
expires = expires % 86400;
|
||||
std::string hours = std::to_string(expires / 3600);
|
||||
expires = expires % 3600;
|
||||
std::string minutes = std::to_string(expires / 60);
|
||||
c->Message_StringID(13, TASK_REJECT_LOCKEDOUT, days.c_str(), hours.c_str(), minutes.c_str());
|
||||
return;
|
||||
}
|
||||
@@ -3440,6 +3439,37 @@ void ClientTaskState::PendSharedTask(Client *c, int TaskID, int NPCID, bool enfo
|
||||
return;
|
||||
}
|
||||
|
||||
// okay, we verified a few things on the requestor, now we need to fire off to world to do the rest
|
||||
SerializeBuffer buf(25 + 10 * player_count);
|
||||
buf.WriteInt32(TaskID); // Task ID
|
||||
buf.WriteString(c->GetName()); // leader name
|
||||
buf.WriteInt32(player_count - 1); // count, not leader
|
||||
if (group) {
|
||||
for (int i = 0; i < MAX_GROUP_MEMBERS; ++i) {
|
||||
if (group->members[i] == c) // skipping requestor
|
||||
continue;
|
||||
|
||||
// TODO: mercs/bots
|
||||
if (group->members[i] != nullptr && group->members[i]->IsClient())
|
||||
buf.WriteString(group->membername[i]);
|
||||
}
|
||||
} else if (raid) {
|
||||
for (int i = 0; i < MAX_RAID_MEMBERS; ++i) {
|
||||
if (raid->members[i].member == c) // skipping requestor
|
||||
continue;
|
||||
// TODO: bots if they ever can live in a raid
|
||||
if (raid->members[i].membername[0] != '\0')
|
||||
buf.WriteString(raid->members[i].membername);
|
||||
}
|
||||
}
|
||||
|
||||
auto pack = new ServerPacket(ServerOP_TaskRequest, buf);
|
||||
worldserver.SendPacket(pack);
|
||||
delete pack;
|
||||
|
||||
return;
|
||||
|
||||
/*
|
||||
std::vector<std::string> missing_players; // names of players not in this zone so we can put the checks off to world
|
||||
bool task_failed = false;
|
||||
if (group) {
|
||||
@@ -3458,15 +3488,14 @@ void ClientTaskState::PendSharedTask(Client *c, int TaskID, int NPCID, bool enfo
|
||||
break;
|
||||
} else {
|
||||
if (task->replay_group) {
|
||||
auto expires = client->GetTaskLockoutExpire(task->replay_group);
|
||||
if (expires) {
|
||||
auto expires = client->GetTaskLockoutTimeLeft(task->replay_group);
|
||||
if (expires > 0) {
|
||||
task_failed = true;
|
||||
auto diff = expires - Timer::GetCurrentTime();
|
||||
std::string days = std::to_string(diff / 86400);
|
||||
diff = diff % 86400;
|
||||
std::string hours = std::to_string(diff / 3600);
|
||||
diff = diff % 3600;
|
||||
std::string minutes = std::to_string(diff / 60);
|
||||
std::string days = std::to_string(expires / 86400);
|
||||
expires = expires % 86400;
|
||||
std::string hours = std::to_string(expires / 3600);
|
||||
expires = expires % 3600;
|
||||
std::string minutes = std::to_string(expires / 60);
|
||||
c->Message_StringID(13, TASK_REJECT_LOCKEDOUT_OTHER,
|
||||
client->GetName(), days.c_str(),
|
||||
hours.c_str(), minutes.c_str());
|
||||
@@ -3497,15 +3526,14 @@ void ClientTaskState::PendSharedTask(Client *c, int TaskID, int NPCID, bool enfo
|
||||
break;
|
||||
} else {
|
||||
if (task->replay_group) {
|
||||
auto expires = client->GetTaskLockoutExpire(task->replay_group);
|
||||
if (expires) {
|
||||
auto expires = client->GetTaskLockoutTimeLeft(task->replay_group);
|
||||
if (expires > 0) {
|
||||
task_failed = true;
|
||||
auto diff = expires - Timer::GetCurrentTime();
|
||||
std::string days = std::to_string(diff / 86400);
|
||||
diff = diff % 86400;
|
||||
std::string hours = std::to_string(diff / 3600);
|
||||
diff = diff % 3600;
|
||||
std::string minutes = std::to_string(diff / 60);
|
||||
std::string days = std::to_string(expires / 86400);
|
||||
expires = expires % 86400;
|
||||
std::string hours = std::to_string(expires / 3600);
|
||||
expires = expires % 3600;
|
||||
std::string minutes = std::to_string(expires / 60);
|
||||
c->Message_StringID(13, TASK_REJECT_LOCKEDOUT_OTHER,
|
||||
client->GetName(), days.c_str(),
|
||||
hours.c_str(), minutes.c_str());
|
||||
@@ -3530,17 +3558,8 @@ void ClientTaskState::PendSharedTask(Client *c, int TaskID, int NPCID, bool enfo
|
||||
// so we've verified all the clients we can and didn't fail, time to pend and yell at world
|
||||
c->SetPendingTask(TaskID, NPCID);
|
||||
c->StartPendingTimer(); // in case something goes wrong and takes ages, we time out
|
||||
*/
|
||||
|
||||
SerializeBuffer buf(25 + 10 * missing_players.size());
|
||||
buf.WriteInt32(TaskID); // Task ID
|
||||
buf.WriteString(c->GetName()); // leader name
|
||||
buf.WriteInt32(missing_players.size()); // count
|
||||
for (auto && name : missing_players)
|
||||
buf.WriteString(name);
|
||||
|
||||
auto pack = new ServerPacket(ServerOP_TaskRequest, buf);
|
||||
worldserver.SendPacket(pack);
|
||||
delete pack;
|
||||
}
|
||||
|
||||
void ClientTaskState::AcceptNewSharedTask(Client *c, int TaskID, int NPCID, int id)
|
||||
@@ -3548,75 +3567,6 @@ void ClientTaskState::AcceptNewSharedTask(Client *c, int TaskID, int NPCID, int
|
||||
|
||||
}
|
||||
|
||||
void ClientTaskState::HandleCanJoinSharedTask(Client *c, int TaskID, int id)
|
||||
{
|
||||
if (!c)
|
||||
return;
|
||||
|
||||
SerializeBuffer buf(15);
|
||||
buf.WriteInt32(id);
|
||||
buf.WriteString(c->GetName());
|
||||
|
||||
if (!taskmanager || TaskID < 0 || TaskID >= MAXTASKS) {
|
||||
buf.WriteInt32(TASKJOINOOZ_NOTASK);
|
||||
auto pack = new ServerPacket(ServerOP_TaskRequestReply, buf);
|
||||
worldserver.SendPacket(pack);
|
||||
delete pack;
|
||||
return;
|
||||
}
|
||||
|
||||
auto task = taskmanager->Tasks[TaskID];
|
||||
|
||||
if (task == nullptr) {
|
||||
buf.WriteInt32(TASKJOINOOZ_NOTASK);
|
||||
auto pack = new ServerPacket(ServerOP_TaskRequestReply, buf);
|
||||
worldserver.SendPacket(pack);
|
||||
delete pack;
|
||||
return;
|
||||
}
|
||||
|
||||
if (task->type != TaskType::Shared) {
|
||||
buf.WriteInt32(TASKJOINOOZ_NOTASK);
|
||||
auto pack = new ServerPacket(ServerOP_TaskRequestReply, buf);
|
||||
worldserver.SendPacket(pack);
|
||||
delete pack;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ActiveSharedTask != nullptr) {
|
||||
buf.WriteInt32(TASKJOINOOZ_HAVEONE);
|
||||
auto pack = new ServerPacket(ServerOP_TaskRequestReply, buf);
|
||||
worldserver.SendPacket(pack);
|
||||
delete pack;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!taskmanager->AppropriateLevel(TaskID, c->GetLevel())) {
|
||||
buf.WriteInt32(TASKJOINOOZ_LEVEL);
|
||||
auto pack = new ServerPacket(ServerOP_TaskRequestReply, buf);
|
||||
worldserver.SendPacket(pack);
|
||||
delete pack;
|
||||
return;
|
||||
}
|
||||
|
||||
if (task->replay_group) {
|
||||
auto expires = c->GetTaskLockoutExpire(task->replay_group);
|
||||
if (expires) {
|
||||
buf.WriteInt32(TASKJOINOOZ_TIMER);
|
||||
buf.WriteInt32(expires);
|
||||
auto pack = new ServerPacket(ServerOP_TaskRequestReply, buf);
|
||||
worldserver.SendPacket(pack);
|
||||
delete pack;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteInt32(TASKJOINOOZ_CAN);
|
||||
auto pack = new ServerPacket(ServerOP_TaskRequestReply, buf);
|
||||
worldserver.SendPacket(pack);
|
||||
delete pack;
|
||||
}
|
||||
|
||||
void ClientTaskState::ProcessTaskProximities(Client *c, float X, float Y, float Z) {
|
||||
|
||||
float LastX = c->ProximityX();
|
||||
|
||||
+1
-126
@@ -21,6 +21,7 @@ Copyright (C) 2001-2004 EQEMu Development Team (http://eqemulator.net)
|
||||
#define TASKS_H
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../common/global_tasks.h"
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
@@ -29,24 +30,6 @@ Copyright (C) 2001-2004 EQEMu Development Team (http://eqemulator.net)
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
|
||||
#define MAXTASKS 10000
|
||||
#define MAXTASKSETS 1000
|
||||
// The Client has a hard cap of 19 active quests, 29 in SoD+
|
||||
#define MAXACTIVEQUESTS 19
|
||||
// The Max Chooser (Task Selector entries) is capped at 40 in the Titanium Client.
|
||||
#define MAXCHOOSERENTRIES 40
|
||||
// The Client has a hard cap of 20 activities per task.
|
||||
#define MAXACTIVITIESPERTASK 20
|
||||
// This is used to determine if a client's active task slot is empty.
|
||||
#define TASKSLOTEMPTY 0
|
||||
|
||||
// Command Codes for worldserver ServerOP_ReloadTasks
|
||||
//
|
||||
#define RELOADTASKS 0
|
||||
#define RELOADTASKGOALLISTS 1
|
||||
#define RELOADTASKPROXIMITIES 2
|
||||
#define RELOADTASKSETS 3
|
||||
|
||||
class Client;
|
||||
class Mob;
|
||||
|
||||
@@ -100,106 +83,6 @@ private:
|
||||
std::vector<TaskProximity> TaskProximities;
|
||||
};
|
||||
|
||||
typedef enum { METHODSINGLEID = 0, METHODLIST = 1, METHODQUEST = 2 } TaskMethodType;
|
||||
|
||||
struct ActivityInformation {
|
||||
int StepNumber;
|
||||
int Type;
|
||||
std::string target_name; // name mob, location -- default empty
|
||||
std::string item_list; // likely defaults to empty
|
||||
std::string skill_list; // IDs ; separated -- default -1
|
||||
std::string spell_list; // IDs ; separated -- default 0
|
||||
std::string desc_override; // overrides auto generated description -- default empty
|
||||
int skill_id; // older clients, first id from above
|
||||
int spell_id; // older clients, first id from above
|
||||
int GoalID;
|
||||
TaskMethodType GoalMethod;
|
||||
int GoalCount;
|
||||
int DeliverToNPC;
|
||||
std::vector<int> ZoneIDs;
|
||||
std::string zones; // IDs ; searated, ZoneID is the first in this list for older clients -- default empty string
|
||||
bool Optional;
|
||||
|
||||
inline bool CheckZone(int zone_id) {
|
||||
if (ZoneIDs.empty())
|
||||
return true;
|
||||
return std::find(ZoneIDs.begin(), ZoneIDs.end(), zone_id) != ZoneIDs.end();
|
||||
}
|
||||
};
|
||||
|
||||
typedef enum { ActivitiesSequential = 0, ActivitiesStepped = 1 } SequenceType;
|
||||
|
||||
enum class TaskType {
|
||||
Task = 0, // can have at max 1
|
||||
Shared = 1, // can have at max 1
|
||||
Quest = 2, // can have at max 19 or 29 depending on client
|
||||
E = 3 // can have at max 19 or 29 depending on client, not present in live anymore
|
||||
};
|
||||
|
||||
enum class DurationCode {
|
||||
None = 0,
|
||||
Short = 1,
|
||||
Medium = 2,
|
||||
Long = 3
|
||||
};
|
||||
|
||||
// need to capture more, shared are just Radiant/Ebon though
|
||||
enum class PointType {
|
||||
None = 0,
|
||||
Radiant = 4,
|
||||
Ebon = 5,
|
||||
};
|
||||
|
||||
struct TaskInformation {
|
||||
TaskType type;
|
||||
int Duration;
|
||||
DurationCode dur_code; // description for time investment for when Duration == 0
|
||||
std::string Title; // max length 64
|
||||
std::string Description; // max length 4000, 2048 on Tit
|
||||
std::string Reward;
|
||||
std::string item_link; // max length 128 older clients, item link gets own string
|
||||
std::string completion_emote; // emote after completing task, yellow. Maybe should make more generic ... but yellow for now!
|
||||
int RewardID;
|
||||
int CashReward; // Expressed in copper
|
||||
int XPReward;
|
||||
int faction_reward; // just a npc_faction_id
|
||||
TaskMethodType RewardMethod;
|
||||
int reward_points; // DoN crystals for shared. Generic "points" for non-shared
|
||||
PointType reward_type; // 4 for Radiant Crystals else Ebon crystals when shared task
|
||||
int ActivityCount;
|
||||
SequenceType SequenceMode;
|
||||
int LastStep;
|
||||
short MinLevel;
|
||||
short MaxLevel;
|
||||
bool Repeatable;
|
||||
int replay_group; // ID of our replay timer group (0 means none)
|
||||
int min_players; // shared tasks
|
||||
int max_players;
|
||||
int task_lock_step; // task locks after this step is completed
|
||||
uint32 instance_zone_id; // instance shit
|
||||
uint32 zone_version;
|
||||
uint16 zone_in_zone_id;
|
||||
float zone_in_x;
|
||||
float zone_in_y;
|
||||
uint16 zone_in_object_id;
|
||||
float dest_x;
|
||||
float dest_y;
|
||||
float dest_z;
|
||||
float dest_h;
|
||||
/* int graveyard_zone_id;
|
||||
float graveyard_x;
|
||||
float graveyard_y;
|
||||
float graveyard_z;
|
||||
float graveyard_radius; */
|
||||
ActivityInformation Activity[MAXACTIVITIESPERTASK];
|
||||
};
|
||||
|
||||
typedef enum { ActivityHidden = 0, ActivityActive = 1, ActivityCompleted = 2 } ActivityState;
|
||||
|
||||
typedef enum { ActivityDeliver = 1, ActivityKill = 2, ActivityLoot = 3, ActivitySpeakWith = 4, ActivityExplore = 5,
|
||||
ActivityTradeSkill = 6, ActivityFish = 7, ActivityForage = 8, ActivityCastOn = 9, ActivitySkillOn = 10,
|
||||
ActivityTouch = 11, ActivityCollect = 13, ActivityGiveCash = 100 } ActivityType;
|
||||
|
||||
|
||||
struct ClientActivityInformation {
|
||||
int ActivityID;
|
||||
@@ -267,7 +150,6 @@ public:
|
||||
void AcceptNewTask(Client *c, int TaskID, int NPCID, bool enforce_level_requirement = false);
|
||||
void AcceptNewSharedTask(Client *c, int TaskID, int NPCID, int id);
|
||||
void PendSharedTask(Client *c, int TaskID, int NPCID, bool enforce_level_requirement = false);
|
||||
void HandleCanJoinSharedTask(Client *c, int TaskID, int id);
|
||||
void FailTask(Client *c, int TaskID);
|
||||
int TaskTimeLeft(int TaskID);
|
||||
int IsTaskCompleted(int TaskID);
|
||||
@@ -345,13 +227,6 @@ private:
|
||||
bool CheckedTouchActivities;
|
||||
};
|
||||
|
||||
// used for timer lockouts and /tasktimers
|
||||
struct TaskTimer {
|
||||
int ID; // ID used in task timer
|
||||
int original_id; // original ID of the task
|
||||
int expires; // UNIX timestamp of when it expires, what happens with DLS? Fuck it.
|
||||
};
|
||||
|
||||
struct TaskReplayGroups {
|
||||
std::string name;
|
||||
int duration;
|
||||
|
||||
+1
-12
@@ -1954,6 +1954,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
||||
}
|
||||
case ServerOP_TaskReject:
|
||||
{
|
||||
// this will be reworked to not use the pend shit, we will depend on hoping successive requests just get thrown out
|
||||
int message = pack->ReadUInt32();
|
||||
char name[64] = { 0 };
|
||||
pack->ReadString(name);
|
||||
@@ -1968,18 +1969,6 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ServerOP_TaskRequest:
|
||||
{
|
||||
int id = pack->ReadUInt32(); // we need the ID when reply to world so we know which shared task we're going to
|
||||
int task_id = pack->ReadUInt32();
|
||||
char name[64] = { 0 };
|
||||
pack->ReadString(name);
|
||||
auto client = entity_list.GetClientByName(name);
|
||||
if (client) {
|
||||
client->HandleCanJoinSharedTask(task_id, id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
std::cout << " Unknown ZSopcode:" << (int)pack->opcode;
|
||||
std::cout << " size:" << pack->size << std::endl;
|
||||
|
||||
Reference in New Issue
Block a user