Uses KnarLib methods
All checks were successful
KnarCraft/PermissionSigns/pipeline/head This commit looks good
All checks were successful
KnarCraft/PermissionSigns/pipeline/head This commit looks good
This commit is contained in:
parent
e77402c164
commit
a3578fe754
@ -1,38 +1,33 @@
|
||||
package net.knarcraft.permissionsigns;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.knarlib.formatting.Translator;
|
||||
import net.knarcraft.knarlib.util.UpdateChecker;
|
||||
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.formatting.Translator;
|
||||
import net.knarcraft.permissionsigns.config.Configuration;
|
||||
import net.knarcraft.permissionsigns.config.Translatable;
|
||||
import net.knarcraft.permissionsigns.listener.BlockListener;
|
||||
import net.knarcraft.permissionsigns.listener.PlayerListener;
|
||||
import net.knarcraft.permissionsigns.listener.SignListener;
|
||||
import net.knarcraft.permissionsigns.manager.EconomyManager;
|
||||
import net.knarcraft.permissionsigns.manager.PermissionManager;
|
||||
import net.knarcraft.permissionsigns.manager.SignCreationManager;
|
||||
import net.knarcraft.permissionsigns.manager.SignManager;
|
||||
import net.knarcraft.permissionsigns.thread.PermissionTimeoutThread;
|
||||
import net.knarcraft.permissionsigns.thread.SignCreationRequestTimeoutThread;
|
||||
import net.knarcraft.permissionsigns.utility.UpdateChecker;
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.ServicesManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Queue;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/*
|
||||
PermissionSigns - A permission shop plugin for Spigot
|
||||
@ -59,13 +54,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
public final class PermissionSigns extends JavaPlugin {
|
||||
|
||||
private static final Queue<SignCreationRequest> signCreationRequests = new PriorityQueue<>();
|
||||
private static String pluginVersion;
|
||||
private static PermissionSigns instance;
|
||||
private static boolean perWorldPermissions;
|
||||
private static boolean enableExtensiveSignProtection;
|
||||
private static boolean enableIndirectSignProtection;
|
||||
private static boolean removePermissionSignIfMissing;
|
||||
private Translator translator;
|
||||
private StringFormatter stringFormatter;
|
||||
private Configuration configuration;
|
||||
|
||||
/**
|
||||
* Instantiates the permission signs class
|
||||
@ -85,96 +77,46 @@ public final class PermissionSigns extends JavaPlugin {
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the translator
|
||||
*
|
||||
* @return <p>The translator</p>
|
||||
*/
|
||||
public @NotNull Translator getTranslator() {
|
||||
return translator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string formatter
|
||||
*
|
||||
* @return <p>The string formatter</p>
|
||||
*/
|
||||
public @NotNull StringFormatter stringFormatter() {
|
||||
return stringFormatter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this plugin's configuration
|
||||
*
|
||||
* @return <p>This plugin's configuration</p>
|
||||
*/
|
||||
public Configuration getConfiguration() {
|
||||
return configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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>
|
||||
*/
|
||||
public static SignCreationRequest getSignCreationRequest(UUID uuid) {
|
||||
Stream<SignCreationRequest> matchingRequests = signCreationRequests.stream().filter(
|
||||
(item) -> item.getPlayer().getUniqueId().equals(uuid));
|
||||
List<SignCreationRequest> requestList = matchingRequests.toList();
|
||||
if (!requestList.isEmpty()) {
|
||||
return requestList.get(0);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
if (requestList.size() > 0) {
|
||||
signCreationRequests.remove(requestList.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether permissions should always be set for the world the sign belongs to
|
||||
*
|
||||
* @return <p>Whether permissions should be set for the current world</p>
|
||||
*/
|
||||
public static boolean usePerWorldPermissions() {
|
||||
return perWorldPermissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether permission signs on falling blocks should be protected
|
||||
*
|
||||
* @return <p>Whether permission signs on falling blocks should be protected</p>
|
||||
*/
|
||||
public static boolean extensiveSignProtectionEnabled() {
|
||||
return enableExtensiveSignProtection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether permission sign explosion and piston protection is enabled
|
||||
*
|
||||
* @return <p>Whether permission sign explosion and piston protection is enabled</p>
|
||||
*/
|
||||
public static boolean indirectProtectionEnabled() {
|
||||
return enableIndirectSignProtection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether to remove permissions signs if their physical signs are missing
|
||||
*
|
||||
* @return <p>Whether tor remove permission signs if their signs are missing</p>
|
||||
*/
|
||||
public static boolean removePermissionSignIfMissing() {
|
||||
return removePermissionSignIfMissing;
|
||||
public String getPluginVersion() {
|
||||
return this.getDescription().getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadConfig() {
|
||||
super.reloadConfig();
|
||||
Translator.loadLanguages(loadConfig());
|
||||
loadConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -182,15 +124,15 @@ public final class PermissionSigns extends JavaPlugin {
|
||||
//Check if vault is loaded
|
||||
setupVault();
|
||||
|
||||
//Get plugin info
|
||||
PluginDescriptionFile pluginDescriptionFile = this.getDescription();
|
||||
pluginVersion = pluginDescriptionFile.getVersion();
|
||||
|
||||
//Load config and write the default config if necessary
|
||||
FileConfiguration config = this.getConfig();
|
||||
this.saveDefaultConfig();
|
||||
config.options().copyDefaults(true);
|
||||
Translator.loadLanguages(loadConfig());
|
||||
|
||||
translator = new Translator();
|
||||
translator.registerMessageCategory(Translatable.ALREADY_HAS_PERMISSIONS);
|
||||
stringFormatter = new StringFormatter(this.getDescription().getName(), translator);
|
||||
configuration = new Configuration(this.getConfig(), translator, this.getDataFolder());
|
||||
|
||||
registerListeners();
|
||||
registerCommands();
|
||||
@ -200,23 +142,26 @@ public final class PermissionSigns extends JavaPlugin {
|
||||
PermissionManager.loadTemporaryPermissions();
|
||||
|
||||
UpdateChecker.checkForUpdate(this, "https://api.spigotmc.org/legacy/update.php?resource=99426",
|
||||
() -> pluginVersion, null);
|
||||
() -> this.getDescription().getVersion(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
try {
|
||||
SignManager.saveSigns();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
SignCreationManager.stopTimeoutTimer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the config file
|
||||
*
|
||||
* @return <p>The currently selected language</p>
|
||||
*/
|
||||
private String loadConfig() {
|
||||
FileConfiguration config = this.getConfig();
|
||||
String language = config.getString("language", "en");
|
||||
perWorldPermissions = config.getBoolean("perWorldPermissions", false);
|
||||
enableExtensiveSignProtection = config.getBoolean("enableExtensiveSignProtection", false);
|
||||
enableIndirectSignProtection = config.getBoolean("enableIndirectSignProtection", true);
|
||||
removePermissionSignIfMissing = config.getBoolean("removePermissionSignIfMissing", true);
|
||||
private void loadConfig() {
|
||||
this.reloadConfig();
|
||||
configuration.loadConfig(this.getConfig());
|
||||
saveConfig();
|
||||
return language;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -224,7 +169,7 @@ public final class PermissionSigns extends JavaPlugin {
|
||||
*/
|
||||
private void runThreads() {
|
||||
BukkitScheduler scheduler = Bukkit.getScheduler();
|
||||
scheduler.runTaskTimer(this, new SignCreationRequestTimeoutThread(signCreationRequests), 0L, 100L);
|
||||
SignCreationManager.runTimeoutTimer();
|
||||
scheduler.runTaskTimer(this, new PermissionTimeoutThread(), 0L, 25L);
|
||||
}
|
||||
|
||||
@ -264,13 +209,4 @@ public final class PermissionSigns extends JavaPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
try {
|
||||
SignManager.saveSigns();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.knarcraft.permissionsigns.command;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
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;
|
||||
@ -14,11 +14,13 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class AboutCommand implements CommandExecutor {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, @NotNull Command command, @NotNull String label,
|
||||
public boolean onCommand(@NotNull 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()));
|
||||
StringFormatter stringFormatter = PermissionSigns.getInstance().stringFormatter();
|
||||
stringFormatter.displaySuccessMessage(sender, "Permission Signs plugin created by " + ChatColor.GOLD +
|
||||
"EpicKnarvik97");
|
||||
stringFormatter.displaySuccessMessage(sender, "Plugin version: " +
|
||||
PermissionSigns.getInstance().getPluginVersion());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
package net.knarcraft.permissionsigns.command;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.permissionsigns.PermissionSigns;
|
||||
import net.knarcraft.permissionsigns.formatting.StringFormatter;
|
||||
import net.knarcraft.permissionsigns.formatting.TranslatableMessage;
|
||||
import net.knarcraft.permissionsigns.config.Translatable;
|
||||
import net.knarcraft.permissionsigns.manager.SignCreationManager;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@ -17,15 +18,17 @@ public class CancelCommand implements CommandExecutor {
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
|
||||
@NotNull String[] args) {
|
||||
StringFormatter stringFormatter = PermissionSigns.getInstance().stringFormatter();
|
||||
|
||||
if (sender instanceof Player player) {
|
||||
if (sender.hasPermission("permissionsigns.admin.create")) {
|
||||
PermissionSigns.cancelSignCreationRequest(player.getUniqueId());
|
||||
sender.sendMessage(StringFormatter.getTranslatedInfoMessage(TranslatableMessage.CREATION_REQUEST_CANCELLED));
|
||||
SignCreationManager.cancelSignCreationRequest(player.getUniqueId());
|
||||
stringFormatter.displaySuccessMessage(sender, Translatable.CREATION_REQUEST_CANCELLED);
|
||||
} else {
|
||||
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.COMMAND_PERMISSION_DENIED));
|
||||
stringFormatter.displayErrorMessage(sender, Translatable.COMMAND_PERMISSION_DENIED);
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.COMMAND_PLAYER_ONLY));
|
||||
stringFormatter.displayErrorMessage(sender, Translatable.COMMAND_PLAYER_ONLY);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
package net.knarcraft.permissionsigns.command;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.permissionsigns.PermissionSigns;
|
||||
import net.knarcraft.permissionsigns.config.Translatable;
|
||||
import net.knarcraft.permissionsigns.container.PermissionSign;
|
||||
import net.knarcraft.permissionsigns.formatting.StringFormatter;
|
||||
import net.knarcraft.permissionsigns.formatting.TranslatableMessage;
|
||||
import net.knarcraft.permissionsigns.manager.SignCreationManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
@ -25,16 +26,18 @@ public class CreateCommand implements CommandExecutor {
|
||||
//Name and permission(s) required, but duration and cost optional
|
||||
String usage = "/ps create <name> <description> <permission,permission> [cost] [duration] - Used for creating" +
|
||||
" a new permission sign";
|
||||
StringFormatter stringFormatter = PermissionSigns.getInstance().stringFormatter();
|
||||
|
||||
if (!(sender instanceof Player)) {
|
||||
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.COMMAND_PLAYER_ONLY));
|
||||
stringFormatter.displayErrorMessage(sender, Translatable.COMMAND_PLAYER_ONLY);
|
||||
return false;
|
||||
}
|
||||
if (!sender.hasPermission("permissionsigns.admin.create")) {
|
||||
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.COMMAND_PERMISSION_DENIED));
|
||||
stringFormatter.displayErrorMessage(sender, Translatable.COMMAND_PERMISSION_DENIED);
|
||||
return false;
|
||||
}
|
||||
if (args.length < 3) {
|
||||
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.MISSING_CREATION_INFO));
|
||||
stringFormatter.displayErrorMessage(sender, Translatable.MISSING_CREATION_INFO);
|
||||
sender.sendMessage(usage);
|
||||
return true;
|
||||
}
|
||||
@ -44,9 +47,9 @@ public class CreateCommand implements CommandExecutor {
|
||||
sender.sendMessage(usage);
|
||||
return true;
|
||||
}
|
||||
PermissionSigns.addSignCreationRequest((Player) sender, newSign);
|
||||
SignCreationManager.addSignCreationRequest((Player) sender, newSign);
|
||||
|
||||
sender.sendMessage(StringFormatter.getTranslatedInfoMessage(TranslatableMessage.CREATION_REQUEST_CREATED));
|
||||
stringFormatter.displaySuccessMessage(sender, Translatable.CREATION_REQUEST_CREATED);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -54,40 +57,45 @@ public class CreateCommand implements CommandExecutor {
|
||||
* Parses the permission sign given in user input
|
||||
*
|
||||
* @param sender <p>The sender that initiated the command</p>
|
||||
* @param args <p>The given command arguments</p>
|
||||
* @param arguments <p>The given command arguments</p>
|
||||
* @return <p>The parsed sign, or null if it could not be parsed</p>
|
||||
*/
|
||||
private PermissionSign parseSign(@NotNull CommandSender sender, @NotNull String[] args) {
|
||||
String name = args[0];
|
||||
String description = replaceUnderscoresWithSpaces(args[1]);
|
||||
String[] permissions = args[2].replaceAll("\\?", " ").split(",");
|
||||
private PermissionSign parseSign(@NotNull CommandSender sender, @NotNull String[] arguments) {
|
||||
String name = arguments[0];
|
||||
String description = replaceUnderscoresWithSpaces(arguments[1]);
|
||||
String[] permissions = arguments[2].replaceAll("\\?", " ").split(",");
|
||||
StringFormatter stringFormatter = PermissionSigns.getInstance().stringFormatter();
|
||||
|
||||
for (String permission : permissions) {
|
||||
if (permission.contains(":")) {
|
||||
if (!permission.contains(":")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String world = permission.split(":")[0];
|
||||
if (!world.equalsIgnoreCase("all") && !world.equalsIgnoreCase("any") &&
|
||||
Bukkit.getWorld(world) == null) {
|
||||
sender.sendMessage(StringFormatter.replacePlaceholder(StringFormatter.getTranslatedErrorMessage(
|
||||
TranslatableMessage.PERMISSION_WORLD_INVALID), "{world}", world));
|
||||
|
||||
stringFormatter.displayErrorMessage(sender, stringFormatter.replacePlaceholder(
|
||||
Translatable.PERMISSION_WORLD_INVALID, "{world}", world));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double cost = 0;
|
||||
int duration = 0;
|
||||
if (args.length > 3) {
|
||||
if (arguments.length > 3) {
|
||||
try {
|
||||
cost = Double.parseDouble(args[3]);
|
||||
cost = Double.parseDouble(arguments[3]);
|
||||
} catch (NumberFormatException exception) {
|
||||
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.COST_INVALID_NUMBER));
|
||||
stringFormatter.displayErrorMessage(sender, Translatable.COST_INVALID_NUMBER);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (args.length > 4) {
|
||||
if (arguments.length > 4) {
|
||||
try {
|
||||
duration = Integer.parseInt(args[4]);
|
||||
duration = Integer.parseInt(arguments[4]);
|
||||
} catch (NumberFormatException exception) {
|
||||
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.DURATION_INVALID_NUMBER));
|
||||
stringFormatter.displayErrorMessage(sender, Translatable.DURATION_INVALID_NUMBER);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package net.knarcraft.permissionsigns.command;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.permissionsigns.PermissionSigns;
|
||||
import net.knarcraft.permissionsigns.formatting.StringFormatter;
|
||||
import net.knarcraft.permissionsigns.formatting.TranslatableMessage;
|
||||
import net.knarcraft.permissionsigns.config.Translatable;
|
||||
import net.knarcraft.permissionsigns.manager.PermissionManager;
|
||||
import net.knarcraft.permissionsigns.manager.SignManager;
|
||||
import org.bukkit.command.Command;
|
||||
@ -18,13 +18,14 @@ public class ReloadCommand implements CommandExecutor {
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
|
||||
@NotNull String[] args) {
|
||||
StringFormatter stringFormatter = PermissionSigns.getInstance().stringFormatter();
|
||||
if (sender.hasPermission("permissionsigns.admin.reload")) {
|
||||
SignManager.loadSigns();
|
||||
PermissionManager.loadTemporaryPermissions();
|
||||
PermissionSigns.getInstance().reloadConfig();
|
||||
sender.sendMessage(StringFormatter.getTranslatedInfoMessage(TranslatableMessage.RELOAD_SUCCESSFUL));
|
||||
stringFormatter.displaySuccessMessage(sender, Translatable.RELOAD_SUCCESSFUL);
|
||||
} else {
|
||||
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.COMMAND_PERMISSION_DENIED));
|
||||
stringFormatter.displayErrorMessage(sender, Translatable.COMMAND_PERMISSION_DENIED);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -0,0 +1,85 @@
|
||||
package net.knarcraft.permissionsigns.config;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.Translator;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* PermissionSigns' configuration file
|
||||
*/
|
||||
public class Configuration {
|
||||
|
||||
private final Translator translator;
|
||||
private final File dataFolder;
|
||||
private boolean perWorldPermissions;
|
||||
private boolean enableExtensiveSignProtection;
|
||||
private boolean enableIndirectSignProtection;
|
||||
private boolean removePermissionSignIfMissing;
|
||||
|
||||
/**
|
||||
* Instantiates a new configuration
|
||||
*
|
||||
* @param fileConfiguration <p>The file configuration to load</p>
|
||||
* @param translator <p>The translator to load translations for</p>
|
||||
* @param dataFolder <p>This plugin's data folder</p>
|
||||
*/
|
||||
public Configuration(@NotNull FileConfiguration fileConfiguration, @NotNull Translator translator,
|
||||
@NotNull File dataFolder) {
|
||||
this.translator = translator;
|
||||
this.dataFolder = dataFolder;
|
||||
loadConfig(fileConfiguration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the current configuration
|
||||
*
|
||||
* @param fileConfiguration <p>The file configuration to load</p>
|
||||
*/
|
||||
public void loadConfig(@NotNull FileConfiguration fileConfiguration) {
|
||||
String language = fileConfiguration.getString("language", "en");
|
||||
perWorldPermissions = fileConfiguration.getBoolean("perWorldPermissions", false);
|
||||
enableExtensiveSignProtection = fileConfiguration.getBoolean("enableExtensiveSignProtection", false);
|
||||
enableIndirectSignProtection = fileConfiguration.getBoolean("enableIndirectSignProtection", true);
|
||||
removePermissionSignIfMissing = fileConfiguration.getBoolean("removePermissionSignIfMissing", true);
|
||||
translator.loadLanguages(dataFolder, "en", language);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether permissions should always be set for the world the sign belongs to
|
||||
*
|
||||
* @return <p>Whether permissions should be set for the current world</p>
|
||||
*/
|
||||
public boolean usePerWorldPermissions() {
|
||||
return perWorldPermissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether permission signs on falling blocks should be protected
|
||||
*
|
||||
* @return <p>Whether permission signs on falling blocks should be protected</p>
|
||||
*/
|
||||
public boolean extensiveSignProtectionEnabled() {
|
||||
return enableExtensiveSignProtection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether permission sign explosion and piston protection is enabled
|
||||
*
|
||||
* @return <p>Whether permission sign explosion and piston protection is enabled</p>
|
||||
*/
|
||||
public boolean indirectProtectionEnabled() {
|
||||
return enableIndirectSignProtection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether to remove permissions signs if their physical signs are missing
|
||||
*
|
||||
* @return <p>Whether tor remove permission signs if their signs are missing</p>
|
||||
*/
|
||||
public boolean removePermissionSignIfMissing() {
|
||||
return removePermissionSignIfMissing;
|
||||
}
|
||||
|
||||
}
|
@ -1,9 +1,12 @@
|
||||
package net.knarcraft.permissionsigns.formatting;
|
||||
package net.knarcraft.permissionsigns.config;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.TranslatableMessage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* An enum representing all translatable messages
|
||||
*/
|
||||
public enum TranslatableMessage {
|
||||
public enum Translatable implements TranslatableMessage {
|
||||
|
||||
/**
|
||||
* The prefix to display in messages
|
||||
@ -173,6 +176,11 @@ public enum TranslatableMessage {
|
||||
/**
|
||||
* The format used for each permission displayed in a list when displaying permission sign info
|
||||
*/
|
||||
SIGN_INFO_PERMISSION_FORMAT
|
||||
SIGN_INFO_PERMISSION_FORMAT;
|
||||
|
||||
@Override
|
||||
public @NotNull TranslatableMessage[] getAllMessages() {
|
||||
return Translatable.values();
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
package net.knarcraft.permissionsigns.container;
|
||||
|
||||
import net.knarcraft.permissionsigns.formatting.TranslatableMessage;
|
||||
import net.knarcraft.permissionsigns.formatting.Translator;
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.knarlib.formatting.Translator;
|
||||
import net.knarcraft.permissionsigns.PermissionSigns;
|
||||
import net.knarcraft.permissionsigns.config.Translatable;
|
||||
import net.knarcraft.permissionsigns.manager.EconomyManager;
|
||||
import org.bukkit.Location;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -13,8 +15,6 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static net.knarcraft.permissionsigns.formatting.StringFormatter.replacePlaceholder;
|
||||
|
||||
/**
|
||||
* This class represents a placed and active permission sign
|
||||
*/
|
||||
@ -27,7 +27,7 @@ public class PermissionSign {
|
||||
private final int duration;
|
||||
private final double cost;
|
||||
|
||||
private static Map<Double, TranslatableMessage[]> timeUnits;
|
||||
private static Map<Double, Translatable[]> timeUnits;
|
||||
private static List<Double> sortedUnits;
|
||||
|
||||
/**
|
||||
@ -147,10 +147,11 @@ public class PermissionSign {
|
||||
* @return <p>The lines used to draw this permission sign</p>
|
||||
*/
|
||||
public @NotNull String[] getSignLines() {
|
||||
Translator translator = PermissionSigns.getInstance().getTranslator();
|
||||
String[] lines = new String[4];
|
||||
lines[0] = Translator.getTranslatedMessage(TranslatableMessage.SIGN_PREFIX);
|
||||
lines[1] = replacePlaceholder(Translator.getTranslatedMessage(
|
||||
TranslatableMessage.SIGN_NAME_FORMAT), "{name}", getName());
|
||||
lines[0] = translator.getTranslatedMessage(Translatable.SIGN_PREFIX);
|
||||
lines[1] = StringFormatter.replacePlaceholder(translator.getTranslatedMessage(
|
||||
Translatable.SIGN_NAME_FORMAT), "{name}", getName());
|
||||
lines[2] = getDurationString();
|
||||
lines[3] = getCostString();
|
||||
return lines;
|
||||
@ -175,7 +176,7 @@ public class PermissionSign {
|
||||
*/
|
||||
public @NotNull String getDurationString() {
|
||||
if (duration == 0) {
|
||||
return Translator.getTranslatedMessage(TranslatableMessage.SIGN_PERMANENT);
|
||||
return PermissionSigns.getInstance().getTranslator().getTranslatedMessage(Translatable.SIGN_PERMANENT);
|
||||
} else {
|
||||
if (sortedUnits == null) {
|
||||
initializeUnits();
|
||||
@ -187,7 +188,7 @@ public class PermissionSign {
|
||||
(units * 10) % 10 == 0);
|
||||
}
|
||||
}
|
||||
return formatDurationString(duration, TranslatableMessage.UNIT_SECONDS, false);
|
||||
return formatDurationString(duration, Translatable.UNIT_SECONDS, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,7 +199,7 @@ public class PermissionSign {
|
||||
*/
|
||||
public @NotNull String getCostString() {
|
||||
if (cost == 0) {
|
||||
return Translator.getTranslatedMessage(TranslatableMessage.SIGN_COST_FREE);
|
||||
return PermissionSigns.getInstance().getTranslator().getTranslatedMessage(Translatable.SIGN_COST_FREE);
|
||||
} else {
|
||||
return EconomyManager.format(cost);
|
||||
}
|
||||
@ -218,17 +219,18 @@ public class PermissionSign {
|
||||
* Formats a duration string
|
||||
*
|
||||
* @param duration <p>The duration to display</p>
|
||||
* @param translatableMessage <p>The time unit to display</p>
|
||||
* @param translatable <p>The time unit to display</p>
|
||||
* @param castToInt <p>Whether to cast the duration to an int</p>
|
||||
* @return <p>The formatted duration string</p>
|
||||
*/
|
||||
private @NotNull String formatDurationString(double duration, @NotNull TranslatableMessage translatableMessage,
|
||||
private @NotNull String formatDurationString(double duration, @NotNull Translatable translatable,
|
||||
boolean castToInt) {
|
||||
String durationFormat = Translator.getTranslatedMessage(TranslatableMessage.SIGN_DURATION_FORMAT);
|
||||
durationFormat = replacePlaceholder(durationFormat, "{unit}",
|
||||
Translator.getTranslatedMessage(translatableMessage));
|
||||
return replacePlaceholder(durationFormat, "{duration}", castToInt ? String.valueOf((int) duration) :
|
||||
String.valueOf(duration));
|
||||
Translator translator = PermissionSigns.getInstance().getTranslator();
|
||||
String durationFormat = translator.getTranslatedMessage(Translatable.SIGN_DURATION_FORMAT);
|
||||
durationFormat = StringFormatter.replacePlaceholder(durationFormat, "{unit}",
|
||||
translator.getTranslatedMessage(translatable));
|
||||
return StringFormatter.replacePlaceholder(durationFormat, "{duration}",
|
||||
castToInt ? String.valueOf((int) duration) : String.valueOf(duration));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -240,10 +242,10 @@ public class PermissionSign {
|
||||
double day = hour * 24;
|
||||
|
||||
timeUnits = new HashMap<>();
|
||||
timeUnits.put(day, new TranslatableMessage[]{TranslatableMessage.UNIT_DAY, TranslatableMessage.UNIT_DAYS});
|
||||
timeUnits.put(hour, new TranslatableMessage[]{TranslatableMessage.UNIT_HOUR, TranslatableMessage.UNIT_HOURS});
|
||||
timeUnits.put(minute, new TranslatableMessage[]{TranslatableMessage.UNIT_MINUTE, TranslatableMessage.UNIT_MINUTES});
|
||||
timeUnits.put(1D, new TranslatableMessage[]{TranslatableMessage.UNIT_SECOND, TranslatableMessage.UNIT_SECONDS});
|
||||
timeUnits.put(day, new Translatable[]{Translatable.UNIT_DAY, Translatable.UNIT_DAYS});
|
||||
timeUnits.put(hour, new Translatable[]{Translatable.UNIT_HOUR, Translatable.UNIT_HOURS});
|
||||
timeUnits.put(minute, new Translatable[]{Translatable.UNIT_MINUTE, Translatable.UNIT_MINUTES});
|
||||
timeUnits.put(1D, new Translatable[]{Translatable.UNIT_SECOND, Translatable.UNIT_SECONDS});
|
||||
|
||||
sortedUnits = new ArrayList<>(timeUnits.keySet());
|
||||
Collections.sort(sortedUnits);
|
||||
|
@ -1,110 +0,0 @@
|
||||
package net.knarcraft.permissionsigns.formatting;
|
||||
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* A formatter for formatting displayed messages
|
||||
*/
|
||||
public class StringFormatter {
|
||||
|
||||
/**
|
||||
* Replaces a placeholder in a string
|
||||
*
|
||||
* @param input <p>The input string to replace in</p>
|
||||
* @param placeholder <p>The placeholder to replace</p>
|
||||
* @param replacement <p>The replacement value</p>
|
||||
* @return <p>The input string with the placeholder replaced</p>
|
||||
*/
|
||||
public static @NotNull String replacePlaceholder(@NotNull String input, @NotNull String placeholder,
|
||||
@NotNull String replacement) {
|
||||
return input.replace(placeholder, replacement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces placeholders in a string
|
||||
*
|
||||
* @param input <p>The input string to replace in</p>
|
||||
* @param placeholders <p>The placeholders to replace</p>
|
||||
* @param replacements <p>The replacement values</p>
|
||||
* @return <p>The input string with placeholders replaced</p>
|
||||
*/
|
||||
public static @NotNull String replacePlaceholders(@NotNull String input, @NotNull String[] placeholders,
|
||||
@NotNull String[] replacements) {
|
||||
for (int i = 0; i < Math.min(placeholders.length, replacements.length); i++) {
|
||||
input = replacePlaceholder(input, placeholders[i], replacements[i]);
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a translated and formatted info message
|
||||
*
|
||||
* @param translatableMessage <p>The translatable message to translate and format</p>
|
||||
* @return <p>The translated and formatted message</p>
|
||||
*/
|
||||
public static @NotNull String getTranslatedInfoMessage(@NotNull TranslatableMessage translatableMessage) {
|
||||
return formatInfoMessage(Translator.getTranslatedMessage(translatableMessage));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a translated and formatted error message
|
||||
*
|
||||
* @param translatableMessage <p>The translatable message to translate and format</p>
|
||||
* @return <p>The translated and formatted message</p>
|
||||
*/
|
||||
public static @NotNull String getTranslatedErrorMessage(@NotNull TranslatableMessage translatableMessage) {
|
||||
return formatErrorMessage(Translator.getTranslatedMessage(translatableMessage));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @NotNull String formatInfoMessage(@NotNull String message) {
|
||||
return ChatColor.DARK_GREEN + 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 @NotNull String formatErrorMessage(@NotNull String message) {
|
||||
return ChatColor.DARK_RED + 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 @NotNull String formatMessage(@NotNull String message) {
|
||||
return Translator.getTranslatedMessage(TranslatableMessage.PREFIX) + " " +
|
||||
ChatColor.RESET + message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates all found color codes to formatting in a string
|
||||
*
|
||||
* @param message <p>The string to search for color codes</p>
|
||||
* @return <p>The message with color codes translated</p>
|
||||
*/
|
||||
public static @NotNull String translateAllColorCodes(@NotNull String message) {
|
||||
message = ChatColor.translateAlternateColorCodes('&', message);
|
||||
Pattern pattern = Pattern.compile("(#[a-fA-F0-9]{6})");
|
||||
Matcher matcher = pattern.matcher(message);
|
||||
while (matcher.find()) {
|
||||
message = message.replace(matcher.group(), "" + ChatColor.of(matcher.group()));
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
@ -1,122 +0,0 @@
|
||||
package net.knarcraft.permissionsigns.formatting;
|
||||
|
||||
import net.knarcraft.permissionsigns.PermissionSigns;
|
||||
import net.knarcraft.permissionsigns.utility.FileHelper;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* A tool to get strings translated to the correct language
|
||||
*/
|
||||
public final class Translator {
|
||||
|
||||
private static Map<TranslatableMessage, String> translatedMessages;
|
||||
private static Map<TranslatableMessage, String> backupTranslatedMessages;
|
||||
|
||||
private Translator() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the languages used by this translator
|
||||
*/
|
||||
public static void loadLanguages(@NotNull String selectedLanguage) {
|
||||
backupTranslatedMessages = loadTranslatedMessages("en");
|
||||
translatedMessages = loadCustomTranslatedMessages(selectedLanguage);
|
||||
if (translatedMessages == null) {
|
||||
translatedMessages = loadTranslatedMessages(selectedLanguage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @NotNull String getTranslatedMessage(@NotNull TranslatableMessage translatableMessage) {
|
||||
if (translatedMessages == null) {
|
||||
return "Translated strings not loaded";
|
||||
}
|
||||
String translatedMessage;
|
||||
if (translatedMessages.containsKey(translatableMessage)) {
|
||||
translatedMessage = translatedMessages.get(translatableMessage);
|
||||
} else if (backupTranslatedMessages.containsKey(translatableMessage)) {
|
||||
translatedMessage = backupTranslatedMessages.get(translatableMessage);
|
||||
} else {
|
||||
translatedMessage = translatableMessage.toString();
|
||||
}
|
||||
return StringFormatter.translateAllColorCodes(translatedMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @Nullable Map<TranslatableMessage, String> loadTranslatedMessages(@NotNull String language) {
|
||||
try {
|
||||
BufferedReader reader = FileHelper.getBufferedReaderForInternalFile("/strings.yml");
|
||||
return loadTranslatableMessages(language, reader);
|
||||
} catch (FileNotFoundException e) {
|
||||
PermissionSigns.getInstance().getLogger().log(Level.SEVERE, "Unable to load translated messages");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to load translated messages from a custom strings.yml file
|
||||
*
|
||||
* @param language <p>The selected language</p>
|
||||
* @return <p>The loaded translated strings, or null if no custom language file exists</p>
|
||||
*/
|
||||
public static @Nullable Map<TranslatableMessage, String> loadCustomTranslatedMessages(@NotNull String language) {
|
||||
File strings = new File(PermissionSigns.getInstance().getDataFolder(), "strings.yml");
|
||||
if (!strings.exists()) {
|
||||
PermissionSigns.getInstance().getLogger().log(Level.FINEST, "Strings file not found");
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
PermissionSigns.getInstance().getLogger().log(Level.WARNING, "Loading custom strings...");
|
||||
return loadTranslatableMessages(language, new BufferedReader(new InputStreamReader(
|
||||
new FileInputStream(strings), StandardCharsets.UTF_8)));
|
||||
} catch (FileNotFoundException e) {
|
||||
PermissionSigns.getInstance().getLogger().log(Level.WARNING, "Unable to load custom messages");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads translatable messages from the given reader
|
||||
*
|
||||
* @param language <p>The selected language</p>
|
||||
* @param reader <p>The buffered reader to read from</p>
|
||||
* @return <p>The loaded translated strings</p>
|
||||
*/
|
||||
private static Map<TranslatableMessage, String> loadTranslatableMessages(String language, BufferedReader reader) {
|
||||
Map<TranslatableMessage, String> translatedMessages = new HashMap<>();
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
package net.knarcraft.permissionsigns.listener;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.permissionsigns.PermissionSigns;
|
||||
import net.knarcraft.permissionsigns.formatting.StringFormatter;
|
||||
import net.knarcraft.permissionsigns.formatting.TranslatableMessage;
|
||||
import net.knarcraft.permissionsigns.config.Translatable;
|
||||
import net.knarcraft.permissionsigns.manager.SignManager;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
@ -27,8 +27,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static net.knarcraft.permissionsigns.PermissionSigns.extensiveSignProtectionEnabled;
|
||||
|
||||
/**
|
||||
* A listener for relevant block events such as signs being broken
|
||||
*/
|
||||
@ -66,7 +64,7 @@ public class BlockListener implements Listener {
|
||||
//Protect the permission sign itself
|
||||
protectBlockIfPermissionSign(event, block, player);
|
||||
|
||||
if (extensiveSignProtectionEnabled()) {
|
||||
if (PermissionSigns.getInstance().getConfiguration().extensiveSignProtectionEnabled()) {
|
||||
protectSignsInDirection(event, block, player, BlockFace.UP);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
@ -105,7 +103,7 @@ public class BlockListener implements Listener {
|
||||
*/
|
||||
private void preventDestruction(@NotNull List<Block> blocks, @NotNull Cancellable event) {
|
||||
//Don't do anything if indirect protection is disabled
|
||||
if (!PermissionSigns.indirectProtectionEnabled()) {
|
||||
if (!PermissionSigns.getInstance().getConfiguration().indirectProtectionEnabled()) {
|
||||
return;
|
||||
}
|
||||
for (Block block : blocks) {
|
||||
@ -114,7 +112,7 @@ public class BlockListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
if (extensiveSignProtectionEnabled()) {
|
||||
if (PermissionSigns.getInstance().getConfiguration().extensiveSignProtectionEnabled()) {
|
||||
protectSignsInDirection(event, block, null, BlockFace.UP);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
@ -186,21 +184,24 @@ public class BlockListener implements Listener {
|
||||
if (!registered) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (player == null) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
StringFormatter stringFormatter = PermissionSigns.getInstance().stringFormatter();
|
||||
if (!player.hasPermission("permissionsigns.admin.create")) {
|
||||
event.setCancelled(true);
|
||||
player.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.PERMISSION_SIGN_DESTROY_DENY));
|
||||
stringFormatter.displayErrorMessage(player, Translatable.PERMISSION_SIGN_DESTROY_DENY);
|
||||
} else {
|
||||
if (!player.isSneaking() && player.getGameMode() == GameMode.CREATIVE) {
|
||||
event.setCancelled(true);
|
||||
player.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.PERMISSION_SIGN_DESTROY_SNEAK));
|
||||
stringFormatter.displayErrorMessage(player, Translatable.PERMISSION_SIGN_DESTROY_SNEAK);
|
||||
return;
|
||||
}
|
||||
SignManager.removeSign(sign.getLocation());
|
||||
player.sendMessage(StringFormatter.getTranslatedInfoMessage(TranslatableMessage.PERMISSION_SIGN_REMOVED));
|
||||
stringFormatter.displaySuccessMessage(player, Translatable.PERMISSION_SIGN_REMOVED);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,14 @@
|
||||
package net.knarcraft.permissionsigns.listener;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.knarlib.formatting.Translator;
|
||||
import net.knarcraft.permissionsigns.PermissionSigns;
|
||||
import net.knarcraft.permissionsigns.config.Translatable;
|
||||
import net.knarcraft.permissionsigns.container.PermissionSign;
|
||||
import net.knarcraft.permissionsigns.container.SignCreationRequest;
|
||||
import net.knarcraft.permissionsigns.formatting.StringFormatter;
|
||||
import net.knarcraft.permissionsigns.formatting.TranslatableMessage;
|
||||
import net.knarcraft.permissionsigns.formatting.Translator;
|
||||
import net.knarcraft.permissionsigns.manager.EconomyManager;
|
||||
import net.knarcraft.permissionsigns.manager.PermissionManager;
|
||||
import net.knarcraft.permissionsigns.manager.SignCreationManager;
|
||||
import net.knarcraft.permissionsigns.manager.SignManager;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
@ -76,7 +77,8 @@ public class SignListener implements Listener {
|
||||
return;
|
||||
}
|
||||
if (!player.hasPermission("permissionsigns.use")) {
|
||||
player.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.INTERACT_PERMISSION_MISSING));
|
||||
PermissionSigns.getInstance().stringFormatter().displayErrorMessage(player,
|
||||
Translatable.INTERACT_PERMISSION_MISSING);
|
||||
return;
|
||||
}
|
||||
//Prevent placement of any blocks, and sign clicking
|
||||
@ -90,7 +92,7 @@ public class SignListener implements Listener {
|
||||
}
|
||||
|
||||
//Check if the player has a creation request that can be fulfilled
|
||||
SignCreationRequest request = PermissionSigns.getSignCreationRequest(player.getUniqueId());
|
||||
SignCreationRequest request = SignCreationManager.getSignCreationRequest(player.getUniqueId());
|
||||
if (request != null) {
|
||||
registerPermissionSign(sign, request, player);
|
||||
}
|
||||
@ -103,14 +105,15 @@ public class SignListener implements Listener {
|
||||
* @return <p>The information to display</p>
|
||||
*/
|
||||
private String getSignInfoText(@NotNull PermissionSign sign) {
|
||||
String rawSignInfo = Translator.getTranslatedMessage(TranslatableMessage.SIGN_INFO);
|
||||
Translator translator = PermissionSigns.getInstance().getTranslator();
|
||||
String rawSignInfo = translator.getTranslatedMessage(Translatable.SIGN_INFO);
|
||||
StringBuilder permissionString = new StringBuilder();
|
||||
List<String> permissionNodes = sign.getPermissionNodes();
|
||||
if (permissionNodes.size() == 1) {
|
||||
permissionString = new StringBuilder(permissionNodes.get(0));
|
||||
} else {
|
||||
for (String permissionNode : permissionNodes) {
|
||||
String format = Translator.getTranslatedMessage(TranslatableMessage.SIGN_INFO_PERMISSION_FORMAT);
|
||||
String format = translator.getTranslatedMessage(Translatable.SIGN_INFO_PERMISSION_FORMAT);
|
||||
permissionString.append(StringFormatter.replacePlaceholder(format, "{permission}", permissionNode));
|
||||
}
|
||||
}
|
||||
@ -139,15 +142,16 @@ public class SignListener implements Listener {
|
||||
hasAllPermissions = false;
|
||||
}
|
||||
}
|
||||
StringFormatter stringFormatter = PermissionSigns.getInstance().stringFormatter();
|
||||
if (hasAllPermissions) {
|
||||
player.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.ALREADY_HAS_PERMISSIONS));
|
||||
stringFormatter.displayErrorMessage(player, Translatable.ALREADY_HAS_PERMISSIONS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (EconomyManager.canAfford(player, permissionSign.getCost())) {
|
||||
performPermissionTransaction(player, permissionSign);
|
||||
} else {
|
||||
player.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.CANNOT_AFFORD));
|
||||
stringFormatter.displayErrorMessage(player, Translatable.CANNOT_AFFORD);
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,14 +183,15 @@ public class SignListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
StringFormatter stringFormatter = PermissionSigns.getInstance().stringFormatter();
|
||||
String grantedPermissions = permissionsJoiner.toString();
|
||||
if (permissionSign.getDuration() > 0) {
|
||||
String successMessage = StringFormatter.getTranslatedInfoMessage(TranslatableMessage.PERMISSIONS_GRANTED);
|
||||
player.sendMessage(StringFormatter.replacePlaceholders(successMessage, new String[]{"{permissions}", "{time}"},
|
||||
stringFormatter.displaySuccessMessage(player, stringFormatter.replacePlaceholders(
|
||||
Translatable.PERMISSIONS_GRANTED, new String[]{"{permissions}", "{time}"},
|
||||
new String[]{grantedPermissions, permissionSign.getDurationString()}));
|
||||
} else {
|
||||
player.sendMessage(StringFormatter.replacePlaceholder(StringFormatter.getTranslatedInfoMessage(
|
||||
TranslatableMessage.PERMISSIONS_GRANTED_PERMANENTLY), "{permissions}", grantedPermissions));
|
||||
stringFormatter.displaySuccessMessage(player, stringFormatter.replacePlaceholder(
|
||||
Translatable.PERMISSIONS_GRANTED_PERMANENTLY, "{permissions}", grantedPermissions));
|
||||
}
|
||||
}
|
||||
|
||||
@ -210,7 +215,7 @@ public class SignListener implements Listener {
|
||||
PermissionSign permissionSign = request.getPermissionSign();
|
||||
permissionSign.setSignLocation(sign.getLocation());
|
||||
SignManager.addSign(permissionSign);
|
||||
PermissionSigns.cancelSignCreationRequest(player.getUniqueId());
|
||||
SignCreationManager.cancelSignCreationRequest(player.getUniqueId());
|
||||
|
||||
//Display the permission sign information on the sign
|
||||
String[] signLines = permissionSign.getSignLines();
|
||||
@ -219,7 +224,9 @@ public class SignListener implements Listener {
|
||||
}
|
||||
sign.setWaxed(true);
|
||||
sign.update();
|
||||
player.sendMessage(StringFormatter.getTranslatedInfoMessage(TranslatableMessage.PERMISSION_SIGN_CREATED));
|
||||
|
||||
PermissionSigns.getInstance().stringFormatter().displaySuccessMessage(player,
|
||||
Translatable.PERMISSION_SIGN_CREATED);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ public final class PermissionManager {
|
||||
if (permissionNode.contains(":")) {
|
||||
grantWorldPermission(player, permissionNode, false);
|
||||
} else {
|
||||
boolean perWorldPermissions = PermissionSigns.usePerWorldPermissions();
|
||||
boolean perWorldPermissions = PermissionSigns.getInstance().getConfiguration().usePerWorldPermissions();
|
||||
permission.playerAdd(perWorldPermissions ? player.getWorld().getName() : null, player, permissionNode);
|
||||
}
|
||||
}
|
||||
@ -79,7 +79,7 @@ public final class PermissionManager {
|
||||
if (permissionNode.contains(":")) {
|
||||
grantWorldPermission(player, permissionNode, true);
|
||||
} else {
|
||||
boolean perWorldPermissions = PermissionSigns.usePerWorldPermissions();
|
||||
boolean perWorldPermissions = PermissionSigns.getInstance().getConfiguration().usePerWorldPermissions();
|
||||
permission.playerAddTransient(perWorldPermissions ? worldName : null, player, permissionNode);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,89 @@
|
||||
package net.knarcraft.permissionsigns.manager;
|
||||
|
||||
import net.knarcraft.permissionsigns.PermissionSigns;
|
||||
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.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Queue;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* A manager for keeping track of sign creation requests
|
||||
*/
|
||||
public final class SignCreationManager {
|
||||
|
||||
private static final Queue<SignCreationRequest> signCreationRequests = new PriorityQueue<>();
|
||||
private static BukkitTask timeoutTask = null;
|
||||
|
||||
private SignCreationManager() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the task for timing out permission sign creation requests
|
||||
*/
|
||||
public static void runTimeoutTimer() {
|
||||
timeoutTask = Bukkit.getScheduler().runTaskTimer(PermissionSigns.getInstance(),
|
||||
new SignCreationRequestTimeoutThread(signCreationRequests), 0L, 1000L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the task for timing out permission sign creation requests
|
||||
*/
|
||||
public static void stopTimeoutTimer() {
|
||||
if (timeoutTask != null) {
|
||||
timeoutTask.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(@NotNull Player player, @NotNull 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>
|
||||
*/
|
||||
public static @Nullable SignCreationRequest getSignCreationRequest(@NotNull UUID uuid) {
|
||||
Stream<SignCreationRequest> matchingRequests = signCreationRequests.stream().filter(
|
||||
(item) -> item.getPlayer().getUniqueId().equals(uuid));
|
||||
List<SignCreationRequest> requestList = matchingRequests.toList();
|
||||
if (!requestList.isEmpty()) {
|
||||
return requestList.get(0);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
if (requestList.size() > 0) {
|
||||
signCreationRequests.remove(requestList.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -125,7 +125,7 @@ public final class SignManager {
|
||||
Block signBlock = key.getBlock();
|
||||
BlockState state = signBlock.getState();
|
||||
if (!(state instanceof Sign sign)) {
|
||||
if (PermissionSigns.removePermissionSignIfMissing()) {
|
||||
if (PermissionSigns.getInstance().getConfiguration().removePermissionSignIfMissing()) {
|
||||
invalidPermissionSigns.add(permissionSign.getSignLocation());
|
||||
}
|
||||
continue;
|
||||
|
@ -1,45 +0,0 @@
|
||||
package net.knarcraft.permissionsigns.utility;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* A helper class for dealing with files
|
||||
*/
|
||||
public final class FileHelper {
|
||||
|
||||
private FileHelper() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a buffered reader for
|
||||
*
|
||||
* @return <p>A buffered read for reading the file</p>
|
||||
* @throws FileNotFoundException <p>If unable to get an input stream for the given file</p>
|
||||
*/
|
||||
public static @NotNull BufferedReader getBufferedReaderForInternalFile(@NotNull String file) throws FileNotFoundException {
|
||||
InputStream inputStream = FileHelper.class.getResourceAsStream(file);
|
||||
if (inputStream == null) {
|
||||
throw new FileNotFoundException("Unable to read the given file");
|
||||
}
|
||||
return new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a buffered reader given an input stream
|
||||
*
|
||||
* @param inputStream <p>The input stream to read</p>
|
||||
* @return <p>A buffered reader reading the input stream</p>
|
||||
*/
|
||||
public static @NotNull BufferedReader getBufferedReaderFromInputStream(@NotNull InputStream inputStream) {
|
||||
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
|
||||
return new BufferedReader(inputStreamReader);
|
||||
}
|
||||
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
package net.knarcraft.permissionsigns.utility;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* The update checker is responsible for looking for new updates
|
||||
*/
|
||||
public final class UpdateChecker {
|
||||
|
||||
private final static String updateNotice = "A new update is available: %s (You are still on %s)";
|
||||
|
||||
private UpdateChecker() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there's a new update available, and alerts the user if necessary
|
||||
*/
|
||||
public static void checkForUpdate(@NotNull Plugin plugin, @NotNull String apiResourceURL,
|
||||
@NotNull Supplier<String> getVersionMethod,
|
||||
@Nullable Consumer<String> setVersionMethod) {
|
||||
BukkitScheduler scheduler = plugin.getServer().getScheduler();
|
||||
scheduler.runTaskAsynchronously(plugin, () -> UpdateChecker.queryAPI(plugin, apiResourceURL, getVersionMethod,
|
||||
setVersionMethod));
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the spigot API to check for a newer version, and informs the user
|
||||
*/
|
||||
private static void queryAPI(@NotNull Plugin plugin, @NotNull String APIResourceURL,
|
||||
@NotNull Supplier<String> getVersionMethod,
|
||||
@Nullable Consumer<String> setVersionMethod) {
|
||||
try {
|
||||
InputStream inputStream = new URL(APIResourceURL).openStream();
|
||||
BufferedReader reader = FileHelper.getBufferedReaderFromInputStream(inputStream);
|
||||
//There should only be one line of output
|
||||
String newVersion = reader.readLine();
|
||||
reader.close();
|
||||
|
||||
String oldVersion = getVersionMethod.get();
|
||||
//If there is a newer version, notify the user
|
||||
if (isVersionHigher(oldVersion, newVersion)) {
|
||||
plugin.getLogger().log(Level.INFO, getUpdateAvailableString(newVersion, oldVersion));
|
||||
if (setVersionMethod != null) {
|
||||
setVersionMethod.accept(newVersion);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().log(Level.WARNING, "Unable to get newest version.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string to display to a user to alert about a new update
|
||||
*
|
||||
* @param newVersion <p>The new available plugin version</p>
|
||||
* @param oldVersion <p>The old (current) plugin version</p>
|
||||
* @return <p>The string to display</p>
|
||||
*/
|
||||
public static @NotNull String getUpdateAvailableString(@NotNull String newVersion, @NotNull String oldVersion) {
|
||||
return String.format(updateNotice, newVersion, oldVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides whether one version number is higher than another
|
||||
*
|
||||
* @param oldVersion <p>The old version to check</p>
|
||||
* @param newVersion <p>The new version to check</p>
|
||||
* @return <p>True if the new version is higher than the old one</p>
|
||||
*/
|
||||
public static boolean isVersionHigher(@NotNull String oldVersion, @NotNull String newVersion) {
|
||||
String[] oldVersionParts = oldVersion.split("\\.");
|
||||
String[] newVersionParts = newVersion.split("\\.");
|
||||
int versionLength = Math.max(oldVersionParts.length, newVersionParts.length);
|
||||
for (int i = 0; i < versionLength; i++) {
|
||||
int oldVersionNumber = oldVersionParts.length > i ? Integer.parseInt(oldVersionParts[i]) : 0;
|
||||
int newVersionNumber = newVersionParts.length > i ? Integer.parseInt(newVersionParts[i]) : 0;
|
||||
if (newVersionNumber != oldVersionNumber) {
|
||||
return newVersionNumber > oldVersionNumber;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user