Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/1.20.x' into 1.20.x
Browse files Browse the repository at this point in the history
  • Loading branch information
XFactHD committed Jan 14, 2024
2 parents 1101781 + f8c5835 commit a1299f0
Show file tree
Hide file tree
Showing 35 changed files with 1,472 additions and 251 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ unsafe_version=0.2.+
typetools_version=0.6.3
nashorn_core_version=15.3
lwjgl_glfw_version=3.3.2
mixin_extras_version=0.3.2
mixin_extras_version=0.3.3

jupiter_api_version=5.7.0
vintage_engine_version=5.+
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
}

@Override
@@ -73,5 +_,16 @@
@@ -73,5 +_,23 @@
@Override
public int getHeight() {
return this.level.getHeight();
Expand All @@ -35,5 +35,12 @@
+ @Nullable
+ public net.neoforged.neoforge.client.model.data.ModelDataManager.Snapshot getModelDataManager() {
+ return modelDataManager;
+ }
+
+ @Override
+ public net.neoforged.neoforge.common.world.AuxiliaryLightManager getAuxLightManager(net.minecraft.world.level.ChunkPos pos) {
+ int relX = pos.x - this.centerX;
+ int relZ = pos.z - this.centerZ;
+ return this.chunks[relX][relZ].wrapped.getAuxLightManager(pos);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
--- a/net/minecraft/server/network/PlayerChunkSender.java
+++ b/net/minecraft/server/network/PlayerChunkSender.java
@@ -77,6 +_,7 @@
p_295237_.send(new ClientboundLevelChunkWithLightPacket(p_295144_, p_294963_.getLightEngine(), null, null));
@@ -74,9 +_,12 @@
}

private static void sendChunk(ServerGamePacketListenerImpl p_295237_, ServerLevel p_294963_, LevelChunk p_295144_) {
- p_295237_.send(new ClientboundLevelChunkWithLightPacket(p_295144_, p_294963_.getLightEngine(), null, null));
+ p_295237_.send(p_295144_.getAuxLightManager(p_295144_.getPos()).sendLightDataTo(
+ new ClientboundLevelChunkWithLightPacket(p_295144_, p_294963_.getLightEngine(), null, null)
+ ));
ChunkPos chunkpos = p_295144_.getPos();
DebugPackets.sendPoiPacketsForChunk(p_294963_, chunkpos);
+ net.neoforged.neoforge.event.EventHooks.fireChunkSent(p_295237_.player, p_295144_, p_294963_);
Expand Down
24 changes: 23 additions & 1 deletion patches/net/minecraft/world/level/chunk/LevelChunk.java.patch
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@
}
}

@@ -385,6 +_,7 @@
BlockEntity blockentity = this.blockEntities.put(blockpos.immutable(), p_156374_);
if (blockentity != null && blockentity != p_156374_) {
blockentity.setRemoved();
+ auxLightManager.removeLightAt(blockpos);
}
}
}
@@ -394,9 +_,14 @@
public CompoundTag getBlockEntityNbtForSaving(BlockPos p_62932_) {
BlockEntity blockentity = this.getBlockEntity(p_62932_);
Expand All @@ -70,6 +78,14 @@
} else {
CompoundTag compoundtag = this.pendingBlockEntities.get(p_62932_);
if (compoundtag != null) {
@@ -419,6 +_,7 @@
}

blockentity.setRemoved();
+ auxLightManager.removeLightAt(p_62919_);
}
}

@@ -479,7 +_,7 @@
p_187974_.accept((p_187968_, p_187969_, p_187970_) -> {
BlockEntity blockentity = this.getBlockEntity(p_187968_, LevelChunk.EntityCreationType.IMMEDIATE);
Expand All @@ -95,12 +111,13 @@
this.blockEntities.values().forEach(p_187988_ -> {
Level level = this.level;
if (level instanceof ServerLevel serverlevel) {
@@ -646,6 +_,27 @@
@@ -646,6 +_,33 @@
return new LevelChunk.BoundTickingBlockEntity<>(p_156376_, p_156377_);
}

+ // FORGE START
+ private final net.neoforged.neoforge.attachment.AttachmentHolder.AsField attachmentHolder = new net.neoforged.neoforge.attachment.AttachmentHolder.AsField(this);
+ private final net.neoforged.neoforge.common.world.LevelChunkAuxiliaryLightManager auxLightManager = new net.neoforged.neoforge.common.world.LevelChunkAuxiliaryLightManager(this);
+
+ @Override
+ public boolean hasData(net.neoforged.neoforge.attachment.AttachmentType<?> type) {
Expand All @@ -118,6 +135,11 @@
+ setUnsaved(true);
+ return attachmentHolder.setData(type, data);
+ }
+
+ @Override
+ public net.neoforged.neoforge.common.world.LevelChunkAuxiliaryLightManager getAuxLightManager(ChunkPos pos) {
+ return auxLightManager;
+ }
+ // FORGE END
+
class BoundTickingBlockEntity<T extends BlockEntity> implements TickingBlockEntity {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
--- a/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
+++ b/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
@@ -180,6 +_,7 @@
@@ -180,6 +_,10 @@
postLoadChunk(p_188231_, p_188234_),
blendingdata
);
+ if (p_188234_.contains(net.neoforged.neoforge.attachment.AttachmentHolder.ATTACHMENTS_NBT_KEY, net.minecraft.nbt.Tag.TAG_COMPOUND)) ((LevelChunk)chunkaccess).readAttachmentsFromNBT(p_188234_.getCompound(net.neoforged.neoforge.attachment.AttachmentHolder.ATTACHMENTS_NBT_KEY));
+ if (p_188234_.contains(net.neoforged.neoforge.attachment.AttachmentHolder.ATTACHMENTS_NBT_KEY, net.minecraft.nbt.Tag.TAG_COMPOUND))
+ ((LevelChunk)chunkaccess).readAttachmentsFromNBT(p_188234_.getCompound(net.neoforged.neoforge.attachment.AttachmentHolder.ATTACHMENTS_NBT_KEY));
+ if (p_188234_.contains(net.neoforged.neoforge.common.world.LevelChunkAuxiliaryLightManager.LIGHT_NBT_KEY, net.minecraft.nbt.Tag.TAG_LIST))
+ Objects.requireNonNull(((LevelChunk)chunkaccess).getAuxLightManager(p_188233_)).deserializeNBT(p_188234_.getList(net.neoforged.neoforge.common.world.LevelChunkAuxiliaryLightManager.LIGHT_NBT_KEY, net.minecraft.nbt.Tag.TAG_COMPOUND));
} else {
ProtoChunkTicks<Block> protochunkticks = ProtoChunkTicks.load(
p_188234_.getList("block_ticks", 10), p_258992_ -> BuiltInRegistries.BLOCK.getOptional(ResourceLocation.tryParse(p_258992_)), p_188233_
Expand All @@ -24,7 +27,7 @@
return protochunk1;
}
}
@@ -372,6 +_,14 @@
@@ -372,6 +_,17 @@
}

compoundtag.put("CarvingMasks", compoundtag4);
Expand All @@ -36,6 +39,9 @@
+ } catch (Exception exception) {
+ LOGGER.error("Failed to write chunk attachments. An attachment has likely thrown an exception trying to write state. It will not persist. Report this to the mod author", exception);
+ }
+
+ Tag lightTag = levelChunk.getAuxLightManager(chunkpos).serializeNBT();
+ if (lightTag != null) compoundtag.put(net.neoforged.neoforge.common.world.LevelChunkAuxiliaryLightManager.LIGHT_NBT_KEY, lightTag);
}

saveTicks(p_63455_, compoundtag, p_63456_.getTicksForSerialization());
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public static class Material {
public float transparency = 0.0f;

// non-standard
public int diffuseTintIndex = 0;
public int diffuseTintIndex = -1;

public Material(String name) {
this.name = name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public class QuadBakingVertexConsumer implements VertexConsumer {
int vertexIndex = 0;
private int[] quadData = new int[QUAD_DATA_SIZE];

private int tintIndex;
private int tintIndex = -1;
private Direction direction = Direction.DOWN;
private TextureAtlasSprite sprite = UnitTextureAtlasSprite.INSTANCE;
private boolean shade;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
import net.neoforged.neoforge.common.IPlantable;
import net.neoforged.neoforge.common.ToolAction;
import net.neoforged.neoforge.common.ToolActions;
import net.neoforged.neoforge.common.world.AuxiliaryLightManager;
import org.jetbrains.annotations.Nullable;

@SuppressWarnings("deprecation")
Expand Down Expand Up @@ -121,9 +122,10 @@ default float getFriction(BlockState state, LevelReader level, BlockPos pos, @Nu
* will cause issues such as wrapping coordinates returning values from the opposing chunk edge
* </li>
* <li>
* This method may be called on a worker thread and must therefore use
* {@link IBlockGetterExtension#getExistingBlockEntity(BlockPos)} to retrieve the {@link BlockEntity}
* at the given position
* If the light value depends on data from a {@link BlockEntity} then the light level must be stored in
* the {@link AuxiliaryLightManager} by the {@code BlockEntity} and retrieved from the
* {@code AuxiliaryLightManager} in this method. This is to ensure thread-safety and availability of
* the data during chunk load from disk.
* </li>
* </ul>
*/
Expand Down Expand Up @@ -826,13 +828,11 @@ default boolean canConnectRedstone(BlockState state, BlockGetter level, BlockPos
* This method should only be used for blocks you don't control, for your own blocks override
* {@link Block#skipRendering(BlockState, BlockState, Direction)} on the respective block instead
* <p>
* WARNING: This method is likely to be called from a worker thread! If you want to retrieve a
* {@link net.minecraft.world.level.block.entity.BlockEntity} from the given level, make sure to use
* {@link IBlockGetterExtension#getExistingBlockEntity(BlockPos)} to not
* accidentally create a new or delete an old {@link net.minecraft.world.level.block.entity.BlockEntity}
* off of the main thread as this would cause a write operation to the given {@link BlockGetter} and cause
* a CME in the process. Any other direct or indirect write operation to the {@link BlockGetter} will have
* the same outcome.
* <b>Note that this method may be called on any of the client's meshing threads.</b><br/>
* As such, if you need any data from your {@link BlockEntity}, you should put it in {@link ModelData} to guarantee
* safe concurrent access to it on the client.<br/>
* {@link ModelDataManager#getAt(BlockPos)} will return the {@link ModelData} for the queried block,
* or {@code null} if none is present.
*
* @param level The world
* @param pos The blocks position in the world
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,56 @@
package net.neoforged.neoforge.common.extensions;

import net.minecraft.core.BlockPos;
import net.minecraft.core.SectionPos;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.chunk.ChunkSource;
import net.minecraft.world.level.chunk.ImposterProtoChunk;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.LightChunk;
import net.neoforged.neoforge.client.model.data.ModelDataManager;
import net.neoforged.neoforge.common.world.AuxiliaryLightManager;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

public interface IBlockGetterExtension {
private BlockGetter self() {
return (BlockGetter) this;
/**
* Get the {@link AuxiliaryLightManager} of the chunk containing the given {@link BlockPos}.
* <p>
* The light manager must be used to hold light values controlled by dynamic data from {@link BlockEntity}s
* to ensure access to the light data is thread-safe and the data is available during chunk load from disk
* where {@code BlockEntity}s are not yet added to the chunk.
*
* @param pos The position for whose containing chunk the light manager is requested
* @return the light manager or {@code null} if the chunk is not accessible ({@link ChunkSource#getChunkForLighting(int, int)}
* returned {@code null}) or the given implementation of {@link BlockGetter} does not implement {@link #getAuxLightManager(ChunkPos)}
*/
@Nullable
@ApiStatus.NonExtendable
default AuxiliaryLightManager getAuxLightManager(BlockPos pos) {
return getAuxLightManager(new ChunkPos(pos));
}

/**
* Get the {@link BlockEntity} at the given position if it exists.
* Get the {@link AuxiliaryLightManager} of the chunk at the given {@link ChunkPos}.
* <p>
* {@link Level#getBlockEntity(BlockPos)} would create a new {@link BlockEntity} if the
* {@link net.minecraft.world.level.block.Block} has one, but it has not been placed in the world yet
* (This can happen on world load).
*
* @return The BlockEntity at the given position or null if it doesn't exist
* The light manager must be used to hold light values controlled by dynamic data from {@link BlockEntity}s
* to ensure access to the light data is thread-safe and the data is available during chunk load from disk
* where {@code BlockEntity}s are not yet added to the chunk.
*
* @param pos The position of the chunk from which the light manager is requested
* @return the light manager or {@code null} if the chunk is not accessible ({@link ChunkSource#getChunkForLighting(int, int)}
* returned {@code null}) or the given implementation of {@link BlockGetter} does not implement this method
*/
@Nullable
default BlockEntity getExistingBlockEntity(BlockPos pos) {
if (this instanceof Level level) {
if (!level.hasChunk(SectionPos.blockToSectionCoord(pos.getX()), SectionPos.blockToSectionCoord(pos.getZ()))) {
return null;
}

return level.getChunk(pos).getExistingBlockEntity(pos);
} else if (this instanceof LevelChunk chunk) {
return chunk.getBlockEntities().get(pos);
default AuxiliaryLightManager getAuxLightManager(ChunkPos pos) {
if (this instanceof LevelAccessor level) {
LightChunk chunk = level.getChunkSource().getChunkForLighting(pos.x, pos.z);
return chunk != null ? chunk.getAuxLightManager(pos) : null;
} else if (this instanceof ImposterProtoChunk chunk) {
return chunk.getWrapped().getExistingBlockEntity(pos);
return chunk.getWrapped().getAuxLightManager(pos);
}
return self().getBlockEntity(pos);
return null;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,14 @@ default <T> FriendlyByteBuf writeArray(T[] array, FriendlyByteBuf.Writer<T> writ
}
return self();
}

/**
* Writes a byte to the buffer
*
* @param value The value to be written
* @return The buffer
*/
default FriendlyByteBuf writeByte(byte value) {
return self().writeByte((int) value);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforge.common.world;

import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.entity.BlockEntity;

/**
* Manager for light values controlled by dynamic data in {@link BlockEntity}s.
*/
public interface AuxiliaryLightManager {
/**
* Set the light value at the given position to the given value
*/
void setLightAt(BlockPos pos, int value);

/**
* Remove the light value at the given position
*/
default void removeLightAt(BlockPos pos) {
setLightAt(pos, 0);
}

/**
* {@return the light value at the given position or 0 if none is present}
*/
int getLightAt(BlockPos pos);
}
Loading

0 comments on commit a1299f0

Please sign in to comment.