mirror of
https://github.com/BlueMap-Minecraft/BlueMap.git
synced 2024-12-28 11:59:21 +01:00
Fix players not shown after spigot reload and tidy up a lot of exception-handling
This commit is contained in:
parent
3960869f15
commit
c63ec971d6
@ -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 {
|
||||
|
@ -56,6 +56,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;
|
||||
|
||||
public class BukkitPlugin extends JavaPlugin implements ServerInterface, Listener {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -122,8 +132,9 @@ public void onEnable() {
|
||||
Logger.global.logInfo("Loading...");
|
||||
this.bluemap.load();
|
||||
if (bluemap.isLoaded()) Logger.global.logInfo("Loaded!");
|
||||
} catch (Throwable t) {
|
||||
Logger.global.logError("Failed to load!", t);
|
||||
} catch (IOException | ParseResourceException | RuntimeException e) {
|
||||
Logger.global.logError("Failed to load!", e);
|
||||
this.bluemap.unload();
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ public void onWorldSaveToDisk(final UUID world) {
|
||||
}
|
||||
|
||||
}
|
||||
} catch (InterruptedException ignore) {}
|
||||
} catch (InterruptedException ignore) { Thread.currentThread().interrupt(); }
|
||||
|
||||
}).start();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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<S> 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!"));
|
||||
|
@ -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.");
|
||||
|
||||
|
@ -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<Vector2i> getChunkList(long modifiedSinceMillis, Predicate<Vec
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
} catch (RuntimeException | IOException ex) {
|
||||
Logger.global.logWarning("Failed to read .mca file: " + file.getAbsolutePath() + " (" + ex.toString() + ")");
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,7 @@
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import de.bluecolored.bluemap.core.BlueMap;
|
||||
import de.bluecolored.bluemap.core.logger.Logger;
|
||||
|
||||
public class Metrics {
|
||||
|
||||
@ -53,7 +54,9 @@ public static void sendReport(String implementation) {
|
||||
|
||||
try {
|
||||
sendData(data.toString());
|
||||
} catch (Exception ex) {}
|
||||
} catch (IOException | RuntimeException ex) {
|
||||
Logger.global.logDebug("Failed to send Metrics-Report: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static String sendData(String data) throws MalformedURLException, IOException {
|
||||
|
@ -37,6 +37,7 @@
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import com.flowpowered.math.vector.Vector2i;
|
||||
@ -116,6 +117,9 @@ public void save(File file, boolean force, boolean useGzip) throws IOException {
|
||||
try {
|
||||
FileUtils.waitForFile(file, 10, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new IOException("Failed to get write-access to file: " + file, e);
|
||||
} catch (TimeoutException e) {
|
||||
throw new IOException("Failed to get write-access to file: " + file, e);
|
||||
}
|
||||
|
||||
|
@ -189,8 +189,8 @@ public BlockStateResource build(String blockstateFile) throws IOException {
|
||||
variant.checkValid();
|
||||
|
||||
blockState.variants.add(variant);
|
||||
} catch (Throwable t) {
|
||||
Logger.global.logWarning("Failed to parse a variant of " + blockstateFile + ": " + t);
|
||||
} catch (ParseResourceException | RuntimeException e) {
|
||||
Logger.global.logWarning("Failed to parse a variant of " + blockstateFile + ": " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,8 +208,8 @@ public BlockStateResource build(String blockstateFile) throws IOException {
|
||||
variant.checkValid();
|
||||
|
||||
blockState.multipart.add(variant);
|
||||
} catch (Throwable t) {
|
||||
Logger.global.logWarning("Failed to parse a multipart-part of " + blockstateFile + ": " + t);
|
||||
} catch (ParseResourceException | RuntimeException e) {
|
||||
Logger.global.logWarning("Failed to parse a multipart-part of " + blockstateFile + ": " + e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,13 +167,13 @@ public synchronized void loadTextureFile(File file) throws IOException, ParseRes
|
||||
boolean transparent = texture.get("transparent").getAsBoolean();
|
||||
Vector4f color = readVector4f(texture.get("color").getAsJsonArray());
|
||||
textureList.set(i, new Texture(i, path, color, transparent, EMPTY_BASE64));
|
||||
} catch (Exception ex) {
|
||||
} catch (ParseResourceException | RuntimeException ex) {
|
||||
Logger.global.logWarning("Failed to load texture with id " + i + " from texture file " + file + "!");
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
throw ex;
|
||||
} catch (Exception ex) {
|
||||
} catch (RuntimeException ex) {
|
||||
throw new ParseResourceException("Invalid texture file format!", ex);
|
||||
} finally {
|
||||
regenerateMap();
|
||||
|
@ -29,6 +29,7 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.flowpowered.math.vector.Vector2i;
|
||||
@ -63,14 +64,14 @@ public static File coordsToFile(Path root, Vector2i coords, String fileType){
|
||||
* Blocks until a file can be read and written.<br>
|
||||
* <i>(Do not use this method to sync file-access from different threads!)</i>
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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!");
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +116,9 @@ public List<String> 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;
|
||||
|
@ -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;
|
||||
@ -123,8 +124,8 @@ public void onServerStart(GameStartingServerEvent evt) {
|
||||
Logger.global.logInfo("Loading...");
|
||||
bluemap.load();
|
||||
if (bluemap.isLoaded()) Logger.global.logInfo("Loaded!");
|
||||
} catch (Throwable t) {
|
||||
Logger.global.logError("Failed to load!", t);
|
||||
} catch (IOException | ParseResourceException | RuntimeException e) {
|
||||
Logger.global.logError("Failed to load!", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -144,13 +145,13 @@ public void onServerReload(GameReloadEvent evt) {
|
||||
Logger.global.logInfo("Reloading...");
|
||||
bluemap.reload();
|
||||
Logger.global.logInfo("Reloaded!");
|
||||
} catch (Exception e) {
|
||||
} catch (IOException | ParseResourceException | RuntimeException e) {
|
||||
Logger.global.logError("Failed to load!", e);
|
||||
bluemap.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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user