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;
|
package com.rsscripting.rstaxi;
|
||||||
|
|
||||||
import com.rsscripting.rstaxi.commands.CabCommand;
|
import com.rsscripting.rstaxi.commands.CabCommand;
|
||||||
|
import com.rsscripting.rstaxi.commands.CabTabCompleter;
|
||||||
import com.rsscripting.rstaxi.language.LanguageManager;
|
import com.rsscripting.rstaxi.language.LanguageManager;
|
||||||
import com.rsscripting.rstaxi.database.DatabaseManager;
|
import com.rsscripting.rstaxi.database.DatabaseManager;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
@@ -42,6 +43,7 @@ public final class RSTaxi extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getCommand("cab").setExecutor(new CabCommand(this));
|
getCommand("cab").setExecutor(new CabCommand(this));
|
||||||
|
getCommand("cab").setTabCompleter(new CabTabCompleter(this));
|
||||||
|
|
||||||
getLogger().info("RS-Taxi has been enabled!");
|
getLogger().info("RS-Taxi has been enabled!");
|
||||||
}
|
}
|
||||||
@@ -62,8 +64,6 @@ public final class RSTaxi extends JavaPlugin {
|
|||||||
return languageManager;
|
return languageManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public DatabaseManager getDatabaseManager() {
|
public DatabaseManager getDatabaseManager() {
|
||||||
return databaseManager;
|
return databaseManager;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,11 +16,14 @@ public final class CabCommand implements CommandExecutor {
|
|||||||
private final RSTaxi plugin;
|
private final RSTaxi plugin;
|
||||||
private final PlatformValidator platformValidator;
|
private final PlatformValidator platformValidator;
|
||||||
private final StopManager stopManager;
|
private final StopManager stopManager;
|
||||||
|
private final CabSearchCommand searchCommand;
|
||||||
|
|
||||||
|
|
||||||
public CabCommand(RSTaxi plugin) {
|
public CabCommand(RSTaxi plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.platformValidator = new PlatformValidator(plugin);
|
this.platformValidator = new PlatformValidator(plugin);
|
||||||
this.stopManager = new StopManager(plugin);
|
this.stopManager = new StopManager(plugin);
|
||||||
|
this.searchCommand = new CabSearchCommand(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -50,6 +53,9 @@ public final class CabCommand implements CommandExecutor {
|
|||||||
case "list" -> {
|
case "list" -> {
|
||||||
return handleList(sender);
|
return handleList(sender);
|
||||||
}
|
}
|
||||||
|
case "search" -> {
|
||||||
|
return searchCommand.execute(sender, args);
|
||||||
|
}
|
||||||
default -> {
|
default -> {
|
||||||
return handleTravel(sender, args);
|
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;
|
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() {
|
private Connection connection() {
|
||||||
return plugin.getDatabaseManager().getConnection();
|
return plugin.getDatabaseManager().getConnection();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,3 +38,7 @@ list:
|
|||||||
platform:
|
platform:
|
||||||
invalid: "&cYou must stand on a valid taxi platform to create a destination."
|
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:
|
commands:
|
||||||
cab:
|
cab:
|
||||||
description: Travel between registered taxi stops.
|
description: Travel between registered taxi stops.
|
||||||
usage: /cab <stop|add|update|edit|remove|list>
|
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
rs-cab.use:
|
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:
|
platform:
|
||||||
invalid: "&cYou must stand on a valid taxi platform to create a destination."
|
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:
|
commands:
|
||||||
cab:
|
cab:
|
||||||
description: Travel between registered taxi stops.
|
description: Travel between registered taxi stops.
|
||||||
usage: /cab <stop|add|update|edit|remove|list>
|
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
rs-cab.use:
|
rs-cab.use:
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
com\rsscripting\rstaxi\stops\StopManager.class
|
com\rsscripting\rstaxi\stops\StopManager.class
|
||||||
com\rsscripting\rstaxi\platform\PlatformValidator.class
|
com\rsscripting\rstaxi\platform\PlatformValidator.class
|
||||||
com\rsscripting\rstaxi\RSTaxi.class
|
com\rsscripting\rstaxi\RSTaxi.class
|
||||||
|
com\rsscripting\rstaxi\commands\CabTabCompleter.class
|
||||||
com\rsscripting\rstaxi\stops\StopManager$StopEntry.class
|
com\rsscripting\rstaxi\stops\StopManager$StopEntry.class
|
||||||
com\rsscripting\rstaxi\commands\CabCommand.class
|
com\rsscripting\rstaxi\commands\CabCommand.class
|
||||||
com\rsscripting\rstaxi\database\DatabaseManager.class
|
com\rsscripting\rstaxi\database\DatabaseManager.class
|
||||||
|
com\rsscripting\rstaxi\commands\CabSearchCommand.class
|
||||||
com\rsscripting\rstaxi\language\LanguageManager.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\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\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\language\LanguageManager.java
|
||||||
C:\Users\russe\IdeaProjects\RS-Taxi\src\main\java\com\rsscripting\rstaxi\platform\PlatformValidator.java
|
C:\Users\russe\IdeaProjects\RS-Taxi\src\main\java\com\rsscripting\rstaxi\platform\PlatformValidator.java
|
||||||
|
|||||||
Reference in new issue
Block a user