Work around a client bug related to simultanious quest item drops

This commit is contained in:
dongresource 2022-02-12 20:59:00 +01:00
parent 91f9a2085b
commit 94af318139

View File

@ -229,10 +229,8 @@ static bool endTask(CNSocket *sock, int32_t taskNum, int choice=0) {
} }
} }
if (!found) { if (!found)
std::cout << "[WARN] Player tried to end task that isn't in journal?" << std::endl;
return false; return false;
}
if (i == ACTIVE_MISSION_COUNT - 1 && plr->tasks[i] != 0) { if (i == ACTIVE_MISSION_COUNT - 1 && plr->tasks[i] != 0) {
std::cout << "[WARN] Player completed non-active mission!?" << std::endl; std::cout << "[WARN] Player completed non-active mission!?" << std::endl;
@ -601,12 +599,30 @@ void Missions::mobKilled(CNSocket *sock, int mobid, int rolledQItem) {
plr->RemainingNPCCount[i][j]--; plr->RemainingNPCCount[i][j]--;
} }
} }
// drop quest item // drop quest item
if (task["m_iCSUItemNumNeeded"][j] != 0 && !isQuestItemFull(sock, task["m_iCSUItemID"][j], task["m_iCSUItemNumNeeded"][j]) ) { if (task["m_iCSUItemNumNeeded"][j] != 0 && !isQuestItemFull(sock, task["m_iCSUItemID"][j], task["m_iCSUItemNumNeeded"][j]) ) {
bool drop = rolledQItem % 100 < task["m_iSTItemDropRate"][j]; bool drop = rolledQItem % 100 < task["m_iSTItemDropRate"][j];
if (drop) { if (drop) {
// XXX: are CSUItemID and CSTItemID the same? // XXX: are CSUItemID and CSTItemID the same?
dropQuestItem(sock, plr->tasks[i], 1, task["m_iCSUItemID"][j], mobid); dropQuestItem(sock, plr->tasks[i], 1, task["m_iCSUItemID"][j], mobid);
/*
* Workaround: The client has a bug where it only sends a TASK_END request
* for the first task of multiple that met their quest item requirements
* at the same time. We deal with this by sending TASK_END response packets
* proactively and then silently ignoring the extra TASK_END requests it
* sends afterwards.
*/
if (isQuestItemFull(sock, task["m_iCSUItemID"][j], task["m_iCSUItemNumNeeded"][j])) {
INITSTRUCT(sP_FE2CL_REP_PC_TASK_END_SUCC, end);
end.iTaskNum = plr->tasks[i];
if (!endTask(sock, plr->tasks[i]))
continue;
sock->sendPacket(end, P_FE2CL_REP_PC_TASK_END_SUCC);
}
} else { } else {
// fail to drop (itemID == 0) // fail to drop (itemID == 0)
dropQuestItem(sock, plr->tasks[i], 1, 0, mobid); dropQuestItem(sock, plr->tasks[i], 1, 0, mobid);