ForgePatch/src/main/java/net/minecraftforge/fml/common/network/internal/EntitySpawnHandler.java

136 lines
5.4 KiB
Java

package net.minecraftforge.fml.common.network.internal;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.apache.logging.log4j.Level;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityTracker;
import net.minecraft.util.IThreadListener;
import net.minecraft.world.World;
import net.minecraftforge.fml.client.FMLClientHandler;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.FMLLog;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.ModContainer;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.network.internal.FMLMessage.EntityMessage;
import net.minecraftforge.fml.common.registry.EntityRegistry;
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
import net.minecraftforge.fml.common.registry.IThrowableEntity;
import net.minecraftforge.fml.common.registry.EntityRegistry.EntityRegistration;
import com.google.common.base.Throwables;
public class EntitySpawnHandler extends SimpleChannelInboundHandler<FMLMessage.EntityMessage> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, final EntityMessage msg) throws Exception
{
IThreadListener thread = FMLCommonHandler.instance().getWorldThread(ctx.channel().attr(NetworkRegistry.NET_HANDLER).get());
if (thread.isCallingFromMinecraftThread())
{
process(msg);
}
else
{
thread.addScheduledTask(new Runnable()
{
public void run()
{
EntitySpawnHandler.this.process(msg);
}
});
}
}
private void process(EntityMessage msg)
{
if (msg.getClass().equals(FMLMessage.EntitySpawnMessage.class))
{
spawnEntity((FMLMessage.EntitySpawnMessage)msg);
}
}
private void spawnEntity(FMLMessage.EntitySpawnMessage spawnMsg)
{
ModContainer mc = Loader.instance().getIndexedModList().get(spawnMsg.modId);
EntityRegistration er = EntityRegistry.instance().lookupModSpawn(mc, spawnMsg.modEntityTypeId);
if (er == null)
{
throw new RuntimeException( "Could not spawn mod entity ModID: " + spawnMsg.modId + " EntityID: " + spawnMsg.modEntityTypeId +
" at ( " + spawnMsg.rawX + "," + spawnMsg.rawY + ", " + spawnMsg.rawZ + ") Please contact mod author or server admin.");
}
WorldClient wc = FMLClientHandler.instance().getWorldClient();
Class<? extends Entity> cls = er.getEntityClass();
try
{
Entity entity;
if (er.hasCustomSpawning())
{
entity = er.doCustomSpawning(spawnMsg);
} else
{
entity = cls.getConstructor(World.class).newInstance(wc);
int offset = spawnMsg.entityId - entity.getEntityId();
entity.setEntityId(spawnMsg.entityId);
entity.setUniqueId(spawnMsg.entityUUID);
entity.setLocationAndAngles(spawnMsg.rawX, spawnMsg.rawY, spawnMsg.rawZ, spawnMsg.scaledYaw, spawnMsg.scaledPitch);
if (entity instanceof EntityLiving)
{
((EntityLiving) entity).rotationYawHead = spawnMsg.scaledHeadYaw;
}
Entity parts[] = entity.getParts();
if (parts != null)
{
for (int j = 0; j < parts.length; j++)
{
parts[j].setEntityId(parts[j].getEntityId() + offset);
}
}
}
EntityTracker.updateServerPosition(entity, spawnMsg.rawX, spawnMsg.rawY, spawnMsg.rawZ);
EntityPlayerSP clientPlayer = FMLClientHandler.instance().getClientPlayerEntity();
if (entity instanceof IThrowableEntity)
{
Entity thrower = clientPlayer.getEntityId() == spawnMsg.throwerId ? clientPlayer : wc.getEntityByID(spawnMsg.throwerId);
((IThrowableEntity) entity).setThrower(thrower);
}
if (spawnMsg.dataWatcherList != null)
{
entity.getDataManager().setEntryValues(spawnMsg.dataWatcherList);
}
if (spawnMsg.throwerId > 0)
{
entity.setVelocity(spawnMsg.speedScaledX, spawnMsg.speedScaledY, spawnMsg.speedScaledZ);
}
if (entity instanceof IEntityAdditionalSpawnData)
{
((IEntityAdditionalSpawnData) entity).readSpawnData(spawnMsg.dataStream);
}
wc.addEntityToWorld(spawnMsg.entityId, entity);
} catch (Exception e)
{
FMLLog.log(Level.ERROR, e, "A severe problem occurred during the spawning of an entity at ( " + spawnMsg.rawX + "," + spawnMsg.rawY + ", " + spawnMsg.rawZ +")");
throw Throwables.propagate(e);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception
{
FMLLog.log(Level.ERROR, cause, "EntitySpawnHandler exception");
super.exceptionCaught(ctx, cause);
}
}