Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Tasks] Avoid removing client tasks from memory on load #4052

Merged
merged 1 commit into from
Feb 10, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 23 additions & 46 deletions zone/task_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1298,13 +1298,23 @@ bool TaskManager::LoadClientState(Client *client, ClientTaskState *cts)
fmt::format("charid = {} ORDER BY acceptedtime", character_id)
);

std::vector<int> remove;

for (auto &character_task: character_tasks) {
int task_id = character_task.taskid;
int slot = character_task.slot;

const TaskInformation* task = GetTaskData(task_id);
if (!task)
{
LogError("Character [{}] has task [{}] which does not exist", character_id, task_id);
remove.push_back(task_id);
continue;
}

// this used to be loaded from character_tasks
// this should just load from the tasks table
auto type = task_manager->GetTaskType(character_task.taskid);
auto type = task->type;

if (task_id < 0) {
LogTasks(
Expand All @@ -1328,6 +1338,7 @@ bool TaskManager::LoadClientState(Client *client, ClientTaskState *cts)

if (task_info->task_id != TASKSLOTEMPTY) {
LogTasks("Error: slot [{}] for task [{}] is already occupied", slot, task_id);
remove.push_back(task_id);
continue;
}

Expand All @@ -1336,8 +1347,10 @@ bool TaskManager::LoadClientState(Client *client, ClientTaskState *cts)
task_info->updated = false;
task_info->was_rewarded = character_task.was_rewarded;

for (auto &i : task_info->activity) {
i.activity_id = -1;
// enable all states in memory, any missing from db get inserted if updated
for (int i = 0; i < MAXACTIVITIESPERTASK; ++i)
{
task_info->activity[i].activity_id = i < task->activity_count ? i : -1;
}

// this check keeps a lot of core task updating code from working properly (shared or otherwise)
Expand All @@ -1355,6 +1368,13 @@ bool TaskManager::LoadClientState(Client *client, ClientTaskState *cts)
);
}

if (!remove.empty())
{
std::string filter = fmt::format("charid = {} AND taskid IN ({})", character_id, fmt::join(remove, ","));
CharacterTasksRepository::DeleteWhere(database, filter);
CharacterActivitiesRepository::DeleteWhere(database, filter);
}

// Load Activities
LogTasks("Loading activities for character_id [{}]", character_id);

Expand Down Expand Up @@ -1525,49 +1545,6 @@ bool TaskManager::LoadClientState(Client *client, ClientTaskState *cts)
}
}

// Check that there is an entry in the client task state for every activity_information in each task
// This should only break if a ServerOP adds or deletes activites for a task that players already
// have active, or due to a bug.
for (int task_index = 0; task_index < MAXACTIVEQUESTS + 1; task_index++) {
int task_id = cts->m_active_tasks[task_index].task_id;
if (task_id == TASKSLOTEMPTY) {
continue;
}
const auto task_data = GetTaskData(task_id);
if (!task_data) {
client->Message(
Chat::Red,
"Active Task Slot %i, references a task (%i), that does not exist. "
"Removing from memory. Contact a GM to resolve this.",
task_index,
task_id
);

LogError("Character [{}] has task [{}] which does not exist", character_id, task_id);
cts->m_active_tasks[task_index].task_id = TASKSLOTEMPTY;
continue;
}
for (int activity_index = 0; activity_index < task_data->activity_count; activity_index++) {
if (cts->m_active_tasks[task_index].activity[activity_index].activity_id != activity_index) {
client->Message(
Chat::Red,
"Active Task %i, %s. activity_information count does not match expected value."
"Removing from memory. Contact a GM to resolve this.",
task_id, task_data->title.c_str()
);

LogTasks(
"Fatal error in character [{}] task state. activity_information [{}] for Task [{}] either missing from client state or from task",
character_id,
activity_index,
task_id
);
cts->m_active_tasks[task_index].task_id = TASKSLOTEMPTY;
break;
}
}
}

LogTasksDetail(
"m_active_task task_id is [{}] slot [{}]",
cts->m_active_task.task_id,
Expand Down