2
0
Эх сурвалжийг харах

Merge pull request #474 from Glitchfinder/master

Added a cleanup task to remove inavlid spawned mobs.
Glitchfinder 12 жил өмнө
parent
commit
2205ad0772

+ 4 - 0
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();
     }
 
     /**

+ 42 - 0
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();
+    }
+}

+ 1 - 0
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();
 }

+ 48 - 8
src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/HashChunkManager.java

@@ -32,9 +32,12 @@ public class HashChunkManager implements ChunkManager {
     private List<Entity> spawnedMobs = new ArrayList<Entity>();
     private List<Entity> spawnedPets = new ArrayList<Entity>();
     private List<Entity> mobsToRemove = new ArrayList<Entity>();
+    private List<Entity> tempSpawnedMobs = new ArrayList<Entity>();
+    private List<Entity> tempSpawnedPets = new ArrayList<Entity>();
     private List<String> savedChunks = new ArrayList<String>();
     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<Entity> tempSpawnedMobs = new ArrayList<Entity>(spawnedMobs);
+            tempSpawnedMobs = new ArrayList<Entity>(spawnedMobs);
             for (Entity entity : tempSpawnedMobs) {
                 if (!isEntityInChunk(entity, cx, cz, world))
                     continue;
@@ -237,7 +248,7 @@ public class HashChunkManager implements ChunkManager {
             }
 
             if (!unloaded) {
-                List<Entity> tempSpawnedPets = new ArrayList<Entity>(spawnedPets);
+                tempSpawnedPets = new ArrayList<Entity>(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<Entity> tempSpawnedMobs = new ArrayList<Entity>(spawnedMobs);
+            tempSpawnedMobs = new ArrayList<Entity>(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<Entity> tempSpawnedPets = new ArrayList<Entity>(spawnedPets);
+            tempSpawnedPets = new ArrayList<Entity>(spawnedPets);
             for (Entity entity : tempSpawnedPets) {
                 if (!isEntityInChunk(entity, cx, cz, world))
                     continue;
@@ -345,7 +356,7 @@ public class HashChunkManager implements ChunkManager {
             }
         }
 
-        List<Entity> tempSpawnedMobs = new ArrayList<Entity>(spawnedMobs);
+        tempSpawnedMobs = new ArrayList<Entity>(spawnedMobs);
         for (Entity entity : tempSpawnedMobs) {
             World entityWorld = entity.getWorld();
 
@@ -358,7 +369,7 @@ public class HashChunkManager implements ChunkManager {
             saveChunk(cx, cz, world);
         }
 
-        List<Entity> tempSpawnedPets = new ArrayList<Entity>(spawnedPets);
+        tempSpawnedPets = new ArrayList<Entity>(spawnedPets);
         for (Entity entity : tempSpawnedPets) {
             World entityWorld = entity.getWorld();
 
@@ -404,7 +415,7 @@ public class HashChunkManager implements ChunkManager {
 
         safeToRemoveMobs = false;
 
-        List<Entity> tempSpawnedMobs = new ArrayList<Entity>(spawnedMobs);
+        tempSpawnedMobs = new ArrayList<Entity>(spawnedMobs);
         for (Entity entity : tempSpawnedMobs) {
             World entityWorld = entity.getWorld();
 
@@ -417,7 +428,7 @@ public class HashChunkManager implements ChunkManager {
             unloadChunk(cx, cz, world);
         }
 
-        List<Entity> tempSpawnedPets = new ArrayList<Entity>(spawnedPets);
+        tempSpawnedPets = new ArrayList<Entity>(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();
+    }
 }

+ 1 - 0
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() {}
 }