From 8afc3334429aa554ea38d5a832e0bfd7e8124a9d Mon Sep 17 00:00:00 2001 From: ceze88 Date: Mon, 19 Sep 2022 19:45:08 +0200 Subject: [PATCH 1/6] Do not apply realistic weapon damage in creative --- .../songoda/ultimatestacker/listeners/DeathListeners.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/songoda/ultimatestacker/listeners/DeathListeners.java b/src/main/java/com/songoda/ultimatestacker/listeners/DeathListeners.java index 0232f20..620d073 100644 --- a/src/main/java/com/songoda/ultimatestacker/listeners/DeathListeners.java +++ b/src/main/java/com/songoda/ultimatestacker/listeners/DeathListeners.java @@ -7,6 +7,7 @@ import com.songoda.core.lootables.loot.DropUtils; import com.songoda.ultimatestacker.UltimateStacker; import com.songoda.ultimatestacker.settings.Settings; import com.songoda.ultimatestacker.stackable.entity.EntityStack; +import org.bukkit.GameMode; import org.bukkit.GameRule; import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; @@ -153,8 +154,9 @@ public class DeathListeners implements Listener { if (!plugin.getEntityStackManager().isStackedAndLoaded(entity)) return; EntityStack stack = plugin.getEntityStackManager().getStack(entity); - if (Settings.KILL_WHOLE_STACK_ON_DEATH.getBoolean() && Settings.REALISTIC_DAMAGE.getBoolean()) { - Player player = (Player) event.getDamager(); + Player player = (Player) event.getDamager(); + + if (Settings.KILL_WHOLE_STACK_ON_DEATH.getBoolean() && Settings.REALISTIC_DAMAGE.getBoolean() && !player.getGameMode().equals(GameMode.CREATIVE)) { ItemStack tool = player.getInventory().getItemInHand(); if (tool.getType().getMaxDurability() < 1 || (tool.getItemMeta() != null && (tool.getItemMeta().isUnbreakable() || (ServerProject.isServer(ServerProject.SPIGOT, ServerProject.PAPER) && tool.getItemMeta().isUnbreakable())))) From 865e45010cd54798e83f385b5528249629d2e273 Mon Sep 17 00:00:00 2001 From: ceze88 Date: Mon, 19 Sep 2022 20:26:08 +0200 Subject: [PATCH 2/6] New method to spawn stacked items --- .../songoda/ultimatestacker/UltimateStacker.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java b/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java index b8fdd84..e23b20d 100644 --- a/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java +++ b/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java @@ -49,6 +49,7 @@ import com.songoda.ultimatestacker.tasks.StackingTask; import com.songoda.ultimatestacker.utils.Methods; import org.apache.commons.lang.WordUtils; import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.EntityType; import org.bukkit.entity.Item; @@ -382,6 +383,19 @@ public class UltimateStacker extends SongodaPlugin { //////// Convenient API ////////// + /** + * Spawn a stacked item at a location + * + * @param item The item to spawn + * @param amount The amount of items to spawn + * @param location The location to spawn the item + */ + public static void spawnStackedItem(ItemStack item, int amount, Location location) { + location.getWorld().dropItem(location, item, dropped -> { + updateItemAmount(dropped, amount); + }); + } + /** * Change the stacked amount for this item * From 610d423d01097daf4521001cc9fa2e48897a5c55 Mon Sep 17 00:00:00 2001 From: ceze88 Date: Mon, 19 Sep 2022 20:30:28 +0200 Subject: [PATCH 3/6] Version 2.3.1-Dev --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index aeba90f..3a49b8c 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ com.songoda UltimateStacker 4.0.0 - 2.3.0 + 2.3.1-Dev clean install UltimateStacker-${project.version} From c6320cb141043c2179574157272568365e7d4b07 Mon Sep 17 00:00:00 2001 From: Christian Koop Date: Wed, 26 Oct 2022 22:04:01 +0200 Subject: [PATCH 4/6] Do entity collection in Bukkit's main thread for StackingTask Paper-Spigot got more strict in 1.19.2 about calling stuff async. I do not know what the whole StackingTask does and don't feel like cleaning it up completely is possible right now. So I only moved the getEntities-calls to the main thread and have the async task wait for it. Not great but it fixed the bug. SD-9374 SD-9377 SD-9392 SD-9401 --- .../ultimatestacker/tasks/StackingTask.java | 66 +++++++++++++++---- 1 file changed, 55 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java b/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java index 97ae05d..f760f48 100644 --- a/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java +++ b/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java @@ -17,7 +17,32 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.*; +import org.bukkit.entity.AbstractHorse; +import org.bukkit.entity.Ageable; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Cat; +import org.bukkit.entity.ChestedHorse; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Horse; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Llama; +import org.bukkit.entity.Ocelot; +import org.bukkit.entity.Parrot; +import org.bukkit.entity.Phantom; +import org.bukkit.entity.Pig; +import org.bukkit.entity.PufferFish; +import org.bukkit.entity.Rabbit; +import org.bukkit.entity.Sheep; +import org.bukkit.entity.Skeleton; +import org.bukkit.entity.Slime; +import org.bukkit.entity.Snowman; +import org.bukkit.entity.Tameable; +import org.bukkit.entity.TropicalFish; +import org.bukkit.entity.Villager; +import org.bukkit.entity.Wolf; +import org.bukkit.entity.Zombie; import org.bukkit.inventory.EntityEquipment; import org.bukkit.scheduler.BukkitRunnable; @@ -30,6 +55,9 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; public class StackingTask extends BukkitRunnable { @@ -42,7 +70,7 @@ public class StackingTask extends BukkitRunnable { private final Map cachedChunks = new HashMap<>(); - private final HashMap entityStackSizes = new HashMap(); + private final Map entityStackSizes = new HashMap<>(); private final int maxEntityStackSize = Settings.MAX_STACK_ENTITIES.getInt(), minEntityStackSize = Settings.MIN_STACK_ENTITIES.getInt(), searchRadius = Settings.SEARCH_RADIUS.getInt(), @@ -83,11 +111,10 @@ public class StackingTask extends BukkitRunnable { // Get the loaded entities from the current world and reverse them. List entities; try { - entities = sWorld.getLivingEntities(); - } catch (Exception ignored) { + entities = getLivingEntitiesSync(sWorld).get(); + } catch (ExecutionException | InterruptedException ex) { + ex.printStackTrace(); continue; - // Sometimes accessing this method asynchronously throws an error. This is super rare and - // as such doesn't really affect the plugin so we're just going to ignore this failure. } Collections.reverse(entities); @@ -113,6 +140,20 @@ public class StackingTask extends BukkitRunnable { this.cachedChunks.clear(); } + private Future> getLivingEntitiesSync(SWorld sWorld) { + CompletableFuture> future = new CompletableFuture<>(); + Bukkit.getScheduler().scheduleSyncDelayedTask(this.plugin, () -> future.complete(sWorld.getLivingEntities())); + + return future; + } + + private Future getEntitiesInChunkSync(CachedChunk cachedChunk) { + CompletableFuture future = new CompletableFuture<>(); + Bukkit.getScheduler().scheduleSyncDelayedTask(this.plugin, () -> future.complete(cachedChunk.getEntities())); + + return future; + } + public boolean isWorldDisabled(World world) { return disabledWorlds.stream().anyMatch(worldStr -> world.getName().equalsIgnoreCase(worldStr)); } @@ -367,19 +408,21 @@ public class StackingTask extends BukkitRunnable { List entities = new ArrayList<>(); for (CachedChunk chunk : getNearbyChunks(sWorld, location, radius, singleChunk)) { if (chunk == null) continue; - Entity[] entityArray = new Entity[0]; + Entity[] entityArray; if (cachedChunks.containsKey(chunk)) { entityArray = cachedChunks.get(chunk); } else { try { - entityArray = chunk.getEntities(); + entityArray = getEntitiesInChunkSync(chunk).get(); cachedChunks.put(chunk, entityArray); - } catch (Exception ignored) { - // Sometimes accessing this method asynchronously throws an error. This is super rare and - // as such doesn't really affect the plugin so we're just going to ignore this failure. + } catch (ExecutionException | InterruptedException ex) { + ex.printStackTrace(); + continue; } } + if (entityArray == null) continue; + for (Entity e : entityArray) { if (e == null) continue; if (e.getWorld() != location.getWorld() @@ -388,6 +431,7 @@ public class StackingTask extends BukkitRunnable { entities.add((LivingEntity) e); } } + return entities; } From e9b7eee57bb8735bde6d0f1bc0c62c65eeb76889 Mon Sep 17 00:00:00 2001 From: Christian Koop Date: Wed, 26 Oct 2022 22:06:11 +0200 Subject: [PATCH 5/6] Fix NullPointerException in StackingTask Kinda related to c6320cb141043c2179574157272568365e7d4b07 --- .../java/com/songoda/ultimatestacker/tasks/StackingTask.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java b/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java index f760f48..a0950a1 100644 --- a/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java +++ b/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java @@ -284,6 +284,10 @@ public class StackingTask extends BukkitRunnable { // Make the friend the new stack host. EntityStack newStack = stackManager.updateStack(livingEntity, entity); + if (newStack == null) { + continue; + } + // Add our entity to that stack plugin.getDataManager().createStackedEntity(newStack, newStack.addEntityToStack(livingEntity)); From 9b5ac542c16c2c7db4cf35e317acbcd43731bba7 Mon Sep 17 00:00:00 2001 From: Christian Koop Date: Wed, 26 Oct 2022 22:16:36 +0200 Subject: [PATCH 6/6] Release v2.3.1 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 3a49b8c..dff2ba4 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ com.songoda UltimateStacker 4.0.0 - 2.3.1-Dev + 2.3.1 clean install UltimateStacker-${project.version} @@ -112,7 +112,7 @@ com.songoda SongodaCore - 2.6.16 + 2.6.17-SNAPSHOT compile