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
@Nullable
+ @Override
@Override
+ public final ChunkAccess getChunkIfLoadedImmediately(int x, int z) {
+ return ((ServerLevel)this).chunkSource.getChunkAtIfLoadedImmediately(x, z);
+ }
@ -258,7 +258,7 @@
+ return chunk == null ? null : chunk.getFluidState(blockposition);
+ }
+
@Override
+ @Override
public ChunkAccess getChunk(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) {
+ // Paper end
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
+ this.sendBlockUpdated(blockposition, iblockdata1, iblockdata, i);
}
+ }
+
+ if ((i & 1) != 0) {
+ this.blockUpdated(blockposition, iblockdata1.getBlock());
+ if (!this.isClientSide && iblockdata.hasAnalogOutputSignal()) {
+ this.updateNeighbourForOutputSignal(blockposition, newBlock.getBlock());
+ }
+ }
}
+
+ if ((i & 16) == 0 && j > 0) {
+ int k = i & -34;
@ -470,7 +470,7 @@
} else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) {
tickingblockentity.tick();
}
@@ -461,6 +720,7 @@
@@ -461,17 +720,18 @@
this.tickingBlockEntities = false;
gameprofilerfiller.pop();
@ -478,6 +478,22 @@
}
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 @@
@Nullable
@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));
+ // CraftBukkit start
+ return this.getBlockEntity(pos, true);
+ }
+
}
+ @Nullable
+ public BlockEntity getBlockEntity(BlockPos blockposition, boolean validate) {
+ if (this.capturedTileEntities.containsKey(blockposition)) {
@ -494,8 +510,8 @@
+ }
+ // CraftBukkit end
+ 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) {
BlockPos blockposition = blockEntity.getBlockPos();

View file

@ -50,7 +50,21 @@
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) {
@ -72,7 +86,7 @@
@Nullable
@Override
public <T> T get(DataComponentType<T> type) {
@@ -284,9 +314,13 @@
@@ -284,9 +319,13 @@
}
});
Objects.requireNonNull(set);
@ -87,7 +101,7 @@
}
protected void collectImplicitComponents(DataComponentMap.Builder builder) {}
@@ -321,6 +355,15 @@
@@ -321,6 +360,15 @@
}
}

View file

@ -322,10 +322,20 @@
this.ticker = blockentityticker;
}
@@ -872,6 +993,7 @@
@@ -867,11 +988,12 @@
this.blockEntity.fillCrashReportCategory(crashreportsystemdetails);
throw new ReportedException(crashreport);
gameprofilerfiller.pop();
} 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
}
}