From 4cda8a92928487b06ce71bd51b97230cd3cf6a74 Mon Sep 17 00:00:00 2001 From: Thijs Wiefferink Date: Sun, 23 Jun 2019 21:53:48 +0200 Subject: [PATCH] Fix sign handling for 1.14 - Setup modules to load different classes for different Bukkit/Spigot versions - Create BukkitHandler to get/set the sign facing and get the block it is attached to - Fix `/as addsign` to use new sign methods - Fix sign updates to use new sign methods - Implement full forwards and backwards compatibility of the saved sign material type - On Bukkit 1.12 and lower all special wood types are translated to the standard sign - On Bukkit 1.13 the internal sign name is translated (and special wood types to the standard one) - On Bukkit 1.14 the signs of 1.13- are translated to the OAK variants - Cleanup the .gitignore files inside of the module folders --- .gitignore | 2 +- AreaShop/.gitignore | 1 - AreaShop/pom.xml | 20 +++- .../java/me/wiefferink/areashop/AreaShop.java | 43 ++++++-- .../areashop/commands/AddsignCommand.java | 4 +- .../areashop/features/signs/RegionSign.java | 53 +++++----- .../areashop/features/signs/SignsFeature.java | 90 +++++++++------- .../areashop/managers/SignLinkerManager.java | 4 +- .../wiefferink/areashop/tools/Materials.java | 100 ++++++++++++++---- areashop-bukkit-1_12/pom.xml | 33 ++++++ .../areashop/handlers/BukkitHandler1_12.java | 76 +++++++++++++ areashop-bukkit-1_13/pom.xml | 31 ++++++ .../areashop/handlers/BukkitHandler1_13.java | 97 +++++++++++++++++ areashop-fastasyncworldedit/.gitignore | 1 - areashop-interface/.gitignore | 1 - .../areashop/interfaces/BukkitInterface.java | 35 ++++++ .../interfaces/WorldEditInterface.java | 24 ++++- areashop-worldedit-5/.gitignore | 1 - areashop-worldedit-6/.gitignore | 1 - areashop-worldedit-7_beta_1/.gitignore | 1 - areashop-worldedit-7_beta_4/.gitignore | 1 - areashop-worldguard-5/.gitignore | 1 - areashop-worldguard-6/.gitignore | 1 - areashop-worldguard-6_1_3/.gitignore | 1 - areashop-worldguard-7_beta_1/.gitignore | 1 - areashop-worldguard-7_beta_2/.gitignore | 1 - pom.xml | 2 + 27 files changed, 505 insertions(+), 121 deletions(-) delete mode 100644 AreaShop/.gitignore create mode 100644 areashop-bukkit-1_12/pom.xml create mode 100644 areashop-bukkit-1_12/src/main/java/me/wiefferink/areashop/handlers/BukkitHandler1_12.java create mode 100644 areashop-bukkit-1_13/pom.xml create mode 100644 areashop-bukkit-1_13/src/main/java/me/wiefferink/areashop/handlers/BukkitHandler1_13.java delete mode 100644 areashop-fastasyncworldedit/.gitignore delete mode 100644 areashop-interface/.gitignore create mode 100644 areashop-interface/src/main/java/me/wiefferink/areashop/interfaces/BukkitInterface.java delete mode 100644 areashop-worldedit-5/.gitignore delete mode 100644 areashop-worldedit-6/.gitignore delete mode 100644 areashop-worldedit-7_beta_1/.gitignore delete mode 100644 areashop-worldedit-7_beta_4/.gitignore delete mode 100644 areashop-worldguard-5/.gitignore delete mode 100644 areashop-worldguard-6/.gitignore delete mode 100644 areashop-worldguard-6_1_3/.gitignore delete mode 100644 areashop-worldguard-7_beta_1/.gitignore delete mode 100644 areashop-worldguard-7_beta_2/.gitignore diff --git a/.gitignore b/.gitignore index ee151fa..178ec35 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ # Maven stuff -/target +target .project .metadata diff --git a/AreaShop/.gitignore b/AreaShop/.gitignore deleted file mode 100644 index ea8c4bf..0000000 --- a/AreaShop/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/AreaShop/pom.xml b/AreaShop/pom.xml index 4d19c83..fa1894e 100644 --- a/AreaShop/pom.xml +++ b/AreaShop/pom.xml @@ -17,9 +17,7 @@ org.bukkit craftbukkit - system - any - ${project.basedir}/../dependencies/craftbukkit-1.7.9-R0.2-SNAPSHOT.jar + 1.14.2-R0.1-SNAPSHOT jar true @@ -63,6 +61,22 @@ compile + + + me.wiefferink + areashop-bukkit-1_12 + latest + jar + compile + + + me.wiefferink + areashop-bukkit-1_13 + latest + jar + compile + + me.wiefferink diff --git a/AreaShop/src/main/java/me/wiefferink/areashop/AreaShop.java b/AreaShop/src/main/java/me/wiefferink/areashop/AreaShop.java index 89bb2eb..e567019 100644 --- a/AreaShop/src/main/java/me/wiefferink/areashop/AreaShop.java +++ b/AreaShop/src/main/java/me/wiefferink/areashop/AreaShop.java @@ -4,6 +4,7 @@ import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.sk89q.worldguard.protection.managers.RegionManager; import me.wiefferink.areashop.interfaces.AreaShopInterface; +import me.wiefferink.areashop.interfaces.BukkitInterface; import me.wiefferink.areashop.interfaces.WorldEditInterface; import me.wiefferink.areashop.interfaces.WorldGuardInterface; import me.wiefferink.areashop.listeners.PlayerLoginLogoutListener; @@ -54,6 +55,7 @@ public final class AreaShop extends JavaPlugin implements AreaShopInterface { private WorldGuardInterface worldGuardInterface = null; private WorldEditPlugin worldEdit = null; private WorldEditInterface worldEditInterface = null; + private BukkitInterface bukkitInterface = null; private FileManager fileManager = null; private LanguageManager languageManager = null; private CommandManager commandManager = null; @@ -294,12 +296,12 @@ public final class AreaShop extends JavaPlugin implements AreaShopInterface { // Load WorldEdit try { - final Class clazz = Class.forName("me.wiefferink.areashop.handlers." + weVersion); + Class clazz = Class.forName("me.wiefferink.areashop.handlers." + weVersion); // Check if we have a NMSHandler class at that location. if(WorldEditInterface.class.isAssignableFrom(clazz)) { // Make sure it actually implements WorldEditInterface worldEditInterface = (WorldEditInterface)clazz.getConstructor(AreaShopInterface.class).newInstance(this); // Set our handler } - } catch(final Exception e) { + } catch(Exception e) { error("Could not load the handler for WorldEdit (tried to load " + weVersion + "), report this problem to the author: " + ExceptionUtils.getStackTrace(e)); error = true; weVersion = null; @@ -307,17 +309,35 @@ public final class AreaShop extends JavaPlugin implements AreaShopInterface { // Load WorldGuard try { - final Class clazz = Class.forName("me.wiefferink.areashop.handlers." + wgVersion); + Class clazz = Class.forName("me.wiefferink.areashop.handlers." + wgVersion); // Check if we have a NMSHandler class at that location. if(WorldGuardInterface.class.isAssignableFrom(clazz)) { // Make sure it actually implements WorldGuardInterface worldGuardInterface = (WorldGuardInterface)clazz.getConstructor(AreaShopInterface.class).newInstance(this); // Set our handler } - } catch(final Exception e) { + } catch(Exception e) { error("Could not load the handler for WorldGuard (tried to load " + wgVersion + "), report this problem to the author:" + ExceptionUtils.getStackTrace(e)); error = true; wgVersion = null; } + // Load Bukkit implementation + String bukkitHandler; + try { + Class.forName("org.bukkit.block.data.type.WallSign"); + bukkitHandler = "1_13"; + } catch (ClassNotFoundException e) { + bukkitHandler = "1_12"; + } + + try { + Class clazz = Class.forName("me.wiefferink.areashop.handlers.BukkitHandler" + bukkitHandler); + bukkitInterface = (BukkitInterface)clazz.getConstructor(AreaShopInterface.class).newInstance(this); + } catch (Exception e) { + error("Could not load the Bukkit handler (used for sign updates), tried to load:", bukkitHandler + ", report this problem to the author:", ExceptionUtils.getStackTrace(e)); + error = true; + bukkitHandler = null; + } + // Check if Vault is present if(getServer().getPluginManager().getPlugin("Vault") == null) { error("Vault plugin is not present or has not loaded correctly"); @@ -332,10 +352,13 @@ public final class AreaShop extends JavaPlugin implements AreaShopInterface { // Print loaded version of WG and WE in debug if(wgVersion != null) { - AreaShop.debug("Loaded WorldGuardHandler", wgVersion, "(raw version:" + rawWgVersion + ", major:" + major + ", minor:" + minor + ", fixes:" + fixes + ", build:" + build + ")"); + AreaShop.debug("Loaded ", wgVersion, "(raw version:" + rawWgVersion + ", major:" + major + ", minor:" + minor + ", fixes:" + fixes + ", build:" + build + ", fawe:" + fawe + ")"); } if(weVersion != null) { - AreaShop.debug("Loaded WorldEditHandler", weVersion, "(raw version:" + rawWeVersion + ", beta:" + weBeta + ")"); + AreaShop.debug("Loaded ", weVersion, "(raw version:" + rawWeVersion + ", beta:" + weBeta + ")"); + } + if(bukkitHandler != null) { + AreaShop.debug("Loaded BukkitHandler", bukkitHandler); } setupLanguageManager(); @@ -550,6 +573,14 @@ public final class AreaShop extends JavaPlugin implements AreaShopInterface { return languageManager; } + /** + * Get the BukkitHandler, for sign interactions. + * @return BukkitHandler + */ + public BukkitInterface getBukkitHandler() { + return this.bukkitInterface; + } + /** * Function to get the CommandManager. * @return the CommandManager diff --git a/AreaShop/src/main/java/me/wiefferink/areashop/commands/AddsignCommand.java b/AreaShop/src/main/java/me/wiefferink/areashop/commands/AddsignCommand.java index 5e106b1..a8a6643 100644 --- a/AreaShop/src/main/java/me/wiefferink/areashop/commands/AddsignCommand.java +++ b/AreaShop/src/main/java/me/wiefferink/areashop/commands/AddsignCommand.java @@ -9,7 +9,6 @@ import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import org.bukkit.material.Sign; import org.bukkit.util.BlockIterator; import java.util.ArrayList; @@ -77,7 +76,6 @@ public class AddsignCommand extends CommandAreaShop { } region = regions.get(0); } - Sign sign = (Sign)block.getState().getData(); String profile = null; if(args.length > 2) { profile = args[2]; @@ -93,7 +91,7 @@ public class AddsignCommand extends CommandAreaShop { return; } - region.getSignsFeature().addSign(block.getLocation(), block.getType(), sign.getFacing(), profile); + region.getSignsFeature().addSign(block.getLocation(), block.getType(), plugin.getBukkitHandler().getSignFacing(block), profile); if(profile == null) { plugin.message(sender, "addsign-success", region); } else { diff --git a/AreaShop/src/main/java/me/wiefferink/areashop/features/signs/RegionSign.java b/AreaShop/src/main/java/me/wiefferink/areashop/features/signs/RegionSign.java index 0ea92b7..2ccfaeb 100644 --- a/AreaShop/src/main/java/me/wiefferink/areashop/features/signs/RegionSign.java +++ b/AreaShop/src/main/java/me/wiefferink/areashop/features/signs/RegionSign.java @@ -84,7 +84,7 @@ public class RegionSign { } /** - * Get the facing of the sign. + * Get the facing of the sign as saved in the config. * @return BlockFace the sign faces, or null if unknown */ public BlockFace getFacing() { @@ -96,17 +96,13 @@ public class RegionSign { } /** - * Get the material of the sign. - * @return Material of the sign, normally {@link Material#WALL_SIGN} or {@link Material#SIGN_POST}, but could be something else or null. + * Get the material of the sign as saved in the config. + * @return Material of the sign, usually {@link Material#OAK_WALL_SIGN}, {@link Material#OAK_SIGN}, or one of the other wood types (different result for 1.13-), Material.AIR if none. */ public Material getMaterial() { String name = getRegion().getConfig().getString("general.signs." + key + ".signType"); - if ("WALL_SIGN".equals(name)) { - return Materials.wallSign; - } else if ("SIGN_POST".equals(name) || "SIGN".equals(name)) { - return Materials.floorSign; - } - return null; + Material result = Materials.signNameToMaterial(name); + return result == null ? Material.AIR : result; } /** @@ -149,40 +145,34 @@ public class RegionSign { } // Place the sign back (with proper rotation and type) after it has been hidden or (indirectly) destroyed - Sign signState = null; if(!Materials.isSign(block.getType())) { Material signType = getMaterial(); - block.setType(signType); + // Don't do physics here, we first need to update the direction + block.setType(signType, false); + + // This triggers a physics update, which pops the sign if not attached properly + if (!AreaShop.getInstance().getBukkitHandler().setSignFacing(block, getFacing())) { + AreaShop.warn("Failed to update the facing direction of the sign at", getStringLocation(), "to ", getFacing(), ", region:", getRegion().getName()); + } + + // Check if the sign has popped if(!Materials.isSign(block.getType())) { - AreaShop.debug("Setting sign", key, "of region", getRegion().getName(), "failed, could not set sign block back"); + AreaShop.warn("Setting sign", key, "of region", getRegion().getName(), "failed, could not set sign block back"); return false; } - signState = (Sign) block.getState(); - org.bukkit.material.Sign signData = (org.bukkit.material.Sign)signState.getData(); - BlockFace signFace = getFacing(); - if(signFace != null) { - signData.setFacingDirection(signFace); - signState.setData(signData); - } - } - if(signState == null) { - signState = (Sign) block.getState(); } // Save current rotation and type - org.bukkit.material.Sign signData = (org.bukkit.material.Sign)signState.getData(); if(!regionConfig.isString("general.signs." + key + ".signType")) { - String signType = signState.getType().name(); - if (signType.equals("SIGN")) { - signType = "SIGN_POST"; // Save with a backwards-compatible name - } - getRegion().setSetting("general.signs." + key + ".signType", signType); + getRegion().setSetting("general.signs." + key + ".signType", block.getType().name()); } if(!regionConfig.isString("general.signs." + key + ".facing")) { - getRegion().setSetting("general.signs." + key + ".facing", signData.getFacing().toString()); + BlockFace signFacing = AreaShop.getInstance().getBukkitHandler().getSignFacing(block); + getRegion().setSetting("general.signs." + key + ".facing", signFacing == null ? null : signFacing.toString()); } // Apply replacements and color and then set it on the sign + Sign signState = (Sign) block.getState(); for(int i = 0; i < signLines.length; i++) { if(signLines[i] == null) { signState.setLine(i, ""); @@ -205,7 +195,12 @@ public class RegionSign { if(signConfig == null || !signConfig.isSet(getRegion().getState().getValue().toLowerCase())) { return false; } + ConfigurationSection stateConfig = signConfig.getConfigurationSection(getRegion().getState().getValue().toLowerCase()); + if(stateConfig == null) { + return false; + } + // Check the lines for the timeleft tag for(int i = 1; i <= 4; i++) { String line = stateConfig.getString("line" + i); diff --git a/AreaShop/src/main/java/me/wiefferink/areashop/features/signs/SignsFeature.java b/AreaShop/src/main/java/me/wiefferink/areashop/features/signs/SignsFeature.java index 1238476..6382c72 100644 --- a/AreaShop/src/main/java/me/wiefferink/areashop/features/signs/SignsFeature.java +++ b/AreaShop/src/main/java/me/wiefferink/areashop/features/signs/SignsFeature.java @@ -28,7 +28,6 @@ import org.bukkit.event.block.BlockPhysicsEvent; import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.world.ChunkLoadEvent; -import org.bukkit.material.Sign; import java.util.ArrayList; import java.util.Collections; @@ -116,20 +115,19 @@ public class SignsFeature extends RegionFeature { } // Check if still attached to a block - Block b = event.getBlock(); - Sign s = (Sign) b.getState().getData(); - Block attachedBlock = b.getRelative(s.getAttachedFace()); + Block attachedBlock = plugin.getBukkitHandler().getSignAttachedTo(event.getBlock()); + // TODO: signs cannot be placed on all blocks, improve this check to isSolid()? if (attachedBlock.getType() != Material.AIR) { return; } - // Check if the rent sign is really the same as a saved rent + // Check if the sign is really the same as a saved rent RegionSign regionSign = SignsFeature.getSignByLocation(event.getBlock().getLocation()); if(regionSign == null) { return; } - // Remove the sign so that it does not fall on the floor as an item (next region update will place it back) + // Remove the sign so that it does not fall on the floor as an item (next region update will place it back when possible) AreaShop.debug("onIndirectSignBreak: Removed block of sign for", regionSign.getRegion().getName(), "at", regionSign.getStringLocation()); event.getBlock().setType(Material.AIR); event.setCancelled(true); @@ -138,34 +136,48 @@ public class SignsFeature extends RegionFeature { @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onSignClick(PlayerInteractEvent event) { Block block = event.getClickedBlock(); - // Check for clicking a sign and rightclicking - if((event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_BLOCK) - && Materials.isSign(block.getType())) { - // Check if the rent sign is really the same as a saved rent - RegionSign regionSign = SignsFeature.getSignByLocation(block.getLocation()); - if(regionSign == null) { - return; - } - Player player = event.getPlayer(); - if(plugin.getSignlinkerManager().isInSignLinkMode(player)) { - return; - } - // Get the clicktype - GeneralRegion.ClickType clickType = null; - if(player.isSneaking() && event.getAction() == Action.LEFT_CLICK_BLOCK) { - clickType = GeneralRegion.ClickType.SHIFTLEFTCLICK; - } else if(!player.isSneaking() && event.getAction() == Action.LEFT_CLICK_BLOCK) { - clickType = GeneralRegion.ClickType.LEFTCLICK; - } else if(player.isSneaking() && event.getAction() == Action.RIGHT_CLICK_BLOCK) { - clickType = GeneralRegion.ClickType.SHIFTRIGHTCLICK; - } else if(!player.isSneaking() && event.getAction() == Action.RIGHT_CLICK_BLOCK) { - clickType = GeneralRegion.ClickType.RIGHTCLICK; - } - // Run the commands - boolean ran = regionSign.runSignCommands(player, clickType); - // Only cancel event if at least one command has been executed - event.setCancelled(ran); + if (block == null) { + return; } + + // Only listen to left and right clicks on blocks + if (!(event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_BLOCK)) { + return; + } + + // Only care about clicking blocks + if(!Materials.isSign(block.getType())) { + return; + } + + // Check if this sign belongs to a region + RegionSign regionSign = SignsFeature.getSignByLocation(block.getLocation()); + if(regionSign == null) { + return; + } + + // Ignore players that are in sign link mode (which will handle the event itself) + Player player = event.getPlayer(); + if(plugin.getSignlinkerManager().isInSignLinkMode(player)) { + return; + } + + // Get the clicktype + GeneralRegion.ClickType clickType = null; + if(player.isSneaking() && event.getAction() == Action.LEFT_CLICK_BLOCK) { + clickType = GeneralRegion.ClickType.SHIFTLEFTCLICK; + } else if(!player.isSneaking() && event.getAction() == Action.LEFT_CLICK_BLOCK) { + clickType = GeneralRegion.ClickType.LEFTCLICK; + } else if(player.isSneaking() && event.getAction() == Action.RIGHT_CLICK_BLOCK) { + clickType = GeneralRegion.ClickType.SHIFTRIGHTCLICK; + } else if(!player.isSneaking() && event.getAction() == Action.RIGHT_CLICK_BLOCK) { + clickType = GeneralRegion.ClickType.RIGHTCLICK; + } + + boolean ran = regionSign.runSignCommands(player, clickType); + + // Only cancel event if at least one command has been executed + event.setCancelled(ran); } @EventHandler(priority = EventPriority.MONITOR) @@ -278,8 +290,7 @@ public class SignsFeature extends RegionFeature { if(durationSet) { rent.setDuration(thirdLine); } - org.bukkit.material.Sign sign = (org.bukkit.material.Sign)event.getBlock().getState().getData(); - rent.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), sign.getFacing(), null); + rent.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), plugin.getBukkitHandler().getSignFacing(event.getBlock()), null); AddingRegionEvent addingRegionEvent = plugin.getFileManager().addRegion(rent); if (addingRegionEvent.isCancelled()) { @@ -383,8 +394,7 @@ public class SignsFeature extends RegionFeature { if(priceSet) { buy.setPrice(price); } - org.bukkit.material.Sign sign = (org.bukkit.material.Sign)event.getBlock().getState().getData(); - buy.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), sign.getFacing(), null); + buy.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), plugin.getBukkitHandler().getSignFacing(event.getBlock()), null); AddingRegionEvent addingRegionEvent = plugin.getFileManager().addRegion(buy); if (addingRegionEvent.isCancelled()) { @@ -428,12 +438,12 @@ public class SignsFeature extends RegionFeature { } region = regions.get(0); } - org.bukkit.material.Sign sign = (org.bukkit.material.Sign)event.getBlock().getState().getData(); + if(thirdLine == null || thirdLine.isEmpty()) { - region.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), sign.getFacing(), null); + region.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), plugin.getBukkitHandler().getSignFacing(event.getBlock()), null); plugin.message(player, "addsign-success", region); } else { - region.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), sign.getFacing(), thirdLine); + region.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), plugin.getBukkitHandler().getSignFacing(event.getBlock()), thirdLine); plugin.message(player, "addsign-successProfile", thirdLine, region); } diff --git a/AreaShop/src/main/java/me/wiefferink/areashop/managers/SignLinkerManager.java b/AreaShop/src/main/java/me/wiefferink/areashop/managers/SignLinkerManager.java index 4bd0311..3e13cef 100644 --- a/AreaShop/src/main/java/me/wiefferink/areashop/managers/SignLinkerManager.java +++ b/AreaShop/src/main/java/me/wiefferink/areashop/managers/SignLinkerManager.java @@ -18,7 +18,6 @@ import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.material.Sign; import org.bukkit.util.BlockIterator; import java.util.HashMap; @@ -131,8 +130,7 @@ public class SignLinkerManager extends Manager implements Listener { plugin.message(player, "linksigns-alreadyRegistered", regionSign.getRegion()); return; } - Sign sign = (Sign)block.getState().getData(); - linker.setSign(block.getLocation(), block.getType(), sign.getFacing()); + linker.setSign(block.getLocation(), block.getType(), plugin.getBukkitHandler().getSignFacing(block)); } } } diff --git a/AreaShop/src/main/java/me/wiefferink/areashop/tools/Materials.java b/AreaShop/src/main/java/me/wiefferink/areashop/tools/Materials.java index ca40604..fb90bb3 100644 --- a/AreaShop/src/main/java/me/wiefferink/areashop/tools/Materials.java +++ b/AreaShop/src/main/java/me/wiefferink/areashop/tools/Materials.java @@ -5,6 +5,7 @@ import org.bukkit.Bukkit; import org.bukkit.Material; import java.util.Arrays; +import java.util.HashSet; import java.util.List; public class Materials { @@ -13,6 +14,35 @@ public class Materials { } + private static final HashSet WALL_SIGN_TYPES = new HashSet<>(Arrays.asList( + // 1.14+ types + "ACACIA_WALL_SIGN", + "BIRCH_WALL_SIGN", + "DARK_OAK_WALL_SIGN", + "JUNGLE_WALL_SIGN", + "OAK_WALL_SIGN", + "SPRUCE_WALL_SIGN", + + // Legacy types + "LEGACY_WALL_SIGN", + "WALL_SIGN" + )); + private static final HashSet FLOOR_SIGN_TYPES = new HashSet<>(Arrays.asList( + // 1.14+ types + "ACACIA_SIGN", + "BIRCH_SIGN", + "DARK_OAK_SIGN", + "JUNGLE_SIGN", + "OAK_SIGN", + "SPRUCE_SIGN", + + // Legacy types + "LEGACY_SIGN", + "LEGACY_SIGN_POST", + "SIGN", + "SIGN_POST" + )); + private static boolean legacyMaterials = false; static { @@ -29,34 +59,53 @@ public class Materials { } } - public static final Material wallSign = get("WALL_SIGN"); - public static final Material floorSign = get("SIGN", "SIGN_POST"); - /** - * Get Material version independent. - * @param name Name in 1.13 and later (uppercase, with underscores) - * @return Material matching the name + * Get material based on a sign material name. + * @param name Name of the sign material + * @return null if not a sign, otherwise the material matching the name (when the material is not available on the current minecraft version, it returns the base type) */ - public static Material get(String name) { - return get(name, null); - } + public static Material signNameToMaterial(String name) { + // Expected null case + if (!isSign(name)) { + return null; + } - /** - * Get Material version independent. - * @param name Name in 1.13 and later (uppercase, with underscores) - * @param legacyName Name in 1.12 and earlier (uppercase, with underscores) - * @return Material matching the name - */ - public static Material get(String name, String legacyName) { - Material result; - if (legacyMaterials && legacyName != null) { - result = Material.getMaterial(legacyName); + Material result = null; + if (legacyMaterials) { + // 1.12 and lower just know SIGN_POST, WALL_SIGN and SIGN + if (FLOOR_SIGN_TYPES.contains(name)) { + result = Material.getMaterial("SIGN_POST"); + } else if (WALL_SIGN_TYPES.contains(name)) { + result = Material.getMaterial("WALL_SIGN"); + if (result == null) { + result = Material.getMaterial("SIGN"); + } + } } else { + // Try saved name (works for wood types on 1.14, regular types for below) result = Material.getMaterial(name); + if (result == null) { + // Cases for 1.13, which don't know wood types, but need new materials + if (FLOOR_SIGN_TYPES.contains(name)) { + // SIGN -> OAK_SIGN for 1.14 + result = Material.getMaterial("OAK_SIGN"); + // Fallback for 1.13 + if (result == null) { + result = Material.getMaterial("SIGN"); + } + } else if (WALL_SIGN_TYPES.contains(name)) { + // WALL_SIGN -> OAK_WALL_SIGN for 1.14 + result = Material.getMaterial("OAK_WALL_SIGN"); + // Fallback for 1.13 + if (result == null) { + result = Material.getMaterial("WALL_SIGN"); + } + } + } } if (result == null) { - AreaShop.debug("Materials.get() null result:", name, legacyName); + AreaShop.debug("Materials.get() null result:", name, "legacyMaterials:", legacyMaterials); } return result; @@ -68,7 +117,16 @@ public class Materials { * @return true if the given material is a sign */ public static boolean isSign(Material material) { - return material != null && material.name().contains("SIGN"); + return isSign(material.name()); + } + + /** + * Check if a Material is a sign (of either the wall or floor type). + * @param name String to check + * @return true if the given material is a sign + */ + public static boolean isSign(String name) { + return name != null && (FLOOR_SIGN_TYPES.contains(name) || WALL_SIGN_TYPES.contains(name)); } } diff --git a/areashop-bukkit-1_12/pom.xml b/areashop-bukkit-1_12/pom.xml new file mode 100644 index 0000000..83b0be9 --- /dev/null +++ b/areashop-bukkit-1_12/pom.xml @@ -0,0 +1,33 @@ + + 4.0.0 + areashop-bukkit-1_12 + jar + AreaShop Bukkit 1.7.9 until 1.12 + latest + + + me.wiefferink + areashop-parent + parent + + + + + org.bukkit + craftbukkit + system + any + ${project.basedir}/../dependencies/craftbukkit-1.7.9-R0.2-SNAPSHOT.jar + jar + true + + + + me.wiefferink + areashop-interface + latest + jar + + + diff --git a/areashop-bukkit-1_12/src/main/java/me/wiefferink/areashop/handlers/BukkitHandler1_12.java b/areashop-bukkit-1_12/src/main/java/me/wiefferink/areashop/handlers/BukkitHandler1_12.java new file mode 100644 index 0000000..9e04c5a --- /dev/null +++ b/areashop-bukkit-1_12/src/main/java/me/wiefferink/areashop/handlers/BukkitHandler1_12.java @@ -0,0 +1,76 @@ +package me.wiefferink.areashop.handlers; + +import me.wiefferink.areashop.interfaces.AreaShopInterface; +import me.wiefferink.areashop.interfaces.BukkitInterface; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; +import org.bukkit.material.MaterialData; + +public class BukkitHandler1_12 extends BukkitInterface { + + public BukkitHandler1_12(AreaShopInterface pluginInterface) { + super(pluginInterface); + } + + // Uses Sign, which is deprecated in 1.13+, broken in 1.14+ + @Override + public BlockFace getSignFacing(Block block) { + if (block == null) { + return null; + } + + BlockState blockState = block.getState(); + if (blockState == null) { + return null; + } + + MaterialData materialData = blockState.getData(); + if(materialData instanceof org.bukkit.material.Sign) { + return ((org.bukkit.material.Sign)materialData).getFacing(); + } + + return null; + } + + @Override + public boolean setSignFacing(Block block, BlockFace facing) { + if (block == null || facing == null) { + return false; + } + + BlockState blockState = block.getState(); + if (blockState == null) { + return false; + } + + org.bukkit.material.Sign signData = (org.bukkit.material.Sign) blockState.getData(); + if (signData == null) { + return false; + } + + signData.setFacingDirection(facing); + blockState.setData(signData); + blockState.update(true, true); + return true; + } + + @Override + public Block getSignAttachedTo(Block block) { + if (block == null) { + return null; + } + + BlockState blockState = block.getState(); + if (blockState == null) { + return null; + } + + org.bukkit.material.Sign signData = (org.bukkit.material.Sign) blockState.getData(); + if (signData == null) { + return null; + } + + return block.getRelative(signData.getAttachedFace()); + } +} diff --git a/areashop-bukkit-1_13/pom.xml b/areashop-bukkit-1_13/pom.xml new file mode 100644 index 0000000..b6325c5 --- /dev/null +++ b/areashop-bukkit-1_13/pom.xml @@ -0,0 +1,31 @@ + + 4.0.0 + areashop-bukkit-1_13 + jar + AreaShop Bukkit 1.13 and higher + latest + + + me.wiefferink + areashop-parent + parent + + + + + org.bukkit + craftbukkit + 1.13-R0.1-SNAPSHOT + jar + true + + + + me.wiefferink + areashop-interface + latest + jar + + + diff --git a/areashop-bukkit-1_13/src/main/java/me/wiefferink/areashop/handlers/BukkitHandler1_13.java b/areashop-bukkit-1_13/src/main/java/me/wiefferink/areashop/handlers/BukkitHandler1_13.java new file mode 100644 index 0000000..732cfef --- /dev/null +++ b/areashop-bukkit-1_13/src/main/java/me/wiefferink/areashop/handlers/BukkitHandler1_13.java @@ -0,0 +1,97 @@ +package me.wiefferink.areashop.handlers; + +import me.wiefferink.areashop.interfaces.AreaShopInterface; +import me.wiefferink.areashop.interfaces.BukkitInterface; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.type.Sign; +import org.bukkit.block.data.type.WallSign; + +public class BukkitHandler1_13 extends BukkitInterface { + + public BukkitHandler1_13(AreaShopInterface pluginInterface) { + super(pluginInterface); + } + + // Uses BlockData, which does not yet exist in 1.12- + @Override + public BlockFace getSignFacing(Block block) { + if (block == null) { + return null; + } + + BlockState blockState = block.getState(); + if (blockState == null) { + return null; + } + + BlockData blockData = blockState.getBlockData(); + if (blockData == null) { + return null; + } + + if(blockData instanceof WallSign) { + return ((WallSign) blockData).getFacing(); + } else if(blockData instanceof Sign) { + return ((Sign) blockData).getRotation(); + } + + return null; + } + + // Uses BlockData, WallSign and Sign which don't exist in 1.12- + @Override + public boolean setSignFacing(Block block, BlockFace facing) { + if (block == null || facing == null) { + return false; + } + + BlockState blockState = block.getState(); + if (blockState == null) { + return false; + } + + BlockData blockData = blockState.getBlockData(); + if (blockData == null) { + return false; + } + + if(blockData instanceof WallSign) { + ((WallSign) blockData).setFacing(facing); + } else if(blockData instanceof Sign) { + ((Sign) blockData).setRotation(facing); + } else { + return false; + } + block.setBlockData(blockData); + return true; + } + + @Override + public Block getSignAttachedTo(Block block) { + if (block == null) { + return null; + } + + BlockState blockState = block.getState(); + if (blockState == null) { + return null; + } + + org.bukkit.block.data.BlockData blockData = blockState.getBlockData(); + if (blockData == null) { + return null; + } + + if(blockData instanceof WallSign) { + return block.getRelative(((WallSign) blockData).getFacing().getOppositeFace()); + } else if(blockData instanceof Sign) { + return block.getRelative(BlockFace.DOWN); + } + + return null; + } + +} diff --git a/areashop-fastasyncworldedit/.gitignore b/areashop-fastasyncworldedit/.gitignore deleted file mode 100644 index ea8c4bf..0000000 --- a/areashop-fastasyncworldedit/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/areashop-interface/.gitignore b/areashop-interface/.gitignore deleted file mode 100644 index ea8c4bf..0000000 --- a/areashop-interface/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/areashop-interface/src/main/java/me/wiefferink/areashop/interfaces/BukkitInterface.java b/areashop-interface/src/main/java/me/wiefferink/areashop/interfaces/BukkitInterface.java new file mode 100644 index 0000000..badf80e --- /dev/null +++ b/areashop-interface/src/main/java/me/wiefferink/areashop/interfaces/BukkitInterface.java @@ -0,0 +1,35 @@ +package me.wiefferink.areashop.interfaces; + +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; + +public abstract class BukkitInterface { + protected final AreaShopInterface pluginInterface; + + public BukkitInterface(AreaShopInterface pluginInterface) { + this.pluginInterface = pluginInterface; + } + + /** + * Get the direciton a sign is facing. + * @param block Sign block to get the facing from + * @return direction the sign is facing + */ + public abstract BlockFace getSignFacing(Block block); + + /** + * Set the direction a sign is facing. + * @param block Sign block to update + * @param facing direction to let the sign face + * @return true when successful, otherwise false + */ + public abstract boolean setSignFacing(Block block, BlockFace facing); + + /** + * Get the block a sign is attached to. + * @param block Sign block + * @return Block the sign is attached to, or null when not a sign or not attached + */ + public abstract Block getSignAttachedTo(Block block); + +} diff --git a/areashop-interface/src/main/java/me/wiefferink/areashop/interfaces/WorldEditInterface.java b/areashop-interface/src/main/java/me/wiefferink/areashop/interfaces/WorldEditInterface.java index c8fc1f7..708579a 100644 --- a/areashop-interface/src/main/java/me/wiefferink/areashop/interfaces/WorldEditInterface.java +++ b/areashop-interface/src/main/java/me/wiefferink/areashop/interfaces/WorldEditInterface.java @@ -11,12 +11,30 @@ public abstract class WorldEditInterface { this.pluginInterface = pluginInterface; } - // Different way to restore blocks per implementation, newer ones support entities as well + /** + * Different way to restore blocks per implementation, newer ones support entities as well. + * Why: the schematic api has changed between WorldEdit 5 and 6, and the schematic format changed between 6 and 7 + * @param file File to try restoring from to the location of the region + * @param regionInterface Region to restore from + * @return true when successful, otherwise false + */ public abstract boolean restoreRegionBlocks(File file, GeneralRegionInterface regionInterface); - // Different way to save blocks per implementation, newer ones support entities as well + /** + * Different way to save blocks per implementation, newer ones support entities as well. + * Why: the schematic api has changed between WorldEdit 5 and 6, and the schematic format changed between 6 and 7 + * @param file File to try saving the region to + * @param regionInterface Region to restore from + * @return true when successful, otherwise false + */ public abstract boolean saveRegionBlocks(File file, GeneralRegionInterface regionInterface); + /** + * Get the selection of the player. + * Why: the underlying WorldEdit selection class has changed from interface <-> class + * @param player Player to get the selection for + * @return WorldEditSelection if the player has selected something, otherwise null + */ public abstract WorldEditSelection getPlayerSelection(Player player); -} \ No newline at end of file +} diff --git a/areashop-worldedit-5/.gitignore b/areashop-worldedit-5/.gitignore deleted file mode 100644 index ea8c4bf..0000000 --- a/areashop-worldedit-5/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/areashop-worldedit-6/.gitignore b/areashop-worldedit-6/.gitignore deleted file mode 100644 index ea8c4bf..0000000 --- a/areashop-worldedit-6/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/areashop-worldedit-7_beta_1/.gitignore b/areashop-worldedit-7_beta_1/.gitignore deleted file mode 100644 index ea8c4bf..0000000 --- a/areashop-worldedit-7_beta_1/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/areashop-worldedit-7_beta_4/.gitignore b/areashop-worldedit-7_beta_4/.gitignore deleted file mode 100644 index ea8c4bf..0000000 --- a/areashop-worldedit-7_beta_4/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/areashop-worldguard-5/.gitignore b/areashop-worldguard-5/.gitignore deleted file mode 100644 index ea8c4bf..0000000 --- a/areashop-worldguard-5/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/areashop-worldguard-6/.gitignore b/areashop-worldguard-6/.gitignore deleted file mode 100644 index ea8c4bf..0000000 --- a/areashop-worldguard-6/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/areashop-worldguard-6_1_3/.gitignore b/areashop-worldguard-6_1_3/.gitignore deleted file mode 100644 index ea8c4bf..0000000 --- a/areashop-worldguard-6_1_3/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/areashop-worldguard-7_beta_1/.gitignore b/areashop-worldguard-7_beta_1/.gitignore deleted file mode 100644 index ea8c4bf..0000000 --- a/areashop-worldguard-7_beta_1/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/areashop-worldguard-7_beta_2/.gitignore b/areashop-worldguard-7_beta_2/.gitignore deleted file mode 100644 index ea8c4bf..0000000 --- a/areashop-worldguard-7_beta_2/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/pom.xml b/pom.xml index f584416..1b026af 100644 --- a/pom.xml +++ b/pom.xml @@ -50,6 +50,8 @@ areashop-interface + areashop-bukkit-1_12 + areashop-bukkit-1_13 areashop-worldguard-5 areashop-worldguard-6 areashop-worldguard-6_1_3