2019-01-13 17:35:57 +00:00
|
|
|
/*
|
|
|
|
* Minecraft Forge
|
2019-02-10 22:57:03 +00:00
|
|
|
* Copyright (c) 2016-2019.
|
2019-01-13 17:35:57 +00:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation version 2.1
|
|
|
|
* of the License.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
|
2019-01-13 03:48:14 +00:00
|
|
|
package net.minecraftforge.fml.network;
|
|
|
|
|
2019-02-08 02:31:17 +00:00
|
|
|
import io.netty.buffer.Unpooled;
|
2019-01-13 03:48:14 +00:00
|
|
|
import net.minecraft.client.Minecraft;
|
|
|
|
import net.minecraft.entity.Entity;
|
|
|
|
import net.minecraft.entity.EntityTracker;
|
|
|
|
import net.minecraft.entity.EntityType;
|
|
|
|
import net.minecraft.network.PacketBuffer;
|
2019-02-08 02:31:17 +00:00
|
|
|
import net.minecraft.util.ResourceLocation;
|
2019-01-13 03:48:14 +00:00
|
|
|
import net.minecraft.util.math.MathHelper;
|
2019-02-14 02:06:39 +00:00
|
|
|
import net.minecraftforge.fml.ExtensionPoint;
|
|
|
|
import net.minecraftforge.fml.ModList;
|
2019-02-14 23:08:53 +00:00
|
|
|
import net.minecraft.util.registry.IRegistry;
|
2019-01-13 03:48:14 +00:00
|
|
|
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
|
|
|
|
|
|
|
import java.util.UUID;
|
|
|
|
import java.util.function.Supplier;
|
|
|
|
|
|
|
|
public class FMLPlayMessages
|
|
|
|
{
|
|
|
|
public static class SpawnEntity
|
|
|
|
{
|
|
|
|
private final Entity entity;
|
|
|
|
private final int typeId;
|
|
|
|
private final int entityId;
|
|
|
|
private final UUID uuid;
|
|
|
|
private final double posX, posY, posZ;
|
2019-01-13 17:51:03 +00:00
|
|
|
private final byte pitch, yaw, headYaw;
|
2019-01-13 03:48:14 +00:00
|
|
|
private final short velX, velY, velZ;
|
|
|
|
private final PacketBuffer buf;
|
|
|
|
|
|
|
|
SpawnEntity(Entity e)
|
|
|
|
{
|
|
|
|
this.entity = e;
|
2019-02-14 23:08:53 +00:00
|
|
|
this.typeId = IRegistry.field_212629_r.getId(e.getType());
|
2019-01-13 03:48:14 +00:00
|
|
|
this.entityId = e.getEntityId();
|
|
|
|
this.uuid = e.getUniqueID();
|
|
|
|
this.posX = e.posX;
|
|
|
|
this.posY = e.posY;
|
|
|
|
this.posZ = e.posZ;
|
|
|
|
this.pitch = (byte) MathHelper.floor(e.rotationPitch * 256.0F / 360.0F);
|
|
|
|
this.yaw = (byte) MathHelper.floor(e.rotationYaw * 256.0F / 360.0F);
|
2019-01-13 17:51:03 +00:00
|
|
|
this.headYaw = (byte) (e.getRotationYawHead() * 256.0F / 360.0F);
|
2019-01-13 03:48:14 +00:00
|
|
|
this.velX = (short)(MathHelper.clamp(e.motionX, -3.9D, 3.9D) * 8000.0D);
|
|
|
|
this.velY = (short)(MathHelper.clamp(e.motionY, -3.9D, 3.9D) * 8000.0D);
|
|
|
|
this.velZ = (short)(MathHelper.clamp(e.motionZ, -3.9D, 3.9D) * 8000.0D);
|
|
|
|
this.buf = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
private SpawnEntity(int typeId, int entityId, UUID uuid, double posX, double posY, double posZ,
|
2019-01-13 17:51:03 +00:00
|
|
|
byte pitch, byte yaw, byte headYaw, short velX, short velY, short velZ, PacketBuffer buf)
|
2019-01-13 03:48:14 +00:00
|
|
|
{
|
|
|
|
this.entity = null;
|
|
|
|
this.typeId = typeId;
|
|
|
|
this.entityId = entityId;
|
|
|
|
this.uuid = uuid;
|
|
|
|
this.posX = posX;
|
|
|
|
this.posY = posY;
|
|
|
|
this.posZ = posZ;
|
|
|
|
this.pitch = pitch;
|
|
|
|
this.yaw = yaw;
|
2019-01-13 17:51:03 +00:00
|
|
|
this.headYaw = headYaw;
|
2019-01-13 03:48:14 +00:00
|
|
|
this.velX = velX;
|
|
|
|
this.velY = velY;
|
|
|
|
this.velZ = velZ;
|
|
|
|
this.buf = buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void encode(SpawnEntity msg, PacketBuffer buf)
|
|
|
|
{
|
|
|
|
buf.writeVarInt(msg.typeId);
|
|
|
|
buf.writeInt(msg.entityId);
|
|
|
|
buf.writeLong(msg.uuid.getMostSignificantBits());
|
|
|
|
buf.writeLong(msg.uuid.getLeastSignificantBits());
|
|
|
|
buf.writeDouble(msg.posX);
|
|
|
|
buf.writeDouble(msg.posY);
|
|
|
|
buf.writeDouble(msg.posZ);
|
|
|
|
buf.writeByte(msg.pitch);
|
|
|
|
buf.writeByte(msg.yaw);
|
2019-01-13 17:51:03 +00:00
|
|
|
buf.writeByte(msg.headYaw);
|
2019-01-13 03:48:14 +00:00
|
|
|
buf.writeShort(msg.velX);
|
|
|
|
buf.writeShort(msg.velY);
|
|
|
|
buf.writeShort(msg.velZ);
|
|
|
|
if (msg.entity instanceof IEntityAdditionalSpawnData)
|
|
|
|
{
|
|
|
|
((IEntityAdditionalSpawnData) msg.entity).writeSpawnData(buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static SpawnEntity decode(PacketBuffer buf)
|
|
|
|
{
|
|
|
|
return new SpawnEntity(
|
|
|
|
buf.readVarInt(),
|
|
|
|
buf.readInt(),
|
|
|
|
new UUID(buf.readLong(), buf.readLong()),
|
|
|
|
buf.readDouble(), buf.readDouble(), buf.readDouble(),
|
2019-01-13 17:51:03 +00:00
|
|
|
buf.readByte(), buf.readByte(), buf.readByte(),
|
2019-01-13 03:48:14 +00:00
|
|
|
buf.readShort(), buf.readShort(), buf.readShort(),
|
|
|
|
buf
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void handle(SpawnEntity msg, Supplier<NetworkEvent.Context> ctx)
|
|
|
|
{
|
|
|
|
ctx.get().enqueueWork(() -> {
|
2019-02-14 23:08:53 +00:00
|
|
|
EntityType<?> type = IRegistry.field_212629_r.get(msg.typeId);
|
2019-01-13 03:48:14 +00:00
|
|
|
if (type == null)
|
|
|
|
{
|
|
|
|
throw new RuntimeException(String.format("Could not spawn entity (id %d) with unknown type at (%f, %f, %f)", msg.entityId, msg.posX, msg.posY, msg.posZ));
|
|
|
|
}
|
|
|
|
|
|
|
|
Entity e = type.handleSpawnMessage(Minecraft.getInstance().world, msg);
|
|
|
|
if (e == null)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
EntityTracker.updateServerPosition(e, msg.posX, msg.posY, msg.posZ);
|
2019-01-13 17:51:03 +00:00
|
|
|
e.setPositionAndRotation(msg.posX, msg.posY, msg.posZ, (msg.pitch * 360) / 256.0F, (msg.yaw * 360) / 256.0F);
|
|
|
|
e.setRotationYawHead((msg.headYaw * 360) / 256.0F);
|
|
|
|
e.setRenderYawOffset((msg.headYaw * 360) / 256.0F);
|
2019-01-13 03:48:14 +00:00
|
|
|
|
|
|
|
Entity[] parts = e.getParts();
|
|
|
|
if (parts != null)
|
|
|
|
{
|
|
|
|
int offset = msg.entityId - e.getEntityId();
|
|
|
|
for (Entity part : parts)
|
|
|
|
{
|
|
|
|
part.setEntityId(part.getEntityId() + offset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
e.setEntityId(msg.entityId);
|
|
|
|
e.setUniqueId(msg.uuid);
|
|
|
|
Minecraft.getInstance().world.addEntityToWorld(msg.entityId, e);
|
|
|
|
e.setVelocity(msg.velX / 8000.0, msg.velY / 8000.0, msg.velZ / 8000.0);
|
|
|
|
if (e instanceof IEntityAdditionalSpawnData)
|
|
|
|
{
|
|
|
|
((IEntityAdditionalSpawnData) e).readSpawnData(msg.buf);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
ctx.get().setPacketHandled(true);
|
|
|
|
}
|
|
|
|
}
|
2019-02-08 02:31:17 +00:00
|
|
|
|
|
|
|
public static class OpenContainer
|
|
|
|
{
|
|
|
|
private final ResourceLocation id;
|
|
|
|
private final int windowId;
|
2019-02-14 02:06:39 +00:00
|
|
|
private final PacketBuffer additionalData;
|
2019-02-08 02:31:17 +00:00
|
|
|
|
2019-02-14 02:06:39 +00:00
|
|
|
OpenContainer(ResourceLocation id, int windowId, PacketBuffer additionalData)
|
2019-02-08 02:31:17 +00:00
|
|
|
{
|
|
|
|
this.id = id;
|
|
|
|
this.windowId = windowId;
|
|
|
|
this.additionalData = additionalData;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void encode(OpenContainer msg, PacketBuffer buf)
|
|
|
|
{
|
|
|
|
buf.writeResourceLocation(msg.id);
|
|
|
|
buf.writeVarInt(msg.windowId);
|
2019-02-14 04:25:48 +00:00
|
|
|
buf.writeByteArray(msg.additionalData.readByteArray());
|
2019-02-08 02:31:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public static OpenContainer decode(PacketBuffer buf)
|
|
|
|
{
|
2019-02-14 02:06:39 +00:00
|
|
|
return new OpenContainer(buf.readResourceLocation(), buf.readVarInt(), new PacketBuffer(Unpooled.wrappedBuffer(buf.readByteArray(32600))));
|
2019-02-08 02:31:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public static void handle(OpenContainer msg, Supplier<NetworkEvent.Context> ctx)
|
|
|
|
{
|
2019-02-14 02:06:39 +00:00
|
|
|
ctx.get().enqueueWork(() -> ModList.get().getModContainerById(msg.id.getNamespace()).ifPresent(mc->
|
|
|
|
mc.getCustomExtension(ExtensionPoint.GUIFACTORY).map(f -> f.apply(msg)).ifPresent(gui-> {
|
|
|
|
Minecraft.getInstance().displayGuiScreen(gui);
|
|
|
|
Minecraft.getInstance().player.openContainer.windowId = msg.windowId;
|
|
|
|
})));
|
2019-02-08 02:31:17 +00:00
|
|
|
ctx.get().setPacketHandled(true);
|
|
|
|
}
|
2019-02-14 02:06:39 +00:00
|
|
|
|
|
|
|
public final ResourceLocation getId() {
|
|
|
|
return this.id;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getWindowId() {
|
|
|
|
return windowId;
|
|
|
|
}
|
|
|
|
|
|
|
|
public PacketBuffer getAdditionalData() {
|
|
|
|
return additionalData;
|
|
|
|
}
|
2019-02-08 02:31:17 +00:00
|
|
|
}
|
2019-01-13 03:48:14 +00:00
|
|
|
}
|