Performs a lot of various changes

Adds some new command classes
Adds support for several languages
Adds README
Updates Java and Spigot versions
Adds command info and additional permission info to plugin.yml
Implements manual sign creation request cancelling
This commit is contained in:
Kristian Knarvik 2022-01-09 12:12:55 +01:00
parent d210b45ad5
commit 2917905b23
19 changed files with 502 additions and 52 deletions

5
README.md Normal file
View File

@ -0,0 +1,5 @@
# Permission Signs
This is a plugin based on the permission signs plugin created by _ForgeUser7294733. As the previous plugin does not
offer source code and has a restrictive license, this plugin is written from scratch, but trying to imitate the original
plugin's behavior.

10
pom.xml
View File

@ -13,7 +13,7 @@
<description>A plugin for selling permissions using signs</description>
<properties>
<java.version>16</java.version>
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<url>git.knarcraft.net</url>
@ -69,8 +69,14 @@
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.17.1-R0.1-SNAPSHOT</version>
<version>1.18.1-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,9 +1,14 @@
package net.knarcraft.permissionsigns;
import net.knarcraft.permissionsigns.command.PermissionSignsCommand;
import net.knarcraft.permissionsigns.command.PermissionSignsTabCompleter;
import net.knarcraft.permissionsigns.container.PermissionSign;
import net.knarcraft.permissionsigns.container.SignCreationRequest;
import net.knarcraft.permissionsigns.thread.SignCreationRequestTimeoutThread;
import org.bukkit.Bukkit;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler;
@ -14,12 +19,32 @@ import java.util.UUID;
import java.util.stream.Stream;
public final class PermissionSigns extends JavaPlugin {
private static Queue<SignCreationRequest> signCreationRequests = new PriorityQueue<>();
private static final Queue<SignCreationRequest> signCreationRequests = new PriorityQueue<>();
private static String pluginVersion;
/**
* Gets the version of this plugin
*
* @return <p>This plugin's version</p>
*/
public static String getPluginVersion() {
return pluginVersion;
}
/**
* Adds a new sign creation request
*
* @param player <p>The player that initiated the sign creation</p>
* @param sign <p>The sign the player is about to create</p>
*/
public static void addSignCreationRequest(Player player, PermissionSign sign) {
signCreationRequests.add(new SignCreationRequest(sign, player, System.currentTimeMillis()));
}
/**
* Gets the sign creation request for the player with the given UUID
*
*
* @param uuid <p>The UUID to get a sign creation request for</p>
* @return <p>A sign creation request, or null if the UUID is not found</p>
*/
@ -34,10 +59,25 @@ public final class PermissionSigns extends JavaPlugin {
}
}
/**
* Cancels the sign creation request triggered by the user
*
* @param uuid <p>The UUID of the player to cancel the request for</p>
*/
public static void cancelSignCreationRequest(UUID uuid) {
Stream<SignCreationRequest> matchingRequests = signCreationRequests.stream().filter(
(item) -> item.getPlayer().getUniqueId().equals(uuid));
List<SignCreationRequest> requestList = matchingRequests.toList();
signCreationRequests.remove(requestList.get(0));
}
@Override
public void onEnable() {
PluginDescriptionFile pluginDescriptionFile = this.getDescription();
pluginVersion = pluginDescriptionFile.getVersion();
// Plugin startup logic
//TODO: Add commands create, add and remove
// /ps create, /ps add, and /ps remove
// create initiates the creation, and add adds properties
@ -53,7 +93,7 @@ public final class PermissionSigns extends JavaPlugin {
// /ps cancel to cancel the sing creation
// Break the sign to remove it, check for permission first
// The name thing is probably useless, as the sign's location works as its id
//TODO: Display and register the permission-sign
// Start with [PermSign] in red
// Next line is the permission node. Last child, upper-cased
@ -61,23 +101,36 @@ public final class PermissionSigns extends JavaPlugin {
// Last line is the cost, including the unit
// Need to store any temporary permissions in a list/queue and have a thread which searches for expired
// permissions to de-register them
//Not persistent, but might work as things shouldn't persist anyway
//player.addAttachment(this, "essentials.fly", true, seconds * 20);
//Vault probably has some API to add permissions
//TODO: Start sign creation when the create command is used and save the data until an empty sign is right-clicked
//TODO: Check for existence of old permission signs when clicked and register them as new permission signs. If
// it has the permissionSigns header and a name matching contents in signdata.yml, add it.
registerCommands();
BukkitScheduler scheduler = Bukkit.getScheduler();
scheduler.runTaskTimer(this, new SignCreationRequestTimeoutThread(signCreationRequests), 0L, 100L);
}
/**
* Registers a command for this plugin
*/
private void registerCommands() {
PluginCommand stargateCommand = this.getCommand("permissionsigns");
if (stargateCommand != null) {
stargateCommand.setExecutor(new PermissionSignsCommand());
stargateCommand.setTabCompleter(new PermissionSignsTabCompleter());
}
}
@Override
public void onDisable() {
// Plugin shutdown logic
}
}

View File

@ -0,0 +1,24 @@
package net.knarcraft.permissionsigns.command;
import net.knarcraft.permissionsigns.PermissionSigns;
import net.knarcraft.permissionsigns.formatting.StringFormatter;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
/**
* A command for getting information about the plugin
*/
public class AboutCommand implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
sender.sendMessage(StringFormatter.formatInfoMessage("Permission Signs plugin created by " + ChatColor.GOLD +
"EpicKnarvik97"));
sender.sendMessage(StringFormatter.formatInfoMessage("Plugin version: " + PermissionSigns.getPluginVersion()));
return true;
}
}

View File

@ -1,14 +1,21 @@
package net.knarcraft.permissionsigns.command;
import net.knarcraft.permissionsigns.PermissionSigns;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
* The command used to cancel a sign creation request
*/
public class CancelCommand implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
return false;
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
PermissionSigns.cancelSignCreationRequest(((Player) sender).getUniqueId());
return true;
}
}

View File

@ -1,17 +1,55 @@
package net.knarcraft.permissionsigns.command;
import net.knarcraft.permissionsigns.PermissionSigns;
import net.knarcraft.permissionsigns.container.PermissionSign;
import net.knarcraft.permissionsigns.formatting.TranslatableMessage;
import net.knarcraft.permissionsigns.formatting.Translator;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* The command used to create a new permission sign
*/
public class CreateCommand implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
// /ps create <name> <permission,permission> <cost> <duration> to create a new permission-sign
//Name and permission(s) required, but duration and cost optional
return false;
if (!(sender instanceof Player)) {
sender.sendMessage(Translator.getTranslatedMessage(TranslatableMessage.COMMAND_PLAYER_ONLY));
return false;
}
if (args.length < 2) {
sender.sendMessage(Translator.getTranslatedMessage(TranslatableMessage.MISSING_CREATION_INFO));
return false;
}
String name = args[0];
String[] permissions = args[1].split(",");
int cost;
int duration;
try {
cost = Integer.parseInt(args[2]);
} catch (NumberFormatException exception) {
sender.sendMessage(Translator.getTranslatedMessage(TranslatableMessage.COST_INVALID_NUMBER));
return false;
}
try {
duration = Integer.parseInt(args[3]);
} catch (NumberFormatException exception) {
sender.sendMessage(Translator.getTranslatedMessage(TranslatableMessage.DURATION_INVALID_NUMBER));
return false;
}
PermissionSign newSign = new PermissionSign(name, List.of(permissions), cost, duration);
PermissionSigns.addSignCreationRequest((Player) sender, newSign);
return true;
}
}

View File

@ -3,14 +3,18 @@ package net.knarcraft.permissionsigns.command;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* The tab completer for the create command
*/
public class CreateTabCompleter implements TabCompleter {
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
return null;
}
}

View File

@ -0,0 +1,27 @@
package net.knarcraft.permissionsigns.command;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
/**
* The main command for this plugin
*/
public class PermissionSignsCommand implements CommandExecutor {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
if (args.length > 0) {
if (args[0].equalsIgnoreCase("create")) {
} else if (args[0].equalsIgnoreCase("cancel")) {
} else if (args[0].equalsIgnoreCase("about")) {
}
}
return false;
}
}

View File

@ -0,0 +1,56 @@
package net.knarcraft.permissionsigns.command;
import org.apache.commons.lang.ArrayUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* The tab completer for this plugin's main command
*/
public class PermissionSignsTabCompleter implements TabCompleter {
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
if (args.length == 1) {
List<String> commands = getAvailableCommands(sender);
List<String> matchingCommands = new ArrayList<>();
for (String availableCommand : commands) {
if (availableCommand.startsWith(args[0])) {
matchingCommands.add(availableCommand);
}
}
return matchingCommands;
} else if (args.length > 1 && args[0].equalsIgnoreCase("create")) {
String[] subArgs = (String[]) ArrayUtils.remove(args, 0);
return new CreateTabCompleter().onTabComplete(sender, command, alias, subArgs);
} else {
return new ArrayList<>();
}
}
/**
* Gets the available commands
*
* @param commandSender <p>The command sender to get available commands for</p>
* @return <p>The commands available to the command sender</p>
*/
private List<String> getAvailableCommands(CommandSender commandSender) {
List<String> commands = new ArrayList<>();
commands.add("about");
if (!(commandSender instanceof Player player) || player.hasPermission("permissionsigns.admin.reload")) {
commands.add("reload");
}
if (commandSender instanceof Player player && player.hasPermission("permissionsigns.admin.create")) {
commands.add("create");
commands.add("cancel");
}
return commands;
}
}

View File

@ -0,0 +1,4 @@
package net.knarcraft.permissionsigns.command;
public class ReloadCommand {
}

View File

@ -1,6 +1,8 @@
package net.knarcraft.permissionsigns.container;
import net.knarcraft.permissionsigns.PermissionSigns;
import net.knarcraft.permissionsigns.formatting.TranslatableMessage;
import net.knarcraft.permissionsigns.formatting.Translator;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import java.util.ArrayList;
@ -30,6 +32,8 @@ public class PermissionSign {
this.signLocation = signLocation;
this.name = name;
this.permissionNodes = new ArrayList<>(permissionNodes);
//Automatically fix negative values
this.duration = Math.max(0, duration);
this.cost = Math.max(0, cost);
}
@ -37,11 +41,12 @@ public class PermissionSign {
/**
* Instantiates a new permission sign
*
* @param name <p>The name to display on the permission sign</p>
* @param permissionNodes <p>The permissions granted when this permission sign is used</p>
* @param duration <p>The duration, in seconds, until the permission should be revoked. 0 for non-temporary</p>
* @param cost <p>The cost of using this permission sign</p>
*/
public PermissionSign(List<String> permissionNodes, int duration, int cost) {
public PermissionSign(String name, List<String> permissionNodes, int duration, int cost) {
this.permissionNodes = new ArrayList<>(permissionNodes);
this.duration = Math.max(0, duration);
this.cost = Math.max(0, cost);
@ -49,7 +54,7 @@ public class PermissionSign {
/**
* Sets the sign location of this permission sign
*
*
* @param signLocation <p>>The location of this permission sign's actual sign</p>
*/
public void setSignLocation(Location signLocation) {
@ -64,7 +69,7 @@ public class PermissionSign {
* Gets the location of this permission sign
*
* <p>The location might be null until a sign has been right-clicked</p>
*
*
* @return <p>The location of this permission sign</p>
*/
public Location getSignLocation() {
@ -73,7 +78,7 @@ public class PermissionSign {
/**
* Gets the name of this permission sign
*
*
* @return <p>The name of this permission sign</p>
*/
public String getName() {
@ -108,7 +113,21 @@ public class PermissionSign {
public int getCost() {
return this.cost;
}
/**
* Gets the lines used to represent this permission sign on a sign
*
* @return <p>The lines used to draw this permission sign</p>
*/
public String[] getSignLines() {
String[] lines = new String[4];
lines[0] = ChatColor.RED + Translator.getTranslatedMessage(TranslatableMessage.PREFIX);
lines[1] = getName();
lines[2] = getDurationString();
lines[3] = getCostString();
return lines;
}
@Override
public boolean equals(Object other) {
if (!(other instanceof PermissionSign)) {
@ -117,8 +136,35 @@ public class PermissionSign {
if (this == other) {
return true;
}
return this.signLocation.equals(((PermissionSign) other).signLocation);
}
/**
* Gets the string used for displaying this sign's duration
*
* @return <p>The string used for displaying this sign's duration</p>
*/
private String getDurationString() {
if (duration == 0) {
return Translator.getTranslatedMessage(TranslatableMessage.PERMANENT);
} else {
return duration + " " + Translator.getTranslatedMessage(TranslatableMessage.TIME_UNIT);
}
}
/**
* Gets the string used for displaying this sign's cost
*
* @return <p>The string used for displaying this sign's cost</p>
*/
private String getCostString() {
if (cost == 0) {
return Translator.getTranslatedMessage(TranslatableMessage.COST_FREE);
} else {
//TODO: Get currency unit from Vault
return cost + "$";
}
}
}

View File

@ -6,16 +6,16 @@ import org.bukkit.entity.Player;
* A sign creation request represents the state where a player has used the create command, but not clicked a sign
*/
public class SignCreationRequest implements Comparable<SignCreationRequest> {
private final PermissionSign permissionSign;
private final Player player;
private final long initiationTime;
/**
* Instantiates a new sign creation request
*
*
* @param permissionSign <p>The sign which is about to be created</p>
* @param player <p>The player starting to create the permission sign</p>
* @param player <p>The player starting to create the permission sign</p>
* @param initiationTime <p></p>
*/
public SignCreationRequest(PermissionSign permissionSign, Player player, long initiationTime) {
@ -26,7 +26,7 @@ public class SignCreationRequest implements Comparable<SignCreationRequest> {
/**
* Gets the permission sign involved in this request
*
*
* @return <p>The involved permission sign</p>
*/
public PermissionSign getPermissionSign() {
@ -35,7 +35,7 @@ public class SignCreationRequest implements Comparable<SignCreationRequest> {
/**
* Gets the player involved in this request
*
*
* @return <p>The involved player</p>
*/
public Player getPlayer() {
@ -44,13 +44,13 @@ public class SignCreationRequest implements Comparable<SignCreationRequest> {
/**
* Gets the time this sign creation request was initiated
*
*
* @return <p>The time this request was initiated</p>
*/
public long initiationTime() {
return this.initiationTime;
}
@Override
public boolean equals(Object other) {
if (!(other instanceof SignCreationRequest otherRequest)) {
@ -59,7 +59,7 @@ public class SignCreationRequest implements Comparable<SignCreationRequest> {
if (this == other) {
return true;
}
return this.getPlayer().getUniqueId() == otherRequest.getPlayer().getUniqueId();
}

View File

@ -0,0 +1,40 @@
package net.knarcraft.permissionsigns.formatting;
import org.bukkit.ChatColor;
/**
* A formatter for formatting displayed messages
*/
public class StringFormatter {
/**
* Formats an information message by adding the prefix and text color
*
* @param message <p>The message to format</p>
* @return <p>The formatted message</p>
*/
public static String formatInfoMessage(String message) {
return ChatColor.DARK_RED + formatMessage(message);
}
/**
* Formats an error message by adding the prefix and text color
*
* @param message <p>The message to format</p>
* @return <p>The formatted message</p>
*/
public static String formatErrorMessage(String message) {
return ChatColor.DARK_GREEN + formatMessage(message);
}
/**
* Formats a message by adding the prefix and text color
*
* @param message <p>The message to format</p>
* @return <p>The formatted message</p>
*/
private static String formatMessage(String message) {
return Translator.getTranslatedMessage(TranslatableMessage.PREFIX) + ChatColor.GRAY + message;
}
}

View File

@ -0,0 +1,19 @@
package net.knarcraft.permissionsigns.formatting;
/**
* An enum representing all translatable messages
*/
public enum TranslatableMessage {
PREFIX,
MISSING_CREATION_INFO,
TIME_UNIT,
COST_FREE,
PERMANENT,
COST_INVALID_NUMBER,
DURATION_INVALID_NUMBER,
COMMAND_PLAYER_ONLY,
PERMISSION_SIGN_DESTROY_DENY,
PERMISSION_SIGN_REMOVED
}

View File

@ -0,0 +1,67 @@
package net.knarcraft.permissionsigns.formatting;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
/**
* A tool to get strings translated to the correct language
*/
public class Translator {
private static Map<TranslatableMessage, String> translatedMessages;
private static Map<TranslatableMessage, String> backupTranslatedMessages;
/**
* Loads the languages used by this translator
*/
public Translator() {
backupTranslatedMessages = loadTranslatedMessages("en");
translatedMessages = loadTranslatedMessages("en");
}
/**
* Gets a translated version of the given translatable message
*
* @param translatableMessage <p>The message to translate</p>
* @return <p>The translated message</p>
*/
public static String getTranslatedMessage(TranslatableMessage translatableMessage) {
if (translatedMessages.containsKey(translatableMessage)) {
return translatedMessages.get(translatableMessage);
} else if (backupTranslatedMessages.containsKey(translatableMessage)) {
return backupTranslatedMessages.get(translatableMessage);
} else {
return translatableMessage.toString();
}
}
/**
* Loads all translated messages for the given language
*
* @param language <p>The language chosen by the user</p>
* @return <p>A mapping of all strings for the given language</p>
*/
public static Map<TranslatableMessage, String> loadTranslatedMessages(String language) {
Map<TranslatableMessage, String> translatedMessages = new HashMap<>();
InputStream inputStream = Translator.class.getResourceAsStream("/strings.yml");
if (inputStream == null) {
throw new IllegalArgumentException("Unable to load strings");
}
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(reader);
for (TranslatableMessage message : TranslatableMessage.values()) {
String translated = configuration.getString(language + "." + message.toString());
if (translated != null) {
translatedMessages.put(message, translated);
}
}
return translatedMessages;
}
}

View File

@ -2,6 +2,8 @@ package net.knarcraft.permissionsigns.listener;
import net.knarcraft.permissionsigns.PermissionSigns;
import net.knarcraft.permissionsigns.container.SignCreationRequest;
import net.knarcraft.permissionsigns.formatting.TranslatableMessage;
import net.knarcraft.permissionsigns.formatting.Translator;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.block.Block;
@ -14,6 +16,9 @@ import org.bukkit.event.player.PlayerInteractEvent;
import java.util.Arrays;
/**
* A listener for all events related to signs
*/
public class SignListener implements Listener {
/**
@ -29,26 +34,46 @@ public class SignListener implements Listener {
if (block == null) {
return;
}
Material material = block.getBlockData().getMaterial();
if (!Tag.SIGNS.isTagged(material) && !Tag.WALL_SIGNS.isTagged(material)) {
return;
}
Sign sign = (Sign) block.getState();
if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
Sign sign = (Sign) block.getState();
handleSignRightClick(sign, player);
} else if (event.getAction() == Action.LEFT_CLICK_BLOCK) {
handleSignLeftClick(sign, player, event);
}
}
private void handleSignLeftClick(Sign sign, Player player, PlayerInteractEvent event) {
//TODO: Check if the sign is a registered permissions sign
boolean registered = true;
if (!registered) {
return;
}
if (!player.hasPermission("permissionsigns.admin")) {
event.setCancelled(true);
player.sendMessage(Translator.getTranslatedMessage(TranslatableMessage.PERMISSION_SIGN_DESTROY_DENY));
} else {
//TODO: Un-register the permissions sign
player.sendMessage(Translator.getTranslatedMessage(TranslatableMessage.PERMISSION_SIGN_REMOVED));
}
}
/**
* Handles the right-clicking action
*
* @param sign <p>The clicked sign</p>
*
* @param sign <p>The clicked sign</p>
* @param player <p>The player that clicked the sign</p>
*/
private void handleSignRightClick(Sign sign, Player player) {
String[] lines = sign.getLines();
//TODO: Check if the sign is a registered permissions sign
//Don't allow non-empty signs to be overwritten
if (!Arrays.stream(lines).allMatch(String::isEmpty)) {
return;
@ -61,5 +86,5 @@ public class SignListener implements Listener {
//TODO: Register the sign and remove the request
}
}

View File

@ -8,23 +8,23 @@ import java.util.Queue;
* The sign creation request timeout thread is responsible for removing sign creation requests as they time out
*/
public class SignCreationRequestTimeoutThread implements Runnable {
private final Queue<SignCreationRequest> signCreationRequests;
/**
* Instantiates a new sign creation request timeout thread
*
*
* @param signCreationRequests <p>A pointer to the queue of sign creation requests</p>
*/
public SignCreationRequestTimeoutThread(Queue<SignCreationRequest> signCreationRequests) {
this.signCreationRequests = signCreationRequests;
}
@Override
public void run() {
long currentTime = System.currentTimeMillis();
int requestTimeoutSeconds = 20;
int requestTimeoutSeconds = 60;
SignCreationRequest firstElement = signCreationRequests.peek();
while (firstElement != null && currentTime > firstElement.initiationTime() + (1000 * requestTimeoutSeconds)) {
//Remove any expired sign creation requests
@ -32,5 +32,5 @@ public class SignCreationRequestTimeoutThread implements Runnable {
firstElement = signCreationRequests.peek();
}
}
}

View File

@ -1,17 +1,35 @@
name: PermissionSigns
version: '${project.version}'
main: net.knarcraft.permissionsigns.Permissionsigns
api-version: 1.17
api-version: 1.18
prefix: PermissionSigns
depend: [ Vault ]
authors: [ EpicKnarvik97 ]
description: A plugin for selling permissions using signs
website: git.knarcraft.net
permissions:
commands:
permissionsigns:
aliases:
- ps
- permsigns
- permsign
- signperm
- signperms
description: Used for all permission sign commands
usage: /<command> <about/create/cancel/reload> - Used for all permission sign commands
permissions:
permissionsigns.use:
description: Allows players to use the permission signs
default: true
permissionsigns.admin:
description: Allows all administrative tasks such as creating permission signs and reloading
default: op
children:
permissionsigns.admin.reload: true
permissionsigns.admin.create: true
permissionsigns.admin.reload:
description: Allows the usage of the /reload command
default: op
permissionsigns.admin.create:
description: Allows players to create/destroy permissionsigns
default: op

View File

@ -0,0 +1,11 @@
en:
PREFIX: "[PermSign]"
MISSING_CREATION_INFO: "You must specify a sign name and a comma-separated list of permissions to create a permission sign"
TIME_UNIT: "seconds"
PERMANENT: "Permanent"
COST_FREE: "Free"
COST_INVALID_NUMBER: "The given cost is not a valid number"
DURATION_INVALID_NUMBER: "The given duration is not a valid number"
COMMAND_PLAYER_ONLY: "This command is only available to players"
PERMISSION_SIGN_DESTROY_DENY: "You do not have permissions to delete a permissions sign"
PERMISSION_SIGN_REMOVED: "Permissions sign removed"