Various improvements to the interface
More time units are supported, which makes long temporary durations more readable Makes right-clicking a sign display a full description, and requires sneaking while clicking to perform the transaction Makes signs only be destroyed when sneaking Improves sign protection a bit, but improvements are required Prevents a creative player breaking a sign from also interacting with it
This commit is contained in:
		@@ -33,6 +33,9 @@ import java.util.Queue;
 | 
				
			|||||||
import java.util.UUID;
 | 
					import java.util.UUID;
 | 
				
			||||||
import java.util.stream.Stream;
 | 
					import java.util.stream.Stream;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * The main permissionsigns class
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
public final class PermissionSigns extends JavaPlugin {
 | 
					public final class PermissionSigns extends JavaPlugin {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static final Queue<SignCreationRequest> signCreationRequests = new PriorityQueue<>();
 | 
					    private static final Queue<SignCreationRequest> signCreationRequests = new PriorityQueue<>();
 | 
				
			||||||
@@ -131,6 +134,7 @@ public final class PermissionSigns extends JavaPlugin {
 | 
				
			|||||||
        PluginDescriptionFile pluginDescriptionFile = this.getDescription();
 | 
					        PluginDescriptionFile pluginDescriptionFile = this.getDescription();
 | 
				
			||||||
        pluginVersion = pluginDescriptionFile.getVersion();
 | 
					        pluginVersion = pluginDescriptionFile.getVersion();
 | 
				
			||||||
        //TODO: Allow for custom language files. Perhaps just look for strings.yml in the folder
 | 
					        //TODO: Allow for custom language files. Perhaps just look for strings.yml in the folder
 | 
				
			||||||
 | 
					        //TODO: Display a notice in the console if a new version is available
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        FileConfiguration config = this.getConfig();
 | 
					        FileConfiguration config = this.getConfig();
 | 
				
			||||||
        config.options().copyDefaults(true);
 | 
					        config.options().copyDefaults(true);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -148,11 +148,34 @@ public class PermissionSign {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return <p>The string used for displaying this sign's duration</p>
 | 
					     * @return <p>The string used for displaying this sign's duration</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private String getDurationString() {
 | 
					    public String getDurationString() {
 | 
				
			||||||
        if (duration == 0) {
 | 
					        if (duration == 0) {
 | 
				
			||||||
            return Translator.getTranslatedMessage(TranslatableMessage.SIGN_PERMANENT);
 | 
					            return Translator.getTranslatedMessage(TranslatableMessage.SIGN_PERMANENT);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            return duration + " " + Translator.getTranslatedMessage(TranslatableMessage.SIGN_TIME_UNIT);
 | 
					            double minute = 60;
 | 
				
			||||||
 | 
					            double hour = minute * 60;
 | 
				
			||||||
 | 
					            double day = hour * 24;
 | 
				
			||||||
 | 
					            if (duration / day >= 1) {
 | 
				
			||||||
 | 
					                double days = round(duration / day);
 | 
				
			||||||
 | 
					                if (days == 1) {
 | 
				
			||||||
 | 
					                    return (int) days + " " + Translator.getTranslatedMessage(TranslatableMessage.UNIT_DAY);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    return days + " " + Translator.getTranslatedMessage(TranslatableMessage.UNIT_DAYS);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } else if (duration / hour >= 1) {
 | 
				
			||||||
 | 
					                double hours = round(duration / hour);
 | 
				
			||||||
 | 
					                if (hours == 1) {
 | 
				
			||||||
 | 
					                    return (int) hours + " " + Translator.getTranslatedMessage(TranslatableMessage.UNIT_HOUR);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    return hours + " " + Translator.getTranslatedMessage(TranslatableMessage.UNIT_HOURS);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                if (duration == 1) {
 | 
				
			||||||
 | 
					                    return duration + " " + Translator.getTranslatedMessage(TranslatableMessage.UNIT_SECOND);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    return duration + " " + Translator.getTranslatedMessage(TranslatableMessage.UNIT_SECONDS);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -161,7 +184,7 @@ public class PermissionSign {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return <p>The string used for displaying this sign's cost</p>
 | 
					     * @return <p>The string used for displaying this sign's cost</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private String getCostString() {
 | 
					    public String getCostString() {
 | 
				
			||||||
        if (cost == 0) {
 | 
					        if (cost == 0) {
 | 
				
			||||||
            return Translator.getTranslatedMessage(TranslatableMessage.SIGN_COST_FREE);
 | 
					            return Translator.getTranslatedMessage(TranslatableMessage.SIGN_COST_FREE);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
@@ -170,4 +193,14 @@ public class PermissionSign {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Rounds a number to its last two digits
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param number <p>The number to round</p>
 | 
				
			||||||
 | 
					     * @return <p>The rounded number</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private double round(double number) {
 | 
				
			||||||
 | 
					        return Math.round(number * 100.0) / 100.0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,9 +16,44 @@ public enum TranslatableMessage {
 | 
				
			|||||||
    SIGN_PREFIX,
 | 
					    SIGN_PREFIX,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * The text to display as a permission sign's duration time unit
 | 
					     * The text to display for 1 second
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    SIGN_TIME_UNIT,
 | 
					    UNIT_SECOND,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The text to display for a number of seconds
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    UNIT_SECONDS,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The text to display for 1 minute
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    UNIT_MINUTE,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The text to display for a number of minutes
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    UNIT_MINUTES,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The text to display for 1 hour
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    UNIT_HOUR,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The text to display for a number of hours
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    UNIT_HOURS,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The text to display for 1 day
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    UNIT_DAY,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The text to display for a number of days
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    UNIT_DAYS,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * The text to display on a permission sign that is entirely free
 | 
					     * The text to display on a permission sign that is entirely free
 | 
				
			||||||
@@ -50,6 +85,11 @@ public enum TranslatableMessage {
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    PERMISSION_SIGN_DESTROY_DENY,
 | 
					    PERMISSION_SIGN_DESTROY_DENY,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The message to display to a non-sneaking player trying to destroy a permissions sign
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    PERMISSION_SIGN_DESTROY_SNEAK,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * The error message to display if the user has not provided necessary information to create a permission sign
 | 
					     * The error message to display if the user has not provided necessary information to create a permission sign
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
@@ -113,6 +153,11 @@ public enum TranslatableMessage {
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * The message to display when a reload action has been successfully performed
 | 
					     * The message to display when a reload action has been successfully performed
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    RELOAD_SUCCESSFUL
 | 
					    RELOAD_SUCCESSFUL,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The text describing all properties of a permission sign
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    SIGN_INFO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,6 @@ import org.bukkit.configuration.file.YamlConfiguration;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import java.io.BufferedReader;
 | 
					import java.io.BufferedReader;
 | 
				
			||||||
import java.io.FileNotFoundException;
 | 
					import java.io.FileNotFoundException;
 | 
				
			||||||
import java.io.UnsupportedEncodingException;
 | 
					 | 
				
			||||||
import java.util.HashMap;
 | 
					import java.util.HashMap;
 | 
				
			||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
import java.util.logging.Level;
 | 
					import java.util.logging.Level;
 | 
				
			||||||
@@ -57,7 +56,7 @@ public final class Translator {
 | 
				
			|||||||
        BufferedReader reader;
 | 
					        BufferedReader reader;
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            reader = FileHelper.getBufferedReaderForInternalFile("/strings.yml");
 | 
					            reader = FileHelper.getBufferedReaderForInternalFile("/strings.yml");
 | 
				
			||||||
        } catch (FileNotFoundException | UnsupportedEncodingException e) {
 | 
					        } catch (FileNotFoundException e) {
 | 
				
			||||||
            PermissionSigns.getInstance().getLogger().log(Level.SEVERE, "Unable to load translated messages");
 | 
					            PermissionSigns.getInstance().getLogger().log(Level.SEVERE, "Unable to load translated messages");
 | 
				
			||||||
            return null;
 | 
					            return null;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,12 +6,19 @@ import net.knarcraft.permissionsigns.manager.SignManager;
 | 
				
			|||||||
import org.bukkit.Material;
 | 
					import org.bukkit.Material;
 | 
				
			||||||
import org.bukkit.Tag;
 | 
					import org.bukkit.Tag;
 | 
				
			||||||
import org.bukkit.block.Block;
 | 
					import org.bukkit.block.Block;
 | 
				
			||||||
 | 
					import org.bukkit.block.BlockFace;
 | 
				
			||||||
import org.bukkit.block.Sign;
 | 
					import org.bukkit.block.Sign;
 | 
				
			||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
import org.bukkit.event.EventHandler;
 | 
					import org.bukkit.event.EventHandler;
 | 
				
			||||||
import org.bukkit.event.Listener;
 | 
					import org.bukkit.event.Listener;
 | 
				
			||||||
import org.bukkit.event.block.BlockBreakEvent;
 | 
					import org.bukkit.event.block.BlockBreakEvent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A listener for relevant block events such as signs being broken
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
public class BlockListener implements Listener {
 | 
					public class BlockListener implements Listener {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @EventHandler
 | 
					    @EventHandler
 | 
				
			||||||
@@ -23,11 +30,60 @@ public class BlockListener implements Listener {
 | 
				
			|||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //if (block instanceof FallingBlock) {
 | 
				
			||||||
 | 
					        //TODO: Search recursively upwards (and downwards if pointed dripstone) until a non-falling block is found.
 | 
				
			||||||
 | 
					        // If upwards, check the non-falling block, but not downwards. If player does not have the create permission,
 | 
				
			||||||
 | 
					        // just stop and cancel once a permission sign is found. If it has, all affected signs need to be 
 | 
				
			||||||
 | 
					        // de-registered. Must account for stacks of sand and signs on top of each-other. So if a normal sign is 
 | 
				
			||||||
 | 
					        // found, the recursion upward must also happen.
 | 
				
			||||||
 | 
					        //}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Material material = block.getBlockData().getMaterial();
 | 
					        Material material = block.getBlockData().getMaterial();
 | 
				
			||||||
        if (!Tag.SIGNS.isTagged(material) && !Tag.WALL_SIGNS.isTagged(material)) {
 | 
					        if (Tag.SIGNS.isTagged(material) || Tag.WALL_SIGNS.isTagged(material)) {
 | 
				
			||||||
 | 
					            checkIfBlockIsPermissionSign(block, player, event);
 | 
				
			||||||
 | 
					            if (event.isCancelled()) {
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Block relativeBlock = block.getRelative(BlockFace.UP);
 | 
				
			||||||
 | 
					        if (Tag.SIGNS.isTagged(relativeBlock.getBlockData().getMaterial())) {
 | 
				
			||||||
 | 
					            checkIfBlockIsPermissionSign(relativeBlock, player, event);
 | 
				
			||||||
 | 
					            if (event.isCancelled()) {
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (block.getBlockData().getMaterial() == Material.POINTED_DRIPSTONE) {
 | 
				
			||||||
 | 
					            relativeBlock = block.getRelative(BlockFace.DOWN);
 | 
				
			||||||
 | 
					            if (Tag.WALL_SIGNS.isTagged(relativeBlock.getBlockData().getMaterial())) {
 | 
				
			||||||
 | 
					                checkIfBlockIsPermissionSign(relativeBlock, player, event);
 | 
				
			||||||
 | 
					                if (event.isCancelled()) {
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        for (BlockFace blockFace : getRelevantBlockFaces()) {
 | 
				
			||||||
 | 
					            relativeBlock = block.getRelative(blockFace);
 | 
				
			||||||
 | 
					            if (Tag.WALL_SIGNS.isTagged(relativeBlock.getBlockData().getMaterial())) {
 | 
				
			||||||
 | 
					                checkIfBlockIsPermissionSign(relativeBlock, player, event);
 | 
				
			||||||
 | 
					                if (event.isCancelled()) {
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //TODO: Need to protect against other things that might damage the sign, such as explosions
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Check if the given block is a permission sign, and perform necessary tasks if it is
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param block  <p>The block to check</p>
 | 
				
			||||||
 | 
					     * @param player <p>The player that caused the event</p>
 | 
				
			||||||
 | 
					     * @param event  <p>The triggered block break event</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private void checkIfBlockIsPermissionSign(Block block, Player player, BlockBreakEvent event) {
 | 
				
			||||||
        Sign sign = (Sign) block.getState();
 | 
					        Sign sign = (Sign) block.getState();
 | 
				
			||||||
        boolean registered = SignManager.getSign(sign.getLocation()) != null;
 | 
					        boolean registered = SignManager.getSign(sign.getLocation()) != null;
 | 
				
			||||||
        if (!registered) {
 | 
					        if (!registered) {
 | 
				
			||||||
@@ -37,12 +93,28 @@ public class BlockListener implements Listener {
 | 
				
			|||||||
            event.setCancelled(true);
 | 
					            event.setCancelled(true);
 | 
				
			||||||
            player.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.PERMISSION_SIGN_DESTROY_DENY));
 | 
					            player.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.PERMISSION_SIGN_DESTROY_DENY));
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
 | 
					            if (!player.isSneaking()) {
 | 
				
			||||||
 | 
					                event.setCancelled(true);
 | 
				
			||||||
 | 
					                player.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.PERMISSION_SIGN_DESTROY_SNEAK));
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            SignManager.removeSign(sign.getLocation());
 | 
					            SignManager.removeSign(sign.getLocation());
 | 
				
			||||||
            player.sendMessage(StringFormatter.getTranslatedInfoMessage(TranslatableMessage.PERMISSION_SIGN_REMOVED));
 | 
					            player.sendMessage(StringFormatter.getTranslatedInfoMessage(TranslatableMessage.PERMISSION_SIGN_REMOVED));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //TODO: Need to protect against other things that might damage the sign, such as explosions
 | 
					    /**
 | 
				
			||||||
        //TODO: Only allow the sign to be broken if shift-clicking?
 | 
					     * Gets the relevant block faces for checking around a block
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return <p>The relevant block faces for checking around a block</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private List<BlockFace> getRelevantBlockFaces() {
 | 
				
			||||||
 | 
					        List<BlockFace> relevantBlockFaces = new ArrayList<>();
 | 
				
			||||||
 | 
					        relevantBlockFaces.add(BlockFace.WEST);
 | 
				
			||||||
 | 
					        relevantBlockFaces.add(BlockFace.EAST);
 | 
				
			||||||
 | 
					        relevantBlockFaces.add(BlockFace.NORTH);
 | 
				
			||||||
 | 
					        relevantBlockFaces.add(BlockFace.SOUTH);
 | 
				
			||||||
 | 
					        return relevantBlockFaces;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,6 +9,8 @@ import net.knarcraft.permissionsigns.formatting.Translator;
 | 
				
			|||||||
import net.knarcraft.permissionsigns.manager.EconomyManager;
 | 
					import net.knarcraft.permissionsigns.manager.EconomyManager;
 | 
				
			||||||
import net.knarcraft.permissionsigns.manager.PermissionManager;
 | 
					import net.knarcraft.permissionsigns.manager.PermissionManager;
 | 
				
			||||||
import net.knarcraft.permissionsigns.manager.SignManager;
 | 
					import net.knarcraft.permissionsigns.manager.SignManager;
 | 
				
			||||||
 | 
					import net.md_5.bungee.api.ChatColor;
 | 
				
			||||||
 | 
					import org.bukkit.GameMode;
 | 
				
			||||||
import org.bukkit.Material;
 | 
					import org.bukkit.Material;
 | 
				
			||||||
import org.bukkit.Tag;
 | 
					import org.bukkit.Tag;
 | 
				
			||||||
import org.bukkit.block.Block;
 | 
					import org.bukkit.block.Block;
 | 
				
			||||||
@@ -16,9 +18,11 @@ import org.bukkit.block.Sign;
 | 
				
			|||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
import org.bukkit.event.EventHandler;
 | 
					import org.bukkit.event.EventHandler;
 | 
				
			||||||
import org.bukkit.event.Listener;
 | 
					import org.bukkit.event.Listener;
 | 
				
			||||||
 | 
					import org.bukkit.event.block.Action;
 | 
				
			||||||
import org.bukkit.event.player.PlayerInteractEvent;
 | 
					import org.bukkit.event.player.PlayerInteractEvent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.Arrays;
 | 
					import java.util.Arrays;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.StringJoiner;
 | 
					import java.util.StringJoiner;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -46,7 +50,7 @@ public class SignListener implements Listener {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Sign sign = (Sign) block.getState();
 | 
					        Sign sign = (Sign) block.getState();
 | 
				
			||||||
        handleSignClick(sign, player);
 | 
					        handleSignClick(sign, player, event.getAction());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -54,19 +58,26 @@ public class SignListener implements Listener {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param sign   <p>The clicked sign</p>
 | 
					     * @param sign   <p>The clicked sign</p>
 | 
				
			||||||
     * @param player <p>The player that clicked the sign</p>
 | 
					     * @param player <p>The player that clicked the sign</p>
 | 
				
			||||||
 | 
					     * @param action <p>The hand the player used to interact with the sign</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private void handleSignClick(Sign sign, Player player) {
 | 
					    private void handleSignClick(Sign sign, Player player, Action action) {
 | 
				
			||||||
        //Check if the sign is a registered permission sign
 | 
					        //Check if the sign is a registered permission sign
 | 
				
			||||||
        PermissionSign permissionSign = SignManager.getSign(sign.getLocation());
 | 
					        PermissionSign permissionSign = SignManager.getSign(sign.getLocation());
 | 
				
			||||||
        if (permissionSign != null) {
 | 
					        if (permissionSign != null) {
 | 
				
			||||||
 | 
					            if (player.getGameMode() == GameMode.CREATIVE && action == Action.LEFT_CLICK_BLOCK) {
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            if (!player.hasPermission("permissionsigns.use")) {
 | 
					            if (!player.hasPermission("permissionsigns.use")) {
 | 
				
			||||||
                player.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.INTERACT_PERMISSION_MISSING));
 | 
					                player.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.INTERACT_PERMISSION_MISSING));
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            if (player.isSneaking()) {
 | 
				
			||||||
                handlePermissionSignInteract(permissionSign, player);
 | 
					                handlePermissionSignInteract(permissionSign, player);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                player.sendMessage(getSignInfoText(permissionSign));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        //TODO: Display information about granted permissions when shift-clicking?
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Check if the player has a creation request that can be fulfilled
 | 
					        //Check if the player has a creation request that can be fulfilled
 | 
				
			||||||
        SignCreationRequest request = PermissionSigns.getSignCreationRequest(player.getUniqueId());
 | 
					        SignCreationRequest request = PermissionSigns.getSignCreationRequest(player.getUniqueId());
 | 
				
			||||||
@@ -75,6 +86,31 @@ public class SignListener implements Listener {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Gets information about a sign
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param sign <p>The sign to get information about</p>
 | 
				
			||||||
 | 
					     * @return <p>The information to display</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private String getSignInfoText(PermissionSign sign) {
 | 
				
			||||||
 | 
					        String rawSignInfo = Translator.getTranslatedMessage(TranslatableMessage.SIGN_INFO);
 | 
				
			||||||
 | 
					        StringBuilder permissionString = new StringBuilder();
 | 
				
			||||||
 | 
					        List<String> permissionNodes = sign.getPermissionNodes();
 | 
				
			||||||
 | 
					        if (permissionNodes.size() == 1) {
 | 
				
			||||||
 | 
					            permissionString = new StringBuilder(permissionNodes.get(0));
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            for (String permissionNode : permissionNodes) {
 | 
				
			||||||
 | 
					                permissionString.append("\n" + "&f| &7- ").append(permissionNode);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            permissionString.append("\n");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        String replacedString = StringFormatter.replacePlaceholders(rawSignInfo, new String[]{"{Name}", "{Permissions}",
 | 
				
			||||||
 | 
					                "{Cost}", "{Duration}"}, new String[]{sign.getName(), permissionString.toString(), sign.getCostString(),
 | 
				
			||||||
 | 
					                sign.getDurationString()});
 | 
				
			||||||
 | 
					        return ChatColor.translateAlternateColorCodes('&', replacedString);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Handles the interaction with a permission sign
 | 
					     * Handles the interaction with a permission sign
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
@@ -137,9 +173,8 @@ public class SignListener implements Listener {
 | 
				
			|||||||
        String grantedPermissions = permissionsJoiner.toString();
 | 
					        String grantedPermissions = permissionsJoiner.toString();
 | 
				
			||||||
        if (permissionSign.getDuration() > 0) {
 | 
					        if (permissionSign.getDuration() > 0) {
 | 
				
			||||||
            String successMessage = StringFormatter.getTranslatedInfoMessage(TranslatableMessage.PERMISSIONS_GRANTED);
 | 
					            String successMessage = StringFormatter.getTranslatedInfoMessage(TranslatableMessage.PERMISSIONS_GRANTED);
 | 
				
			||||||
            String timeUnit = Translator.getTranslatedMessage(TranslatableMessage.SIGN_TIME_UNIT);
 | 
					 | 
				
			||||||
            player.sendMessage(StringFormatter.replacePlaceholders(successMessage, new String[]{"{permissions}", "{time}"},
 | 
					            player.sendMessage(StringFormatter.replacePlaceholders(successMessage, new String[]{"{permissions}", "{time}"},
 | 
				
			||||||
                    new String[]{grantedPermissions, permissionSign.getDuration() + " " + timeUnit}));
 | 
					                    new String[]{grantedPermissions, permissionSign.getDurationString()}));
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            player.sendMessage(StringFormatter.replacePlaceholder(StringFormatter.getTranslatedInfoMessage(
 | 
					            player.sendMessage(StringFormatter.replacePlaceholder(StringFormatter.getTranslatedInfoMessage(
 | 
				
			||||||
                    TranslatableMessage.PERMISSIONS_GRANTED_PERMANENTLY), "{permissions}", grantedPermissions));
 | 
					                    TranslatableMessage.PERMISSIONS_GRANTED_PERMANENTLY), "{permissions}", grantedPermissions));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,6 @@ import java.io.BufferedReader;
 | 
				
			|||||||
import java.io.FileNotFoundException;
 | 
					import java.io.FileNotFoundException;
 | 
				
			||||||
import java.io.InputStream;
 | 
					import java.io.InputStream;
 | 
				
			||||||
import java.io.InputStreamReader;
 | 
					import java.io.InputStreamReader;
 | 
				
			||||||
import java.io.UnsupportedEncodingException;
 | 
					 | 
				
			||||||
import java.nio.charset.StandardCharsets;
 | 
					import java.nio.charset.StandardCharsets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -18,7 +17,7 @@ public class FileHelper {
 | 
				
			|||||||
     * @return <p>A buffered read for reading the file</p>
 | 
					     * @return <p>A buffered read for reading the file</p>
 | 
				
			||||||
     * @throws FileNotFoundException <p>If unable to get an input stream for the given file</p>
 | 
					     * @throws FileNotFoundException <p>If unable to get an input stream for the given file</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static BufferedReader getBufferedReaderForInternalFile(String file) throws FileNotFoundException, UnsupportedEncodingException {
 | 
					    public static BufferedReader getBufferedReaderForInternalFile(String file) throws FileNotFoundException {
 | 
				
			||||||
        InputStream inputStream = FileHelper.class.getResourceAsStream(file);
 | 
					        InputStream inputStream = FileHelper.class.getResourceAsStream(file);
 | 
				
			||||||
        if (inputStream == null) {
 | 
					        if (inputStream == null) {
 | 
				
			||||||
            throw new FileNotFoundException("Unable to read the given file");
 | 
					            throw new FileNotFoundException("Unable to read the given file");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,13 +2,21 @@ en:
 | 
				
			|||||||
  PREFIX: "[PermissionSigns]"
 | 
					  PREFIX: "[PermissionSigns]"
 | 
				
			||||||
  SIGN_PREFIX: "&4[PermSign]"
 | 
					  SIGN_PREFIX: "&4[PermSign]"
 | 
				
			||||||
  MISSING_CREATION_INFO: "&7You must specify a sign name and a comma-separated list of permissions to create a permission sign"
 | 
					  MISSING_CREATION_INFO: "&7You must specify a sign name and a comma-separated list of permissions to create a permission sign"
 | 
				
			||||||
  SIGN_TIME_UNIT: "seconds"
 | 
					  UNIT_SECOND: "second"
 | 
				
			||||||
 | 
					  UNIT_SECONDS: "seconds"
 | 
				
			||||||
 | 
					  UNIT_MINUTE: "minute"
 | 
				
			||||||
 | 
					  UNIT_MINUTES: "minutes"
 | 
				
			||||||
 | 
					  UNIT_HOUR: "hour"
 | 
				
			||||||
 | 
					  UNIT_HOURS: "hours"
 | 
				
			||||||
 | 
					  UNIT_DAY: "day"
 | 
				
			||||||
 | 
					  UNIT_DAYS: "days"
 | 
				
			||||||
  SIGN_PERMANENT: "Permanent"
 | 
					  SIGN_PERMANENT: "Permanent"
 | 
				
			||||||
  SIGN_COST_FREE: "Free"
 | 
					  SIGN_COST_FREE: "Free"
 | 
				
			||||||
  COST_INVALID_NUMBER: "&7The given cost is not a valid number"
 | 
					  COST_INVALID_NUMBER: "&7The given cost is not a valid number"
 | 
				
			||||||
  DURATION_INVALID_NUMBER: "&7The given duration is not a valid number"
 | 
					  DURATION_INVALID_NUMBER: "&7The given duration is not a valid number"
 | 
				
			||||||
  COMMAND_PLAYER_ONLY: "&7This command is only available to players"
 | 
					  COMMAND_PLAYER_ONLY: "&7This command is only available to players"
 | 
				
			||||||
  PERMISSION_SIGN_DESTROY_DENY: "&7You do not have permissions to delete permissions signs"
 | 
					  PERMISSION_SIGN_DESTROY_DENY: "&7You do not have permissions to delete permissions signs"
 | 
				
			||||||
 | 
					  PERMISSION_SIGN_DESTROY_SNEAK: "&7You must be sneaking to remove a permissions sign"
 | 
				
			||||||
  PERMISSION_SIGN_REMOVED: "&7Permissions sign removed"
 | 
					  PERMISSION_SIGN_REMOVED: "&7Permissions sign removed"
 | 
				
			||||||
  COMMAND_PERMISSION_DENIED: "&7You do not have necessary permissions to perform this command"
 | 
					  COMMAND_PERMISSION_DENIED: "&7You do not have necessary permissions to perform this command"
 | 
				
			||||||
  CREATION_REQUEST_CREATED: "&7Permission Sign request created. Right-click an empty sign within 60 seconds to create the new permission sign"
 | 
					  CREATION_REQUEST_CREATED: "&7Permission Sign request created. Right-click an empty sign within 60 seconds to create the new permission sign"
 | 
				
			||||||
@@ -21,17 +29,26 @@ en:
 | 
				
			|||||||
  INTERACT_PERMISSION_MISSING: "&7You do not have the necessary permissions required to use permission signs"
 | 
					  INTERACT_PERMISSION_MISSING: "&7You do not have the necessary permissions required to use permission signs"
 | 
				
			||||||
  CREATION_REQUEST_CANCELLED: "&7Your last permission sign creation request has been cancelled"
 | 
					  CREATION_REQUEST_CANCELLED: "&7Your last permission sign creation request has been cancelled"
 | 
				
			||||||
  RELOAD_SUCCESSFUL: "&7The plugin has been successfully reloaded"
 | 
					  RELOAD_SUCCESSFUL: "&7The plugin has been successfully reloaded"
 | 
				
			||||||
 | 
					  SIGN_INFO: "&f---- &4Permission Sign&f ----\n&f| &bName: &7{Name}\n&f| &bPermission(s): &7{Permissions}\n&f| &bCost: &7{Cost}\n&f| &bDuration: &7{Duration}\n&f| &7Right-click the sign while sneaking to buy the permission(s)\n&f-------------------------"
 | 
				
			||||||
nb-no:
 | 
					nb-no:
 | 
				
			||||||
  PREFIX: "[Tilgangsrettighetsskilt]"
 | 
					  PREFIX: "[Tilgangsrettighetsskilt]"
 | 
				
			||||||
  SIGN_PREFIX: "&4[PermSign]"
 | 
					  SIGN_PREFIX: "&4[PermSign]"
 | 
				
			||||||
  MISSING_CREATION_INFO: "&7Du må spesifisere et skiltnavn og en komma-separert liste av tilgangsrettigheter for å opprette et tilgangsrettighetsskilt"
 | 
					  MISSING_CREATION_INFO: "&7Du må spesifisere et skiltnavn og en komma-separert liste av tilgangsrettigheter for å opprette et tilgangsrettighetsskilt"
 | 
				
			||||||
  SIGN_TIME_UNIT: "sekunder"
 | 
					  UNIT_SECOND: "sekund"
 | 
				
			||||||
 | 
					  UNIT_SECONDS: "sekunder"
 | 
				
			||||||
 | 
					  UNIT_MINUTE: "minutt"
 | 
				
			||||||
 | 
					  UNIT_MINUTES: "minutter"
 | 
				
			||||||
 | 
					  UNIT_HOUR: "time"
 | 
				
			||||||
 | 
					  UNIT_HOURS: "timer"
 | 
				
			||||||
 | 
					  UNIT_DAY: "dag"
 | 
				
			||||||
 | 
					  UNIT_DAYS: "dager"
 | 
				
			||||||
  SIGN_PERMANENT: "Permanent"
 | 
					  SIGN_PERMANENT: "Permanent"
 | 
				
			||||||
  SIGN_COST_FREE: "Gratis"
 | 
					  SIGN_COST_FREE: "Gratis"
 | 
				
			||||||
  COST_INVALID_NUMBER: "&7Den gitte kostnaden er ikke et gyldig nummer"
 | 
					  COST_INVALID_NUMBER: "&7Den gitte kostnaden er ikke et gyldig nummer"
 | 
				
			||||||
  DURATION_INVALID_NUMBER: "&7Den gitte varigheten er ikke et gyldig nummer"
 | 
					  DURATION_INVALID_NUMBER: "&7Den gitte varigheten er ikke et gyldig nummer"
 | 
				
			||||||
  COMMAND_PLAYER_ONLY: "&7Denne kommandoen kan bare brukes av spillere"
 | 
					  COMMAND_PLAYER_ONLY: "&7Denne kommandoen kan bare brukes av spillere"
 | 
				
			||||||
  PERMISSION_SIGN_DESTROY_DENY: "&7Du har ikke tillatelse til å ødelegge tilgangsrettighetsskilter"
 | 
					  PERMISSION_SIGN_DESTROY_DENY: "&7Du har ikke tillatelse til å ødelegge tilgangsrettighetsskilter"
 | 
				
			||||||
 | 
					  PERMISSION_SIGN_DESTROY_SNEAK: "&7Du må snike for å fjerne et tilgangsrettighetsskilt"
 | 
				
			||||||
  PERMISSION_SIGN_REMOVED: "&7Tilgangsrettighetsskilt fjernet"
 | 
					  PERMISSION_SIGN_REMOVED: "&7Tilgangsrettighetsskilt fjernet"
 | 
				
			||||||
  COMMAND_PERMISSION_DENIED: "&7Du har ikke de nødvendige tilgangsrettighetene for å kjøre denne kommandoen"
 | 
					  COMMAND_PERMISSION_DENIED: "&7Du har ikke de nødvendige tilgangsrettighetene for å kjøre denne kommandoen"
 | 
				
			||||||
  CREATION_REQUEST_CREATED: "&7Tilgangsrettighetsskiltsforespørsel opprettet. Høyre-klikk på et tomt skilt innen 60 sekunder for å opprette det nye tilgangsrettighetsskiltet"
 | 
					  CREATION_REQUEST_CREATED: "&7Tilgangsrettighetsskiltsforespørsel opprettet. Høyre-klikk på et tomt skilt innen 60 sekunder for å opprette det nye tilgangsrettighetsskiltet"
 | 
				
			||||||
@@ -44,3 +61,4 @@ nb-no:
 | 
				
			|||||||
  INTERACT_PERMISSION_MISSING: "&7Du har ikke de nødvendige tilgangsrettighetene for å bruke tilgangsrettighetsskilt"
 | 
					  INTERACT_PERMISSION_MISSING: "&7Du har ikke de nødvendige tilgangsrettighetene for å bruke tilgangsrettighetsskilt"
 | 
				
			||||||
  CREATION_REQUEST_CANCELLED: "&7Din siste tilgangsrettighetsskiltsforespørsel har blitt kansellert"
 | 
					  CREATION_REQUEST_CANCELLED: "&7Din siste tilgangsrettighetsskiltsforespørsel har blitt kansellert"
 | 
				
			||||||
  RELOAD_SUCCESSFUL: "&7Plugin-modulen har blitt lastet inn på nytt"
 | 
					  RELOAD_SUCCESSFUL: "&7Plugin-modulen har blitt lastet inn på nytt"
 | 
				
			||||||
 | 
					  SIGN_INFO: "&f---- &4Tilgangsrettighetsskilt&f ----\n&f| &bNavn: &7{Name}\n&f| &bTilgangsrettighet(er): &7{Permissions}\n&f| &bKostnad: &7{Cost}\n&f| &bVarighet: &7{Duration}\n&f| &7Høyreklikk skiltet mens du sniker for å kjøpe tilgangsrettighet(en/ene)\n&f-------------------------"
 | 
				
			||||||
		Reference in New Issue
	
	Block a user