From 67a49ccdd2fc691af5b872b015ac38453f82e30b Mon Sep 17 00:00:00 2001 From: LexManos Date: Thu, 16 Feb 2012 20:04:40 -0800 Subject: [PATCH 1/6] Split mod_MinecraftForge so that Clients arnt required to have MLMP installed if they don't use a MP mod. --- .../net/minecraft/src/mod_MinecraftForge.java | 24 +++++++++++++++++++ .../net/minecraft/src/mod_MinecraftForge.java | 0 2 files changed, 24 insertions(+) create mode 100644 forge/forge_client/src/net/minecraft/src/mod_MinecraftForge.java rename forge/{forge_common => forge_server/src}/net/minecraft/src/mod_MinecraftForge.java (100%) diff --git a/forge/forge_client/src/net/minecraft/src/mod_MinecraftForge.java b/forge/forge_client/src/net/minecraft/src/mod_MinecraftForge.java new file mode 100644 index 000000000..6673fba9d --- /dev/null +++ b/forge/forge_client/src/net/minecraft/src/mod_MinecraftForge.java @@ -0,0 +1,24 @@ +package net.minecraft.src; + +import net.minecraft.src.forge.ForgeHooks; +import net.minecraft.src.forge.MinecraftForge; + +/** + * This class is just here to make the Forge version show up nicely in the ModLoader logs/Crash Screen + */ +public class mod_MinecraftForge extends BaseMod +{ + @Override + public String getVersion() + { + return String.format("%d.%d.%d.%d", + ForgeHooks.majorVersion, ForgeHooks.minorVersion, + ForgeHooks.revisionVersion, ForgeHooks.buildVersion); + } + + @Override + public void load() + { + MinecraftForge.getDungeonLootTries(); //Random thing to make things Initialize + } +} diff --git a/forge/forge_common/net/minecraft/src/mod_MinecraftForge.java b/forge/forge_server/src/net/minecraft/src/mod_MinecraftForge.java similarity index 100% rename from forge/forge_common/net/minecraft/src/mod_MinecraftForge.java rename to forge/forge_server/src/net/minecraft/src/mod_MinecraftForge.java From 87524cfa31d318505272a7b38076272d77550710 Mon Sep 17 00:00:00 2001 From: LexManos Date: Sat, 18 Feb 2012 10:47:45 -0800 Subject: [PATCH 2/6] Fixed up the install scripts. The linux script no longer needs sed. Should fix some issues on OSX's without gsed. Also forge sources will only be copied to sides that were downloaded. Also, install scripts now prompt for input to cleanup. --- forge/install/install.cmd | 15 ++++++--------- forge/install/install.sh | 20 +++++--------------- 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/forge/install/install.cmd b/forge/install/install.cmd index ecea3b638..450628ad3 100755 --- a/forge/install/install.cmd +++ b/forge/install/install.cmd @@ -9,12 +9,8 @@ pushd .. >nul xcopy /Y /E /I forge\conf\* conf -if exist runtime\bin\fernflower.jar move runtime\bin\fernflower.jar runtime\bin\fernflower.jar-backup - -echo | call cleanup.bat -echo | call decompile.bat - -if exist runtime\bin\fernflower.jar-backup move runtime\bin\fernflower.jar-backup runtime\bin\fernflower.jar +runtime\bin\python\python_mcp runtime\cleanup.py +runtime\bin\python\python_mcp runtime\decompile.py --jad pushd src >nul @@ -29,6 +25,7 @@ pushd src >nul ..\runtime\bin\applydiff.exe -uf -p2 -i "%%a" ) else popd ) + xcopy /Y /E ..\forge\src\minecraft\* minecraft ) if exist ..\jars\minecraft_server.jar ( @@ -45,13 +42,13 @@ pushd src >nul ..\runtime\bin\applydiff.exe -uf -p2 -i "%%a" ) else popd ) - + xcopy /Y /E ..\forge\src\minecraft_server\* minecraft_server ) popd >nul -xcopy /Y /E forge\src\* src rem Removed until MCP's Update Names is fixed rem cmd /C updatemcp.bat rem cmd /C updatenames.bat -cmd /C updatemd5.bat \ No newline at end of file +runtime\bin\python\python_mcp runtime\updatemd5.py +pause \ No newline at end of file diff --git a/forge/install/install.sh b/forge/install/install.sh index 90989e6c4..95f2b475f 100644 --- a/forge/install/install.sh +++ b/forge/install/install.sh @@ -9,23 +9,12 @@ rm -rf conf mkdir conf cp -r forge/conf/* conf -if [ -f runtime/bin/fernflower.jar ]; -then - mv runtime/bin/fernflower.jar runtime/bin/fernflower.jar-backup -fi - ./cleanup.sh -./decompile.sh - -if [ -f runtime/bin/fernflower.jar-backup ]; -then - mv runtime/bin/fernflower.jar-backup runtime/bin/fernflower.jar -fi - +./decompile.sh --jad pushd src > /dev/null - find . -name *.java -exec sed -i 's/\r//g' \{\} \; - find ../forge/ -name *.patch -exec sed -i 's/\r//g' \{\} \; + #find . -name *.java -exec sed -i 's/\r//g' \{\} \; + #find ../forge/ -name *.patch -exec sed -i 's/\r//g' \{\} \; if [ -f ../jars/bin/minecraft.jar ]; then @@ -35,6 +24,7 @@ pushd src > /dev/null do patch -p2 -i $i done + cp -r ../forge/src/minecraft/* minecraft fi @@ -48,10 +38,10 @@ pushd src > /dev/null do patch -p2 -i $i done + cp -r ../forge/src/minecraft_server/* minecraft_server fi popd > /dev/null -cp -r forge/src/* src # Removed until MCP's UpdateNames Is fixed #./updatemcp.sh From 546a0fce41df1e386c5d55a22700a07174ca9a70 Mon Sep 17 00:00:00 2001 From: LexManos Date: Mon, 20 Feb 2012 23:42:26 -0800 Subject: [PATCH 3/6] Exposed getters for NetServerHandler.playerEntity and NetworkManager.netHandler --- .../net/minecraft/src/NetworkManager.java.patch | 15 +++++++++++++++ .../net/minecraft/src/NetServerHandler.java.patch | 7 ++++++- .../net/minecraft/src/NetworkManager.java.patch | 15 +++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/forge/patches/minecraft/net/minecraft/src/NetworkManager.java.patch b/forge/patches/minecraft/net/minecraft/src/NetworkManager.java.patch index 11c6db027..f163583a7 100644 --- a/forge/patches/minecraft/net/minecraft/src/NetworkManager.java.patch +++ b/forge/patches/minecraft/net/minecraft/src/NetworkManager.java.patch @@ -17,3 +17,18 @@ } public void processReadPackets() +@@ -293,4 +296,14 @@ + { + return networkmanager.writeThread; + } ++ ++ /** ++ * Retrieves the current associated network handler. ++ * Added so modders dont have to use reflection. ++ * @return The current registered Network Handler ++ */ ++ public NetHandler getNetHandler() ++ { ++ return netHandler; ++ } + } diff --git a/forge/patches/minecraft_server/net/minecraft/src/NetServerHandler.java.patch b/forge/patches/minecraft_server/net/minecraft/src/NetServerHandler.java.patch index 89ae125d2..51e67a58d 100644 --- a/forge/patches/minecraft_server/net/minecraft/src/NetServerHandler.java.patch +++ b/forge/patches/minecraft_server/net/minecraft/src/NetServerHandler.java.patch @@ -34,11 +34,16 @@ { playerEntity.itemInWorldManager.activeBlockOrUseItem(playerEntity, worldserver, itemstack, i, j, k, l); } -@@ -764,4 +770,44 @@ +@@ -764,4 +770,49 @@ { return true; } + ++ public EntityPlayerMP getPlayerEntity() ++ { ++ return playerEntity; ++ } ++ + @Override + public void handleCustomPayload(Packet250CustomPayload pkt) + { diff --git a/forge/patches/minecraft_server/net/minecraft/src/NetworkManager.java.patch b/forge/patches/minecraft_server/net/minecraft/src/NetworkManager.java.patch index 6ac292da1..2ce6f1bfc 100644 --- a/forge/patches/minecraft_server/net/minecraft/src/NetworkManager.java.patch +++ b/forge/patches/minecraft_server/net/minecraft/src/NetworkManager.java.patch @@ -19,3 +19,18 @@ } public void processReadPackets() +@@ -313,4 +318,14 @@ + { + return networkmanager.writeThread; + } ++ ++ /** ++ * Retrieves the current associated network handler. ++ * Added so modders dont have to use reflection. ++ * @return The current registered Network Handler ++ */ ++ public NetHandler getNetHandler() ++ { ++ return netHandler; ++ } + } From 70fbe4f403e190b9fc246972c07985fa021eb316 Mon Sep 17 00:00:00 2001 From: LexManos Date: Mon, 20 Feb 2012 23:50:26 -0800 Subject: [PATCH 4/6] 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. --- .../src/forge/PacketHandlerClient.java | 47 ++++++++++++--- .../src/forge/EntityTrackerInfo.java | 4 +- .../net/minecraft/src/forge/ForgeHooks.java | 30 ++-------- .../minecraft/src/forge/MinecraftForge.java | 41 +++++++++++-- .../net/minecraft/src/forge/NetworkMod.java | 25 ++++++++ .../src/forge/packets/ForgePacket.java | 49 ++++++++++++++++ .../{ => packets}/PacketEntitySpawn.java | 27 +++++++-- .../src/forge/packets/PacketModList.java | 58 +++++++++++++++++++ .../minecraft/src/NetClientHandler.java.patch | 17 +++--- .../net/minecraft/src/ModLoader.java.patch | 29 +++++++++- .../minecraft/src/NetLoginHandler.java.patch | 11 ++-- 11 files changed, 278 insertions(+), 60 deletions(-) create mode 100644 forge/forge_common/net/minecraft/src/forge/NetworkMod.java create mode 100644 forge/forge_common/net/minecraft/src/forge/packets/ForgePacket.java rename forge/forge_common/net/minecraft/src/forge/{ => packets}/PacketEntitySpawn.java (74%) create mode 100644 forge/forge_common/net/minecraft/src/forge/packets/PacketModList.java diff --git a/forge/forge_client/src/net/minecraft/src/forge/PacketHandlerClient.java b/forge/forge_client/src/net/minecraft/src/forge/PacketHandlerClient.java index 5ddf23d6e..57a8093ac 100644 --- a/forge/forge_client/src/net/minecraft/src/forge/PacketHandlerClient.java +++ b/forge/forge_client/src/net/minecraft/src/forge/PacketHandlerClient.java @@ -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)ModLoader.getLoadedMods()) + { + pkt.Mods[x++] = mod.toString(); + } + net.addToSendQueue(pkt.getPacket()); + } } diff --git a/forge/forge_common/net/minecraft/src/forge/EntityTrackerInfo.java b/forge/forge_common/net/minecraft/src/forge/EntityTrackerInfo.java index 1e88261e0..e9444f1b7 100644 --- a/forge/forge_common/net/minecraft/src/forge/EntityTrackerInfo.java +++ b/forge/forge_common/net/minecraft/src/forge/EntityTrackerInfo.java @@ -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; diff --git a/forge/forge_common/net/minecraft/src/forge/ForgeHooks.java b/forge/forge_common/net/minecraft/src/forge/ForgeHooks.java index eadfefaa9..e1544c3bf 100644 --- a/forge/forge_common/net/minecraft/src/forge/ForgeHooks.java +++ b/forge/forge_common/net/minecraft/src/forge/ForgeHooks.java @@ -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 networkMods = new Hashtable(); 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; } diff --git a/forge/forge_common/net/minecraft/src/forge/MinecraftForge.java b/forge/forge_common/net/minecraft/src/forge/MinecraftForge.java index 7c7d28ae2..9df81093a 100755 --- a/forge/forge_common/net/minecraft/src/forge/MinecraftForge.java +++ b/forge/forge_common/net/minecraft/src/forge/MinecraftForge.java @@ -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)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 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 ret = new ArrayList(); + for(BaseMod mod : (List)ModLoader.getLoadedMods()) + { + if (mod instanceof NetworkMod) + { + ret.add((NetworkMod)mod); + } + } + return ret.toArray(new NetworkMod[0]); } diff --git a/forge/forge_common/net/minecraft/src/forge/NetworkMod.java b/forge/forge_common/net/minecraft/src/forge/NetworkMod.java new file mode 100644 index 000000000..a7aa76d9e --- /dev/null +++ b/forge/forge_common/net/minecraft/src/forge/NetworkMod.java @@ -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(); +} diff --git a/forge/forge_common/net/minecraft/src/forge/packets/ForgePacket.java b/forge/forge_common/net/minecraft/src/forge/packets/ForgePacket.java new file mode 100644 index 000000000..c650a2337 --- /dev/null +++ b/forge/forge_common/net/minecraft/src/forge/packets/ForgePacket.java @@ -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(); +} diff --git a/forge/forge_common/net/minecraft/src/forge/PacketEntitySpawn.java b/forge/forge_common/net/minecraft/src/forge/packets/PacketEntitySpawn.java similarity index 74% rename from forge/forge_common/net/minecraft/src/forge/PacketEntitySpawn.java rename to forge/forge_common/net/minecraft/src/forge/packets/PacketEntitySpawn.java index 5d55fff76..2a29ba47c 100644 --- a/forge/forge_common/net/minecraft/src/forge/PacketEntitySpawn.java +++ b/forge/forge_common/net/minecraft/src/forge/packets/PacketEntitySpawn.java @@ -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; + } } diff --git a/forge/forge_common/net/minecraft/src/forge/packets/PacketModList.java b/forge/forge_common/net/minecraft/src/forge/packets/PacketModList.java new file mode 100644 index 000000000..47191f67a --- /dev/null +++ b/forge/forge_common/net/minecraft/src/forge/packets/PacketModList.java @@ -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; + } + +} diff --git a/forge/patches/minecraft/net/minecraft/src/NetClientHandler.java.patch b/forge/patches/minecraft/net/minecraft/src/NetClientHandler.java.patch index 46105316b..8c70a3751 100644 --- a/forge/patches/minecraft/net/minecraft/src/NetClientHandler.java.patch +++ b/forge/patches/minecraft/net/minecraft/src/NetClientHandler.java.patch @@ -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)); } diff --git a/forge/patches/minecraft_server/net/minecraft/src/ModLoader.java.patch b/forge/patches/minecraft_server/net/minecraft/src/ModLoader.java.patch index 045abcab8..97c3e2980 100644 --- a/forge/patches/minecraft_server/net/minecraft/src/ModLoader.java.patch +++ b/forge/patches/minecraft_server/net/minecraft/src/ModLoader.java.patch @@ -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)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); diff --git a/forge/patches/minecraft_server/net/minecraft/src/NetLoginHandler.java.patch b/forge/patches/minecraft_server/net/minecraft/src/NetLoginHandler.java.patch index 1dad01427..9f3d6603f 100644 --- a/forge/patches/minecraft_server/net/minecraft/src/NetLoginHandler.java.patch +++ b/forge/patches/minecraft_server/net/minecraft/src/NetLoginHandler.java.patch @@ -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 From a6f93ed5281f3dee7511c8494bc891c8506e868f Mon Sep 17 00:00:00 2001 From: LexManos Date: Mon, 20 Feb 2012 23:54:11 -0800 Subject: [PATCH 5/6] Expanded the Mod check to test for missing mods and display a GUI screen for the client if it is missing any. The client now downloads NetworkMod ID's from the server upon connecting. --- .../minecraft/src/forge/GuiMissingMods.java | 39 +++++ .../src/forge/PacketHandlerClient.java | 67 +++++++++ .../src/forge/packets/PacketMissingMods.java | 21 +++ .../src/forge/packets/PacketModIDs.java | 41 ++++++ .../minecraft/src/forge/ForgeHooksServer.java | 10 +- .../src/forge/PacketHandlerServer.java | 136 +++++++++++++++++- 6 files changed, 310 insertions(+), 4 deletions(-) create mode 100644 forge/forge_client/src/net/minecraft/src/forge/GuiMissingMods.java create mode 100644 forge/forge_common/net/minecraft/src/forge/packets/PacketMissingMods.java create mode 100644 forge/forge_common/net/minecraft/src/forge/packets/PacketModIDs.java diff --git a/forge/forge_client/src/net/minecraft/src/forge/GuiMissingMods.java b/forge/forge_client/src/net/minecraft/src/forge/GuiMissingMods.java new file mode 100644 index 000000000..f015eba9e --- /dev/null +++ b/forge/forge_client/src/net/minecraft/src/forge/GuiMissingMods.java @@ -0,0 +1,39 @@ +package net.minecraft.src.forge; + +import net.minecraft.src.*; +import net.minecraft.src.forge.packets.PacketMissingMods; + +public class GuiMissingMods extends GuiScreen +{ + PacketMissingMods packet; + public GuiMissingMods(PacketMissingMods pkt) + { + packet = pkt; + } + + public void initGui() + { + controlList.clear(); + controlList.add(new GuiButton(0, width / 2 - 100, height - 60, StringTranslate.getInstance().translateKey("gui.toMenu"))); + } + + protected void actionPerformed(GuiButton guibutton) + { + if (guibutton.id == 0) + { + mc.displayGuiScreen(new GuiMainMenu()); + } + } + + public void drawScreen(int i, int j, float f) + { + drawDefaultBackground(); + drawCenteredString(fontRenderer, "The server requires the following mods:", width / 2, height / 2 - 50, 0xffffff); + int y = 0; + for (String mod : packet.Mods) + { + drawCenteredString(fontRenderer, mod, width / 2, (height / 2 - 10) + y++ * 10, 0xffffff); + } + super.drawScreen(i, j, f); + } +} diff --git a/forge/forge_client/src/net/minecraft/src/forge/PacketHandlerClient.java b/forge/forge_client/src/net/minecraft/src/forge/PacketHandlerClient.java index 57a8093ac..9052238ae 100644 --- a/forge/forge_client/src/net/minecraft/src/forge/PacketHandlerClient.java +++ b/forge/forge_client/src/net/minecraft/src/forge/PacketHandlerClient.java @@ -33,6 +33,26 @@ public class PacketHandlerClient implements IPacketHandler pkt.readData(data); onEntitySpawnPacket((PacketEntitySpawn)pkt, data, ModLoader.getMinecraftInstance().theWorld); break; + + case ForgePacket.MODLIST: + /* + pkt = new PacketModList(false); + pkt.readData(data); + */ + onModListCheck(net); + break; + + case ForgePacket.MOD_MISSING: + pkt = new PacketMissingMods(false); + pkt.readData(data); + onMissingMods((PacketMissingMods)pkt, net); + break; + + case ForgePacket.MOD_IDS: + pkt = new PacketModIDs(); + pkt.readData(data); + onModIDs((PacketModIDs)pkt); + break; } } catch(IOException e) @@ -125,4 +145,51 @@ public class PacketHandlerClient implements IPacketHandler } net.addToSendQueue(pkt.getPacket()); } + + /** + * Received when the client does not have a mod installed that the server requires them to. + * Displays a informative screen, and disconnects from the server. + * + * @param pkt The missing mods packet + * @param net The network handler + */ + private void onMissingMods(PacketMissingMods pkt, NetClientHandler net) + { + net.disconnect(); + Minecraft mc = ModLoader.getMinecraftInstance(); + mc.changeWorld1(null); + mc.displayGuiScreen(new GuiMissingMods(pkt)); + } + + /** + * Sets up the list of ID to mod mappings. + * TODO; Make it display an error, and prompt if the user wishes to continue anyways + * if it detects that the server does not have a corresponding mod to one it has installed. + * + * @param pkt The mod id packet + */ + private void onModIDs(PacketModIDs pkt) + { + ForgeHooks.networkMods.clear(); + NetworkMod[] mods = MinecraftForge.getNetworkMods(); + for (NetworkMod mod : mods) + { + for (Entry entry : pkt.Mods.entrySet()) + { + if (mod.toString().equals(entry.getValue())) + { + ForgeHooks.networkMods.put(entry.getKey(), mod); + } + } + } + ArrayList missing = new ArrayList(); + for (NetworkMod mod : mods) + { + if (MinecraftForge.getModID(mod) == -1 && mod.serverSideRequired()) + { + missing.add(mod); + } + } + //TODO: Display error/confirmation screen + } } diff --git a/forge/forge_common/net/minecraft/src/forge/packets/PacketMissingMods.java b/forge/forge_common/net/minecraft/src/forge/packets/PacketMissingMods.java new file mode 100644 index 000000000..c36f1cee6 --- /dev/null +++ b/forge/forge_common/net/minecraft/src/forge/packets/PacketMissingMods.java @@ -0,0 +1,21 @@ +package net.minecraft.src.forge.packets; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class PacketMissingMods extends PacketModList +{ + + public PacketMissingMods(boolean server) + { + super(!server); + } + + @Override + public int getID() + { + return ForgePacket.MOD_MISSING; + } + +} diff --git a/forge/forge_common/net/minecraft/src/forge/packets/PacketModIDs.java b/forge/forge_common/net/minecraft/src/forge/packets/PacketModIDs.java new file mode 100644 index 000000000..6a3298823 --- /dev/null +++ b/forge/forge_common/net/minecraft/src/forge/packets/PacketModIDs.java @@ -0,0 +1,41 @@ +package net.minecraft.src.forge.packets; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.Hashtable; +import java.util.Map.Entry; + +public class PacketModIDs extends ForgePacket +{ + public Hashtable Mods = new Hashtable(); + public int Length; + + @Override + public void writeData(DataOutputStream data) throws IOException + { + data.writeInt(Mods.size()); + for (Entry entry : Mods.entrySet()) + { + data.writeInt(entry.getKey()); + data.writeUTF(entry.getValue()); + } + } + + @Override + public void readData(DataInputStream data) throws IOException + { + Length = data.readInt(); + for(int x = 0; x < Length; x++) + { + Mods.put(data.readInt(), data.readUTF()); + } + } + + @Override + public int getID() + { + return ForgePacket.MOD_IDS; + } + +} diff --git a/forge/forge_server/src/net/minecraft/src/forge/ForgeHooksServer.java b/forge/forge_server/src/net/minecraft/src/forge/ForgeHooksServer.java index cf60baf9a..682cc6499 100644 --- a/forge/forge_server/src/net/minecraft/src/forge/ForgeHooksServer.java +++ b/forge/forge_server/src/net/minecraft/src/forge/ForgeHooksServer.java @@ -2,8 +2,8 @@ package net.minecraft.src.forge; import java.util.Map; -import net.minecraft.src.Entity; -import net.minecraft.src.EntityTracker; +import net.minecraft.src.*; +import net.minecraft.src.forge.packets.PacketModList; public class ForgeHooksServer { @@ -26,6 +26,12 @@ public class ForgeHooksServer return false; } + public static void sendModListRequest(NetworkManager net) + { + PacketModList pkt = new PacketModList(true); + ((NetServerHandler)net.getNetHandler()).sendPacket(pkt.getPacket()); + } + private static boolean hasInit = false; public static void init() diff --git a/forge/forge_server/src/net/minecraft/src/forge/PacketHandlerServer.java b/forge/forge_server/src/net/minecraft/src/forge/PacketHandlerServer.java index 13a3c53ca..eaca8c126 100644 --- a/forge/forge_server/src/net/minecraft/src/forge/PacketHandlerServer.java +++ b/forge/forge_server/src/net/minecraft/src/forge/PacketHandlerServer.java @@ -1,11 +1,143 @@ package net.minecraft.src.forge; -import net.minecraft.src.NetworkManager; +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.Arrays; +import java.util.List; +import java.util.logging.Level; + +import net.minecraft.server.MinecraftServer; +import net.minecraft.src.*; +import net.minecraft.src.forge.packets.*; public class PacketHandlerServer implements IPacketHandler { @Override - public void onPacketData(NetworkManager network, String channel, byte[] data) + public void onPacketData(NetworkManager network, String channel, byte[] bytes) { + NetServerHandler net = (NetServerHandler)network.getNetHandler(); + DataInputStream data = new DataInputStream(new ByteArrayInputStream(bytes)); + ForgePacket pkt = null; + + try + { + int packetID = data.read(); + switch(packetID) + { + case ForgePacket.MODLIST: + pkt = new PacketModList(true); + pkt.readData(data); + onModListResponse(net, (PacketModList)pkt); + break; + } + } + catch(IOException e) + { + ModLoader.getLogger().log(Level.SEVERE, "Exception in PacketHandlerServer.onPacketData", e); + e.printStackTrace(); + } + } + + private void onModListResponse(NetServerHandler net, PacketModList pkt) throws IOException + { + if (pkt.Length < 0) + { + net.kickPlayer("Invalid mod list response, Size: " + pkt.Length); + return; + } + if (pkt.Mods.length == 0) + { + ModLoader.getLogger().log(Level.INFO, net.getUsername() + " joined with no mods"); + } + else + { + ModLoader.getLogger().log(Level.INFO, net.getUsername() + " joined with: " + Arrays.toString(pkt.Mods).replaceAll("mod_", "")); + } + + //TODO: Write a 'banned mods' system and do the checks here + + NetworkMod[] serverMods = MinecraftForge.getNetworkMods(); + ArrayList missing = new ArrayList(); + for (NetworkMod mod : serverMods) + { + if (!mod.clientSideRequired()) + { + continue; + } + boolean found = true; + for (String modName : pkt.Mods) + { + if (modName.equals(mod.toString())) + { + found = false; + break; + } + } + if (!found) + { + missing.add(mod); + } + } + if (missing.size() > 0) + { + doMissingMods(net, missing); + } + else + { + sendModIDs(net, serverMods); + } + } + + /** + * Sends the user a list of mods they are missing and then disconnects them + * @param net The network handler + */ + private void doMissingMods(NetServerHandler net, ArrayList list) + { + PacketMissingMods pkt = new PacketMissingMods(true); + pkt.Mods = new String[list.size()]; + int x = 0; + for(NetworkMod mod : list) + { + pkt.Mods[x++] = mod.toString(); + } + net.sendPacket(pkt.getPacket()); + disconnectUser(net); + } + + + /** + * Sends a list of mod id mappings to the client. + * Only mod ID's are sent, not item or blocks. + * + * @param net The network handler + * @param list A list of network mods + */ + private void sendModIDs(NetServerHandler net, NetworkMod[] list) + { + PacketModIDs pkt = new PacketModIDs(); + for (NetworkMod mod : list) + { + pkt.Mods.put(MinecraftForge.getModID(mod), mod.toString()); + } + net.sendPacket(pkt.getPacket()); + } + + /** + * Disconnects the player just like kicking them, just without the kick message. + * @param net The network handler + */ + private void disconnectUser(NetServerHandler net) + { + MinecraftServer mc = ModLoader.getMinecraftServerInstance(); + net.getPlayerEntity().func_30002_A(); + net.netManager.serverShutdown(); + mc.configManager.sendPacketToAllPlayers(new Packet3Chat("\247e" + net.getUsername() + " left the game.")); + mc.configManager.playerLoggedOut(net.getPlayerEntity()); + net.connectionClosed = true; } } From 54ec1567b239a2fc3a2d7c1db1f7196e514bb8b5 Mon Sep 17 00:00:00 2001 From: LexManos Date: Mon, 20 Feb 2012 23:56:01 -0800 Subject: [PATCH 6/6] Implemented a generic EntityPlayer.openGui system, and the network backend for it to work on server and client. --- .../net/minecraft/src/forge/IGuiHandler.java | 21 +++++++ .../src/forge/PacketHandlerClient.java | 22 +++++++ .../net/minecraft/src/forge/ForgeHooks.java | 1 + .../minecraft/src/forge/MinecraftForge.java | 22 +++++++ .../src/forge/packets/PacketOpenGUI.java | 54 ++++++++++++++++ .../net/minecraft/src/forge/IGuiHandler.java | 21 +++++++ .../net/minecraft/src/EntityPlayer.java.patch | 17 +++++ .../minecraft/src/EntityPlayerSP.java.patch | 40 ++++++++++++ .../net/minecraft/src/EntityPlayer.java.patch | 17 +++++ .../minecraft/src/EntityPlayerMP.java.patch | 62 +++++++++++++++++-- 10 files changed, 271 insertions(+), 6 deletions(-) create mode 100644 forge/forge_client/src/net/minecraft/src/forge/IGuiHandler.java create mode 100644 forge/forge_common/net/minecraft/src/forge/packets/PacketOpenGUI.java create mode 100644 forge/forge_server/src/net/minecraft/src/forge/IGuiHandler.java create mode 100644 forge/patches/minecraft/net/minecraft/src/EntityPlayerSP.java.patch diff --git a/forge/forge_client/src/net/minecraft/src/forge/IGuiHandler.java b/forge/forge_client/src/net/minecraft/src/forge/IGuiHandler.java new file mode 100644 index 000000000..a654b7a8c --- /dev/null +++ b/forge/forge_client/src/net/minecraft/src/forge/IGuiHandler.java @@ -0,0 +1,21 @@ +package net.minecraft.src.forge; + +import net.minecraft.src.EntityPlayerSP; +import net.minecraft.src.GuiScreen; +import net.minecraft.src.World; + +public interface IGuiHandler +{ + /** + * Returns a GuiScreen to be displayed to the user. This is client side + * + * @param ID The Gui ID Number + * @param player The player viewing the Gui + * @param world The current world + * @param X X Position + * @param Y Y Position + * @param Z Z Position + * @return A GuiScreen to be displayed to the user, null if none. + */ + public GuiScreen getGuiScreen(int ID, EntityPlayerSP player, World world, int X, int Y, int Z); +} diff --git a/forge/forge_client/src/net/minecraft/src/forge/PacketHandlerClient.java b/forge/forge_client/src/net/minecraft/src/forge/PacketHandlerClient.java index 9052238ae..81cbf5ef5 100644 --- a/forge/forge_client/src/net/minecraft/src/forge/PacketHandlerClient.java +++ b/forge/forge_client/src/net/minecraft/src/forge/PacketHandlerClient.java @@ -53,6 +53,12 @@ public class PacketHandlerClient implements IPacketHandler pkt.readData(data); onModIDs((PacketModIDs)pkt); break; + + case ForgePacket.OPEN_GUI: + pkt = new PacketOpenGUI(); + pkt.readData(data); + onOpenGui((PacketOpenGUI)pkt); + break; } } catch(IOException e) @@ -192,4 +198,20 @@ public class PacketHandlerClient implements IPacketHandler } //TODO: Display error/confirmation screen } + + /** + * Handles opening the Gui for the player. + * + * @param pkt The Open Gui Packet + */ + private void onOpenGui(PacketOpenGUI pkt) + { + NetworkMod mod = MinecraftForge.getModByID(pkt.ModID); + if (mod != null) + { + EntityPlayerSP player = (EntityPlayerSP)ModLoader.getMinecraftInstance().thePlayer; + player.openGui(mod, pkt.GuiID, player.worldObj, pkt.X, pkt.Y, pkt.Z); + player.craftingInventory.windowId = pkt.WindowID; + } + } } diff --git a/forge/forge_common/net/minecraft/src/forge/ForgeHooks.java b/forge/forge_common/net/minecraft/src/forge/ForgeHooks.java index e1544c3bf..f5b0d3b45 100644 --- a/forge/forge_common/net/minecraft/src/forge/ForgeHooks.java +++ b/forge/forge_common/net/minecraft/src/forge/ForgeHooks.java @@ -368,6 +368,7 @@ public class ForgeHooks { } public static Hashtable networkMods = new Hashtable(); + public static Hashtable guiHandlers = new Hashtable(); public static final int majorVersion=0; public static final int minorVersion=0; diff --git a/forge/forge_common/net/minecraft/src/forge/MinecraftForge.java b/forge/forge_common/net/minecraft/src/forge/MinecraftForge.java index 9df81093a..e669f3c71 100755 --- a/forge/forge_common/net/minecraft/src/forge/MinecraftForge.java +++ b/forge/forge_common/net/minecraft/src/forge/MinecraftForge.java @@ -906,6 +906,28 @@ public class MinecraftForge { } return ret.toArray(new NetworkMod[0]); } + + /** + * Sets the GuiHandler associated with a mod. + * + * @param mod The mod + * @param handler The Gui Handler + */ + public static void setGuiHandler(BaseMod mod, IGuiHandler handler) + { + ForgeHooks.guiHandlers.put(mod, handler); + } + + /** + * Gets the GuiHandler associated with a mod + * + * @param mod The mod + * @return The handler, or null if none associated. + */ + public static IGuiHandler getGuiHandler(BaseMod mod) + { + return ForgeHooks.guiHandlers.get(mod); + } static diff --git a/forge/forge_common/net/minecraft/src/forge/packets/PacketOpenGUI.java b/forge/forge_common/net/minecraft/src/forge/packets/PacketOpenGUI.java new file mode 100644 index 000000000..f2939e42f --- /dev/null +++ b/forge/forge_common/net/minecraft/src/forge/packets/PacketOpenGUI.java @@ -0,0 +1,54 @@ +package net.minecraft.src.forge.packets; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class PacketOpenGUI extends ForgePacket +{ + public int WindowID; + public int ModID; + public int GuiID; + public int X; + public int Y; + public int Z; + + public PacketOpenGUI(){} + public PacketOpenGUI(int window, int mod, int id, int x, int y, int z) + { + WindowID = window; + ModID = mod; + GuiID = id; + X = x; + Y = y; + Z = z; + } + + @Override + public void writeData(DataOutputStream data) throws IOException + { + data.writeInt(WindowID); + data.writeInt(ModID); + data.writeInt(GuiID); + data.writeInt(X); + data.writeInt(Y); + data.writeInt(Z); + } + + @Override + public void readData(DataInputStream data) throws IOException + { + WindowID = data.readInt(); + ModID = data.readInt(); + GuiID = data.readInt(); + X = data.readInt(); + Y = data.readInt(); + Z = data.readInt(); + } + + @Override + public int getID() + { + return ForgePacket.OPEN_GUI; + } +} diff --git a/forge/forge_server/src/net/minecraft/src/forge/IGuiHandler.java b/forge/forge_server/src/net/minecraft/src/forge/IGuiHandler.java new file mode 100644 index 000000000..d4ab03722 --- /dev/null +++ b/forge/forge_server/src/net/minecraft/src/forge/IGuiHandler.java @@ -0,0 +1,21 @@ +package net.minecraft.src.forge; + +import net.minecraft.src.Container; +import net.minecraft.src.EntityPlayerMP; +import net.minecraft.src.World; + +public interface IGuiHandler +{ + /** + * Returns a Container to be displayed to the user. This is server side + * + * @param ID The Gui ID Number + * @param player The player viewing the Gui + * @param world The current world + * @param X X Position + * @param Y Y Position + * @param Z Z Position + * @return A GuiScreen to be displayed to the user, null if none. + */ + public Container getGuiContainer(int ID, EntityPlayerMP player, World world, int X, int Y, int Z); +} diff --git a/forge/patches/minecraft/net/minecraft/src/EntityPlayer.java.patch b/forge/patches/minecraft/net/minecraft/src/EntityPlayer.java.patch index 8974e3133..48b414818 100644 --- a/forge/patches/minecraft/net/minecraft/src/EntityPlayer.java.patch +++ b/forge/patches/minecraft/net/minecraft/src/EntityPlayer.java.patch @@ -140,3 +140,20 @@ if (!worldObj.isRemote) { if (isPlayerSleeping() || !isEntityAlive()) +@@ -1473,4 +1545,16 @@ + experience = entityplayer.experience; + score = entityplayer.score; + } ++ ++ /** ++ * Opens a Gui for the player. ++ * ++ * @param mod The mod associated with the gui ++ * @param ID The ID number for the Gui ++ * @param world The World ++ * @param X X Position ++ * @param Y Y Position ++ * @param Z Z Position ++ */ ++ public void openGui(BaseMod mod, int ID, World world, int X, int Y, int Z){} + } diff --git a/forge/patches/minecraft/net/minecraft/src/EntityPlayerSP.java.patch b/forge/patches/minecraft/net/minecraft/src/EntityPlayerSP.java.patch new file mode 100644 index 000000000..a4747b95a --- /dev/null +++ b/forge/patches/minecraft/net/minecraft/src/EntityPlayerSP.java.patch @@ -0,0 +1,40 @@ +--- ../src_base/minecraft/net/minecraft/src/EntityPlayerSP.java 0000-00-00 00:00:00.000000000 -0000 ++++ ../src_work/minecraft/net/minecraft/src/EntityPlayerSP.java 0000-00-00 00:00:00.000000000 -0000 +@@ -2,6 +2,8 @@ + + import java.util.Random; + import net.minecraft.client.Minecraft; ++import net.minecraft.src.forge.IGuiHandler; ++import net.minecraft.src.forge.MinecraftForge; + + public class EntityPlayerSP extends EntityPlayer + { +@@ -474,4 +476,28 @@ + experienceTotal = i; + experienceLevel = j; + } ++ ++ /** ++ * Opens a Gui for the player. ++ * ++ * @param mod The mod associated with the gui ++ * @param ID The ID number for the Gui ++ * @param world The World ++ * @param X X Position ++ * @param Y Y Position ++ * @param Z Z Position ++ */ ++ @Override ++ public void openGui(BaseMod mod, int ID, World world, int X, int Y, int Z) ++ { ++ IGuiHandler handler = MinecraftForge.getGuiHandler(mod); ++ if (handler != null) ++ { ++ GuiScreen screen = handler.getGuiScreen(ID, this, world, X, Y, Z); ++ if (screen != null) ++ { ++ mc.displayGuiScreen(screen); ++ } ++ } ++ } + } diff --git a/forge/patches/minecraft_server/net/minecraft/src/EntityPlayer.java.patch b/forge/patches/minecraft_server/net/minecraft/src/EntityPlayer.java.patch index 748565193..6f784ae02 100644 --- a/forge/patches/minecraft_server/net/minecraft/src/EntityPlayer.java.patch +++ b/forge/patches/minecraft_server/net/minecraft/src/EntityPlayer.java.patch @@ -150,3 +150,20 @@ if (!worldObj.isRemote) { if (isPlayerSleeping() || !isEntityAlive()) +@@ -1353,4 +1428,16 @@ + experience = entityplayer.experience; + score = entityplayer.score; + } ++ ++ /** ++ * Opens a Gui for the player. ++ * ++ * @param mod The mod associated with the gui ++ * @param ID The ID number for the Gui ++ * @param world The World ++ * @param X X Position ++ * @param Y Y Position ++ * @param Z Z Position ++ */ ++ public void openGui(BaseMod mod, int ID, World world, int X, int Y, int Z){} + } diff --git a/forge/patches/minecraft_server/net/minecraft/src/EntityPlayerMP.java.patch b/forge/patches/minecraft_server/net/minecraft/src/EntityPlayerMP.java.patch index fb0401f7c..2d207b352 100644 --- a/forge/patches/minecraft_server/net/minecraft/src/EntityPlayerMP.java.patch +++ b/forge/patches/minecraft_server/net/minecraft/src/EntityPlayerMP.java.patch @@ -1,6 +1,17 @@ --- ../src_base/minecraft_server/net/minecraft/src/EntityPlayerMP.java 0000-00-00 00:00:00.000000000 -0000 +++ ../src_work/minecraft_server/net/minecraft/src/EntityPlayerMP.java 0000-00-00 00:00:00.000000000 -0000 -@@ -405,6 +405,7 @@ +@@ -2,6 +2,10 @@ + + import java.util.*; + import net.minecraft.server.MinecraftServer; ++import net.minecraft.src.forge.IGuiHandler; ++import net.minecraft.src.forge.MinecraftForge; ++import net.minecraft.src.forge.NetworkMod; ++import net.minecraft.src.forge.packets.PacketOpenGUI; + + public class EntityPlayerMP extends EntityPlayer + implements ICrafting +@@ -405,6 +409,7 @@ public void displayWorkbenchGUI(int i, int j, int k) { getNextWidowId(); @@ -8,7 +19,7 @@ playerNetServerHandler.sendPacket(new Packet100OpenWindow(currentWindowId, 1, "Crafting", 9)); craftingInventory = new ContainerWorkbench(inventory, worldObj, i, j, k); craftingInventory.windowId = currentWindowId; -@@ -414,6 +415,7 @@ +@@ -414,6 +419,7 @@ public void displayGUIEnchantment(int i, int j, int k) { getNextWidowId(); @@ -16,7 +27,7 @@ playerNetServerHandler.sendPacket(new Packet100OpenWindow(currentWindowId, 4, "Enchanting", 9)); craftingInventory = new ContainerEnchantment(inventory, worldObj, i, j, k); craftingInventory.windowId = currentWindowId; -@@ -423,6 +425,7 @@ +@@ -423,6 +429,7 @@ public void displayGUIChest(IInventory iinventory) { getNextWidowId(); @@ -24,7 +35,7 @@ playerNetServerHandler.sendPacket(new Packet100OpenWindow(currentWindowId, 0, iinventory.getInvName(), iinventory.getSizeInventory())); craftingInventory = new ContainerChest(inventory, iinventory); craftingInventory.windowId = currentWindowId; -@@ -432,6 +435,7 @@ +@@ -432,6 +439,7 @@ public void displayGUIFurnace(TileEntityFurnace tileentityfurnace) { getNextWidowId(); @@ -32,7 +43,7 @@ playerNetServerHandler.sendPacket(new Packet100OpenWindow(currentWindowId, 2, tileentityfurnace.getInvName(), tileentityfurnace.getSizeInventory())); craftingInventory = new ContainerFurnace(inventory, tileentityfurnace); craftingInventory.windowId = currentWindowId; -@@ -441,6 +445,7 @@ +@@ -441,6 +449,7 @@ public void displayGUIDispenser(TileEntityDispenser tileentitydispenser) { getNextWidowId(); @@ -40,7 +51,7 @@ playerNetServerHandler.sendPacket(new Packet100OpenWindow(currentWindowId, 3, tileentitydispenser.getInvName(), tileentitydispenser.getSizeInventory())); craftingInventory = new ContainerDispenser(inventory, tileentitydispenser); craftingInventory.windowId = currentWindowId; -@@ -450,6 +455,7 @@ +@@ -450,6 +459,7 @@ public void displayGUIBrewingStand(TileEntityBrewingStand tileentitybrewingstand) { getNextWidowId(); @@ -48,3 +59,42 @@ playerNetServerHandler.sendPacket(new Packet100OpenWindow(currentWindowId, 5, tileentitybrewingstand.getInvName(), tileentitybrewingstand.getSizeInventory())); craftingInventory = new ContainerBrewingStand(inventory, tileentitybrewingstand); craftingInventory.windowId = currentWindowId; +@@ -613,4 +623,38 @@ + EntityTracker entitytracker = mcServer.getEntityTracker(dimension); + entitytracker.sendPacketToTrackedPlayersAndTrackedEntity(this, new Packet18Animation(entity, 7)); + } ++ ++ /** ++ * Opens a Gui for the player. ++ * ++ * @param mod The mod associated with the gui ++ * @param ID The ID number for the Gui ++ * @param world The World ++ * @param X X Position ++ * @param Y Y Position ++ * @param Z Z Position ++ */ ++ @Override ++ public void openGui(BaseMod mod, int ID, World world, int X, int Y, int Z) ++ { ++ if (!(mod instanceof NetworkMod)) ++ { ++ return; ++ } ++ IGuiHandler handler = MinecraftForge.getGuiHandler(mod); ++ if (handler != null) ++ { ++ Container container = handler.getGuiContainer(ID, this, world, X, Y, Z); ++ if (container != null) ++ { ++ getNextWidowId(); ++ closeCraftingGui(); ++ PacketOpenGUI pkt = new PacketOpenGUI(currentWindowId, MinecraftForge.getModID((NetworkMod)mod), ID, X, Y, Z); ++ playerNetServerHandler.sendPacket(pkt.getPacket()); ++ craftingInventory = container; ++ craftingInventory.windowId = currentWindowId; ++ craftingInventory.onCraftGuiOpened(this); ++ } ++ } ++ } + }