Reformat save/load since they were lacking tabs

This commit is contained in:
Michael Cook (mackal) 2018-07-08 17:35:37 -04:00
parent 9b229779db
commit 7e0c4eb93f

View File

@ -278,140 +278,147 @@ bool TaskManager::LoadTasks(int singleTask)
return true; return true;
} }
bool TaskManager::SaveClientState(Client *c, ClientTaskState *state) { bool TaskManager::SaveClientState(Client *c, ClientTaskState *state)
{
// I am saving the slot in the ActiveTasks table, because unless a Task is cancelled/completed, the client doesn't // I am saving the slot in the ActiveTasks table, because unless a Task is cancelled/completed, the client
// seem to like tasks moving slots between zoning and you can end up with 'bogus' activities if the task previously // doesn't seem to like tasks moving slots between zoning and you can end up with 'bogus' activities if the task
// in that slot had more activities than the one now occupying it. Hopefully retaining the slot number for the // previously in that slot had more activities than the one now occupying it. Hopefully retaining the slot
// duration of a session will overcome this. // number for the duration of a session will overcome this.
// if (!c || !state)
if(!c || !state) return false;
return false;
const char *ERR_MYSQLERROR = "[TASKS]Error in TaskManager::SaveClientState %s"; const char *ERR_MYSQLERROR = "[TASKS]Error in TaskManager::SaveClientState %s";
int characterID = c->CharacterID(); int characterID = c->CharacterID();
Log(Logs::Detail, Logs::Tasks,"TaskManager::SaveClientState for character ID %d", characterID); Log(Logs::Detail, Logs::Tasks, "TaskManager::SaveClientState for character ID %d", characterID);
if(state->ActiveTaskCount > 0) { // TODO: tasks if (state->ActiveTaskCount > 0) { // TODO: tasks
for(int task=0; task<MAXACTIVEQUESTS; task++) { for (int task = 0; task < MAXACTIVEQUESTS; task++) {
int taskID = state->ActiveQuests[task].TaskID; int taskID = state->ActiveQuests[task].TaskID;
if(taskID==TASKSLOTEMPTY) if (taskID == TASKSLOTEMPTY)
continue; continue;
if(state->ActiveQuests[task].Updated) { if (state->ActiveQuests[task].Updated) {
Log(Logs::General, Logs::Tasks, "[CLIENTSAVE] TaskManager::SaveClientState for character ID %d, Updating TaskIndex %i TaskID %i", characterID, task, taskID); Log(Logs::General, Logs::Tasks,
"[CLIENTSAVE] TaskManager::SaveClientState for character ID %d, Updating TaskIndex "
"%i TaskID %i",
characterID, task, taskID);
std::string query = StringFormat("REPLACE INTO character_tasks (charid, taskid, slot, type, acceptedtime) " std::string query = StringFormat(
"VALUES (%i, %i, %i, %i, %i)", "REPLACE INTO character_tasks (charid, taskid, slot, type, acceptedtime) "
characterID, taskID, task, static_cast<int>(Tasks[taskID]->type), state->ActiveQuests[task].AcceptedTime); "VALUES (%i, %i, %i, %i, %i)",
auto results = database.QueryDatabase(query); characterID, taskID, task, static_cast<int>(Tasks[taskID]->type),
state->ActiveQuests[task].AcceptedTime);
auto results = database.QueryDatabase(query);
if (!results.Success()) { if (!results.Success()) {
Log(Logs::General, Logs::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); Log(Logs::General, Logs::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str());
} } else {
else {
state->ActiveQuests[task].Updated = false; state->ActiveQuests[task].Updated = false;
} }
} }
std::string query = "REPLACE INTO character_activities (charid, taskid, activityid, donecount, completed) " std::string query =
"VALUES "; "REPLACE INTO character_activities (charid, taskid, activityid, donecount, completed) "
"VALUES ";
int updatedActivityCount = 0; int updatedActivityCount = 0;
for(int activityIndex = 0; activityIndex<Tasks[taskID]->ActivityCount; ++activityIndex) { for (int activityIndex = 0; activityIndex < Tasks[taskID]->ActivityCount; ++activityIndex) {
if(!state->ActiveQuests[task].Activity[activityIndex].Updated) if (!state->ActiveQuests[task].Activity[activityIndex].Updated)
continue; continue;
Log(Logs::General, Logs::Tasks, "[CLIENTSAVE] TaskManager::SaveClientSate for character ID %d, Updating Activity %i, %i", Log(Logs::General, Logs::Tasks,
characterID, task, activityIndex); "[CLIENTSAVE] TaskManager::SaveClientSate for character ID %d, Updating Activity "
"%i, %i",
characterID, task, activityIndex);
if(updatedActivityCount==0) if (updatedActivityCount == 0)
query += StringFormat("(%i, %i, %i, %i, %i)", query +=
characterID, taskID, activityIndex, StringFormat("(%i, %i, %i, %i, %i)", characterID, taskID, activityIndex,
state->ActiveQuests[task].Activity[activityIndex].DoneCount, state->ActiveQuests[task].Activity[activityIndex].DoneCount,
state->ActiveQuests[task].Activity[activityIndex].State == ActivityCompleted); state->ActiveQuests[task].Activity[activityIndex].State ==
else ActivityCompleted);
query += StringFormat(", (%i, %i, %i, %i, %i)", else
characterID, taskID, activityIndex, query +=
state->ActiveQuests[task].Activity[activityIndex].DoneCount, StringFormat(", (%i, %i, %i, %i, %i)", characterID, taskID, activityIndex,
state->ActiveQuests[task].Activity[activityIndex].State == ActivityCompleted); state->ActiveQuests[task].Activity[activityIndex].DoneCount,
state->ActiveQuests[task].Activity[activityIndex].State ==
ActivityCompleted);
updatedActivityCount++; updatedActivityCount++;
} }
if(updatedActivityCount == 0) if (updatedActivityCount == 0)
continue; continue;
Log(Logs::General, Logs::Tasks, "[CLIENTSAVE] Executing query %s", query.c_str()); Log(Logs::General, Logs::Tasks, "[CLIENTSAVE] Executing query %s", query.c_str());
auto results = database.QueryDatabase(query); auto results = database.QueryDatabase(query);
if(!results.Success()) { if (!results.Success()) {
Log(Logs::General, Logs::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); Log(Logs::General, Logs::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str());
continue; continue;
} }
state->ActiveQuests[task].Updated=false;
for(int activityIndex=0; activityIndex<Tasks[taskID]->ActivityCount; ++activityIndex)
state->ActiveQuests[task].Activity[activityIndex].Updated=false;
state->ActiveQuests[task].Updated = false;
for (int activityIndex = 0; activityIndex < Tasks[taskID]->ActivityCount; ++activityIndex)
state->ActiveQuests[task].Activity[activityIndex].Updated = false;
} }
} }
if(!RuleB(TaskSystem, RecordCompletedTasks) || (state->CompletedTasks.size() <= (unsigned int)state->LastCompletedTaskLoaded)) { if (!RuleB(TaskSystem, RecordCompletedTasks) ||
state->LastCompletedTaskLoaded = state->CompletedTasks.size(); (state->CompletedTasks.size() <= (unsigned int)state->LastCompletedTaskLoaded)) {
return true; state->LastCompletedTaskLoaded = state->CompletedTasks.size();
} return true;
}
const char* completedTaskQuery = "REPLACE INTO completed_tasks (charid, completedtime, taskid, activityid) " const char *completedTaskQuery = "REPLACE INTO completed_tasks (charid, completedtime, taskid, activityid) "
"VALUES (%i, %i, %i, %i)"; "VALUES (%i, %i, %i, %i)";
for(unsigned int i=state->LastCompletedTaskLoaded; i<state->CompletedTasks.size(); i++) { for (unsigned int i = state->LastCompletedTaskLoaded; i < state->CompletedTasks.size(); i++) {
Log(Logs::General, Logs::Tasks, "[CLIENTSAVE] TaskManager::SaveClientState Saving Completed Task at slot %i", i); Log(Logs::General, Logs::Tasks,
int taskID = state->CompletedTasks[i].TaskID; "[CLIENTSAVE] TaskManager::SaveClientState Saving Completed Task at slot %i", i);
int taskID = state->CompletedTasks[i].TaskID;
if((taskID <= 0) || (taskID >= MAXTASKS) || (Tasks[taskID] == nullptr)) if ((taskID <= 0) || (taskID >= MAXTASKS) || (Tasks[taskID] == nullptr))
continue; continue;
// First we save a record with an ActivityID of -1. // First we save a record with an ActivityID of -1.
// This indicates this task was completed at the given time. We infer that all // This indicates this task was completed at the given time. We infer that all
// none optional activities were completed. // none optional activities were completed.
// //
std::string query = StringFormat(completedTaskQuery, characterID, state->CompletedTasks[i].CompletedTime, taskID, -1); std::string query =
auto results = database.QueryDatabase(query); StringFormat(completedTaskQuery, characterID, state->CompletedTasks[i].CompletedTime, taskID, -1);
if(!results.Success()) { auto results = database.QueryDatabase(query);
Log(Logs::General, Logs::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); if (!results.Success()) {
continue; Log(Logs::General, Logs::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str());
} continue;
}
// If the Rule to record non-optional task completion is not enabled, don't save it // If the Rule to record non-optional task completion is not enabled, don't save it
if(!RuleB(TaskSystem, RecordCompletedOptionalActivities)) if (!RuleB(TaskSystem, RecordCompletedOptionalActivities))
continue; continue;
// Insert one record for each completed optional task. // Insert one record for each completed optional task.
for(int j=0; j<Tasks[taskID]->ActivityCount; j++) { for (int j = 0; j < Tasks[taskID]->ActivityCount; j++) {
if(!Tasks[taskID]->Activity[j].Optional || !state->CompletedTasks[i].ActivityDone[j]) if (!Tasks[taskID]->Activity[j].Optional || !state->CompletedTasks[i].ActivityDone[j])
continue; continue;
query = StringFormat(completedTaskQuery, characterID, state->CompletedTasks[i].CompletedTime, taskID, j); query = StringFormat(completedTaskQuery, characterID, state->CompletedTasks[i].CompletedTime,
results = database.QueryDatabase(query); taskID, j);
if(!results.Success()) results = database.QueryDatabase(query);
Log(Logs::General, Logs::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); if (!results.Success())
Log(Logs::General, Logs::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str());
}
}
} state->LastCompletedTaskLoaded = state->CompletedTasks.size();
}
state->LastCompletedTaskLoaded = state->CompletedTasks.size();
return true; return true;
} }
void Client::LoadClientTaskState() { void Client::LoadClientTaskState() {
if(RuleB(TaskSystem, EnableTaskSystem) && taskmanager) { if(RuleB(TaskSystem, EnableTaskSystem) && taskmanager) {
@ -438,10 +445,10 @@ void Client::RemoveClientTaskState() {
} }
} }
bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) { bool TaskManager::LoadClientState(Client *c, ClientTaskState *state)
{
if(!c || !state) if (!c || !state)
return false; return false;
int characterID = c->CharacterID(); int characterID = c->CharacterID();
@ -449,182 +456,202 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) {
Log(Logs::General, Logs::Tasks, "[CLIENTLOAD] TaskManager::LoadClientState for character ID %d", characterID); Log(Logs::General, Logs::Tasks, "[CLIENTLOAD] TaskManager::LoadClientState for character ID %d", characterID);
std::string query = StringFormat("SELECT `taskid`, `slot`, `acceptedtime` " std::string query = StringFormat("SELECT `taskid`, `slot`, `acceptedtime` "
"FROM `character_tasks` " "FROM `character_tasks` "
"WHERE `charid` = %i ORDER BY acceptedtime", characterID); "WHERE `charid` = %i ORDER BY acceptedtime",
auto results = database.QueryDatabase(query); characterID);
if (!results.Success()) { auto results = database.QueryDatabase(query);
Log(Logs::General, Logs::Error, "[TASKS]Error in TaskManager::LoadClientState load Tasks: %s", results.ErrorMessage().c_str()); if (!results.Success()) {
Log(Logs::General, Logs::Error, "[TASKS]Error in TaskManager::LoadClientState load Tasks: %s",
results.ErrorMessage().c_str());
return false; return false;
} }
for(auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
int taskID = atoi(row[0]); int taskID = atoi(row[0]);
int slot = atoi(row[1]); int slot = atoi(row[1]);
if((taskID<0) || (taskID>=MAXTASKS)) { if ((taskID < 0) || (taskID >= MAXTASKS)) {
Log(Logs::General, Logs::Error, "[TASKS]Task ID %i out of range while loading character tasks from database", taskID); Log(Logs::General, Logs::Error,
continue; "[TASKS]Task ID %i out of range while loading character tasks from database", taskID);
} continue;
}
if((slot<0) || (slot>=MAXACTIVEQUESTS)) { if ((slot < 0) || (slot >= MAXACTIVEQUESTS)) {
Log(Logs::General, Logs::Error, "[TASKS] Slot %i out of range while loading character tasks from database", slot); Log(Logs::General, Logs::Error,
continue; "[TASKS] Slot %i out of range while loading character tasks from database", slot);
} continue;
}
if(state->ActiveQuests[slot].TaskID != TASKSLOTEMPTY) { if (state->ActiveQuests[slot].TaskID != TASKSLOTEMPTY) {
Log(Logs::General, Logs::Error, "[TASKS] Slot %i for Task %is is already occupied.", slot, taskID); Log(Logs::General, Logs::Error, "[TASKS] Slot %i for Task %is is already occupied.", slot,
continue; taskID);
} continue;
}
int acceptedtime = atoi(row[2]); int acceptedtime = atoi(row[2]);
state->ActiveQuests[slot].TaskID = taskID; state->ActiveQuests[slot].TaskID = taskID;
state->ActiveQuests[slot].CurrentStep = -1; state->ActiveQuests[slot].CurrentStep = -1;
state->ActiveQuests[slot].AcceptedTime = acceptedtime; state->ActiveQuests[slot].AcceptedTime = acceptedtime;
state->ActiveQuests[slot].Updated = false; state->ActiveQuests[slot].Updated = false;
for(int i=0; i<MAXACTIVITIESPERTASK; i++) for (int i = 0; i < MAXACTIVITIESPERTASK; i++)
state->ActiveQuests[slot].Activity[i].ActivityID = -1; state->ActiveQuests[slot].Activity[i].ActivityID = -1;
++state->ActiveTaskCount; ++state->ActiveTaskCount;
Log(Logs::General, Logs::Tasks, "[CLIENTLOAD] TaskManager::LoadClientState. Char: %i Task ID %i, Accepted Time: %8X", characterID, taskID, acceptedtime); Log(Logs::General, Logs::Tasks,
"[CLIENTLOAD] TaskManager::LoadClientState. Char: %i Task ID %i, Accepted Time: %8X", characterID,
taskID, acceptedtime);
} }
// Load Activities // Load Activities
Log(Logs::General, Logs::Tasks, "[CLIENTLOAD] LoadClientState. Loading activities for character ID %d", characterID); Log(Logs::General, Logs::Tasks, "[CLIENTLOAD] LoadClientState. Loading activities for character ID %d",
characterID);
query = StringFormat("SELECT `taskid`, `activityid`, `donecount`, `completed` " query = StringFormat("SELECT `taskid`, `activityid`, `donecount`, `completed` "
"FROM `character_activities` " "FROM `character_activities` "
"WHERE `charid` = %i " "WHERE `charid` = %i "
"ORDER BY `taskid` ASC, `activityid` ASC", characterID); "ORDER BY `taskid` ASC, `activityid` ASC",
results = database.QueryDatabase(query); characterID);
if (!results.Success()){ results = database.QueryDatabase(query);
Log(Logs::General, Logs::Error, "[TASKS]Error in TaskManager::LoadClientState load Activities: %s", results.ErrorMessage().c_str()); if (!results.Success()) {
Log(Logs::General, Logs::Error, "[TASKS]Error in TaskManager::LoadClientState load Activities: %s",
results.ErrorMessage().c_str());
return false; return false;
} }
for (auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
int taskID = atoi(row[0]); int taskID = atoi(row[0]);
if((taskID<0) || (taskID>=MAXTASKS)) { if ((taskID < 0) || (taskID >= MAXTASKS)) {
Log(Logs::General, Logs::Error, "[TASKS]Task ID %i out of range while loading character activities from database", taskID); Log(Logs::General, Logs::Error,
continue; "[TASKS]Task ID %i out of range while loading character activities from database", taskID);
} continue;
}
int activityID = atoi(row[1]); int activityID = atoi(row[1]);
if((activityID<0) || (activityID>=MAXACTIVITIESPERTASK)) { if ((activityID < 0) || (activityID >= MAXACTIVITIESPERTASK)) {
Log(Logs::General, Logs::Error, "[TASKS]Activity ID %i out of range while loading character activities from database", activityID); Log(Logs::General, Logs::Error,
continue; "[TASKS]Activity ID %i out of range while loading character activities from database",
} activityID);
continue;
}
// Find Active Task Slot // Find Active Task Slot
int activeTaskIndex = -1; int activeTaskIndex = -1;
for(int i=0; i<MAXACTIVEQUESTS; i++) for (int i = 0; i < MAXACTIVEQUESTS; i++)
if(state->ActiveQuests[i].TaskID == taskID) { if (state->ActiveQuests[i].TaskID == taskID) {
activeTaskIndex = i; activeTaskIndex = i;
break; break;
} }
if(activeTaskIndex == -1) { if (activeTaskIndex == -1) {
Log(Logs::General, Logs::Error, "[TASKS]Activity %i found for task %i which client does not have.", activityID, taskID); Log(Logs::General, Logs::Error,
continue; "[TASKS]Activity %i found for task %i which client does not have.", activityID, taskID);
} continue;
}
int doneCount = atoi(row[2]); int doneCount = atoi(row[2]);
bool completed = atoi(row[3]); bool completed = atoi(row[3]);
state->ActiveQuests[activeTaskIndex].Activity[activityID].ActivityID = activityID; state->ActiveQuests[activeTaskIndex].Activity[activityID].ActivityID = activityID;
state->ActiveQuests[activeTaskIndex].Activity[activityID].DoneCount = doneCount; state->ActiveQuests[activeTaskIndex].Activity[activityID].DoneCount = doneCount;
if(completed) if (completed)
state->ActiveQuests[activeTaskIndex].Activity[activityID].State = ActivityCompleted; state->ActiveQuests[activeTaskIndex].Activity[activityID].State = ActivityCompleted;
else else
state->ActiveQuests[activeTaskIndex].Activity[activityID].State = ActivityHidden; state->ActiveQuests[activeTaskIndex].Activity[activityID].State = ActivityHidden;
state->ActiveQuests[activeTaskIndex].Activity[activityID].Updated = false; state->ActiveQuests[activeTaskIndex].Activity[activityID].Updated = false;
Log(Logs::General, Logs::Tasks, "[CLIENTLOAD] TaskManager::LoadClientState. Char: %i Task ID %i, ActivityID: %i, DoneCount: %i, Completed: %i", characterID, taskID, activityID, doneCount, completed); Log(Logs::General, Logs::Tasks,
"[CLIENTLOAD] TaskManager::LoadClientState. Char: %i Task ID %i, ActivityID: %i, DoneCount: %i, "
"Completed: %i",
characterID, taskID, activityID, doneCount, completed);
}
} if (RuleB(TaskSystem, RecordCompletedTasks)) {
query = StringFormat("SELECT `taskid`, `activityid`, `completedtime` "
if(RuleB(TaskSystem, RecordCompletedTasks)) { "FROM `completed_tasks` "
query = StringFormat("SELECT `taskid`, `activityid`, `completedtime` " "WHERE `charid` = %i ORDER BY completedtime, taskid, activityid",
"FROM `completed_tasks` " characterID);
"WHERE `charid` = %i ORDER BY completedtime, taskid, activityid", results = database.QueryDatabase(query);
characterID); if (!results.Success()) {
results = database.QueryDatabase(query); Log(Logs::General, Logs::Error,
if (!results.Success()) { "[TASKS]Error in TaskManager::LoadClientState load completed tasks: %s",
Log(Logs::General, Logs::Error, "[TASKS]Error in TaskManager::LoadClientState load completed tasks: %s", results.ErrorMessage().c_str()); results.ErrorMessage().c_str());
return false; return false;
} }
CompletedTaskInformation cti; CompletedTaskInformation cti;
for(int i=0; i<MAXACTIVITIESPERTASK; i++) for (int i = 0; i < MAXACTIVITIESPERTASK; i++)
cti.ActivityDone[i] = false; cti.ActivityDone[i] = false;
int previousTaskID = -1; int previousTaskID = -1;
int previousCompletedTime = -1; int previousCompletedTime = -1;
for(auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
int taskID = atoi(row[0]); int taskID = atoi(row[0]);
if((taskID <= 0) || (taskID >=MAXTASKS)) { if ((taskID <= 0) || (taskID >= MAXTASKS)) {
Log(Logs::General, Logs::Error, "[TASKS]Task ID %i out of range while loading completed tasks from database", taskID); Log(Logs::General, Logs::Error,
continue; "[TASKS]Task ID %i out of range while loading completed tasks from database",
} taskID);
continue;
}
// An ActivityID of -1 means mark all the none optional activities in the // An ActivityID of -1 means mark all the none optional activities in the
// task as complete. If the Rule to record optional activities is enabled, // task as complete. If the Rule to record optional activities is enabled,
// subsequent records for this task will flag any optional tasks that were // subsequent records for this task will flag any optional tasks that were
// completed. // completed.
int activityID = atoi(row[1]); int activityID = atoi(row[1]);
if((activityID<-1) || (activityID>=MAXACTIVITIESPERTASK)) { if ((activityID < -1) || (activityID >= MAXACTIVITIESPERTASK)) {
Log(Logs::General, Logs::Error, "[TASKS]Activity ID %i out of range while loading completed tasks from database", activityID); Log(Logs::General, Logs::Error,
continue; "[TASKS]Activity ID %i out of range while loading completed tasks from database",
} activityID);
continue;
}
int completedTime = atoi(row[2]); int completedTime = atoi(row[2]);
if((previousTaskID != -1) && ((taskID != previousTaskID) || (completedTime != previousCompletedTime))) { if ((previousTaskID != -1) &&
state->CompletedTasks.push_back(cti); ((taskID != previousTaskID) || (completedTime != previousCompletedTime))) {
for(int i=0; i<MAXACTIVITIESPERTASK; i++) state->CompletedTasks.push_back(cti);
cti.ActivityDone[i] = false; for (int i = 0; i < MAXACTIVITIESPERTASK; i++)
} cti.ActivityDone[i] = false;
}
cti.TaskID = previousTaskID = taskID; cti.TaskID = previousTaskID = taskID;
cti.CompletedTime = previousCompletedTime = completedTime; cti.CompletedTime = previousCompletedTime = completedTime;
// If ActivityID is -1, Mark all the non-optional tasks as completed. // If ActivityID is -1, Mark all the non-optional tasks as completed.
if(activityID < 0) { if (activityID < 0) {
TaskInformation* task = Tasks[taskID]; TaskInformation *task = Tasks[taskID];
if(task == nullptr) if (task == nullptr)
continue; continue;
for(int i=0; i<task->ActivityCount; i++) for (int i = 0; i < task->ActivityCount; i++)
if(!task->Activity[i].Optional) if (!task->Activity[i].Optional)
cti.ActivityDone[i] = true; cti.ActivityDone[i] = true;
} } else
else cti.ActivityDone[activityID] = true;
cti.ActivityDone[activityID] = true; }
} if (previousTaskID != -1)
state->CompletedTasks.push_back(cti);
if(previousTaskID != -1)
state->CompletedTasks.push_back(cti);
state->LastCompletedTaskLoaded = state->CompletedTasks.size();
state->LastCompletedTaskLoaded = state->CompletedTasks.size();
} }
query = StringFormat("SELECT `taskid` FROM character_enabledtasks " query = StringFormat("SELECT `taskid` FROM character_enabledtasks "
"WHERE `charid` = %i AND `taskid` >0 AND `taskid` < %i " "WHERE `charid` = %i AND `taskid` >0 AND `taskid` < %i "
"ORDER BY `taskid` ASC", "ORDER BY `taskid` ASC",
characterID, MAXTASKS); characterID, MAXTASKS);
results = database.QueryDatabase(query); results = database.QueryDatabase(query);
if (!results.Success()) { if (!results.Success()) {
Log(Logs::General, Logs::Error, "[TASKS]Error in TaskManager::LoadClientState load enabled tasks: %s", results.ErrorMessage().c_str()); Log(Logs::General, Logs::Error, "[TASKS]Error in TaskManager::LoadClientState load enabled tasks: %s",
} results.ErrorMessage().c_str());
else { } else {
for (auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
int taskID = atoi(row[0]); int taskID = atoi(row[0]);
state->EnabledTasks.push_back(taskID); state->EnabledTasks.push_back(taskID);
@ -635,28 +662,34 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) {
// Check that there is an entry in the client task state for every activity in each task // Check that there is an entry in the client task state for every activity in each task
// This should only break if a ServerOP adds or deletes activites for a task that players already // This should only break if a ServerOP adds or deletes activites for a task that players already
// have active, or due to a bug. // have active, or due to a bug.
for(int i=0; i<MAXACTIVEQUESTS; i++) { for (int i = 0; i < MAXACTIVEQUESTS; i++) {
int taskID = state->ActiveQuests[i].TaskID; int taskID = state->ActiveQuests[i].TaskID;
if(taskID==TASKSLOTEMPTY) continue; if (taskID == TASKSLOTEMPTY)
if(!Tasks[taskID]) {
c->Message(13, "Active Task Slot %i, references a task (%i), that does not exist. "
"Removing from memory. Contact a GM to resolve this.",i, taskID);
Log(Logs::General, Logs::Error, "[TASKS]Character %i has task %i which does not exist.", characterID, taskID);
state->ActiveQuests[i].TaskID=TASKSLOTEMPTY;
continue; continue;
if (!Tasks[taskID]) {
c->Message(13,
"Active Task Slot %i, references a task (%i), that does not exist. "
"Removing from memory. Contact a GM to resolve this.",
i, taskID);
Log(Logs::General, Logs::Error, "[TASKS]Character %i has task %i which does not exist.",
characterID, taskID);
state->ActiveQuests[i].TaskID = TASKSLOTEMPTY;
continue;
} }
for(int j=0; j<Tasks[taskID]->ActivityCount; j++) { for (int j = 0; j < Tasks[taskID]->ActivityCount; j++) {
if(state->ActiveQuests[i].Activity[j].ActivityID != j) { if (state->ActiveQuests[i].Activity[j].ActivityID != j) {
c->Message(13, "Active Task %i, %s. Activity count does not match expected value." c->Message(13,
"Removing from memory. Contact a GM to resolve this.", "Active Task %i, %s. Activity count does not match expected value."
taskID, Tasks[taskID]->Title.c_str()); "Removing from memory. Contact a GM to resolve this.",
taskID, Tasks[taskID]->Title.c_str());
Log(Logs::General, Logs::Error, "[TASKS]Fatal error in character %i task state. Activity %i for " Log(Logs::General, Logs::Error,
"Task %i either missing from client state or from task.", characterID, j, taskID); "[TASKS]Fatal error in character %i task state. Activity %i for "
state->ActiveQuests[i].TaskID=TASKSLOTEMPTY; "Task %i either missing from client state or from task.",
characterID, j, taskID);
state->ActiveQuests[i].TaskID = TASKSLOTEMPTY;
break; break;
} }
} }