0.1.0 - Added
- Clickable /cab list - Clickable /cab search xxxx
This commit is contained in:
1 parent
a7fba84cd3
commit
2e8b4b19c8
15 files changed
+217
-48
No files matched your search
@@ -5,6 +5,9 @@ import com.rsscripting.rstaxi.RSTaxi;
|
||||
import com.rsscripting.rstaxi.platform.PlatformValidator;
|
||||
import com.rsscripting.rstaxi.stops.StopManager;
|
||||
import com.rsscripting.rstaxi.integrations.BlueMapManager;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
import org.bukkit.command.Command;
|
||||
@@ -55,7 +58,7 @@ public final class CabCommand implements CommandExecutor {
|
||||
return handleRemove(sender, args);
|
||||
}
|
||||
case "list" -> {
|
||||
return handleList(sender);
|
||||
return openList(sender);
|
||||
}
|
||||
case "search" -> {
|
||||
return searchCommand.execute(sender, args);
|
||||
@@ -66,7 +69,6 @@ public final class CabCommand implements CommandExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean handleTravel(
|
||||
CommandSender sender,
|
||||
String[] args
|
||||
@@ -88,7 +90,7 @@ public final class CabCommand implements CommandExecutor {
|
||||
}
|
||||
|
||||
if (args.length == 0) {
|
||||
sender.sendMessage(
|
||||
player.sendMessage(
|
||||
plugin.getLanguageManager()
|
||||
.getMessage("general.invalid-usage")
|
||||
);
|
||||
@@ -96,10 +98,22 @@ public final class CabCommand implements CommandExecutor {
|
||||
}
|
||||
|
||||
String name = String.join(" ", args).trim();
|
||||
boolean allowCrossWorld = plugin.getConfig()
|
||||
.getBoolean("allow-cross-world", true);
|
||||
|
||||
try {
|
||||
StopManager.StopLocation stop =
|
||||
stopManager.getStopLocation(name);
|
||||
StopManager.StopLocation stop;
|
||||
|
||||
if (allowCrossWorld && name.contains(":")) {
|
||||
int separator = name.indexOf(':');
|
||||
String worldName = name.substring(0, separator).trim();
|
||||
String stopName = name.substring(separator + 1).trim();
|
||||
|
||||
stop = stopManager.getStopLocation(stopName, worldName);
|
||||
name = stopName;
|
||||
} else {
|
||||
stop = stopManager.getStopLocation(name);
|
||||
}
|
||||
|
||||
if (stop == null) {
|
||||
player.sendMessage(
|
||||
@@ -111,6 +125,15 @@ public final class CabCommand implements CommandExecutor {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!allowCrossWorld
|
||||
&& !player.getWorld().getName().equals(stop.world())) {
|
||||
player.sendMessage(
|
||||
plugin.getLanguageManager()
|
||||
.getMessage("general.stop-in-another-world")
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
World world = Bukkit.getWorld(stop.world());
|
||||
|
||||
if (world == null) {
|
||||
@@ -141,7 +164,12 @@ public final class CabCommand implements CommandExecutor {
|
||||
player.sendMessage(
|
||||
plugin.getLanguageManager().getMessage(
|
||||
"teleport.success",
|
||||
Map.of("stop", stop.name())
|
||||
Map.of(
|
||||
"stop",
|
||||
allowCrossWorld
|
||||
? stop.world() + ":" + stop.name()
|
||||
: stop.name()
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
@@ -341,9 +369,7 @@ public final class CabCommand implements CommandExecutor {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private boolean handleList(CommandSender sender) {
|
||||
public boolean openList(CommandSender sender) {
|
||||
if (!sender.hasPermission("rs-cab.use")) {
|
||||
sender.sendMessage(
|
||||
plugin.getLanguageManager()
|
||||
@@ -352,35 +378,55 @@ public final class CabCommand implements CommandExecutor {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(sender instanceof Player player)) {
|
||||
sender.sendMessage(
|
||||
plugin.getLanguageManager()
|
||||
.getMessage("general.player-only")
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
var stops = stopManager.getAllStops();
|
||||
boolean allowCrossWorld = plugin.getConfig()
|
||||
.getBoolean("allow-cross-world", true);
|
||||
|
||||
if (!allowCrossWorld) {
|
||||
String currentWorld = player.getWorld().getName();
|
||||
|
||||
stops = stops.stream()
|
||||
.filter(stop -> stop.world().equals(currentWorld))
|
||||
.toList();
|
||||
}
|
||||
|
||||
if (stops.isEmpty()) {
|
||||
sender.sendMessage(
|
||||
player.sendMessage(
|
||||
plugin.getLanguageManager()
|
||||
.getMessage("general.no-stops")
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
sender.sendMessage(
|
||||
player.sendMessage(
|
||||
plugin.getLanguageManager()
|
||||
.getMessage("list.header")
|
||||
);
|
||||
|
||||
for (StopManager.StopEntry stop : stops) {
|
||||
sender.sendMessage(
|
||||
plugin.getLanguageManager()
|
||||
.getMessage(
|
||||
"list.entry",
|
||||
Map.of(
|
||||
"icon", stop.icon(),
|
||||
"stop", stop.name()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
String displayName = allowCrossWorld
|
||||
? stop.world() + ":" + stop.name()
|
||||
: stop.name();
|
||||
|
||||
String command = "/cab " + stop.name();
|
||||
|
||||
Component clickableStop = Component.text(displayName)
|
||||
.color(NamedTextColor.WHITE)
|
||||
.clickEvent(ClickEvent.runCommand(command))
|
||||
.hoverEvent(net.kyori.adventure.text.event.HoverEvent
|
||||
.showText(Component.text("Click to teleport")));
|
||||
|
||||
player.sendMessage(clickableStop);
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().log(
|
||||
@@ -389,17 +435,15 @@ public final class CabCommand implements CommandExecutor {
|
||||
e
|
||||
);
|
||||
|
||||
sender.sendMessage(
|
||||
player.sendMessage(
|
||||
plugin.getLanguageManager()
|
||||
.getMessage("list.error")
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private boolean checkPermission(
|
||||
CommandSender sender,
|
||||
String permission
|
||||
|
||||
@@ -4,9 +4,12 @@ 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;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public final class CabSearchCommand {
|
||||
|
||||
@@ -49,6 +52,17 @@ public final class CabSearchCommand {
|
||||
? stopManager.searchByIcon(value)
|
||||
: stopManager.searchByName(value);
|
||||
|
||||
boolean allowCrossWorld = plugin.getConfig()
|
||||
.getBoolean("allow-cross-world", true);
|
||||
|
||||
if (!allowCrossWorld && sender instanceof Player player) {
|
||||
String currentWorld = player.getWorld().getName();
|
||||
|
||||
stops = stops.stream()
|
||||
.filter(stop -> stop.world().equals(currentWorld))
|
||||
.toList();
|
||||
}
|
||||
|
||||
if (stops.isEmpty()) {
|
||||
sender.sendMessage(
|
||||
plugin.getLanguageManager()
|
||||
@@ -63,15 +77,23 @@ public final class CabSearchCommand {
|
||||
);
|
||||
|
||||
for (StopManager.StopEntry stop : stops) {
|
||||
sender.sendMessage(
|
||||
plugin.getLanguageManager().getMessage(
|
||||
"list.entry",
|
||||
Map.of(
|
||||
"icon", stop.icon(),
|
||||
"stop", stop.name()
|
||||
)
|
||||
)
|
||||
String displayName = allowCrossWorld
|
||||
? stop.world() + ":" + stop.name()
|
||||
: stop.name();
|
||||
|
||||
if (sender instanceof Player) {
|
||||
Component clickableStop = Component.text(displayName)
|
||||
.color(NamedTextColor.WHITE)
|
||||
.clickEvent(ClickEvent.runCommand("/cab " + stop.name()))
|
||||
.hoverEvent(
|
||||
net.kyori.adventure.text.event.HoverEvent
|
||||
.showText(Component.text("Click to teleport"))
|
||||
);
|
||||
|
||||
sender.sendMessage(clickableStop);
|
||||
} else {
|
||||
sender.sendMessage(displayName);
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().log(
|
||||
|
||||
@@ -40,11 +40,26 @@ public final class CabTabCompleter implements TabCompleter {
|
||||
}
|
||||
|
||||
String input = args[0].toLowerCase(Locale.ROOT);
|
||||
boolean allowCrossWorld = plugin.getConfig()
|
||||
.getBoolean("allow-cross-world", true);
|
||||
|
||||
String currentWorld = sender instanceof org.bukkit.entity.Player player
|
||||
? player.getWorld().getName()
|
||||
: null;
|
||||
|
||||
for (StopManager.StopEntry stop : getSortedStops()) {
|
||||
if (stop.name().toLowerCase(Locale.ROOT)
|
||||
.startsWith(input)) {
|
||||
suggestions.add(stop.name());
|
||||
if (!allowCrossWorld
|
||||
&& currentWorld != null
|
||||
&& !stop.world().equals(currentWorld)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String suggestion = allowCrossWorld
|
||||
? stop.world() + ":" + stop.name()
|
||||
: stop.name();
|
||||
|
||||
if (suggestion.toLowerCase(Locale.ROOT).startsWith(input)) {
|
||||
suggestions.add(suggestion);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,10 @@ import org.bukkit.block.Block;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import com.rsscripting.rstaxi.commands.CabCommand;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -29,6 +33,38 @@ public final class PlatformProtectionListener implements Listener {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlatformInteract(PlayerInteractEvent event) {
|
||||
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
|
||||
if (!player.isSneaking()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!plugin.getConfig().getBoolean("platform.enabled", true)
|
||||
|| !plugin.getConfig().getBoolean(
|
||||
"platform.sneak-rightclick-platform", false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Block clicked = event.getClickedBlock();
|
||||
|
||||
if (clicked == null
|
||||
|| clicked.getType() != getMaterial("platform.target-block")
|
||||
|| !hasRequiredSurroundings(clicked)) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
|
||||
CabCommand cabCommand = new CabCommand(plugin);
|
||||
cabCommand.openList(player);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockBreak(BlockBreakEvent event) {
|
||||
|
||||
|
||||
@@ -19,8 +19,11 @@ public final class StopManager {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public record StopEntry(String name, String icon) {
|
||||
}
|
||||
public record StopEntry(
|
||||
String name,
|
||||
String icon,
|
||||
String world
|
||||
) {}
|
||||
|
||||
public record StopLocation(
|
||||
String name,
|
||||
@@ -34,6 +37,40 @@ public final class StopManager {
|
||||
) {
|
||||
}
|
||||
|
||||
public StopLocation getStopLocation(String name, String world)
|
||||
throws SQLException {
|
||||
|
||||
String sql = """
|
||||
SELECT name, icon, world, x, y, z, yaw, pitch
|
||||
FROM stops
|
||||
WHERE name = ? AND world = ?
|
||||
""";
|
||||
|
||||
try (PreparedStatement statement = connection()
|
||||
.prepareStatement(sql)) {
|
||||
|
||||
statement.setString(1, name);
|
||||
statement.setString(2, world);
|
||||
|
||||
try (ResultSet results = statement.executeQuery()) {
|
||||
if (!results.next()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new StopLocation(
|
||||
results.getString("name"),
|
||||
results.getString("icon"),
|
||||
results.getString("world"),
|
||||
results.getDouble("x"),
|
||||
results.getDouble("y"),
|
||||
results.getDouble("z"),
|
||||
results.getFloat("yaw"),
|
||||
results.getFloat("pitch")
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean exists(String name) throws SQLException {
|
||||
String sql = "SELECT 1 FROM stops WHERE name = ?";
|
||||
|
||||
@@ -126,7 +163,7 @@ public final class StopManager {
|
||||
|
||||
public List<StopEntry> getAllStops() throws SQLException {
|
||||
String sql = """
|
||||
SELECT name, icon
|
||||
SELECT name, icon, world
|
||||
FROM stops
|
||||
ORDER BY name COLLATE NOCASE
|
||||
""";
|
||||
@@ -140,7 +177,8 @@ public final class StopManager {
|
||||
while (results.next()) {
|
||||
stops.add(new StopEntry(
|
||||
results.getString("name"),
|
||||
results.getString("icon")
|
||||
results.getString("icon"),
|
||||
results.getString("world")
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -153,9 +191,9 @@ public final class StopManager {
|
||||
throws SQLException {
|
||||
|
||||
String sql = """
|
||||
SELECT name, icon
|
||||
SELECT name, icon, world
|
||||
FROM stops
|
||||
WHERE name LIKE ? ESCAPE '\\'
|
||||
WHERE LOWER(name) LIKE LOWER(?)
|
||||
ORDER BY name COLLATE NOCASE
|
||||
""";
|
||||
|
||||
@@ -175,7 +213,8 @@ public final class StopManager {
|
||||
while (results.next()) {
|
||||
stops.add(new StopEntry(
|
||||
results.getString("name"),
|
||||
results.getString("icon")
|
||||
results.getString("icon"),
|
||||
results.getString("world")
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -188,9 +227,9 @@ public final class StopManager {
|
||||
throws SQLException {
|
||||
|
||||
String sql = """
|
||||
SELECT name, icon
|
||||
SELECT name, icon, world
|
||||
FROM stops
|
||||
WHERE icon = ?
|
||||
WHERE LOWER(icon) = LOWER(?)
|
||||
ORDER BY name COLLATE NOCASE
|
||||
""";
|
||||
|
||||
@@ -205,7 +244,8 @@ public final class StopManager {
|
||||
while (results.next()) {
|
||||
stops.add(new StopEntry(
|
||||
results.getString("name"),
|
||||
results.getString("icon")
|
||||
results.getString("icon"),
|
||||
results.getString("world")
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,11 @@
|
||||
# Example: en_us, de_de, fr_fr
|
||||
language: "en_us"
|
||||
|
||||
# Allow players to travel between different worlds.
|
||||
# true: Players can travel to stops in any world.
|
||||
# false: Players can only travel to stops in their current world.
|
||||
allow-cross-world: true
|
||||
|
||||
# Platform Settings.
|
||||
platform:
|
||||
# Determines wether platforms are required before adding a destination
|
||||
@@ -22,6 +27,12 @@ platform:
|
||||
# false: platforms can be broken.
|
||||
protect-platforms: true
|
||||
|
||||
# Allow players to sneak + right-click the center block
|
||||
# of a valid 3x3 taxi platform to open a clickable list of
|
||||
# taxi stops.
|
||||
# Requires platform.enabled to be true.
|
||||
sneak-rightclick-platform: false
|
||||
|
||||
#Layout requirement for add a destination if enabled is set to true.
|
||||
layout:
|
||||
north: "OAK_PLANKS"
|
||||
|
||||
@@ -8,6 +8,7 @@ general:
|
||||
invalid-usage: "&cInvalid command usage."
|
||||
unknown-stop: "&cThe stop &e%stop% &cdoes not exist."
|
||||
no-stops: "&eNo taxi stops have been created yet."
|
||||
stop-in-another-world: "&cStop is in another world, you need to enter that world first."
|
||||
|
||||
database:
|
||||
connection-success: "&aDatabase connected successfully."
|
||||
@@ -32,7 +33,7 @@ confirmation:
|
||||
|
||||
list:
|
||||
header: "&6Available Taxi Destinations:"
|
||||
entry: "&e%icon% &f%stop%"
|
||||
entry: "&f%stop%"
|
||||
error: "&cUnable to retrieve taxi destinations. Check the server logs."
|
||||
|
||||
platform:
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in new issue
Block a user