Bunch more work on fixing up DB and packets

This commit is contained in:
Michael Cook (mackal)
2018-07-02 22:01:17 -04:00
parent 1b8736188d
commit 0ea82b5d88
8 changed files with 360 additions and 162 deletions
+123 -161
View File
@@ -172,21 +172,19 @@ bool TaskManager::LoadTasks(int singleTask)
}
if (singleTask == 0)
query = StringFormat("SELECT `taskid`, `step`, `activityid`, `activitytype`, "
"`text1`, `text2`, `text3`, `goalid`, `goalmethod`, "
"`goalcount`, `delivertonpc`, `zoneid`, `optional` "
"FROM `activities` "
"WHERE `taskid` < %i AND `activityid` < %i "
"ORDER BY taskid, activityid ASC",
MAXTASKS, MAXACTIVITIESPERTASK);
query =
StringFormat("SELECT `taskid`, `step`, `activityid`, `activitytype`, `target_name`, `item_list`, "
"`skill_list`, `spell_list`, `description_override`, `goalid`, `goalmethod`, "
"`goalcount`, `delivertonpc`, `zones`, `optional` FROM `activities` WHERE `taskid` < "
"%i AND `activityid` < %i ORDER BY taskid, activityid ASC",
MAXTASKS, MAXACTIVITIESPERTASK);
else
query = StringFormat("SELECT `taskid`, `step`, `activityid`, `activitytype`, "
"`text1`, `text2`, `text3`, `goalid`, `goalmethod`, "
"`goalcount`, `delivertonpc`, `zoneid`, `optional` "
"FROM `activities` "
"WHERE `taskid` = %i AND `activityid` < %i "
"ORDER BY taskid, activityid ASC",
singleTask, MAXACTIVITIESPERTASK);
query =
StringFormat("SELECT `taskid`, `step`, `activityid`, `activitytype`, `target_name`, `item_list`, "
"`skill_list`, `spell_list`, `description_override`, `goalid`, `goalmethod`, "
"`goalcount`, `delivertonpc`, `zones`, `optional` FROM `activities` WHERE `taskid` = "
"%i AND `activityid` < %i ORDER BY taskid, activityid ASC",
singleTask, MAXACTIVITIESPERTASK);
results = database.QueryDatabase(query);
if (!results.Success()) {
Log(Logs::General, Logs::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str());
@@ -237,38 +235,42 @@ bool TaskManager::LoadTasks(int singleTask)
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Type = atoi(row[3]);
if (row[4][0])
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Text1 = row[4];
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].target_name = row[4];
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].item_list = row[5];
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].skill_list = row[6];
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].skill_id = atoi(row[6]); // for older clients
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].spell_list = row[7];
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].spell_id = atoi(row[7]); // for older clients
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].desc_override = row[8];
if (row[5][0])
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Text2 = row[5];
if (row[6][0])
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Text3 = row[6];
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].GoalID = atoi(row[7]);
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].GoalMethod = (TaskMethodType)atoi(row[8]);
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].GoalCount = atoi(row[9]);
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].DeliverToNPC = atoi(row[10]);
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].ZoneID = atoi(row[11]);
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Optional = atoi(row[12]);
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].GoalID = atoi(row[9]);
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].GoalMethod = (TaskMethodType)atoi(row[10]);
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].GoalCount = atoi(row[11]);
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].DeliverToNPC = atoi(row[12]);
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].zones = row[13];
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].ZoneID = atoi(row[13]); // for older clients
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Optional = atoi(row[14]);
Log(Logs::General, Logs::Tasks,
"[GLOBALLOAD] Activity Slot %2i: ID %i for Task %5i. Type: %3i, GoalID: %8i, "
"GoalMethod: %i, GoalCount: %3i, ZoneID:%3i",
"GoalMethod: %i, GoalCount: %3i, Zones:%s",
Tasks[taskID]->ActivityCount, activityID, taskID,
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Type,
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].GoalID,
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].GoalMethod,
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].GoalCount,
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].ZoneID);
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].zones.c_str());
Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] Text1: %s",
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Text1.c_str());
Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] Text2: %s",
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Text2.c_str());
Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] Text3: %s",
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Text3.c_str());
Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] target_name: %s",
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].target_name.c_str());
Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] item_list: %s",
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].item_list.c_str());
Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] skill_list: %s",
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].skill_list.c_str());
Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] spell_list: %s",
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].spell_list.c_str());
Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] description_override: %s",
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].desc_override.c_str());
Tasks[taskID]->ActivityCount++;
}
@@ -1155,110 +1157,88 @@ void TaskManager::SendTaskSelector(Client *c, Mob *mob, int TaskCount, int *Task
}
void TaskManager::SendTaskSelectorNew(Client *c, Mob *mob, int TaskCount, int *TaskList) {
void TaskManager::SendTaskSelectorNew(Client *c, Mob *mob, int TaskCount, int *TaskList)
{
Log(Logs::General, Logs::Tasks, "[UPDATE] TaskSelector for %i Tasks", TaskCount);
int PlayerLevel = c->GetLevel();
// Check if any of the tasks exist
for(int i=0; i<TaskCount; i++)
{
if(Tasks[TaskList[i]] != nullptr) break;
}
int PacketLength = 12; // Header
for (int i = 0; i < TaskCount; i++)
if (Tasks[TaskList[i]] != nullptr)
break;
int ValidTasks = 0;
char StartZone[10];
for(int i=0; i<TaskCount; i++) {
if(!AppropriateLevel(TaskList[i], PlayerLevel)) continue;
if(c->IsTaskActive(TaskList[i])) continue;
if(!IsTaskRepeatable(TaskList[i]) && c->IsTaskCompleted(TaskList[i])) continue;
for (int i = 0; i < TaskCount; i++) {
if (!AppropriateLevel(TaskList[i], PlayerLevel))
continue;
if (c->IsTaskActive(TaskList[i]))
continue;
if (!IsTaskRepeatable(TaskList[i]) && c->IsTaskCompleted(TaskList[i]))
continue;
ValidTasks++;
PacketLength += 21; // Task Data - strings
PacketLength += Tasks[TaskList[i]]->Title.size() + 1 +
Tasks[TaskList[i]]->Description.size() + 1;
sprintf(StartZone, "%i", Tasks[TaskList[i]]->StartZone);
/*
PacketLength += strlen(Tasks[TaskList[i]]->Activity[ActivityID].Text1) + 1 +
strlen(Tasks[TaskList[i]]->Activity[ActivityID].Text2) +
strlen(Tasks[TaskList[i]]->Activity[ActivityID].Text3) + 1 +
strlen(itoa(Tasks[TaskList[i]]->Activity[ActivityID].ZoneID)) + 1 +
3 + 3 + 5; // Other strings (Hard set for now)
*/
PacketLength += 11 + 11 + 11 + 3 + 3 + (strlen(StartZone) * 2) + 2; // Other strings (Hard set for now)
PacketLength += 28; // Activity Data - strings (Hard set for 1 activity per task for now)
}
if(ValidTasks == 0) return;
if (ValidTasks == 0)
return;
auto outapp = new EQApplicationPacket(OP_OpenNewTasksWindow, PacketLength);
SerializeBuffer buf(50 * ValidTasks);
outapp->WriteUInt32(ValidTasks); // TaskCount
outapp->WriteUInt32(2); // Type, valid values: 0-3. 0 = Task, 1 = Shared Task, 2 = Quest, 3 = ???
buf.WriteUInt32(ValidTasks); // TaskCount
buf.WriteUInt32(2); // Type, valid values: 0-3. 0 = Task, 1 = Shared Task, 2 = Quest, 3 = ??? -- should fix maybe some day, but we let more than 1 type through :P
// so I guess an NPC can only offer one type of quests or we can only open a selection with one type :P (so quest call can tell us I guess)
// this is also sent in OP_TaskDescription
outapp->WriteUInt32(mob->GetID()); // TaskGiver
buf.WriteUInt32(mob->GetID()); // TaskGiver
for(int i=0; i<TaskCount;i++) { // max 40
for (int i = 0; i < TaskCount; i++) { // max 40
if (!AppropriateLevel(TaskList[i], PlayerLevel))
continue;
if (c->IsTaskActive(TaskList[i]))
continue;
if (!IsTaskRepeatable(TaskList[i]) && c->IsTaskCompleted(TaskList[i]))
continue;
if(!AppropriateLevel(TaskList[i], PlayerLevel)) continue;
buf.WriteUInt32(TaskList[i]); // TaskID
buf.WriteFloat(1.0f); // affects color, difficulty?
buf.WriteUInt32(Tasks[TaskList[i]]->Duration);
buf.WriteUInt32(static_cast<int>(Tasks[TaskList[i]]->dur_code)); // 1 = Short, 2 = Medium, 3 = Long, anything else Unlimited
if(c->IsTaskActive(TaskList[i])) continue;
buf.WriteString(Tasks[TaskList[i]]->Title.c_str()); // max 64 with null
buf.WriteString(Tasks[TaskList[i]]->Description.c_str()); // max 4000 with null
if(!IsTaskRepeatable(TaskList[i]) && c->IsTaskCompleted(TaskList[i])) continue;
buf.WriteUInt8(0); // Has reward set flag
buf.WriteUInt32(Tasks[TaskList[i]]->ActivityCount); // ActivityCount
outapp->WriteUInt32(TaskList[i]); // TaskID
outapp->WriteFloat(1.0f); // affects color, difficulty?
outapp->WriteUInt32(Tasks[TaskList[i]]->Duration);
outapp->WriteUInt32(static_cast<int>(Tasks[TaskList[i]]->dur_code)); // 1 = Short, 2 = Medium, 3 = Long, anything else Unlimited
for (int j = 0; j < Tasks[TaskList[i]]->ActivityCount; ++j) {
buf.WriteUInt32(j); // ActivityNumber
auto &activity = Tasks[TaskList[i]]->Activity[j];
buf.WriteUInt32(activity.Type); // ActivityType
buf.WriteUInt32(0); // solo, group, raid?
buf.WriteString(activity.target_name); // max length 64, "target name" so like loot x foo from bar (this is bar)
outapp->WriteString(Tasks[TaskList[i]]->Title.c_str()); // max 64 with null
outapp->WriteString(Tasks[TaskList[i]]->Description.c_str()); // max 4000 with null
// this string is item names
buf.WriteLengthString(activity.item_list.length(), activity.item_list.c_str());
outapp->WriteUInt8(0); // Has reward set flag
outapp->WriteUInt32(1); // ActivityCount - Hard set to 1 for now
buf.WriteUInt32(activity.GoalCount); // GoalCount
// Activity stuff below - Will need to iterate through each task
// Currently hard set for testing
// this string is skill IDs? probably one of the "use on" tasks
buf.WriteLengthString(activity.skill_list.length(), activity.skill_list.c_str());
// this string is spell IDs? probably one of the "use on" tasks
buf.WriteLengthString(activity.spell_list.length(), activity.spell_list.c_str());
sprintf(StartZone, "%i", Tasks[TaskList[i]]->StartZone);
outapp->WriteUInt32(0); // ActivityNumber
outapp->WriteUInt32(1); // ActivityType
outapp->WriteUInt32(0); // solo, group, raid?
outapp->WriteString("Text1 Test"); // max length 64 -- affects what string ID it will use for the description, should be a name here?
// this string is item names
outapp->WriteUInt32(11); // Text2Len
outapp->WriteString("Text2 Test");
outapp->WriteUInt32(1); // GoalCount
// this string is skill IDs? probably one of the "use on" tasks
outapp->WriteUInt32(3); // NumString1Len
outapp->WriteString("-1");
// this string is spell IDs? probably one of the "use on" tasks
outapp->WriteUInt32(3); // NumString2Len
outapp->WriteString("-1");
//outapp->WriteString(itoa(Tasks[TaskList[i]]->Activity[ActivityID].ZoneID));
outapp->WriteString(StartZone); // Zone number in ascii max length 64, can be multiple with separated by ;
outapp->WriteString("Text3 Test"); // max length 128 -- overrides the automatic descriptions
outapp->WriteString(StartZone); // Zone number in ascii max length 64, probably can be separated by ; too, haven't found it used
//buf.WriteString(itoa(Tasks[TaskList[i]]->Activity[ActivityID].ZoneID));
buf.WriteString(activity.zones); // Zone number in ascii max length 64, can be multiple with separated by ;
buf.WriteString(activity.desc_override); // max length 128 -- overrides the automatic descriptions
// this doesn't appear to be shown to the client at all and isn't the same as zones ... defaults to '0' though
buf.WriteString(activity.zones); // Zone number in ascii max length 64, probably can be separated by ; too, haven't found it used
}
}
auto outapp = new EQApplicationPacket(OP_OpenNewTasksWindow, buf.buffer(), buf.length());
c->QueuePacket(outapp);
safe_delete(outapp);
@@ -2609,12 +2589,12 @@ void TaskManager::SendTaskActivityLong(Client *c, int TaskID, int ActivityID, in
tah->ActivityID = ActivityID;
tah->unknown3 = 0x00000000;
// We send our 'internal' types as ActivityUse1. text3 should be set to the activity description, so it makes
// We send our 'internal' types as ActivityCastOn. text3 should be set to the activity description, so it makes
// no difference to the client. All activity updates will be done based on our interal activity types.
if((Tasks[TaskID]->Activity[ActivityID].Type > 0) && Tasks[TaskID]->Activity[ActivityID].Type < 100)
tah->ActivityType = Tasks[TaskID]->Activity[ActivityID].Type;
else
tah->ActivityType = ActivityUse1;
tah->ActivityType = ActivityCastOn;
tah->Optional = Optional;
tah->unknown5 = 0x00000000;
@@ -2667,77 +2647,59 @@ void TaskManager::SendTaskActivityLong(Client *c, int TaskID, int ActivityID, in
}
// Used only by RoF+ Clients
void TaskManager::SendTaskActivityNew(Client *c, int TaskID, int ActivityID, int ClientTaskIndex, bool Optional, bool TaskComplete) {
void TaskManager::SendTaskActivityNew(Client *c, int TaskID, int ActivityID, int ClientTaskIndex, bool Optional, bool TaskComplete)
{
SerializeBuffer buf(100);
uint32 String2Len = 3;
if(TaskComplete)
String2Len = 4;
buf.WriteUInt32(ClientTaskIndex); // TaskSequenceNumber
buf.WriteUInt32(static_cast<uint32>(Tasks[TaskID]->type)); // task type
buf.WriteUInt32(TaskID);
buf.WriteUInt32(ActivityID);
buf.WriteUInt32(0); // unknown3
long PacketLength = 29 + 4 + 8 + 4 + 4 + 5;
PacketLength = PacketLength + Tasks[TaskID]->Activity[ActivityID].Text1.size() + 1 +
Tasks[TaskID]->Activity[ActivityID].Text2.size() + 1 +
Tasks[TaskID]->Activity[ActivityID].Text3.size() + 1 +
((strlen(itoa(Tasks[TaskID]->Activity[ActivityID].ZoneID)) + 1) * 2) +
3 + String2Len;
auto outapp = new EQApplicationPacket(OP_TaskActivity, PacketLength);
outapp->WriteUInt32(ClientTaskIndex); // TaskSequenceNumber
outapp->WriteUInt32(static_cast<uint32>(Tasks[TaskID]->type)); // task type
outapp->WriteUInt32(TaskID);
outapp->WriteUInt32(ActivityID);
outapp->WriteUInt32(0); // unknown3
// We send our 'internal' types as ActivityUse1. text3 should be set to the activity description, so it makes
// We send our 'internal' types as ActivityCastOn. text3 should be set to the activity description, so it makes
// no difference to the client. All activity updates will be done based on our interal activity types.
if((Tasks[TaskID]->Activity[ActivityID].Type > 0) && Tasks[TaskID]->Activity[ActivityID].Type < 100)
outapp->WriteUInt32(Tasks[TaskID]->Activity[ActivityID].Type);
buf.WriteUInt32(Tasks[TaskID]->Activity[ActivityID].Type);
else
outapp->WriteUInt32(ActivityUse1);
buf.WriteUInt32(ActivityCastOn); // w/e!
outapp->WriteUInt32(Optional);
outapp->WriteUInt8(0); // unknown5
buf.WriteUInt8(Optional);
buf.WriteUInt32(0); // solo, group, raid
// One of these unknown fields maybe related to the 'Use On' activity types
outapp->WriteString(Tasks[TaskID]->Activity[ActivityID].Text1.c_str());
buf.WriteString(Tasks[TaskID]->Activity[ActivityID].target_name); // target name string
outapp->WriteUInt32(Tasks[TaskID]->Activity[ActivityID].Text2.length() + 1); // String Length - Add in null terminator
outapp->WriteString(Tasks[TaskID]->Activity[ActivityID].Text2.c_str());
buf.WriteLengthString(Tasks[TaskID]->Activity[ActivityID].item_list.length(), Tasks[TaskID]->Activity[ActivityID].item_list.c_str()); // item name list
// Goal Count
if(Tasks[TaskID]->Activity[ActivityID].Type != ActivityGiveCash)
outapp->WriteUInt32(Tasks[TaskID]->Activity[ActivityID].GoalCount);
buf.WriteUInt32(Tasks[TaskID]->Activity[ActivityID].GoalCount);
else
outapp->WriteUInt32(1); // GoalCount
buf.WriteUInt32(1); // GoalCount
outapp->WriteUInt32(3); // String Length - Add in null terminator
outapp->WriteString("-1");
// skill ID list ; separated
buf.WriteLengthString(Tasks[TaskID]->Activity[ActivityID].skill_list.length(), Tasks[TaskID]->Activity[ActivityID].skill_list.c_str());
if(!TaskComplete) {
outapp->WriteUInt32(3); // String Length - Add in null terminator
outapp->WriteString("-1");
}
else
{
outapp->WriteUInt32(4); // String Length - Add in null terminator
outapp->WriteString("-54");
}
// spelll ID list ; separated -- unsure wtf we're doing here
buf.WriteLengthString(Tasks[TaskID]->Activity[ActivityID].spell_list.length(), Tasks[TaskID]->Activity[ActivityID].spell_list.c_str());
outapp->WriteString(itoa(Tasks[TaskID]->Activity[ActivityID].ZoneID));
outapp->WriteUInt32(0); // unknown7
buf.WriteString(Tasks[TaskID]->Activity[ActivityID].zones);
buf.WriteUInt32(0); // unknown7
outapp->WriteString(Tasks[TaskID]->Activity[ActivityID].Text3.c_str());
buf.WriteString(Tasks[TaskID]->Activity[ActivityID].desc_override); // description override
if(Tasks[TaskID]->Activity[ActivityID].Type != ActivityGiveCash)
outapp->WriteUInt32(c->GetTaskActivityDoneCount(ClientTaskIndex, ActivityID)); // DoneCount
buf.WriteUInt32(c->GetTaskActivityDoneCount(ClientTaskIndex, ActivityID)); // DoneCount
else
// For internal activity types, DoneCount is either 1 if the activity is complete, 0 otherwise.
outapp->WriteUInt32((c->GetTaskActivityDoneCount(ClientTaskIndex, ActivityID) >= Tasks[TaskID]->Activity[ActivityID].GoalCount));
buf.WriteUInt32((c->GetTaskActivityDoneCount(ClientTaskIndex, ActivityID) >= Tasks[TaskID]->Activity[ActivityID].GoalCount));
outapp->WriteUInt8(1); // unknown9
buf.WriteUInt8(1); // unknown9
outapp->WriteString(itoa(Tasks[TaskID]->Activity[ActivityID].ZoneID));
buf.WriteString(Tasks[TaskID]->Activity[ActivityID].zones);
auto outapp = new EQApplicationPacket(OP_TaskActivity, buf.buffer(), buf.length());
c->QueuePacket(outapp);
safe_delete(outapp);