From 1366a25821bb2892a0fe01372347950caf788673 Mon Sep 17 00:00:00 2001 From: Penal Buffalo Date: Mon, 8 Nov 2021 16:36:12 -0600 Subject: [PATCH 1/3] 3.2.5 b559 * fixed compatibility with certain spawner plugins such as SpawnerMeta --- pom.xml | 2 +- .../me/lokka30/levelledmobs/listeners/EntitySpawnListener.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7dc310673..fa9a5fba1 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ me.lokka30 LevelledMobs - 3.2.4 b557 + 3.2.5 b559 jar LevelledMobs diff --git a/src/main/java/me/lokka30/levelledmobs/listeners/EntitySpawnListener.java b/src/main/java/me/lokka30/levelledmobs/listeners/EntitySpawnListener.java index 00522ec3c..340076bba 100644 --- a/src/main/java/me/lokka30/levelledmobs/listeners/EntitySpawnListener.java +++ b/src/main/java/me/lokka30/levelledmobs/listeners/EntitySpawnListener.java @@ -68,6 +68,9 @@ public void onEntitySpawn(@NotNull final EntitySpawnEvent event) { return; } + if (event instanceof CreatureSpawnEvent && ((CreatureSpawnEvent) event).getSpawnReason().equals(CreatureSpawnEvent.SpawnReason.SPAWNER)) + lmEntity.setSpawnReason(LevelledMobSpawnReason.SPAWNER); + if (main.configUtils.playerLevellingEnabled && lmEntity.getPlayerForLevelling() == null) updateMobForPlayerLevelling(lmEntity); From 924a9e8ac6fb509026ba7976557e01e532efc7d4 Mon Sep 17 00:00:00 2001 From: Penal Buffalo Date: Thu, 11 Nov 2021 16:44:04 -0600 Subject: [PATCH 2/3] 3.2.5 b562 * added better error handling to prevent logic flow disruptions --- pom.xml | 2 +- .../listeners/EntitySpawnListener.java | 1 + .../managers/MobsQueueManager.java | 21 +++-- .../managers/NametagQueueManager.java | 92 +++++++++++-------- 4 files changed, 70 insertions(+), 46 deletions(-) diff --git a/pom.xml b/pom.xml index fa9a5fba1..2e400cbb0 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ me.lokka30 LevelledMobs - 3.2.5 b559 + 3.2.5 b562 jar LevelledMobs diff --git a/src/main/java/me/lokka30/levelledmobs/listeners/EntitySpawnListener.java b/src/main/java/me/lokka30/levelledmobs/listeners/EntitySpawnListener.java index 340076bba..a78cb1f39 100644 --- a/src/main/java/me/lokka30/levelledmobs/listeners/EntitySpawnListener.java +++ b/src/main/java/me/lokka30/levelledmobs/listeners/EntitySpawnListener.java @@ -209,6 +209,7 @@ public void run() { public void preprocessMob(final @NotNull LivingEntityWrapper lmEntity, @NotNull final Event event){ if (!lmEntity.reEvaluateLevel && lmEntity.isLevelled()) return; + if (lmEntity.getLivingEntity() == null) return; LevelledMobSpawnReason spawnReason = LevelledMobSpawnReason.DEFAULT; AdditionalLevelInformation additionalInfo = AdditionalLevelInformation.NOT_APPLICABLE; diff --git a/src/main/java/me/lokka30/levelledmobs/managers/MobsQueueManager.java b/src/main/java/me/lokka30/levelledmobs/managers/MobsQueueManager.java index c105a9c02..0e9a09478 100644 --- a/src/main/java/me/lokka30/levelledmobs/managers/MobsQueueManager.java +++ b/src/main/java/me/lokka30/levelledmobs/managers/MobsQueueManager.java @@ -67,13 +67,22 @@ private void main() throws InterruptedException{ final QueueItem item = queue.poll(200, TimeUnit.MILLISECONDS); if (item == null) continue; - if (item.lmEntity.getLivingEntity() != null) { - if (!item.lmEntity.getIsPopulated()) continue; - if (!item.lmEntity.getShouldShowLM_Nametag()) continue; - main.levelManager.entitySpawnListener.preprocessMob(item.lmEntity, item.event); + String lastEntityType = null; + try { + if (item.lmEntity.getLivingEntity() != null) { + if (!item.lmEntity.getIsPopulated()) continue; + if (!item.lmEntity.getShouldShowLM_Nametag()) continue; + lastEntityType = item.lmEntity.getNameIfBaby(); + main.levelManager.entitySpawnListener.preprocessMob(item.lmEntity, item.event); + } + } + catch (Exception e){ + Utils.logger.error("Got exception while processing " + (lastEntityType != null ? lastEntityType : "(unknown)")); + e.printStackTrace(); + } + finally { + item.lmEntity.free(); } - - item.lmEntity.free(); } isRunning = false; diff --git a/src/main/java/me/lokka30/levelledmobs/managers/NametagQueueManager.java b/src/main/java/me/lokka30/levelledmobs/managers/NametagQueueManager.java index 0d9cf4146..08c2ccfe8 100644 --- a/src/main/java/me/lokka30/levelledmobs/managers/NametagQueueManager.java +++ b/src/main/java/me/lokka30/levelledmobs/managers/NametagQueueManager.java @@ -88,60 +88,74 @@ private void main() throws InterruptedException{ continue; } - final int nametagTimerResetTime = item.lmEntity.getNametagCooldownTime(); + String lastEntityType = null; + try { + lastEntityType = item.lmEntity.getNameIfBaby(); + processItem(item); + } + catch (Exception e){ + Utils.logger.error("Got exception while processing nametag updates on " + (lastEntityType != null ? lastEntityType : "(unknown)")); + e.printStackTrace(); + } + finally { + item.lmEntity.free(); + } + } - if (nametagTimerResetTime > 0 && !"".equals(item.nametag)) { - synchronized (NametagTimerChecker.nametagTimer_Lock) { - final Map> nametagCooldownQueue = main.nametagTimerChecker.getNametagCooldownQueue(); + isRunning = false; + } - if (item.lmEntity.playersNeedingNametagCooldownUpdate != null) { - // record which players should get the cooldown for this mob - // public Map> nametagCooldownQueue; - for (final Player player : item.lmEntity.playersNeedingNametagCooldownUpdate) { - if (!nametagCooldownQueue.containsKey(player)) continue; + private void processItem(final @NotNull QueueItem item){ + final int nametagTimerResetTime = item.lmEntity.getNametagCooldownTime(); - nametagCooldownQueue.get(player).put(item.lmEntity.getLivingEntity(), Instant.now()); - main.nametagTimerChecker.cooldownTimes.put(item.lmEntity.getLivingEntity(), item.lmEntity.getNametagCooldownTime()); - } + if (nametagTimerResetTime > 0 && !"".equals(item.nametag)) { + synchronized (NametagTimerChecker.nametagTimer_Lock) { + final Map> nametagCooldownQueue = main.nametagTimerChecker.getNametagCooldownQueue(); - // if any players already have a cooldown on this mob then don't remove the cooldown - for (final Player player : nametagCooldownQueue.keySet()){ - if (item.lmEntity.playersNeedingNametagCooldownUpdate.contains(player)) continue; + if (item.lmEntity.playersNeedingNametagCooldownUpdate != null) { + // record which players should get the cooldown for this mob + // public Map> nametagCooldownQueue; + for (final Player player : item.lmEntity.playersNeedingNametagCooldownUpdate) { + if (!nametagCooldownQueue.containsKey(player)) continue; - if (nametagCooldownQueue.get(player).containsKey(item.lmEntity.getLivingEntity())) - item.lmEntity.playersNeedingNametagCooldownUpdate.add(player); - } + nametagCooldownQueue.get(player).put(item.lmEntity.getLivingEntity(), Instant.now()); + main.nametagTimerChecker.cooldownTimes.put(item.lmEntity.getLivingEntity(), item.lmEntity.getNametagCooldownTime()); } - else{ - // if there's any existing cooldowns we'll use them - for (final Player player : nametagCooldownQueue.keySet()){ - if (nametagCooldownQueue.get(player).containsKey(item.lmEntity.getLivingEntity())) { - if (item.lmEntity.playersNeedingNametagCooldownUpdate == null) - item.lmEntity.playersNeedingNametagCooldownUpdate = new HashSet<>(); - - item.lmEntity.playersNeedingNametagCooldownUpdate.add(player); - } + + // if any players already have a cooldown on this mob then don't remove the cooldown + for (final Player player : nametagCooldownQueue.keySet()){ + if (item.lmEntity.playersNeedingNametagCooldownUpdate.contains(player)) continue; + + if (nametagCooldownQueue.get(player).containsKey(item.lmEntity.getLivingEntity())) + item.lmEntity.playersNeedingNametagCooldownUpdate.add(player); + } + } + else{ + // if there's any existing cooldowns we'll use them + for (final Player player : nametagCooldownQueue.keySet()){ + if (nametagCooldownQueue.get(player).containsKey(item.lmEntity.getLivingEntity())) { + if (item.lmEntity.playersNeedingNametagCooldownUpdate == null) + item.lmEntity.playersNeedingNametagCooldownUpdate = new HashSet<>(); + + item.lmEntity.playersNeedingNametagCooldownUpdate.add(player); } } } } - else if (item.lmEntity.playersNeedingNametagCooldownUpdate != null) - item.lmEntity.playersNeedingNametagCooldownUpdate = null; + } + else if (item.lmEntity.playersNeedingNametagCooldownUpdate != null) + item.lmEntity.playersNeedingNametagCooldownUpdate = null; - synchronized (NametagTimerChecker.entityTarget_Lock){ - if (main.nametagTimerChecker.entityTargetMap.containsKey(item.lmEntity.getLivingEntity())){ - if (item.lmEntity.playersNeedingNametagCooldownUpdate == null) - item.lmEntity.playersNeedingNametagCooldownUpdate = new HashSet<>(); + synchronized (NametagTimerChecker.entityTarget_Lock){ + if (main.nametagTimerChecker.entityTargetMap.containsKey(item.lmEntity.getLivingEntity())){ + if (item.lmEntity.playersNeedingNametagCooldownUpdate == null) + item.lmEntity.playersNeedingNametagCooldownUpdate = new HashSet<>(); - item.lmEntity.playersNeedingNametagCooldownUpdate.add(main.nametagTimerChecker.entityTargetMap.get(item.lmEntity.getLivingEntity())); - } + item.lmEntity.playersNeedingNametagCooldownUpdate.add(main.nametagTimerChecker.entityTargetMap.get(item.lmEntity.getLivingEntity())); } - - updateNametag(item.lmEntity, item.nametag, item.players); - item.lmEntity.free(); } - isRunning = false; + updateNametag(item.lmEntity, item.nametag, item.players); } private void updateNametag(final @NotNull LivingEntityWrapper lmEntity, final String nametag, final List players) { From aa4f70960f9183c8f2a79212322334d93d42d752 Mon Sep 17 00:00:00 2001 From: Penal Buffalo Date: Sat, 13 Nov 2021 08:18:42 -0600 Subject: [PATCH 3/3] 3.2.5 b564 * fix for occasional ConcurrentModificationException error --- pom.xml | 2 +- .../levelledmobs/managers/LevelManager.java | 29 +++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 2e400cbb0..a9c9ab3c0 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ me.lokka30 LevelledMobs - 3.2.5 b562 + 3.2.5 b564 jar LevelledMobs diff --git a/src/main/java/me/lokka30/levelledmobs/managers/LevelManager.java b/src/main/java/me/lokka30/levelledmobs/managers/LevelManager.java index b1b283250..2794f25a9 100644 --- a/src/main/java/me/lokka30/levelledmobs/managers/LevelManager.java +++ b/src/main/java/me/lokka30/levelledmobs/managers/LevelManager.java @@ -1198,9 +1198,34 @@ private void getPlayersNearMob(final @NotNull LivingEntityWrapper lmEntity){ * @return if the mob is levelled or not */ public boolean isLevelled(@NotNull final LivingEntity livingEntity) { - synchronized (livingEntity.getPersistentDataContainer()) { - return livingEntity.getPersistentDataContainer().has(main.namespaced_keys.levelKey, PersistentDataType.INTEGER); + boolean hadError = false; + boolean succeeded = false; + boolean isLevelled = false; + + for (int i = 0; i < 2; i++) { + try { + synchronized (livingEntity.getPersistentDataContainer()) { + isLevelled = livingEntity.getPersistentDataContainer().has(main.namespaced_keys.levelKey, PersistentDataType.INTEGER); + } + succeeded = true; + break; + } + catch (ConcurrentModificationException ignored) { + hadError = true; + try + { Thread.sleep(10); } + catch (InterruptedException ignored2) { return false; } + } } + + if (hadError) { + if (succeeded) + Utils.logger.warning("Got ConcurrentModificationException in LevelManager checking entity isLevelled, succeeded on retry"); + else + Utils.logger.warning("Got ConcurrentModificationException (2x) in LevelManager checking entity isLevelled"); + } + + return isLevelled; } /**