mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-12 16:27:47 +00:00
Make default Entity.getAddPacket automatically use Forge's enhanced spawn packet if nessasary.
This spawn packet needs to be re-designed, it is effectively only there to hook into creating the new entity instance. This will be re-evaluated during the cleanup in 1.21+
This commit is contained in:
8 files changed
+78
-53
No files matched your search
@@ -30,6 +30,7 @@ import com.mojang.serialization.Dynamic;
|
||||
import com.mojang.serialization.DynamicOps;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.Commands;
|
||||
@@ -42,6 +43,7 @@ import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.ClickEvent;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
@@ -96,6 +98,7 @@ import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.syncher.EntityDataSerializer;
|
||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket;
|
||||
import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket;
|
||||
import net.minecraft.world.item.alchemy.Potion;
|
||||
@@ -116,6 +119,7 @@ import net.minecraftforge.common.util.BrainBuilder;
|
||||
import net.minecraftforge.common.util.Lazy;
|
||||
import net.minecraftforge.common.util.MavenVersionStringHelper;
|
||||
import net.minecraftforge.common.util.MutableHashedLinkedMap;
|
||||
import net.minecraftforge.entity.IEntityAdditionalSpawnData;
|
||||
import net.minecraftforge.event.AnvilUpdateEvent;
|
||||
import net.minecraftforge.event.BuildCreativeModeTabContentsEvent;
|
||||
import net.minecraftforge.event.DifficultyChangeEvent;
|
||||
@@ -166,7 +170,10 @@ import net.minecraftforge.fml.util.thread.EffectiveSide;
|
||||
import net.minecraftforge.network.ConnectionType;
|
||||
import net.minecraftforge.network.ICustomPacket;
|
||||
import net.minecraftforge.network.NetworkContext;
|
||||
import net.minecraftforge.network.NetworkDirection;
|
||||
import net.minecraftforge.network.NetworkInitialization;
|
||||
import net.minecraftforge.network.NetworkRegistry;
|
||||
import net.minecraftforge.network.packets.SpawnEntity;
|
||||
import net.minecraftforge.resource.ResourcePackLoader;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.minecraftforge.registries.ForgeRegistry;
|
||||
@@ -1251,4 +1258,16 @@ public class ForgeHooks {
|
||||
LOGGER.info("Connected to a modded server.");
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static Packet<ClientGamePacketListener> getEntitySpawnPacket(Entity entity) {
|
||||
if (!(entity instanceof IEntityAdditionalSpawnData add))
|
||||
throw new IllegalArgumentException(entity.getClass() + " is not an instance of " + IEntityAdditionalSpawnData.class);
|
||||
|
||||
var play = NetworkInitialization.PLAY;
|
||||
var msg = new SpawnEntity(entity);
|
||||
var data = play.toBuffer(msg);
|
||||
@SuppressWarnings("unchecked")
|
||||
var pkt = (Packet<ClientGamePacketListener>)NetworkDirection.PLAY_TO_CLIENT.buildPacket(data, play.getName()).getThis();
|
||||
return pkt;
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@ public abstract class Channel<MSG> {
|
||||
return NetworkContext.get(connection).getRemoteChannels().contains(getName());
|
||||
}
|
||||
|
||||
protected abstract FriendlyByteBuf toBuffer(MSG message);
|
||||
public abstract FriendlyByteBuf toBuffer(MSG message);
|
||||
|
||||
// Package private so we can call from ourselves.
|
||||
Packet<?> toVanillaPacket(Connection connection, MSG message) {
|
||||
|
||||
@@ -42,7 +42,7 @@ public class EventNetworkChannel extends Channel<FriendlyByteBuf> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FriendlyByteBuf toBuffer(FriendlyByteBuf message) {
|
||||
public FriendlyByteBuf toBuffer(FriendlyByteBuf message) {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
@@ -94,16 +94,16 @@ public class NetworkInitialization {
|
||||
.consumerNetworkThread(CONTEXT, ForgePacketHandler::handleModMismatchData)
|
||||
.add()
|
||||
|
||||
.messageBuilder(SpawnEntity.class)
|
||||
.messageBuilder(SpawnEntity.class, NetworkDirection.PLAY_TO_CLIENT)
|
||||
.decoder(SpawnEntity::decode)
|
||||
.encoder(SpawnEntity::encode)
|
||||
.consumerNetworkThread(SpawnEntity::handle)
|
||||
.consumerMainThread(SpawnEntity::handle)
|
||||
.add()
|
||||
|
||||
.messageBuilder(OpenContainer.class)
|
||||
.decoder(OpenContainer::decode)
|
||||
.encoder(OpenContainer::encode)
|
||||
.consumerNetworkThread(OpenContainer::handle)
|
||||
.consumerMainThread(OpenContainer::handle)
|
||||
.add();
|
||||
|
||||
public static void init() {
|
||||
|
||||
@@ -334,7 +334,7 @@ public class SimpleChannel extends Channel<Object> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected FriendlyByteBuf toBuffer(Object message) {
|
||||
public FriendlyByteBuf toBuffer(Object message) {
|
||||
var msg = byType.get(message.getClass());
|
||||
|
||||
if (msg == null) {
|
||||
|
||||
@@ -10,8 +10,6 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
import io.netty.buffer.Unpooled;
|
||||
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.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
@@ -55,23 +53,20 @@ public class OpenContainer {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void handle(OpenContainer msg, CustomPayloadEvent.Context ctx) {
|
||||
ctx.enqueueWork(() -> {
|
||||
try {
|
||||
var mc = Minecraft.getInstance();
|
||||
var inv = mc.player.getInventory();
|
||||
MenuScreens.getScreenFactory(msg.getType(), mc, msg.getWindowId(), msg.getName()).ifPresent(f -> {
|
||||
AbstractContainerMenu c = msg.getType().create(msg.getWindowId(), inv, msg.getAdditionalData());
|
||||
try {
|
||||
var mc = Minecraft.getInstance();
|
||||
var inv = mc.player.getInventory();
|
||||
var factory = MenuScreens.getScreenFactory(msg.getType(), mc, msg.getWindowId(), msg.getName());
|
||||
factory.ifPresent(f -> {
|
||||
var c = msg.getType().create(msg.getWindowId(), inv, msg.getAdditionalData());
|
||||
|
||||
Screen s = ((MenuScreens.ScreenConstructor<AbstractContainerMenu, ?>)f).create(c, inv, msg.getName());
|
||||
mc.player.containerMenu = ((MenuAccess<?>)s).getMenu();
|
||||
mc.setScreen(s);
|
||||
});
|
||||
} finally {
|
||||
msg.getAdditionalData().release();
|
||||
}
|
||||
|
||||
});
|
||||
ctx.setPacketHandled(true);
|
||||
var s = ((MenuScreens.ScreenConstructor<AbstractContainerMenu, ?>)f).create(c, inv, msg.getName());
|
||||
mc.player.containerMenu = s.getMenu();
|
||||
mc.setScreen(s);
|
||||
});
|
||||
} finally {
|
||||
msg.getAdditionalData().release();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
|
||||
@@ -8,6 +8,8 @@ package net.minecraftforge.network.packets;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
@@ -30,6 +32,7 @@ import net.minecraftforge.event.network.CustomPayloadEvent;
|
||||
* {@link EntityType})
|
||||
* see {@link EntityType.Builder#setCustomClientFactory}.
|
||||
*/
|
||||
// TODO: Re-write this packet into something simpler. This is literally just ClientboundAddEntityPacket with an extra byte[]
|
||||
public class SpawnEntity {
|
||||
private final Entity entity;
|
||||
private final int typeId;
|
||||
@@ -41,7 +44,8 @@ public class SpawnEntity {
|
||||
private final FriendlyByteBuf buf;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
SpawnEntity(Entity e) {
|
||||
@ApiStatus.Internal
|
||||
public SpawnEntity(Entity e) {
|
||||
this.entity = e;
|
||||
this.typeId = BuiltInRegistries.ENTITY_TYPE.getId(e.getType()); //TODO: Codecs
|
||||
this.entityId = e.getId();
|
||||
@@ -123,36 +127,33 @@ public class SpawnEntity {
|
||||
}
|
||||
|
||||
public static void handle(SpawnEntity msg, CustomPayloadEvent.Context ctx) {
|
||||
ctx.enqueueWork(() -> {
|
||||
try {
|
||||
@SuppressWarnings("deprecation")
|
||||
EntityType<?> type = BuiltInRegistries.ENTITY_TYPE.byId(msg.typeId);
|
||||
Optional<Level> world = LogicalSidedProvider.CLIENTWORLD.get(ctx.getDirection().getReceptionSide());
|
||||
Entity e = world.map(w -> type.customClientSpawn(msg, w)).orElse(null);
|
||||
if (e == null)
|
||||
return;
|
||||
try {
|
||||
@SuppressWarnings("deprecation")
|
||||
EntityType<?> type = BuiltInRegistries.ENTITY_TYPE.byId(msg.typeId);
|
||||
Optional<Level> world = LogicalSidedProvider.CLIENTWORLD.get(ctx.getDirection().getReceptionSide());
|
||||
Entity e = world.map(w -> type.customClientSpawn(msg, w)).orElse(null);
|
||||
if (e == null)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Sets the postiion on the client, Mirrors what
|
||||
* Entity#recreateFromPacket and LivingEntity#recreateFromPacket does.
|
||||
*/
|
||||
e.syncPacketPositionCodec(msg.posX, msg.posY, msg.posZ);
|
||||
e.absMoveTo(msg.posX, msg.posY, msg.posZ, (msg.yaw * 360) / 256.0F, (msg.pitch * 360) / 256.0F);
|
||||
e.setYHeadRot((msg.headYaw * 360) / 256.0F);
|
||||
e.setYBodyRot((msg.headYaw * 360) / 256.0F);
|
||||
/*
|
||||
* Sets the postiion on the client, Mirrors what
|
||||
* Entity#recreateFromPacket and LivingEntity#recreateFromPacket does.
|
||||
*/
|
||||
e.syncPacketPositionCodec(msg.posX, msg.posY, msg.posZ);
|
||||
e.absMoveTo(msg.posX, msg.posY, msg.posZ, (msg.yaw * 360) / 256.0F, (msg.pitch * 360) / 256.0F);
|
||||
e.setYHeadRot((msg.headYaw * 360) / 256.0F);
|
||||
e.setYBodyRot((msg.headYaw * 360) / 256.0F);
|
||||
|
||||
e.setId(msg.entityId);
|
||||
e.setUUID(msg.uuid);
|
||||
if (world.orElse(null) instanceof ClientLevel cworld)
|
||||
cworld.addEntity(e);
|
||||
e.lerpMotion(msg.velX / 8000.0, msg.velY / 8000.0, msg.velZ / 8000.0);
|
||||
if (e instanceof IEntityAdditionalSpawnData entityAdditionalSpawnData)
|
||||
entityAdditionalSpawnData.readSpawnData(msg.buf);
|
||||
} finally {
|
||||
msg.buf.release();
|
||||
}
|
||||
});
|
||||
ctx.setPacketHandled(true);
|
||||
e.setId(msg.entityId);
|
||||
e.setUUID(msg.uuid);
|
||||
if (world.orElse(null) instanceof ClientLevel cworld)
|
||||
cworld.addEntity(e);
|
||||
e.lerpMotion(msg.velX / 8000.0, msg.velY / 8000.0, msg.velZ / 8000.0);
|
||||
if (e instanceof IEntityAdditionalSpawnData entityAdditionalSpawnData)
|
||||
entityAdditionalSpawnData.readSpawnData(msg.buf);
|
||||
} finally {
|
||||
msg.buf.release();
|
||||
}
|
||||
}
|
||||
|
||||
public Entity getEntity() {
|
||||
|
||||
Reference in new issue
Block a user