From febf598aa320e1fd3aeeacd55ebac0089a586232 Mon Sep 17 00:00:00 2001 From: Brianna Date: Tue, 8 Dec 2020 10:28:17 -0600 Subject: [PATCH 01/11] Support other WorldEdit versions. --- .../com/songoda/skyblock/utils/structure/SchematicUtil.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/songoda/skyblock/utils/structure/SchematicUtil.java b/src/main/java/com/songoda/skyblock/utils/structure/SchematicUtil.java index 697668a4..a74cb0b8 100644 --- a/src/main/java/com/songoda/skyblock/utils/structure/SchematicUtil.java +++ b/src/main/java/com/songoda/skyblock/utils/structure/SchematicUtil.java @@ -4,6 +4,7 @@ import com.songoda.skyblock.SkyBlock; import com.songoda.skyblock.utils.version.NMSUtil; import org.bukkit.Bukkit; import org.bukkit.World; +import org.bukkit.plugin.PluginManager; import java.io.File; import java.io.FileInputStream; @@ -14,7 +15,8 @@ import java.lang.reflect.Method; public class SchematicUtil { public static Float[] pasteSchematic(File schematicFile, org.bukkit.Location location) { - if (!Bukkit.getPluginManager().isPluginEnabled("WorldEdit")) + PluginManager pluginManager = Bukkit.getPluginManager(); + if (!pluginManager.isPluginEnabled("WorldEdit") && !pluginManager.isPluginEnabled("AsyncWorldEdit") && !pluginManager.isPluginEnabled("FastAsyncWorldEdit")) throw new IllegalStateException("Tried to generate an island using a schematic file without WorldEdit installed!"); Runnable pasteTask = () -> { From 8e8cb7a01b3823c3d731c43f2745c8cd384f6c3d Mon Sep 17 00:00:00 2001 From: FixedDev Date: Sat, 5 Dec 2020 18:26:51 -0600 Subject: [PATCH 02/11] Rename this method to prevent it from being called by the finalizers --- .../com/songoda/skyblock/levelling/QueuedIslandScan.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/songoda/skyblock/levelling/QueuedIslandScan.java b/src/main/java/com/songoda/skyblock/levelling/QueuedIslandScan.java index 77f4793d..312d4371 100644 --- a/src/main/java/com/songoda/skyblock/levelling/QueuedIslandScan.java +++ b/src/main/java/com/songoda/skyblock/levelling/QueuedIslandScan.java @@ -12,7 +12,6 @@ import org.bukkit.Bukkit; import org.bukkit.configuration.Configuration; import org.bukkit.entity.Player; -import java.io.File; import java.text.NumberFormat; import java.util.*; @@ -55,7 +54,7 @@ public class QueuedIslandScan { update(); if (toScan.isEmpty()) { - finalize(); + finalizeScan(); return false; } IslandWorld world = toScan.poll(); @@ -63,8 +62,7 @@ public class QueuedIslandScan { return true; } - public void finalize() { - + public void finalizeScan() { final Map materials = new HashMap<>(amounts.size()); for (Map.Entry entry : amounts.entrySet()) { From 41e87c55b97a5d4c5e083d37b9d7943f0702add0 Mon Sep 17 00:00:00 2001 From: FixedDev Date: Sat, 5 Dec 2020 19:58:31 -0600 Subject: [PATCH 03/11] Add a method to know if a snapshot for a CachedChunk is available --- .../java/com/songoda/skyblock/blockscanner/CachedChunk.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/songoda/skyblock/blockscanner/CachedChunk.java b/src/main/java/com/songoda/skyblock/blockscanner/CachedChunk.java index 17864e92..b49d0091 100644 --- a/src/main/java/com/songoda/skyblock/blockscanner/CachedChunk.java +++ b/src/main/java/com/songoda/skyblock/blockscanner/CachedChunk.java @@ -49,6 +49,10 @@ public class CachedChunk { return PaperLib.getChunkAtAsync(world, this.x, this.z); } + public boolean isSnapshotAvailable() { + return latestSnapshot != null; + } + public ChunkSnapshot getSnapshot() { if (latestSnapshot == null) return takeSnapshot(); From 489bfd14bc1e7f0ca613a4e8396c63c74ba036bb Mon Sep 17 00:00:00 2001 From: FixedDev Date: Sat, 5 Dec 2020 20:08:31 -0600 Subject: [PATCH 04/11] Fix issue causing island scans never finish. There was an issue in 1.8 specifically(where PaperLib doesn't has async chunks) that caused a similar error to this https://pastebin.com/tHtKdH5y. The issue was caused by the async task trying to take an snapshot of a chunk that couldn't be loaded async correctly, which caused issues like the shown above. The fix works in the next way. All the chunks that don't have an available snapshot are sent into a pendingChunks list where a sync task will try to process a certain amount of chunks every tick. After the async processing is finished, the task remains waiting for the pending chunks to be available. When all the pending chunks are ready to be processed(have an available snapshot) the async task resumes and process the chunks that were pending. --- .../skyblock/blockscanner/BlockScanner.java | 225 +++++++++++++----- 1 file changed, 168 insertions(+), 57 deletions(-) diff --git a/src/main/java/com/songoda/skyblock/blockscanner/BlockScanner.java b/src/main/java/com/songoda/skyblock/blockscanner/BlockScanner.java index 57956cfc..92c4fdf1 100644 --- a/src/main/java/com/songoda/skyblock/blockscanner/BlockScanner.java +++ b/src/main/java/com/songoda/skyblock/blockscanner/BlockScanner.java @@ -7,6 +7,7 @@ import com.songoda.skyblock.SkyBlock; import com.songoda.skyblock.island.Island; import com.songoda.skyblock.island.IslandEnvironment; import com.songoda.skyblock.world.WorldManager; +import io.papermc.lib.PaperLib; import org.bukkit.Bukkit; import org.bukkit.ChunkSnapshot; import org.bukkit.Location; @@ -15,26 +16,33 @@ import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.scheduler.BukkitRunnable; -import java.io.File; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; public final class BlockScanner extends BukkitRunnable { private static final Method ID_FIELD; + private static final int MAX_CHUNKS_PER_ITERATION = 2; + private static final int MAX_EMPTY_ITERATIONS = 20; static { Method temp = null; try { temp = ChunkSnapshot.class.getMethod("getBlockTypeId", int.class, int.class, int.class); - } catch (NoSuchMethodException ignored) {} + } catch (NoSuchMethodException ignored) { + } ID_FIELD = temp; } @@ -57,9 +65,9 @@ public final class BlockScanner extends BukkitRunnable { private final int threadCount; private final Queue blocks; private final ScannerTasks tasks; - + private final Island island; - + private final boolean ignoreLiquids; private final boolean ignoreAir; @@ -84,35 +92,35 @@ public final class BlockScanner extends BukkitRunnable { for (Entry> entry : snapshots.entrySet()) { final List> parts = Lists.partition(entry.getValue(), 16); - + threadCount += parts.size(); World world = entry.getKey(); final String env; switch (world.getEnvironment()) { - case NETHER: - env = "Nether"; - break; - case THE_END: - env = "End"; - break; - default: - env = "Normal"; - break; + case NETHER: + env = "Nether"; + break; + case THE_END: + env = "End"; + break; + default: + env = "Normal"; + break; } final ConfigurationSection liquidSection = config.getConfigurationSection("Island.World." + env + ".Liquid"); int startY; - if(ignoreY){ + if (ignoreY) { startY = 255; } else { startY = !ignoreLiquidsY && liquidSection.getBoolean("Enable") && !config.getBoolean("Island.Levelling.ScanLiquid") ? liquidSection.getInt("Height") + 1 : 0; } for (List sub : parts) { - queueWork(world, startY, sub); + queueWork(world, startY, sub); } } @@ -121,63 +129,166 @@ public final class BlockScanner extends BukkitRunnable { private void queueWork(World world, int scanY, List subList) { WorldManager worldManager = SkyBlock.getInstance().getWorldManager(); - + + // The chunks that couldn't be taken snapshot async + List pendingChunks = new ArrayList<>(); + + // The chunks that are ready to be processed asynchronously + List readyChunks = new ArrayList<>(); + + // This lock will help to make the bukkit task wait after all the chunks that could be processed async are processed + Lock lock = new ReentrantLock(); + + // This is the actual object that we will use to wait + Condition emptyCondition = lock.newCondition(); + Bukkit.getServer().getScheduler().runTaskAsynchronously(SkyBlock.getInstance(), () -> { + // We need to hold the lock on the thread calling the await + lock.lock(); + LocationBounds bounds = null; - if(island != null) { + if (island != null) { Location islandLocation = island.getLocation(worldManager.getIslandWorld(world), IslandEnvironment.Island); - + Location minLocation = new Location(world, islandLocation.getBlockX() - island.getRadius(), 0, islandLocation.getBlockZ() - island.getRadius()); Location maxLocation = new Location(world, islandLocation.getBlockX() + island.getRadius(), world.getMaxHeight(), islandLocation.getBlockZ() + island.getRadius()); - + int minX = Math.min(maxLocation.getBlockX(), minLocation.getBlockX()); int minZ = Math.min(maxLocation.getBlockZ(), minLocation.getBlockZ()); - + int maxX = Math.max(maxLocation.getBlockX(), minLocation.getBlockX()); int maxZ = Math.max(maxLocation.getBlockZ(), minLocation.getBlockZ()); - + bounds = new LocationBounds(minX, minZ, maxX, maxZ); } - for (CachedChunk shot : subList) { - final int cX = shot.getX() << 4; - final int cZ = shot.getZ() << 4; - - int initX = 0; - int initZ = 0; - int lastX = 15; - int lastZ = 15; - - if(bounds != null) { - initX = Math.max(cX, bounds.getMinX())&0x000F; - initZ = Math.max(cZ, bounds.getMinZ())&0x000F; - - lastX = Math.min(cX | 15, bounds.getMaxX()-1)&0x000F; - lastZ = Math.min(cZ | 15, bounds.getMaxZ()-1)&0x000F; - } - - for (int x = initX; x <= lastX; x++) { - for (int z = initZ; z <= lastZ; z++) { - for (int y = scanY; y < world.getMaxHeight(); y++) { - final CompatibleMaterial type = CompatibleMaterial.getBlockMaterial( - ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13) - ? shot.getSnapshot().getBlockType(x, y, z) : - MaterialIDHelper.getLegacyMaterial(getBlockTypeID(shot, x, y, z))); - - if(type == null){ - continue; - } else if(type.equals(CompatibleMaterial.AIR) && ignoreAir){ - continue; - } else if(type.equals(CompatibleMaterial.WATER) && ignoreLiquids){ - continue; - } - blocks.add(new BlockInfo(world, x + (cX), y, z + (cZ))); - } - } + for (CachedChunk shot : subList) { + if (!shot.isSnapshotAvailable() && !areAsyncChunksAvailable()) { + pendingChunks.add(shot); + + continue; } + + processCachedChunk(world, scanY, shot, bounds); } + + // Don't wait for the condition if the async chunks are available, since it would never be signalled + if (areAsyncChunksAvailable()) { + increment(); + + lock.unlock(); + return; + } + + try { + emptyCondition.await(); + } catch (InterruptedException e) { + // Pass the interruption + Thread.currentThread().interrupt(); + } + + // process the pending chunks + for (CachedChunk shot : readyChunks) { + processCachedChunk(world, scanY, shot, bounds); + } + + lock.unlock(); increment(); }); + + if (!areAsyncChunksAvailable()) { + startChunkSnapshotTask(pendingChunks, readyChunks, emptyCondition, lock); + } + } + + private boolean areAsyncChunksAvailable() { + return PaperLib.isVersion(9) && PaperLib.isPaper(); + } + + private void startChunkSnapshotTask(List pendingChunks, List readyChunks, Condition emptyCondition, Lock lock) { + new BukkitRunnable() { + // The number of iterations with the pendingChunks list empty + private int emptyIterations = 0; + + @Override + public void run() { + lock.lock(); + int updatedChunks = 0; + + Iterator chunkIterator = pendingChunks.iterator(); + + try { + while (chunkIterator.hasNext()) { + CachedChunk pendingChunk = chunkIterator.next(); + + if (updatedChunks >= MAX_CHUNKS_PER_ITERATION) { + break; + } + + // take the snapshot + pendingChunk.takeSnapshot(); + + chunkIterator.remove(); + readyChunks.add(pendingChunk); + + updatedChunks++; + } + + if (pendingChunks.isEmpty()) { + if (emptyIterations >= MAX_EMPTY_ITERATIONS) { + // Send the signal to unlock the async thread and continue with the processing + emptyCondition.signalAll(); + this.cancel(); + + return; + } + + emptyIterations++; + } + } finally { + lock.unlock(); + } + } + }.runTaskTimer(SkyBlock.getInstance(), 1, 1); + } + + private void processCachedChunk(World world, int scanY, CachedChunk shot, LocationBounds bounds) { + final int cX = shot.getX() << 4; + final int cZ = shot.getZ() << 4; + + int initX = 0; + int initZ = 0; + int lastX = 15; + int lastZ = 15; + + if (bounds != null) { + initX = Math.max(cX, bounds.getMinX()) & 0x000F; + initZ = Math.max(cZ, bounds.getMinZ()) & 0x000F; + + lastX = Math.min(cX | 15, bounds.getMaxX() - 1) & 0x000F; + lastZ = Math.min(cZ | 15, bounds.getMaxZ() - 1) & 0x000F; + } + + for (int x = initX; x <= lastX; x++) { + for (int z = initZ; z <= lastZ; z++) { + for (int y = scanY; y < world.getMaxHeight(); y++) { + final CompatibleMaterial type = CompatibleMaterial.getBlockMaterial( + ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13) + ? shot.getSnapshot().getBlockType(x, y, z) : + MaterialIDHelper.getLegacyMaterial(getBlockTypeID(shot, x, y, z))); + + if (type == null) { + continue; + } else if (type.equals(CompatibleMaterial.AIR) && ignoreAir) { + continue; + } else if (type.equals(CompatibleMaterial.WATER) && ignoreLiquids) { + continue; + } + + blocks.add(new BlockInfo(world, x + (cX), y, z + (cZ))); + } + } + } } private synchronized int increment() { From c2d32a86002ae91ab434531936075fb59d8d872b Mon Sep 17 00:00:00 2001 From: Brianna Date: Tue, 8 Dec 2020 11:57:26 -0600 Subject: [PATCH 05/11] Remove gitlab stuff. --- .gitlab-ci.yml | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index bbbc60f0..00000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,16 +0,0 @@ -image: maven:latest - -cache: - paths: - - .m2/repository/ - - target/ - -build: - stage: build - script: - - mvn compile - -test: - stage: test - script: - - mvn test \ No newline at end of file From af918a7c9f4f31c876de07cf4a3fbaeb9492db17 Mon Sep 17 00:00:00 2001 From: Brianna Date: Tue, 8 Dec 2020 11:59:16 -0600 Subject: [PATCH 06/11] 2.3.20 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 84322726..8b93babb 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.songoda skyblock - 2.3.19 + 2.3.20 jar UTF-8 From 96db34a90f1f3d9cfbe7675f23a7d4152912f92c Mon Sep 17 00:00:00 2001 From: Fernando Pettinelli Date: Mon, 21 Dec 2020 16:49:11 -0300 Subject: [PATCH 07/11] Fix nether lava issues. --- .../songoda/skyblock/world/WorldManager.java | 14 ++++---- .../world/generator/VoidGenerator.java | 34 +++++++++---------- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/songoda/skyblock/world/WorldManager.java b/src/main/java/com/songoda/skyblock/world/WorldManager.java index abb93f75..98451d38 100644 --- a/src/main/java/com/songoda/skyblock/world/WorldManager.java +++ b/src/main/java/com/songoda/skyblock/world/WorldManager.java @@ -47,9 +47,9 @@ public class WorldManager { String netherWorldGeneratorName = configLoad.getString("Island.World.End.CustomWorldGenerator"); String endWorldGeneratorName = configLoad.getString("Island.World.End.CustomWorldGenerator"); - normalWorldWorldGenerator = getWorldGenerator(normalWorldName, normalWorldGeneratorName); - netherWorldWorldGenerator = getWorldGenerator(netherWorldName, netherWorldGeneratorName); - endWorldWorldGenerator = getWorldGenerator(endWorldName, endWorldGeneratorName); + normalWorldWorldGenerator = getWorldGenerator(normalWorldName, normalWorldGeneratorName, IslandWorld.Normal); + netherWorldWorldGenerator = getWorldGenerator(netherWorldName, netherWorldGeneratorName, IslandWorld.Nether); + endWorldWorldGenerator = getWorldGenerator(endWorldName, endWorldGeneratorName, IslandWorld.End); normalWorld = Bukkit.getServer().getWorld(normalWorldName); netherWorld = Bukkit.getServer().getWorld(netherWorldName); @@ -138,9 +138,9 @@ public class WorldManager { return location; } - private ChunkGenerator getWorldGenerator(String mapName, String worldGeneratorName) { + private ChunkGenerator getWorldGenerator(String mapName, String worldGeneratorName, IslandWorld islandWorld) { if (worldGeneratorName == null || worldGeneratorName == "default" || worldGeneratorName.length() == 0) { - return new VoidGenerator(); + return new VoidGenerator(islandWorld); } ChunkGenerator customWorldGenerator = WorldCreator.getGeneratorForName(mapName, worldGeneratorName, null); @@ -149,7 +149,7 @@ public class WorldManager { return customWorldGenerator; } - return new VoidGenerator(); + return new VoidGenerator(islandWorld); } public ChunkGenerator getWorldGeneratorForMapName(String mapName) { @@ -159,6 +159,6 @@ public class WorldManager { if (endWorld != null && endWorld.getName().equals(mapName)) return endWorldWorldGenerator; - return new VoidGenerator(); + return new VoidGenerator(IslandWorld.Normal); } } diff --git a/src/main/java/com/songoda/skyblock/world/generator/VoidGenerator.java b/src/main/java/com/songoda/skyblock/world/generator/VoidGenerator.java index e35500ff..0c5fe61a 100644 --- a/src/main/java/com/songoda/skyblock/world/generator/VoidGenerator.java +++ b/src/main/java/com/songoda/skyblock/world/generator/VoidGenerator.java @@ -21,6 +21,11 @@ import java.util.Random; public class VoidGenerator extends ChunkGenerator { + private final IslandWorld islandWorld; + public VoidGenerator(IslandWorld islandWorld) { + this.islandWorld = islandWorld; + } + @Override public @Nonnull ChunkData generateChunkData(@Nonnull World world, @Nonnull Random random, int chunkX, int chunkZ, @Nonnull BiomeGrid biomeGrid) { final ChunkData chunkData = createChunkData(world); @@ -28,7 +33,7 @@ public class VoidGenerator extends ChunkGenerator { final SkyBlock plugin = SkyBlock.getInstance(); final Configuration configLoad = plugin.getConfiguration(); final ConfigurationSection worldSection = configLoad.getConfigurationSection("Island.World"); - + Biome biome; switch (world.getEnvironment()) { @@ -50,26 +55,19 @@ public class VoidGenerator extends ChunkGenerator { } else { setChunkBiome2D(biome, biomeGrid); } - - for (IslandWorld worldList : IslandWorld.values()) { - if (world.getEnvironment() == World.Environment.NETHER - || world.getEnvironment() == World.Environment.NORMAL - || world.getEnvironment() == World.Environment.THE_END) { - ConfigurationSection section = worldSection.getConfigurationSection(worldList.name()); + ConfigurationSection section = worldSection.getConfigurationSection(islandWorld.name()); - if (section.getBoolean("Liquid.Enable")) { - if (section.getBoolean("Liquid.Lava")) { - setBlock(chunkData, CompatibleMaterial.LAVA.getBlockMaterial(), section.getInt("Liquid.Height")); - } else { - setBlock(chunkData, CompatibleMaterial.WATER.getBlockMaterial(), section.getInt("Liquid.Height")); - } - } - - break; + if (section.getBoolean("Liquid.Enable")) { + if (section.getBoolean("Liquid.Lava")) { + setBlock(chunkData, CompatibleMaterial.LAVA.getBlockMaterial(), section.getInt("Liquid.Height")); + } else { + setBlock(chunkData, CompatibleMaterial.WATER.getBlockMaterial(), section.getInt("Liquid.Height")); } } + + return chunkData; } @@ -96,7 +94,7 @@ public class VoidGenerator extends ChunkGenerator { } } } - + // Do not use - Too laggy private void setChunkBiome3D(Biome biome, BiomeGrid grid, World world) { for(int x = 0; x < 16; x++){ @@ -107,7 +105,7 @@ public class VoidGenerator extends ChunkGenerator { } } } - + private void setChunkBiome2D(Biome biome, BiomeGrid grid) { for(int x = 0; x < 16; x++){ for(int z = 0; z < 16; z++){ From 1c90e593272af3517bdc4592d39c88f26f385c12 Mon Sep 17 00:00:00 2001 From: Fernando Pettinelli Date: Tue, 22 Dec 2020 12:20:02 -0300 Subject: [PATCH 08/11] Add failsafes to config enums. --- .../java/com/songoda/skyblock/island/IslandStatus.java | 7 ++++++- .../songoda/skyblock/world/generator/VoidGenerator.java | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/songoda/skyblock/island/IslandStatus.java b/src/main/java/com/songoda/skyblock/island/IslandStatus.java index 682e9495..97bd7893 100644 --- a/src/main/java/com/songoda/skyblock/island/IslandStatus.java +++ b/src/main/java/com/songoda/skyblock/island/IslandStatus.java @@ -1,11 +1,16 @@ package com.songoda.skyblock.island; +import java.util.Arrays; + public enum IslandStatus { OPEN, CLOSED, WHITELISTED; public static IslandStatus getEnum(String value) { - return valueOf(value.toUpperCase()); + return Arrays.stream(values()) + .filter(status -> value.toUpperCase().equals(status.name())) + .findFirst() + .orElse(OPEN); } } diff --git a/src/main/java/com/songoda/skyblock/world/generator/VoidGenerator.java b/src/main/java/com/songoda/skyblock/world/generator/VoidGenerator.java index 0c5fe61a..53228cf3 100644 --- a/src/main/java/com/songoda/skyblock/world/generator/VoidGenerator.java +++ b/src/main/java/com/songoda/skyblock/world/generator/VoidGenerator.java @@ -38,7 +38,10 @@ public class VoidGenerator extends ChunkGenerator { switch (world.getEnvironment()) { case NORMAL: - biome = CompatibleBiome.valueOf(configLoad.getString("Island.Biome.Default.Type", "PLAINS").toUpperCase()).getBiome(); + biome = Arrays.stream(CompatibleBiome.values()) + .filter(compatibleBiome -> compatibleBiome.getBiome().equals(configLoad.getString("Island.Biome.Default.Type", "PLAINS").toUpperCase())) + .findFirst() + .orElse(CompatibleBiome.PLAINS).getBiome(); break; case NETHER: biome = CompatibleBiome.NETHER_WASTES.getBiome(); From a8459f53b48b644283a088eb77662929ff24d17a Mon Sep 17 00:00:00 2001 From: Fernando Pettinelli Date: Tue, 22 Dec 2020 12:21:42 -0300 Subject: [PATCH 09/11] Fix a small mistake with the enum check. --- .../com/songoda/skyblock/world/generator/VoidGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/songoda/skyblock/world/generator/VoidGenerator.java b/src/main/java/com/songoda/skyblock/world/generator/VoidGenerator.java index 53228cf3..1a392224 100644 --- a/src/main/java/com/songoda/skyblock/world/generator/VoidGenerator.java +++ b/src/main/java/com/songoda/skyblock/world/generator/VoidGenerator.java @@ -39,7 +39,7 @@ public class VoidGenerator extends ChunkGenerator { switch (world.getEnvironment()) { case NORMAL: biome = Arrays.stream(CompatibleBiome.values()) - .filter(compatibleBiome -> compatibleBiome.getBiome().equals(configLoad.getString("Island.Biome.Default.Type", "PLAINS").toUpperCase())) + .filter(compatibleBiome -> compatibleBiome.getBiome().name().equals(configLoad.getString("Island.Biome.Default.Type", "PLAINS").toUpperCase())) .findFirst() .orElse(CompatibleBiome.PLAINS).getBiome(); break; From abedf91b04276c1866ffa0fe4e10161e1f59a710 Mon Sep 17 00:00:00 2001 From: Fernando Pettinelli Date: Tue, 22 Dec 2020 16:40:28 -0300 Subject: [PATCH 10/11] Check if economy is null before checking if it's enabled. --- .../skyblock/command/commands/island/UpgradeCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/songoda/skyblock/command/commands/island/UpgradeCommand.java b/src/main/java/com/songoda/skyblock/command/commands/island/UpgradeCommand.java index a90df98c..aecd3043 100644 --- a/src/main/java/com/songoda/skyblock/command/commands/island/UpgradeCommand.java +++ b/src/main/java/com/songoda/skyblock/command/commands/island/UpgradeCommand.java @@ -29,7 +29,7 @@ public class UpgradeCommand extends SubCommand { configLoad.getString("Command.Island.Upgrade.Owner.Message")); soundManager.playSound(player, CompatibleSound.BLOCK_ANVIL_LAND.getSound(), 1.0F, 1.0F); } else { - if (!economy.isEnabled()) { + if (economy == null || !economy.isEnabled()) { messageManager.sendMessage(player, configLoad.getString("Command.Island.Upgrade.Disabled.Message")); soundManager.playSound(player, CompatibleSound.BLOCK_ANVIL_LAND.getSound(), 1.0F, 1.0F); return; From a6c8bfc05edda7d465fdf2d04dce7c8d7c9611d0 Mon Sep 17 00:00:00 2001 From: Fernando Pettinelli Date: Wed, 23 Dec 2020 13:12:26 -0300 Subject: [PATCH 11/11] Version 2.3.21 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8b93babb..4916424b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.songoda skyblock - 2.3.20 + 2.3.21 jar UTF-8