3496f2d7e4
Developers!: You will need to clean up your work/Minecraft/1.13.2 folder for this Upstream has released updates that appears 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: b850a822 SPIGOT-4526: Add conversion time API for Zombie & subclasses CraftBukkit Changes:38cf676e
SPIGOT-4534: CreatureSpawnEvent not being called for CHUNK_GENb446cb5d
SPIGOT-4527: Fix sponges with waterlogged blocks6ec8ea5c
SPIGOT-4526: Add conversion time API for Zombie & subclassesc64fe508
Mappings Updatea3c2ec03
Fix missing ServerListPingEvent call for legacy pings Spigot Changes: 1dc156ce Rebuild patches 140f654d Mappings Update
340 Zeilen
18 KiB
Diff
340 Zeilen
18 KiB
Diff
From d59504f70dfb71a27f3bee67630007337fc29f74 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 000000000..f699ce18c
|
|
--- /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 c5d562dca..37bea8dbe 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.Queues;
|
|
import com.google.common.collect.Sets;
|
|
@@ -425,6 +426,7 @@ public class Chunk implements IChunkAccess {
|
|
return this.getBlockData(i, j, k).b(this.world, new BlockPosition(i, j, k));
|
|
}
|
|
|
|
+ public IBlockData getBlockData(BlockPosition blockposition) { return getType(blockposition); } // Paper
|
|
public IBlockData getType(BlockPosition blockposition) {
|
|
return this.getBlockData(blockposition.getX(), blockposition.getY(), blockposition.getZ());
|
|
}
|
|
@@ -820,10 +822,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.locX * 16) + "," + (this.locZ * 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()
|
|
+ + " (" + getBlockData(blockposition) + ") where there was no entity tile!\n" +
|
|
+ "Chunk coordinates: " + (this.locX * 16) + "," + (this.locZ * 16));
|
|
+ e.printStackTrace();
|
|
+ ServerInternalException.reportInternalException(e);
|
|
+ // Paper end
|
|
// CraftBukkit end
|
|
}
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
|
index 6a9b9fa2a..557aa5180 100644
|
|
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
|
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
|
@@ -15,6 +15,7 @@ import java.util.function.BooleanSupplier;
|
|
import java.util.function.Consumer;
|
|
import java.util.function.Function;
|
|
import javax.annotation.Nullable;
|
|
+import com.destroystokyo.paper.exception.ServerInternalException;
|
|
import org.apache.logging.log4j.LogManager;
|
|
import org.apache.logging.log4j.Logger;
|
|
|
|
@@ -209,9 +210,16 @@ public class ChunkProviderServer implements IChunkProvider {
|
|
ichunkaccess.setLastSaved(this.world.getTime());
|
|
this.chunkLoader.saveChunk(this.world, ichunkaccess, unloaded); // Spigot
|
|
} catch (IOException ioexception) {
|
|
- ChunkProviderServer.a.error("Couldn't save chunk", ioexception);
|
|
+ // Paper start
|
|
+ String msg = "Couldn\'t save chunk";
|
|
+ ChunkProviderServer.a.error(msg, ioexception);
|
|
+ ServerInternalException.reportInternalException(ioexception);
|
|
} catch (ExceptionWorldConflict exceptionworldconflict) {
|
|
- ChunkProviderServer.a.error("Couldn't save chunk; already in use by another instance of Minecraft?", exceptionworldconflict);
|
|
+ ChunkProviderServer.a.error("Couldn\'t save chunk; already in use by another instance of Minecraft?", exceptionworldconflict);
|
|
+ String msg = "Couldn\'t save chunk; already in use by another instance of Minecraft?";
|
|
+ ChunkProviderServer.a.error(msg, exceptionworldconflict);
|
|
+ ServerInternalException.reportInternalException(exceptionworldconflict);
|
|
+ // Paper end
|
|
}
|
|
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/NameReferencingFileConverter.java b/src/main/java/net/minecraft/server/NameReferencingFileConverter.java
|
|
index 95120be5d..5977d3b48 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;
|
|
@@ -356,6 +357,7 @@ public class NameReferencingFileConverter {
|
|
root = NBTCompressedStreamTools.a(new java.io.FileInputStream(file1));
|
|
} catch (Exception exception) {
|
|
exception.printStackTrace();
|
|
+ ServerInternalException.reportInternalException(exception); // Paper
|
|
}
|
|
|
|
if (root != null) {
|
|
@@ -369,6 +371,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/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java
|
|
index 66fe6ff86..06417b9ec 100644
|
|
--- a/src/main/java/net/minecraft/server/RegionFile.java
|
|
+++ b/src/main/java/net/minecraft/server/RegionFile.java
|
|
@@ -1,5 +1,6 @@
|
|
package net.minecraft.server;
|
|
|
|
+import com.destroystokyo.paper.exception.ServerInternalException;
|
|
import com.google.common.collect.Lists;
|
|
import java.io.BufferedInputStream;
|
|
import java.io.BufferedOutputStream;
|
|
@@ -75,6 +76,7 @@ public class RegionFile {
|
|
}
|
|
} catch (IOException ioexception) {
|
|
ioexception.printStackTrace();
|
|
+ ServerInternalException.reportInternalException(ioexception); // Paper
|
|
}
|
|
|
|
}
|
|
@@ -221,6 +223,7 @@ public class RegionFile {
|
|
this.b(i, j, (int)(SystemUtils.getTimeMillis() / 1000L));
|
|
} catch (IOException ioexception) {
|
|
ioexception.printStackTrace();
|
|
+ ServerInternalException.reportInternalException(ioexception); // Paper
|
|
}
|
|
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/RegionFileCache.java b/src/main/java/net/minecraft/server/RegionFileCache.java
|
|
index c5ca89691..e507a996f 100644
|
|
--- a/src/main/java/net/minecraft/server/RegionFileCache.java
|
|
+++ b/src/main/java/net/minecraft/server/RegionFileCache.java
|
|
@@ -1,5 +1,6 @@
|
|
package net.minecraft.server;
|
|
|
|
+import com.destroystokyo.paper.exception.ServerInternalException;
|
|
import com.google.common.collect.Maps;
|
|
import java.io.DataInputStream;
|
|
import java.io.DataOutputStream;
|
|
@@ -71,6 +72,7 @@ public class RegionFileCache {
|
|
}
|
|
} catch (IOException ioexception) {
|
|
ioexception.printStackTrace();
|
|
+ ServerInternalException.reportInternalException(ioexception); // Paper
|
|
}
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
index 4233b94a1..1ff5dcd85 100644
|
|
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
@@ -10,6 +10,7 @@ import org.apache.logging.log4j.LogManager;
|
|
import org.apache.logging.log4j.Logger;
|
|
|
|
// CraftBukkit start
|
|
+import com.destroystokyo.paper.exception.ServerInternalException;
|
|
import org.bukkit.craftbukkit.util.LongHash;
|
|
import org.bukkit.craftbukkit.util.LongHashSet;
|
|
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
|
@@ -171,6 +172,7 @@ public final class SpawnerCreature {
|
|
entityinsentient = (EntityInsentient) biomebase_biomemeta.b.a((World) worldserver);
|
|
} catch (Exception exception) {
|
|
SpawnerCreature.a.warn("Failed to create mob", exception);
|
|
+ ServerInternalException.reportInternalException(exception); // Paper
|
|
return j1;
|
|
}
|
|
|
|
@@ -291,6 +293,7 @@ public final class SpawnerCreature {
|
|
entityinsentient = (EntityInsentient) biomebase_biomemeta.b.a(generatoraccess.getMinecraftWorld());
|
|
} catch (Exception exception) {
|
|
SpawnerCreature.a.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 e649d662a..560edb523 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 java.util.List;
|
|
import javax.annotation.Nullable;
|
|
@@ -136,6 +138,7 @@ public class VillageSiege {
|
|
entityzombie.prepare(this.a.getDamageScaler(new BlockPosition(entityzombie)), (GroupDataEntity) null, (NBTTagCompound) null);
|
|
} catch (Exception exception) {
|
|
exception.printStackTrace();
|
|
+ ServerInternalException.reportInternalException(exception); // Paper
|
|
return false;
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
|
index a9239ee7b..0e70a3d68 100644
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
|
@@ -1,6 +1,8 @@
|
|
package net.minecraft.server;
|
|
|
|
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 it.unimi.dsi.fastutil.longs.LongSet;
|
|
@@ -1150,8 +1152,10 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
|
|
} catch (Throwable throwable1) {
|
|
entity.tickTimer.stopTiming();
|
|
// 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);
|
|
throwable1.printStackTrace();
|
|
+ getServer().getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(msg, throwable1)));
|
|
entity.dead = true;
|
|
continue;
|
|
// Paper end
|
|
@@ -1216,8 +1220,10 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
|
|
this.methodProfiler.exit();
|
|
} catch (Throwable throwable2) {
|
|
// 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);
|
|
throwable2.printStackTrace();
|
|
+ getServer().getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(msg, throwable2)));
|
|
tilesThisCycle--;
|
|
this.tileEntityListTick.remove(tileTickPosition--);
|
|
continue;
|
|
diff --git a/src/main/java/net/minecraft/server/WorldPersistentData.java b/src/main/java/net/minecraft/server/WorldPersistentData.java
|
|
index f0a826cd1..2dee02669 100644
|
|
--- a/src/main/java/net/minecraft/server/WorldPersistentData.java
|
|
+++ b/src/main/java/net/minecraft/server/WorldPersistentData.java
|
|
@@ -121,6 +121,7 @@ public class WorldPersistentData {
|
|
int j = nbttagcompound.hasKeyOfType("DataVersion", 99) ? nbttagcompound.getInt("DataVersion") : 1343;
|
|
nbttagcompound1 = GameProfileSerializer.a(idatamanager.i(), DataFixTypes.SAVED_DATA, nbttagcompound, j, i);
|
|
} catch (Throwable throwable2) {
|
|
+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(throwable2); // Paper
|
|
throwable = throwable2;
|
|
throw throwable2;
|
|
} finally {
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
|
index 311c4f5ca..e76882b8e 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.function.Consumer;
|
|
import java.util.logging.Level;
|
|
|
|
import co.aikar.timings.MinecraftTimings; // Paper
|
|
+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;
|
|
@@ -390,20 +393,26 @@ public class CraftScheduler implements BukkitScheduler {
|
|
try {
|
|
task.run();
|
|
} catch (final Throwable throwable) {
|
|
+ // Paper start
|
|
+ String msg = String.format(
|
|
+ "Task #%s for %s generated an exception",
|
|
+ task.getTaskId(),
|
|
+ task.getOwner().getDescription().getFullName());
|
|
task.getOwner().getLogger().log(
|
|
Level.WARNING,
|
|
- String.format(
|
|
- "Task #%s for %s generated an exception",
|
|
- task.getTaskId(),
|
|
- task.getOwner().getDescription().getFullName()),
|
|
+ msg,
|
|
throwable);
|
|
+ task.getOwner().getServer().getPluginManager().callEvent(
|
|
+ new ServerExceptionEvent(new ServerSchedulerException(msg, throwable, task))
|
|
+ );
|
|
+ // Paper end
|
|
} finally {
|
|
currentTask = null;
|
|
}
|
|
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)
|
|
}
|
|
--
|
|
2.20.0
|
|
|