From 62ce024dc61342a22702a605f25116dc310d1884 Mon Sep 17 00:00:00 2001 From: "Blue (Lukas Rieger)" Date: Sat, 28 Mar 2020 16:25:38 +0100 Subject: [PATCH] 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 a63a7da6..f5fb2048 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 545a7bdc..2184dd99 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 1fb04b0a..e697dd15 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); + + 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); } - try (RandomAccessFile raf = new RandomAccessFile(regionPath.toFile(), "r")) { + raf.seek(offset + 4); // +4 skip chunk size - 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; + 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