Skip to content

Commit 3b6c7e3

Browse files
committed
Add manual line management, unique IDs, and config improvements
Introduces manual line creation, editing, and removal via new /railway line subcommands with granular permission checks. Adds short unique hex IDs for lines, minimum line length filtering, and improved debug logging. Updates config and permissions structure, enhances map rendering, and expands documentation in README.
1 parent 7bd62dc commit 3b6c7e3

File tree

18 files changed

+835
-119
lines changed

18 files changed

+835
-119
lines changed

README.md

Lines changed: 347 additions & 66 deletions
Large diffs are not rendered by default.

src/main/java/com/fabianoley/dynmaprailways/DynmapRailways.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,21 @@ public void apiEnabled(DynmapCommonAPI api) {
6161
}
6262

6363
// Initialize map renderer
64-
getLogger().info("[DEBUG] About to initialize map renderer...");
64+
boolean debugEnabled = getConfig().getBoolean("general.debug", false);
65+
if (debugEnabled) {
66+
getLogger().info("[DEBUG] About to initialize map renderer...");
67+
}
6568
mapRenderer = new RailwayMapRenderer(DynmapRailways.this, dynmapAPI, dataStorage);
66-
getLogger().info("[DEBUG] RailwayMapRenderer created, calling initialize()...");
69+
if (debugEnabled) {
70+
getLogger().info("[DEBUG] RailwayMapRenderer created, calling initialize()...");
71+
}
6772
mapRenderer.initialize();
68-
getLogger().info("[DEBUG] Railway map renderer initialization complete.");
73+
if (debugEnabled) {
74+
getLogger().info("[DEBUG] Railway map renderer initialization complete.");
75+
}
6976

7077
// Provide CoreProtect integration to scanner (optional)
71-
com.fabianoley.dynmaprailways.scan.RailScanner.setCoreProtectIntegration(coreProtect);
78+
com.fabianoley.dynmaprailways.scan.RailScanner.setCoreProtectIntegration(coreProtect, DynmapRailways.this);
7279

7380
// Register commands
7481
registerCommands();

src/main/java/com/fabianoley/dynmaprailways/commands/RailwayCommand.java

Lines changed: 289 additions & 12 deletions
Large diffs are not rendered by default.

src/main/java/com/fabianoley/dynmaprailways/map/RailwayMapRenderer.java

Lines changed: 81 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -37,47 +37,68 @@ public RailwayMapRenderer(DynmapRailways plugin, DynmapCommonAPI dynmapAPI, Rail
3737
// No CoreProtect filtering
3838
}
3939

40+
/**
41+
* Check if debug mode is enabled.
42+
*/
43+
private boolean isDebugEnabled() {
44+
return plugin.getConfig().getBoolean("general.debug", false);
45+
}
46+
4047
/**
4148
* Initialize the map renderer.
4249
*/
4350
public void initialize() {
44-
logger.info("[DEBUG] Starting RailwayMapRenderer initialization...");
51+
if (isDebugEnabled()) {
52+
logger.info("[DEBUG] Starting RailwayMapRenderer initialization...");
53+
}
4554
// Touch plugin to avoid unused field warning and for debugging context
4655
if (plugin != null) {
47-
logger.fine("[DEBUG] Renderer initialized for plugin: " + plugin.getClass().getName());
56+
if (isDebugEnabled()) {
57+
logger.fine("[DEBUG] Renderer initialized for plugin: " + plugin.getClass().getName());
58+
}
4859
}
4960

50-
// No CoreProtect filtering
51-
5261
if (dynmapAPI == null) {
5362
logger.severe("[DEBUG] Dynmap API is null!");
5463
return;
5564
}
56-
logger.info("[DEBUG] Dynmap API found: " + dynmapAPI.getClass().getName());
65+
if (isDebugEnabled()) {
66+
logger.info("[DEBUG] Dynmap API found: " + dynmapAPI.getClass().getName());
67+
}
5768

5869
// Get Marker API
5970
markerAPI = dynmapAPI.getMarkerAPI();
60-
logger.info("[DEBUG] Marker API retrieved: " + (markerAPI != null ? markerAPI.getClass().getName() : "null"));
71+
if (isDebugEnabled()) {
72+
logger.info("[DEBUG] Marker API retrieved: " + (markerAPI != null ? markerAPI.getClass().getName() : "null"));
73+
}
6174

6275
if (markerAPI == null) {
6376
logger.severe("[DEBUG] Dynmap Marker API not available!");
6477
return;
6578
}
6679

6780
// Get or create marker sets
68-
logger.info("[DEBUG] Creating marker sets...");
81+
if (isDebugEnabled()) {
82+
logger.info("[DEBUG] Creating marker sets...");
83+
}
6984
createMarkerSets();
7085

71-
logger.info("[DEBUG] Railway marker set: " + (railwayMarkerSet != null ? railwayMarkerSet.getClass().getName() : "null"));
72-
logger.info("[DEBUG] Station marker set: " + (stationMarkerSet != null ? stationMarkerSet.getClass().getName() : "null"));
86+
if (isDebugEnabled()) {
87+
logger.info("[DEBUG] Railway marker set: " + (railwayMarkerSet != null ? railwayMarkerSet.getClass().getName() : "null"));
88+
logger.info("[DEBUG] Station marker set: " + (stationMarkerSet != null ? stationMarkerSet.getClass().getName() : "null"));
89+
}
7390

7491
if (railwayMarkerSet == null || stationMarkerSet == null) {
75-
logger.warning("[DEBUG] Failed to create marker sets");
92+
if (isDebugEnabled()) {
93+
logger.warning("[DEBUG] Failed to create marker sets");
94+
}
7695
return;
7796
}
7897

7998
// Initial render
80-
logger.info("[DEBUG] Updating all markers...");
99+
if (isDebugEnabled()) {
100+
logger.info("[DEBUG] Updating all markers...");
101+
}
81102
updateAllMarkers();
82103

83104
logger.info("Railway map renderer initialized successfully.");
@@ -87,23 +108,35 @@ public void initialize() {
87108
* Create or get marker sets.
88109
*/
89110
private void createMarkerSets() {
90-
logger.info("[DEBUG] createMarkerSets() called");
111+
if (isDebugEnabled()) {
112+
logger.info("[DEBUG] createMarkerSets() called");
113+
}
91114
// Get marker sets
92115
railwayMarkerSet = markerAPI.getMarkerSet(MARKER_SET_ID);
93116
stationMarkerSet = markerAPI.getMarkerSet(STATIONS_SET_ID);
94-
logger.info("[DEBUG] Retrieved existing marker sets: railway=" + (railwayMarkerSet != null) + ", station=" + (stationMarkerSet != null));
117+
if (isDebugEnabled()) {
118+
logger.info("[DEBUG] Retrieved existing marker sets: railway=" + (railwayMarkerSet != null) + ", station=" + (stationMarkerSet != null));
119+
}
95120

96121
// Create if missing
97122
if (railwayMarkerSet == null) {
98-
logger.info("[DEBUG] Railway marker set is null, attempting to create...");
123+
if (isDebugEnabled()) {
124+
logger.info("[DEBUG] Railway marker set is null, attempting to create...");
125+
}
99126
railwayMarkerSet = markerAPI.createMarkerSet(MARKER_SET_ID, "Railway Lines", null, false);
100-
logger.info("[DEBUG] Created Railway Lines marker set successfully");
127+
if (isDebugEnabled()) {
128+
logger.info("[DEBUG] Created Railway Lines marker set successfully");
129+
}
101130
}
102131

103132
if (stationMarkerSet == null) {
104-
logger.info("[DEBUG] Station marker set is null, attempting to create...");
133+
if (isDebugEnabled()) {
134+
logger.info("[DEBUG] Station marker set is null, attempting to create...");
135+
}
105136
stationMarkerSet = markerAPI.createMarkerSet(STATIONS_SET_ID, "Railway Stations", null, false);
106-
logger.info("[DEBUG] Created Railway Stations marker set successfully");
137+
if (isDebugEnabled()) {
138+
logger.info("[DEBUG] Created Railway Stations marker set successfully");
139+
}
107140
}
108141

109142
// Set layer priorities - higher priority renders on top
@@ -121,10 +154,14 @@ private void createMarkerSets() {
121154
*/
122155
public void updateAllMarkers() {
123156
try {
124-
logger.info("[DEBUG] updateAllMarkers() called");
157+
if (isDebugEnabled()) {
158+
logger.info("[DEBUG] updateAllMarkers() called");
159+
}
125160

126161
if (railwayMarkerSet == null || stationMarkerSet == null) {
127-
logger.warning("[DEBUG] Marker sets not available - cannot render");
162+
if (isDebugEnabled()) {
163+
logger.warning("[DEBUG] Marker sets not available - cannot render");
164+
}
128165
return;
129166
}
130167

@@ -136,34 +173,50 @@ public void updateAllMarkers() {
136173
// Clear old markers
137174
clearMarkers(railwayMarkerSet);
138175
clearMarkers(stationMarkerSet);
139-
logger.info("[DEBUG] Cleared old markers");
176+
if (isDebugEnabled()) {
177+
logger.info("[DEBUG] Cleared old markers");
178+
}
140179

141180
// Render rail lines
142181
Map<String, RailLine> railLines = dataStorage.getRailLines();
143-
logger.info("[DEBUG] Found " + railLines.size() + " rail lines to render");
182+
if (isDebugEnabled()) {
183+
logger.info("[DEBUG] Found " + railLines.size() + " rail lines to render");
184+
}
144185

145186
boolean playerPlacedOnly = plugin.getConfig().getBoolean("coreprotect.player-placed-only", true);
146187
for (RailLine line : railLines.values()) {
147-
logger.info("[DEBUG] Processing line: " + line.getId() + " with " + line.getBlockCount() + " blocks, active=" + line.isActive());
188+
if (isDebugEnabled()) {
189+
logger.info("[DEBUG] Processing line: " + line.getId() + " with " + line.getBlockCount() + " blocks, active=" + line.isActive());
190+
}
148191
if (line.isActive() && line.getBlockCount() > 1 && (!playerPlacedOnly || line.getCreatedBy() != null)) {
149192
renderRailLine(line);
150-
logger.info("[DEBUG] Rendered line: " + line.getId());
193+
if (isDebugEnabled()) {
194+
logger.info("[DEBUG] Rendered line: " + line.getId());
195+
}
151196
}
152197
}
153198

154199
// Render stations
155200
Map<String, Station> stations = dataStorage.getStations();
156-
logger.info("[DEBUG] Found " + stations.size() + " stations to render");
201+
if (isDebugEnabled()) {
202+
logger.info("[DEBUG] Found " + stations.size() + " stations to render");
203+
}
157204

158205
for (Station station : stations.values()) {
159-
logger.info("[DEBUG] Processing station: " + station.getId() + ", active=" + station.isActive());
206+
if (isDebugEnabled()) {
207+
logger.info("[DEBUG] Processing station: " + station.getId() + ", active=" + station.isActive());
208+
}
160209
if (station.isActive()) {
161210
renderStation(station);
162-
logger.info("[DEBUG] Rendered station: " + station.getId());
211+
if (isDebugEnabled()) {
212+
logger.info("[DEBUG] Rendered station: " + station.getId());
213+
}
163214
}
164215
}
165216

166-
logger.info("[DEBUG] updateAllMarkers() completed successfully");
217+
if (isDebugEnabled()) {
218+
logger.info("[DEBUG] updateAllMarkers() completed successfully");
219+
}
167220
} catch (Exception e) {
168221
logger.warning("Error updating markers: " + e.getMessage());
169222
e.printStackTrace();
@@ -379,7 +432,7 @@ private void renderStation(Station station) {
379432
// Get station appearance settings from config (with defaults)
380433
double radius = plugin.getConfig().getDouble("stations.radius", 5.0);
381434
String fillColorHex = plugin.getConfig().getString("stations.fill-color", "#FFFFFF");
382-
double fillOpacity = plugin.getConfig().getDouble("stations.fill-opacity", 0.9);
435+
double fillOpacity = plugin.getConfig().getDouble("stations.fill-opacity", 0.3);
383436
int borderWidth = plugin.getConfig().getInt("stations.border-width", 2);
384437
String borderColorHex = plugin.getConfig().getString("stations.border-color", "#000000");
385438
double borderOpacity = plugin.getConfig().getDouble("stations.border-opacity", 1.0);

src/main/java/com/fabianoley/dynmaprailways/scan/RailScanner.java

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.bukkit.block.Block;
55
import org.bukkit.Material;
66

7+
import com.fabianoley.dynmaprailways.DynmapRailways;
78
import com.fabianoley.dynmaprailways.integration.CoreProtectIntegration;
89
import com.fabianoley.dynmaprailways.rail.RailLine;
910
import com.fabianoley.dynmaprailways.rail.RailLine.RailBlock;
@@ -17,9 +18,15 @@ public class RailScanner {
1718

1819
private static final Logger logger = Logger.getLogger("DynmapRailways");
1920
private static CoreProtectIntegration coreProtect;
21+
private static DynmapRailways plugin;
2022

21-
public static void setCoreProtectIntegration(CoreProtectIntegration integration) {
23+
public static void setCoreProtectIntegration(CoreProtectIntegration integration, DynmapRailways pluginInstance) {
2224
coreProtect = integration;
25+
plugin = pluginInstance;
26+
}
27+
28+
private static boolean isDebugEnabled() {
29+
return plugin != null && plugin.getConfig().getBoolean("general.debug", false);
2330
}
2431

2532
/**
@@ -131,8 +138,10 @@ public static List<RailLine> mergeWithExistingLines(World world, List<RailLine>
131138
blocksInExistingLines.add(block);
132139
}
133140

134-
logger.info("Added new line " + newLine.getId() + " (" + newLine.getBlockCount() + " blocks, " +
135-
(int)(overlapRatio * 100) + "% overlap)");
141+
if (isDebugEnabled()) {
142+
logger.info("Added new line " + newLine.getId() + " (" + newLine.getBlockCount() + " blocks, " + (int)(overlapRatio * 100) + "% overlap)");
143+
}
144+
136145
}
137146
}
138147

@@ -229,6 +238,13 @@ private static boolean isRailBlock(Block block) {
229238
* Lines are traced from endpoints (1 neighbor) following the path until reaching another endpoint.
230239
*/
231240
private static List<RailLine> clusterRails(World world, Set<RailBlock> allRails) {
241+
return clusterRailsWithIdGenerator(world, allRails, null);
242+
}
243+
244+
/**
245+
* Cluster rails with optional ID generator for creating unique IDs.
246+
*/
247+
private static List<RailLine> clusterRailsWithIdGenerator(World world, Set<RailBlock> allRails, java.util.function.Supplier<String> idGenerator) {
232248
List<RailLine> lines = new ArrayList<>();
233249
Set<RailBlock> visited = new HashSet<>();
234250
String[] colors = getTflColors();
@@ -353,8 +369,9 @@ private static List<RailLine> clusterRails(World world, Set<RailBlock> allRails)
353369

354370
// Create line if it has more than one block
355371
if (line.size() > 1) {
372+
String lineId = idGenerator != null ? idGenerator.get() : "tmp_" + lines.size();
356373
RailLine railLine = new RailLine(
357-
"line_" + lines.size(),
374+
lineId,
358375
colors[colorIndex % colors.length]
359376
);
360377
railLine.addBlocks(line);
@@ -378,8 +395,9 @@ private static List<RailLine> clusterRails(World world, Set<RailBlock> allRails)
378395
if (!visited.contains(rail)) {
379396
Set<RailBlock> cluster = dfsCluster(rail, neighborMap, new HashSet<>());
380397
if (!cluster.isEmpty()) {
398+
String lineId = idGenerator != null ? idGenerator.get() : "tmp_" + lines.size();
381399
RailLine railLine = new RailLine(
382-
"line_" + lines.size(),
400+
lineId,
383401
colors[colorIndex % colors.length]
384402
);
385403
railLine.addBlocks(cluster);

src/main/java/com/fabianoley/dynmaprailways/storage/RailwayDataStorage.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,35 @@ private void ensureDataFolder() {
5050
}
5151
}
5252

53+
/**
54+
* Generate a short unique hex ID for a rail line.
55+
* Starts with 3 characters and grows if needed to avoid collisions.
56+
*/
57+
public String generateLineId() {
58+
Random random = new Random();
59+
int length = 3;
60+
int maxAttempts = 100;
61+
62+
while (length <= 8) { // Max 8 characters
63+
for (int attempt = 0; attempt < maxAttempts; attempt++) {
64+
StringBuilder id = new StringBuilder();
65+
for (int i = 0; i < length; i++) {
66+
id.append(Integer.toHexString(random.nextInt(16)));
67+
}
68+
String candidate = id.toString();
69+
70+
// Check if this ID is already in use
71+
if (!railLines.containsKey(candidate)) {
72+
return candidate;
73+
}
74+
}
75+
length++; // Grow length if we couldn't find unique ID
76+
}
77+
78+
// Fallback to timestamp-based if somehow we still have collisions
79+
return Long.toHexString(System.currentTimeMillis());
80+
}
81+
5382
/**
5483
* Load all data from storage.
5584
*/
@@ -198,6 +227,23 @@ public void replaceAllRailLines(List<RailLine> newLines) throws Exception {
198227
logger.info("Replaced all rail lines. Now storing " + railLines.size() + " lines.");
199228
}
200229

230+
/**
231+
* Replace all rail lines with filtering by minimum length from config.
232+
*/
233+
public void replaceAllRailLinesFiltered(List<RailLine> newLines, int minLength) throws Exception {
234+
railLines.clear();
235+
int filtered = 0;
236+
for (RailLine line : newLines) {
237+
if (line.getBlockCount() >= minLength) {
238+
railLines.put(line.getId(), line);
239+
} else {
240+
filtered++;
241+
}
242+
}
243+
saveRailLines();
244+
logger.info("Replaced all rail lines. Now storing " + railLines.size() + " lines (filtered " + filtered + " lines below minimum length).");
245+
}
246+
201247
/**
202248
* Clear all data.
203249
*/

src/main/resources/config.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# DynmapRailways Configuration
22

3+
# General settings
4+
general:
5+
# Enable debug logging to console
6+
debug: false
7+
# Minimum number of blocks required for a line to be saved
8+
# Lines with fewer blocks will be ignored
9+
min-line-length: 15
10+
311
# CoreProtect integration settings
412
coreprotect:
513
# Enable or disable CoreProtect integration
@@ -26,7 +34,7 @@ stations:
2634
# Fill color (hex color code)
2735
fill-color: "#FFFFFF"
2836
# Fill opacity (0.0 to 1.0)
29-
fill-opacity: 0.9
37+
fill-opacity: 0.5
3038
# Border line width (in pixels)
3139
border-width: 2
3240
# Border color (hex color code)

0 commit comments

Comments
 (0)