diff --git a/BlueMapBukkit/build.gradle b/BlueMapBukkit/build.gradle index d4b1f7a0..deb7fc75 100644 --- a/BlueMapBukkit/build.gradle +++ b/BlueMapBukkit/build.gradle @@ -10,7 +10,8 @@ repositories { dependencies { shadow "org.spigotmc:spigot-api:1.16.2-R0.1-SNAPSHOT" - compile group: 'org.bstats', name: 'bstats-bukkit-lite', version: '1.5' + + compile group: 'org.bstats', name: 'bstats-bukkit-lite', version: '1.7' compile (project(':BlueMapCommon')) { //exclude dependencies provided by bukkit diff --git a/BlueMapBukkit/src/main/java/de/bluecolored/bluemap/bukkit/BukkitCommands.java b/BlueMapBukkit/src/main/java/de/bluecolored/bluemap/bukkit/BukkitCommands.java index 8779020e..506300f1 100644 --- a/BlueMapBukkit/src/main/java/de/bluecolored/bluemap/bukkit/BukkitCommands.java +++ b/BlueMapBukkit/src/main/java/de/bluecolored/bluemap/bukkit/BukkitCommands.java @@ -86,7 +86,9 @@ public void onTabComplete(TabCompleteEvent evt) { completions.sort((s1, s2) -> s1.compareToIgnoreCase(s2)); evt.setCompletions(completions); } - } catch (InterruptedException | ExecutionException | TimeoutException ignore) {} + } catch (InterruptedException ignore) { + Thread.currentThread().interrupt(); + } catch (ExecutionException | TimeoutException ignore) {} } private class CommandProxy extends BukkitCommand { diff --git a/BlueMapBukkit/src/main/java/de/bluecolored/bluemap/bukkit/BukkitPlugin.java b/BlueMapBukkit/src/main/java/de/bluecolored/bluemap/bukkit/BukkitPlugin.java index b51cff4b..a1192da2 100644 --- a/BlueMapBukkit/src/main/java/de/bluecolored/bluemap/bukkit/BukkitPlugin.java +++ b/BlueMapBukkit/src/main/java/de/bluecolored/bluemap/bukkit/BukkitPlugin.java @@ -56,12 +56,13 @@ import de.bluecolored.bluemap.common.plugin.serverinterface.ServerEventListener; import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface; import de.bluecolored.bluemap.core.logger.Logger; +import de.bluecolored.bluemap.core.resourcepack.ParseResourceException; public class BukkitPlugin extends JavaPlugin implements ServerInterface, Listener { private static BukkitPlugin instance; - private Plugin bluemap; + private Plugin pluginInstance; private EventForwarder eventForwarder; private BukkitCommands commands; @@ -76,15 +77,15 @@ public BukkitPlugin() { this.onlinePlayerList = Collections.synchronizedList(new ArrayList<>()); this.eventForwarder = new EventForwarder(); - this.bluemap = new Plugin("bukkit", this); - this.commands = new BukkitCommands(this.bluemap); + this.pluginInstance = new Plugin("bukkit", this); + this.commands = new BukkitCommands(this.pluginInstance); BukkitPlugin.instance = this; } @Override public void onEnable() { - new MetricsLite(this); + new MetricsLite(this, 5912); //save world so the level.dat is present on new worlds Logger.global.logInfo("Saving all worlds once, to make sure the level.dat is present..."); @@ -113,6 +114,15 @@ public void onEnable() { //tab completions getServer().getPluginManager().registerEvents(commands, this); + //update online-player collections + this.onlinePlayerList.clear(); + this.onlinePlayerMap.clear(); + for (org.bukkit.entity.Player player : getServer().getOnlinePlayers()) { + BukkitPlayer bukkitPlayer = new BukkitPlayer(player); + onlinePlayerMap.put(player.getUniqueId(), bukkitPlayer); + onlinePlayerList.add(bukkitPlayer); + } + //start updating players getServer().getScheduler().runTaskTimer(this, this::updateSomePlayers, 1, 1); @@ -120,10 +130,11 @@ public void onEnable() { getServer().getScheduler().runTaskAsynchronously(this, () -> { try { Logger.global.logInfo("Loading..."); - this.bluemap.load(); - if (bluemap.isLoaded()) Logger.global.logInfo("Loaded!"); - } catch (Throwable t) { - Logger.global.logError("Failed to load!", t); + this.pluginInstance.load(); + if (pluginInstance.isLoaded()) Logger.global.logInfo("Loaded!"); + } catch (IOException | ParseResourceException | RuntimeException e) { + Logger.global.logError("Failed to load!", e); + this.pluginInstance.unload(); } }); } @@ -132,7 +143,7 @@ public void onEnable() { public void onDisable() { Logger.global.logInfo("Stopping..."); getServer().getScheduler().cancelTasks(this); - bluemap.unload(); + pluginInstance.unload(); Logger.global.logInfo("Saved and stopped!"); } @@ -165,6 +176,7 @@ public UUID getUUIDForWorld(File worldFolder) throws IOException { try { return futureUUID.get(); } catch (InterruptedException e) { + Thread.currentThread().interrupt(); throw new IOException(e); } catch (ExecutionException e) { if (e.getCause() instanceof IOException) { @@ -197,7 +209,7 @@ public File getConfigFolder() { } public Plugin getBlueMap() { - return bluemap; + return pluginInstance; } public static BukkitPlugin getInstance() { diff --git a/BlueMapCLI/src/main/java/de/bluecolored/bluemap/cli/BlueMapCLI.java b/BlueMapCLI/src/main/java/de/bluecolored/bluemap/cli/BlueMapCLI.java index d3d9f5a4..6d66cac3 100644 --- a/BlueMapCLI/src/main/java/de/bluecolored/bluemap/cli/BlueMapCLI.java +++ b/BlueMapCLI/src/main/java/de/bluecolored/bluemap/cli/BlueMapCLI.java @@ -222,7 +222,7 @@ public void renderMaps() throws IOException { while(renderManager.getRenderTaskCount() != 0) { try { Thread.sleep(200); - } catch (InterruptedException e) {} + } catch (InterruptedException e) { Thread.currentThread().interrupt(); return; } long now = System.currentTimeMillis(); @@ -390,7 +390,7 @@ public static void main(String[] args) throws IOException, ParseResourceExceptio //wait a second to let the webserver start, looks nicer in the log try { Thread.sleep(1000); - } catch (InterruptedException ignore) {} + } catch (InterruptedException ignore) { Thread.currentThread().interrupt(); } } @@ -452,7 +452,7 @@ private static void printHelp() { filename = file.getAbsolutePath(); } } - } catch (Exception ex) {} + } catch (IOException ex) {} String command = "java -jar " + filename; diff --git a/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/RenderManager.java b/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/RenderManager.java index 31c884c7..f391238d 100644 --- a/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/RenderManager.java +++ b/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/RenderManager.java @@ -75,7 +75,6 @@ public synchronized void stop() { for (int i = 0; i < renderThreads.length; i++) { if (renderThreads[i] != null) { renderThreads[i].interrupt(); - renderThreads[i] = null; } } @@ -141,7 +140,7 @@ public boolean removeRenderTask(RenderTask renderTask) { private void renderThread() { RenderTicket ticket = null; - while (!Thread.interrupted() && running) { + while (running) { synchronized (renderTickets) { ticket = renderTickets.poll(); if (ticket != null) renderTicketMap.remove(ticket); @@ -163,17 +162,22 @@ private void renderThread() { if (ticket != null) { try { ticket.render(); - } catch (Exception e) { + } catch (RuntimeException e) { //catch possible runtime exceptions, display them, and wait a while .. then resurrect this render-thread Logger.global.logError("Unexpected exception in render-thread!", e); try { Thread.sleep(10000); - } catch (InterruptedException interrupt) { break; } + } catch (InterruptedException interrupt) { Thread.currentThread().interrupt(); break; } } } else { try { Thread.sleep(1000); // we don't need a super fast response time, so waiting a second is totally fine - } catch (InterruptedException interrupt) { break; } + } catch (InterruptedException interrupt) { Thread.currentThread().interrupt(); break; } + } + + if (Thread.interrupted()) { + Thread.currentThread().interrupt(); + break; } } } diff --git a/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/plugin/MapUpdateHandler.java b/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/plugin/MapUpdateHandler.java index ac69cd1a..e7bfe570 100644 --- a/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/plugin/MapUpdateHandler.java +++ b/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/plugin/MapUpdateHandler.java @@ -66,7 +66,7 @@ public void onWorldSaveToDisk(final UUID world) { } } - } catch (InterruptedException ignore) {} + } catch (InterruptedException ignore) { Thread.currentThread().interrupt(); } }).start(); } diff --git a/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/plugin/Plugin.java b/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/plugin/Plugin.java index 4c99bdac..8d823c27 100644 --- a/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/plugin/Plugin.java +++ b/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/plugin/Plugin.java @@ -262,6 +262,7 @@ public synchronized void load() throws IOException, ParseResourceException { } } } catch (InterruptedException ex){ + Thread.currentThread().interrupt(); return; } }); @@ -316,6 +317,7 @@ public synchronized void load() throws IOException, ParseResourceException { Thread.sleep(TimeUnit.MINUTES.toMillis(30)); } } catch (InterruptedException ex){ + Thread.currentThread().interrupt(); return; } }); @@ -339,9 +341,13 @@ public synchronized void unload() { //stop scheduled threads if (metricsThread != null) metricsThread.interrupt(); + try {metricsThread.join(1000);} catch (InterruptedException ignore) { Thread.currentThread().interrupt(); } + if (metricsThread.isAlive()) Logger.global.logWarning("The metricsThread did not terminate correctly in time!"); metricsThread = null; if (periodicalSaveThread != null) periodicalSaveThread.interrupt(); + try {periodicalSaveThread.join(1000);} catch (InterruptedException ignore) { Thread.currentThread().interrupt(); } + if (periodicalSaveThread.isAlive()) Logger.global.logWarning("The periodicalSaveThread did not terminate correctly in time!"); periodicalSaveThread = null; //stop services diff --git a/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/plugin/commands/Commands.java b/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/plugin/commands/Commands.java index b32ea461..65169787 100644 --- a/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/plugin/commands/Commands.java +++ b/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/plugin/commands/Commands.java @@ -60,6 +60,7 @@ import de.bluecolored.bluemap.core.mca.Chunk; import de.bluecolored.bluemap.core.mca.ChunkAnvil112; import de.bluecolored.bluemap.core.mca.MCAWorld; +import de.bluecolored.bluemap.core.resourcepack.ParseResourceException; import de.bluecolored.bluemap.core.world.Block; import de.bluecolored.bluemap.core.world.World; @@ -307,7 +308,7 @@ public int reloadCommand(CommandContext context) { source.sendMessage(Text.of(TextColor.RED, "Could not load BlueMap! See the console for details!")); } - } catch (Exception ex) { + } catch (IOException | ParseResourceException | RuntimeException ex) { Logger.global.logError("Failed to reload BlueMap!", ex); source.sendMessage(Text.of(TextColor.RED, "There was an error reloading BlueMap! See the console for details!")); diff --git a/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/plugin/skins/PlayerSkin.java b/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/plugin/skins/PlayerSkin.java index a0b7bd99..52412125 100644 --- a/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/plugin/skins/PlayerSkin.java +++ b/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/plugin/skins/PlayerSkin.java @@ -73,7 +73,7 @@ public void update(File storageFolder) { Logger.global.logDebug("Failed to load player-skin from mojang-servers: " + e); } catch (IOException e) { Logger.global.logError("Failed to write player-head image!", e); - } catch (InterruptedException ignore) {} + } catch (InterruptedException ignore) { Thread.currentThread().interrupt(); } }).start(); } @@ -87,7 +87,7 @@ public BufferedImage createHead(BufferedImage skinTexture) { Graphics2D g = head.createGraphics(); g.drawImage(layer1, 0, 0, null); g.drawImage(layer2, 0, 0, null); - } catch (Throwable t) { // There might be problems with headless servers when loading the graphics class + } catch (Throwable t) { // There might be problems with headless servers when loading the graphics class, so we catch every exception and error on purpose here Logger.global.noFloodWarning("headless-graphics-fail", "Could not access Graphics2D to render player-skin texture. Try adding '-Djava.awt.headless=true' to your startup flags or ignore this warning."); diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/MCAWorld.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/MCAWorld.java index bbf95e66..200793f1 100644 --- a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/MCAWorld.java +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/MCAWorld.java @@ -142,15 +142,9 @@ private MCAWorld( } public BlockState getBlockState(Vector3i pos) { - try { - - Vector2i chunkPos = blockToChunk(pos); - Chunk chunk = getChunk(chunkPos); - return chunk.getBlockState(pos); - - } catch (Exception ex) { - return BlockState.MISSING; - } + Vector2i chunkPos = blockToChunk(pos); + Chunk chunk = getChunk(chunkPos); + return chunk.getBlockState(pos); } @Override @@ -200,22 +194,22 @@ public Chunk getChunk(Vector2i chunkPos) { Chunk chunk = CHUNK_CACHE.get(new WorldChunkHash(this, chunkPos), () -> this.loadChunkOrEmpty(chunkPos, 2, 1000)); return chunk; } catch (UncheckedExecutionException | ExecutionException e) { + if (e.getCause() instanceof InterruptedException) Thread.currentThread().interrupt(); throw new RuntimeException(e.getCause()); } } - private Chunk loadChunkOrEmpty(Vector2i chunkPos, int tries, long tryInterval) { + private Chunk loadChunkOrEmpty(Vector2i chunkPos, int tries, long tryInterval) throws InterruptedException { Exception loadException = null; for (int i = 0; i < tries; i++) { try { return loadChunk(chunkPos); - } catch (Exception e) { + } catch (IOException | RuntimeException e) { + if (loadException != null) e.addSuppressed(loadException); loadException = e; if (tryInterval > 0 && i+1 < tries) { - try { - Thread.sleep(tryInterval); - } catch (InterruptedException interrupt) {} + Thread.sleep(tryInterval); } } } @@ -261,7 +255,7 @@ private Chunk loadChunk(Vector2i chunkPos) throws IOException { } else { throw new IOException("Invalid data tag: " + (tag == null ? "null" : tag.getClass().getName())); } - } catch (Exception e) { + } catch (RuntimeException | IOException e) { throw new IOException("Exception trying to load chunk (" + chunkPos + ")", e); } } @@ -312,7 +306,7 @@ public Collection getChunkList(long modifiedSinceMillis, Predicate * (Do not use this method to sync file-access from different threads!) */ - public static void waitForFile(File file, long time, TimeUnit unit) throws InterruptedException { + public static void waitForFile(File file, long time, TimeUnit unit) throws InterruptedException, TimeoutException { long start = System.currentTimeMillis(); long timeout = start + TimeUnit.MILLISECONDS.convert(time, unit); long sleepTime = 1; while(!file.canWrite() || !file.canRead()){ Thread.sleep(sleepTime); sleepTime = (long) Math.min(Math.ceil(sleepTime * 1.5), 1000); - if (System.currentTimeMillis() > timeout) throw new InterruptedException(); + if (System.currentTimeMillis() > timeout) throw new TimeoutException(); } } diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/world/BlockState.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/world/BlockState.java index 9c901969..ac829d51 100644 --- a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/world/BlockState.java +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/world/BlockState.java @@ -183,7 +183,7 @@ public static BlockState fromString(String serializedBlockState) throws IllegalA String blockId = m.group(1).trim(); return new BlockState(blockId, pt); - } catch (Exception ex) { + } catch (RuntimeException ex) { throw new IllegalArgumentException("'" + serializedBlockState + "' could not be parsed to a BlockState!"); } } diff --git a/BlueMapCore/src/main/webroot/js/libs/BlueMap.js b/BlueMapCore/src/main/webroot/js/libs/BlueMap.js index d91d423b..d5d13c20 100644 --- a/BlueMapCore/src/main/webroot/js/libs/BlueMap.js +++ b/BlueMapCore/src/main/webroot/js/libs/BlueMap.js @@ -206,18 +206,16 @@ export default class BlueMap { this.controls.direction = this.controls.targetDirection; this.controls.distance = this.controls.targetDistance; this.controls.angle = this.controls.targetAngle; - this.controls.targetPosition.y = this.controls.minHeight; this.controls.position.copy(this.controls.targetPosition); } } if (hashVars.length >= 7){ let height = parseInt(hashVars[6]); if (!isNaN(height)){ - this.controls.minHeight = height; - this.controls.targetPosition.y = height; + this.controls.terrainHeight = height; if (!smooth) { - this.controls.position.copy(this.controls.targetPosition); + if (this.controls.position.y < this.controls.terrainHeight) this.controls.position.y = this.controls.terrainHeight; } } } @@ -257,7 +255,7 @@ export default class BlueMap { + ':' + Math.round(this.controls.targetDirection * 100) / 100 + ':' + Math.round(this.controls.targetDistance * 100) / 100 + ':' + Math.ceil(this.controls.targetAngle * 100) / 100 - + ':' + Math.floor(this.controls.targetPosition.y); + + ':' + Math.floor(this.controls.terrainHeight); // only update hash when changed if (window.location.hash !== this.locationHash) { history.replaceState(undefined, undefined, this.locationHash); diff --git a/BlueMapCore/src/main/webroot/js/libs/Controls.js b/BlueMapCore/src/main/webroot/js/libs/Controls.js index 2ec7b679..c17574ec 100644 --- a/BlueMapCore/src/main/webroot/js/libs/Controls.js +++ b/BlueMapCore/src/main/webroot/js/libs/Controls.js @@ -79,7 +79,7 @@ export default class Controls { this.camera = camera; this.element = element; this.heightScene = heightScene; - this.minHeight = 0; + this.terrainHeight = 70; this.raycaster = new Raycaster(); this.rayDirection = new Vector3(0, -1, 0); @@ -159,8 +159,8 @@ export default class Controls { } resetPosition() { - this.position = new Vector3(0, 70, 0); - this.targetPosition = new Vector3(0, 70, 0); + this.position = new Vector3(0, 0, 0); + this.targetPosition = new Vector3(0, 0, 0); this.distance = 5000; this.targetDistance = 1000; @@ -177,13 +177,10 @@ export default class Controls { let changed = false; - let zoomLerp = (this.distance - 100) / 200; - if (zoomLerp < 0) zoomLerp = 0; - if (zoomLerp > 1) zoomLerp = 1; - this.targetPosition.y = 300 * zoomLerp + this.minHeight * (1 - zoomLerp); + let targetY = Math.max(this.targetPosition.y, this.terrainHeight); this.position.x += (this.targetPosition.x - this.position.x) * this.settings.move.smooth; - this.position.y += (this.targetPosition.y - this.position.y) * this.settings.move.smoothY; + this.position.y += (targetY - this.position.y) * this.settings.move.smoothY; this.position.z += (this.targetPosition.z - this.position.z) * this.settings.move.smooth; this.distance += (this.targetDistance - this.distance) * this.settings.zoom.smooth; @@ -241,7 +238,7 @@ export default class Controls { let intersects = this.raycaster.intersectObjects(tileChildren(this.targetPosition)); if (intersects.length > 0) { - this.minHeight = intersects[0].point.y; + this.terrainHeight = intersects[0].point.y; } } catch (ignore){} @@ -251,8 +248,8 @@ export default class Controls { this.raycaster.set(rayStart, this.rayDirection); let intersects = this.raycaster.intersectObjects(tileChildren(this.camera.position)); if (intersects.length > 0) { - if (intersects[0].point.y > this.minHeight) { - this.minHeight = intersects[0].point.y; + if (intersects[0].point.y > this.terrainHeight) { + this.terrainHeight = intersects[0].point.y; } } } catch (ignore){} diff --git a/BlueMapCore/src/main/webroot/js/libs/hud/PlayerMarker.js b/BlueMapCore/src/main/webroot/js/libs/hud/PlayerMarker.js index 2022c793..38d189bc 100644 --- a/BlueMapCore/src/main/webroot/js/libs/hud/PlayerMarker.js +++ b/BlueMapCore/src/main/webroot/js/libs/hud/PlayerMarker.js @@ -27,7 +27,7 @@ export default class PlayerMarker extends Marker { if (!this.renderObject){ this.iconElement = $(`
${this.label}
`); this.iconElement.find("img").click(this.onClick); - $(window).on('mousedown touchstart', this.onStopFollowing); + $(window).on('mousedown touchstart', this.onUserInput); this.renderObject = new CSS2DObject(this.iconElement[0]); this.renderObject.position.copy(this.position); @@ -47,6 +47,12 @@ export default class PlayerMarker extends Marker { this.blueMap.hudScene.add(this.renderObject); } else { this.blueMap.hudScene.remove(this.renderObject); + + if (this.follow) { + this.follow = false; + this.iconElement.removeClass("following"); + this.blueMap.controls.targetPosition.y = 0; + } } } @@ -62,8 +68,7 @@ export default class PlayerMarker extends Marker { } if (this.follow){ - this.blueMap.controls.targetPosition.x = this.position.x; - this.blueMap.controls.targetPosition.z = this.position.z; + this.blueMap.controls.targetPosition.copy(this.position); } } }; @@ -97,14 +102,14 @@ export default class PlayerMarker extends Marker { this.follow = true; this.iconElement.addClass("following"); - this.blueMap.controls.targetPosition.x = this.position.x; - this.blueMap.controls.targetPosition.z = this.position.z; + this.blueMap.controls.targetPosition.copy(this.position); }; - onStopFollowing = event => { - if(this.follow) { - this.follow = true; + onUserInput = e => { + if ((e.type !== "mousedown" || e.button === 0) && this.follow) { + this.follow = false; this.iconElement.removeClass("following"); + this.blueMap.controls.targetPosition.y = 0; } }; diff --git a/BlueMapCore/src/main/webroot/js/libs/hud/PlayerMarkerSet.js b/BlueMapCore/src/main/webroot/js/libs/hud/PlayerMarkerSet.js index 073c9139..43fcedb7 100644 --- a/BlueMapCore/src/main/webroot/js/libs/hud/PlayerMarkerSet.js +++ b/BlueMapCore/src/main/webroot/js/libs/hud/PlayerMarkerSet.js @@ -42,8 +42,11 @@ export default class PlayerMarkerSet { ); }).then((liveData) => { this.updateWith(liveData) - }).catch((e) => { - console.error("Failed to update player-markers!", e); + }).catch(() => { + this.marker.forEach(marker => { + marker.online = false; + marker.setVisible(false); + }); }); } diff --git a/BlueMapFabric/src/main/java/de/bluecolored/bluemap/fabric/FabricMod.java b/BlueMapFabric/src/main/java/de/bluecolored/bluemap/fabric/FabricMod.java index 1d8d03d7..02d91712 100644 --- a/BlueMapFabric/src/main/java/de/bluecolored/bluemap/fabric/FabricMod.java +++ b/BlueMapFabric/src/main/java/de/bluecolored/bluemap/fabric/FabricMod.java @@ -114,6 +114,7 @@ public void onInitialize() { if (pluginInstance.isLoaded()) Logger.global.logInfo("BlueMap loaded!"); } catch (IOException | ParseResourceException e) { Logger.global.logError("Failed to load bluemap!", e); + pluginInstance.unload(); } }).start(); }); diff --git a/BlueMapForge/src/main/java/de/bluecolored/bluemap/forge/ForgeMod.java b/BlueMapForge/src/main/java/de/bluecolored/bluemap/forge/ForgeMod.java index 8af0bd47..dc7c674a 100644 --- a/BlueMapForge/src/main/java/de/bluecolored/bluemap/forge/ForgeMod.java +++ b/BlueMapForge/src/main/java/de/bluecolored/bluemap/forge/ForgeMod.java @@ -116,6 +116,7 @@ public void onServerStarting(FMLServerStartingEvent event) { if (pluginInstance.isLoaded()) Logger.global.logInfo("Loaded!"); } catch (IOException | ParseResourceException e) { Logger.global.logError("Failed to load bluemap!", e); + pluginInstance.unload(); } }).start(); } diff --git a/BlueMapSponge/build.gradle b/BlueMapSponge/build.gradle index b5481d12..9b3c1001 100644 --- a/BlueMapSponge/build.gradle +++ b/BlueMapSponge/build.gradle @@ -1,6 +1,7 @@ dependencies { shadow "org.spongepowered:spongeapi:7.2.0" - compile group: 'org.bstats', name: 'bstats-sponge-lite', version: '1.5' + + compile group: 'org.bstats', name: 'bstats-sponge-lite', version: '1.7' compile (project(':BlueMapCommon')) { //exclude dependencies provided by sponge diff --git a/BlueMapSponge/src/main/java/de/bluecolored/bluemap/sponge/SpongeCommands.java b/BlueMapSponge/src/main/java/de/bluecolored/bluemap/sponge/SpongeCommands.java index bd19b154..e9dc4bf8 100644 --- a/BlueMapSponge/src/main/java/de/bluecolored/bluemap/sponge/SpongeCommands.java +++ b/BlueMapSponge/src/main/java/de/bluecolored/bluemap/sponge/SpongeCommands.java @@ -116,7 +116,9 @@ public List getSuggestions(CommandSource source, String arguments, Locat completions.add(text); } } - } catch (InterruptedException | ExecutionException | TimeoutException ignore) {} + } catch (InterruptedException ignore) { + Thread.currentThread().interrupt(); + } catch (ExecutionException | TimeoutException ignore) {} completions.sort((s1, s2) -> s1.compareToIgnoreCase(s2)); return completions; diff --git a/BlueMapSponge/src/main/java/de/bluecolored/bluemap/sponge/SpongePlugin.java b/BlueMapSponge/src/main/java/de/bluecolored/bluemap/sponge/SpongePlugin.java index 832e51a7..10c9e43d 100644 --- a/BlueMapSponge/src/main/java/de/bluecolored/bluemap/sponge/SpongePlugin.java +++ b/BlueMapSponge/src/main/java/de/bluecolored/bluemap/sponge/SpongePlugin.java @@ -58,6 +58,7 @@ import de.bluecolored.bluemap.common.plugin.serverinterface.ServerEventListener; import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface; import de.bluecolored.bluemap.core.logger.Logger; +import de.bluecolored.bluemap.core.resourcepack.ParseResourceException; import de.bluecolored.bluemap.sponge.SpongeCommands.SpongeCommandProxy; import net.querz.nbt.CompoundTag; import net.querz.nbt.NBTUtil; @@ -74,11 +75,7 @@ public class SpongePlugin implements ServerInterface { @ConfigDir(sharedRoot = false) private Path configurationDir; - @SuppressWarnings("unused") - @Inject - private MetricsLite2 metrics; - - private Plugin bluemap; + private Plugin pluginInstance; private SpongeCommands commands; private SpongeExecutorService asyncExecutor; @@ -88,14 +85,17 @@ public class SpongePlugin implements ServerInterface { private List onlinePlayerList; @Inject - public SpongePlugin(org.slf4j.Logger logger) { + public SpongePlugin(org.slf4j.Logger logger, MetricsLite2.Factory bstatsFactory) { Logger.global = new Slf4jLogger(logger); this.onlinePlayerMap = new ConcurrentHashMap<>(); this.onlinePlayerList = Collections.synchronizedList(new ArrayList<>()); - this.bluemap = new Plugin("sponge", this); - this.commands = new SpongeCommands(bluemap); + this.pluginInstance = new Plugin("sponge", this); + this.commands = new SpongeCommands(pluginInstance); + + //init bstats metrics + bstatsFactory.make(5911); } @Listener @@ -121,10 +121,11 @@ public void onServerStart(GameStartingServerEvent evt) { asyncExecutor.execute(() -> { try { Logger.global.logInfo("Loading..."); - bluemap.load(); - if (bluemap.isLoaded()) Logger.global.logInfo("Loaded!"); - } catch (Throwable t) { - Logger.global.logError("Failed to load!", t); + pluginInstance.load(); + if (pluginInstance.isLoaded()) Logger.global.logInfo("Loaded!"); + } catch (IOException | ParseResourceException | RuntimeException e) { + Logger.global.logError("Failed to load!", e); + pluginInstance.unload(); } }); } @@ -133,7 +134,7 @@ public void onServerStart(GameStartingServerEvent evt) { public void onServerStop(GameStoppingEvent evt) { Logger.global.logInfo("Stopping..."); Sponge.getScheduler().getScheduledTasks(this).forEach(t -> t.cancel()); - bluemap.unload(); + pluginInstance.unload(); Logger.global.logInfo("Saved and stopped!"); } @@ -142,15 +143,15 @@ public void onServerReload(GameReloadEvent evt) { asyncExecutor.execute(() -> { try { Logger.global.logInfo("Reloading..."); - bluemap.reload(); + pluginInstance.reload(); Logger.global.logInfo("Reloaded!"); - } catch (Exception e) { + } catch (IOException | ParseResourceException | RuntimeException e) { Logger.global.logError("Failed to load!", e); + pluginInstance.unload(); } }); } - @Listener public void onPlayerJoin(ClientConnectionEvent.Join evt) { SpongePlayer player = new SpongePlayer(evt.getTargetEntity()); @@ -186,8 +187,8 @@ public UUID getUUIDForWorld(File worldFolder) throws IOException { long most = spongeData.getLong("UUIDMost"); long least = spongeData.getLong("UUIDLeast"); return new UUID(most, least); - } catch (Throwable t) { - throw new IOException("Failed to read level_sponge.dat", t); + } catch (IOException | RuntimeException e) { + throw new IOException("Failed to read level_sponge.dat", e); } } diff --git a/logs/latest.log b/logs/latest.log new file mode 100644 index 00000000..e69de29b