|
public void onLivingUpdate(LivingUpdateEvent event) { |
|
if (event.getEntityLiving().world.isRemote) return; |
|
if (!(event.getEntityLiving() instanceof EntityPlayerMP)) return; |
|
if (event.getEntityLiving().ticksExisted % 20 != 0) return; // Only triggers once per second |
|
|
|
EntityPlayerMP player = (EntityPlayerMP) event.getEntityLiving(); |
|
betterquesting.api2.cache.QuestCache qc = player.getCapability(CapabilityProviderQuestCache.CAP_QUEST_CACHE, null); |
|
boolean editMode = QuestSettings.INSTANCE.getProperty(NativeProps.EDIT_MODE); |
|
|
|
if (qc == null) return; |
|
|
|
List<DBEntry<IQuest>> activeQuests = QuestDatabase.INSTANCE.bulkLookup(qc.getActiveQuests()); |
|
List<DBEntry<IQuest>> pendingAutoClaims = QuestDatabase.INSTANCE.bulkLookup(qc.getPendingAutoClaims()); |
|
QResetTime[] pendingResets = qc.getScheduledResets(); |
|
|
|
UUID uuid = QuestingAPI.getQuestingUUID(player); |
|
boolean refreshCache = false; |
|
|
|
if (!editMode && player.ticksExisted % 60 == 0) // Passive quest state check every 3 seconds |
|
{ |
|
List<Integer> com = new ArrayList<>(); |
|
|
|
for (DBEntry<IQuest> quest : activeQuests) { |
|
if (!quest.getValue().isUnlocked(uuid)) continue; // Although it IS active, it cannot be completed yet |
|
|
|
if (quest.getValue().canSubmit(player)) quest.getValue().update(player); |
|
|
|
if (quest.getValue().isComplete(uuid) && !quest.getValue().canSubmit(player)) { |
|
refreshCache = true; |
|
qc.markQuestDirty(quest.getID()); |
|
|
|
com.add(quest.getID()); |
|
if (!quest.getValue().getProperty(NativeProps.SILENT)) |
|
postPresetNotice(quest.getValue(), player, 2); |
|
|
|
DBEntry<IParty> partyEntry = PartyManager.INSTANCE.getParty(uuid); |
|
if (partyEntry != null && player.getServer() != null) { |
|
for (UUID memID : partyEntry.getValue().getMembers()) { |
|
EntityPlayerMP memPlayer = player.getServer().getPlayerList().getPlayerByUsername(NameCache.INSTANCE.getName(memID)); |
|
if (memPlayer != null) { |
|
quest.getValue().detect(memPlayer); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
MinecraftForge.EVENT_BUS.post(new QuestEvent(Type.COMPLETED, uuid, com)); |
|
} |
|
|
|
if (!editMode && player.getServer() != null) // Repeatable quest resets |
|
{ |
|
List<Integer> res = new ArrayList<>(); |
|
long totalTime = System.currentTimeMillis(); |
|
|
|
for (QResetTime rTime : pendingResets) { |
|
IQuest entry = QuestDatabase.INSTANCE.getValue(rTime.questID); |
|
|
|
if (totalTime >= rTime.time && !entry.canSubmit(player)) // REEEEEEEEEset |
|
{ |
|
if (entry.getProperty(NativeProps.GLOBAL)) { |
|
entry.resetUser(null, false); |
|
} else { |
|
entry.resetUser(uuid, false); |
|
} |
|
|
|
refreshCache = true; |
|
qc.markQuestDirty(rTime.questID); |
|
res.add(rTime.questID); |
|
if (!entry.getProperty(NativeProps.SILENT)) postPresetNotice(entry, player, 1); |
|
} else break; // Entries are sorted by time so we fail fast and skip checking the others |
|
} |
|
|
|
MinecraftForge.EVENT_BUS.post(new QuestEvent(Type.RESET, uuid, res)); |
|
} |
|
|
|
if (!editMode) { |
|
for (DBEntry<IQuest> entry : pendingAutoClaims) // Auto claims |
|
{ |
|
if (entry.getValue().canClaim(player)) { |
|
entry.getValue().claimReward(player); |
|
refreshCache = true; |
|
qc.markQuestDirty(entry.getID()); |
|
// Not going to notify of auto-claims anymore. Kinda pointless if they're already being pinged for completion |
|
} |
|
} |
|
} |
|
|
|
if (refreshCache || player.ticksExisted % 200 == 0) // Refresh the cache if something changed or every 10 seconds |
|
{ |
|
qc.updateCache(player); |
|
} |
|
|
|
if (qc.getDirtyQuests().length > 0) NetQuestSync.sendSync(player, qc.getDirtyQuests(), false, true, true); |
|
qc.cleanAllQuests(); |
|
} |
Description
Attempting to interact with choice quest rewards too fast can result in a client-side crash. This issue appears more prevalent with large quest books that take a moment to update after a quest is complete.
Problematic Code
It appears that there are two different event subscribers to the same event with the same priority within the EventHandler, likely resulting in the events firing in the incorrect order.
BetterQuesting/src/main/java/betterquesting/handlers/EventHandler.java
Lines 189 to 284 in d594e94
BetterQuesting/src/main/java/betterquesting/handlers/EventHandler.java
Lines 671 to 689 in d594e94
Crashlog
crash-2026-05-09_09.02.03-server.txt