Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion patches/net/minecraft/server/MinecraftServer.java.patch
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@
return configureRepositoryWithSelection(packRepository, selected, forcedFeatures, true);
}
}
@@ -1845,6 +_,31 @@
@@ -1845,6 +_,43 @@

public abstract boolean isSingleplayerOwner(NameAndId nameAndId);

Expand Down Expand Up @@ -273,6 +273,18 @@
+ worldArrayLast = worldArrayMarker;
+ return worldArray;
+ }
+
+ @org.jetbrains.annotations.ApiStatus.Internal
+ private final net.neoforged.neoforge.attachment.vanilla.ServerAttachmentHolder attachments = new net.neoforged.neoforge.attachment.vanilla.ServerAttachmentHolder(this);
+ @org.jetbrains.annotations.ApiStatus.Internal
+ public net.neoforged.neoforge.attachment.IAttachmentHolder getAttachmentHolder() {
Comment thread
robotgryphon marked this conversation as resolved.
+ return attachments;
+ }
+
+ @Override
+ public net.neoforged.neoforge.attachment.storage.AttachmentDataStorage attachmentDataStorage() {
+ return attachments;
+ }
+
public void dumpServerProperties(Path path) throws IOException {
}
Expand Down
2 changes: 1 addition & 1 deletion patches/net/minecraft/server/level/ChunkHolder.java.patch
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
if (packet != null) {
this.broadcast(players, packet);
}
+ net.neoforged.neoforge.attachment.AttachmentSync.syncBlockEntityUpdates(blockEntity, players);
+ net.neoforged.neoforge.attachment.sync.AttachmentSync.syncBlockEntityUpdates(blockEntity, players);
}
}

2 changes: 1 addition & 1 deletion patches/net/minecraft/server/level/ServerEntity.java.patch
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
broadcast.accept(new ClientboundSetEntityLinkPacket(this.entity, leashable.getLeashHolder()));
}
+
+ net.neoforged.neoforge.attachment.AttachmentSync.syncInitialEntityAttachments(this.entity, player, broadcast);
+ net.neoforged.neoforge.attachment.sync.AttachmentSync.syncInitialEntityAttachments(this.entity, player, broadcast);
}

public Vec3 getPositionBase() {
10 changes: 2 additions & 8 deletions patches/net/minecraft/server/level/ServerLevel.java.patch
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,11 @@
this.structureCheck = new StructureCheck(
this.chunkSource.chunkScanner(),
this.registryAccess(),
@@ -303,6 +_,11 @@
@@ -303,6 +_,10 @@
this.waypointManager = new ServerWaypointManager();
this.environmentAttributes = EnvironmentAttributeSystem.builder().addDefaultLayers(this).build();
this.updateSkyBrightness();
+
+ net.neoforged.neoforge.attachment.LevelAttachmentsSavedData.init(this);
+ // Neo: Move the initialization of customSpawners to the end of costructor
+ // Providing a fully initialized ServerLevel instance for the ServerLevelEvent.CustomSpawners
+ this.customSpawners = net.neoforged.neoforge.event.EventHooks.getCustomSpawners(this, customSpawners);
Expand Down Expand Up @@ -272,7 +271,7 @@
ServerLevel.this.dragonParts.put(subEntity.getId(), subEntity);
}
}
@@ -1927,25 +_,62 @@
@@ -1927,25 +_,57 @@
if (ServerLevel.this.isUpdatingNavigations) {
String message = "onTrackingStart called during navigation iteration";
Util.logAndPauseIfInIde(
Expand Down Expand Up @@ -304,11 +303,6 @@
}
+ }
+
+ @Override
+ public final void syncData(net.neoforged.neoforge.attachment.AttachmentType<?> type) {
+ net.neoforged.neoforge.attachment.AttachmentSync.syncLevelUpdate(this, type);
+ }
+
+ private final net.neoforged.neoforge.capabilities.CapabilityListenerHolder capListenerHolder = new net.neoforged.neoforge.capabilities.CapabilityListenerHolder();
+
+ @Override
Expand Down
2 changes: 1 addition & 1 deletion patches/net/minecraft/server/level/ServerPlayer.java.patch
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
this.lastSentFood = -1;
this.teleportSpectators(transition, oldLevel);
+ // Neo: On the client all attachments are lost on dimension change and need to be re-sent
+ net.neoforged.neoforge.attachment.AttachmentSync.syncInitialPlayerAttachments(this);
+ net.neoforged.neoforge.attachment.sync.AttachmentSync.syncInitialPlayerAttachments(this);
+ net.neoforged.neoforge.event.EventHooks.firePlayerChangedDimensionEvent(this, lastDimension, transition.newLevel().dimension());
return this;
}
Expand Down
6 changes: 3 additions & 3 deletions patches/net/minecraft/server/players/PlayerList.java.patch
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
this.server.notificationManager().playerJoined(player);
playerConnection.resumeFlushing();
+
+ net.neoforged.neoforge.attachment.AttachmentSync.syncInitialPlayerAttachments(player);
+ net.neoforged.neoforge.attachment.sync.AttachmentSync.syncInitialPlayerAttachments(player);
+ net.neoforged.neoforge.event.EventHooks.firePlayerLoggedIn(player);
}

Expand Down Expand Up @@ -82,7 +82,7 @@
this.playersByUUID.put(player.getUUID(), player);
player.initInventoryMenu();
player.setHealth(player.getHealth());
+ net.neoforged.neoforge.attachment.AttachmentSync.syncInitialPlayerAttachments(player);
+ net.neoforged.neoforge.attachment.sync.AttachmentSync.syncInitialPlayerAttachments(player);
+ net.neoforged.neoforge.event.EventHooks.firePlayerRespawnEvent(player, keepAllPlayerData);
ServerPlayer.RespawnConfig respawnConfig = player.getRespawnConfig();
if (!keepAllPlayerData && respawnConfig != null) {
Expand All @@ -107,7 +107,7 @@

player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.LEVEL_CHUNKS_LOAD_START, 0.0F));
this.server.tickRateManager().updateJoiningPlayer(player);
+ net.neoforged.neoforge.attachment.AttachmentSync.syncInitialLevelAttachments(level, player);
+ net.neoforged.neoforge.attachment.sync.AttachmentSync.syncInitialLevelAttachments(level, player);
}

public void sendAllPlayerInfo(ServerPlayer player) {
Expand Down
2 changes: 1 addition & 1 deletion patches/net/minecraft/world/entity/Entity.java.patch
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@
+
+ @Override
+ public final void syncData(net.neoforged.neoforge.attachment.AttachmentType<?> type) {
+ net.neoforged.neoforge.attachment.AttachmentSync.syncEntityUpdate(this, type);
+ net.neoforged.neoforge.attachment.sync.AttachmentSync.syncEntityUpdate(this, type);
+ }
+
+ // Neo: Hookup Capabilities getters to entities
Expand Down
9 changes: 0 additions & 9 deletions patches/net/minecraft/world/level/Level.java.patch
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
--- a/net/minecraft/world/level/Level.java
+++ b/net/minecraft/world/level/Level.java
@@ -90,7 +_,7 @@
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.jspecify.annotations.Nullable;

-public abstract class Level implements LevelAccessor, AutoCloseable, net.neoforged.neoforge.common.extensions.ILevelExtension {
+public abstract class Level extends net.neoforged.neoforge.attachment.AttachmentHolder implements LevelAccessor, AutoCloseable, net.neoforged.neoforge.common.extensions.ILevelExtension {
public static final Codec<ResourceKey<Level>> RESOURCE_KEY_CODEC = ResourceKey.codec(Registries.DIMENSION);
public static final ResourceKey<Level> OVERWORLD = ResourceKey.create(Registries.DIMENSION, Identifier.withDefaultNamespace("overworld"));
public static final ResourceKey<Level> NETHER = ResourceKey.create(Registries.DIMENSION, Identifier.withDefaultNamespace("the_nether"));
@@ -130,6 +_,11 @@
private final DamageSources damageSources;
private final PalettedContainerFactory palettedContainerFactory;
Expand Down
41 changes: 11 additions & 30 deletions patches/net/minecraft/world/level/chunk/ChunkAccess.java.patch
Original file line number Diff line number Diff line change
Expand Up @@ -28,47 +28,32 @@
}
}
}
@@ -476,6 +_,83 @@
@@ -476,6 +_,64 @@
public ChunkSkyLightSources getSkyLightSources() {
return this.skyLightSources;
}
+
+ // Neo: Hook in AttachmentHolder to chunks for data storage and retrieval
+ private final net.neoforged.neoforge.attachment.AttachmentHolder.AsField attachmentHolder = new net.neoforged.neoforge.attachment.AttachmentHolder.AsField(this);
+
+ @Override
+ public boolean hasAttachments() {
+ return getAttachmentHolder().hasAttachments();
+ }
+
+ @Override
+ public boolean hasData(net.neoforged.neoforge.attachment.AttachmentType<?> type) {
+ return getAttachmentHolder().hasData(type);
+ }
+
+ @Override
+ public <T> T getData(net.neoforged.neoforge.attachment.AttachmentType<T> type) {
+ return getAttachmentHolder().getData(type);
+ }
+ @org.jetbrains.annotations.ApiStatus.Internal
+ protected final net.neoforged.neoforge.attachment.AttachmentHolder attachments = new net.neoforged.neoforge.attachment.AttachmentHolder();
+
+ @Override
+ @Nullable
+ public <T> T getExistingDataOrNull(net.neoforged.neoforge.attachment.AttachmentType<T> type) {
+ return getAttachmentHolder().getExistingDataOrNull(type);
+ @org.jetbrains.annotations.ApiStatus.Internal
+ public net.neoforged.neoforge.attachment.storage.AttachmentDataStorage attachmentDataStorage() {
+ return attachments;
+ }
+
+ @Override
+ @Nullable
+ public <T> T setData(net.neoforged.neoforge.attachment.AttachmentType<T> type, T data) {
+ markUnsaved();
+ return getAttachmentHolder().setData(type, data);
+ return attachments.setData(type, data);
+ }
+
+ @Override
+ @Nullable
+ public <T> T removeData(net.neoforged.neoforge.attachment.AttachmentType<T> type) {
+ markUnsaved();
+ return getAttachmentHolder().removeData(type);
+ return attachments.removeData(type);
+ }
+
+ /**
Expand All @@ -81,7 +66,7 @@
+ public final CompoundTag writeAttachmentsToNBT(HolderLookup.Provider provider) {
+ ProblemReporter.Collector reporter = new ProblemReporter.Collector();
+ var tag = net.minecraft.world.level.storage.TagValueOutput.createWithContext(reporter, provider);
+ getAttachmentHolder().serializeAttachments(tag);
+ attachments.serializeAttachments(tag);
+ if (!reporter.isEmpty()) throw new IllegalArgumentException("Attachments failed to serialise: " + reporter.getReport());
+ return tag.isEmpty() ? null : tag.buildResult();
+ }
Expand All @@ -96,17 +81,13 @@
+ public final void readAttachmentsFromNBT(HolderLookup.Provider provider, CompoundTag tag) {
+ ProblemReporter.Collector reporter = new ProblemReporter.Collector();
+ var input = net.minecraft.world.level.storage.TagValueInput.create(reporter, provider, tag);
+ getAttachmentHolder().deserializeInternal(provider, input);
+ if(attachments.attachmentPersistenceHandler() instanceof net.neoforged.neoforge.attachment.persistence.AttachmentHolderPersistenceHandler persist)
+ persist.deserialize(input);
+ if (!reporter.isEmpty()) {
+ throw new IllegalArgumentException("Attachments failed to deserialise: " + reporter.getReport());
+ }
+ }
+
+ @org.jetbrains.annotations.ApiStatus.Internal
+ public net.neoforged.neoforge.attachment.AttachmentHolder.AsField getAttachmentHolder() {
+ return attachmentHolder;
+ }
+
+ // Neo: Allow for exposing the Level a chunk is tied to if available
+ public net.minecraft.world.level.@Nullable Level getLevel() { return null; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
+ }
+
+ @Override
+ public net.neoforged.neoforge.attachment.AttachmentHolder.AsField getAttachmentHolder() {
+ return wrapped.getAttachmentHolder();
+ public net.neoforged.neoforge.attachment.AttachmentHolder attachmentDataStorage() {
+ return wrapped.attachments;
}
}
9 changes: 2 additions & 7 deletions patches/net/minecraft/world/level/chunk/LevelChunk.java.patch
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
this.setAllStarts(protoChunk.getAllStarts());
this.setAllReferences(protoChunk.getAllReferences());

+ net.neoforged.neoforge.attachment.AttachmentInternals.copyChunkAttachmentsOnPromotion(level.registryAccess(), protoChunk.getAttachmentHolder(), this.getAttachmentHolder());
+ net.neoforged.neoforge.attachment.AttachmentInternals.copyChunkAttachmentsOnPromotion(level.registryAccess(), protoChunk.attachments, this.attachments);
for (Entry<Heightmap.Types, Heightmap> entry : protoChunk.getHeightmaps()) {
if (ChunkStatus.FULL.heightmapsAfter().contains(entry.getKey())) {
this.setHeightmap(entry.getKey(), entry.getValue().getRawData());
Expand Down Expand Up @@ -111,7 +111,7 @@
this.blockEntities.values().forEach(blockEntity -> {
if (this.level instanceof ServerLevel serverLevel) {
this.addGameEventListener(blockEntity, serverLevel);
@@ -728,6 +_,19 @@
@@ -728,6 +_,14 @@
return new LevelChunk.BoundTickingBlockEntity<>(blockEntity, ticker);
}

Expand All @@ -122,11 +122,6 @@
+ public net.neoforged.neoforge.common.world.LevelChunkAuxiliaryLightManager getAuxLightManager(ChunkPos pos) {
+ return auxLightManager;
+ }
+
+ @Override
+ public final void syncData(net.neoforged.neoforge.attachment.AttachmentType<?> type) {
+ net.neoforged.neoforge.attachment.AttachmentSync.syncChunkUpdate(this, getAttachmentHolder(), type);
+ }
+
private class BoundTickingBlockEntity<T extends BlockEntity> implements TickingBlockEntity {
private final T blockEntity;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.item.crafting.RecipeMap;
import net.minecraft.world.level.chunk.status.ChunkStatus;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.attachment.AttachmentSync;
import net.neoforged.neoforge.attachment.sync.SyncAttachmentsPayload;
import net.neoforged.neoforge.client.event.RecipesReceivedEvent;
import net.neoforged.neoforge.client.network.event.RegisterClientPayloadHandlersEvent;
import net.neoforged.neoforge.client.registries.ClientRegistryManager;
Expand All @@ -50,7 +49,7 @@
import net.neoforged.neoforge.network.payload.KnownRegistryDataMapsPayload;
import net.neoforged.neoforge.network.payload.RecipeContentPayload;
import net.neoforged.neoforge.network.payload.RegistryDataMapSyncPayload;
import net.neoforged.neoforge.network.payload.SyncAttachmentsPayload;
import net.neoforged.neoforge.registries.NeoForgeRegistries;
import net.neoforged.neoforge.registries.RegistryManager;
import net.neoforged.neoforge.registries.RegistrySnapshot;
import org.jetbrains.annotations.ApiStatus;
Expand Down Expand Up @@ -188,34 +187,10 @@ private static void handle(final RecipeContentPayload payload, final IPayloadCon
}

private static void handle(SyncAttachmentsPayload payload, IPayloadContext context) {
switch (payload.target()) {
case SyncAttachmentsPayload.BlockEntityTarget(var pos) -> {
var blockEntity = context.player().level().getBlockEntity(pos);
if (blockEntity == null) {
LOGGER.warn("Received synced attachments from unknown block entity");
} else {
AttachmentSync.receiveSyncedDataAttachments(blockEntity, context.player().registryAccess(), payload.types(), payload.syncPayload());
}
}
case SyncAttachmentsPayload.ChunkTarget(var pos) -> {
var chunk = context.player().level().getChunk(pos.x(), pos.z(), ChunkStatus.FULL, false);
if (chunk == null) {
LOGGER.warn("Received synced attachments from unknown chunk");
} else {
AttachmentSync.receiveSyncedDataAttachments(chunk.getAttachmentHolder(), chunk.getLevel().registryAccess(), payload.types(), payload.syncPayload());
}
}
case SyncAttachmentsPayload.EntityTarget(var entityId) -> {
var entity = context.player().level().getEntity(entityId);
if (entity == null) {
LOGGER.warn("Received synced attachments from unknown entity");
} else {
AttachmentSync.receiveSyncedDataAttachments(entity, entity.registryAccess(), payload.types(), payload.syncPayload());
}
}
case SyncAttachmentsPayload.LevelTarget() -> {
AttachmentSync.receiveSyncedDataAttachments(context.player().level(), context.player().registryAccess(), payload.types(), payload.syncPayload());
}
}
final var level = context.player().level();
var reg = level.registryAccess().lookupOrThrow(NeoForgeRegistries.ATTACHMENT_HOLDER_SYNC_HANDLERS.key());
reg.get(payload.syncHandlerKey()).ifPresent(handler -> {
handler.value().receiveData(level.registryAccess(), payload.types(), payload.syncPayload());
});
}
}
Loading
Loading