From 11a3bf9227f36131e76284efa4d96c1c1d853807 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 5 Dec 2021 13:46:54 -0800 Subject: [PATCH] Release 1.18.1 (#1886) * Version 1.18.1 * Added snapshot repo to Maven info. * Fixes console teleporting. https://github.com/BentoBoxWorld/BentoBox/issues/1877 * Address potential NPE's * Preveent NPEs and other items. * Remove dead paper forks (#1884) Tuinity has since merged with Paper, and is now not a valid fork Airplane is shutting down / not updating to 1.18.x * Added toString to resolve issue with arrays * Fix minor JavaDoc mistake Co-authored-by: Fredthedoggy <45927799+Fredthedoggy@users.noreply.github.com> --- README.md | 4 + pom.xml | 2 +- .../commands/admin/AdminTeleportCommand.java | 6 +- .../panels/reader/PanelTemplateRecord.java | 52 ++++++- .../worldedit/BlueprintClipboardFormat.java | 136 ------------------ .../worldedit/BlueprintClipboardReader.java | 33 ----- .../worldedit/BlueprintClipboardWriter.java | 32 ----- .../BlueprintSchematicConverter.java | 42 ------ .../bentobox/database/objects/Players.java | 2 +- .../CommandRankClickListener.java | 2 +- .../listeners/flags/settings/PVPListener.java | 4 - .../worldsettings/IslandRespawnListener.java | 10 +- .../bentobox/managers/IslandsManager.java | 17 ++- .../bentobox/managers/PlayersManager.java | 10 +- .../bentobox/managers/island/IslandCache.java | 62 ++++++-- .../panels/BlueprintManagementPanel.java | 40 +++--- .../world/bentobox/bentobox/util/Util.java | 48 +++---- .../versions/ServerCompatibility.java | 2 - .../admin/AdminTeleportCommandTest.java | 19 --- 19 files changed, 173 insertions(+), 350 deletions(-) delete mode 100644 src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardFormat.java delete mode 100644 src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardReader.java delete mode 100644 src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardWriter.java delete mode 100644 src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintSchematicConverter.java diff --git a/README.md b/README.md index 28648010e..8989d0508 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,10 @@ BentoBox uses Maven, and its Maven repository is kindly provided by [CodeMC](htt ### Maven ```xml + + codemc-snapshots + https://repo.codemc.org/repository/maven-snapshots + codemc-repo https://repo.codemc.org/repository/maven-public/ diff --git a/pom.xml b/pom.xml index 7cd32f209..3193a6fae 100644 --- a/pom.xml +++ b/pom.xml @@ -83,7 +83,7 @@ -LOCAL - 1.18.0 + 1.18.1 bentobox-world https://sonarcloud.io diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommand.java index abdeffe81..bb98b9ab4 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommand.java @@ -100,10 +100,9 @@ public class AdminTeleportCommand extends CompositeCommand { // Otherwise, ask the admin to go to a safe spot String failureMessage = user.getTranslation("commands.admin.tp.manual", "[location]", warpSpot.getBlockX() + " " + warpSpot.getBlockY() + " " + warpSpot.getBlockZ()); - - Player player = user.getPlayer(); + // Set the player + Player player = args.size() == 2 ? userToTeleport.getPlayer() : user.getPlayer(); if (args.size() == 2) { - player = userToTeleport.getPlayer(); failureMessage = userToTeleport.getTranslation(NOT_SAFE); } @@ -112,6 +111,7 @@ public class AdminTeleportCommand extends CompositeCommand { .entity(player) .location(warpSpot) .failureMessage(failureMessage) + .thenRun(() -> user.sendMessage("general.success")) .build(); return true; } diff --git a/src/main/java/world/bentobox/bentobox/api/panels/reader/PanelTemplateRecord.java b/src/main/java/world/bentobox/bentobox/api/panels/reader/PanelTemplateRecord.java index f2c48dbf5..2a20c99d0 100644 --- a/src/main/java/world/bentobox/bentobox/api/panels/reader/PanelTemplateRecord.java +++ b/src/main/java/world/bentobox/bentobox/api/panels/reader/PanelTemplateRecord.java @@ -7,6 +7,9 @@ package world.bentobox.bentobox.api.panels.reader; +import java.util.Arrays; +import java.util.Objects; + import org.bukkit.inventory.ItemStack; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; @@ -28,11 +31,11 @@ import world.bentobox.bentobox.api.panels.Panel; * @since 1.17.3 */ public record PanelTemplateRecord(Panel.Type type, - @Nullable String title, - @Nullable TemplateItem border, - @Nullable TemplateItem background, - boolean[] forcedRows, - @NonNull ItemTemplateRecord[][] content) + @Nullable String title, + @Nullable TemplateItem border, + @Nullable TemplateItem background, + boolean[] forcedRows, + @NonNull ItemTemplateRecord[][] content) { /** * Instantiates a new Panel template record with empty content. @@ -76,4 +79,43 @@ public record PanelTemplateRecord(Panel.Type type, this(icon, null, null); } } + + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.deepHashCode(content); + result = prime * result + Arrays.hashCode(forcedRows); + result = prime * result + Objects.hash(background, border, title, type); + return result; + } + + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof PanelTemplateRecord)) { + return false; + } + PanelTemplateRecord other = (PanelTemplateRecord) obj; + return Objects.equals(background, other.background) && Objects.equals(border, other.border) + && Arrays.deepEquals(content, other.content) && Arrays.equals(forcedRows, other.forcedRows) + && Objects.equals(title, other.title) && type == other.type; + } + + + @Override + public String toString() { + return "PanelTemplateRecord {type=" + type + + ", title=" + title + + ", border=" + border + + ", background=" + background + + ", forcedRows=" + Arrays.toString(forcedRows) + + ", content=" + Arrays.toString(content) + "}"; + } + + } diff --git a/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardFormat.java b/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardFormat.java deleted file mode 100644 index 602827df5..000000000 --- a/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardFormat.java +++ /dev/null @@ -1,136 +0,0 @@ -package world.bentobox.bentobox.blueprints.worldedit; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Set; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat; -import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats; -import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader; -import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter; - -import world.bentobox.bentobox.BentoBox; -import world.bentobox.bentobox.blueprints.Blueprint; -import world.bentobox.bentobox.database.json.BentoboxTypeAdapterFactory; - -/** - * @since 1.6.0 - * @author CustomEntity - */ -public class BlueprintClipboardFormat implements ClipboardFormat { - - public BlueprintClipboardFormat() { - ClipboardFormats.registerClipboardFormat(this); - } - - @Override - public String getName() { - return "Blueprint"; - } - - @Override - public Set getAliases() { - return Sets.newHashSet("Bp"); - } - - @Override - public ClipboardReader getReader(InputStream inputStream) { - return new BlueprintClipboardReader(inputStream); - } - - @Override - public ClipboardWriter getWriter(OutputStream outputStream) { - return new BlueprintClipboardWriter(outputStream); - } - - @Override - public boolean isFormat(File file) { - try { - Gson gson = getGson(); - - unzip(file.getAbsolutePath()); - - File unzippedFile = new File(file.getParentFile(), file.getName()); - - return gsonCheck(gson, unzippedFile); - - } catch (IOException e) { - BentoBox.getInstance().logStacktrace(e); - } - return false; - } - - private boolean gsonCheck(Gson gson, File unzippedFile) { - try (FileReader fr = new FileReader(unzippedFile)) { - gson.fromJson(fr, Blueprint.class); - return true; - } catch (Exception e) { - return false; - } - } - - @Override - public String getPrimaryFileExtension() { - return "blueprint"; - } - - @Override - public Set getFileExtensions() { - return ImmutableSet.of("blu", "blueprint"); - } - - private Gson getGson() { - GsonBuilder builder = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().enableComplexMapKeySerialization(); - // Disable <>'s escaping etc. - builder.disableHtmlEscaping(); - // Register adapter factory - builder.registerTypeAdapterFactory(new BentoboxTypeAdapterFactory(BentoBox.getInstance())); - return builder.create(); - } - - private void unzip(final String zipFilePath) throws IOException { - Path path = Paths.get(zipFilePath); - if (!(path.toFile().exists())) { - throw new IOException("No file exists!"); - } - try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFilePath))) { - ZipEntry entry = zipInputStream.getNextEntry(); - while (entry != null) { - Path filePath = Paths.get(path.getParent().toString(), entry.getName()); - if (!entry.isDirectory()) { - unzipFiles(zipInputStream, filePath); - } else { - Files.createDirectories(filePath); - } - - zipInputStream.closeEntry(); - entry = zipInputStream.getNextEntry(); - } - } - } - - private void unzipFiles(final ZipInputStream zipInputStream, final Path unzipFilePath) throws IOException { - try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(unzipFilePath.toAbsolutePath().toString()))) { - byte[] bytesIn = new byte[1024]; - int read; - while ((read = zipInputStream.read(bytesIn)) != -1) { - bos.write(bytesIn, 0, read); - } - } - } -} diff --git a/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardReader.java b/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardReader.java deleted file mode 100644 index c0701ba1f..000000000 --- a/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardReader.java +++ /dev/null @@ -1,33 +0,0 @@ -package world.bentobox.bentobox.blueprints.worldedit; - -import java.io.InputStream; - -import com.sk89q.worldedit.extent.clipboard.Clipboard; -import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader; - -/** - * @since 1.6.0 - * @author CustomEntity - */ -public class BlueprintClipboardReader implements ClipboardReader { - - private final InputStream inputStream; - - public BlueprintClipboardReader(InputStream inputStream) { - this.inputStream = inputStream; - } - - @Override - public Clipboard read() { - throw new UnsupportedOperationException(); // TODO - } - - @Override - public void close() { - throw new UnsupportedOperationException(); // TODO - } - - public InputStream getInputStream() { - return inputStream; - } -} diff --git a/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardWriter.java b/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardWriter.java deleted file mode 100644 index 095ffbf3f..000000000 --- a/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardWriter.java +++ /dev/null @@ -1,32 +0,0 @@ -package world.bentobox.bentobox.blueprints.worldedit; - -import java.io.OutputStream; - -import com.sk89q.worldedit.extent.clipboard.Clipboard; -import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter; - -/** - * @since 1.6.0 - * @author CustomEntity - */ -public class BlueprintClipboardWriter implements ClipboardWriter { - - private final OutputStream outputStream; - - public BlueprintClipboardWriter(OutputStream outputStream) { - this.outputStream = outputStream; - } - @Override - public void write(Clipboard clipboard) { - throw new UnsupportedOperationException(); // TODO - } - - @Override - public void close() { - throw new UnsupportedOperationException(); // TODO - } - - public OutputStream getOutputStream() { - return outputStream; - } -} diff --git a/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintSchematicConverter.java b/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintSchematicConverter.java deleted file mode 100644 index 05c4621a9..000000000 --- a/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintSchematicConverter.java +++ /dev/null @@ -1,42 +0,0 @@ -package world.bentobox.bentobox.blueprints.worldedit; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; - -import com.sk89q.worldedit.extent.clipboard.Clipboard; -import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats; - -import world.bentobox.bentobox.BentoBox; - -/** - * @since 1.6.0 - * @author CustomEntity - */ -public class BlueprintSchematicConverter { - - private File blueprintFile; - - public BlueprintSchematicConverter(File blueprintFile) { - if(BentoBox.getInstance().getHooks().getHook("WorldEdit").isEmpty()) { - BentoBox.getInstance().logError("WorldEdit must be installed to use that class !"); - return; - } - this.blueprintFile = blueprintFile; - } - - public Clipboard convertBlueprintToSchematic() { - Clipboard clipboard = null; - try { - clipboard = ClipboardFormats.findByFile(blueprintFile).getReader(new FileInputStream(blueprintFile)).read(); - } catch (IOException e) { - BentoBox.getInstance().logWarning("Error while trying to convert blueprint format to schematic format."); - BentoBox.getInstance().logStacktrace(e); - } - return clipboard; - } - - public File getBlueprintFile() { - return blueprintFile; - } -} diff --git a/src/main/java/world/bentobox/bentobox/database/objects/Players.java b/src/main/java/world/bentobox/bentobox/database/objects/Players.java index 2a3e6dbb7..7590147cb 100644 --- a/src/main/java/world/bentobox/bentobox/database/objects/Players.java +++ b/src/main/java/world/bentobox/bentobox/database/objects/Players.java @@ -237,7 +237,7 @@ public class Players implements DataObject, MetaDataAble { /** * Clears all home Locations in world * @param world - world - * @deprecated Home locations are no longer stored for players. Use {@link IslandManager} + * @deprecated Home locations are no longer stored for players. Use {@link world.bentobox.bentobox.managers.IslandsManager} */ @Deprecated(since="1.18.0", forRemoval=true) public void clearHomeLocations(World world) { diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandRankClickListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandRankClickListener.java index 201b3ced3..71f0b9461 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandRankClickListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandRankClickListener.java @@ -57,7 +57,7 @@ public class CommandRankClickListener implements ClickHandler { // Get the user's island Island island = plugin.getIslands().getIsland(panel.getWorld().orElse(user.getWorld()), user.getUniqueId()); - if (island == null || !island.getOwner().equals(user.getUniqueId())) { + if (island == null || island.getOwner() == null || !island.getOwner().equals(user.getUniqueId())) { user.sendMessage("general.errors.not-owner"); user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F); return true; diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/settings/PVPListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/settings/PVPListener.java index 23ea9cf5d..28228bfa2 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/settings/PVPListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/settings/PVPListener.java @@ -124,10 +124,6 @@ public class PVPListener extends FlagListener { if (this.PVPAllowed(c.getLocation())) { return; } - // Is PVP allowed here? - if (this.PVPAllowed(e.getCaught().getLocation())) { - return; - } // Protect visitors if (protectedVisitor(c)) { User.getInstance(e.getPlayer()).notify(Flags.INVINCIBLE_VISITORS.getHintReference()); diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/IslandRespawnListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/IslandRespawnListener.java index 8a0c32618..1c8196716 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/IslandRespawnListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/IslandRespawnListener.java @@ -60,10 +60,12 @@ public class IslandRespawnListener extends FlagListener { if (world == null) { return; // world no longer available } - - final Location respawnLocation = getIslands().getSafeHomeLocation(Util.getWorld(world), User.getInstance(e.getPlayer().getUniqueId()), ""); - if (respawnLocation != null) { - e.setRespawnLocation(respawnLocation); + World w = Util.getWorld(world); + if (w != null) { + final Location respawnLocation = getIslands().getSafeHomeLocation(w, User.getInstance(e.getPlayer().getUniqueId()), ""); + if (respawnLocation != null) { + e.setRespawnLocation(respawnLocation); + } } // Run respawn commands, if any Util.runCommands(User.getInstance(e.getPlayer()), getIWM().getOnRespawnCommands(world), "respawn"); diff --git a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java index 7a0931f04..e5f51af6f 100644 --- a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java @@ -512,7 +512,7 @@ public class IslandsManager { int islandMax = island.getMaxMembers(rank) == null ? worldDefault : island.getMaxMembers(rank); // Update based on owner permissions if online - if (Bukkit.getPlayer(island.getOwner()) != null) { + if (island.getOwner() != null && Bukkit.getPlayer(island.getOwner()) != null) { User owner = User.getInstance(island.getOwner()); islandMax = owner.getPermissionValue(plugin.getIWM().getPermissionPrefix(island.getWorld()) + perm, islandMax); @@ -544,7 +544,7 @@ public class IslandsManager { public int getMaxHomes(@NonNull Island island) { int islandMax = island.getMaxHomes() == null ? plugin.getIWM().getMaxHomes(island.getWorld()) : island.getMaxHomes(); // Update based on owner permissions if online - if (Bukkit.getPlayer(island.getOwner()) != null) { + if (island.getOwner() != null && Bukkit.getPlayer(island.getOwner()) != null) { User owner = User.getInstance(island.getOwner()); islandMax = owner.getPermissionValue(plugin.getIWM().getPermissionPrefix(island.getWorld()) + "island.maxhomes", islandMax); @@ -705,10 +705,13 @@ public class IslandsManager { return l; } else { // try owner's home - Location tlh = getHomeLocation(world, getOwner(world, user.getUniqueId())); - if (tlh != null && isSafeLocation(tlh)) { - setHomeLocation(user, tlh, name); - return tlh; + UUID owner = getOwner(world, user.getUniqueId()); + if (owner != null) { + Location tlh = getHomeLocation(world, owner); + if (tlh != null && isSafeLocation(tlh)) { + setHomeLocation(user, tlh, name); + return tlh; + } } } } else { @@ -874,7 +877,7 @@ public class IslandsManager { // No migration required return; } - if (island.getOwner().equals(uuid)) { + if (island.getOwner() != null && island.getOwner().equals(uuid)) { // Owner island.setHomes(homes.entrySet().stream().collect(Collectors.toMap(this::getHomeName, Map.Entry::getKey))); plugin.getPlayers().clearHomeLocations(world, uuid); diff --git a/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java b/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java index c43702250..6b1baf3b3 100644 --- a/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java @@ -555,7 +555,10 @@ public class PlayersManager { if (target.isOnline()) { target.getPlayer().getEnderChest().clear(); } else { - getPlayer(target.getUniqueId()).addToPendingKick(world); + Players p = getPlayer(target.getUniqueId()); + if (p != null) { + p.addToPendingKick(world); + } } } if ((kicked && plugin.getIWM().isOnLeaveResetInventory(world) && !plugin.getIWM().isKickedKeepInventory(world)) @@ -563,7 +566,10 @@ public class PlayersManager { if (target.isOnline()) { target.getPlayer().getInventory().clear(); } else { - getPlayer(target.getUniqueId()).addToPendingKick(world); + Players p = getPlayer(target.getUniqueId()); + if (p != null) { + p.addToPendingKick(world); + } } } diff --git a/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java b/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java index a577d601d..976266070 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java @@ -5,6 +5,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.UUID; @@ -141,7 +142,11 @@ public class IslandCache { */ @Nullable public Island get(@NonNull World world, @NonNull UUID uuid) { - return islandsByUUID.containsKey(Util.getWorld(world)) ? islandsByUUID.get(Util.getWorld(world)).get(uuid) : null; + World w = Util.getWorld(world); + if (w == null) { + return null; + } + return islandsByUUID.containsKey(w) ? islandsByUUID.get(w).get(uuid) : null; } /** @@ -153,10 +158,11 @@ public class IslandCache { */ @Nullable public Island getIslandAt(@NonNull Location location) { - if (!grids.containsKey(Util.getWorld(location.getWorld()))) { + World w = Util.getWorld(location.getWorld()); + if (w == null || !grids.containsKey(w)) { return null; } - return grids.get(Util.getWorld(location.getWorld())).getIslandAt(location.getBlockX(), location.getBlockZ()); + return grids.get(w).getIslandAt(location.getBlockX(), location.getBlockZ()); } /** @@ -177,7 +183,9 @@ public class IslandCache { @NonNull public Collection getIslands(@NonNull World world) { World overworld = Util.getWorld(world); - + if (overworld == null) { + return Collections.emptyList(); + } return islandsByLocation.entrySet().stream() .filter(entry -> overworld.equals(Util.getWorld(entry.getKey().getWorld()))) // shouldn't make NPEs .map(Map.Entry::getValue).toList(); @@ -191,7 +199,11 @@ public class IslandCache { */ @NonNull public Set getMembers(@NonNull World world, @NonNull UUID uuid, int minimumRank) { - Island island = islandsByUUID.computeIfAbsent(Util.getWorld(world), k -> new HashMap<>()).get(uuid); + World w = Util.getWorld(world); + if (w == null) { + return new HashSet<>(); + } + Island island = islandsByUUID.computeIfAbsent(w, k -> new HashMap<>()).get(uuid); return island != null ? island.getMemberSet(minimumRank) : new HashSet<>(); } @@ -202,7 +214,11 @@ public class IslandCache { */ @Nullable public UUID getOwner(@NonNull World world, @NonNull UUID uuid) { - Island island = islandsByUUID.computeIfAbsent(Util.getWorld(world), k -> new HashMap<>()).get(uuid); + World w = Util.getWorld(world); + if (w == null) { + return null; + } + Island island = islandsByUUID.computeIfAbsent(w, k -> new HashMap<>()).get(uuid); return island != null ? island.getOwner() : null; } @@ -213,7 +229,11 @@ public class IslandCache { * @return true if player has island and owns it */ public boolean hasIsland(@NonNull World world, @NonNull UUID uuid) { - Island island = islandsByUUID.computeIfAbsent(Util.getWorld(world), k -> new HashMap<>()).get(uuid); + World w = Util.getWorld(world); + if (w == null) { + return false; + } + Island island = islandsByUUID.computeIfAbsent(w, k -> new HashMap<>()).get(uuid); return island != null && uuid.equals(island.getOwner()); } @@ -226,7 +246,11 @@ public class IslandCache { */ @Nullable public Island removePlayer(@NonNull World world, @NonNull UUID uuid) { - Island island = islandsByUUID.computeIfAbsent(Util.getWorld(world), k -> new HashMap<>()).get(uuid); + World w = Util.getWorld(world); + if (w == null) { + return null; + } + Island island = islandsByUUID.computeIfAbsent(w, k -> new HashMap<>()).get(uuid); if (island != null) { if (uuid.equals(island.getOwner())) { // Clear ownership and members @@ -237,7 +261,7 @@ public class IslandCache { island.removeMember(uuid); } } - islandsByUUID.get(world).remove(uuid); + islandsByUUID.get(w).remove(uuid); return island; } @@ -267,7 +291,7 @@ public class IslandCache { public void setOwner(@NonNull Island island, @Nullable UUID newOwnerUUID) { island.setOwner(newOwnerUUID); if (newOwnerUUID != null) { - islandsByUUID.computeIfAbsent(Util.getWorld(island.getWorld()), k -> new HashMap<>()).put(newOwnerUUID, island); + islandsByUUID.computeIfAbsent(Objects.requireNonNull(Util.getWorld(island.getWorld())), k -> new HashMap<>()).put(newOwnerUUID, island); } islandsByLocation.put(island.getCenter(), island); islandsById.put(island.getUniqueId(), island); @@ -292,11 +316,15 @@ public class IslandCache { public void removeIsland(@NonNull Island island) { islandsByLocation.values().removeIf(island::equals); islandsById.values().removeIf(island::equals); - if (islandsByUUID.containsKey(Util.getWorld(island.getWorld()))) { - islandsByUUID.get(Util.getWorld(island.getWorld())).values().removeIf(island::equals); + World w = Util.getWorld(island.getWorld()); + if (w == null) { + return; } - if (grids.containsKey(Util.getWorld(island.getWorld()))) { - grids.get(Util.getWorld(island.getWorld())).removeFromGrid(island); + if (islandsByUUID.containsKey(w)) { + islandsByUUID.get(w).values().removeIf(island::equals); + } + if (grids.containsKey(w)) { + grids.get(w).removeFromGrid(island); } } @@ -307,6 +335,9 @@ public class IslandCache { */ public void resetAllFlags(World world) { World w = Util.getWorld(world); + if (w == null) { + return; + } islandsById.values().stream().filter(i -> i.getWorld().equals(w)).forEach(Island::setFlagsDefaults); } @@ -318,6 +349,9 @@ public class IslandCache { */ public void resetFlag(World world, Flag flag) { World w = Util.getWorld(world); + if (w == null) { + return; + } int setting = BentoBox.getInstance().getIWM().getDefaultIslandFlags(w).getOrDefault(flag, flag.getDefaultRank()); islandsById.values().stream().filter(i -> i.getWorld().equals(w)).forEach(i -> i.setFlag(flag, setting)); } diff --git a/src/main/java/world/bentobox/bentobox/panels/BlueprintManagementPanel.java b/src/main/java/world/bentobox/bentobox/panels/BlueprintManagementPanel.java index cee6b2d2f..cca3b030a 100644 --- a/src/main/java/world/bentobox/bentobox/panels/BlueprintManagementPanel.java +++ b/src/main/java/world/bentobox/bentobox/panels/BlueprintManagementPanel.java @@ -183,7 +183,7 @@ public class BlueprintManagementPanel { // Toggle permission - default is always allowed pb.item(39, getNoPermissionIcon()); } else { - // Panel has a Trash icon. If right clicked it is discarded + // Panel has a Trash icon. If right clicked it is discarded pb.item(36, getTrashIcon(addon, bb)); // Toggle permission - default is always allowed pb.item(39, getPermissionIcon(addon, bb)); @@ -256,22 +256,22 @@ public class BlueprintManagementPanel { Material icon; String worldName; switch (env) { - case NORMAL -> { - icon = Material.GRASS_BLOCK; - worldName = normalBlueprint.getName(); - } - case NETHER -> { - icon = Material.NETHERRACK; - worldName = netherBlueprint.getName(); - } - case THE_END -> { - icon = Material.END_STONE; - worldName = endBlueprint.getName(); - } - default -> { - icon = Material.STONE; - worldName = Util.prettifyText(env.name()); - } + case NORMAL -> { + icon = Material.GRASS_BLOCK; + worldName = normalBlueprint.getName(); + } + case NETHER -> { + icon = Material.NETHERRACK; + worldName = netherBlueprint.getName(); + } + case THE_END -> { + icon = Material.END_STONE; + worldName = endBlueprint.getName(); + } + default -> { + icon = Material.STONE; + worldName = Util.prettifyText(env.name()); + } } return new PanelItemBuilder() @@ -297,7 +297,7 @@ public class BlueprintManagementPanel { }) .build(); } - + private PanelItem getNoTrashIcon() { return new PanelItemBuilder() .name(t("no-trash")) @@ -321,7 +321,7 @@ public class BlueprintManagementPanel { return true; }).build(); } - + private PanelItem getNoPermissionIcon() { return new PanelItemBuilder().icon(Material.PAINTING).name(t("no-permission")) .description(t("no-perm-required")) @@ -350,7 +350,7 @@ public class BlueprintManagementPanel { return new PanelItemBuilder() .name(blueprint.getDisplayName() == null ? blueprint.getName() : blueprint.getDisplayName()) .description(desc) - .icon(blueprint.getIcon() == null ? Material.PAPER : blueprint.getIcon()) + .icon(blueprint.getIcon()) .glow(selected != null && pos == selected.getKey()) .clickHandler((panel, u, clickType, slot) -> { // Handle the world squares diff --git a/src/main/java/world/bentobox/bentobox/util/Util.java b/src/main/java/world/bentobox/bentobox/util/Util.java index 953952dcb..cc09d2b53 100644 --- a/src/main/java/world/bentobox/bentobox/util/Util.java +++ b/src/main/java/world/bentobox/bentobox/util/Util.java @@ -238,7 +238,7 @@ public class Util { /** * Convert world to an overworld * @param world - world - * @return over world + * @return over world or null if world is null or a world cannot be found */ @Nullable public static World getWorld(@Nullable World world) { @@ -284,21 +284,21 @@ public class Util { */ public static float blockFaceToFloat(BlockFace face) { return switch (face) { - case EAST -> 90F; - case EAST_NORTH_EAST -> 67.5F; - case NORTH_EAST -> 45F; - case NORTH_NORTH_EAST -> 22.5F; - case NORTH_NORTH_WEST -> 337.5F; - case NORTH_WEST -> 315F; - case SOUTH -> 180F; - case SOUTH_EAST -> 135F; - case SOUTH_SOUTH_EAST -> 157.5F; - case SOUTH_SOUTH_WEST -> 202.5F; - case SOUTH_WEST -> 225F; - case WEST -> 270F; - case WEST_NORTH_WEST -> 292.5F; - case WEST_SOUTH_WEST -> 247.5F; - default -> 0F; + case EAST -> 90F; + case EAST_NORTH_EAST -> 67.5F; + case NORTH_EAST -> 45F; + case NORTH_NORTH_EAST -> 22.5F; + case NORTH_NORTH_WEST -> 337.5F; + case NORTH_WEST -> 315F; + case SOUTH -> 180F; + case SOUTH_EAST -> 135F; + case SOUTH_SOUTH_EAST -> 157.5F; + case SOUTH_SOUTH_WEST -> 202.5F; + case SOUTH_WEST -> 225F; + case WEST -> 270F; + case WEST_NORTH_WEST -> 292.5F; + case WEST_SOUTH_WEST -> 247.5F; + default -> 0F; }; } @@ -548,21 +548,21 @@ public class Util { if (group.length() == 6) { // Parses #ffffff to a color text. matcher.appendReplacement(buffer, ChatColor.COLOR_CHAR + "x" - + ChatColor.COLOR_CHAR + group.charAt(0) + ChatColor.COLOR_CHAR + group.charAt(1) - + ChatColor.COLOR_CHAR + group.charAt(2) + ChatColor.COLOR_CHAR + group.charAt(3) - + ChatColor.COLOR_CHAR + group.charAt(4) + ChatColor.COLOR_CHAR + group.charAt(5)); + + ChatColor.COLOR_CHAR + group.charAt(0) + ChatColor.COLOR_CHAR + group.charAt(1) + + ChatColor.COLOR_CHAR + group.charAt(2) + ChatColor.COLOR_CHAR + group.charAt(3) + + ChatColor.COLOR_CHAR + group.charAt(4) + ChatColor.COLOR_CHAR + group.charAt(5)); } else { // Parses #fff to a color text. matcher.appendReplacement(buffer, ChatColor.COLOR_CHAR + "x" - + ChatColor.COLOR_CHAR + group.charAt(0) + ChatColor.COLOR_CHAR + group.charAt(0) - + ChatColor.COLOR_CHAR + group.charAt(1) + ChatColor.COLOR_CHAR + group.charAt(1) - + ChatColor.COLOR_CHAR + group.charAt(2) + ChatColor.COLOR_CHAR + group.charAt(2)); + + ChatColor.COLOR_CHAR + group.charAt(0) + ChatColor.COLOR_CHAR + group.charAt(0) + + ChatColor.COLOR_CHAR + group.charAt(1) + ChatColor.COLOR_CHAR + group.charAt(1) + + ChatColor.COLOR_CHAR + group.charAt(2) + ChatColor.COLOR_CHAR + group.charAt(2)); } } // transform normal codes and strip spaces after color code. return Util.stripSpaceAfterColorCodes( - ChatColor.translateAlternateColorCodes('&', matcher.appendTail(buffer).toString())); + ChatColor.translateAlternateColorCodes('&', matcher.appendTail(buffer).toString())); } @@ -717,7 +717,7 @@ public class Util { throw new IllegalStateException("Class " + clazz.getName() + " does not implement NMSAbstraction"); } } - + /** * Broadcast a localized message to all players with the permission {@link Server#BROADCAST_CHANNEL_USERS} * diff --git a/src/main/java/world/bentobox/bentobox/versions/ServerCompatibility.java b/src/main/java/world/bentobox/bentobox/versions/ServerCompatibility.java index fb966c959..d29b4b849 100644 --- a/src/main/java/world/bentobox/bentobox/versions/ServerCompatibility.java +++ b/src/main/java/world/bentobox/bentobox/versions/ServerCompatibility.java @@ -75,8 +75,6 @@ public class ServerCompatibility { GLOWSTONE(Compatibility.INCOMPATIBLE), SPIGOT(Compatibility.COMPATIBLE), PAPER(Compatibility.SUPPORTED), - TUINITY(Compatibility.SUPPORTED), - AIRPLANE(Compatibility.SUPPORTED), PURPUR(Compatibility.SUPPORTED), TACOSPIGOT(Compatibility.NOT_SUPPORTED), AKARIN(Compatibility.NOT_SUPPORTED), diff --git a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommandTest.java index 71960c644..9d692be09 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommandTest.java @@ -283,24 +283,5 @@ public class AdminTeleportCommandTest { verify(user).getTranslation(eq("commands.admin.tp.manual"), eq("[location]"), eq("0 0 0")); } - - - - - - - - - - - - - - - - - - - }