Initial Development
- /cab list complete.
This commit is contained in:
1 parent
54f22aebbb
commit
9611dacc96
15 files changed
+356
-4
No files matched your search
@@ -2,6 +2,7 @@
|
||||
package com.rsscripting.rstaxi;
|
||||
|
||||
import com.rsscripting.rstaxi.commands.CabCommand;
|
||||
import com.rsscripting.rstaxi.commands.CabTabCompleter;
|
||||
import com.rsscripting.rstaxi.language.LanguageManager;
|
||||
import com.rsscripting.rstaxi.database.DatabaseManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
@@ -42,6 +43,7 @@ public final class RSTaxi extends JavaPlugin {
|
||||
}
|
||||
|
||||
getCommand("cab").setExecutor(new CabCommand(this));
|
||||
getCommand("cab").setTabCompleter(new CabTabCompleter(this));
|
||||
|
||||
getLogger().info("RS-Taxi has been enabled!");
|
||||
}
|
||||
@@ -62,8 +64,6 @@ public final class RSTaxi extends JavaPlugin {
|
||||
return languageManager;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public DatabaseManager getDatabaseManager() {
|
||||
return databaseManager;
|
||||
}
|
||||
|
||||
@@ -16,11 +16,14 @@ public final class CabCommand implements CommandExecutor {
|
||||
private final RSTaxi plugin;
|
||||
private final PlatformValidator platformValidator;
|
||||
private final StopManager stopManager;
|
||||
private final CabSearchCommand searchCommand;
|
||||
|
||||
|
||||
public CabCommand(RSTaxi plugin) {
|
||||
this.plugin = plugin;
|
||||
this.platformValidator = new PlatformValidator(plugin);
|
||||
this.stopManager = new StopManager(plugin);
|
||||
this.searchCommand = new CabSearchCommand(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -50,6 +53,9 @@ public final class CabCommand implements CommandExecutor {
|
||||
case "list" -> {
|
||||
return handleList(sender);
|
||||
}
|
||||
case "search" -> {
|
||||
return searchCommand.execute(sender, args);
|
||||
}
|
||||
default -> {
|
||||
return handleTravel(sender, args);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
|
||||
package com.rsscripting.rstaxi.commands;
|
||||
|
||||
import com.rsscripting.rstaxi.RSTaxi;
|
||||
import com.rsscripting.rstaxi.stops.StopManager;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
import java.util.Locale;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public final class CabSearchCommand {
|
||||
|
||||
private final RSTaxi plugin;
|
||||
private final StopManager stopManager;
|
||||
|
||||
public CabSearchCommand(RSTaxi plugin) {
|
||||
this.plugin = plugin;
|
||||
this.stopManager = new StopManager(plugin);
|
||||
}
|
||||
|
||||
public boolean execute(CommandSender sender, String[] args) {
|
||||
if (!sender.hasPermission("rs-cab.use")) {
|
||||
sender.sendMessage(
|
||||
plugin.getLanguageManager()
|
||||
.getMessage("general.no-permission")
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length < 2) {
|
||||
sendUsage(sender);
|
||||
return true;
|
||||
}
|
||||
|
||||
String query = String.join(" ", args)
|
||||
.substring(args[0].length() + 1)
|
||||
.trim();
|
||||
|
||||
if (query.isBlank()) {
|
||||
sendUsage(sender);
|
||||
return true;
|
||||
}
|
||||
|
||||
String lowerQuery = query.toLowerCase(Locale.ROOT);
|
||||
boolean iconSearch = lowerQuery.startsWith("icon:");
|
||||
boolean textSearch = lowerQuery.startsWith("text:");
|
||||
|
||||
if (!iconSearch && !textSearch) {
|
||||
sendUsage(sender);
|
||||
return true;
|
||||
}
|
||||
|
||||
String value = query.substring(query.indexOf(':') + 1).trim();
|
||||
|
||||
if (value.isBlank()) {
|
||||
sendUsage(sender);
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
var stops = iconSearch
|
||||
? stopManager.searchByIcon(value)
|
||||
: stopManager.searchByName(value);
|
||||
|
||||
if (stops.isEmpty()) {
|
||||
sender.sendMessage(
|
||||
plugin.getLanguageManager()
|
||||
.getMessage("search.no-results")
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
sender.sendMessage(
|
||||
plugin.getLanguageManager()
|
||||
.getMessage("search.header")
|
||||
);
|
||||
|
||||
for (StopManager.StopEntry stop : stops) {
|
||||
sender.sendMessage(
|
||||
plugin.getLanguageManager().getMessage(
|
||||
"list.entry",
|
||||
Map.of(
|
||||
"icon", stop.icon(),
|
||||
"stop", stop.name()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().log(
|
||||
java.util.logging.Level.SEVERE,
|
||||
"Failed to search taxi destinations.",
|
||||
e
|
||||
);
|
||||
|
||||
sender.sendMessage(
|
||||
plugin.getLanguageManager()
|
||||
.getMessage("search.error")
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void sendUsage(CommandSender sender) {
|
||||
sender.sendMessage(
|
||||
plugin.getLanguageManager()
|
||||
.getMessage("general.invalid-usage")
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
|
||||
package com.rsscripting.rstaxi.commands;
|
||||
|
||||
import com.rsscripting.rstaxi.RSTaxi;
|
||||
import com.rsscripting.rstaxi.stops.StopManager;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Level;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
|
||||
public final class CabTabCompleter implements TabCompleter {
|
||||
|
||||
private final RSTaxi plugin;
|
||||
private final StopManager stopManager;
|
||||
|
||||
public CabTabCompleter(RSTaxi plugin) {
|
||||
this.plugin = plugin;
|
||||
this.stopManager = new StopManager(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(
|
||||
CommandSender sender,
|
||||
Command command,
|
||||
String alias,
|
||||
String[] args
|
||||
) {
|
||||
List<String> suggestions = new ArrayList<>();
|
||||
|
||||
if (args.length == 1) {
|
||||
String input = args[0].toLowerCase(Locale.ROOT);
|
||||
|
||||
// Management commands first, in the requested order.
|
||||
if (sender.hasPermission("rs-cab.add")
|
||||
&& "add".startsWith(input)) {
|
||||
suggestions.add("add");
|
||||
}
|
||||
|
||||
if (sender.hasPermission("rs-cab.use")
|
||||
&& "search".startsWith(input)) {
|
||||
suggestions.add("search");
|
||||
}
|
||||
|
||||
if (sender.hasPermission("rs-cab.delete")
|
||||
&& "remove".startsWith(input)) {
|
||||
suggestions.add("remove");
|
||||
}
|
||||
|
||||
// Destinations follow the management commands.
|
||||
if (sender.hasPermission("rs-cab.use")) {
|
||||
try {
|
||||
List<StopManager.StopEntry> stops =
|
||||
stopManager.getAllStops();
|
||||
|
||||
stops.sort(Comparator.comparing(
|
||||
StopManager.StopEntry::name,
|
||||
String.CASE_INSENSITIVE_ORDER
|
||||
));
|
||||
|
||||
for (StopManager.StopEntry stop : stops) {
|
||||
String name = stop.name();
|
||||
|
||||
if (name.toLowerCase(Locale.ROOT)
|
||||
.startsWith(input)
|
||||
&& !isReservedCommand(name)) {
|
||||
suggestions.add(name);
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().log(
|
||||
Level.WARNING,
|
||||
"Failed to load taxi destinations for tab completion.",
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
// Preserve search prefix and icon suggestions.
|
||||
if (args[0].equalsIgnoreCase("search")
|
||||
&& sender.hasPermission("rs-cab.use")) {
|
||||
|
||||
String input = String.join(" ", args)
|
||||
.substring(args[0].length() + 1);
|
||||
|
||||
String lowerInput = input.toLowerCase(Locale.ROOT);
|
||||
|
||||
if (args.length == 2
|
||||
&& !lowerInput.startsWith("icon:")) {
|
||||
if ("text:".startsWith(lowerInput)) {
|
||||
suggestions.add("text:");
|
||||
}
|
||||
|
||||
if ("icon:".startsWith(lowerInput)) {
|
||||
suggestions.add("icon:");
|
||||
}
|
||||
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
if (lowerInput.startsWith("icon:")) {
|
||||
String iconPrefix = input.substring("icon:".length())
|
||||
.toLowerCase(Locale.ROOT);
|
||||
|
||||
try {
|
||||
for (String icon : stopManager.getUsedIcons()) {
|
||||
if (icon.toLowerCase(Locale.ROOT)
|
||||
.startsWith(iconPrefix)) {
|
||||
suggestions.add("icon:" + icon);
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().log(
|
||||
Level.WARNING,
|
||||
"Failed to load taxi icons for tab completion.",
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
private boolean isReservedCommand(String name) {
|
||||
return name.equalsIgnoreCase("add")
|
||||
|| name.equalsIgnoreCase("remove")
|
||||
|| name.equalsIgnoreCase("search")
|
||||
|| name.equalsIgnoreCase("list");
|
||||
}
|
||||
}
|
||||
@@ -90,6 +90,94 @@ public final class StopManager {
|
||||
return stops;
|
||||
}
|
||||
|
||||
|
||||
public List<StopEntry> searchByName(String name)
|
||||
throws SQLException {
|
||||
|
||||
String sql = """
|
||||
SELECT name, icon
|
||||
FROM stops
|
||||
WHERE name LIKE ? ESCAPE '\\'
|
||||
ORDER BY name COLLATE NOCASE
|
||||
""";
|
||||
|
||||
List<StopEntry> stops = new ArrayList<>();
|
||||
|
||||
String escapedName = name
|
||||
.replace("\\", "\\\\")
|
||||
.replace("%", "\\%")
|
||||
.replace("_", "\\_");
|
||||
|
||||
try (PreparedStatement statement = connection()
|
||||
.prepareStatement(sql)) {
|
||||
|
||||
statement.setString(1, "%" + escapedName + "%");
|
||||
|
||||
try (ResultSet results = statement.executeQuery()) {
|
||||
while (results.next()) {
|
||||
stops.add(new StopEntry(
|
||||
results.getString("name"),
|
||||
results.getString("icon")
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return stops;
|
||||
}
|
||||
|
||||
public List<StopEntry> searchByIcon(String icon)
|
||||
throws SQLException {
|
||||
|
||||
String sql = """
|
||||
SELECT name, icon
|
||||
FROM stops
|
||||
WHERE icon = ?
|
||||
ORDER BY name COLLATE NOCASE
|
||||
""";
|
||||
|
||||
List<StopEntry> stops = new ArrayList<>();
|
||||
|
||||
try (PreparedStatement statement = connection()
|
||||
.prepareStatement(sql)) {
|
||||
|
||||
statement.setString(1, icon);
|
||||
|
||||
try (ResultSet results = statement.executeQuery()) {
|
||||
while (results.next()) {
|
||||
stops.add(new StopEntry(
|
||||
results.getString("name"),
|
||||
results.getString("icon")
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return stops;
|
||||
}
|
||||
|
||||
|
||||
public List<String> getUsedIcons() throws SQLException {
|
||||
String sql = """
|
||||
SELECT DISTINCT icon
|
||||
FROM stops
|
||||
ORDER BY icon COLLATE NOCASE
|
||||
""";
|
||||
|
||||
List<String> icons = new ArrayList<>();
|
||||
|
||||
try (PreparedStatement statement = connection()
|
||||
.prepareStatement(sql);
|
||||
ResultSet results = statement.executeQuery()) {
|
||||
|
||||
while (results.next()) {
|
||||
icons.add(results.getString("icon"));
|
||||
}
|
||||
}
|
||||
|
||||
return icons;
|
||||
}
|
||||
|
||||
private Connection connection() {
|
||||
return plugin.getDatabaseManager().getConnection();
|
||||
}
|
||||
|
||||
@@ -38,3 +38,7 @@ list:
|
||||
platform:
|
||||
invalid: "&cYou must stand on a valid taxi platform to create a destination."
|
||||
|
||||
search:
|
||||
header: "&6Search Results:"
|
||||
no-results: "&eNo taxi stops matched your search."
|
||||
error: "&cUnable to search taxi destinations. Check the server logs."
|
||||
@@ -9,7 +9,6 @@ author: RSScripting
|
||||
commands:
|
||||
cab:
|
||||
description: Travel between registered taxi stops.
|
||||
usage: /cab <stop|add|update|edit|remove|list>
|
||||
|
||||
permissions:
|
||||
rs-cab.use:
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -38,3 +38,7 @@ list:
|
||||
platform:
|
||||
invalid: "&cYou must stand on a valid taxi platform to create a destination."
|
||||
|
||||
search:
|
||||
header: "&6Search Results:"
|
||||
no-results: "&eNo taxi stops matched your search."
|
||||
error: "&cUnable to search taxi destinations. Check the server logs."
|
||||
@@ -9,7 +9,6 @@ author: RSScripting
|
||||
commands:
|
||||
cab:
|
||||
description: Travel between registered taxi stops.
|
||||
usage: /cab <stop|add|update|edit|remove|list>
|
||||
|
||||
permissions:
|
||||
rs-cab.use:
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
com\rsscripting\rstaxi\stops\StopManager.class
|
||||
com\rsscripting\rstaxi\platform\PlatformValidator.class
|
||||
com\rsscripting\rstaxi\RSTaxi.class
|
||||
com\rsscripting\rstaxi\commands\CabTabCompleter.class
|
||||
com\rsscripting\rstaxi\stops\StopManager$StopEntry.class
|
||||
com\rsscripting\rstaxi\commands\CabCommand.class
|
||||
com\rsscripting\rstaxi\database\DatabaseManager.class
|
||||
com\rsscripting\rstaxi\commands\CabSearchCommand.class
|
||||
com\rsscripting\rstaxi\language\LanguageManager.class
|
||||
@@ -1,4 +1,6 @@
|
||||
C:\Users\russe\IdeaProjects\RS-Taxi\src\main\java\com\rsscripting\rstaxi\commands\CabCommand.java
|
||||
C:\Users\russe\IdeaProjects\RS-Taxi\src\main\java\com\rsscripting\rstaxi\commands\CabSearchCommand.java
|
||||
C:\Users\russe\IdeaProjects\RS-Taxi\src\main\java\com\rsscripting\rstaxi\commands\CabTabCompleter.java
|
||||
C:\Users\russe\IdeaProjects\RS-Taxi\src\main\java\com\rsscripting\rstaxi\database\DatabaseManager.java
|
||||
C:\Users\russe\IdeaProjects\RS-Taxi\src\main\java\com\rsscripting\rstaxi\language\LanguageManager.java
|
||||
C:\Users\russe\IdeaProjects\RS-Taxi\src\main\java\com\rsscripting\rstaxi\platform\PlatformValidator.java
|
||||
|
||||
Reference in new issue
Block a user