From 1ef0f01f1bb4eaed20a5d35a8dfdcd8343692bc5 Mon Sep 17 00:00:00 2001 From: Brianna Date: Thu, 1 Aug 2019 13:47:20 -0400 Subject: [PATCH] More performance boosts. --- .../ultimatestacker/tasks/StackingTask.java | 12 +-- .../ultimatestacker/utils/CachedChunk.java | 60 +++++++++++++ .../ultimatestacker/utils/EntityUtils.java | 86 +++++++++++-------- .../ultimatestacker/utils/Methods.java | 5 +- 4 files changed, 117 insertions(+), 46 deletions(-) create mode 100644 src/main/java/com/songoda/ultimatestacker/utils/CachedChunk.java diff --git a/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java b/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java index 3ec83fe..dffbfce 100644 --- a/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java +++ b/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java @@ -15,10 +15,7 @@ import org.bukkit.entity.HumanEntity; import org.bukkit.entity.LivingEntity; import org.bukkit.scheduler.BukkitRunnable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.UUID; +import java.util.*; import java.util.stream.Collectors; public class StackingTask extends BukkitRunnable { @@ -74,7 +71,9 @@ public class StackingTask extends BukkitRunnable { } } - processed.clear(); + // Clear caches in preparation for the next run. + this.processed.clear(); + plugin.getEntityUtils().clearChunkCache(); } public boolean isWorldDisabled(World world) { @@ -134,7 +133,8 @@ public class StackingTask extends BukkitRunnable { // Get similar entities around our entity and make sure those entities are both compatible and stackable. List stackableFriends = plugin.getEntityUtils().getSimilarEntitiesAroundEntity(livingEntity, location) - .stream().filter(entity -> isEntityStackable(entity, location)).collect(Collectors.toList()); + .stream().filter(entity -> isEntityStackable(entity, location)) + .collect(Collectors.toCollection(LinkedList::new)); // Loop through our similar stackable entities. for (LivingEntity entity : stackableFriends) { diff --git a/src/main/java/com/songoda/ultimatestacker/utils/CachedChunk.java b/src/main/java/com/songoda/ultimatestacker/utils/CachedChunk.java new file mode 100644 index 0000000..9194c0d --- /dev/null +++ b/src/main/java/com/songoda/ultimatestacker/utils/CachedChunk.java @@ -0,0 +1,60 @@ +package com.songoda.ultimatestacker.utils; + +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.World; + +import java.util.Objects; + +public class CachedChunk { + + private final String world; + private final int x; + private final int z; + + public CachedChunk(Chunk chunk) { + this(chunk.getWorld().getName(), chunk.getX(), chunk.getZ()); + } + + public CachedChunk(String world, int x, int z) { + this.world = world; + this.x = x; + this.z = z; + } + + public String getWorld() { + return this.world; + } + + public int getX() { + return this.x; + } + + public int getZ() { + return this.z; + } + + public Chunk getChunk() { + World world = Bukkit.getWorld(this.world); + if (world == null) + return null; + return world.getChunkAt(this.x, this.z); + } + + @Override + public boolean equals(Object o) { + if (o instanceof Chunk) { + Chunk other = (Chunk) o; + return this.world.equals(other.getWorld().getName()) && this.x == other.getX() && this.z == other.getZ(); + } else if (o instanceof CachedChunk) { + CachedChunk other = (CachedChunk) o; + return this.world.equals(other.getWorld()) && this.x == other.getX() && this.z == other.getZ(); + } else return false; + } + + @Override + public int hashCode() { + return Objects.hash(this.world, this.x, this.z); + } + +} diff --git a/src/main/java/com/songoda/ultimatestacker/utils/EntityUtils.java b/src/main/java/com/songoda/ultimatestacker/utils/EntityUtils.java index 69995bc..0d03944 100644 --- a/src/main/java/com/songoda/ultimatestacker/utils/EntityUtils.java +++ b/src/main/java/com/songoda/ultimatestacker/utils/EntityUtils.java @@ -1,6 +1,5 @@ package com.songoda.ultimatestacker.utils; -import com.google.common.collect.Lists; import com.songoda.ultimatestacker.UltimateStacker; import com.songoda.ultimatestacker.entity.Check; import com.songoda.ultimatestacker.entity.EntityStack; @@ -10,9 +9,7 @@ import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.*; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; +import java.util.*; import java.util.stream.Collectors; public class EntityUtils { @@ -23,6 +20,53 @@ public class EntityUtils { private boolean keepPotion = Setting.KEEP_POTION.getBoolean(); private int searchRadius = Setting.SEARCH_RADIUS.getInt(); + private final Map cachedChunks = new HashMap<>(); + + public void clearChunkCache() { + this.cachedChunks.clear(); + } + + + private Set getNearbyChunks(Location location, double radius) { + World world = location.getWorld(); + Set chunks = new HashSet<>(); + if (world == null) return chunks; + + Chunk firstChunk = location.getChunk(); + chunks.add(new CachedChunk(firstChunk)); + int minX = (int) Math.floor(((location.getX() - radius) - 2.0D) / 16.0D); + int maxX = (int) Math.floor(((location.getX() + radius) + 2.0D) / 16.0D); + int minZ = (int) Math.floor(((location.getZ() - radius) - 2.0D) / 16.0D); + int maxZ = (int) Math.floor(((location.getZ() + radius) + 2.0D) / 16.0D); + + for (int x = minX; x <= maxX; ++x) { + for (int z = minZ; z <= maxZ; ++z) { + if (firstChunk.getX() == x && firstChunk.getZ() == z) continue; + chunks.add(new CachedChunk(world.getName(), x, z)); + } + } + return chunks; + } + + private List getNearbyEntities(Location location, double radius) { + List entities = new ArrayList<>(); + for (CachedChunk chunk : getNearbyChunks(location, radius)) { + Entity[] entityArray; + if (cachedChunks.containsKey(chunk)) { + entityArray = cachedChunks.get(chunk); + } else { + entityArray = chunk.getChunk().getEntities(); + cachedChunks.put(chunk, entityArray); + } + for (Entity e : entityArray) { + if (!(e instanceof LivingEntity) + || location.distance(e.getLocation()) >= radius) continue; + entities.add((LivingEntity) e); + } + } + return entities; + } + public LivingEntity newEntity(LivingEntity toClone) { LivingEntity newEntity = (LivingEntity) toClone.getWorld().spawnEntity(toClone.getLocation(), toClone.getType()); newEntity.setVelocity(toClone.getVelocity()); @@ -174,40 +218,6 @@ public class EntityUtils { return newEntity; } - private List getNearbyEntities(Location location, double radius) { - List entities = new ArrayList<>(); - for (Chunk chunk : getNearbyChunks(location, radius)) { - for (Entity e : chunk.getEntities()) { - if (!(e instanceof LivingEntity) || location.distance(e.getLocation()) >= radius) continue; - entities.add((LivingEntity) e); - } - } - return entities; - } - - private List getNearbyChunks(Location location, double radius) { - World world = location.getWorld(); - if (world == null) return new ArrayList<>(); - - Chunk firstChunk = location.getChunk(); - List chunks = Lists.newArrayList(); - chunks.add(firstChunk); - int minX = (int) Math.floor(((location.getX() - radius) - 2.0D) / 16.0D); - int maxX = (int) Math.floor(((location.getX() + radius) + 2.0D) / 16.0D); - int minZ = (int) Math.floor(((location.getZ() - radius) - 2.0D) / 16.0D); - int maxZ = (int) Math.floor(((location.getZ() + radius) + 2.0D) / 16.0D); - - for (int x = minX; x <= maxX; ++x) { - for (int z = minZ; z <= maxZ; ++z) { - if (firstChunk.getX() == x && firstChunk.getZ() == z) continue; - Chunk chunk = world.getChunkAt(x, z); - if (chunk.isLoaded() && !chunks.contains(chunk)) - chunks.add(chunk); - } - } - return chunks; - } - public List getSimilarEntitiesAroundEntity(LivingEntity initalEntity, Location location) { // Create a list of all entities around the initial entity of the same type. List entityList = getNearbyEntities(location, searchRadius) diff --git a/src/main/java/com/songoda/ultimatestacker/utils/Methods.java b/src/main/java/com/songoda/ultimatestacker/utils/Methods.java index f5b0312..539598a 100644 --- a/src/main/java/com/songoda/ultimatestacker/utils/Methods.java +++ b/src/main/java/com/songoda/ultimatestacker/utils/Methods.java @@ -66,10 +66,11 @@ public class Methods { } public static int getActualItemAmount(Item item) { - if (item.getItemStack().getAmount() >= 32 && item.hasMetadata("US_AMT")) { + int amount = item.getItemStack().getAmount(); + if (amount >= 32 && item.hasMetadata("US_AMT")) { return item.getMetadata("US_AMT").get(0).asInt(); } else { - return item.getItemStack().getAmount(); + return amount; } }