Prevent block entity and entity crashes

This commit is contained in:
Aikar 2016-03-01 23:52:34 -06:00
parent 6212f523fa
commit 0255317409
3 changed files with 55 additions and 15 deletions

View file

@ -226,7 +226,7 @@
+ // Paper start - if loaded + // Paper start - if loaded
@Nullable @Nullable
+ @Override @Override
+ public final ChunkAccess getChunkIfLoadedImmediately(int x, int z) { + public final ChunkAccess getChunkIfLoadedImmediately(int x, int z) {
+ return ((ServerLevel)this).chunkSource.getChunkAtIfLoadedImmediately(x, z); + return ((ServerLevel)this).chunkSource.getChunkAtIfLoadedImmediately(x, z);
+ } + }
@ -258,7 +258,7 @@
+ return chunk == null ? null : chunk.getFluidState(blockposition); + return chunk == null ? null : chunk.getFluidState(blockposition);
+ } + }
+ +
@Override + @Override
public ChunkAccess getChunk(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) { public ChunkAccess getChunk(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) {
+ // Paper end + // Paper end
ChunkAccess ichunkaccess = this.getChunkSource().getChunk(chunkX, chunkZ, leastStatus, create); ChunkAccess ichunkaccess = this.getChunkSource().getChunk(chunkX, chunkZ, leastStatus, create);
@ -383,14 +383,14 @@
+ +
+ if ((i & 2) != 0 && (!this.isClientSide || (i & 4) == 0) && (this.isClientSide || chunk == null || (chunk.getFullStatus() != null && chunk.getFullStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING)))) { // allow chunk to be null here as chunk.isReady() is false when we send our notification during block placement + if ((i & 2) != 0 && (!this.isClientSide || (i & 4) == 0) && (this.isClientSide || chunk == null || (chunk.getFullStatus() != null && chunk.getFullStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING)))) { // allow chunk to be null here as chunk.isReady() is false when we send our notification during block placement
+ this.sendBlockUpdated(blockposition, iblockdata1, iblockdata, i); + this.sendBlockUpdated(blockposition, iblockdata1, iblockdata, i);
} + }
+ +
+ if ((i & 1) != 0) { + if ((i & 1) != 0) {
+ this.blockUpdated(blockposition, iblockdata1.getBlock()); + this.blockUpdated(blockposition, iblockdata1.getBlock());
+ if (!this.isClientSide && iblockdata.hasAnalogOutputSignal()) { + if (!this.isClientSide && iblockdata.hasAnalogOutputSignal()) {
+ this.updateNeighbourForOutputSignal(blockposition, newBlock.getBlock()); + this.updateNeighbourForOutputSignal(blockposition, newBlock.getBlock());
+ } + }
+ } }
+ +
+ if ((i & 16) == 0 && j > 0) { + if ((i & 16) == 0 && j > 0) {
+ int k = i & -34; + int k = i & -34;
@ -470,7 +470,7 @@
} else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) { } else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) {
tickingblockentity.tick(); tickingblockentity.tick();
} }
@@ -461,6 +720,7 @@ @@ -461,17 +720,18 @@
this.tickingBlockEntities = false; this.tickingBlockEntities = false;
gameprofilerfiller.pop(); gameprofilerfiller.pop();
@ -478,6 +478,22 @@
} }
public <T extends Entity> void guardEntityTick(Consumer<T> tickConsumer, T entity) { public <T extends Entity> void guardEntityTick(Consumer<T> tickConsumer, T entity) {
try {
tickConsumer.accept(entity);
} catch (Throwable throwable) {
- CrashReport crashreport = CrashReport.forThrowable(throwable, "Ticking entity");
- CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being ticked");
-
- entity.fillCrashReportCategory(crashreportsystemdetails);
- throw new ReportedException(crashreport);
+ // Paper start - Prevent block entity and entity crashes
+ final String msg = String.format("Entity threw exception at %s:%s,%s,%s", entity.level().getWorld().getName(), entity.getX(), entity.getY(), entity.getZ());
+ MinecraftServer.LOGGER.error(msg, throwable);
+ entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD);
+ // Paper end - Prevent block entity and entity crashes
}
}
@@ -510,13 +770,29 @@ @@ -510,13 +770,29 @@
@Nullable @Nullable
@Override @Override
@ -485,8 +501,8 @@
- return this.isOutsideBuildHeight(pos) ? null : (!this.isClientSide && Thread.currentThread() != this.thread ? null : this.getChunkAt(pos).getBlockEntity(pos, LevelChunk.EntityCreationType.IMMEDIATE)); - return this.isOutsideBuildHeight(pos) ? null : (!this.isClientSide && Thread.currentThread() != this.thread ? null : this.getChunkAt(pos).getBlockEntity(pos, LevelChunk.EntityCreationType.IMMEDIATE));
+ // CraftBukkit start + // CraftBukkit start
+ return this.getBlockEntity(pos, true); + return this.getBlockEntity(pos, true);
+ } }
+
+ @Nullable + @Nullable
+ public BlockEntity getBlockEntity(BlockPos blockposition, boolean validate) { + public BlockEntity getBlockEntity(BlockPos blockposition, boolean validate) {
+ if (this.capturedTileEntities.containsKey(blockposition)) { + if (this.capturedTileEntities.containsKey(blockposition)) {
@ -494,8 +510,8 @@
+ } + }
+ // CraftBukkit end + // CraftBukkit end
+ return this.isOutsideBuildHeight(blockposition) ? null : (!this.isClientSide && Thread.currentThread() != this.thread ? null : this.getChunkAt(blockposition).getBlockEntity(blockposition, LevelChunk.EntityCreationType.IMMEDIATE)); + return this.isOutsideBuildHeight(blockposition) ? null : (!this.isClientSide && Thread.currentThread() != this.thread ? null : this.getChunkAt(blockposition).getBlockEntity(blockposition, LevelChunk.EntityCreationType.IMMEDIATE));
} + }
+
public void setBlockEntity(BlockEntity blockEntity) { public void setBlockEntity(BlockEntity blockEntity) {
BlockPos blockposition = blockEntity.getBlockPos(); BlockPos blockposition = blockEntity.getBlockPos();

View file

@ -50,7 +50,21 @@
return nbttagcompound; return nbttagcompound;
} }
@@ -263,13 +287,19 @@ @@ -234,7 +258,12 @@
public void fillCrashReportCategory(CrashReportCategory crashReportSection) {
crashReportSection.setDetail("Name", this::getNameForReporting);
if (this.level != null) {
- CrashReportCategory.populateBlockDetails(crashReportSection, this.level, this.worldPosition, this.getBlockState());
+ // Paper start - Prevent block entity and entity crashes
+ BlockState block = this.getBlockState();
+ if (block != null) {
+ CrashReportCategory.populateBlockDetails(crashReportSection, this.level, this.worldPosition, block);
+ }
+ // Paper end - Prevent block entity and entity crashes
CrashReportCategory.populateBlockDetails(crashReportSection, this.level, this.worldPosition, this.level.getBlockState(this.worldPosition));
}
}
@@ -263,13 +292,19 @@
} }
public final void applyComponents(DataComponentMap defaultComponents, DataComponentPatch components) { public final void applyComponents(DataComponentMap defaultComponents, DataComponentPatch components) {
@ -72,7 +86,7 @@
@Nullable @Nullable
@Override @Override
public <T> T get(DataComponentType<T> type) { public <T> T get(DataComponentType<T> type) {
@@ -284,9 +314,13 @@ @@ -284,9 +319,13 @@
} }
}); });
Objects.requireNonNull(set); Objects.requireNonNull(set);
@ -87,7 +101,7 @@
} }
protected void collectImplicitComponents(DataComponentMap.Builder builder) {} protected void collectImplicitComponents(DataComponentMap.Builder builder) {}
@@ -321,6 +355,15 @@ @@ -321,6 +360,15 @@
} }
} }

View file

@ -322,10 +322,20 @@
this.ticker = blockentityticker; this.ticker = blockentityticker;
} }
@@ -872,6 +993,7 @@ @@ -867,11 +988,12 @@
this.blockEntity.fillCrashReportCategory(crashreportsystemdetails); gameprofilerfiller.pop();
throw new ReportedException(crashreport); } catch (Throwable throwable) {
- CrashReport crashreport = CrashReport.forThrowable(throwable, "Ticking block entity");
- CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Block entity being ticked");
-
- this.blockEntity.fillCrashReportCategory(crashreportsystemdetails);
- throw new ReportedException(crashreport);
+ // Paper start - Prevent block entity and entity crashes
+ final String msg = String.format("BlockEntity threw exception at %s:%s,%s,%s", LevelChunk.this.getLevel().getWorld().getName(), this.getPos().getX(), this.getPos().getY(), this.getPos().getZ());
+ net.minecraft.server.MinecraftServer.LOGGER.error(msg, throwable);
+ LevelChunk.this.removeBlockEntity(this.getPos());
+ // Paper end - Prevent block entity and entity crashes
+ // Spigot start + // Spigot start
} }
} }