Compare commits
	
		
			23 Commits
		
	
	
		
			0.1.0-ALPH
			...
			0.2.0-ALPH
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 996d062674 | |||
| 990339499a | |||
| 3b7268d2ff | |||
| 91d477b45a | |||
| 0f958f0908 | |||
| 36678fd2d0 | |||
| 4e44909f80 | |||
| 0ad953cc14 | |||
| db869c0c5b | |||
| 8a030276c5 | |||
| 7e01d77723 | |||
| 86cb1c0fed | |||
| 5bc62d5bc0 | |||
| 2f559ce2af | |||
| 90b5ff7304 | |||
| d76d5cdf93 | |||
| 6f35da03e7 | |||
| eaa4f929ca | |||
| 419a79bc9f | |||
| 16faa1ddb2 | |||
| d2f152334f | |||
| 4189053ed8 | |||
| 5e52e3d4de | 
							
								
								
									
										66
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										66
									
								
								README.md
									
									
									
									
									
								
							@@ -10,3 +10,69 @@ As this plugin only listens to sign change events, there are some limitations:
 | 
				
			|||||||
1. The plugin is not aware of whether the creation of a sign is successful
 | 
					1. The plugin is not aware of whether the creation of a sign is successful
 | 
				
			||||||
2. It is assumed that any protection plugins run before this plugin, but it's not guaranteed
 | 
					2. It is assumed that any protection plugins run before this plugin, but it's not guaranteed
 | 
				
			||||||
3. Plugins changing the lines on signs when successful might create confusion and mismatches
 | 
					3. Plugins changing the lines on signs when successful might create confusion and mismatches
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Commands
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* /addpaidsign <name> <cost> \[permission] \[ignore case] \[ignore color]
 | 
				
			||||||
 | 
					* /addpaidsigncondition <name (of a paid sign)> <line number> <string to match> \[executeRegEx] \[ignoreCase]
 | 
				
			||||||
 | 
					  \[ignoreColor]
 | 
				
			||||||
 | 
					* /listpaidsigns \[name (of a paid sign)] \[line number]
 | 
				
			||||||
 | 
					* /removepaidsigncondition <name (of a paid sign)> <line number>
 | 
				
			||||||
 | 
					* /removepaidsign <name (of a paid sign)>
 | 
				
			||||||
 | 
					* /reload
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Command explanation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### /addpaidsign
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This command adds a new paid sign that does nothing until a condition is added.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* name - A recognizable name only used to differentiate between registered paid signs
 | 
				
			||||||
 | 
					* cost - The cost a player need to pay to create any sign matching the paid sign
 | 
				
			||||||
 | 
					* permission - If the paid sign is used to represent a plugin sign, the permission should be the permission necessary
 | 
				
			||||||
 | 
					  for creating the plugin sign. This is used to decide if the plugin sign was created, or the player was denied.
 | 
				
			||||||
 | 
					* ignore case - Whether any conditions of the paid sign should ignore case by default, when matching against text (
 | 
				
			||||||
 | 
					  default uses the config file value).
 | 
				
			||||||
 | 
					* ignore color - Whether any condition of the paid sign should ignore color by default, when matching against text (
 | 
				
			||||||
 | 
					  default uses the config file value).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### /addpaidsigncondition
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This adds a condition to a paid sign which is used to decide if a sign created by a player matches the paid sign. Adding
 | 
				
			||||||
 | 
					a paid sign condition to a line that already has one will replace the previous condition.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* name - The name of the paid sign to add the condition to
 | 
				
			||||||
 | 
					* line number - The line on the sign (1-4) to search for any matches
 | 
				
			||||||
 | 
					* string to match - The string or regular expression to look for on a sign
 | 
				
			||||||
 | 
					* executeRegEx - Whether to use a regular expression match instead of looking for the exact string
 | 
				
			||||||
 | 
					* ignoreCase - Whether this condition should ignore case when trying to match the string (default uses the "parent"
 | 
				
			||||||
 | 
					  sign's value)
 | 
				
			||||||
 | 
					* ignoreColor - Whether this condition should ignore color when trying to match the string (default uses the "parent"
 | 
				
			||||||
 | 
					  sign's value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### /listpaidsigns
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This lists registered paid signs and paid sign conditions. No arguments will print a list of paid signs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* name - The name of the paid sign to see information about
 | 
				
			||||||
 | 
					* line number - The line number of the condition to see information about
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### /removepaidsigncondition
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Removes a paid sign condition from a sign
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* name - The name of the paid sign to remove the condition from
 | 
				
			||||||
 | 
					* line number - The line the condition is associated with
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### /removepaidsign
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Removes a registered paid sign
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* name - The name of the paid sign to remove
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Permissions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* paidsigns.* - Grants all paid signs permissions
 | 
				
			||||||
 | 
					* paidsigns.manage - Grants the permission to add/remove a paid sign
 | 
				
			||||||
 | 
					* paidsigns.reload - Grants the permissions to reload the plugin
 | 
				
			||||||
 | 
					* paidsigns.paymentexempt - Makes this player exempt from the cost of paid signs
 | 
				
			||||||
							
								
								
									
										2
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								pom.xml
									
									
									
									
									
								
							@@ -6,7 +6,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    <groupId>net.knarcraft</groupId>
 | 
					    <groupId>net.knarcraft</groupId>
 | 
				
			||||||
    <artifactId>paidsigns</artifactId>
 | 
					    <artifactId>paidsigns</artifactId>
 | 
				
			||||||
    <version>1.0-SNAPSHOT</version>
 | 
					    <version>0.2.0-ALPHA</version>
 | 
				
			||||||
    <packaging>jar</packaging>
 | 
					    <packaging>jar</packaging>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <name>Paid Signs</name>
 | 
					    <name>Paid Signs</name>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,15 @@
 | 
				
			|||||||
package net.knarcraft.paidsigns;
 | 
					package net.knarcraft.paidsigns;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import net.knarcraft.paidsigns.command.AddCommand;
 | 
					import net.knarcraft.paidsigns.command.AddCommand;
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.command.AddConditionCommand;
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.command.AddConditionTabCompleter;
 | 
				
			||||||
import net.knarcraft.paidsigns.command.AddTabCompleter;
 | 
					import net.knarcraft.paidsigns.command.AddTabCompleter;
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.command.ListCommand;
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.command.ListTabCompleter;
 | 
				
			||||||
import net.knarcraft.paidsigns.command.ReloadTabCommand;
 | 
					import net.knarcraft.paidsigns.command.ReloadTabCommand;
 | 
				
			||||||
import net.knarcraft.paidsigns.command.RemoveCommand;
 | 
					import net.knarcraft.paidsigns.command.RemoveConditionCommand;
 | 
				
			||||||
import net.knarcraft.paidsigns.command.RemoveTabCompleter;
 | 
					import net.knarcraft.paidsigns.command.RemoveConditionTabCompleter;
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.command.RemoveTabCommand;
 | 
				
			||||||
import net.knarcraft.paidsigns.listener.SignListener;
 | 
					import net.knarcraft.paidsigns.listener.SignListener;
 | 
				
			||||||
import net.knarcraft.paidsigns.manager.EconomyManager;
 | 
					import net.knarcraft.paidsigns.manager.EconomyManager;
 | 
				
			||||||
import net.knarcraft.paidsigns.manager.PaidSignManager;
 | 
					import net.knarcraft.paidsigns.manager.PaidSignManager;
 | 
				
			||||||
@@ -106,10 +111,29 @@ public final class PaidSigns extends JavaPlugin {
 | 
				
			|||||||
            addCommand.setTabCompleter(new AddTabCompleter());
 | 
					            addCommand.setTabCompleter(new AddTabCompleter());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        PluginCommand listCommand = this.getCommand("listPaidSigns");
 | 
				
			||||||
 | 
					        if (listCommand != null) {
 | 
				
			||||||
 | 
					            listCommand.setExecutor(new ListCommand());
 | 
				
			||||||
 | 
					            listCommand.setTabCompleter(new ListTabCompleter());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        PluginCommand addConditionCommand = this.getCommand("addPaidSignCondition");
 | 
				
			||||||
 | 
					        if (addConditionCommand != null) {
 | 
				
			||||||
 | 
					            addConditionCommand.setExecutor(new AddConditionCommand());
 | 
				
			||||||
 | 
					            addConditionCommand.setTabCompleter(new AddConditionTabCompleter());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        PluginCommand removeConditionCommand = this.getCommand("removePaidSignCondition");
 | 
				
			||||||
 | 
					        if (removeConditionCommand != null) {
 | 
				
			||||||
 | 
					            removeConditionCommand.setExecutor(new RemoveConditionCommand());
 | 
				
			||||||
 | 
					            removeConditionCommand.setTabCompleter(new RemoveConditionTabCompleter());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        PluginCommand removeCommand = this.getCommand("removePaidSign");
 | 
					        PluginCommand removeCommand = this.getCommand("removePaidSign");
 | 
				
			||||||
        if (removeCommand != null) {
 | 
					        if (removeCommand != null) {
 | 
				
			||||||
            removeCommand.setExecutor(new RemoveCommand());
 | 
					            TabExecutor removeTabExecutor = new RemoveTabCommand();
 | 
				
			||||||
            removeCommand.setTabCompleter(new RemoveTabCompleter());
 | 
					            removeCommand.setExecutor(removeTabExecutor);
 | 
				
			||||||
 | 
					            removeCommand.setTabCompleter(removeTabExecutor);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        PluginCommand reloadCommand = this.getCommand("reload");
 | 
					        PluginCommand reloadCommand = this.getCommand("reload");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,58 +4,71 @@ import net.knarcraft.paidsigns.PaidSigns;
 | 
				
			|||||||
import net.knarcraft.paidsigns.container.PaidSign;
 | 
					import net.knarcraft.paidsigns.container.PaidSign;
 | 
				
			||||||
import net.knarcraft.paidsigns.manager.PaidSignManager;
 | 
					import net.knarcraft.paidsigns.manager.PaidSignManager;
 | 
				
			||||||
import net.knarcraft.paidsigns.property.OptionState;
 | 
					import net.knarcraft.paidsigns.property.OptionState;
 | 
				
			||||||
import net.knarcraft.paidsigns.utility.Tokenizer;
 | 
					 | 
				
			||||||
import org.bukkit.command.Command;
 | 
					import org.bukkit.command.Command;
 | 
				
			||||||
import org.bukkit.command.CommandExecutor;
 | 
					 | 
				
			||||||
import org.bukkit.command.CommandSender;
 | 
					import org.bukkit.command.CommandSender;
 | 
				
			||||||
import org.jetbrains.annotations.NotNull;
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
import java.util.Arrays;
 | 
					import java.util.Arrays;
 | 
				
			||||||
import java.util.List;
 | 
					 | 
				
			||||||
import java.util.logging.Level;
 | 
					import java.util.logging.Level;
 | 
				
			||||||
import java.util.logging.Logger;
 | 
					import java.util.logging.Logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * A representation of the command for adding a new paid sign
 | 
					 * A representation of the command for adding a new paid sign
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public class AddCommand implements CommandExecutor {
 | 
					public class AddCommand extends TokenizedCommand {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
 | 
					    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
 | 
				
			||||||
                             @NotNull String[] args) {
 | 
					                             @NotNull String[] args) {
 | 
				
			||||||
        if (args.length < 3) {
 | 
					        super.onCommand(sender, command, label, args);
 | 
				
			||||||
 | 
					        if (argumentSize < 2) {
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        PaidSignManager manager = PaidSigns.getInstance().getSignManager();
 | 
					 | 
				
			||||||
        List<String> arguments = Tokenizer.tokenize(String.join(" ", args));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        String id = arguments.get(0);
 | 
					        String signName = arguments.get(0).trim();
 | 
				
			||||||
        short line;
 | 
					 | 
				
			||||||
        double cost;
 | 
					        double cost;
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            line = (short) (Short.parseShort(arguments.get(1)) - 1);
 | 
					            cost = Double.parseDouble(arguments.get(1));
 | 
				
			||||||
            cost = Double.parseDouble(arguments.get(2));
 | 
					 | 
				
			||||||
        } catch (NumberFormatException exception) {
 | 
					        } catch (NumberFormatException exception) {
 | 
				
			||||||
            sender.sendMessage("You provided an invalid number");
 | 
					            sender.sendMessage("You provided an invalid number");
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        String permission = "";
 | 
				
			||||||
 | 
					        if (argumentSize > 2) {
 | 
				
			||||||
 | 
					            permission = arguments.get(2);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        OptionState ignoreCase = OptionState.DEFAULT;
 | 
					        OptionState ignoreCase = OptionState.DEFAULT;
 | 
				
			||||||
        OptionState ignoreColor = OptionState.DEFAULT;
 | 
					        OptionState ignoreColor = OptionState.DEFAULT;
 | 
				
			||||||
        if (arguments.size() > 3) {
 | 
					        if (argumentSize > 3) {
 | 
				
			||||||
            ignoreCase = OptionState.fromString(arguments.get(3));
 | 
					            ignoreCase = OptionState.fromString(arguments.get(3));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (arguments.size() > 4) {
 | 
					        if (argumentSize > 4) {
 | 
				
			||||||
            ignoreColor = OptionState.fromString(arguments.get(4));
 | 
					            ignoreColor = OptionState.fromString(arguments.get(4));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try {
 | 
					        return createPaidSign(sender, signName, cost, permission, ignoreCase, ignoreColor);
 | 
				
			||||||
            PaidSign sign = new PaidSign(id, line, cost, ignoreCase, ignoreColor);
 | 
					 | 
				
			||||||
            for (PaidSign similarSign : manager.getPaidSigns(sign.getCleanId(), sign.getLineIndex())) {
 | 
					 | 
				
			||||||
                if (sign.matches(similarSign)) {
 | 
					 | 
				
			||||||
                    sender.sendMessage("A paid sign with the same id and line already exists");
 | 
					 | 
				
			||||||
                    return false;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Creates a new paid sign with the given user input
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param sender      <p>The command sender that called the add command</p>
 | 
				
			||||||
 | 
					     * @param signName    <p>The name of the new paid sign</p>
 | 
				
			||||||
 | 
					     * @param cost        <p>The cost of the new paid sign</p>
 | 
				
			||||||
 | 
					     * @param permission  <p>The permission required for creating the sign represented by the paid sign</p>
 | 
				
			||||||
 | 
					     * @param ignoreCase  <p>Whether to ignore case for the paid sign's conditions</p>
 | 
				
			||||||
 | 
					     * @param ignoreColor <p>Whether to ignore color for the paid sign's conditions</p>
 | 
				
			||||||
 | 
					     * @return <p>True if the paid sign was successfully created and registered</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private boolean createPaidSign(CommandSender sender, String signName, double cost, String permission,
 | 
				
			||||||
 | 
					                                   OptionState ignoreCase, OptionState ignoreColor) {
 | 
				
			||||||
 | 
					        PaidSignManager manager = PaidSigns.getInstance().getSignManager();
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            PaidSign sign = new PaidSign(signName, cost, permission, ignoreCase, ignoreColor);
 | 
				
			||||||
 | 
					            if (manager.getPaidSign(signName) != null) {
 | 
				
			||||||
 | 
					                sender.sendMessage("A paid sign with the same name already exists");
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            manager.addPaidSign(sign);
 | 
					            manager.addPaidSign(sign);
 | 
				
			||||||
            sender.sendMessage("Successfully added new paid sign");
 | 
					            sender.sendMessage("Successfully added new paid sign");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,69 @@
 | 
				
			|||||||
 | 
					package net.knarcraft.paidsigns.command;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.PaidSigns;
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.container.PaidSign;
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.manager.PaidSignManager;
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.property.OptionState;
 | 
				
			||||||
 | 
					import org.bukkit.command.Command;
 | 
				
			||||||
 | 
					import org.bukkit.command.CommandSender;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					import java.util.Arrays;
 | 
				
			||||||
 | 
					import java.util.logging.Level;
 | 
				
			||||||
 | 
					import java.util.logging.Logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A representation of the command for adding a new match condition for a sign
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class AddConditionCommand extends TokenizedCommand {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
 | 
				
			||||||
 | 
					        super.onCommand(sender, command, label, args);
 | 
				
			||||||
 | 
					        if (argumentSize < 3) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        String name = arguments.get(0);
 | 
				
			||||||
 | 
					        short lineNumber;
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            lineNumber = (short) (Short.parseShort(arguments.get(1)) - 1);
 | 
				
			||||||
 | 
					        } catch (NumberFormatException exception) {
 | 
				
			||||||
 | 
					            sender.sendMessage("Invalid line number given");
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        String stringToMatch = arguments.get(2);
 | 
				
			||||||
 | 
					        boolean executeRegEx = false;
 | 
				
			||||||
 | 
					        if (argumentSize > 3) {
 | 
				
			||||||
 | 
					            executeRegEx = Boolean.parseBoolean(arguments.get(3));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        OptionState ignoreCase = OptionState.DEFAULT;
 | 
				
			||||||
 | 
					        if (argumentSize > 4) {
 | 
				
			||||||
 | 
					            ignoreCase = OptionState.getFromBoolean(Boolean.parseBoolean(arguments.get(4)));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        OptionState ignoreColor = OptionState.DEFAULT;
 | 
				
			||||||
 | 
					        if (argumentSize > 5) {
 | 
				
			||||||
 | 
					            ignoreColor = OptionState.getFromBoolean(Boolean.parseBoolean(arguments.get(5)));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        PaidSignManager signManager = PaidSigns.getInstance().getSignManager();
 | 
				
			||||||
 | 
					        PaidSign sign = signManager.getPaidSign(name);
 | 
				
			||||||
 | 
					        if (sign == null) {
 | 
				
			||||||
 | 
					            sender.sendMessage("No such paid sign exists");
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        sign.addCondition(lineNumber, stringToMatch, executeRegEx, ignoreCase, ignoreColor);
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            signManager.saveSigns();
 | 
				
			||||||
 | 
					        } catch (IOException e) {
 | 
				
			||||||
 | 
					            Logger logger = PaidSigns.getInstance().getLogger();
 | 
				
			||||||
 | 
					            logger.log(Level.SEVERE, "Exception encountered while trying to write to the data file");
 | 
				
			||||||
 | 
					            logger.log(Level.SEVERE, Arrays.toString(e.getStackTrace()));
 | 
				
			||||||
 | 
					            sender.sendMessage("An exception occurred. Please notify the server administrator or check the server log.");
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        sender.sendMessage("Condition added");
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					package net.knarcraft.paidsigns.command;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.utility.TabCompleteHelper;
 | 
				
			||||||
 | 
					import org.bukkit.command.Command;
 | 
				
			||||||
 | 
					import org.bukkit.command.CommandSender;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.Nullable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * The tab completer for the add paid sign condition command
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class AddConditionTabCompleter extends TokenizedTabCompleter {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private List<String> lineIndices;
 | 
				
			||||||
 | 
					    private List<String> stringsToMatch;
 | 
				
			||||||
 | 
					    private List<String> booleans;
 | 
				
			||||||
 | 
					    private List<String> optionStates;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nullable
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias,
 | 
				
			||||||
 | 
					                                      @NotNull String[] args) {
 | 
				
			||||||
 | 
					        super.onTabComplete(sender, command, alias, args);
 | 
				
			||||||
 | 
					        if (lineIndices == null) {
 | 
				
			||||||
 | 
					            initializeValues();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (argumentSize == 1) {
 | 
				
			||||||
 | 
					            return TabCompleteHelper.filterMatchingStartsWith(TabCompleteHelper.getPaidSignNames(), arguments.get(0));
 | 
				
			||||||
 | 
					        } else if (argumentSize == 2) {
 | 
				
			||||||
 | 
					            return TabCompleteHelper.filterMatchingStartsWith(this.lineIndices, arguments.get(1));
 | 
				
			||||||
 | 
					        } else if (argumentSize == 3) {
 | 
				
			||||||
 | 
					            return TabCompleteHelper.filterMatchingStartsWith(stringsToMatch, arguments.get(2));
 | 
				
			||||||
 | 
					        } else if (argumentSize == 4) {
 | 
				
			||||||
 | 
					            return TabCompleteHelper.filterMatchingStartsWith(booleans, arguments.get(3));
 | 
				
			||||||
 | 
					        } else if (argumentSize == 5) {
 | 
				
			||||||
 | 
					            return TabCompleteHelper.filterMatchingStartsWith(optionStates, arguments.get(4));
 | 
				
			||||||
 | 
					        } else if (argumentSize == 6) {
 | 
				
			||||||
 | 
					            return TabCompleteHelper.filterMatchingStartsWith(optionStates, arguments.get(5));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return new ArrayList<>();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Initializes the values available for tab completion
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private void initializeValues() {
 | 
				
			||||||
 | 
					        lineIndices = TabCompleteHelper.getSignLines();
 | 
				
			||||||
 | 
					        stringsToMatch = TabCompleteHelper.getExampleConditionStrings();
 | 
				
			||||||
 | 
					        booleans = TabCompleteHelper.getBooleans();
 | 
				
			||||||
 | 
					        optionStates = TabCompleteHelper.getOptionStates();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,71 +1,136 @@
 | 
				
			|||||||
package net.knarcraft.paidsigns.command;
 | 
					package net.knarcraft.paidsigns.command;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import net.knarcraft.paidsigns.utility.Tokenizer;
 | 
					import net.knarcraft.paidsigns.utility.TabCompleteHelper;
 | 
				
			||||||
 | 
					import org.bukkit.Bukkit;
 | 
				
			||||||
import org.bukkit.command.Command;
 | 
					import org.bukkit.command.Command;
 | 
				
			||||||
import org.bukkit.command.CommandSender;
 | 
					import org.bukkit.command.CommandSender;
 | 
				
			||||||
import org.bukkit.command.TabCompleter;
 | 
					import org.bukkit.permissions.Permission;
 | 
				
			||||||
import org.jetbrains.annotations.NotNull;
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
import org.jetbrains.annotations.Nullable;
 | 
					import org.jetbrains.annotations.Nullable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.HashMap;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					import java.util.StringJoiner;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * The tab completer for the add paid sign command
 | 
					 * The tab completer for the add paid sign command
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public class AddTabCompleter implements TabCompleter {
 | 
					public class AddTabCompleter extends TokenizedTabCompleter {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static List<String> ids;
 | 
					    private static List<String> names;
 | 
				
			||||||
    private static List<String> lines;
 | 
					 | 
				
			||||||
    private static List<String> costs;
 | 
					    private static List<String> costs;
 | 
				
			||||||
 | 
					    private static List<String> plugins;
 | 
				
			||||||
 | 
					    private static Map<String, List<String>> permissions;
 | 
				
			||||||
    private static List<String> options;
 | 
					    private static List<String> options;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Nullable
 | 
					    @Nullable
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias,
 | 
					    public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias,
 | 
				
			||||||
                                      @NotNull String[] args) {
 | 
					                                      @NotNull String[] args) {
 | 
				
			||||||
        if (ids == null) {
 | 
					        super.onTabComplete(sender, command, alias, args);
 | 
				
			||||||
 | 
					        if (names == null) {
 | 
				
			||||||
            initializeValues();
 | 
					            initializeValues();
 | 
				
			||||||
 | 
					            loadAvailablePermissions();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        List<String> arguments = Tokenizer.tokenize(String.join(" ", args));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (arguments.size() < 1) {
 | 
					        if (argumentSize == 1) {
 | 
				
			||||||
            return ids;
 | 
					            return TabCompleteHelper.filterMatchingStartsWith(names, arguments.get(0));
 | 
				
			||||||
        } else if (arguments.size() < 2) {
 | 
					        } else if (argumentSize == 2) {
 | 
				
			||||||
            return lines;
 | 
					            return TabCompleteHelper.filterMatchingStartsWith(costs, arguments.get(1));
 | 
				
			||||||
        } else if (arguments.size() < 3) {
 | 
					        } else if (argumentSize == 3) {
 | 
				
			||||||
            return costs;
 | 
					            return tabCompletePermission(arguments.get(arguments.size() - 1));
 | 
				
			||||||
        } else if (arguments.size() < 5) {
 | 
					        } else if (argumentSize == 4) {
 | 
				
			||||||
            return options;
 | 
					            return TabCompleteHelper.filterMatchingStartsWith(options, arguments.get(3));
 | 
				
			||||||
 | 
					        } else if (argumentSize == 5) {
 | 
				
			||||||
 | 
					            return TabCompleteHelper.filterMatchingStartsWith(options, arguments.get(4));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return new ArrayList<>();
 | 
					        return new ArrayList<>();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Gets the tab complete value for the permission typed
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param typedNode <p>The full permission node typed by the player</p>
 | 
				
			||||||
 | 
					     * @return <p>All known valid auto-complete options</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private List<String> tabCompletePermission(String typedNode) {
 | 
				
			||||||
 | 
					        List<String> output;
 | 
				
			||||||
 | 
					        if (typedNode.contains(".")) {
 | 
				
			||||||
 | 
					            List<String> matchingPermissions = permissions.get(typedNode.substring(0, typedNode.lastIndexOf(".")));
 | 
				
			||||||
 | 
					            if (matchingPermissions == null) {
 | 
				
			||||||
 | 
					                output = new ArrayList<>();
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                //Filter by the typed text
 | 
				
			||||||
 | 
					                output = filterMatching(matchingPermissions, typedNode);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            output = plugins;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //Add previous permissions in the comma-separated lists as a prefix
 | 
				
			||||||
 | 
					        return output;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Find completable strings which match the text typed by the command's sender
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param values    <p>The values to filter</p>
 | 
				
			||||||
 | 
					     * @param typedText <p>The text the player has started typing</p>
 | 
				
			||||||
 | 
					     * @return <p>The given string values which start with the player's typed text</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private List<String> filterMatching(List<String> values, String typedText) {
 | 
				
			||||||
 | 
					        List<String> configValues = new ArrayList<>();
 | 
				
			||||||
 | 
					        for (String value : values) {
 | 
				
			||||||
 | 
					            if (value.toLowerCase().startsWith(typedText.toLowerCase())) {
 | 
				
			||||||
 | 
					                configValues.add(value);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return configValues;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Loads all permissions available from bukkit plugins
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private static void loadAvailablePermissions() {
 | 
				
			||||||
 | 
					        plugins = new ArrayList<>();
 | 
				
			||||||
 | 
					        permissions = new HashMap<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (Permission permission : Bukkit.getPluginManager().getPermissions()) {
 | 
				
			||||||
 | 
					            loadPermission(permission.getName());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Loads a given permission into the proper lists and maps
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param permissionName <p>The permission to load</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private static void loadPermission(String permissionName) {
 | 
				
			||||||
 | 
					        String[] permissionParts = permissionName.split("\\.");
 | 
				
			||||||
 | 
					        if (permissionParts.length == 1 && !plugins.contains(permissionParts[0])) {
 | 
				
			||||||
 | 
					            plugins.add(permissionParts[0]);
 | 
				
			||||||
 | 
					        } else if (permissionParts.length > 1) {
 | 
				
			||||||
 | 
					            StringJoiner pathJoiner = new StringJoiner(".");
 | 
				
			||||||
 | 
					            for (int j = 0; j < permissionParts.length - 1; j++) {
 | 
				
			||||||
 | 
					                pathJoiner.add(permissionParts[j]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            String path = pathJoiner.toString();
 | 
				
			||||||
 | 
					            List<String> permissionList = permissions.computeIfAbsent(path, k -> new ArrayList<>());
 | 
				
			||||||
 | 
					            permissionList.add(permissionName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            loadPermission(path);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Initializes the values available for tab completion
 | 
					     * Initializes the values available for tab completion
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private static void initializeValues() {
 | 
					    private static void initializeValues() {
 | 
				
			||||||
        ids = new ArrayList<>();
 | 
					        names = TabCompleteHelper.getExamplePaidSignNames();
 | 
				
			||||||
        ids.add("[Gate]");
 | 
					        costs = TabCompleteHelper.getCosts();
 | 
				
			||||||
        ids.add("\"[Lift Up]\"");
 | 
					        options = TabCompleteHelper.getOptionStates();
 | 
				
			||||||
        ids.add("\"[Lift Down]\"");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        lines = new ArrayList<>();
 | 
					 | 
				
			||||||
        lines.add("1");
 | 
					 | 
				
			||||||
        lines.add("2");
 | 
					 | 
				
			||||||
        lines.add("3");
 | 
					 | 
				
			||||||
        lines.add("4");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        costs = new ArrayList<>();
 | 
					 | 
				
			||||||
        costs.add("1");
 | 
					 | 
				
			||||||
        costs.add("5");
 | 
					 | 
				
			||||||
        costs.add("10");
 | 
					 | 
				
			||||||
        costs.add("15");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        options = new ArrayList<>();
 | 
					 | 
				
			||||||
        options.add("default");
 | 
					 | 
				
			||||||
        options.add("true");
 | 
					 | 
				
			||||||
        options.add("false");
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										104
									
								
								src/main/java/net/knarcraft/paidsigns/command/ListCommand.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								src/main/java/net/knarcraft/paidsigns/command/ListCommand.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,104 @@
 | 
				
			|||||||
 | 
					package net.knarcraft.paidsigns.command;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.PaidSigns;
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.container.PaidSign;
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.container.PaidSignCondition;
 | 
				
			||||||
 | 
					import org.bukkit.command.Command;
 | 
				
			||||||
 | 
					import org.bukkit.command.CommandSender;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A representation of the command for listing information about paid signs
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class ListCommand extends TokenizedCommand {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
 | 
				
			||||||
 | 
					                             @NotNull String[] args) {
 | 
				
			||||||
 | 
					        super.onCommand(sender, command, label, args);
 | 
				
			||||||
 | 
					        if (argumentSize < 1) {
 | 
				
			||||||
 | 
					            sender.sendMessage("Paid signs:");
 | 
				
			||||||
 | 
					            for (String signName : PaidSigns.getInstance().getSignManager().getAllPaidSigns().keySet()) {
 | 
				
			||||||
 | 
					                sender.sendMessage(" | " + signName);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        } else if (argumentSize < 3) {
 | 
				
			||||||
 | 
					            return parsePaidSignSelection(sender);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Parses the given input and displays the wanted paid-sign information
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param sender <p>The command sender to display the information to</p>
 | 
				
			||||||
 | 
					     * @return <p>True if successful. False if the input contained errors</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private boolean parsePaidSignSelection(CommandSender sender) {
 | 
				
			||||||
 | 
					        PaidSign paidSign = PaidSigns.getInstance().getSignManager().getPaidSign(arguments.get(0));
 | 
				
			||||||
 | 
					        if (paidSign == null) {
 | 
				
			||||||
 | 
					            sender.sendMessage("No such paid sign");
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (argumentSize < 2) {
 | 
				
			||||||
 | 
					            displayPaidSign(sender, paidSign);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            short signLine;
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                signLine = (short) (Short.parseShort(arguments.get(1)) - 1);
 | 
				
			||||||
 | 
					            } catch (NumberFormatException exception) {
 | 
				
			||||||
 | 
					                sender.sendMessage("Invalid number given");
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (!paidSign.getConditions().containsKey(signLine)) {
 | 
				
			||||||
 | 
					                sender.sendMessage("The paid sign you specified has no condition for line " + signLine);
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            PaidSignCondition condition = paidSign.getConditions().get(signLine);
 | 
				
			||||||
 | 
					            displayPaidSignCondition(sender, paidSign.getName(), signLine, condition);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Displays information about a paid sign condition
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param sender    <p>The command sender to display the information to</p>
 | 
				
			||||||
 | 
					     * @param signName  <p>The name of the sign to display the condition for</p>
 | 
				
			||||||
 | 
					     * @param signLine  <p>The line the condition is for</p>
 | 
				
			||||||
 | 
					     * @param condition <p>The condition to display information about</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private void displayPaidSignCondition(CommandSender sender, String signName, short signLine,
 | 
				
			||||||
 | 
					                                          PaidSignCondition condition) {
 | 
				
			||||||
 | 
					        sender.sendMessage("Paid sign condition info: ");
 | 
				
			||||||
 | 
					        sender.sendMessage("Paid sign name: " + signName);
 | 
				
			||||||
 | 
					        sender.sendMessage("Condition line: " + signLine);
 | 
				
			||||||
 | 
					        sender.sendMessage("Condition match string: " + condition.getStringToMatch());
 | 
				
			||||||
 | 
					        sender.sendMessage("Execute RegEx: " + condition.executeRegex());
 | 
				
			||||||
 | 
					        sender.sendMessage("Ignore case: " + condition.ignoreCase());
 | 
				
			||||||
 | 
					        sender.sendMessage("Ignore color: " + condition.ignoreColor());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Displays information about a paid sign
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param sender   <p>The command sender to display the information to</p>
 | 
				
			||||||
 | 
					     * @param paidSign <p>The paid sign to display information about</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private void displayPaidSign(CommandSender sender, PaidSign paidSign) {
 | 
				
			||||||
 | 
					        sender.sendMessage("Paid sign info:");
 | 
				
			||||||
 | 
					        sender.sendMessage("Name: " + paidSign.getName());
 | 
				
			||||||
 | 
					        sender.sendMessage("Cost: " + paidSign.getCost());
 | 
				
			||||||
 | 
					        sender.sendMessage("Permission: " + paidSign.getPermission());
 | 
				
			||||||
 | 
					        sender.sendMessage("Ignore case: " + paidSign.getIgnoreCase());
 | 
				
			||||||
 | 
					        sender.sendMessage("Ignore color: " + paidSign.getIgnoreColor());
 | 
				
			||||||
 | 
					        sender.sendMessage("Sign conditions: ");
 | 
				
			||||||
 | 
					        Map<Short, PaidSignCondition> conditions = paidSign.getConditions();
 | 
				
			||||||
 | 
					        for (short lineIndex : conditions.keySet()) {
 | 
				
			||||||
 | 
					            sender.sendMessage(" | " + (lineIndex + 1) + ". " + conditions.get(lineIndex).getStringToMatch());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,39 @@
 | 
				
			|||||||
 | 
					package net.knarcraft.paidsigns.command;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.PaidSigns;
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.container.PaidSign;
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.utility.TabCompleteHelper;
 | 
				
			||||||
 | 
					import org.bukkit.command.Command;
 | 
				
			||||||
 | 
					import org.bukkit.command.CommandSender;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.Nullable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * The tab completer for the list paid signs command
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class ListTabCompleter extends TokenizedTabCompleter {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nullable
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias,
 | 
				
			||||||
 | 
					                                      @NotNull String[] args) {
 | 
				
			||||||
 | 
					        super.onTabComplete(sender, command, alias, args);
 | 
				
			||||||
 | 
					        if (argumentSize == 1) {
 | 
				
			||||||
 | 
					            return TabCompleteHelper.filterMatchingStartsWith(TabCompleteHelper.getPaidSignNames(), arguments.get(0));
 | 
				
			||||||
 | 
					        } else if (argumentSize == 2) {
 | 
				
			||||||
 | 
					            PaidSign sign = PaidSigns.getInstance().getSignManager().getPaidSign(arguments.get(0));
 | 
				
			||||||
 | 
					            if (sign != null) {
 | 
				
			||||||
 | 
					                List<String> availableConditions = new ArrayList<>();
 | 
				
			||||||
 | 
					                for (Short signLine : sign.getConditions().keySet()) {
 | 
				
			||||||
 | 
					                    availableConditions.add(String.valueOf(signLine + 1));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                return TabCompleteHelper.filterMatchingStartsWith(availableConditions, arguments.get(1));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return new ArrayList<>();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					package net.knarcraft.paidsigns.command;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.PaidSigns;
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.container.PaidSign;
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.manager.PaidSignManager;
 | 
				
			||||||
 | 
					import org.bukkit.command.Command;
 | 
				
			||||||
 | 
					import org.bukkit.command.CommandSender;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					import java.util.Arrays;
 | 
				
			||||||
 | 
					import java.util.logging.Level;
 | 
				
			||||||
 | 
					import java.util.logging.Logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A representation of the command for removing a condition from a sign
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class RemoveConditionCommand extends TokenizedCommand {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
 | 
				
			||||||
 | 
					        super.onCommand(sender, command, label, args);
 | 
				
			||||||
 | 
					        if (argumentSize < 2) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        String name = arguments.get(0);
 | 
				
			||||||
 | 
					        short line;
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            line = (short) (Short.parseShort(arguments.get(1)) - 1);
 | 
				
			||||||
 | 
					        } catch (NumberFormatException exception) {
 | 
				
			||||||
 | 
					            sender.sendMessage("Invalid line number given");
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        PaidSignManager signManager = PaidSigns.getInstance().getSignManager();
 | 
				
			||||||
 | 
					        PaidSign sign = signManager.getPaidSign(name);
 | 
				
			||||||
 | 
					        if (sign == null) {
 | 
				
			||||||
 | 
					            sender.sendMessage("Invalid sign name given");
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!sign.getConditions().containsKey(line)) {
 | 
				
			||||||
 | 
					            sender.sendMessage("No condition registered for line " + (line + 1));
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        sign.removeCondition(line);
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            signManager.saveSigns();
 | 
				
			||||||
 | 
					        } catch (IOException e) {
 | 
				
			||||||
 | 
					            Logger logger = PaidSigns.getInstance().getLogger();
 | 
				
			||||||
 | 
					            logger.log(Level.SEVERE, "Exception encountered while trying to write to the data file");
 | 
				
			||||||
 | 
					            logger.log(Level.SEVERE, Arrays.toString(e.getStackTrace()));
 | 
				
			||||||
 | 
					            sender.sendMessage("An exception occurred. Please notify the server administrator or check the server log.");
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        sender.sendMessage("Condition removed");
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,52 @@
 | 
				
			|||||||
 | 
					package net.knarcraft.paidsigns.command;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.PaidSigns;
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.container.PaidSign;
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.utility.TabCompleteHelper;
 | 
				
			||||||
 | 
					import org.bukkit.command.Command;
 | 
				
			||||||
 | 
					import org.bukkit.command.CommandSender;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.Nullable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * The tab completer for the remove paid sign condition command
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class RemoveConditionTabCompleter extends TokenizedTabCompleter {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private List<String> lineIndices;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nullable
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias,
 | 
				
			||||||
 | 
					                                      @NotNull String[] args) {
 | 
				
			||||||
 | 
					        super.onTabComplete(sender, command, alias, args);
 | 
				
			||||||
 | 
					        if (lineIndices == null) {
 | 
				
			||||||
 | 
					            initializeValues();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (argumentSize == 1) {
 | 
				
			||||||
 | 
					            return TabCompleteHelper.filterMatchingStartsWith(TabCompleteHelper.getPaidSignNames(), arguments.get(0));
 | 
				
			||||||
 | 
					        } else if (argumentSize == 2) {
 | 
				
			||||||
 | 
					            PaidSign sign = PaidSigns.getInstance().getSignManager().getPaidSign(arguments.get(0));
 | 
				
			||||||
 | 
					            if (sign != null) {
 | 
				
			||||||
 | 
					                List<String> availableConditions = new ArrayList<>();
 | 
				
			||||||
 | 
					                for (Short signLine : sign.getConditions().keySet()) {
 | 
				
			||||||
 | 
					                    availableConditions.add(String.valueOf(signLine + 1));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                return TabCompleteHelper.filterMatchingStartsWith(availableConditions, arguments.get(1));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return new ArrayList<>();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Initializes the values available for tab completion
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private void initializeValues() {
 | 
				
			||||||
 | 
					        lineIndices = TabCompleteHelper.getSignLines();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,42 +1,38 @@
 | 
				
			|||||||
package net.knarcraft.paidsigns.command;
 | 
					package net.knarcraft.paidsigns.command;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import net.knarcraft.paidsigns.PaidSigns;
 | 
					import net.knarcraft.paidsigns.PaidSigns;
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.container.PaidSign;
 | 
				
			||||||
import net.knarcraft.paidsigns.utility.Tokenizer;
 | 
					import net.knarcraft.paidsigns.utility.Tokenizer;
 | 
				
			||||||
import org.apache.commons.lang.ArrayUtils;
 | 
					 | 
				
			||||||
import org.bukkit.command.Command;
 | 
					import org.bukkit.command.Command;
 | 
				
			||||||
import org.bukkit.command.CommandExecutor;
 | 
					 | 
				
			||||||
import org.bukkit.command.CommandSender;
 | 
					import org.bukkit.command.CommandSender;
 | 
				
			||||||
 | 
					import org.bukkit.command.TabExecutor;
 | 
				
			||||||
import org.jetbrains.annotations.NotNull;
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.Nullable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
import java.util.Arrays;
 | 
					import java.util.Arrays;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					import java.util.Map;
 | 
				
			||||||
import java.util.logging.Level;
 | 
					import java.util.logging.Level;
 | 
				
			||||||
import java.util.logging.Logger;
 | 
					import java.util.logging.Logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * A representation of the command for removing a paid sign
 | 
					 * A representation of the command for removing a paid sign
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public class RemoveCommand implements CommandExecutor {
 | 
					public class RemoveTabCommand implements TabExecutor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
 | 
					    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
 | 
				
			||||||
                             @NotNull String[] args) {
 | 
					                             @NotNull String[] args) {
 | 
				
			||||||
        if (args.length < 1) {
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        List<String> arguments = Tokenizer.tokenize(String.join(" ", args));
 | 
					        List<String> arguments = Tokenizer.tokenize(String.join(" ", args));
 | 
				
			||||||
        String[] input = arguments.get(0).split("\\|");
 | 
					        if (arguments.size() < 1) {
 | 
				
			||||||
        short line;
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            line = (short) (Short.parseShort(input[0]) - 1);
 | 
					 | 
				
			||||||
        } catch (NumberFormatException exception) {
 | 
					 | 
				
			||||||
            sender.sendMessage("Invalid line number given");
 | 
					 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        String id = String.join("|", (String[]) ArrayUtils.remove(input, 0));
 | 
					        String name = arguments.get(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            if (PaidSigns.getInstance().getSignManager().removePaidSign(id, line)) {
 | 
					            if (PaidSigns.getInstance().getSignManager().removePaidSign(name)) {
 | 
				
			||||||
                sender.sendMessage("Successfully removed paid sign");
 | 
					                sender.sendMessage("Successfully removed paid sign");
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                sender.sendMessage("No matching paid sign was found");
 | 
					                sender.sendMessage("No matching paid sign was found");
 | 
				
			||||||
@@ -52,4 +48,23 @@ public class RemoveCommand implements CommandExecutor {
 | 
				
			|||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nullable
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias,
 | 
				
			||||||
 | 
					                                      @NotNull String[] args) {
 | 
				
			||||||
 | 
					        List<String> arguments = Tokenizer.tokenize(String.join(" ", args));
 | 
				
			||||||
 | 
					        int argumentSize = args[args.length - 1].isEmpty() ? arguments.size() : arguments.size() - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (argumentSize < 1) {
 | 
				
			||||||
 | 
					            Map<String, PaidSign> allPaidSigns = PaidSigns.getInstance().getSignManager().getAllPaidSigns();
 | 
				
			||||||
 | 
					            List<String> signNames = new ArrayList<>();
 | 
				
			||||||
 | 
					            for (String name : allPaidSigns.keySet()) {
 | 
				
			||||||
 | 
					                signNames.add("\"" + name + "\"");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return signNames;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            return new ArrayList<>();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,31 +0,0 @@
 | 
				
			|||||||
package net.knarcraft.paidsigns.command;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import net.knarcraft.paidsigns.PaidSigns;
 | 
					 | 
				
			||||||
import net.knarcraft.paidsigns.container.PaidSign;
 | 
					 | 
				
			||||||
import org.bukkit.command.Command;
 | 
					 | 
				
			||||||
import org.bukkit.command.CommandSender;
 | 
					 | 
				
			||||||
import org.bukkit.command.TabCompleter;
 | 
					 | 
				
			||||||
import org.jetbrains.annotations.NotNull;
 | 
					 | 
				
			||||||
import org.jetbrains.annotations.Nullable;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import java.util.ArrayList;
 | 
					 | 
				
			||||||
import java.util.List;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * The tab completer for the remove command
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
public class RemoveTabCompleter implements TabCompleter {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Nullable
 | 
					 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias,
 | 
					 | 
				
			||||||
                                      @NotNull String[] args) {
 | 
					 | 
				
			||||||
        List<PaidSign> allPaidSigns = PaidSigns.getInstance().getSignManager().getAllPaidSigns();
 | 
					 | 
				
			||||||
        List<String> signIds = new ArrayList<>();
 | 
					 | 
				
			||||||
        for (PaidSign sign : allPaidSigns) {
 | 
					 | 
				
			||||||
            signIds.add("\"" + (sign.getLineIndex() + 1) + "|" + sign.getId() + "\"");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return signIds;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					package net.knarcraft.paidsigns.command;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.utility.Tokenizer;
 | 
				
			||||||
 | 
					import org.bukkit.command.Command;
 | 
				
			||||||
 | 
					import org.bukkit.command.CommandExecutor;
 | 
				
			||||||
 | 
					import org.bukkit.command.CommandSender;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A command executor with tokenized arguments
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class TokenizedCommand implements CommandExecutor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected List<String> arguments;
 | 
				
			||||||
 | 
					    protected int argumentSize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
 | 
				
			||||||
 | 
					        arguments = Tokenizer.tokenize(String.join(" ", args));
 | 
				
			||||||
 | 
					        argumentSize = arguments.size();
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					package net.knarcraft.paidsigns.command;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.utility.Tokenizer;
 | 
				
			||||||
 | 
					import org.bukkit.command.Command;
 | 
				
			||||||
 | 
					import org.bukkit.command.CommandSender;
 | 
				
			||||||
 | 
					import org.bukkit.command.TabCompleter;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.Nullable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A tab completer with tokenized arguments
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class TokenizedTabCompleter implements TabCompleter {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected List<String> arguments;
 | 
				
			||||||
 | 
					    protected int argumentSize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nullable
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias,
 | 
				
			||||||
 | 
					                                      @NotNull String[] args) {
 | 
				
			||||||
 | 
					        arguments = Tokenizer.tokenize(String.join(" ", args));
 | 
				
			||||||
 | 
					        if (args.length == 0) {
 | 
				
			||||||
 | 
					            argumentSize = 0;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            if (args[args.length - 1].isEmpty()) {
 | 
				
			||||||
 | 
					                arguments.add("");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            argumentSize = arguments.size();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -2,58 +2,55 @@ package net.knarcraft.paidsigns.container;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import net.knarcraft.paidsigns.PaidSigns;
 | 
					import net.knarcraft.paidsigns.PaidSigns;
 | 
				
			||||||
import net.knarcraft.paidsigns.property.OptionState;
 | 
					import net.knarcraft.paidsigns.property.OptionState;
 | 
				
			||||||
import net.knarcraft.paidsigns.utility.ColorHelper;
 | 
					
 | 
				
			||||||
import net.md_5.bungee.api.ChatColor;
 | 
					import java.util.HashMap;
 | 
				
			||||||
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * A representation of a paid sign
 | 
					 * A representation of a paid sign
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public class PaidSign {
 | 
					public class PaidSign {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private final String id;
 | 
					    private final String name;
 | 
				
			||||||
    private final String cleanId;
 | 
					 | 
				
			||||||
    private final short lineIndex;
 | 
					 | 
				
			||||||
    private final double cost;
 | 
					    private final double cost;
 | 
				
			||||||
 | 
					    private final String permission;
 | 
				
			||||||
    private final OptionState ignoreCase;
 | 
					    private final OptionState ignoreCase;
 | 
				
			||||||
    private final OptionState ignoreColor;
 | 
					    private final OptionState ignoreColor;
 | 
				
			||||||
 | 
					    private final Map<Short, PaidSignCondition> conditions = new HashMap<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Instantiates a new paid sign
 | 
					     * Instantiates a new paid sign
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param id          <p>The string that identifies this type of paid sign</p>
 | 
					     * @param name        <p>A recognizable, unique, name used to identify this paid sign</p>
 | 
				
			||||||
     * @param lineIndex   <p>The line the id has to be on to trigger payment</p>
 | 
					 | 
				
			||||||
     * @param cost        <p>The cost of creating this paid sign</p>
 | 
					     * @param cost        <p>The cost of creating this paid sign</p>
 | 
				
			||||||
 | 
					     * @param permission  <p>The permission required to create the sign this paid sign matches</p>
 | 
				
			||||||
     * @param ignoreCase  <p>Whether to ignore case when looking for this permission sign</p>
 | 
					     * @param ignoreCase  <p>Whether to ignore case when looking for this permission sign</p>
 | 
				
			||||||
     * @param ignoreColor <p>Whether to ignore color when looking for this permission sign</p>
 | 
					     * @param ignoreColor <p>Whether to ignore color when looking for this permission sign</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public PaidSign(String id, short lineIndex, double cost, OptionState ignoreCase, OptionState ignoreColor) {
 | 
					    public PaidSign(String name, double cost, String permission, OptionState ignoreCase, OptionState ignoreColor) {
 | 
				
			||||||
        if (id == null || id.trim().isBlank()) {
 | 
					        if (name == null || name.trim().isBlank()) {
 | 
				
			||||||
            throw new IllegalArgumentException("Id cannot be empty");
 | 
					            throw new IllegalArgumentException("Name cannot be empty");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (cost <= 0) {
 | 
					        if (cost <= 0) {
 | 
				
			||||||
            throw new IllegalArgumentException("Cost must be larger than 0");
 | 
					            throw new IllegalArgumentException("Cost must be larger than 0");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (lineIndex < 0 || lineIndex > 3) {
 | 
					 | 
				
			||||||
            throw new IllegalArgumentException("Sign line must be between 0 and 3");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (ignoreCase == null || ignoreColor == null) {
 | 
					        if (ignoreCase == null || ignoreColor == null) {
 | 
				
			||||||
            throw new IllegalArgumentException("Ignore case and ignore color options cannot be null");
 | 
					            throw new IllegalArgumentException("Ignore case and ignore color options cannot be null");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        this.id = id;
 | 
					        this.name = name;
 | 
				
			||||||
        this.lineIndex = lineIndex;
 | 
					 | 
				
			||||||
        this.cost = cost;
 | 
					        this.cost = cost;
 | 
				
			||||||
 | 
					        this.permission = permission;
 | 
				
			||||||
        this.ignoreCase = ignoreCase;
 | 
					        this.ignoreCase = ignoreCase;
 | 
				
			||||||
        this.ignoreColor = ignoreColor;
 | 
					        this.ignoreColor = ignoreColor;
 | 
				
			||||||
        this.cleanId = getCleanString(id);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Gets the id string of this paid sign
 | 
					     * Gets the name identifying this paid sign
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return <p>The id string of this paid sign</p>
 | 
					     * @return <p>The name identifying this paid sign</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public String getId() {
 | 
					    public String getName() {
 | 
				
			||||||
        return id;
 | 
					        return name;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -66,66 +63,21 @@ public class PaidSign {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Gets the line on the sign the id must be on to trigger payment
 | 
					     * Gets the permission required by a player to create the sign this paid sign matches
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return <p>The sign line to search for the id</p>
 | 
					     * @return <p>The permission required by a player to create the sign this paid sign matches</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public short getLineIndex() {
 | 
					    public String getPermission() {
 | 
				
			||||||
        return lineIndex;
 | 
					        return this.permission;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Gets the clean id of this paid sign
 | 
					     * Gets all conditions registered for this paid sign
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return <p>The clean id of this paid sign</p>
 | 
					     * @return <p>All conditions registered for this paid sign</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public String getCleanId() {
 | 
					    public Map<Short, PaidSignCondition> getConditions() {
 | 
				
			||||||
        return cleanId;
 | 
					        return new HashMap<>(this.conditions);
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Gets the "clean" version of the given string
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * <p>The "cleaning" removes color codes and lower-cases the string.</p>
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param string <p>The string to clean</p>
 | 
					 | 
				
			||||||
     * @return <p>The cleaned string</p>
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public static String getCleanString(String string) {
 | 
					 | 
				
			||||||
        return ChatColor.stripColor(ColorHelper.translateAllColorCodes(string.toLowerCase()));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Checks whether this paid sign matches the given line
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param lineNumber <p>The line number of the given line</p>
 | 
					 | 
				
			||||||
     * @param line       <p>The line to compare against this paid sign's id</p>
 | 
					 | 
				
			||||||
     * @return <p>True if the line matches this sign</p>
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public boolean matches(short lineNumber, String line) {
 | 
					 | 
				
			||||||
        if (lineNumber != this.lineIndex) {
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        String idCopy = id;
 | 
					 | 
				
			||||||
        if (getIgnoreCase()) {
 | 
					 | 
				
			||||||
            idCopy = idCopy.toLowerCase();
 | 
					 | 
				
			||||||
            line = line.toLowerCase();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (getIgnoreColor()) {
 | 
					 | 
				
			||||||
            idCopy = ColorHelper.stripColorCodes(idCopy);
 | 
					 | 
				
			||||||
            line = ColorHelper.stripColorCodes(line);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return idCopy.equals(line);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Checks whether this paid sign matches another paid sign
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param paidSign <p>The other paid sign to compare to</p>
 | 
					 | 
				
			||||||
     * @return <p>True if the signs match</p>
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public boolean matches(PaidSign paidSign) {
 | 
					 | 
				
			||||||
        return matches(paidSign.lineIndex, paidSign.id);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -134,11 +86,7 @@ public class PaidSign {
 | 
				
			|||||||
     * @return <p>Whether the text case should be ignored for this paid sign</p>
 | 
					     * @return <p>Whether the text case should be ignored for this paid sign</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public boolean getIgnoreCase() {
 | 
					    public boolean getIgnoreCase() {
 | 
				
			||||||
        if (this.ignoreCase == OptionState.DEFAULT) {
 | 
					        return OptionState.getBooleanValue(this.ignoreCase, PaidSigns.getInstance().ignoreCase());
 | 
				
			||||||
            return PaidSigns.getInstance().ignoreCase();
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            return OptionState.getBooleanValue(this.ignoreCase);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -147,11 +95,55 @@ public class PaidSign {
 | 
				
			|||||||
     * @return <p>Whether the text color should be ignored for this paid sign</p>
 | 
					     * @return <p>Whether the text color should be ignored for this paid sign</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public boolean getIgnoreColor() {
 | 
					    public boolean getIgnoreColor() {
 | 
				
			||||||
        if (this.ignoreColor == OptionState.DEFAULT) {
 | 
					        return OptionState.getBooleanValue(this.ignoreColor, PaidSigns.getInstance().ignoreColor());
 | 
				
			||||||
            return PaidSigns.getInstance().ignoreColor();
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            return OptionState.getBooleanValue(this.ignoreColor);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Checks whether this paid sign matches the given set of sign lines
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param lines <p>The sign lines to test against</p>
 | 
				
			||||||
 | 
					     * @return <p>True if this paid sign matches the given lines</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public boolean matches(String[] lines) {
 | 
				
			||||||
 | 
					        //Make sure a paid sign without a condition never matches anything
 | 
				
			||||||
 | 
					        if (this.conditions.isEmpty()) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        boolean success = true;
 | 
				
			||||||
 | 
					        for (short i = 0; i < 4; i++) {
 | 
				
			||||||
 | 
					            PaidSignCondition condition = this.conditions.get(i);
 | 
				
			||||||
 | 
					            if (condition != null) {
 | 
				
			||||||
 | 
					                success = success && condition.test(lines[i]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return success;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Adds a condition to this paid sign
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param line          <p>The line on the sign the matched text must be on</p>
 | 
				
			||||||
 | 
					     * @param stringToMatch <p>The string that should be matched for the new condition to be true</p>
 | 
				
			||||||
 | 
					     * @param executeRegex  <p>Whether to execute the string as RegEx</p>
 | 
				
			||||||
 | 
					     * @param ignoreCase    <p>Whether to ignore case when matching against the condition</p>
 | 
				
			||||||
 | 
					     * @param ignoreColor   <p>Whether to ignore color when matching against the condition</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public void addCondition(short line, String stringToMatch, boolean executeRegex, OptionState ignoreCase, OptionState ignoreColor) {
 | 
				
			||||||
 | 
					        if (line < 0 || line > 3) {
 | 
				
			||||||
 | 
					            throw new IllegalArgumentException("Invalid sign line given for new paid sign condition");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        boolean ignoreCaseBoolean = OptionState.getBooleanValue(ignoreCase, this.getIgnoreCase());
 | 
				
			||||||
 | 
					        boolean ignoreColorBoolean = OptionState.getBooleanValue(ignoreColor, this.getIgnoreColor());
 | 
				
			||||||
 | 
					        this.conditions.put(line, new PaidSignCondition(stringToMatch, executeRegex, ignoreCaseBoolean, ignoreColorBoolean));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Removes a condition from this paid sign
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param line <p>The sign line the condition belongs to</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public void removeCondition(short line) {
 | 
				
			||||||
 | 
					        this.conditions.remove(line);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,96 @@
 | 
				
			|||||||
 | 
					package net.knarcraft.paidsigns.container;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.utility.ColorHelper;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A condition for deciding if a paid sign matches a sign line
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class PaidSignCondition {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    final String stringToMatch;
 | 
				
			||||||
 | 
					    final boolean executeRegex;
 | 
				
			||||||
 | 
					    final boolean ignoreCase;
 | 
				
			||||||
 | 
					    final boolean ignoreColor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Instantiates a new paid sign condition
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param stringToMatch <p>The string/regular expression the line has to match to fulfill this condition</p>
 | 
				
			||||||
 | 
					     * @param executeRegex  <p>Whether to execute the match string as a regular expression</p>
 | 
				
			||||||
 | 
					     * @param ignoreCase    <p>Whether to ignore uppercase/lowercase when comparing against this condition</p>
 | 
				
			||||||
 | 
					     * @param ignoreColor   <p>Whether to ignore color codes when comparing against this condition</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public PaidSignCondition(String stringToMatch, boolean executeRegex, boolean ignoreCase, boolean ignoreColor) {
 | 
				
			||||||
 | 
					        this.stringToMatch = stringToMatch;
 | 
				
			||||||
 | 
					        this.executeRegex = executeRegex;
 | 
				
			||||||
 | 
					        this.ignoreCase = ignoreCase;
 | 
				
			||||||
 | 
					        this.ignoreColor = ignoreColor;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Gets the string this condition should match
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return <p>The string this condition should match</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public String getStringToMatch() {
 | 
				
			||||||
 | 
					        return this.stringToMatch;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Gets whether to execute the match string as RegEx
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return <p>Whether to execute the match string as RegEx</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public boolean executeRegex() {
 | 
				
			||||||
 | 
					        return this.executeRegex;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Gets whether to ignore case when trying to match strings
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return <p>Whether to ignore case when trying to match strings</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public boolean ignoreCase() {
 | 
				
			||||||
 | 
					        return this.ignoreCase;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Gets whether to ignore color when trying to match strings
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return <p>Whether to ignore color when trying to match strings</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public boolean ignoreColor() {
 | 
				
			||||||
 | 
					        return this.ignoreColor;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Tests whether the given line matches this condition
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param line <p>The sign line to test</p>
 | 
				
			||||||
 | 
					     * @return <p>True if this condition matches the given line</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public boolean test(String line) {
 | 
				
			||||||
 | 
					        String stringToMatch = this.stringToMatch;
 | 
				
			||||||
 | 
					        //Strip color codes if they shouldn't matter
 | 
				
			||||||
 | 
					        if (this.ignoreColor) {
 | 
				
			||||||
 | 
					            stringToMatch = ColorHelper.stripColorCodes(stringToMatch);
 | 
				
			||||||
 | 
					            line = ColorHelper.stripColorCodes(line);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (this.executeRegex) {
 | 
				
			||||||
 | 
					            //Match using RegEx
 | 
				
			||||||
 | 
					            if (this.ignoreCase) {
 | 
				
			||||||
 | 
					                return line.matches("(?i)" + stringToMatch);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                return line.matches(stringToMatch);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            //Match regularly
 | 
				
			||||||
 | 
					            if (this.ignoreCase) {
 | 
				
			||||||
 | 
					                return stringToMatch.equalsIgnoreCase(line);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                return stringToMatch.equals(line);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -3,53 +3,53 @@ package net.knarcraft.paidsigns.listener;
 | 
				
			|||||||
import net.knarcraft.paidsigns.PaidSigns;
 | 
					import net.knarcraft.paidsigns.PaidSigns;
 | 
				
			||||||
import net.knarcraft.paidsigns.container.PaidSign;
 | 
					import net.knarcraft.paidsigns.container.PaidSign;
 | 
				
			||||||
import net.knarcraft.paidsigns.manager.EconomyManager;
 | 
					import net.knarcraft.paidsigns.manager.EconomyManager;
 | 
				
			||||||
import net.knarcraft.paidsigns.manager.PaidSignManager;
 | 
					 | 
				
			||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
import org.bukkit.event.EventHandler;
 | 
					import org.bukkit.event.EventHandler;
 | 
				
			||||||
import org.bukkit.event.EventPriority;
 | 
					import org.bukkit.event.EventPriority;
 | 
				
			||||||
import org.bukkit.event.Listener;
 | 
					import org.bukkit.event.Listener;
 | 
				
			||||||
import org.bukkit.event.block.SignChangeEvent;
 | 
					import org.bukkit.event.block.SignChangeEvent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * A listener for listening to registered paid signs
 | 
					 * A listener for listening to registered paid signs
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public class SignListener implements Listener {
 | 
					public class SignListener implements Listener {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @EventHandler(priority = EventPriority.MONITOR)
 | 
					    @EventHandler(priority = EventPriority.LOW)
 | 
				
			||||||
 | 
					    @SuppressWarnings("unused")
 | 
				
			||||||
    public void onSignChange(SignChangeEvent event) {
 | 
					    public void onSignChange(SignChangeEvent event) {
 | 
				
			||||||
        if (event.isCancelled() || event.getPlayer().hasPermission("paidsigns.paymentexempt")) {
 | 
					        if (event.isCancelled() || event.getPlayer().hasPermission("paidsigns.paymentexempt")) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        String[] lines = event.getLines();
 | 
					        String[] lines = event.getLines();
 | 
				
			||||||
        PaidSignManager signManager = PaidSigns.getInstance().getSignManager();
 | 
					        Map<String, PaidSign> matchingSigns = PaidSigns.getInstance().getSignManager().getAllPaidSigns();
 | 
				
			||||||
        for (short lineIndex = 0; lineIndex < lines.length; lineIndex++) {
 | 
					        for (PaidSign paidSign : matchingSigns.values()) {
 | 
				
			||||||
            //Get all "weak" matches (any paid sign with a clean id matching the clean line)
 | 
					            //If a match is found, just return
 | 
				
			||||||
            List<PaidSign> matchingSigns = signManager.getPaidSigns(PaidSign.getCleanString(lines[lineIndex]), lineIndex);
 | 
					            if (matchSign(paidSign, lines, event)) {
 | 
				
			||||||
            if (matchingSigns.isEmpty()) {
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (testMatchingSigns(lineIndex, lines[lineIndex], matchingSigns, event)) {
 | 
					 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Tests all weak matches of paid signs to check if a strong match is found
 | 
					     * Checks if the given paid sign matches the given sign lines
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param lineIndex     <p>The index of the currently managed line</p>
 | 
					     * @param paidSign <p>The paid sign to test against the sign lines</p>
 | 
				
			||||||
     * @param line          <p>The text on the currently managed line</p>
 | 
					     * @param lines    <p>The lines of a sign</p>
 | 
				
			||||||
     * @param matchingSigns <p>The signs that weakly match the </p>
 | 
					     * @param event    <p>The triggered sign change event to cancel if necessary</p>
 | 
				
			||||||
     * @param event         <p>The triggered sign change event</p>
 | 
					     * @return <p>True if a match was found and actions have been taken</p>
 | 
				
			||||||
     * @return <p>True if a match was found and thw work is finished</p>
 | 
					 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private boolean testMatchingSigns(short lineIndex, String line, List<PaidSign> matchingSigns, SignChangeEvent event) {
 | 
					    private boolean matchSign(PaidSign paidSign, String[] lines, SignChangeEvent event) {
 | 
				
			||||||
        for (PaidSign paidSign : matchingSigns) {
 | 
					        if (paidSign.matches(lines)) {
 | 
				
			||||||
            if (paidSign.matches(lineIndex, line)) {
 | 
					 | 
				
			||||||
            Player player = event.getPlayer();
 | 
					            Player player = event.getPlayer();
 | 
				
			||||||
 | 
					            String permission = paidSign.getPermission();
 | 
				
			||||||
 | 
					            //If a match is found, but the player is missing the permission, assume no plugin sign was created
 | 
				
			||||||
 | 
					            if (permission != null && !permission.trim().isEmpty() && !player.hasPermission(permission)) {
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            double cost = paidSign.getCost();
 | 
					            double cost = paidSign.getCost();
 | 
				
			||||||
            boolean canAfford = EconomyManager.canAfford(player, cost);
 | 
					            boolean canAfford = EconomyManager.canAfford(player, cost);
 | 
				
			||||||
            if (!canAfford) {
 | 
					            if (!canAfford) {
 | 
				
			||||||
@@ -62,7 +62,6 @@ public class SignListener implements Listener {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,15 +2,15 @@ package net.knarcraft.paidsigns.manager;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import net.knarcraft.paidsigns.PaidSigns;
 | 
					import net.knarcraft.paidsigns.PaidSigns;
 | 
				
			||||||
import net.knarcraft.paidsigns.container.PaidSign;
 | 
					import net.knarcraft.paidsigns.container.PaidSign;
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.container.PaidSignCondition;
 | 
				
			||||||
import net.knarcraft.paidsigns.property.OptionState;
 | 
					import net.knarcraft.paidsigns.property.OptionState;
 | 
				
			||||||
import org.bukkit.configuration.ConfigurationSection;
 | 
					import org.bukkit.configuration.ConfigurationSection;
 | 
				
			||||||
import org.bukkit.configuration.file.YamlConfiguration;
 | 
					import org.bukkit.configuration.file.YamlConfiguration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.File;
 | 
					import java.io.File;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.HashMap;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.Map;
 | 
				
			||||||
import java.util.function.Predicate;
 | 
					 | 
				
			||||||
import java.util.logging.Level;
 | 
					import java.util.logging.Level;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -18,16 +18,15 @@ import java.util.logging.Level;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
public final class PaidSignManager {
 | 
					public final class PaidSignManager {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private final List<PaidSign> paidSigns;
 | 
					    private final Map<String, PaidSign> paidSigns;
 | 
				
			||||||
    private static final File signsFile = new File(PaidSigns.getInstance().getDataFolder(), "data.yml");
 | 
					    private static final File signsFile = new File(PaidSigns.getInstance().getDataFolder(), "data.yml");
 | 
				
			||||||
    private static final String signLineIdSeparator = "-,_,-";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Instantiate a new paid sign manager
 | 
					     * Instantiate a new paid sign manager
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param paidSigns <p>The paid signs this manager should manage</p>
 | 
					     * @param paidSigns <p>The paid signs this manager should manage</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public PaidSignManager(List<PaidSign> paidSigns) {
 | 
					    public PaidSignManager(Map<String, PaidSign> paidSigns) {
 | 
				
			||||||
        this.paidSigns = paidSigns;
 | 
					        this.paidSigns = paidSigns;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -38,36 +37,35 @@ public final class PaidSignManager {
 | 
				
			|||||||
     * @throws IOException <p>If unable to write to the signs file</p>
 | 
					     * @throws IOException <p>If unable to write to the signs file</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public void addPaidSign(PaidSign paidSign) throws IOException {
 | 
					    public void addPaidSign(PaidSign paidSign) throws IOException {
 | 
				
			||||||
        this.paidSigns.add(paidSign);
 | 
					        this.paidSigns.put(paidSign.getName(), paidSign);
 | 
				
			||||||
        saveSigns(this.paidSigns);
 | 
					        saveSigns();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Removes a paid sign from this paid sign manager
 | 
					     * Removes a paid sign from this paid sign manager
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param id   <p>The identifier for the paid sign to remove</p>
 | 
					     * @param name <p>The name of the paid sign to remove</p>
 | 
				
			||||||
     * @param line <p>The line the identifier has to match to be valid</p>
 | 
					 | 
				
			||||||
     * @return <p>True if a sign was removed</p>
 | 
					     * @return <p>True if a sign was removed</p>
 | 
				
			||||||
     * @throws IOException <p>If unable to write to the signs file</p>
 | 
					     * @throws IOException <p>If unable to write to the signs file</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public boolean removePaidSign(String id, short line) throws IOException {
 | 
					    public boolean removePaidSign(String name) throws IOException {
 | 
				
			||||||
        boolean removed = this.paidSigns.removeIf((sign) -> sign.getId().equals(id) && sign.getLineIndex() == line);
 | 
					        boolean removed = this.paidSigns.remove(name) != null;
 | 
				
			||||||
        if (!removed) {
 | 
					        if (!removed) {
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        } else {
 | 
				
			||||||
        saveSigns(this.paidSigns);
 | 
					            saveSigns();
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Gets the paid signs that match the given properties
 | 
					     * Gets the paid sign with the given name
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param cleanId <p>The clean id to search for</p>
 | 
					     * @param name <p>The paid sign with the given name</p>
 | 
				
			||||||
     * @param line    <p>The line number to search for</p>
 | 
					     * @return <p>The paid sign with the given name, or null if it does not exist</p>
 | 
				
			||||||
     * @return <p>The paid signs that matched the given properties</p>
 | 
					 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public List<PaidSign> getPaidSigns(String cleanId, short line) {
 | 
					    public PaidSign getPaidSign(String name) {
 | 
				
			||||||
        return filterPaidSigns(filterPaidSigns(paidSigns, line), cleanId);
 | 
					        return paidSigns.get(name);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -75,19 +73,8 @@ public final class PaidSignManager {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return <p>All registered paid signs</p>
 | 
					     * @return <p>All registered paid signs</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public List<PaidSign> getAllPaidSigns() {
 | 
					    public Map<String, PaidSign> getAllPaidSigns() {
 | 
				
			||||||
        return new ArrayList<>(paidSigns);
 | 
					        return new HashMap<>(paidSigns);
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Filters a list of paid signs to match the given line number
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param paidSigns <p>The list of paid signs to start with</p>
 | 
					 | 
				
			||||||
     * @param line      <p>The line number to filter by</p>
 | 
					 | 
				
			||||||
     * @return <p>The filtered list of paid signs</p>
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private static List<PaidSign> filterPaidSigns(List<PaidSign> paidSigns, short line) {
 | 
					 | 
				
			||||||
        return filterPaidSigns(paidSigns, (paidSign) -> paidSign.getLineIndex() == line);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -95,66 +82,85 @@ public final class PaidSignManager {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return <p>The loaded paid signs</p>
 | 
					     * @return <p>The loaded paid signs</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static List<PaidSign> loadSigns() {
 | 
					    public static Map<String, PaidSign> loadSigns() {
 | 
				
			||||||
        YamlConfiguration configuration = YamlConfiguration.loadConfiguration(signsFile);
 | 
					        YamlConfiguration configuration = YamlConfiguration.loadConfiguration(signsFile);
 | 
				
			||||||
        ConfigurationSection signSection = configuration.getConfigurationSection("paidSigns");
 | 
					        ConfigurationSection signSection = configuration.getConfigurationSection("paidSigns");
 | 
				
			||||||
        if (signSection == null) {
 | 
					        if (signSection == null) {
 | 
				
			||||||
            PaidSigns.getInstance().getLogger().log(Level.WARNING, "Signs section not found in data.yml");
 | 
					            PaidSigns.getInstance().getLogger().log(Level.WARNING, "Signs section not found in data.yml");
 | 
				
			||||||
            return new ArrayList<>();
 | 
					            return new HashMap<>();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        List<PaidSign> paidSigns = new ArrayList<>();
 | 
					        Map<String, PaidSign> paidSigns = new HashMap<>();
 | 
				
			||||||
        for (String combinedId : signSection.getKeys(false)) {
 | 
					        for (String name : signSection.getKeys(false)) {
 | 
				
			||||||
            String[] idParts = combinedId.split(signLineIdSeparator);
 | 
					            double cost = signSection.getDouble(name + ".cost");
 | 
				
			||||||
            short lineNumber = Short.parseShort(idParts[0]);
 | 
					            String permission = signSection.getString(name + ".permission");
 | 
				
			||||||
            String id = idParts[1];
 | 
					            OptionState ignoreCase = OptionState.getFromBoolean(signSection.getBoolean(name + ".ignoreCase"));
 | 
				
			||||||
            double cost = signSection.getDouble(combinedId + ".cost");
 | 
					            OptionState ignoreColor = OptionState.getFromBoolean(signSection.getBoolean(name + ".ignoreColor"));
 | 
				
			||||||
            OptionState ignoreCase = OptionState.getFromBoolean(signSection.getBoolean(combinedId + ".ignoreCase"));
 | 
					            PaidSign sign = new PaidSign(name, cost, permission, ignoreCase, ignoreColor);
 | 
				
			||||||
            OptionState ignoreColor = OptionState.getFromBoolean(signSection.getBoolean(combinedId + ".ignoreColor"));
 | 
					            loadConditions(signSection, sign);
 | 
				
			||||||
            paidSigns.add(new PaidSign(id, lineNumber, cost, ignoreCase, ignoreColor));
 | 
					            paidSigns.put(name, sign);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return paidSigns;
 | 
					        return paidSigns;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Saves all signs registered to this paid sign manager
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @throws IOException <p>If unable to write to the signs file</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public void saveSigns() throws IOException {
 | 
				
			||||||
 | 
					        saveSigns(this.paidSigns);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Saves the given paid signs to the signs file
 | 
					     * Saves the given paid signs to the signs file
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param signs <p>The signs to save</p>
 | 
					     * @param signs <p>The signs to save</p>
 | 
				
			||||||
     * @throws IOException <p>If unable to write to the signs file</p>
 | 
					     * @throws IOException <p>If unable to write to the signs file</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static void saveSigns(List<PaidSign> signs) throws IOException {
 | 
					    public static void saveSigns(Map<String, PaidSign> signs) throws IOException {
 | 
				
			||||||
        YamlConfiguration configuration = YamlConfiguration.loadConfiguration(signsFile);
 | 
					        YamlConfiguration configuration = YamlConfiguration.loadConfiguration(signsFile);
 | 
				
			||||||
        ConfigurationSection signSection = configuration.createSection("paidSigns");
 | 
					        ConfigurationSection signSection = configuration.createSection("paidSigns");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (PaidSign sign : signs) {
 | 
					        for (PaidSign sign : signs.values()) {
 | 
				
			||||||
            String signId = sign.getLineIndex() + signLineIdSeparator + sign.getId();
 | 
					            String name = sign.getName();
 | 
				
			||||||
            signSection.set(signId + ".cost", sign.getCost());
 | 
					            signSection.set(name + ".cost", sign.getCost());
 | 
				
			||||||
            signSection.set(signId + ".ignoreCase", sign.getIgnoreCase());
 | 
					            signSection.set(name + ".permission", sign.getPermission());
 | 
				
			||||||
            signSection.set(signId + ".ignoreColor", sign.getIgnoreColor());
 | 
					            signSection.set(name + ".ignoreCase", sign.getIgnoreCase());
 | 
				
			||||||
 | 
					            signSection.set(name + ".ignoreColor", sign.getIgnoreColor());
 | 
				
			||||||
 | 
					            ConfigurationSection conditionsSection = signSection.createSection(name + ".conditions");
 | 
				
			||||||
 | 
					            Map<Short, PaidSignCondition> signConditions = sign.getConditions();
 | 
				
			||||||
 | 
					            for (short lineIndex : signConditions.keySet()) {
 | 
				
			||||||
 | 
					                PaidSignCondition condition = signConditions.get(lineIndex);
 | 
				
			||||||
 | 
					                conditionsSection.set(lineIndex + ".stringToMatch", condition.getStringToMatch());
 | 
				
			||||||
 | 
					                conditionsSection.set(lineIndex + ".executeRegEx", condition.executeRegex());
 | 
				
			||||||
 | 
					                conditionsSection.set(lineIndex + ".ignoreCase", condition.ignoreCase());
 | 
				
			||||||
 | 
					                conditionsSection.set(lineIndex + ".ignoreColor", condition.ignoreColor());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        configuration.save(signsFile);
 | 
					        configuration.save(signsFile);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Filters a list of paid signs to match the given clean id
 | 
					     * Loads any saved paid sign conditions and applies them to the given sign
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param paidSigns <p>The list of paid signs to start with</p>
 | 
					     * @param signSection <p>The configuration section containing sign information</p>
 | 
				
			||||||
     * @param cleanId   <p>The clean id to filter by</p>
 | 
					     * @param sign        <p>The sign to load conditions for</p>
 | 
				
			||||||
     * @return <p>The filtered list of paid signs</p>
 | 
					 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private static List<PaidSign> filterPaidSigns(List<PaidSign> paidSigns, String cleanId) {
 | 
					    private static void loadConditions(ConfigurationSection signSection, PaidSign sign) {
 | 
				
			||||||
        return filterPaidSigns(paidSigns, (paidSign) -> paidSign.getCleanId().equals(cleanId));
 | 
					        ConfigurationSection conditionSection = signSection.getConfigurationSection(sign.getName() + ".conditions");
 | 
				
			||||||
 | 
					        if (conditionSection != null) {
 | 
				
			||||||
 | 
					            for (String lineIndex : conditionSection.getKeys(false)) {
 | 
				
			||||||
 | 
					                short lineNumber = Short.parseShort(lineIndex);
 | 
				
			||||||
 | 
					                String stringToMatch = conditionSection.getString(lineIndex + ".stringToMatch");
 | 
				
			||||||
 | 
					                boolean executeRegEx = conditionSection.getBoolean(lineIndex + ".executeRegEx");
 | 
				
			||||||
 | 
					                boolean ignoreConditionCase = conditionSection.getBoolean(lineIndex + ".ignoreCase");
 | 
				
			||||||
 | 
					                boolean ignoreConditionColor = conditionSection.getBoolean(lineIndex + ".ignoreColor");
 | 
				
			||||||
 | 
					                sign.addCondition(lineNumber, stringToMatch, executeRegEx,
 | 
				
			||||||
 | 
					                        OptionState.getFromBoolean(ignoreConditionCase),
 | 
				
			||||||
 | 
					                        OptionState.getFromBoolean(ignoreConditionColor));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Filters a list of paid signs using the given predicate
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param paidSigns <p>The list of paid signs to start with</p>
 | 
					 | 
				
			||||||
     * @param predicate <p>The predicate used to filter paid signs</p>
 | 
					 | 
				
			||||||
     * @return <p>The filtered list of paid signs</p>
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private static List<PaidSign> filterPaidSigns(List<PaidSign> paidSigns, Predicate<PaidSign> predicate) {
 | 
					 | 
				
			||||||
        return new ArrayList<>(paidSigns).stream().filter(predicate).toList();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,13 +24,14 @@ public enum OptionState {
 | 
				
			|||||||
     * Gets the boolean value of the given option state if it's boolean compatible
 | 
					     * Gets the boolean value of the given option state if it's boolean compatible
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param optionState  <p>The option state to get the boolean from</p>
 | 
					     * @param optionState  <p>The option state to get the boolean from</p>
 | 
				
			||||||
     * @return <p>The boolean value, or an illegal argument exception if called on DEFAULT</p>
 | 
					     * @param defaultValue <p>The default value to use if the option state is DEFAULT</p>
 | 
				
			||||||
 | 
					     * @return <p>The boolean value</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static boolean getBooleanValue(OptionState optionState) {
 | 
					    public static boolean getBooleanValue(OptionState optionState, boolean defaultValue) {
 | 
				
			||||||
        return switch (optionState) {
 | 
					        return switch (optionState) {
 | 
				
			||||||
            case TRUE -> true;
 | 
					            case TRUE -> true;
 | 
				
			||||||
            case FALSE -> false;
 | 
					            case FALSE -> false;
 | 
				
			||||||
            case DEFAULT -> throw new IllegalArgumentException("No boolean value available for DEFAULT");
 | 
					            case DEFAULT -> defaultValue;
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,142 @@
 | 
				
			|||||||
 | 
					package net.knarcraft.paidsigns.utility;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import net.knarcraft.paidsigns.PaidSigns;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					import java.util.Set;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A helper class for providing common tab complete options
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public final class TabCompleteHelper {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private TabCompleteHelper() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Finds tab complete values that contain the typed text
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param values    <p>The values to filter</p>
 | 
				
			||||||
 | 
					     * @param typedText <p>The text the player has started typing</p>
 | 
				
			||||||
 | 
					     * @return <p>The given string values that contain the player's typed text</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static List<String> filterMatchingContains(List<String> values, String typedText) {
 | 
				
			||||||
 | 
					        List<String> configValues = new ArrayList<>();
 | 
				
			||||||
 | 
					        for (String value : values) {
 | 
				
			||||||
 | 
					            if (value.toLowerCase().contains(typedText.toLowerCase())) {
 | 
				
			||||||
 | 
					                configValues.add(value);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return configValues;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Finds tab complete values that match the start of the typed text
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param values    <p>The values to filter</p>
 | 
				
			||||||
 | 
					     * @param typedText <p>The text the player has started typing</p>
 | 
				
			||||||
 | 
					     * @return <p>The given string values that start with the player's typed text</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static List<String> filterMatchingStartsWith(List<String> values, String typedText) {
 | 
				
			||||||
 | 
					        List<String> configValues = new ArrayList<>();
 | 
				
			||||||
 | 
					        for (String value : values) {
 | 
				
			||||||
 | 
					            if (value.toLowerCase().startsWith(typedText.toLowerCase())) {
 | 
				
			||||||
 | 
					                configValues.add(value);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return configValues;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Gets the available boolean values for tab completion
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return <p>The available boolean values</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static List<String> getBooleans() {
 | 
				
			||||||
 | 
					        List<String> booleans = new ArrayList<>();
 | 
				
			||||||
 | 
					        booleans.add("true");
 | 
				
			||||||
 | 
					        booleans.add("false");
 | 
				
			||||||
 | 
					        return booleans;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Gets the available option states for tab completion
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return <p>The available option states</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static List<String> getOptionStates() {
 | 
				
			||||||
 | 
					        List<String> optionStates = getBooleans();
 | 
				
			||||||
 | 
					        optionStates.add("default");
 | 
				
			||||||
 | 
					        return optionStates;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Gets the names of all registered paid signs
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return <p>The names of all registered paid signs</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static List<String> getPaidSignNames() {
 | 
				
			||||||
 | 
					        Set<String> paidSignNames = PaidSigns.getInstance().getSignManager().getAllPaidSigns().keySet();
 | 
				
			||||||
 | 
					        List<String> quotedNames = new ArrayList<>(paidSignNames.size());
 | 
				
			||||||
 | 
					        for (String paidSignName : paidSignNames) {
 | 
				
			||||||
 | 
					            quotedNames.add("\"" + paidSignName + "\"");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return quotedNames;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Gets all the choices for lines on a sign
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return <p>All the line indices of a sign</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static List<String> getSignLines() {
 | 
				
			||||||
 | 
					        List<String> lines = new ArrayList<>();
 | 
				
			||||||
 | 
					        for (int i = 1; i < 5; i++) {
 | 
				
			||||||
 | 
					            lines.add(String.valueOf(i));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return lines;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Gets some valid costs as example values
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return <p>Some valid costs</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static List<String> getCosts() {
 | 
				
			||||||
 | 
					        List<String> costs = new ArrayList<>();
 | 
				
			||||||
 | 
					        costs.add("1");
 | 
				
			||||||
 | 
					        costs.add("5");
 | 
				
			||||||
 | 
					        costs.add("10");
 | 
				
			||||||
 | 
					        costs.add("15");
 | 
				
			||||||
 | 
					        return costs;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Gets some example paid sign names for auto-completion
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return <p>Some example paid sign names</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static List<String> getExamplePaidSignNames() {
 | 
				
			||||||
 | 
					        List<String> names = new ArrayList<>();
 | 
				
			||||||
 | 
					        names.add("sign1");
 | 
				
			||||||
 | 
					        names.add("\"lift up sign\"");
 | 
				
			||||||
 | 
					        names.add("\"lift down sign\"");
 | 
				
			||||||
 | 
					        return names;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Gets some example condition matching strings for tab completion
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return <p>Some example "stringToMatch" values</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static List<String> getExampleConditionStrings() {
 | 
				
			||||||
 | 
					        List<String> conditionStrings = new ArrayList<>();
 | 
				
			||||||
 | 
					        conditionStrings.add("[Gate]");
 | 
				
			||||||
 | 
					        conditionStrings.add("\"[Lift Up]\"");
 | 
				
			||||||
 | 
					        conditionStrings.add("\"[Lift Down]\"");
 | 
				
			||||||
 | 
					        return conditionStrings;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -6,15 +6,30 @@ import java.util.List;
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 * A tokenizer for being able to support quotes in commands
 | 
					 * A tokenizer for being able to support quotes in commands
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public class Tokenizer {
 | 
					public final class Tokenizer {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private Tokenizer() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Tokenizes a string
 | 
					     * Tokenizes a string
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param input <p>A string.</p>
 | 
					     * @param input <p>A string</p>
 | 
				
			||||||
     * @return <p>A list of tokens.</p>
 | 
					     * @return <p>A list of tokens</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static List<String> tokenize(String input) {
 | 
					    public static List<String> tokenize(String input) {
 | 
				
			||||||
 | 
					        return tokenize(input, true);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Tokenizes a string
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param input            <p>A string</p>
 | 
				
			||||||
 | 
					     * @param allowEmptyQuotes <p>Whether to treat "" as a token</p>
 | 
				
			||||||
 | 
					     * @return <p>A list of tokens</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static List<String> tokenize(String input, boolean allowEmptyQuotes) {
 | 
				
			||||||
        List<String> tokens = new ArrayList<>();
 | 
					        List<String> tokens = new ArrayList<>();
 | 
				
			||||||
        boolean startedQuote = false;
 | 
					        boolean startedQuote = false;
 | 
				
			||||||
        StringBuilder currentToken = new StringBuilder();
 | 
					        StringBuilder currentToken = new StringBuilder();
 | 
				
			||||||
@@ -29,7 +44,7 @@ public class Tokenizer {
 | 
				
			|||||||
                case '"':
 | 
					                case '"':
 | 
				
			||||||
                    if (startedQuote) {
 | 
					                    if (startedQuote) {
 | 
				
			||||||
                        //This quote signifies the end of the argument
 | 
					                        //This quote signifies the end of the argument
 | 
				
			||||||
                        if (isNotEmpty(currentToken)) {
 | 
					                        if (allowEmptyQuotes || isNotEmpty(currentToken)) {
 | 
				
			||||||
                            tokens.add(currentToken.toString());
 | 
					                            tokens.add(currentToken.toString());
 | 
				
			||||||
                            currentToken = new StringBuilder();
 | 
					                            currentToken = new StringBuilder();
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,16 +6,28 @@ prefix: PaidSigns
 | 
				
			|||||||
depend: [ Vault ]
 | 
					depend: [ Vault ]
 | 
				
			||||||
authors: [ EpicKnarvik97 ]
 | 
					authors: [ EpicKnarvik97 ]
 | 
				
			||||||
description: Add costs for creating plugin signs
 | 
					description: Add costs for creating plugin signs
 | 
				
			||||||
website: https://git.knarcraft.net
 | 
					website: https://git.knarcraft.net/EpicKnarvik97/PaidSigns
 | 
				
			||||||
commands:
 | 
					commands:
 | 
				
			||||||
  addpaidsign:
 | 
					  addpaidsign:
 | 
				
			||||||
    description: Used to add a new paid sign
 | 
					    description: Used to add a new paid sign
 | 
				
			||||||
    usage: /<command> <id (the text to look for)> <line> <cost> [ignore case] [ignore color]
 | 
					    usage: /<command> <name> <cost> [permission] [ignore case] [ignore color]
 | 
				
			||||||
    permission: paidsigns.add
 | 
					    permission: paidsigns.manage
 | 
				
			||||||
 | 
					  addpaidsigncondition:
 | 
				
			||||||
 | 
					    description: Used to add a new match condition for a paid sign
 | 
				
			||||||
 | 
					    usage: /<command> <name (of a paid sign)> <line number> <string to match> [executeRegEx] [ignoreCase] [ignoreColor]
 | 
				
			||||||
 | 
					    permission: paidsigns.manage
 | 
				
			||||||
 | 
					  listpaidsigns:
 | 
				
			||||||
 | 
					    description: Lists all previously added paid signs
 | 
				
			||||||
 | 
					    usage: /<command> [sign name] [line number]
 | 
				
			||||||
 | 
					    permission: paidsigns.manage
 | 
				
			||||||
 | 
					  removepaidsigncondition:
 | 
				
			||||||
 | 
					    description: Used to remove a match condition from a paid sign
 | 
				
			||||||
 | 
					    usage: /<command> <name (of a paid sign)> <line number>
 | 
				
			||||||
 | 
					    permission: paidsigns.manage
 | 
				
			||||||
  removepaidsign:
 | 
					  removepaidsign:
 | 
				
			||||||
    description: Used to remove a paid sign
 | 
					    description: Used to remove a paid sign
 | 
				
			||||||
    usage: /<command> <id (the text to look for)> <line>
 | 
					    usage: /<command> <name (of a paid sign)>
 | 
				
			||||||
    permission: paidsigns.remove
 | 
					    permission: paidsigns.manage
 | 
				
			||||||
  reload:
 | 
					  reload:
 | 
				
			||||||
    description: Reloads paid signs from disk
 | 
					    description: Reloads paid signs from disk
 | 
				
			||||||
    usage: /<command>
 | 
					    usage: /<command>
 | 
				
			||||||
@@ -28,7 +40,7 @@ permissions:
 | 
				
			|||||||
      paidsigns.create: true
 | 
					      paidsigns.create: true
 | 
				
			||||||
      paidsigns.paymentexempt: true
 | 
					      paidsigns.paymentexempt: true
 | 
				
			||||||
      paidsigns.reload: true
 | 
					      paidsigns.reload: true
 | 
				
			||||||
  paidsigns.add:
 | 
					  paidsigns.manage:
 | 
				
			||||||
    description: Grants the permission to add/remove a paid sign
 | 
					    description: Grants the permission to add/remove a paid sign
 | 
				
			||||||
    default: false
 | 
					    default: false
 | 
				
			||||||
  paidsigns.reload:
 | 
					  paidsigns.reload:
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user