From de7b0cba0225ef8f24e63e18b528802115297301 Mon Sep 17 00:00:00 2001 From: "Blue (Lukas Rieger)" Date: Fri, 27 Mar 2020 15:41:09 +0100 Subject: [PATCH 1/3] Tentative fix for #24 --- .../bluemap/core/mca/MCAWorld.java | 73 ++++++++++++------- 1 file changed, 45 insertions(+), 28 deletions(-) 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 1217c996e..1fb04b0a8 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 @@ -218,40 +218,57 @@ private Chunk loadChunk(Vector2i chunkPos) throws IOException { Vector2i regionPos = chunkToRegion(chunkPos); Path regionPath = getMCAFilePath(regionPos); - try (RandomAccessFile raf = new RandomAccessFile(regionPath.toFile(), "r")) { + Throwable exception = null; - int xzChunk = Math.floorMod(chunkPos.getY(), 32) * 32 + Math.floorMod(chunkPos.getX(), 32); - - raf.seek(xzChunk * 4); - int offset = raf.read() << 16; - offset |= (raf.read() & 0xFF) << 8; - offset |= raf.read() & 0xFF; - offset *= 4096; - - int size = raf.readByte() * 4096; - if (size == 0) { - return Chunk.empty(this, chunkPos); + for (int tries = 1; tries <= 5; tries++) { + if (tries > 1) { + try { + Thread.sleep(200); + } catch (InterruptedException interrupt) { + throw new IOException("Interrupted while waiting for the " + tries + "th try to load a chunk.."); + } } - raf.seek(offset + 4); // +4 skip chunk size + try (RandomAccessFile raf = new RandomAccessFile(regionPath.toFile(), "r")) { - byte compressionTypeByte = raf.readByte(); - CompressionType compressionType = CompressionType.getFromID(compressionTypeByte); - if (compressionType == null) { - throw new IOException("invalid compression type " + compressionTypeByte); - } - - DataInputStream dis = new DataInputStream(new BufferedInputStream(compressionType.decompress(new FileInputStream(raf.getFD())))); - Tag tag = Tag.deserialize(dis, Tag.DEFAULT_MAX_DEPTH); - if (tag instanceof CompoundTag) { - return Chunk.create(this, (CompoundTag) tag); - } else { - throw new IOException("invalid data tag: " + (tag == null ? "null" : tag.getClass().getName())); + int xzChunk = Math.floorMod(chunkPos.getY(), 32) * 32 + Math.floorMod(chunkPos.getX(), 32); + + raf.seek(xzChunk * 4); + int offset = raf.read() << 16; + offset |= (raf.read() & 0xFF) << 8; + offset |= raf.read() & 0xFF; + offset *= 4096; + + int size = raf.readByte() * 4096; + if (size == 0) { + return Chunk.empty(this, chunkPos); + } + + raf.seek(offset + 4); // +4 skip chunk size + + byte compressionTypeByte = raf.readByte(); + CompressionType compressionType = CompressionType.getFromID(compressionTypeByte); + if (compressionType == null) { + throw new IOException("invalid compression type " + compressionTypeByte); + } + + DataInputStream dis = new DataInputStream(new BufferedInputStream(compressionType.decompress(new FileInputStream(raf.getFD())))); + Tag tag = Tag.deserialize(dis, Tag.DEFAULT_MAX_DEPTH); + if (tag instanceof CompoundTag) { + return Chunk.create(this, (CompoundTag) tag); + } else { + throw new IOException("invalid data tag: " + (tag == null ? "null" : tag.getClass().getName())); + } + + } catch (FileNotFoundException ex) { + return Chunk.empty(this, chunkPos); + } catch (Throwable ex) { + exception = ex; } - - } catch (FileNotFoundException ex) { - return Chunk.empty(this, chunkPos); } + + if (exception == null) throw new IOException("Failed to load chunk after multiple attempts!"); + throw new IOException("Failed to load chunk after multiple attempts!", exception); } @Override From 62ce024dc61342a22702a605f25116dc310d1884 Mon Sep 17 00:00:00 2001 From: "Blue (Lukas Rieger)" Date: Sat, 28 Mar 2020 16:25:38 +0100 Subject: [PATCH 2/3] Better tentative fix for #24 --- .../bluemap/common/RenderManager.java | 12 +++- .../bluemap/common/RenderTicket.java | 9 +++ .../bluemap/core/mca/MCAWorld.java | 72 +++++++------------ 3 files changed, 45 insertions(+), 48 deletions(-) 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 a63a7da65..f5fb20483 100644 --- a/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/RenderManager.java +++ b/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/RenderManager.java @@ -66,7 +66,10 @@ public void addRenderTask(RenderTask task) { } public RenderTicket createTicket(MapType mapType, Vector2i tile) { - RenderTicket ticket = new RenderTicket(mapType, tile); + return createTicket(new RenderTicket(mapType, tile)); + } + + private RenderTicket createTicket(RenderTicket ticket) { synchronized (renderTickets) { if (renderTicketMap.putIfAbsent(ticket, ticket) == null) { renderTickets.add(ticket); @@ -138,7 +141,12 @@ private void renderThread() { try { ticket.render(); } catch (IOException e) { - Logger.global.logError("Failed to render tile " + ticket.getTile() + " of map '" + ticket.getMapType().getId() + "'!", e); + if (ticket.getRenderAttempts() < 3) { + Logger.global.logDebug("Failed to render tile " + ticket.getTile() + " of map '" + ticket.getMapType().getId() + "', rescheduling for " + (ticket.getRenderAttempts() + 1) + ". attempt.."); + createTicket(ticket); //this might be a temporary issue, so we reschedule ticket for another attempt + } else { + Logger.global.logError("Failed to render tile " + ticket.getTile() + " of map '" + ticket.getMapType().getId() + "'!", e); + } } } else { try { diff --git a/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/RenderTicket.java b/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/RenderTicket.java index 545a7bdc1..2184dd99d 100644 --- a/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/RenderTicket.java +++ b/BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/RenderTicket.java @@ -10,15 +10,20 @@ public class RenderTicket { private final MapType map; private final Vector2i tile; + private int renderAttempts; private boolean finished; public RenderTicket(MapType map, Vector2i tile) { this.map = map; this.tile = tile; + + this.renderAttempts = 0; this.finished = false; } public synchronized void render() throws IOException { + renderAttempts++; + if (!finished) { map.renderTile(tile); @@ -34,6 +39,10 @@ public Vector2i getTile() { return tile; } + public int getRenderAttempts() { + return renderAttempts; + } + public boolean isFinished() { return finished; } 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 1fb04b0a8..e697dd154 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 @@ -217,58 +217,38 @@ public Chunk getChunk(Vector2i chunkPos) throws IOException { private Chunk loadChunk(Vector2i chunkPos) throws IOException { Vector2i regionPos = chunkToRegion(chunkPos); Path regionPath = getMCAFilePath(regionPos); + + try (RandomAccessFile raf = new RandomAccessFile(regionPath.toFile(), "r")) { - Throwable exception = null; - - for (int tries = 1; tries <= 5; tries++) { - if (tries > 1) { - try { - Thread.sleep(200); - } catch (InterruptedException interrupt) { - throw new IOException("Interrupted while waiting for the " + tries + "th try to load a chunk.."); - } - } + int xzChunk = Math.floorMod(chunkPos.getY(), 32) * 32 + Math.floorMod(chunkPos.getX(), 32); - try (RandomAccessFile raf = new RandomAccessFile(regionPath.toFile(), "r")) { + raf.seek(xzChunk * 4); + int offset = raf.read() << 16; + offset |= (raf.read() & 0xFF) << 8; + offset |= raf.read() & 0xFF; + offset *= 4096; - int xzChunk = Math.floorMod(chunkPos.getY(), 32) * 32 + Math.floorMod(chunkPos.getX(), 32); - - raf.seek(xzChunk * 4); - int offset = raf.read() << 16; - offset |= (raf.read() & 0xFF) << 8; - offset |= raf.read() & 0xFF; - offset *= 4096; - - int size = raf.readByte() * 4096; - if (size == 0) { - return Chunk.empty(this, chunkPos); - } - - raf.seek(offset + 4); // +4 skip chunk size - - byte compressionTypeByte = raf.readByte(); - CompressionType compressionType = CompressionType.getFromID(compressionTypeByte); - if (compressionType == null) { - throw new IOException("invalid compression type " + compressionTypeByte); - } - - DataInputStream dis = new DataInputStream(new BufferedInputStream(compressionType.decompress(new FileInputStream(raf.getFD())))); - Tag tag = Tag.deserialize(dis, Tag.DEFAULT_MAX_DEPTH); - if (tag instanceof CompoundTag) { - return Chunk.create(this, (CompoundTag) tag); - } else { - throw new IOException("invalid data tag: " + (tag == null ? "null" : tag.getClass().getName())); - } - - } catch (FileNotFoundException ex) { + int size = raf.readByte() * 4096; + if (size == 0) { return Chunk.empty(this, chunkPos); - } catch (Throwable ex) { - exception = ex; + } + + raf.seek(offset + 4); // +4 skip chunk size + + byte compressionTypeByte = raf.readByte(); + CompressionType compressionType = CompressionType.getFromID(compressionTypeByte); + if (compressionType == null) { + throw new IOException("invalid compression type " + compressionTypeByte); + } + + DataInputStream dis = new DataInputStream(new BufferedInputStream(compressionType.decompress(new FileInputStream(raf.getFD())))); + Tag tag = Tag.deserialize(dis, Tag.DEFAULT_MAX_DEPTH); + if (tag instanceof CompoundTag) { + return Chunk.create(this, (CompoundTag) tag); + } else { + throw new IOException("invalid data tag: " + (tag == null ? "null" : tag.getClass().getName())); } } - - if (exception == null) throw new IOException("Failed to load chunk after multiple attempts!"); - throw new IOException("Failed to load chunk after multiple attempts!", exception); } @Override From de8031effd23c9f7f02a9a058702c84f75cced27 Mon Sep 17 00:00:00 2001 From: "Blue (Lukas Rieger)" Date: Sun, 29 Mar 2020 11:47:37 +0200 Subject: [PATCH 3/3] Push version for next release --- BlueMapBukkit/src/main/resources/plugin.yml | 2 +- BlueMapCommon/src/main/resources/mcmod.info | 2 +- .../src/main/java/de/bluecolored/bluemap/core/BlueMap.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/BlueMapBukkit/src/main/resources/plugin.yml b/BlueMapBukkit/src/main/resources/plugin.yml index 97e9f9c1d..5b985d3d9 100644 --- a/BlueMapBukkit/src/main/resources/plugin.yml +++ b/BlueMapBukkit/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ name: BlueMap description: "A 3d-map of your Minecraft worlds view-able in your browser using three.js (WebGL)" main: de.bluecolored.bluemap.bukkit.BukkitPlugin -version: 0.5.0-mc1.13 +version: 0.5.1-mc1.13 author: "Blue (TBlueF / Lukas Rieger)" authors: [Blue (TBlueF / Lukas Rieger)] website: "https://github.com/BlueMap-Minecraft" diff --git a/BlueMapCommon/src/main/resources/mcmod.info b/BlueMapCommon/src/main/resources/mcmod.info index 2912edd81..c90767642 100644 --- a/BlueMapCommon/src/main/resources/mcmod.info +++ b/BlueMapCommon/src/main/resources/mcmod.info @@ -2,7 +2,7 @@ { "modid": "bluemap", "name": "BlueMap", - "version": "0.5.0-mc1.13", + "version": "0.5.1-mc1.13", "description": "A 3d-map of your Minecraft worlds view-able in your browser using three.js (WebGL)", "url": "https://github.com/BlueMap-Minecraft", "authorList": [ diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/BlueMap.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/BlueMap.java index 7c9fbf1de..002156168 100644 --- a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/BlueMap.java +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/BlueMap.java @@ -2,6 +2,6 @@ public class BlueMap { - public static final String VERSION = "0.5.0-mc1.13"; + public static final String VERSION = "0.5.1-mc1.13"; }