Path: blob/1.21.x/patches/minecraft/net/minecraft/world/level/chunk/LevelChunk.java.patch
7479 views
--- a/net/minecraft/world/level/chunk/LevelChunk.java1+++ b/net/minecraft/world/level/chunk/LevelChunk.java2@@ -62,7 +_,7 @@3import net.minecraft.world.ticks.TickContainerAccess;4import org.slf4j.Logger;56-public class LevelChunk extends ChunkAccess implements DebugValueSource {7+public class LevelChunk extends ChunkAccess implements DebugValueSource, net.minecraftforge.common.capabilities.ICapabilityProviderImpl<LevelChunk> {8static final Logger LOGGER = LogUtils.getLogger();9private static final TickingBlockEntity NULL_TICKER = new TickingBlockEntity() {10@Override11@@ -124,6 +_,7 @@12this.postLoad = p_196861_;13this.blockTicks = p_196857_;14this.fluidTicks = p_196858_;15+ this.capProvider.initInternal();16}1718public LevelChunk(ServerLevel p_196850_, ProtoChunk p_196851_, @Nullable LevelChunk.PostLoadProcessor p_196852_) {19@@ -321,7 +_,7 @@20if (!levelchunksection.getBlockState(j, k, l).is(block)) {21return null;22} else {23- if (!this.level.isClientSide() && (p_393998_ & 512) == 0) {24+ if (!this.level.isClientSide() && (p_393998_ & 512) == 0 && !this.level.captureBlockSnapshots) {25p_62866_.onPlace(this.level, p_62865_, blockstate, flag2);26}2728@@ -376,6 +_,12 @@29@Nullable30public BlockEntity getBlockEntity(BlockPos p_62868_, LevelChunk.EntityCreationType p_62869_) {31BlockEntity blockentity = this.blockEntities.get(p_62868_);32+33+ if (blockentity != null && blockentity.isRemoved()) {34+ blockEntities.remove(p_62868_);35+ blockentity = null;36+ }37+38if (blockentity == null) {39CompoundTag compoundtag = this.pendingBlockEntities.remove(p_62868_);40if (compoundtag != null) {41@@ -393,9 +_,6 @@42this.addAndRegisterBlockEntity(blockentity);43}44}45- } else if (blockentity.isRemoved()) {46- this.blockEntities.remove(p_62868_);47- return null;48}4950return blockentity;51@@ -410,6 +_,7 @@5253this.level.onBlockEntityAdded(p_156391_);54this.updateBlockEntityTicker(p_156391_);55+ p_156391_.onLoad();56}57}5859@@ -462,9 +_,14 @@60public CompoundTag getBlockEntityNbtForSaving(BlockPos p_62932_, HolderLookup.Provider p_329605_) {61BlockEntity blockentity = this.getBlockEntity(p_62932_);62if (blockentity != null && !blockentity.isRemoved()) {63+ try {64CompoundTag compoundtag1 = blockentity.saveWithFullMetadata(this.level.registryAccess());65compoundtag1.putBoolean("keepPacked", false);66return compoundtag1;67+ } catch (Exception e) {68+ LOGGER.error("A BlockEntity type {} has thrown an exception trying to write state. It will not persist, Report this to the mod author", blockentity.getClass().getName(), e);69+ return null;70+ }71} else {72CompoundTag compoundtag = this.pendingBlockEntities.get(p_62932_);73if (compoundtag != null) {74@@ -544,9 +_,10 @@75(p_405747_, p_405748_, p_405749_) -> {76BlockEntity blockentity = this.getBlockEntity(p_405747_, LevelChunk.EntityCreationType.IMMEDIATE);77if (blockentity != null && p_405749_ != null && blockentity.getType() == p_405748_) {78- blockentity.loadWithComponents(79+ var input = (80TagValueInput.create(problemreporter$scopedcollector.forChild(blockentity.problemPath()), this.level.registryAccess(), p_405749_)81);82+ blockentity.handleUpdateTag(input, this.level.registryAccess());83}84}85);86@@ -684,6 +_,7 @@87}8889public void clearAllBlockEntities() {90+ this.blockEntities.values().forEach(BlockEntity::onChunkUnloaded);91this.blockEntities.values().forEach(BlockEntity::setRemoved);92this.blockEntities.clear();93this.tickersInLevel.values().forEach(p_187966_ -> p_187966_.rebind(NULL_TICKER));94@@ -691,6 +_,7 @@95}9697public void registerAllBlockEntitiesAfterLevelLoad() {98+ this.level.addFreshBlockEntities(this.blockEntities.values());99this.blockEntities.values().forEach(p_405750_ -> {100if (this.level instanceof ServerLevel serverlevel) {101this.addGameEventListener(p_405750_, serverlevel);102@@ -743,6 +_,24 @@103return new LevelChunk.BoundTickingBlockEntity<>(p_156376_, p_156377_);104}105106+ private final net.minecraftforge.common.capabilities.CapabilityProvider.AsField.LevelChunks capProvider = new net.minecraftforge.common.capabilities.CapabilityProvider.AsField.LevelChunks(this);107+108+ @org.jetbrains.annotations.NotNull109+ @Override110+ public <T> net.minecraftforge.common.util.LazyOptional<T> getCapability(@org.jetbrains.annotations.NotNull net.minecraftforge.common.capabilities.Capability<T> cap, @org.jetbrains.annotations.Nullable net.minecraft.core.Direction side) {111+ return capProvider.getCapability(cap, side);112+ }113+114+ @Override115+ public void invalidateCaps() {116+ capProvider.invalidateCaps();117+ }118+119+ @Override120+ public void reviveCaps() {121+ capProvider.reviveCaps();122+ }123+124class BoundTickingBlockEntity<T extends BlockEntity> implements TickingBlockEntity {125private final T blockEntity;126private final BlockEntityTicker<T> ticker;127@@ -760,6 +_,7 @@128if (LevelChunk.this.isTicking(blockpos)) {129try {130ProfilerFiller profilerfiller = Profiler.get();131+ net.minecraftforge.server.timings.TimeTracker.BLOCK_ENTITY_UPDATE.trackStart(blockEntity);132profilerfiller.push(this::getType);133BlockState blockstate = LevelChunk.this.getBlockState(blockpos);134if (this.blockEntity.getType().isValid(blockstate)) {135@@ -781,6 +_,11 @@136CrashReport crashreport = CrashReport.forThrowable(throwable, "Ticking block entity");137CrashReportCategory crashreportcategory = crashreport.addCategory("Block entity being ticked");138this.blockEntity.fillCrashReportCategory(crashreportcategory);139+ if (net.minecraftforge.common.ForgeConfig.SERVER.removeErroringBlockEntities.get()) {140+ LOGGER.error("{}", crashreport.getFriendlyReport(net.minecraft.ReportType.CRASH));141+ blockEntity.setRemoved();142+ LevelChunk.this.removeBlockEntity(blockEntity.getBlockPos());143+ } else144throw new ReportedException(crashreport);145}146}147@@ -854,6 +_,33 @@148public String toString() {149return this.ticker + " <wrapped>";150}151+ }152+153+ /**154+ * <strong>FOR INTERNAL USE ONLY</strong>155+ * <p>156+ * Only public for use in {@link net.minecraft.world.level.chunk.storage.ChunkSerializer}.157+ */158+ @java.lang.Deprecated159+ @org.jetbrains.annotations.Nullable160+ public final CompoundTag writeCapsToNBT(HolderLookup.Provider registryAccess) {161+ return capProvider.serializeInternal(registryAccess);162+ }163+164+ /**165+ * <strong>FOR INTERNAL USE ONLY</strong>166+ * <p>167+ * Only public for use in {@link net.minecraft.world.level.chunk.storage.ChunkSerializer}.168+ *169+ */170+ @java.lang.Deprecated171+ public final void readCapsFromNBT(HolderLookup.Provider registryAccess, CompoundTag tag) {172+ capProvider.deserializeInternal(registryAccess, tag);173+ }174+175+ @Override176+ public Level getWorldForge() {177+ return getLevel();178}179180@FunctionalInterface181182183