Async Operation Catching
Catch and throw an exception when a potentially unsafe operation occurs on a thread other than the main server thread. By: md_5 <git@md-5.net>
This commit is contained in:
@@ -898,6 +898,7 @@ public final class CraftServer implements Server {
|
||||
public boolean dispatchCommand(CommandSender sender, String commandLine) {
|
||||
Preconditions.checkArgument(sender != null, "sender cannot be null");
|
||||
Preconditions.checkArgument(commandLine != null, "commandLine cannot be null");
|
||||
org.spigotmc.AsyncCatcher.catchOp("command dispatch"); // Spigot
|
||||
|
||||
if (this.commandMap.dispatch(sender, commandLine)) {
|
||||
return true;
|
||||
|
||||
@@ -283,6 +283,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public boolean unloadChunkRequest(int x, int z) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("chunk unload"); // Spigot
|
||||
if (this.isChunkLoaded(x, z)) {
|
||||
this.world.getChunkSource().removeRegionTicket(TicketType.PLUGIN, new ChunkPos(x, z), 1, Unit.INSTANCE);
|
||||
}
|
||||
@@ -291,6 +292,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
}
|
||||
|
||||
private boolean unloadChunk0(int x, int z, boolean save) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("chunk unload"); // Spigot
|
||||
if (!this.isChunkLoaded(x, z)) {
|
||||
return true;
|
||||
}
|
||||
@@ -307,6 +309,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public boolean regenerateChunk(int x, int z) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("chunk regenerate"); // Spigot
|
||||
throw new UnsupportedOperationException("Not supported in this Minecraft version! Unless you can fix it, this is not a bug :)");
|
||||
/*
|
||||
if (!unloadChunk0(x, z, false)) {
|
||||
@@ -384,6 +387,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public boolean loadChunk(int x, int z, boolean generate) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot
|
||||
ChunkAccess chunk = this.world.getChunkSource().getChunk(x, z, generate ? ChunkStatus.FULL : ChunkStatus.EMPTY, true);
|
||||
|
||||
// If generate = false, but the chunk already exists, we will get this back.
|
||||
@@ -919,6 +923,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public Collection<Entity> getNearbyEntities(BoundingBox boundingBox, Predicate<? super Entity> filter) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("getNearbyEntities"); // Spigot
|
||||
Preconditions.checkArgument(boundingBox != null, "BoundingBox cannot be null");
|
||||
|
||||
AABB bb = new AABB(boundingBox.getMinX(), boundingBox.getMinY(), boundingBox.getMinZ(), boundingBox.getMaxX(), boundingBox.getMaxY(), boundingBox.getMaxZ());
|
||||
@@ -1073,6 +1078,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
org.spigotmc.AsyncCatcher.catchOp("world save"); // Spigot
|
||||
this.server.checkSaveState();
|
||||
boolean oldSave = this.world.noSave;
|
||||
|
||||
|
||||
@@ -228,6 +228,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
@Override
|
||||
public List<org.bukkit.entity.Entity> getNearbyEntities(double x, double y, double z) {
|
||||
Preconditions.checkState(!this.entity.generation, "Cannot get nearby entities during world generation");
|
||||
org.spigotmc.AsyncCatcher.catchOp("getNearbyEntities"); // Spigot
|
||||
|
||||
List<Entity> notchEntityList = this.entity.level().getEntities(this.entity, this.entity.getBoundingBox().inflate(x, y, z), Predicates.alwaysTrue());
|
||||
List<org.bukkit.entity.Entity> bukkitEntityList = new java.util.ArrayList<org.bukkit.entity.Entity>(notchEntityList.size());
|
||||
|
||||
@@ -492,6 +492,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
@Override
|
||||
public void kickPlayer(String message) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("player kick"); // Spigot
|
||||
this.getHandle().transferCookieConnection.kickPlayer(CraftChatMessage.fromStringOrEmpty(message, true));
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ public final class CraftScoreboardManager implements ScoreboardManager {
|
||||
|
||||
@Override
|
||||
public CraftScoreboard getNewScoreboard() {
|
||||
org.spigotmc.AsyncCatcher.catchOp("scoreboard creation"); // Spigot
|
||||
CraftScoreboard scoreboard = new CraftScoreboard(new ServerScoreboard(this.server));
|
||||
this.scoreboards.add(scoreboard);
|
||||
return scoreboard;
|
||||
|
||||
@@ -12,6 +12,7 @@ public class ServerShutdownThread extends Thread {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
org.spigotmc.AsyncCatcher.enabled = false; // Spigot
|
||||
this.server.close();
|
||||
} finally {
|
||||
try {
|
||||
|
||||
17
paper-server/src/main/java/org/spigotmc/AsyncCatcher.java
Normal file
17
paper-server/src/main/java/org/spigotmc/AsyncCatcher.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package org.spigotmc;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
|
||||
public class AsyncCatcher
|
||||
{
|
||||
|
||||
public static boolean enabled = true;
|
||||
|
||||
public static void catchOp(String reason)
|
||||
{
|
||||
if ( AsyncCatcher.enabled && Thread.currentThread() != MinecraftServer.getServer().serverThread )
|
||||
{
|
||||
throw new IllegalStateException( "Asynchronous " + reason + "!" );
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user