diff --git a/forge/forge_client/src/net/minecraft/src/forge/ForgeHooksClient.java b/forge/forge_client/src/net/minecraft/src/forge/ForgeHooksClient.java index 4ae2efe229..0b653a1e86 100644 --- a/forge/forge_client/src/net/minecraft/src/forge/ForgeHooksClient.java +++ b/forge/forge_client/src/net/minecraft/src/forge/ForgeHooksClient.java @@ -6,15 +6,21 @@ package net.minecraft.src.forge; import net.minecraft.src.Block; +import net.minecraft.src.Entity; import net.minecraft.src.ModLoader; +import net.minecraft.src.Packet100OpenWindow; import net.minecraft.src.RenderBlocks; import net.minecraft.src.Tessellator; import net.minecraft.src.RenderGlobal; import net.minecraft.src.EntityPlayer; import net.minecraft.src.MovingObjectPosition; import net.minecraft.src.ItemStack; +import net.minecraft.src.WorldClient; + import org.lwjgl.opengl.GL11; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.util.*; import net.minecraft.src.*; import org.lwjgl.opengl.GL12; @@ -287,4 +293,103 @@ public class ForgeHooksClient GL11.glPopMatrix(); } } + + /** + * Trys to get the class for the specified name, will also try the + * net.minecraft.src package in case we are in MCP + * Returns null if not found. + * + * @param name The class name + * @return The Class, or null if not found + */ + private static Class getClass(String name) + { + try + { + return Class.forName(name); + } + catch (Exception e) + { + try + { + return Class.forName("net.minecraft.src." + name); + } + catch (Exception e2) + { + return null; + } + } + } + + /** + * Helper function to try and invoke ModLoaderMp's NetClientHandler.handleVehicleSpawn modifications + * if ModLoaderMp is install along side Forge. + */ + public static Object tryMLMPVehicleSpawn(int type, World world, double x, double y, double z, Entity thrower) throws Exception + { + Class mlmp = getClass("ModLoaderMp"); + if (mlmp == null) + { + return null; + } + + Object entry = mlmp.getDeclaredMethod("handleNetClientHandlerEntities", int.class).invoke(null, type); + if (entry == null) + { + return null; + } + + Class entityClass = (Class)entry.getClass().getDeclaredField("entityClass").get(entry); + Object ret = (Entity)entityClass.getConstructor(World.class, Double.TYPE, Double.TYPE, Double.TYPE).newInstance(world, x, y, z); + + if (entry.getClass().getDeclaredField("entityHasOwner").getBoolean(entry)) + { + Field owner = entityClass.getField("owner"); + + if (!Entity.class.isAssignableFrom(owner.getType())) + { + throw new Exception(String.format("Entity\'s owner field must be of type Entity, but it is of type %s.", owner.getType())); + } + + if (thrower == null) + { + System.out.println("Received spawn packet for entity with owner, but owner was not found."); + ModLoader.getLogger().fine("Received spawn packet for entity with owner, but owner was not found."); + } + else + { + if (!owner.getType().isAssignableFrom(thrower.getClass())) + { + throw new Exception(String.format("Tried to assign an entity of type %s to entity owner, which is of type %s.", thrower.getClass(), owner.getType())); + } + + owner.set(ret, thrower); + } + } + return ret; + } + + /** + * helper function to try and call ModLoaderMp's handleGUI function + * if ModLoaderMp is installed client side along with Forge. + * + * @param pkt The open window packet + */ + public static void tryMLMPOpenWindow(Packet100OpenWindow pkt) + { + Class mlmp = getClass("ModLoaderMp"); + if (mlmp == null) + { + return; + } + + try + { + mlmp.getDeclaredMethod("handleGUI", Packet100OpenWindow.class).invoke(null, pkt); + } + catch (Exception e) + { + e.printStackTrace(); + } + } } diff --git a/forge/patches/minecraft/net/minecraft/src/NetClientHandler.java.patch b/forge/patches/minecraft/net/minecraft/src/NetClientHandler.java.patch index ae59de2474..8477bb82a9 100644 --- a/forge/patches/minecraft/net/minecraft/src/NetClientHandler.java.patch +++ b/forge/patches/minecraft/net/minecraft/src/NetClientHandler.java.patch @@ -1,6 +1,6 @@ --- ../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 -@@ -14,7 +14,13 @@ +@@ -14,7 +14,14 @@ import java.util.List; import java.util.Map; import java.util.Random; @@ -8,13 +8,14 @@ + import net.minecraft.client.Minecraft; +import net.minecraft.src.forge.ForgeHooks; ++import net.minecraft.src.forge.ForgeHooksClient; +import net.minecraft.src.forge.MessageManager; +import net.minecraft.src.forge.packets.ForgePacket; +import java.io.UnsupportedEncodingException; public class NetClientHandler extends NetHandler { -@@ -46,6 +52,8 @@ +@@ -46,6 +53,8 @@ this.mc = par1Minecraft; Socket var4 = new Socket(InetAddress.getByName(par2Str), par3); this.netManager = new NetworkManager(var4, "Client", this); @@ -23,7 +24,7 @@ } /** -@@ -73,6 +81,30 @@ +@@ -73,6 +82,30 @@ this.mc.thePlayer.entityId = par1Packet1Login.protocolVersion; this.currentServerMaxPlayers = par1Packet1Login.maxPlayers; ((PlayerControllerMP)this.mc.playerController).setCreative(par1Packet1Login.serverMode == 1); @@ -54,7 +55,27 @@ ModLoader.serverConnect(this, par1Packet1Login); } -@@ -545,8 +577,12 @@ +@@ -178,6 +211,19 @@ + { + var8 = new EntityFallingSand(this.worldClient, var2, var4, var6, Block.dragonEgg.blockID); + } ++ ++ try ++ { ++ var8 = ForgeHooksClient.tryMLMPVehicleSpawn(par1Packet23VehicleSpawn.type, ++ worldClient, var2, var4, var6, ++ getEntityByID(par1Packet23VehicleSpawn.throwerEntityId)); ++ } ++ catch (Exception e) ++ { ++ ModLoader.getLogger().throwing("NetClientHandler", "handleVehicleSpawn", e); ++ ModLoader.throwException(String.format("Error initalizing entity of type %d", par1Packet23VehicleSpawn.type), e); ++ return; ++ } + + if (var8 != null) + { +@@ -545,8 +591,12 @@ public void handleChat(Packet3Chat par1Packet3Chat) { @@ -69,7 +90,7 @@ } public void handleAnimation(Packet18Animation par1Packet18Animation) -@@ -633,7 +669,19 @@ +@@ -633,7 +683,19 @@ } else if (par1Packet2Handshake.username.equals("-")) { @@ -90,7 +111,7 @@ } else { -@@ -646,7 +694,19 @@ +@@ -646,7 +708,19 @@ if (var6.equalsIgnoreCase("ok")) { @@ -111,7 +132,18 @@ } else { -@@ -939,6 +999,19 @@ +@@ -833,6 +907,10 @@ + case 5: + var2.displayGUIBrewingStand(new TileEntityBrewingStand()); + var2.craftingInventory.windowId = par1Packet100OpenWindow.windowId; ++ break; ++ ++ default: ++ ForgeHooksClient.tryMLMPOpenWindow(par1Packet100OpenWindow); + } + } + +@@ -939,6 +1017,19 @@ { ((TileEntityMobSpawner)var2).setMobID(EntityList.getStringFromID(par1Packet132TileEntityData.customParam1)); } @@ -131,7 +163,7 @@ } } -@@ -1012,6 +1085,10 @@ +@@ -1012,6 +1103,10 @@ { ItemMap.getMPMapData(par1Packet131MapData.uniqueID, this.mc.theWorld).func_28171_a(par1Packet131MapData.itemData); } @@ -142,7 +174,7 @@ else { System.out.println("Unknown itemid: " + par1Packet131MapData.uniqueID); -@@ -1114,5 +1191,40 @@ +@@ -1114,5 +1209,40 @@ public void handleCustomPayload(Packet250CustomPayload var1) { ModLoader.receivePacket(var1);