136 lines
5.4 KiB
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);
|
|
}
|
|
}
|