mirror of
https://github.com/PaperMC/Paper.git
synced 2024-11-30 04:02:50 +01:00
0faaa7da92
Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 19b7b7bd #561: Add clear weather World API 5929c808 #552: Add the ability to retrieve hit, step, fall, and other sounds from blocks. CraftBukkit Changes: e1ebdd92 #771: Add clear weather World API 424598d2 #752: Add the ability to retrieve hit, step, fall, and other sounds from blocks.
272 lines
15 KiB
Diff
272 lines
15 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Joseph Hirschfeld <joe@ibj.io>
|
|
Date: Thu, 3 Mar 2016 03:15:41 -0600
|
|
Subject: [PATCH] Add exception reporting event
|
|
|
|
|
|
diff --git a/src/main/java/com/destroystokyo/paper/ServerSchedulerReportingWrapper.java b/src/main/java/com/destroystokyo/paper/ServerSchedulerReportingWrapper.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..f699ce18ca044f813e194ef2786b7ea853ea86e7
|
|
--- /dev/null
|
|
+++ b/src/main/java/com/destroystokyo/paper/ServerSchedulerReportingWrapper.java
|
|
@@ -0,0 +1,38 @@
|
|
+package com.destroystokyo.paper;
|
|
+
|
|
+import com.google.common.base.Preconditions;
|
|
+import org.bukkit.craftbukkit.scheduler.CraftTask;
|
|
+import com.destroystokyo.paper.event.server.ServerExceptionEvent;
|
|
+import com.destroystokyo.paper.exception.ServerSchedulerException;
|
|
+
|
|
+/**
|
|
+ * Reporting wrapper to catch exceptions not natively
|
|
+ */
|
|
+public class ServerSchedulerReportingWrapper implements Runnable {
|
|
+
|
|
+ private final CraftTask internalTask;
|
|
+
|
|
+ public ServerSchedulerReportingWrapper(CraftTask internalTask) {
|
|
+ this.internalTask = Preconditions.checkNotNull(internalTask, "internalTask");
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void run() {
|
|
+ try {
|
|
+ internalTask.run();
|
|
+ } catch (RuntimeException e) {
|
|
+ internalTask.getOwner().getServer().getPluginManager().callEvent(
|
|
+ new ServerExceptionEvent(new ServerSchedulerException(e, internalTask))
|
|
+ );
|
|
+ throw e;
|
|
+ } catch (Throwable t) {
|
|
+ internalTask.getOwner().getServer().getPluginManager().callEvent(
|
|
+ new ServerExceptionEvent(new ServerSchedulerException(t, internalTask))
|
|
+ ); //Do not rethrow, since it is not permitted with Runnable#run
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public CraftTask getInternalTask() {
|
|
+ return internalTask;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
|
|
index 4c051667028ebed6b6f57d4e7d7acbad850c1052..399641433a874cb6426a6092722036446df32eb6 100644
|
|
--- a/src/main/java/net/minecraft/server/Chunk.java
|
|
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
|
@@ -1,5 +1,6 @@
|
|
package net.minecraft.server;
|
|
|
|
+import com.destroystokyo.paper.exception.ServerInternalException;
|
|
import com.google.common.collect.Maps;
|
|
import com.google.common.collect.Sets;
|
|
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
|
@@ -616,10 +617,15 @@ public class Chunk implements IChunkAccess {
|
|
this.tileEntities.remove(blockposition);
|
|
// Paper end
|
|
} else {
|
|
- System.out.println("Attempted to place a tile entity (" + tileentity + ") at " + tileentity.position.getX() + "," + tileentity.position.getY() + "," + tileentity.position.getZ()
|
|
- + " (" + getType(blockposition) + ") where there was no entity tile!");
|
|
- System.out.println("Chunk coordinates: " + (this.loc.x * 16) + "," + (this.loc.z * 16));
|
|
- new Exception().printStackTrace();
|
|
+ // Paper start
|
|
+ ServerInternalException e = new ServerInternalException(
|
|
+ "Attempted to place a tile entity (" + tileentity + ") at " + tileentity.position.getX() + ","
|
|
+ + tileentity.position.getY() + "," + tileentity.position.getZ()
|
|
+ + " (" + getType(blockposition) + ") where there was no entity tile!\n" +
|
|
+ "Chunk coordinates: " + (this.loc.x * 16) + "," + (this.loc.z * 16));
|
|
+ e.printStackTrace();
|
|
+ ServerInternalException.reportInternalException(e);
|
|
+ // Paper end
|
|
// CraftBukkit end
|
|
}
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/NameReferencingFileConverter.java b/src/main/java/net/minecraft/server/NameReferencingFileConverter.java
|
|
index bf0ccfb9bf20422b90ef26370d113b49be7d730b..060887d765604e4be82913607bb6266a278f5db6 100644
|
|
--- a/src/main/java/net/minecraft/server/NameReferencingFileConverter.java
|
|
+++ b/src/main/java/net/minecraft/server/NameReferencingFileConverter.java
|
|
@@ -1,5 +1,6 @@
|
|
package net.minecraft.server;
|
|
|
|
+import com.destroystokyo.paper.exception.ServerInternalException;
|
|
import com.google.common.collect.Lists;
|
|
import com.google.common.collect.Maps;
|
|
import com.google.common.io.Files;
|
|
@@ -353,6 +354,7 @@ public class NameReferencingFileConverter {
|
|
root = NBTCompressedStreamTools.a(new java.io.FileInputStream(file5));
|
|
} catch (Exception exception) {
|
|
exception.printStackTrace();
|
|
+ ServerInternalException.reportInternalException(exception); // Paper
|
|
}
|
|
|
|
if (root != null) {
|
|
@@ -366,6 +368,7 @@ public class NameReferencingFileConverter {
|
|
NBTCompressedStreamTools.a(root, new java.io.FileOutputStream(file2));
|
|
} catch (Exception exception) {
|
|
exception.printStackTrace();
|
|
+ ServerInternalException.reportInternalException(exception); // Paper
|
|
}
|
|
}
|
|
// CraftBukkit end
|
|
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
|
index b40f6b7d45028b5bc58a222e2d54cb8693273325..0542dde09d288488b88e17a044cc508d5d39782f 100644
|
|
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
|
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
|
@@ -761,6 +761,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
|
return true;
|
|
} catch (Exception exception) {
|
|
PlayerChunkMap.LOGGER.error("Failed to save chunk {},{}", chunkcoordintpair.x, chunkcoordintpair.z, exception);
|
|
+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exception); // Paper
|
|
return false;
|
|
}
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java
|
|
index 135f38cc5d5d2fa3866aa1063df49a96b5e72ac2..f722b148464b7b8e515dba25aeffe8dfd3c0d6c3 100644
|
|
--- a/src/main/java/net/minecraft/server/RegionFile.java
|
|
+++ b/src/main/java/net/minecraft/server/RegionFile.java
|
|
@@ -261,6 +261,7 @@ public class RegionFile implements AutoCloseable {
|
|
return true;
|
|
}
|
|
} catch (IOException ioexception) {
|
|
+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(ioexception); // Paper
|
|
return false;
|
|
}
|
|
}
|
|
@@ -333,6 +334,7 @@ public class RegionFile implements AutoCloseable {
|
|
filechannel.write(bytebuffer);
|
|
} catch (Throwable throwable1) {
|
|
throwable = throwable1;
|
|
+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(throwable); // Paper
|
|
throw throwable1;
|
|
} finally {
|
|
if (filechannel != null) {
|
|
diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
index d787fab2c25e31ca6caa56c5e47409512c5ac568..137ee1b453b80e96c1a8fa3271f6350f9294cafb 100644
|
|
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
@@ -14,6 +14,7 @@ import org.apache.logging.log4j.LogManager;
|
|
import org.apache.logging.log4j.Logger;
|
|
|
|
// CraftBukkit start
|
|
+import com.destroystokyo.paper.exception.ServerInternalException;
|
|
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
|
// CraftBukkit end
|
|
|
|
@@ -268,6 +269,7 @@ public final class SpawnerCreature {
|
|
}
|
|
} catch (Exception exception) {
|
|
SpawnerCreature.LOGGER.warn("Failed to create mob", exception);
|
|
+ ServerInternalException.reportInternalException(exception); // Paper
|
|
return null;
|
|
}
|
|
}
|
|
@@ -374,6 +376,7 @@ public final class SpawnerCreature {
|
|
entity = biomesettingsmobs_c.c.a((World) worldaccess.getMinecraftWorld());
|
|
} catch (Exception exception) {
|
|
SpawnerCreature.LOGGER.warn("Failed to create mob", exception);
|
|
+ ServerInternalException.reportInternalException(exception); // Paper
|
|
continue;
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/VillageSiege.java b/src/main/java/net/minecraft/server/VillageSiege.java
|
|
index 1844a6504acc420bdfaaf8f045c569e970d055db..d6aadbda5c5a17976659f57ee04cf9b917e09160 100644
|
|
--- a/src/main/java/net/minecraft/server/VillageSiege.java
|
|
+++ b/src/main/java/net/minecraft/server/VillageSiege.java
|
|
@@ -1,5 +1,7 @@
|
|
package net.minecraft.server;
|
|
|
|
+import com.destroystokyo.paper.exception.ServerInternalException;
|
|
+
|
|
import java.util.Iterator;
|
|
import javax.annotation.Nullable;
|
|
import org.apache.logging.log4j.LogManager;
|
|
@@ -104,6 +106,7 @@ public class VillageSiege implements MobSpawner {
|
|
entityzombie.prepare(worldserver, worldserver.getDamageScaler(entityzombie.getChunkCoordinates()), EnumMobSpawn.EVENT, (GroupDataEntity) null, (NBTTagCompound) null);
|
|
} catch (Exception exception) {
|
|
VillageSiege.LOGGER.warn("Failed to create zombie for village siege at {}", vec3d, exception);
|
|
+ ServerInternalException.reportInternalException(exception); // Paper
|
|
return;
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
|
index 70d6ed9a226ab114b090017cec6998a740b2cb66..db637b5f9ed4180844ddc12dc53050a89a4d163d 100644
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
|
@@ -1,5 +1,10 @@
|
|
package net.minecraft.server;
|
|
|
|
+import co.aikar.timings.Timing;
|
|
+import co.aikar.timings.Timings;
|
|
+import com.destroystokyo.paper.event.server.ServerExceptionEvent;
|
|
+import com.destroystokyo.paper.exception.ServerInternalException;
|
|
+import com.google.common.base.MoreObjects;
|
|
import com.google.common.collect.Lists;
|
|
import com.mojang.serialization.Codec;
|
|
import java.io.IOException;
|
|
@@ -685,8 +690,11 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
|
|
gameprofilerfiller.exit();
|
|
} catch (Throwable throwable) {
|
|
// Paper start - Prevent tile entity and entity crashes
|
|
- System.err.println("TileEntity threw exception at " + tileentity.world.getWorld().getName() + ":" + tileentity.position.getX() + "," + tileentity.position.getY() + "," + tileentity.position.getZ());
|
|
+ String msg = "TileEntity threw exception at " + tileentity.world.getWorld().getName() + ":" + tileentity.position.getX() + "," + tileentity.position.getY() + "," + tileentity.position.getZ();
|
|
+ System.err.println(msg);
|
|
throwable.printStackTrace();
|
|
+ getServer().getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(msg, throwable)));
|
|
+ // Paper end
|
|
tilesThisCycle--;
|
|
this.tileEntityListTick.remove(tileTickPosition--);
|
|
continue;
|
|
@@ -757,8 +765,10 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
|
|
consumer.accept(entity);
|
|
} catch (Throwable throwable) {
|
|
// Paper start - Prevent tile entity and entity crashes
|
|
- System.err.println("Entity threw exception at " + entity.world.getWorld().getName() + ":" + entity.locX() + "," + entity.locY() + "," + entity.locZ());
|
|
+ String msg = "Entity threw exception at " + entity.world.getWorld().getName() + ":" + entity.locX() + "," + entity.locY() + "," + entity.locZ();
|
|
+ System.err.println(msg);
|
|
throwable.printStackTrace();
|
|
+ getServer().getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(msg, throwable)));
|
|
entity.dead = true;
|
|
return;
|
|
// Paper end
|
|
diff --git a/src/main/java/net/minecraft/server/WorldPersistentData.java b/src/main/java/net/minecraft/server/WorldPersistentData.java
|
|
index 141a8e31151010e5a0bd8d4661033f109f6a2e67..138c6d707e33cd352aa4b26dfb279c5b77448de0 100644
|
|
--- a/src/main/java/net/minecraft/server/WorldPersistentData.java
|
|
+++ b/src/main/java/net/minecraft/server/WorldPersistentData.java
|
|
@@ -144,6 +144,7 @@ public class WorldPersistentData {
|
|
}
|
|
} catch (Throwable throwable6) {
|
|
throwable = throwable6;
|
|
+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(throwable); // Paper
|
|
throw throwable6;
|
|
} finally {
|
|
if (fileinputstream != null) {
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
|
index ffe9cc1011226d604dc5499e7692e9a9a5132b72..343cdb06881fa8b0155b56d29c110bba489f9667 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
|
@@ -16,6 +16,9 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|
import java.util.concurrent.atomic.AtomicReference;
|
|
import java.util.function.Consumer;
|
|
import java.util.logging.Level;
|
|
+import com.destroystokyo.paper.ServerSchedulerReportingWrapper;
|
|
+import com.destroystokyo.paper.event.server.ServerExceptionEvent;
|
|
+import com.destroystokyo.paper.exception.ServerSchedulerException;
|
|
import org.apache.commons.lang.Validate;
|
|
import org.bukkit.plugin.IllegalPluginAccessException;
|
|
import org.bukkit.plugin.Plugin;
|
|
@@ -419,6 +422,8 @@ public class CraftScheduler implements BukkitScheduler {
|
|
msg,
|
|
throwable);
|
|
}
|
|
+ task.getOwner().getServer().getPluginManager().callEvent(
|
|
+ new ServerExceptionEvent(new ServerSchedulerException(msg, throwable, task)));
|
|
// Paper end
|
|
} finally {
|
|
currentTask = null;
|
|
@@ -426,7 +431,7 @@ public class CraftScheduler implements BukkitScheduler {
|
|
parsePending();
|
|
} else {
|
|
debugTail = debugTail.setNext(new CraftAsyncDebugger(currentTick + RECENT_TICKS, task.getOwner(), task.getTaskClass()));
|
|
- executor.execute(task);
|
|
+ executor.execute(new ServerSchedulerReportingWrapper(task)); // Paper
|
|
// We don't need to parse pending
|
|
// (async tasks must live with race-conditions if they attempt to cancel between these few lines of code)
|
|
}
|