diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
index eddf071..28e2617 100644
--- a/.idea/jarRepositories.xml
+++ b/.idea/jarRepositories.xml
@@ -21,6 +21,11 @@
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index 01b5727..6350c9a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -25,6 +25,10 @@
papermc
https://repo.papermc.io/repository/maven-public/
+
+ bluemap
+ https://repo.bluecolored.de/releases
+
@@ -34,6 +38,12 @@
26.1.2.build.25-alpha
provided
+
+ de.bluecolored
+ bluemap-api
+ 2.8.0
+ provided
+
diff --git a/src/main/java/com/rsscripting/rstaxi/RSTaxi.java b/src/main/java/com/rsscripting/rstaxi/RSTaxi.java
index 8e233a9..ed9ad81 100644
--- a/src/main/java/com/rsscripting/rstaxi/RSTaxi.java
+++ b/src/main/java/com/rsscripting/rstaxi/RSTaxi.java
@@ -5,12 +5,15 @@ 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 com.rsscripting.rstaxi.integrations.BlueMapManager;
import org.bukkit.plugin.java.JavaPlugin;
+import org.bukkit.Bukkit;
public final class RSTaxi extends JavaPlugin {
private LanguageManager languageManager;
private DatabaseManager databaseManager;
+ private BlueMapManager blueMapManager;
@Override
public void onEnable() {
@@ -45,6 +48,15 @@ public final class RSTaxi extends JavaPlugin {
getCommand("cab").setExecutor(new CabCommand(this));
getCommand("cab").setTabCompleter(new CabTabCompleter(this));
+ if (Bukkit.getPluginManager().isPluginEnabled("BlueMap")) {
+ getLogger().info("BlueMap detected. Map integration will be enabled.");
+ } else {
+ getLogger().info("BlueMap not detected. Map integration is disabled.");
+ }
+
+ blueMapManager = new BlueMapManager(this);
+ blueMapManager.initialize();
+
getLogger().info("RS-Taxi has been enabled!");
}
@@ -60,6 +72,10 @@ public final class RSTaxi extends JavaPlugin {
}
+ public BlueMapManager getBlueMapManager() {
+ return blueMapManager;
+ }
+
public LanguageManager getLanguageManager() {
return languageManager;
}
diff --git a/src/main/java/com/rsscripting/rstaxi/commands/CabCommand.java b/src/main/java/com/rsscripting/rstaxi/commands/CabCommand.java
index 14da11e..14297b1 100644
--- a/src/main/java/com/rsscripting/rstaxi/commands/CabCommand.java
+++ b/src/main/java/com/rsscripting/rstaxi/commands/CabCommand.java
@@ -4,12 +4,16 @@ package com.rsscripting.rstaxi.commands;
import com.rsscripting.rstaxi.RSTaxi;
import com.rsscripting.rstaxi.platform.PlatformValidator;
import com.rsscripting.rstaxi.stops.StopManager;
+import com.rsscripting.rstaxi.integrations.BlueMapManager;
import java.sql.SQLException;
import java.util.Map;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.World;
public final class CabCommand implements CommandExecutor {
@@ -62,6 +66,7 @@ public final class CabCommand implements CommandExecutor {
}
}
+
private boolean handleTravel(
CommandSender sender,
String[] args
@@ -82,11 +87,80 @@ public final class CabCommand implements CommandExecutor {
return true;
}
- // Travel behavior will be implemented in Phase 2.
+ if (args.length == 0) {
+ sender.sendMessage(
+ plugin.getLanguageManager()
+ .getMessage("general.invalid-usage")
+ );
+ return true;
+ }
+
+ String name = String.join(" ", args).trim();
+
+ try {
+ StopManager.StopLocation stop =
+ stopManager.getStopLocation(name);
+
+ if (stop == null) {
+ player.sendMessage(
+ plugin.getLanguageManager().getMessage(
+ "general.unknown-stop",
+ Map.of("stop", name)
+ )
+ );
+ return true;
+ }
+
+ World world = Bukkit.getWorld(stop.world());
+
+ if (world == null) {
+ player.sendMessage(
+ plugin.getLanguageManager()
+ .getMessage("general.invalid-usage")
+ );
+
+ plugin.getLogger().warning(
+ "Cannot teleport to taxi stop '" + name
+ + "': world '" + stop.world()
+ + "' is not loaded."
+ );
+ return true;
+ }
+
+ Location destination = new Location(
+ world,
+ stop.x(),
+ stop.y(),
+ stop.z(),
+ stop.yaw(),
+ stop.pitch()
+ );
+
+ player.teleport(destination);
+
+ player.sendMessage(
+ plugin.getLanguageManager().getMessage(
+ "teleport.success",
+ Map.of("stop", stop.name())
+ )
+ );
+
+ } catch (SQLException e) {
+ plugin.getLogger().log(
+ java.util.logging.Level.SEVERE,
+ "Failed to retrieve taxi stop for teleport: " + name,
+ e
+ );
+
+ player.sendMessage(
+ plugin.getLanguageManager()
+ .getMessage("list.error")
+ );
+ }
+
return true;
}
-
private boolean handleAdd(
CommandSender sender,
String[] args
@@ -155,9 +229,14 @@ public final class CabCommand implements CommandExecutor {
}
if (stopManager.add(name, icon, player.getLocation())) {
+ if (plugin.getBlueMapManager() != null) {
+ plugin.getBlueMapManager().addStop(name);
+ }
+
sender.sendMessage(plugin.getLanguageManager()
.getMessage("stop.added",
Map.of("stop", name)));
+
} else {
sender.sendMessage(plugin.getLanguageManager()
.getMessage("stop.already-exists",
@@ -224,6 +303,9 @@ public final class CabCommand implements CommandExecutor {
try {
if (stopManager.delete(name)) {
+
+ plugin.getBlueMapManager().removeStop(name);
+
sender.sendMessage(
plugin.getLanguageManager().getMessage(
"stop.deleted",
diff --git a/src/main/java/com/rsscripting/rstaxi/integrations/BlueMapManager.java b/src/main/java/com/rsscripting/rstaxi/integrations/BlueMapManager.java
new file mode 100644
index 0000000..e47fdb3
--- /dev/null
+++ b/src/main/java/com/rsscripting/rstaxi/integrations/BlueMapManager.java
@@ -0,0 +1,208 @@
+
+package com.rsscripting.rstaxi.integrations;
+
+import com.rsscripting.rstaxi.RSTaxi;
+import com.rsscripting.rstaxi.stops.StopManager;
+import de.bluecolored.bluemap.api.BlueMapAPI;
+import de.bluecolored.bluemap.api.BlueMapMap;
+import de.bluecolored.bluemap.api.markers.MarkerSet;
+import de.bluecolored.bluemap.api.markers.POIMarker;
+
+import java.nio.charset.StandardCharsets;
+import java.sql.SQLException;
+import java.util.Locale;
+import java.util.UUID;
+
+public final class BlueMapManager {
+
+ private static final String MARKER_SET_ID = "rs-taxi-stops";
+
+ private final RSTaxi plugin;
+ private final StopManager stopManager;
+
+ public BlueMapManager(RSTaxi plugin) {
+ this.plugin = plugin;
+ this.stopManager = new StopManager(plugin);
+ }
+
+
+ public void initialize() {
+ if (!plugin.getServer()
+ .getPluginManager()
+ .isPluginEnabled("BlueMap")) {
+
+ plugin.getLogger().info(
+ "BlueMap not detected. Map integration is disabled."
+ );
+ return;
+ }
+
+ BlueMapAPI.onEnable(api -> {
+ try {
+ // Create the RS-Taxi layer on every map first.
+ api.getMaps().forEach(map ->
+ map.getMarkerSets().computeIfAbsent(
+ MARKER_SET_ID,
+ id -> MarkerSet.builder()
+ .label("RS-Taxi")
+ .toggleable(true)
+ .defaultHidden(false)
+ .build()
+ )
+ );
+
+ // Add markers for saved taxi stops.
+ for (StopManager.StopEntry entry
+ : stopManager.getAllStops()) {
+
+ StopManager.StopLocation stop =
+ stopManager.getStopLocation(entry.name());
+
+ if (stop == null) {
+ continue;
+ }
+
+ api.getWorld(stop.world()).ifPresentOrElse(
+ world -> world.getMaps().forEach(map -> {
+ MarkerSet markerSet =
+ map.getMarkerSets().get(MARKER_SET_ID);
+
+ if (markerSet == null) {
+ return;
+ }
+
+ String markerId = "stop_"
+ + UUID.nameUUIDFromBytes(
+ stop.name()
+ .toLowerCase(Locale.ROOT)
+ .getBytes(StandardCharsets.UTF_8)
+ );
+
+ POIMarker marker = POIMarker.builder()
+ .label(stop.name())
+ .position(
+ stop.x(),
+ stop.y(),
+ stop.z()
+ )
+ .build();
+
+ markerSet.getMarkers().put(markerId, marker);
+ }),
+ () -> plugin.getLogger().warning(
+ "BlueMap has no loaded world for taxi stop '"
+ + stop.name() + "' ("
+ + stop.world() + ")."
+ )
+ );
+ }
+
+ plugin.getLogger().info(
+ "BlueMap taxi stop markers initialized."
+ );
+
+ } catch (SQLException e) {
+ plugin.getLogger().severe(
+ "Failed to load taxi stops for BlueMap."
+ );
+ plugin.getLogger().log(
+ java.util.logging.Level.SEVERE,
+ "Database error while creating BlueMap markers.",
+ e
+ );
+ }
+ });
+ }
+
+
+ public void addStop(String stopName) {
+ try {
+ StopManager.StopLocation stop =
+ stopManager.getStopLocation(stopName);
+
+ if (stop == null) {
+ plugin.getLogger().warning(
+ "Cannot create BlueMap marker: taxi stop '"
+ + stopName + "' was not found."
+ );
+ return;
+ }
+
+ BlueMapAPI.getInstance().ifPresentOrElse(api ->
+ api.getWorld(stop.world()).ifPresentOrElse(
+ world -> world.getMaps().forEach(map -> {
+ MarkerSet markerSet =
+ map.getMarkerSets().get(MARKER_SET_ID);
+
+ if (markerSet == null) {
+ markerSet = MarkerSet.builder()
+ .label("RS-Taxi")
+ .toggleable(true)
+ .defaultHidden(false)
+ .build();
+
+ map.getMarkerSets().put(
+ MARKER_SET_ID,
+ markerSet
+ );
+ }
+
+ String markerId = "stop_"
+ + UUID.nameUUIDFromBytes(
+ stop.name()
+ .toLowerCase(Locale.ROOT)
+ .getBytes(StandardCharsets.UTF_8)
+ );
+
+ POIMarker marker = POIMarker.builder()
+ .label(stop.name())
+ .position(
+ stop.x(),
+ stop.y(),
+ stop.z()
+ )
+ .build();
+
+ markerSet.getMarkers().put(markerId, marker);
+ }),
+ () -> plugin.getLogger().warning(
+ "BlueMap has no loaded world for taxi stop '"
+ + stop.name() + "' ("
+ + stop.world() + ")."
+ )
+ ),
+ () -> plugin.getLogger().warning(
+ "BlueMap is not currently available; "
+ + "could not add marker for '" + stopName + "'."
+ )
+ );
+
+ } catch (SQLException e) {
+ plugin.getLogger().log(
+ java.util.logging.Level.SEVERE,
+ "Failed to load taxi stop for BlueMap: " + stopName,
+ e
+ );
+ }
+ }
+
+ public void removeStop(String stopName) {
+ String markerId = "stop_"
+ + UUID.nameUUIDFromBytes(
+ stopName.toLowerCase(Locale.ROOT)
+ .getBytes(StandardCharsets.UTF_8)
+ );
+
+ BlueMapAPI.getInstance().ifPresent(api -> {
+ for (BlueMapMap map : api.getMaps()) {
+ MarkerSet markerSet =
+ map.getMarkerSets().get(MARKER_SET_ID);
+
+ if (markerSet != null) {
+ markerSet.getMarkers().remove(markerId);
+ }
+ }
+ });
+ }
+
+}
diff --git a/src/main/java/com/rsscripting/rstaxi/stops/StopManager.java b/src/main/java/com/rsscripting/rstaxi/stops/StopManager.java
index b7419dc..a4b9758 100644
--- a/src/main/java/com/rsscripting/rstaxi/stops/StopManager.java
+++ b/src/main/java/com/rsscripting/rstaxi/stops/StopManager.java
@@ -22,6 +22,17 @@ public final class StopManager {
public record StopEntry(String name, String icon) {
}
+ public record StopLocation(
+ String name,
+ String world,
+ double x,
+ double y,
+ double z,
+ float yaw,
+ float pitch
+ ) {
+ }
+
public boolean exists(String name) throws SQLException {
String sql = "SELECT 1 FROM stops WHERE name = ?";
@@ -36,6 +47,39 @@ public final class StopManager {
}
}
+
+ public StopLocation getStopLocation(String name)
+ throws SQLException {
+
+ String sql = """
+ SELECT name, world, x, y, z, yaw, pitch
+ FROM stops
+ WHERE name = ?
+ """;
+
+ try (PreparedStatement statement = connection()
+ .prepareStatement(sql)) {
+
+ statement.setString(1, name);
+
+ try (ResultSet results = statement.executeQuery()) {
+ if (!results.next()) {
+ return null;
+ }
+
+ return new StopLocation(
+ results.getString("name"),
+ results.getString("world"),
+ results.getDouble("x"),
+ results.getDouble("y"),
+ results.getDouble("z"),
+ results.getFloat("yaw"),
+ results.getFloat("pitch")
+ );
+ }
+ }
+ }
+
public boolean delete(String name) throws SQLException {
String sql = "DELETE FROM stops WHERE name = ?";
diff --git a/target/RS-Taxi-0.1.0.jar b/target/RS-Taxi-0.1.0.jar
index a7a7e30..31c1c2b 100644
Binary files a/target/RS-Taxi-0.1.0.jar and b/target/RS-Taxi-0.1.0.jar differ
diff --git a/target/classes/com/rsscripting/rstaxi/RSTaxi.class b/target/classes/com/rsscripting/rstaxi/RSTaxi.class
index 8331df7..3680f7d 100644
Binary files a/target/classes/com/rsscripting/rstaxi/RSTaxi.class and b/target/classes/com/rsscripting/rstaxi/RSTaxi.class differ
diff --git a/target/classes/com/rsscripting/rstaxi/commands/CabCommand.class b/target/classes/com/rsscripting/rstaxi/commands/CabCommand.class
index 17e0fd1..dde157b 100644
Binary files a/target/classes/com/rsscripting/rstaxi/commands/CabCommand.class and b/target/classes/com/rsscripting/rstaxi/commands/CabCommand.class differ
diff --git a/target/classes/com/rsscripting/rstaxi/stops/StopManager.class b/target/classes/com/rsscripting/rstaxi/stops/StopManager.class
index e05fe44..3ba7a4a 100644
Binary files a/target/classes/com/rsscripting/rstaxi/stops/StopManager.class and b/target/classes/com/rsscripting/rstaxi/stops/StopManager.class differ
diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
index 6a42d04..e1e13fc 100644
--- a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
+++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -1,9 +1,11 @@
+com\rsscripting\rstaxi\stops\StopManager$StopEntry.class
+com\rsscripting\rstaxi\commands\CabCommand.class
+com\rsscripting\rstaxi\integrations\BlueMapManager.class
+com\rsscripting\rstaxi\database\DatabaseManager.class
+com\rsscripting\rstaxi\commands\CabSearchCommand.class
+com\rsscripting\rstaxi\stops\StopManager$StopLocation.class
+com\rsscripting\rstaxi\language\LanguageManager.class
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
diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
index 03d27db..86678f9 100644
--- a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
+++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -2,6 +2,7 @@ C:\Users\russe\IdeaProjects\RS-Taxi\src\main\java\com\rsscripting\rstaxi\command
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\integrations\BlueMapManager.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\RSTaxi.java