From 637e826c1b1b9860ff7b307b7d6a0267c4292718 Mon Sep 17 00:00:00 2001 From: Glitchfinder Date: Thu, 10 Jan 2013 14:12:41 -0800 Subject: [PATCH] Adding a cleanup task to remove invalid entities from the spawned mob storage. --- src/main/java/com/gmail/nossr50/mcMMO.java | 4 ++ .../nossr50/runnables/MobStoreCleaner.java | 42 ++++++++++++++ .../blockmeta/chunkmeta/ChunkManager.java | 1 + .../blockmeta/chunkmeta/HashChunkManager.java | 56 ++++++++++++++++--- .../blockmeta/chunkmeta/NullChunkManager.java | 1 + 5 files changed, 96 insertions(+), 8 deletions(-) create mode 100755 src/main/java/com/gmail/nossr50/runnables/MobStoreCleaner.java diff --git a/src/main/java/com/gmail/nossr50/mcMMO.java b/src/main/java/com/gmail/nossr50/mcMMO.java index b3cad00e4..10b775c79 100644 --- a/src/main/java/com/gmail/nossr50/mcMMO.java +++ b/src/main/java/com/gmail/nossr50/mcMMO.java @@ -67,6 +67,7 @@ import com.gmail.nossr50.locale.LocaleLoader; import com.gmail.nossr50.party.PartyManager; import com.gmail.nossr50.runnables.BleedTimer; import com.gmail.nossr50.runnables.ChunkletUnloader; +import com.gmail.nossr50.runnables.MobStoreCleaner; import com.gmail.nossr50.runnables.SaveTimer; import com.gmail.nossr50.runnables.SkillMonitor; import com.gmail.nossr50.runnables.SpoutStart; @@ -230,6 +231,9 @@ public class mcMMO extends JavaPlugin { // Get our ChunkletManager placeStore = ChunkManagerFactory.getChunkManager(); + + // Automatically starts and stores itself + MobStoreCleaner cleaner = new MobStoreCleaner(); } /** diff --git a/src/main/java/com/gmail/nossr50/runnables/MobStoreCleaner.java b/src/main/java/com/gmail/nossr50/runnables/MobStoreCleaner.java new file mode 100755 index 000000000..d2ddb1312 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/runnables/MobStoreCleaner.java @@ -0,0 +1,42 @@ +package com.gmail.nossr50.runnables; + +import java.lang.Runnable; + +import org.bukkit.Bukkit; +import org.bukkit.scheduler.BukkitScheduler; + +import com.gmail.nossr50.mcMMO; + +public class MobStoreCleaner implements Runnable +{ + private int taskID; + + public MobStoreCleaner() + { + taskID = -1; + start(); + } + + public void start() + { + if (taskID >= 0) + return; + + BukkitScheduler scheduler = Bukkit.getServer().getScheduler(); + taskID = scheduler.scheduleSyncRepeatingTask(mcMMO.p, this, 12000, 12000); + } + + public void stop() + { + if(taskID < 0) + return; + + Bukkit.getServer().getScheduler().cancelTask(taskID); + taskID = -1; + } + + public void run() + { + mcMMO.p.placeStore.cleanMobLists(); + } +} \ No newline at end of file diff --git a/src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/ChunkManager.java b/src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/ChunkManager.java index 23b24a8a4..db262e546 100755 --- a/src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/ChunkManager.java +++ b/src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/ChunkManager.java @@ -173,4 +173,5 @@ public interface ChunkManager { public void addSpawnedPet(Entity entity); public void removeSpawnedMob(Entity entity); public void removeSpawnedPet(Entity entity); + public void cleanMobLists(); } diff --git a/src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/HashChunkManager.java b/src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/HashChunkManager.java index 8ac1ca98d..ff50cea81 100755 --- a/src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/HashChunkManager.java +++ b/src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/HashChunkManager.java @@ -32,9 +32,12 @@ public class HashChunkManager implements ChunkManager { private List spawnedMobs = new ArrayList(); private List spawnedPets = new ArrayList(); private List mobsToRemove = new ArrayList(); + private List tempSpawnedMobs = new ArrayList(); + private List tempSpawnedPets = new ArrayList(); private List savedChunks = new ArrayList(); private boolean safeToRemoveMobs = true; private boolean savingWorld = false; + private boolean iteratingMobs = false; @Override public synchronized void closeAll() { @@ -174,6 +177,8 @@ public class HashChunkManager implements ChunkManager { if (mobs.isEmpty() && pets.isEmpty()) return; + iteratingMobs = true; + for (LivingEntity entity : world.getLivingEntities()) { if (mobs.contains(entity.getUniqueId())) addSpawnedMob(entity); @@ -182,6 +187,9 @@ public class HashChunkManager implements ChunkManager { addSpawnedPet(entity); } + if(safeToRemoveMobs) + iteratingMobs = false; + in.clearSpawnedMobs(); in.clearSpawnedPets(); } @@ -194,6 +202,8 @@ public class HashChunkManager implements ChunkManager { if (store.containsKey(world.getName() + "," + cx + "," + cz)) { store.remove(world.getName() + "," + cx + "," + cz); + iteratingMobs = true; + for (Entity entity : spawnedMobs) { if (!isEntityInChunk(entity, cx, cz, world)) continue; @@ -212,6 +222,7 @@ public class HashChunkManager implements ChunkManager { spawnedMobs.remove(mobsToRemove); spawnedPets.remove(mobsToRemove); mobsToRemove.clear(); + iteratingMobs = false; } } } @@ -226,7 +237,7 @@ public class HashChunkManager implements ChunkManager { boolean unloaded = false; if (!store.containsKey(world.getName() + "," + cx + "," + cz)) { - List tempSpawnedMobs = new ArrayList(spawnedMobs); + tempSpawnedMobs = new ArrayList(spawnedMobs); for (Entity entity : tempSpawnedMobs) { if (!isEntityInChunk(entity, cx, cz, world)) continue; @@ -237,7 +248,7 @@ public class HashChunkManager implements ChunkManager { } if (!unloaded) { - List tempSpawnedPets = new ArrayList(spawnedPets); + tempSpawnedPets = new ArrayList(spawnedPets); for (Entity entity : tempSpawnedPets) { if (!isEntityInChunk(entity, cx, cz, world)) continue; @@ -257,7 +268,7 @@ public class HashChunkManager implements ChunkManager { if (store.containsKey(world.getName() + "," + cx + "," + cz)) { ChunkStore out = store.get(world.getName() + "," + cx + "," + cz); - List tempSpawnedMobs = new ArrayList(spawnedMobs); + tempSpawnedMobs = new ArrayList(spawnedMobs); for (Entity entity : tempSpawnedMobs) { if (!isEntityInChunk(entity, cx, cz, world)) continue; @@ -265,7 +276,7 @@ public class HashChunkManager implements ChunkManager { out.addSpawnedMob(entity.getUniqueId()); } - List tempSpawnedPets = new ArrayList(spawnedPets); + tempSpawnedPets = new ArrayList(spawnedPets); for (Entity entity : tempSpawnedPets) { if (!isEntityInChunk(entity, cx, cz, world)) continue; @@ -345,7 +356,7 @@ public class HashChunkManager implements ChunkManager { } } - List tempSpawnedMobs = new ArrayList(spawnedMobs); + tempSpawnedMobs = new ArrayList(spawnedMobs); for (Entity entity : tempSpawnedMobs) { World entityWorld = entity.getWorld(); @@ -358,7 +369,7 @@ public class HashChunkManager implements ChunkManager { saveChunk(cx, cz, world); } - List tempSpawnedPets = new ArrayList(spawnedPets); + tempSpawnedPets = new ArrayList(spawnedPets); for (Entity entity : tempSpawnedPets) { World entityWorld = entity.getWorld(); @@ -404,7 +415,7 @@ public class HashChunkManager implements ChunkManager { safeToRemoveMobs = false; - List tempSpawnedMobs = new ArrayList(spawnedMobs); + tempSpawnedMobs = new ArrayList(spawnedMobs); for (Entity entity : tempSpawnedMobs) { World entityWorld = entity.getWorld(); @@ -417,7 +428,7 @@ public class HashChunkManager implements ChunkManager { unloadChunk(cx, cz, world); } - List tempSpawnedPets = new ArrayList(spawnedPets); + tempSpawnedPets = new ArrayList(spawnedPets); for (Entity entity : tempSpawnedPets) { World entityWorld = entity.getWorld(); @@ -625,4 +636,33 @@ public class HashChunkManager implements ChunkManager { if (isSpawnedPet(entity)) spawnedPets.remove(entity); } + + public synchronized void cleanMobLists() { + if (!safeToRemoveMobs || iteratingMobs) + return; + + mobsToRemove.clear(); + + tempSpawnedMobs = new ArrayList(spawnedMobs); + for (Entity entity : tempSpawnedMobs) { + if (entity.isDead()) + mobsToRemove.add(entity); + + if (!entity.isValid()) + mobsToRemove.add(entity); + } + + tempSpawnedPets = new ArrayList(spawnedPets); + for (Entity entity : tempSpawnedPets) { + if (entity.isDead()) + mobsToRemove.add(entity); + + if (!entity.isValid()) + mobsToRemove.add(entity); + } + + spawnedMobs.remove(mobsToRemove); + spawnedPets.remove(mobsToRemove); + mobsToRemove.clear(); + } } diff --git a/src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/NullChunkManager.java b/src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/NullChunkManager.java index 12816b9d6..6f0caa90c 100755 --- a/src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/NullChunkManager.java +++ b/src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/NullChunkManager.java @@ -94,4 +94,5 @@ public class NullChunkManager implements ChunkManager { public void addSpawnedPet(Entity entity) {} public void removeSpawnedMob(Entity entity) {} public void removeSpawnedPet(Entity entity) {} + public synchronized void cleanMobLists() {} } \ No newline at end of file