Created a Entity tracking ans spawning system.

Mod creators should call MinecraftForge.registerEntity to register a entity.
All entity ID numbers are Mod Unique. Meaning two mods can have Entity #1.
Added client and server side packet handlers for the 'Forge' channel. For use in internal packets such as the new Spawn packet.
Updated the build scripts to copy over unique server source files now that there actually are some.
For modders:
  If you have a entity that used MLMP's 'owner' system, you should have your entity implement IThrowableEntity
  If you have a entity that implments MLMLP's ISpawnable, you should implement ISpawnHandler.
They provide the same functionality, just in a cleaner, more orginized way and will be the method used when we eventually drop MLMP.
This commit is contained in:
LexManos committed 2012-02-10 03:06:08 -08:00
1 parent fcc781b100
commit 2ea1775224
17 files changed
+587 -55

No files matched your search

+1
View File
@@ -4,6 +4,7 @@
@mkdir src
xcopy /Y /E src_work\* src\
xcopy /Y /E forge\forge_client\src\net\* src\minecraft\net
xcopy /Y /E forge\forge_server\src\net\* src\minecraft_server\net
xcopy /Y /E forge\forge_common\net\* src\minecraft\net
xcopy /Y /E forge\forge_common\net\* src\minecraft_server\net
+1
View File
@@ -7,6 +7,7 @@ rm -rf src bin src_forge
cp -a src_work src_forge
cp -a forge/forge_client/src/net/* src_forge/minecraft/net/
cp -a forge/forge_server/src/net/* src_forge/minecraft_server/net/
cp -a forge/forge_common/net/* src_forge/minecraft/net/
cp -a forge/forge_common/net/* src_forge/minecraft_server/net/
@@ -87,4 +87,20 @@ public class MinecraftForgeClient {
public static ICustomItemRenderer getCustomItemRenderer (int itemID) {
return customItemRenderers [itemID];
}
private static boolean hasInit = false;
public static void init()
{
if (hasInit)
{
return;
}
hasInit = true;
ForgeHooks.setPacketHandler(new PacketHandlerClient());
}
static
{
init();
}
}
@@ -0,0 +1,99 @@
package net.minecraft.src.forge;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.logging.Level;
import net.minecraft.client.Minecraft;
import net.minecraft.src.Entity;
import net.minecraft.src.ModLoader;
import net.minecraft.src.NetworkManager;
import net.minecraft.src.World;
import net.minecraft.src.WorldClient;
public class PacketHandlerClient implements IPacketHandler
{
@Override
public void onPacketData(NetworkManager network, String channel, byte[] bytes)
{
DataInputStream data = new DataInputStream(new ByteArrayInputStream(bytes));
try
{
int packetID = data.read();
switch(packetID)
{
case ForgeHooks.FORGE_PACKET_SPAWN:
PacketEntitySpawn pkt = new PacketEntitySpawn();
pkt.readData(data);
onEntitySpawnPacket(pkt, data, ModLoader.getMinecraftInstance().theWorld);
break;
}
}
catch(IOException e)
{
ModLoader.getLogger().log(Level.SEVERE, "Exception in PacketHandlerClient.onPacketData", e);
e.printStackTrace();
}
}
public void onEntitySpawnPacket(PacketEntitySpawn packet, DataInputStream data, World world)
{
Class cls = MinecraftForge.getEntityClass(packet.modID, packet.typeID);
if (cls == null)
{
System.out.println("Could not find entity info for " + Integer.toHexString(packet.modID) + " : " + packet.typeID);
return;
}
double posX = (double)packet.posX / 32D;
double posY = (double)packet.posY / 32D;
double posZ = (double)packet.posZ / 32D;
try
{
Entity entity = (Entity)(cls.getConstructor(World.class, double.class, double.class, double.class).newInstance(world, posX, posY, posZ));
if (entity instanceof IThrowableEntity)
{
Minecraft mc = ModLoader.getMinecraftInstance();
Entity thrower = (mc.thePlayer.entityId == packet.throwerID ? mc.thePlayer : ((WorldClient)world).getEntityByID(packet.throwerID));
((IThrowableEntity)entity).setThrower(thrower);
}
entity.serverPosX = packet.posX;
entity.serverPosY = packet.posX;
entity.serverPosZ = packet.posZ;
entity.rotationYaw = 0.0F;
entity.rotationPitch = 0.0F;
Entity parts[] = entity.getParts();
if (parts != null)
{
int i = packet.entityID - entity.entityId;
for (int j = 0; j < parts.length; j++)
{
parts[j].entityId += i;
}
}
entity.entityId = packet.entityID;
if (packet.throwerID > 0)
{
entity.setVelocity(packet.speedX / 8000D, packet.speedY / 8000D, packet.speedZ / 8000D);
}
if (entity instanceof ISpawnHandler)
{
((ISpawnHandler)entity).readSpawnData(data);
}
((WorldClient)world).addEntityToWorld(packet.entityID, entity);
}
catch (Exception e)
{
e.printStackTrace();
ModLoader.getLogger().throwing("ForgeHooksClient", "onEntitySpawnPacket", e);
ModLoader.ThrowException(String.format("Error spawning entity of type %d for %s.", packet.typeID, MinecraftForge.getModByID(packet.modID)), e);
}
}
}
@@ -0,0 +1,21 @@
package net.minecraft.src.forge;
import net.minecraft.src.BaseMod;
public class EntityTrackerInfo
{
public final BaseMod Mod;
public final int ID;
public final int Range;
public final int UpdateFrequancy;
public final boolean SendVelocityInfo;
public EntityTrackerInfo(BaseMod mod, int ID, int range, int updateFrequancy, boolean sendVelocityInfo)
{
Mod = mod;
this.ID = ID;
Range = range;
UpdateFrequancy = updateFrequancy;
SendVelocityInfo = sendVelocityInfo;
}
}
@@ -15,9 +15,15 @@ import net.minecraft.src.Item;
import net.minecraft.src.EnumStatus;
import net.minecraft.src.ModLoader;
import net.minecraft.src.NetworkManager;
import net.minecraft.src.Packet;
import net.minecraft.src.Packet1Login;
import net.minecraft.src.Packet250CustomPayload;
import net.minecraft.src.World;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.*;
public class ForgeHooks {
@@ -165,37 +171,33 @@ public class ForgeHooks {
static int seedGrassWeight;
static {
plantGrassList=new ArrayList<ProbableItem>();
plantGrassList.add(new ProbableItem(
Block.plantYellow.blockID,0,1,0,20));
plantGrassList.add(new ProbableItem(
Block.plantRed.blockID,0,1,20,30));
plantGrassWeight=30;
plantGrassList = new ArrayList<ProbableItem>();
plantGrassList.add(new ProbableItem(Block.plantYellow.blockID, 0, 1, 0, 20));
plantGrassList.add(new ProbableItem(Block.plantRed.blockID, 0, 1, 20, 30));
plantGrassWeight = 30;
seedGrassList=new ArrayList<ProbableItem>();
seedGrassList.add(new ProbableItem(
Item.seeds.shiftedIndex,0,1,0,10));
seedGrassWeight=10;
seedGrassList = new ArrayList<ProbableItem>();
seedGrassList.add(new ProbableItem(Item.seeds.shiftedIndex, 0, 1, 0, 10));
seedGrassWeight = 10;
}
public static void plantGrassPlant(World world, int i, int j, int k) {
int n=world.rand.nextInt(plantGrassWeight);
ProbableItem pi=getRandomItem(plantGrassList,n);
if(pi==null) return;
world.setBlockAndMetadataWithNotify(i,j,k,pi.itemid,pi.meta);
int n = world.rand.nextInt(plantGrassWeight);
ProbableItem pi = getRandomItem(plantGrassList, n);
if (pi == null) return;
world.setBlockAndMetadataWithNotify(i, j, k, pi.itemid, pi.meta);
}
public static void addPlantGrass(int item, int md, int prop) {
plantGrassList.add(new ProbableItem(
item,md,1,plantGrassWeight,plantGrassWeight+prop));
plantGrassWeight+=prop;
plantGrassList.add(new ProbableItem(item, md, 1, plantGrassWeight, plantGrassWeight + prop));
plantGrassWeight += prop;
}
public static ItemStack getGrassSeed(World world) {
int n=world.rand.nextInt(seedGrassWeight);
ProbableItem pi=getRandomItem(seedGrassList,n);
if(pi==null) return null;
return new ItemStack(pi.itemid,pi.qty,pi.meta);
int n = world.rand.nextInt(seedGrassWeight);
ProbableItem pi = getRandomItem(seedGrassList,n);
if (pi == null) return null;
return new ItemStack(pi.itemid, pi.qty, pi.meta);
}
public static void addGrassSeed(int item, int md, int qty, int prop) {
@@ -206,22 +208,21 @@ public class ForgeHooks {
// Tool Path
// ------------------------------------------------------------
public static boolean canHarvestBlock(Block bl,
EntityPlayer player, int md) {
public static boolean canHarvestBlock(Block bl, EntityPlayer player, int md) {
if(bl.blockMaterial.getIsHarvestable())
return true;
ItemStack itemstack = player.inventory.getCurrentItem();
if(itemstack == null) return false;
if (itemstack == null) return false;
List tc=(List)toolClasses.get(itemstack.itemID);
if(tc==null) return itemstack.canHarvestBlock(bl);
Object[] ta=tc.toArray();
String cls=(String)ta[0]; int hvl=(Integer)ta[1];
List tc = (List)toolClasses.get(itemstack.itemID);
if (tc == null) return itemstack.canHarvestBlock(bl);
Object[] ta = tc.toArray();
String cls = (String)ta[0];
int hvl = (Integer)ta[1];
Integer bhl=(Integer)toolHarvestLevels.get(Arrays.asList(
bl.blockID,md,cls));
if(bhl==null) return itemstack.canHarvestBlock(bl);
if(bhl>hvl) return false;
Integer bhl = (Integer)toolHarvestLevels.get(Arrays.asList(bl.blockID, md, cls));
if(bhl == null) return itemstack.canHarvestBlock(bl);
if(bhl > hvl) return false;
return true;
}
@@ -326,6 +327,46 @@ public class ForgeHooks {
}
}
public static HashMap<Class, EntityTrackerInfo> entityTrackerMap = new HashMap<Class, EntityTrackerInfo>();
/**
* Builds the 'Spawn' packet using the Custom Payload packet on the 'Forge' channel.
* Supports entities that have custom spawn data, as well as the generic 'Owner' construct.
*
* @param entity The entity instance to spawn
* @return The spawn packet, or null if we arn't spawning it.
*/
public static Packet getEntitySpawnPacket(Entity entity)
{
EntityTrackerInfo info = MinecraftForge.getEntityTrackerInfo(entity, false);
if (info == null)
{
return null;
}
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream data = new DataOutputStream(bytes);
try
{
data.writeByte(FORGE_PACKET_SPAWN);
PacketEntitySpawn spawn = new PacketEntitySpawn(entity, info.Mod, info.ID);
spawn.writeData(data);
if (entity instanceof ISpawnHandler)
{
((ISpawnHandler)entity).writeSpawnData(data);
}
}
catch (IOException e)
{
e.printStackTrace();
}
Packet250CustomPayload pkt = new Packet250CustomPayload();
pkt.channel = "Forge";
pkt.data = bytes.toByteArray();
pkt.length = pkt.data.length;
return pkt;
}
public static final int majorVersion=0;
public static final int minorVersion=0;
@@ -340,5 +381,22 @@ public class ForgeHooks {
static HashMap toolClasses=new HashMap();
static HashMap toolHarvestLevels=new HashMap();
static HashSet toolEffectiveness=new HashSet();
private static IPacketHandler forgePacketHandler = null;
public static void setPacketHandler(IPacketHandler handler)
{
if (forgePacketHandler != null)
{
throw new RuntimeException("Attempted to set Forge's Internal packet handler after it was already set");
}
forgePacketHandler = handler;
}
public static IPacketHandler getPacketHandler()
{
return forgePacketHandler;
}
//Forge Packet ID Constants.
public static final int FORGE_ID = 0x040E9B47; //"Forge".hashCode();
public static final int FORGE_PACKET_SPAWN = 1;
}
@@ -0,0 +1,27 @@
package net.minecraft.src.forge;
import java.io.DataInputStream;
import java.io.DataOutputStream;
/**
* A interface for Entities that need extra information to be communicated
* between the server and client when they are spawned.
*/
public interface ISpawnHandler
{
/**
* Called by the server when constructing the spawn packet.
* Data should be added to the provided stream.
*
* @param data The packet data stream
*/
public void writeSpawnData(DataOutputStream data);
/**
* Called by the client when it receives a Entity spawn packet.
* Data should be read out of the stream in the same way as it was written.
*
* @param data The packet data stream
*/
public void readSpawnData(DataInputStream data);
}
@@ -0,0 +1,22 @@
package net.minecraft.src.forge;
import net.minecraft.src.Entity;
/**
* This interface should be implemented by an Entity that can be 'thrown', like snowballs.
* This was created to mimic ModLoaderMP's 'owner' functionality.
*/
public interface IThrowableEntity
{
/**
* Gets the entity that threw/created this entity.
* @return The owner instance, Null if none.
*/
public Entity getThrower();
/**
* Sets the entity that threw/created this entity.
* @param entity The new thrower/creator.
*/
public void setThrower(Entity entity);
}
@@ -408,12 +408,12 @@ public class MessageManager
{
if (channel.equals("Forge"))
{
/* Currently Forge has no custom tasks, but will eventually have
* Mod list testing, and whatever, when we remove ModLoaderMP
*
byte[] tmpData = new byte[data.length];
System.arraycopy(data, 0, tmpData, 0, data.length);
*/
if (ForgeHooks.getPacketHandler() != null)
{
byte[] tmpData = new byte[data.length];
System.arraycopy(data, 0, tmpData, 0, data.length);
ForgeHooks.getPacketHandler().onPacketData(manager, channel, tmpData);
}
}
if (connections.contains(manager))
@@ -5,10 +5,13 @@
package net.minecraft.src.forge;
import net.minecraft.src.BaseMod;
import net.minecraft.src.Block;
import net.minecraft.src.Entity;
import net.minecraft.src.EntityMinecart;
import net.minecraft.src.Item;
import net.minecraft.src.ItemStack;
import net.minecraft.src.ModLoader;
import net.minecraft.src.World;
import java.util.*;
@@ -382,17 +385,25 @@ public class MinecraftForge {
* mods that use recent, new, or unstable APIs to prevent
* incompatibilities.
*/
public static void versionDetectStrict(String modname,
int major, int minor, int revision) {
if(major!=ForgeHooks.majorVersion) {
public static void versionDetectStrict(String modname, int major, int minor, int revision)
{
if(major!=ForgeHooks.majorVersion)
{
killMinecraft(modname,"MinecraftForge Major Version Mismatch, expecting "+major+".x.x");
} else if(minor!=ForgeHooks.minorVersion) {
if(minor>ForgeHooks.minorVersion) {
}
else if(minor!=ForgeHooks.minorVersion)
{
if(minor>ForgeHooks.minorVersion)
{
killMinecraft(modname,"MinecraftForge Too Old, need at least "+major+"."+minor+"."+revision);
} else {
}
else
{
killMinecraft(modname,"MinecraftForge minor version mismatch, expecting "+major+"."+minor+".x");
}
} else if(revision>ForgeHooks.revisionVersion) {
}
else if(revision>ForgeHooks.revisionVersion)
{
killMinecraft(modname,"MinecraftForge Too Old, need at least "+major+"."+minor+"."+revision);
}
}
@@ -775,6 +786,88 @@ public class MinecraftForge {
}
return ret;
}
/**
* Registers a Entity class tracking information. Used for sendingEntity
* information over the network.
*
* @param entityClass The class for the Entity
* @param mod The BaseMod that provides this Entity.
* @param ID The ID for the Entity. Needs to be unique combination of Mod and ID.
* @param range How close a player has to be to be informed this Entity exists.
* @param updateFrequancy How many ticks between checking and sending information updates for this Entity.
* @param sendVelocityInfo If velocity information should be included in the update information.
* @return True, if successfully registered. False if the class is already registered.
*/
public static boolean registerEntity(Class entityClass, BaseMod mod, int ID, int range, int updateFrequancy, boolean sendVelocityInfo)
{
if (ForgeHooks.entityTrackerMap.containsKey(entityClass))
{
return false;
}
ForgeHooks.entityTrackerMap.put(entityClass, new EntityTrackerInfo(mod, ID, range, updateFrequancy, sendVelocityInfo));
return true;
}
/**
* Retrieves the tracker info for input Entity.
*
* @param entity The Entity to find tracking info for.
* @param checkSupers If we should check the super-classes for a match.
* @return The information, or Null if not found.
*/
public static EntityTrackerInfo getEntityTrackerInfo(Entity entity, boolean checkSupers)
{
for (Map.Entry<Class, EntityTrackerInfo> entry : ForgeHooks.entityTrackerMap.entrySet())
{
if (entry.getKey().isInstance(entity))
{
if (!checkSupers || entry.getKey() == entry.getClass())
{
return entry.getValue();
}
}
}
return null;
}
/**
* Retrieves the Class for a registered Entity based on ModID and Entity Type.
*
* @param modID The ID of the mod (mod.toString().hashCode())
* @param type The ID for the Entity
* @return The entity Class, or null if not found.
*/
public static Class getEntityClass(int modID, int type)
{
for (Map.Entry<Class, EntityTrackerInfo> entry : ForgeHooks.entityTrackerMap.entrySet())
{
EntityTrackerInfo info = entry.getValue();
if (type == info.ID && modID == info.Mod.toString().hashCode())
{
return entry.getKey();
}
}
return null;
}
/**
* Retrieves a mod instance based on it's ID. (toString().hashCode())
*
* @param id The mod ID
* @return The mod, or null if not found
*/
public static BaseMod getModByID(int id)
{
for(BaseMod mod : (List<BaseMod>)ModLoader.getLoadedMods())
{
if (mod.toString().hashCode() == id)
{
return mod;
}
}
return null;
}
static
@@ -0,0 +1,89 @@
package net.minecraft.src.forge;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import net.minecraft.src.BaseMod;
import net.minecraft.src.Entity;
import net.minecraft.src.MathHelper;
public class PacketEntitySpawn
{
public int entityID;
public int posX;
public int posY;
public int posZ;
public int speedX;
public int speedY;
public int speedZ;
public int typeID;
public int modID;
public int throwerID;
public PacketEntitySpawn(){}
public PacketEntitySpawn(Entity ent, BaseMod mod, int type)
{
entityID = ent.entityId;
posX = MathHelper.floor_double(ent.posX * 32D);
posY = MathHelper.floor_double(ent.posY * 32D);
posZ = MathHelper.floor_double(ent.posZ * 32D);
typeID = type;
modID = mod.toString().hashCode();
if (ent instanceof IThrowableEntity)
{
Entity owner = ((IThrowableEntity)ent).getThrower();
throwerID = (owner == null ? ent.entityId : owner.entityId);
double maxVel = 3.9D;
double mX = ent.motionX;
double mY = ent.motionY;
double mZ = ent.motionZ;
if (mX < -maxVel) mX = -maxVel;
if (mY < -maxVel) mY = -maxVel;
if (mZ < -maxVel) mZ = -maxVel;
if (mX > maxVel) mX = maxVel;
if (mY > maxVel) mY = maxVel;
if (mZ > maxVel) mZ = maxVel;
speedX = (int)(mX * 8000D);
speedY = (int)(mY * 8000D);
speedZ = (int)(mZ * 8000D);
}
}
public void writeData(DataOutputStream data) throws IOException
{
data.writeInt(modID);
data.writeInt(entityID);
data.writeByte(typeID);
data.writeInt(posX);
data.writeInt(posY);
data.writeInt(posZ);
data.writeInt(throwerID);
if (throwerID != 0)
{
data.writeShort(speedX);
data.writeShort(speedY);
data.writeShort(speedZ);
}
}
public void readData(DataInputStream data) throws IOException
{
modID = data.readInt();
entityID = data.readInt();
typeID = data.readByte();
posX = data.readInt();
posY = data.readInt();
posZ = data.readInt();
throwerID = data.readInt();
if (throwerID != 0)
{
speedX = data.readShort();
speedY = data.readShort();
speedX = data.readShort();
}
}
}
@@ -0,0 +1,45 @@
package net.minecraft.src.forge;
import java.util.Map;
import net.minecraft.src.Entity;
import net.minecraft.src.EntityTracker;
public class ForgeHooksServer
{
/**
* Called when a Entity is being added to a EntityTracker.
* If we have valid info, register the entity.
*
* @param tracker The EntityTracker instance
* @param entity The Entity to add
* @return True if we registered the Entity
*/
public static boolean OnTrackEntity(EntityTracker tracker, Entity entity)
{
EntityTrackerInfo info = MinecraftForge.getEntityTrackerInfo(entity, true);
if (info != null)
{
tracker.trackEntity(entity, info.Range, info.UpdateFrequancy, info.SendVelocityInfo);
return true;
}
return false;
}
private static boolean hasInit = false;
public static void init()
{
if (hasInit)
{
return;
}
hasInit = true;
ForgeHooks.setPacketHandler(new PacketHandlerServer());
}
static
{
init();
}
}
@@ -0,0 +1,11 @@
package net.minecraft.src.forge;
import net.minecraft.src.NetworkManager;
public class PacketHandlerServer implements IPacketHandler
{
@Override
public void onPacketData(NetworkManager network, String channel, byte[] data)
{
}
}
@@ -53,7 +53,7 @@
- addToSendQueue(new Packet1Login(mc.session.username, 23));
+ /**
+ * We use some of the unused fields in Packet 001 Login to identify the user as having Forge installed.
+ * This allows modded clients to connect to Vinella server without crashing.
+ * This allows modded clients to connect to Vanilla server without crashing.
+ * It also allows unmodded clients to connect to Forge server without crashing.
+ * Its a bit of a dirty hack, but it doesnt interrupt the login flow, and its unused data.
+ * The C->S serverMode is set to the hash code of the string "Forge", this should provide a fairly unique
@@ -61,8 +61,8 @@
+ * The C->S mapSeed is set to the current Forge build number, in case we need to do any quick version checks.
+ */
+ Packet1Login pkt = new Packet1Login(mc.session.username, 23);
+ pkt.serverMode = 0x040E9B47; //"Forge".hashCode();
+ pkt.mapSeed = ForgeHooks.buildVersion;
+ pkt.serverMode = ForgeHooks.FORGE_ID;
+ pkt.mapSeed = ForgeHooks.buildVersion;
+ addToSendQueue(pkt);
}
else
@@ -74,7 +74,7 @@
- addToSendQueue(new Packet1Login(mc.session.username, 23));
+ /**
+ * We use some of the unused fields in Packet 001 Login to identify the user as having Forge installed.
+ * This allows modded clients to connect to Vinella server without crashing.
+ * This allows modded clients to connect to Vanilla server without crashing.
+ * It also allows unmodded clients to connect to Forge server without crashing.
+ * Its a bit of a dirty hack, but it doesnt interrupt the login flow, and its unused data.
+ * The C->S serverMode is set to the hash code of the string "Forge", this should provide a fairly unique
@@ -82,8 +82,8 @@
+ * The C->S mapSeed is set to the current Forge build number, in case we need to do any quick version checks.
+ */
+ Packet1Login pkt = new Packet1Login(mc.session.username, 23);
+ pkt.serverMode = 0x040E9B47; //"Forge".hashCode();
+ pkt.mapSeed = ForgeHooks.buildVersion;
+ pkt.serverMode = ForgeHooks.FORGE_ID;
+ pkt.mapSeed = ForgeHooks.buildVersion;
+ addToSendQueue(pkt);
}
else
@@ -0,0 +1,21 @@
--- ../src_base/minecraft_server/net/minecraft/src/EntityTracker.java 0000-00-00 00:00:00.000000000 -0000
+++ ../src_work/minecraft_server/net/minecraft/src/EntityTracker.java 0000-00-00 00:00:00.000000000 -0000
@@ -2,6 +2,7 @@
import java.util.*;
import net.minecraft.server.MinecraftServer;
+import net.minecraft.src.forge.ForgeHooksServer;
public class EntityTracker
{
@@ -22,6 +23,10 @@
public void trackEntity(Entity entity)
{
+ if (ForgeHooksServer.OnTrackEntity(this, entity))
+ {
+ return;
+ }
if (entity instanceof EntityPlayerMP)
{
trackEntity(entity, 512, 2);
@@ -0,0 +1,25 @@
--- ../src_base/minecraft_server/net/minecraft/src/EntityTrackerEntry.java 0000-00-00 00:00:00.000000000 -0000
+++ ../src_work/minecraft_server/net/minecraft/src/EntityTrackerEntry.java 0000-00-00 00:00:00.000000000 -0000
@@ -5,6 +5,8 @@
import java.util.*;
import java.util.logging.Logger;
+import net.minecraft.src.forge.ForgeHooks;
+
public class EntityTrackerEntry
{
public Entity trackedEntity;
@@ -250,6 +252,13 @@
{
System.out.println("Fetching addPacket for removed entity");
}
+
+ Packet pkt = ForgeHooks.getEntitySpawnPacket(trackedEntity);
+ if (pkt != null)
+ {
+ return pkt;
+ }
+
EntityTrackerEntry2 entitytrackerentry2 = ModLoaderMp.HandleEntityTrackerEntries(trackedEntity);
if (entitytrackerentry2 != null)
{
@@ -1,6 +1,6 @@
--- ../src_base/minecraft_server/net/minecraft/src/NetLoginHandler.java 0000-00-00 00:00:00.000000000 -0000
+++ ../src_work/minecraft_server/net/minecraft/src/NetLoginHandler.java 0000-00-00 00:00:00.000000000 -0000
@@ -1,10 +1,13 @@
@@ -1,10 +1,14 @@
package net.minecraft.src;
import java.io.IOException;
@@ -10,11 +10,12 @@
import java.util.logging.Logger;
import net.minecraft.server.MinecraftServer;
+import net.minecraft.src.forge.ForgeHooks;
+import net.minecraft.src.forge.ForgeHooksServer;
+import net.minecraft.src.forge.MessageManager;
public class NetLoginHandler extends NetHandler
{
@@ -29,6 +32,7 @@
@@ -29,6 +33,7 @@
mcServer = minecraftserver;
netManager = new NetworkManager(socket, s, this);
netManager.chunkDataSendCounter = 0;
@@ -22,14 +23,16 @@
}
public void tryLogin()
@@ -129,7 +133,37 @@
@@ -129,7 +134,39 @@
}
entityplayermp.func_20057_k();
- ModLoaderMp.HandleAllLogins(entityplayermp);
+
+ if (packet1login.serverMode == 0x040E9B47) //"Forge".hashCode();
+ if (packet1login.serverMode == ForgeHooks.FORGE_ID)
+ {
+ //Pretty hackish place to put it, but it needs to go somewhere
+ ForgeHooksServer.init();
+ //pkt.mapSeed = ForgeHooks.buildVersion;
+ ForgeHooks.onLogin(netManager, packet1login);
+