From d09526e4709c4a8821485618df44af5ef4d3eba7 Mon Sep 17 00:00:00 2001 From: Glitchfinder Date: Fri, 18 Jan 2013 12:39:57 -0800 Subject: [PATCH 1/4] Changing chunk unloading to patch logic hole for entity tracking. --- .../nossr50/util/blockmeta/chunkmeta/HashChunkManager.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 b9e839edf..086d99692 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 @@ -19,7 +19,6 @@ import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; -import com.gmail.nossr50.runnables.ChunkletUnloader; import com.gmail.nossr50.runnables.blockstoreconversion.BlockStoreConversionZDirectory; import org.getspout.spoutapi.chunkstore.mcMMOSimpleRegionFile; @@ -346,7 +345,7 @@ public class HashChunkManager implements ChunkManager { if (world == null) return; - ChunkletUnloader.addToList(cx, cz, world); + unloadChunk(cx, cz, world); } @Override From ca2673f258bf91756d11a31631d7eadae5b0380f Mon Sep 17 00:00:00 2001 From: Glitchfinder Date: Fri, 18 Jan 2013 14:43:14 -0800 Subject: [PATCH 2/4] Condensing entity tracking into a single set of storage, to reduce CPU use. Also handily causes invalid falling blocks to be removed. (Fell out of the world, etc) --- .../nossr50/listeners/EntityListener.java | 19 ++-- src/main/java/com/gmail/nossr50/mcMMO.java | 39 -------- .../blockmeta/chunkmeta/HashChunkManager.java | 95 ++----------------- .../chunkmeta/PrimitiveChunkStore.java | 26 ++--- 4 files changed, 28 insertions(+), 151 deletions(-) diff --git a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java index a1ee10958..ad443eac0 100644 --- a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java @@ -58,20 +58,15 @@ public class EntityListener implements Listener { Entity entity = event.getEntity(); if (entity instanceof FallingBlock) { - int entityID = entity.getEntityId(); Block block = event.getBlock(); - Material type = block.getType(); - if (type == Material.SAND || type == Material.GRAVEL) { - if (mcMMO.placeStore.isTrue(block)) { - mcMMO.placeStore.setFalse(block); - plugin.addToFallingBlockTracker(entityID, block); - } - - if (plugin.fallingBlockIsTracked(entityID)) { - mcMMO.placeStore.setTrue(block); - plugin.removeFromFallingBlockTracker(entityID); - } + if (mcMMO.placeStore.isTrue(block) && !mcMMO.placeStore.isSpawnedMob(entity)) { + mcMMO.placeStore.setFalse(block); + mcMMO.placeStore.addSpawnedMob(entity); + } + else if (mcMMO.placeStore.isSpawnedMob(entity)) { + mcMMO.placeStore.setTrue(block); + mcMMO.placeStore.removeSpawnedMob(entity); } } } diff --git a/src/main/java/com/gmail/nossr50/mcMMO.java b/src/main/java/com/gmail/nossr50/mcMMO.java index c2f2c0eb9..bf140f5b2 100644 --- a/src/main/java/com/gmail/nossr50/mcMMO.java +++ b/src/main/java/com/gmail/nossr50/mcMMO.java @@ -97,7 +97,6 @@ public class mcMMO extends JavaPlugin { private HashMap aliasMap = new HashMap(); //Alias - Command private HashMap tntTracker = new HashMap(); - private HashMap fallingBlockTracker = new HashMap(); private static Database database; public static mcMMO p; @@ -521,44 +520,6 @@ public class mcMMO extends JavaPlugin { tntTracker.remove(tntID); } - /** - * Add an ID value to the FallingBlock tracker. - * - * @param fallingBlockID The EntityID of the FallingBlock - */ - public void addToFallingBlockTracker(int fallingBlockID, Block sourceBlock) { - fallingBlockTracker.put(fallingBlockID, sourceBlock); - } - - /** - * Check to see if a given FallingBlock Entity is tracked. - * - * @param tntID The EntityID of the FallingBlock - * @return true if the FallingBlock is being tracked, false otherwise - */ - public boolean fallingBlockIsTracked(int fallingBlockID) { - return fallingBlockTracker.containsKey(fallingBlockID); - } - - /** - * Get the initial location of the FallingBlock. - * - * @param fallingBlockID The EntityID of the FallingBlock - * @return the Player who detonated it - */ - public Block getSourceBlock(int fallingBlockID) { - return fallingBlockTracker.get(fallingBlockID); - } - - /** - * Remove FallingBlock from the tracker after it lands. - * - * @param fallingBlockID The EntityID of the FallingBlock - */ - public void removeFromFallingBlockTracker(int fallingBlockID) { - fallingBlockTracker.remove(fallingBlockID); - } - public static String getMainDirectory() { return mainDirectory; } 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 086d99692..f9a239e60 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 @@ -29,7 +29,6 @@ public class HashChunkManager implements ChunkManager { public ArrayList converters = new ArrayList(); private HashMap oldData = new HashMap(); private List spawnedMobs = new ArrayList(); - private List spawnedPets = new ArrayList(); private List mobsToRemove = new ArrayList(); private List savedChunks = new ArrayList(); private List checkedMobs = new ArrayList(); @@ -174,26 +173,21 @@ public class HashChunkManager implements ChunkManager { store.put(world.getName() + "," + cx + "," + cz, in); List mobs = in.getSpawnedMobs(); - List pets = in.getSpawnedPets(); - if (mobs.isEmpty() && pets.isEmpty()) + if (mobs.isEmpty()) return; iteratingMobs = true; - for (LivingEntity entity : world.getLivingEntities()) { + for (Entity entity : world.getEntities()) { if (mobs.contains(entity.getUniqueId())) addSpawnedMob(entity); - - if (pets.contains(entity.getUniqueId())) - addSpawnedPet(entity); } if(safeToRemoveMobs) iteratingMobs = false; in.clearSpawnedMobs(); - in.clearSpawnedPets(); } } @@ -217,20 +211,8 @@ public class HashChunkManager implements ChunkManager { removalCheckedMobs.add(entity); } - List tempSpawnedPets = new ArrayList(spawnedPets); - tempSpawnedPets.remove(removalCheckedMobs); - tempSpawnedPets.remove(checkedMobs); - for (Entity entity : tempSpawnedPets) { - if (!isEntityInChunk(entity, cx, cz, world)) - continue; - - mobsToRemove.add(entity); - removalCheckedMobs.add(entity); - } - if (safeToRemoveMobs) { spawnedMobs.remove(mobsToRemove); - spawnedPets.remove(mobsToRemove); mobsToRemove.clear(); removalCheckedMobs.clear(); iteratingMobs = false; @@ -258,19 +240,6 @@ public class HashChunkManager implements ChunkManager { unloaded = true; break; } - - if (!unloaded) { - List tempSpawnedPets = new ArrayList(spawnedPets); - tempSpawnedPets.remove(checkedMobs); - for (Entity entity : tempSpawnedPets) { - if (!isEntityInChunk(entity, cx, cz, world)) - continue; - - loadChunk(cx, cz, world); - unloaded = true; - break; - } - } } if (!store.containsKey(world.getName() + "," + cx + "," + cz) && unloaded) { @@ -291,16 +260,6 @@ public class HashChunkManager implements ChunkManager { checkedMobs.add(entity); } - List tempSpawnedPets = new ArrayList(spawnedPets); - tempSpawnedPets.remove(checkedMobs); - for (Entity entity : tempSpawnedPets) { - if (!isEntityInChunk(entity, cx, cz, world)) - continue; - - out.addSpawnedPet(entity.getUniqueId()); - checkedMobs.add(entity); - } - if (!out.isDirty()) return; @@ -389,20 +348,6 @@ public class HashChunkManager implements ChunkManager { saveChunk(cx, cz, world); } - List tempSpawnedPets = new ArrayList(spawnedPets); - tempSpawnedPets.remove(checkedMobs); - for (Entity entity : tempSpawnedPets) { - World entityWorld = entity.getWorld(); - - if (world != entityWorld) - continue; - - int cx = entity.getLocation().getChunk().getX(); - int cz = entity.getLocation().getChunk().getZ(); - - saveChunk(cx, cz, world); - } - savingWorld = false; savedChunks.clear(); checkedMobs.clear(); @@ -452,25 +397,9 @@ public class HashChunkManager implements ChunkManager { unloadChunk(cx, cz, world); } - List tempSpawnedPets = new ArrayList(spawnedPets); - tempSpawnedPets.remove(checkedMobs); - tempSpawnedMobs.remove(removalCheckedMobs); - for (Entity entity : tempSpawnedPets) { - World entityWorld = entity.getWorld(); - - if (world != entityWorld) - continue; - - int cx = entity.getLocation().getChunk().getX(); - int cz = entity.getLocation().getChunk().getZ(); - - unloadChunk(cx, cz, world); - } - safeToRemoveMobs = true; spawnedMobs.remove(mobsToRemove); - spawnedPets.remove(mobsToRemove); mobsToRemove.clear(); checkedMobs.clear(); removalCheckedMobs.clear(); @@ -642,7 +571,7 @@ public class HashChunkManager implements ChunkManager { } public boolean isSpawnedPet(Entity entity) { - return spawnedPets.contains(entity); + return spawnedMobs.contains(entity); } public void addSpawnedMob(Entity entity) { @@ -651,8 +580,8 @@ public class HashChunkManager implements ChunkManager { } public void addSpawnedPet(Entity entity) { - if (!isSpawnedPet(entity)) - spawnedPets.add(entity); + if (!isSpawnedMob(entity)) + spawnedMobs.add(entity); } public void removeSpawnedMob(Entity entity) { @@ -661,8 +590,8 @@ public class HashChunkManager implements ChunkManager { } public void removeSpawnedPet(Entity entity) { - if (isSpawnedPet(entity)) - spawnedPets.remove(entity); + if (isSpawnedMob(entity)) + spawnedMobs.remove(entity); } public synchronized void cleanMobLists() { @@ -680,17 +609,7 @@ public class HashChunkManager implements ChunkManager { mobsToRemove.add(entity); } - List 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/PrimitiveChunkStore.java b/src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/PrimitiveChunkStore.java index 407fa9494..f09341796 100755 --- a/src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/PrimitiveChunkStore.java +++ b/src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/PrimitiveChunkStore.java @@ -17,13 +17,12 @@ public class PrimitiveChunkStore implements ChunkStore { transient private boolean dirty = false; /** X, Z, Y */ public boolean[][][] store; - private static final int CURRENT_VERSION = 6; + private static final int CURRENT_VERSION = 7; private static final int MAGIC_NUMBER = 0xEA5EDEBB; private int cx; private int cz; private UUID worldUid; private List spawnedMobs = new ArrayList(); - private List spawnedPets = new ArrayList(); transient private int worldHeight; transient private int xBitShifts; @@ -110,7 +109,7 @@ public class PrimitiveChunkStore implements ChunkStore { } public boolean isSpawnedPet(UUID id) { - return spawnedPets.contains(id); + return spawnedMobs.contains(id); } public void addSpawnedMob(UUID id) { @@ -122,7 +121,7 @@ public class PrimitiveChunkStore implements ChunkStore { public void addSpawnedPet(UUID id) { if (!isSpawnedPet(id)) { - spawnedPets.add(id); + spawnedMobs.add(id); dirty = true; } } @@ -136,7 +135,7 @@ public class PrimitiveChunkStore implements ChunkStore { public void removeSpawnedPet(UUID id) { if (isSpawnedPet(id)) { - spawnedPets.remove(id); + spawnedMobs.remove(id); dirty = true; } } @@ -149,8 +148,8 @@ public class PrimitiveChunkStore implements ChunkStore { } public void clearSpawnedPets() { - if (!spawnedPets.isEmpty()) { - spawnedPets.clear(); + if (!spawnedMobs.isEmpty()) { + spawnedMobs.clear(); dirty = true; } } @@ -160,7 +159,7 @@ public class PrimitiveChunkStore implements ChunkStore { } public List getSpawnedPets() { - return spawnedPets; + return spawnedMobs; } private void writeObject(ObjectOutputStream out) throws IOException { @@ -174,7 +173,6 @@ public class PrimitiveChunkStore implements ChunkStore { out.writeObject(store); out.writeObject(spawnedMobs); - out.writeObject(spawnedPets); dirty = false; } @@ -209,15 +207,19 @@ public class PrimitiveChunkStore implements ChunkStore { fixArray(); if (fileVersionNumber < 6) { spawnedMobs = new ArrayList(); - spawnedPets = new ArrayList(); } dirty = true; } - if (fileVersionNumber >= 6) { + if (fileVersionNumber == 6) { //What do we want to do about this? These casts are unchecked. spawnedMobs = (ArrayList) in.readObject(); - spawnedPets = (ArrayList) in.readObject(); + List spawnedPets = (ArrayList) in.readObject(); + spawnedMobs.addAll(spawnedPets); + } + + if(fileVersionNumber >= 7) { + spawnedMobs = (ArrayList) in.readObject(); } } From 50de88a0a0f07083f26c1b0956eed4ab456cce4c Mon Sep 17 00:00:00 2001 From: Glitchfinder Date: Fri, 18 Jan 2013 14:47:55 -0800 Subject: [PATCH 3/4] Fixing minor spacing issue. --- src/main/java/com/gmail/nossr50/listeners/EntityListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java index ad443eac0..8d9ea9cd8 100644 --- a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java @@ -64,7 +64,7 @@ public class EntityListener implements Listener { mcMMO.placeStore.setFalse(block); mcMMO.placeStore.addSpawnedMob(entity); } - else if (mcMMO.placeStore.isSpawnedMob(entity)) { + else if (mcMMO.placeStore.isSpawnedMob(entity)) { mcMMO.placeStore.setTrue(block); mcMMO.placeStore.removeSpawnedMob(entity); } From 00f24fd5bdac67e4e695b8da1981dd795a17652d Mon Sep 17 00:00:00 2001 From: Glitchfinder Date: Fri, 18 Jan 2013 14:55:29 -0800 Subject: [PATCH 4/4] Reducing CPU usage on chunk load. --- .../util/blockmeta/chunkmeta/HashChunkManager.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) 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 f9a239e60..eecfeb84b 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 @@ -17,6 +17,7 @@ import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.entity.Entity; +import org.bukkit.entity.FallingBlock; import org.bukkit.entity.LivingEntity; import com.gmail.nossr50.runnables.blockstoreconversion.BlockStoreConversionZDirectory; @@ -179,7 +180,12 @@ public class HashChunkManager implements ChunkManager { iteratingMobs = true; - for (Entity entity : world.getEntities()) { + for (LivingEntity entity : world.getLivingEntities()) { + if (mobs.contains(entity.getUniqueId())) + addSpawnedMob(entity); + } + + for(FallingBlock entity: world.getEntitiesByClass(FallingBlock.class)) { if (mobs.contains(entity.getUniqueId())) addSpawnedMob(entity); }