1.2.2 Filtered tab completion and update notice

This commit is contained in:
Kristian Knarvik 2022-02-19 20:06:35 +01:00
parent ed54ae84b5
commit 0ce85af61b
12 changed files with 186 additions and 19 deletions

View File

@ -51,9 +51,9 @@ An in-game description of available commands is available through the /bwb comma
book from your personal directory
* /givepublicbook <file name or number> <playername> \[# of copies (num)] \[signed (true/false)] - Same as givebook, but
uses books from the public directory
* /loadbook <file name or number> \[# of copies] \[signed (true/false)] - Creates a book from the specified file and gives
it to the player. If no file is specified, a list of available files is returned. If true is specified, the book will
be signed, if false it will be unsigned
* /loadbook <file name or number> \[# of copies] \[signed (true/false)] - Creates a book from the specified file and
gives it to the player. If no file is specified, a list of available files is returned. If true is specified, the book
will be signed, if false it will be unsigned
* /loadpublicbook <file name or number> \[# of copies] \[signed (true/false)] - Same as loadbook, but views files in the
public directory
* /reload - Reloads BwB's configuration file

View File

@ -6,7 +6,7 @@
<groupId>net.knarcraft</groupId>
<artifactId>BooksWithoutBorders</artifactId>
<version>1.2.1</version>
<version>1.2.2</version>
<packaging>jar</packaging>
<licenses>

View File

@ -25,12 +25,14 @@ import net.knarcraft.bookswithoutborders.listener.BookEventListener;
import net.knarcraft.bookswithoutborders.listener.PlayerEventListener;
import net.knarcraft.bookswithoutborders.listener.SignEventListener;
import net.knarcraft.bookswithoutborders.utility.FileHelper;
import net.knarcraft.bookswithoutborders.utility.UpdateChecker;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.inventory.ItemFactory;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
@ -106,6 +108,10 @@ public class BooksWithoutBorders extends JavaPlugin {
config.options().copyDefaults(true);
this.saveDefaultConfig();
//Get plugin info
PluginDescriptionFile pluginDescriptionFile = this.getDescription();
String pluginVersion = pluginDescriptionFile.getVersion();
booksWithoutBorders = this;
consoleSender = this.getServer().getConsoleSender();
playerBooksList = new HashMap<>();
@ -123,6 +129,9 @@ public class BooksWithoutBorders extends JavaPlugin {
}
registerCommands();
UpdateChecker.checkForUpdate(this, "https://api.spigotmc.org/legacy/update.php?resource=96069",
() -> pluginVersion, null);
}
/**

View File

@ -90,7 +90,7 @@ public class CommandCopy implements TabExecutor {
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
int argumentCount = args.length;
if (argumentCount == 1) {
return TabCompletionHelper.getNumbers(1, 20);
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionHelper.getNumbers(1, 20), args[0]);
}
return new ArrayList<>();
}

View File

@ -3,6 +3,7 @@ package net.knarcraft.bookswithoutborders.command;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.utility.FileHelper;
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
import net.knarcraft.bookswithoutborders.utility.TabCompletionHelper;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
@ -123,7 +124,8 @@ public class CommandDelete implements TabExecutor {
protected List<String> doTabCompletion(CommandSender sender, String[] args, boolean deletePublic) {
int argumentCount = args.length;
if (argumentCount == 1) {
return BooksWithoutBorders.getAvailableBooks(sender, deletePublic);
return TabCompletionHelper.filterMatchingContains(BooksWithoutBorders.getAvailableBooks(sender, deletePublic),
args[0]);
}
return new ArrayList<>();
}

View File

@ -5,6 +5,7 @@ import net.knarcraft.bookswithoutborders.state.EncryptionStyle;
import net.knarcraft.bookswithoutborders.state.ItemSlot;
import net.knarcraft.bookswithoutborders.utility.EncryptionHelper;
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
import net.knarcraft.bookswithoutborders.utility.TabCompletionHelper;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
@ -125,12 +126,13 @@ public class CommandEncrypt implements TabExecutor {
info.add("<group>");
return info;
} else {
return encryptionStyles;
return TabCompletionHelper.filterMatchingStartsWith(encryptionStyles, args[1]);
}
} else if (argumentsCount == 3 && groupEncrypt) {
return encryptionStyles;
return TabCompletionHelper.filterMatchingStartsWith(encryptionStyles, args[2]);
}
return new ArrayList<>();
}
}

View File

@ -132,18 +132,19 @@ public class CommandGive implements TabExecutor {
if (argumentCount == 1) {
//Return list of books
return BooksWithoutBorders.getAvailableBooks(sender, listPublic);
return TabCompletionHelper.filterMatchingContains(BooksWithoutBorders.getAvailableBooks(sender, listPublic),
args[0]);
} else if (argumentCount == 2) {
//Return online players
return null;
} else if (argumentCount == 3) {
//Number of copies
return TabCompletionHelper.getBooleansAndNumbers(1, 3);
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionHelper.getBooleansAndNumbers(1, 3), args[2]);
} else if (argumentCount == 4) {
//Signed
try {
Integer.parseInt(args[2]);
return TabCompletionHelper.getBooleans();
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionHelper.getBooleans(), args[3]);
} catch (NumberFormatException e) {
return new ArrayList<>();
}

View File

@ -110,15 +110,16 @@ public class CommandLoad implements TabExecutor {
int argumentCount = args.length;
if (argumentCount == 1) {
//Return list of books
return BooksWithoutBorders.getAvailableBooks(sender, loadPublic);
return TabCompletionHelper.filterMatchingContains(BooksWithoutBorders.getAvailableBooks(sender, loadPublic),
args[0]);
} else if (argumentCount == 2) {
//Number of copies
return TabCompletionHelper.getBooleansAndNumbers(1, 3);
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionHelper.getBooleansAndNumbers(1, 3), args[1]);
} else if (argumentCount == 3) {
//Signed
try {
Integer.parseInt(args[1]);
return TabCompletionHelper.getBooleans();
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionHelper.getBooleans(), args[2]);
} catch (NumberFormatException e) {
return new ArrayList<>();
}

View File

@ -22,6 +22,7 @@ import java.util.List;
public class CommandSetBookPrice implements TabExecutor {
private final BooksWithoutBorders booksWithoutBorders = BooksWithoutBorders.getInstance();
private List<String> paymentTypes;
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
@ -135,16 +136,26 @@ public class CommandSetBookPrice implements TabExecutor {
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
if (paymentTypes == null) {
initializeTabCompleteLists();
}
int argumentCount = args.length;
if (argumentCount == 1) {
List<String> paymentTypes = new ArrayList<>();
paymentTypes.add("item");
paymentTypes.add("eco");
return paymentTypes;
return TabCompletionHelper.filterMatchingStartsWith(paymentTypes, args[0]);
} else if (argumentCount == 2) {
return TabCompletionHelper.getNumbers(1, 3);
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionHelper.getNumbers(1, 3), args[1]);
}
return new ArrayList<>();
}
/**
* Initializes the lists of tab complete values
*/
private void initializeTabCompleteLists() {
paymentTypes = new ArrayList<>();
paymentTypes.add("item");
paymentTypes.add("eco");
}
}

View File

@ -4,7 +4,11 @@ import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@ -173,4 +177,15 @@ public final class FileHelper {
return foundDuplicates;
}
/**
* 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 BufferedReader getBufferedReaderFromInputStream(InputStream inputStream) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
return new BufferedReader(inputStreamReader);
}
}

View File

@ -11,6 +11,40 @@ public final class TabCompletionHelper {
private TabCompletionHelper() {
}
/**
* 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 a list of booleans
*

View File

@ -0,0 +1,92 @@
package net.knarcraft.bookswithoutborders.utility;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitScheduler;
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(Plugin plugin, String apiResourceURL, Supplier<String> getVersionMethod,
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(Plugin plugin, String APIResourceURL, Supplier<String> getVersionMethod,
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 String getUpdateAvailableString(String newVersion, 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(String oldVersion, 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;
}
}