Skip to content

Commit

Permalink
Re-introduce custom data in menu screen opening
Browse files Browse the repository at this point in the history
  • Loading branch information
Minecraftschurli committed Dec 16, 2023
1 parent 0792e87 commit 3a52359
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 32 deletions.
27 changes: 25 additions & 2 deletions patches/net/minecraft/server/level/ServerPlayer.java.patch
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,31 @@
return this.isReachableBedBlock(p_9117_) || this.isReachableBedBlock(p_9117_.relative(p_9118_.getOpposite()));
}

@@ -1003,6 +_,7 @@
.send(new ClientboundOpenScreenPacket(abstractcontainermenu.containerId, abstractcontainermenu.getType(), p_9033_.getDisplayName()));
@@ -983,6 +_,11 @@

@Override
public OptionalInt openMenu(@Nullable MenuProvider p_9033_) {
+ return openMenu(p_9033_, (java.util.function.Consumer<net.minecraft.network.FriendlyByteBuf>) null);
+ }
+
+ @Override
+ public OptionalInt openMenu(@Nullable MenuProvider p_9033_, @Nullable java.util.function.Consumer<net.minecraft.network.FriendlyByteBuf> extraDataWriter) {
if (p_9033_ == null) {
return OptionalInt.empty();
} else {
@@ -999,10 +_,16 @@

return OptionalInt.empty();
} else {
- this.connection
- .send(new ClientboundOpenScreenPacket(abstractcontainermenu.containerId, abstractcontainermenu.getType(), p_9033_.getDisplayName()));
+ if (extraDataWriter == null) {
+ this.connection
+ .send(new ClientboundOpenScreenPacket(abstractcontainermenu.containerId, abstractcontainermenu.getType(), p_9033_.getDisplayName()));
+ } else {
+ this.connection
+ .send(new net.neoforged.neoforge.network.payload.AdvancedOpenScreenPayload(abstractcontainermenu.containerId, abstractcontainermenu.getType(), p_9033_.getDisplayName(), extraDataWriter));
+ }
this.initMenu(abstractcontainermenu);
this.containerMenu = abstractcontainermenu;
+ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.entity.player.PlayerContainerEvent.Open(this, this.containerMenu));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,19 @@

package net.neoforged.neoforge.common.extensions;

import java.util.OptionalInt;
import java.util.function.Consumer;
import net.minecraft.core.BlockPos;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.client.ConfigScreenHandler;
import net.neoforged.neoforge.common.NeoForgeMod;
import org.jetbrains.annotations.Nullable;

public interface IPlayerExtension {

Expand Down Expand Up @@ -92,4 +98,31 @@ default boolean isCloseEnough(Entity entity, double dist) {
return aabb.distanceToSqr(eye) < dist * dist;
}

/**
* Request to open a GUI on the client, from the server
* <p>
* Refer to {@link ConfigScreenHandler.ConfigScreenFactory} for how to provide a function to consume
* these GUI requests on the client.
*
* @param menuProvider A supplier of container properties including the registry name of the container
* @param pos A block pos, which will be encoded into the additional data for this request
*/
default OptionalInt openMenu(@Nullable MenuProvider menuProvider, BlockPos pos) {
return openMenu(menuProvider, buf -> buf.writeBlockPos(pos));
}

/**
* Request to open a GUI on the client, from the server
* <p>
* Refer to {@link ConfigScreenHandler.ConfigScreenFactory} for how to provide a function to consume
* these GUI requests on the client.
* <p>
* The maximum size for #extraDataWriter is 32600 bytes.
*
* @param menuProvider A supplier of container properties including the registry name of the container
* @param extraDataWriter Consumer to write any additional data the GUI needs
*/
default OptionalInt openMenu(@Nullable MenuProvider menuProvider, @Nullable Consumer<FriendlyByteBuf> extraDataWriter) {
return OptionalInt.empty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ public static void register(final RegisterPacketHandlerEvent event) {
AdvancedAddEntityPayload.ID,
AdvancedAddEntityPayload::new,
handlers -> handlers.client(ClientPayloadHandler.getInstance()::handle)
)
.play(
AdvancedOpenScreenPayload.ID,
AdvancedOpenScreenPayload::new,
handlers -> handlers.client(ClientPayloadHandler.getInstance()::handle)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.MenuScreens;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.MenuAccess;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.level.Level;
import net.neoforged.neoforge.common.TierSortingRegistry;
import net.neoforged.neoforge.common.util.LogicalSidedProvider;
Expand All @@ -22,6 +26,7 @@
import net.neoforged.neoforge.network.handling.ConfigurationPayloadContext;
import net.neoforged.neoforge.network.handling.PlayPayloadContext;
import net.neoforged.neoforge.network.payload.AdvancedAddEntityPayload;
import net.neoforged.neoforge.network.payload.AdvancedOpenScreenPayload;
import net.neoforged.neoforge.network.payload.ConfigFilePayload;
import net.neoforged.neoforge.network.payload.FrozenRegistryPayload;
import net.neoforged.neoforge.network.payload.FrozenRegistrySyncCompletedPayload;
Expand Down Expand Up @@ -77,9 +82,8 @@ public void handle(ConfigurationPayloadContext context, TierSortingRegistryPaylo
}

public void handle(PlayPayloadContext context, AdvancedAddEntityPayload msg) {
EntityType<?> type = BuiltInRegistries.ENTITY_TYPE.byId(msg.typeId());
Optional<Level> world = LogicalSidedProvider.CLIENTWORLD.get(context.flow().getReceptionSide());
Entity e = world.map(w -> type.customClientSpawn(msg, w)).orElse(null);
Entity e = world.map(w -> msg.typeId().customClientSpawn(msg, w)).orElse(null);
if (e == null) {
return;
}
Expand All @@ -99,8 +103,29 @@ public void handle(PlayPayloadContext context, AdvancedAddEntityPayload msg) {
e.lerpMotion(msg.velX() / 8000.0, msg.velY() / 8000.0, msg.velZ() / 8000.0);
if (e instanceof IEntityAdditionalSpawnData entityAdditionalSpawnData) {
final FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.wrappedBuffer(msg.customPayload()));
entityAdditionalSpawnData.readSpawnData(buf);
try {
entityAdditionalSpawnData.readSpawnData(buf);
} finally {
buf.release();
}
}
}

public void handle(PlayPayloadContext context, AdvancedOpenScreenPayload msg) {
final FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.wrappedBuffer(msg.additionalData()));
try {
createMenuScreen(msg.name(), msg.menuType(), msg.windowId(), buf);
} finally {
buf.release();
}
}

private static <T extends AbstractContainerMenu> void createMenuScreen(Component name, MenuType<T> menuType, int windowId, FriendlyByteBuf buf) {
Minecraft mc = Minecraft.getInstance();
MenuScreens.getScreenFactory(menuType, mc, windowId, name).ifPresent(f -> {
Screen s = f.create(menuType.create(windowId, mc.player.getInventory(), buf), mc.player.getInventory(), name);
mc.player.containerMenu = ((MenuAccess<?>) s).getMenu();
mc.setScreen(s);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,14 @@
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.dimension.BuiltinDimensionTypes;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.entity.EntityType;
import net.neoforged.neoforge.entity.IEntityAdditionalSpawnData;
import net.neoforged.neoforge.internal.versions.neoforge.NeoForgeVersion;
import org.jetbrains.annotations.NotNull;

import java.util.UUID;

public record AdvancedAddEntityPayload(
int typeId,
EntityType<?> typeId,
int entityId,
UUID uuid,
double posX,
Expand All @@ -34,7 +32,7 @@ public record AdvancedAddEntityPayload(

public AdvancedAddEntityPayload(FriendlyByteBuf buf) {
this(
buf.readVarInt(),
buf.readById(BuiltInRegistries.ENTITY_TYPE),
buf.readVarInt(),
buf.readUUID(),
buf.readDouble(),
Expand All @@ -52,7 +50,7 @@ public AdvancedAddEntityPayload(FriendlyByteBuf buf) {

public AdvancedAddEntityPayload(Entity e) {
this(
BuiltInRegistries.ENTITY_TYPE.getId(e.getType()),
e.getType(),
e.getId(),
e.getUUID(),
e.getX(),
Expand All @@ -70,31 +68,32 @@ public AdvancedAddEntityPayload(Entity e) {

private static byte[] writeCustomData(final Entity entity) {
final FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
try {
if (entity instanceof IEntityAdditionalSpawnData additionalSpawnData) {
additionalSpawnData.writeSpawnData(buf);
}

if (entity instanceof IEntityAdditionalSpawnData additionalSpawnData) {
additionalSpawnData.writeSpawnData(buf);
return buf.array();
} finally {
buf.release();
}

final byte[] payload = buf.array();
buf.release();
return payload;
}

@Override
public void write(FriendlyByteBuf buffer) {
buffer.writeVarInt(typeId);
buffer.writeVarInt(entityId);
buffer.writeUUID(uuid);
buffer.writeDouble(posX);
buffer.writeDouble(posY);
buffer.writeDouble(posZ);
buffer.writeByte(pitch);
buffer.writeByte(yaw);
buffer.writeByte(headYaw);
buffer.writeVarInt(velX);
buffer.writeVarInt(velY);
buffer.writeVarInt(velZ);
buffer.writeByteArray(customPayload);
buffer.writeId(BuiltInRegistries.ENTITY_TYPE, typeId());
buffer.writeVarInt(entityId());
buffer.writeUUID(uuid());
buffer.writeDouble(posX());
buffer.writeDouble(posY());
buffer.writeDouble(posZ());
buffer.writeByte(pitch());
buffer.writeByte(yaw());
buffer.writeByte(headYaw());
buffer.writeVarInt(velX());
buffer.writeVarInt(velY());
buffer.writeVarInt(velZ());
buffer.writeByteArray(customPayload());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package net.neoforged.neoforge.network.payload;

import io.netty.buffer.Unpooled;
import java.util.function.Consumer;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.inventory.MenuType;
import net.neoforged.neoforge.internal.versions.neoforge.NeoForgeVersion;

public record AdvancedOpenScreenPayload(
int windowId,
MenuType<?> menuType,
Component name,
byte[] additionalData
) implements CustomPacketPayload {
public static final ResourceLocation ID = new ResourceLocation(NeoForgeVersion.MOD_ID, "advanced_open_screen");

public AdvancedOpenScreenPayload(int windowId, MenuType<?> menuType, Component name, Consumer<FriendlyByteBuf> dataWriter) {
this(windowId, menuType, name, writeCustomData(dataWriter));
}

private static byte[] writeCustomData(Consumer<FriendlyByteBuf> dataWriter) {
final FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
try {
dataWriter.accept(buf);
return buf.array();
} finally {
buf.release();
}
}

public AdvancedOpenScreenPayload(FriendlyByteBuf buffer) {
this(buffer.readVarInt(), buffer.readById(BuiltInRegistries.MENU), buffer.readComponentTrusted(), buffer.readByteArray());
}
@Override
public void write(FriendlyByteBuf buffer) {
buffer.writeVarInt(windowId());
buffer.writeId(BuiltInRegistries.MENU, menuType());
buffer.writeComponent(name());
buffer.writeByteArray(additionalData());
}

@Override
public ResourceLocation id() {
return ID;
}
}

0 comments on commit 3a52359

Please sign in to comment.