Introuduced NetworkMod, a BaseMod extension and replacement for BaseModMP. All mods that are designed to work in the server environment should extend this.

NetworkMods will be assigned unique ModIDs by the server, and those IDs will be sent to the client upon connection.
Refactored Forge packets to the net.minecraft.src.forge.packets package. And introduced the base ForgePacket class.
Added initial ModList request/response.
This commit is contained in:
LexManos committed 2012-02-20 23:50:26 -08:00
1 parent 546a0fce41
commit 70fbe4f403
11 files changed
+278 -60

No files matched your search

@@ -1,16 +1,18 @@
package net.minecraft.src.forge;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
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;
import net.minecraft.src.*;
import net.minecraft.src.forge.packets.*;
public class PacketHandlerClient implements IPacketHandler
{
@@ -20,13 +22,16 @@ public class PacketHandlerClient implements IPacketHandler
DataInputStream data = new DataInputStream(new ByteArrayInputStream(bytes));
try
{
ForgePacket pkt = null;
NetClientHandler net = (NetClientHandler)network.getNetHandler();
int packetID = data.read();
switch(packetID)
{
case ForgeHooks.FORGE_PACKET_SPAWN:
PacketEntitySpawn pkt = new PacketEntitySpawn();
case ForgePacket.SPAWN:
pkt = new PacketEntitySpawn();
pkt.readData(data);
onEntitySpawnPacket(pkt, data, ModLoader.getMinecraftInstance().theWorld);
onEntitySpawnPacket((PacketEntitySpawn)pkt, data, ModLoader.getMinecraftInstance().theWorld);
break;
}
}
@@ -36,7 +41,14 @@ public class PacketHandlerClient implements IPacketHandler
e.printStackTrace();
}
}
/**
* Processes the Entity Spawn packet. And spawns an entity in world as needed.
* If the client has the required client mod.
* @param packet The Spawn Packet
* @param data A stream holding extra data for the entity to read
* @param world The world to spawn the entity in
*/
public void onEntitySpawnPacket(PacketEntitySpawn packet, DataInputStream data, World world)
{
Class cls = MinecraftForge.getEntityClass(packet.modID, packet.typeID);
@@ -96,4 +108,21 @@ public class PacketHandlerClient implements IPacketHandler
ModLoader.ThrowException(String.format("Error spawning entity of type %d for %s.", packet.typeID, MinecraftForge.getModByID(packet.modID)), e);
}
}
/**
* Sends a list of all loaded mods to the server.
* For now, it it simple a String[] of mod.toString()
* @param network The network connection to send the packet on.
*/
private void onModListCheck(NetClientHandler net)
{
PacketModList pkt = new PacketModList(false);
pkt.Mods = new String[ModLoader.getLoadedMods().size()];
int x = 0;
for(BaseMod mod : (List<BaseMod>)ModLoader.getLoadedMods())
{
pkt.Mods[x++] = mod.toString();
}
net.addToSendQueue(pkt.getPacket());
}
}
@@ -4,13 +4,13 @@ import net.minecraft.src.BaseMod;
public class EntityTrackerInfo
{
public final BaseMod Mod;
public final NetworkMod 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)
public EntityTrackerInfo(NetworkMod mod, int ID, int range, int updateFrequancy, boolean sendVelocityInfo)
{
Mod = mod;
this.ID = ID;
@@ -5,6 +5,7 @@
package net.minecraft.src.forge;
import net.minecraft.src.BaseMod;
import net.minecraft.src.Block;
import net.minecraft.src.Entity;
import net.minecraft.src.EntityItem;
@@ -20,6 +21,7 @@ import net.minecraft.src.Packet;
import net.minecraft.src.Packet1Login;
import net.minecraft.src.Packet250CustomPayload;
import net.minecraft.src.World;
import net.minecraft.src.forge.packets.PacketEntitySpawn;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
@@ -360,29 +362,12 @@ public class ForgeHooks {
{
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;
PacketEntitySpawn pkt = new PacketEntitySpawn(entity, info.Mod, info.ID);
return pkt.getPacket();
}
public static Hashtable<Integer, NetworkMod> networkMods = new Hashtable<Integer, NetworkMod>();
public static final int majorVersion=0;
public static final int minorVersion=0;
@@ -411,8 +396,5 @@ public class ForgeHooks {
{
return forgePacketHandler;
}
//Forge Packet ID Constants.
public static final int FORGE_ID = 0x040E9B47; //"Forge".hashCode();
public static final int FORGE_PACKET_SPAWN = 1;
}
@@ -15,6 +15,7 @@ import net.minecraft.src.ModLoader;
import net.minecraft.src.World;
import java.util.*;
import java.util.Map.Entry;
public class MinecraftForge {
@@ -808,7 +809,7 @@ public class MinecraftForge {
* @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)
public static boolean registerEntity(Class entityClass, NetworkMod mod, int ID, int range, int updateFrequancy, boolean sendVelocityInfo)
{
if (ForgeHooks.entityTrackerMap.containsKey(entityClass))
{
@@ -866,16 +867,44 @@ public class MinecraftForge {
* @param id The mod ID
* @return The mod, or null if not found
*/
public static BaseMod getModByID(int id)
public static NetworkMod getModByID(int id)
{
for(BaseMod mod : (List<BaseMod>)ModLoader.getLoadedMods())
return ForgeHooks.networkMods.get(id);
}
/**
* Returns a unique index number for the specific mod.
*
* @param mod The mod to find
* @return The index number, -1 if no index found
*/
public static int getModID(NetworkMod mod)
{
for (Entry<Integer, NetworkMod> entry : ForgeHooks.networkMods.entrySet())
{
if (mod.toString().hashCode() == id)
if (entry.getValue() == mod)
{
return mod;
return entry.getKey();
}
}
return null;
return -1;
}
/**
* Returns a list of mods that are designed to be used over the network.
* @return
*/
public static NetworkMod[] getNetworkMods()
{
ArrayList<NetworkMod> ret = new ArrayList<NetworkMod>();
for(BaseMod mod : (List<BaseMod>)ModLoader.getLoadedMods())
{
if (mod instanceof NetworkMod)
{
ret.add((NetworkMod)mod);
}
}
return ret.toArray(new NetworkMod[0]);
}
@@ -0,0 +1,25 @@
package net.minecraft.src.forge;
import net.minecraft.src.BaseMod;
/**
* This is for mods that are designed to be used on the server side alone,
* or both the client and server side. This class is used when registering
* various things relating to network traffic. Entity ID's, GUI Id's, etc..
*/
public abstract class NetworkMod extends BaseMod
{
/**
* Returns true if every client is required to have this
* mod installed when it is installed on a server.
* @return True if client is required, false if not.
*/
public abstract boolean clientSideRequired();
/**
* Returns true if the server is required to have this
* mod when it is installed on the client.
* @return True if server is required, false if not.
*/
public abstract boolean serverSideRequired();
}
@@ -0,0 +1,49 @@
package net.minecraft.src.forge.packets;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.List;
import net.minecraft.src.BaseMod;
import net.minecraft.src.ModLoader;
import net.minecraft.src.Packet;
import net.minecraft.src.Packet250CustomPayload;
import net.minecraft.src.forge.ForgeHooks;
public abstract class ForgePacket
{
//Forge Packet ID Constants.
public static final int FORGE_ID = 0x040E9B47; //"Forge".hashCode();
public static final int SPAWN = 1;
public static final int MODLIST = 2;
public static final int MOD_MISSING = 3;
public static final int MOD_IDS = 4;
public static final int OPEN_GUI = 5;
public Packet getPacket()
{
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream data = new DataOutputStream(bytes);
try
{
data.writeByte(getID());
writeData(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 abstract void writeData(DataOutputStream data) throws IOException;
public abstract void readData(DataInputStream data) throws IOException;
public abstract int getID();
}
@@ -1,4 +1,4 @@
package net.minecraft.src.forge;
package net.minecraft.src.forge.packets;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@@ -7,10 +7,13 @@ import java.io.IOException;
import net.minecraft.src.BaseMod;
import net.minecraft.src.Entity;
import net.minecraft.src.MathHelper;
import net.minecraft.src.forge.ISpawnHandler;
import net.minecraft.src.forge.IThrowableEntity;
import net.minecraft.src.forge.MinecraftForge;
import net.minecraft.src.forge.NetworkMod;
public class PacketEntitySpawn
public class PacketEntitySpawn extends ForgePacket
{
public int entityID;
public int posX;
public int posY;
@@ -21,9 +24,10 @@ public class PacketEntitySpawn
public int typeID;
public int modID;
public int throwerID;
private ISpawnHandler handler;
public PacketEntitySpawn(){}
public PacketEntitySpawn(Entity ent, BaseMod mod, int type)
public PacketEntitySpawn(Entity ent, NetworkMod mod, int type)
{
entityID = ent.entityId;
@@ -32,7 +36,7 @@ public class PacketEntitySpawn
posZ = MathHelper.floor_double(ent.posZ * 32D);
typeID = type;
modID = mod.toString().hashCode();
modID = MinecraftForge.getModID(mod);
if (ent instanceof IThrowableEntity)
{
@@ -52,6 +56,10 @@ public class PacketEntitySpawn
speedY = (int)(mY * 8000D);
speedZ = (int)(mZ * 8000D);
}
if (ent instanceof ISpawnHandler)
{
handler = (ISpawnHandler)ent;
}
}
public void writeData(DataOutputStream data) throws IOException
{
@@ -68,6 +76,10 @@ public class PacketEntitySpawn
data.writeShort(speedY);
data.writeShort(speedZ);
}
if (handler != null)
{
handler.writeSpawnData(data);
}
}
public void readData(DataInputStream data) throws IOException
@@ -86,4 +98,9 @@ public class PacketEntitySpawn
speedX = data.readShort();
}
}
@Override
public int getID()
{
return ForgePacket.SPAWN;
}
}
@@ -0,0 +1,58 @@
package net.minecraft.src.forge.packets;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.List;
import net.minecraft.src.BaseMod;
import net.minecraft.src.ModLoader;
public class PacketModList extends ForgePacket
{
private boolean isServer = false;
public String[] Mods;
public int Length = -1;
public PacketModList(boolean server)
{
isServer = server;
}
@Override
public void writeData(DataOutputStream data) throws IOException
{
if (!isServer)
{
data.writeInt(Mods.length);
for(String mod : Mods)
{
data.writeUTF(mod);
}
}
}
@Override
public void readData(DataInputStream data) throws IOException
{
if (isServer)
{
Length = data.readInt();
if (Length >= 0)
{
Mods = new String[Length];
for (int x = 0; x < Length; x++)
{
Mods[x] = data.readUTF();
}
}
}
}
@Override
public int getID()
{
return ForgePacket.MODLIST;
}
}
@@ -1,15 +1,16 @@
--- ../src_base/minecraft/net/minecraft/src/NetClientHandler.java 0000-00-00 00:00:00.000000000 -0000
+++ ../src_work/minecraft/net/minecraft/src/NetClientHandler.java 0000-00-00 00:00:00.000000000 -0000
@@ -7,6 +7,8 @@
@@ -7,6 +7,9 @@
import java.util.*;
import java.util.logging.Logger;
import net.minecraft.client.Minecraft;
+import net.minecraft.src.forge.ForgeHooks;
+import net.minecraft.src.forge.MessageManager;
+import net.minecraft.src.forge.packets.ForgePacket;
public class NetClientHandler extends NetHandler
{
@@ -35,6 +37,8 @@
@@ -35,6 +38,8 @@
mc = minecraft;
Socket socket = new Socket(InetAddress.getByName(s), i);
netManager = new NetworkManager(socket, "Client", this);
@@ -18,7 +19,7 @@
}
public void processReadPackets()
@@ -58,6 +62,27 @@
@@ -58,6 +63,27 @@
mc.thePlayer.entityId = packet1login.protocolVersion;
currentServerMaxPlayers = packet1login.maxPlayers;
((PlayerControllerMP)mc.playerController).setCreative(packet1login.serverMode == 1);
@@ -46,7 +47,7 @@
}
public void handlePickupSpawn(Packet21PickupSpawn packet21pickupspawn)
@@ -608,7 +633,19 @@
@@ -608,7 +634,19 @@
}
else if (packet2handshake.username.equals("-"))
{
@@ -61,13 +62,13 @@
+ * 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 = ForgeHooks.FORGE_ID;
+ pkt.serverMode = ForgePacket.FORGE_ID;
+ pkt.mapSeed = ForgeHooks.buildVersion;
+ addToSendQueue(pkt);
}
else
{
@@ -620,7 +657,19 @@
@@ -620,7 +658,19 @@
bufferedreader.close();
if (s1.equalsIgnoreCase("ok"))
{
@@ -82,13 +83,13 @@
+ * 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 = ForgeHooks.FORGE_ID;
+ pkt.serverMode = ForgePacket.FORGE_ID;
+ pkt.mapSeed = ForgeHooks.buildVersion;
+ addToSendQueue(pkt);
}
else
{
@@ -1017,4 +1066,44 @@
@@ -1017,4 +1067,44 @@
{
addToSendQueue(new Packet0KeepAlive(packet0keepalive.randomId));
}
@@ -1,6 +1,33 @@
--- ../src_base/minecraft_server/net/minecraft/src/ModLoader.java 0000-00-00 00:00:00.000000000 -0000
+++ ../src_work/minecraft_server/net/minecraft/src/ModLoader.java 0000-00-00 00:00:00.000000000 -0000
@@ -1325,6 +1325,7 @@
@@ -10,6 +10,8 @@
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import net.minecraft.server.MinecraftServer;
+import net.minecraft.src.forge.ForgeHooks;
+import net.minecraft.src.forge.NetworkMod;
public final class ModLoader
{
@@ -626,6 +628,17 @@
readFromClassPath(file);
System.out.println("Done.");
props.setProperty("loggingLevel", cfgLoggingLevel.getName());
+ /*
+ * Gather up a list of network mods and assign them an id
+ */
+ int x = 0;
+ for (BaseMod mod : (List<BaseMod>)modList)
+ {
+ if (mod instanceof NetworkMod)
+ {
+ ForgeHooks.networkMods.put(x++, (NetworkMod)mod);
+ }
+ }
Iterator iterator = modList.iterator();
do
{
@@ -1325,6 +1338,7 @@
{
method_getNextWindowId.invoke(entityplayermp, new Object[0]);
int j = field_currentWindowId.getInt(entityplayermp);
@@ -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,14 @@
@@ -1,10 +1,15 @@
package net.minecraft.src;
import java.io.IOException;
@@ -12,10 +12,11 @@
+import net.minecraft.src.forge.ForgeHooks;
+import net.minecraft.src.forge.ForgeHooksServer;
+import net.minecraft.src.forge.MessageManager;
+import net.minecraft.src.forge.packets.ForgePacket;
public class NetLoginHandler extends NetHandler
{
@@ -29,6 +33,7 @@
@@ -29,6 +34,7 @@
mcServer = minecraftserver;
netManager = new NetworkManager(socket, s, this);
netManager.chunkDataSendCounter = 0;
@@ -23,13 +24,13 @@
}
public void tryLogin()
@@ -129,7 +134,39 @@
@@ -129,7 +135,39 @@
}
entityplayermp.func_20057_k();
- ModLoaderMp.HandleAllLogins(entityplayermp);
+
+ if (packet1login.serverMode == ForgeHooks.FORGE_ID)
+ if (packet1login.serverMode == ForgePacket.FORGE_ID)
+ {
+ //Pretty hackish place to put it, but it needs to go somewhere
+ ForgeHooksServer.init();
@@ -53,7 +54,7 @@
+ }
+ pkt.length = pkt.data.length;
+ netserverhandler.sendPacket(pkt);
+
+ ForgeHooksServer.sendModListRequest(netManager);
+ ModLoaderMp.HandleAllLogins(entityplayermp);
+ }
+ else