avoid race condition with casting a spell before queue pops

This commit is contained in:
avitasia
2025-12-15 12:05:21 -08:00
parent e8d153847b
commit 12c6c5b90b
2 changed files with 21 additions and 7 deletions
+18
View File
@@ -105,6 +105,24 @@ namespace Nampower {
return nullptr;
}
bool removeSpellId(uint32_t spellId) {
for (int i = 0; i < size; i++) {
int index = (front + i) % maxSize;
if (queue[index].spellId == spellId) {
// Shift all elements after this one forward
for (int j = i; j < size - 1; j++) {
int currentIndex = (front + j) % maxSize;
int nextIndex = (front + j + 1) % maxSize;
queue[currentIndex] = queue[nextIndex];
}
rear = (rear - 1 + maxSize) % maxSize;
size--;
return true;
}
}
return false;
}
CastSpellParams *findOldestWaitingForServerSpellId(uint32_t spellId) {
for (int i = size - 1; i >= 0; i--) {
int index = (front + i) % maxSize;
+3 -7
View File
@@ -448,6 +448,9 @@ namespace Nampower {
// save the detour to allow quickly calling this hook
castSpellDetour = detour;
// it is possible when spamming to attempt to cast before queues are processed
processQueues();
if (item == nullptr && casterUnit != game::GetObjectPtr(game::ClntObjMgrGetActivePlayerGuid())) {
DEBUG_LOG("Ignoring non active player cast of spell " << game::GetSpellName(spellId) << " " << spellId);
// just call original function if caster is not the active player
@@ -496,13 +499,6 @@ namespace Nampower {
}
}
if (gCastData.nonGcdSpellQueued && spellOnGcd) {
// it is possible when spamming to attempt to cast before non gcd spells are processed, process queue first
if (processQueues()) {
return false;
}
}
gLastCastData.attemptTimeMs = currentTime;
gLastCastData.attemptSpellId = spellId;