Initial Development

- /cab list complete.
This commit is contained in:
BigPappa committed 2026-10-11 11:37:17 -05:00
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();
} }
+4
View File
@@ -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."
-1
View File
@@ -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.
+4
View File
@@ -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."
-1
View File
@@ -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