diff --git a/patches/minecraft/net/minecraft/client/Minecraft.java.patch b/patches/minecraft/net/minecraft/client/Minecraft.java.patch index dd4c8406dd..2d13c36f19 100644 --- a/patches/minecraft/net/minecraft/client/Minecraft.java.patch +++ b/patches/minecraft/net/minecraft/client/Minecraft.java.patch @@ -44,7 +44,7 @@ Display.setVSyncEnabled(this.field_71474_y.field_74352_v); } -@@ -916,9 +925,11 @@ +@@ -915,9 +924,11 @@ if (!this.field_71454_w) { @@ -56,7 +56,7 @@ } GL11.glFlush(); -@@ -1491,11 +1502,15 @@ +@@ -1490,11 +1501,15 @@ public void func_71407_l() { @@ -72,7 +72,7 @@ this.field_71424_I.func_76320_a("gui"); if (!this.field_71445_n) -@@ -1978,6 +1993,8 @@ +@@ -1977,6 +1992,8 @@ this.field_71453_ak.func_74428_b(); } diff --git a/patches/minecraft/net/minecraft/entity/player/EntityPlayerMP.java.patch b/patches/minecraft/net/minecraft/entity/player/EntityPlayerMP.java.patch index 54579b83e5..4098001acb 100644 --- a/patches/minecraft/net/minecraft/entity/player/EntityPlayerMP.java.patch +++ b/patches/minecraft/net/minecraft/entity/player/EntityPlayerMP.java.patch @@ -10,12 +10,3 @@ import net.minecraft.crash.CrashReport; import net.minecraft.crash.CrashReportCategory; import net.minecraft.entity.Entity; -@@ -108,7 +111,7 @@ - public final ItemInWorldManager field_71134_c; - public double field_71131_d; - public double field_71132_e; -- public final List field_71129_f = new LinkedList(); -+ public final Queue field_71129_f = new ConcurrentLinkedQueue(); - public final List field_71130_g = new LinkedList(); - private final StatisticsFile field_147103_bO; - private float field_130068_bO = Float.MIN_VALUE; diff --git a/src/main/java/cpw/mods/fml/common/network/FMLNetworkException.java b/src/main/java/cpw/mods/fml/common/network/FMLNetworkException.java index 67c40e4945..d10b955405 100644 --- a/src/main/java/cpw/mods/fml/common/network/FMLNetworkException.java +++ b/src/main/java/cpw/mods/fml/common/network/FMLNetworkException.java @@ -24,4 +24,9 @@ public class FMLNetworkException extends RuntimeException public FMLNetworkException() { } + + public FMLNetworkException(String string) + { + super(string); + } } diff --git a/src/main/java/cpw/mods/fml/common/network/FMLOutboundHandler.java b/src/main/java/cpw/mods/fml/common/network/FMLOutboundHandler.java index 72de8d60ad..cb570ecbb4 100644 --- a/src/main/java/cpw/mods/fml/common/network/FMLOutboundHandler.java +++ b/src/main/java/cpw/mods/fml/common/network/FMLOutboundHandler.java @@ -164,6 +164,13 @@ public class FMLOutboundHandler extends ChannelOutboundHandlerAdapter { } OutboundTarget outboundTarget; Object args = null; + NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get(); + // INTERNAL message callback - let it pass out + if (dispatcher != null) + { + ctx.write(msg, promise); + return; + } if (ctx.channel().attr(NetworkRegistry.CHANNEL_SOURCE).get() == Side.CLIENT) { outboundTarget = OutboundTarget.TOSERVER; @@ -183,9 +190,9 @@ public class FMLOutboundHandler extends ChannelOutboundHandlerAdapter { ctx.write(msg, promise); return; } - for (NetworkDispatcher dispatcher : dispatchers) + for (NetworkDispatcher targetDispatcher : dispatchers) { - dispatcher.sendProxy((FMLProxyPacket) msg); + targetDispatcher.sendProxy((FMLProxyPacket) msg); } } diff --git a/src/main/java/cpw/mods/fml/common/network/handshake/FMLHandshakeClientState.java b/src/main/java/cpw/mods/fml/common/network/handshake/FMLHandshakeClientState.java index 313be96cd3..8fb571c50c 100644 --- a/src/main/java/cpw/mods/fml/common/network/handshake/FMLHandshakeClientState.java +++ b/src/main/java/cpw/mods/fml/common/network/handshake/FMLHandshakeClientState.java @@ -4,6 +4,7 @@ import io.netty.channel.ChannelHandlerContext; import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.network.NetworkRegistry; +import cpw.mods.fml.common.network.internal.FMLMessage; import cpw.mods.fml.common.network.internal.FMLNetworkHandler; import cpw.mods.fml.common.registry.GameData; import cpw.mods.fml.relauncher.Side; @@ -83,10 +84,9 @@ enum FMLHandshakeClientState implements IHandshakeState @Override public FMLHandshakeClientState accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg) { - NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get(); - dispatcher.continueToClientPlayState(); - FMLLog.info("Client side modded connection established"); + FMLMessage.CompleteHandshake complete = new FMLMessage.CompleteHandshake(Side.SERVER); ctx.writeAndFlush(new FMLHandshakeMessage.HandshakeAck()); + ctx.fireChannelRead(complete); return DONE; } }, diff --git a/src/main/java/cpw/mods/fml/common/network/handshake/FMLHandshakeServerState.java b/src/main/java/cpw/mods/fml/common/network/handshake/FMLHandshakeServerState.java index 9bde3e1aef..9f6f7d3276 100644 --- a/src/main/java/cpw/mods/fml/common/network/handshake/FMLHandshakeServerState.java +++ b/src/main/java/cpw/mods/fml/common/network/handshake/FMLHandshakeServerState.java @@ -4,6 +4,7 @@ import io.netty.channel.ChannelHandlerContext; import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.network.NetworkRegistry; +import cpw.mods.fml.common.network.internal.FMLMessage; import cpw.mods.fml.common.network.internal.FMLNetworkHandler; import cpw.mods.fml.common.registry.GameData; import cpw.mods.fml.relauncher.Side; @@ -65,9 +66,8 @@ enum FMLHandshakeServerState implements IHandshakeState @Override public FMLHandshakeServerState accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg) { - NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get(); - FMLLog.info("Server side modded connection established"); - dispatcher.continueToServerPlayState(); + FMLMessage.CompleteHandshake complete = new FMLMessage.CompleteHandshake(Side.SERVER); + ctx.fireChannelRead(complete); return DONE; } }, diff --git a/src/main/java/cpw/mods/fml/common/network/handshake/NetworkDispatcher.java b/src/main/java/cpw/mods/fml/common/network/handshake/NetworkDispatcher.java index ca25d3be9e..7e0b6bd5c1 100644 --- a/src/main/java/cpw/mods/fml/common/network/handshake/NetworkDispatcher.java +++ b/src/main/java/cpw/mods/fml/common/network/handshake/NetworkDispatcher.java @@ -12,6 +12,7 @@ import io.netty.util.concurrent.GenericFutureListener; import io.netty.util.concurrent.ScheduledFuture; import java.net.SocketAddress; +import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; @@ -26,7 +27,10 @@ import net.minecraft.network.play.server.S40PacketDisconnect; import net.minecraft.server.management.ServerConfigurationManager; import net.minecraft.util.ChatComponentText; import cpw.mods.fml.common.FMLLog; +import cpw.mods.fml.common.network.FMLNetworkException; import cpw.mods.fml.common.network.NetworkRegistry; +import cpw.mods.fml.common.network.internal.FMLMessage; +import cpw.mods.fml.common.network.internal.FMLNetworkHandler; import cpw.mods.fml.common.network.internal.FMLProxyPacket; import cpw.mods.fml.relauncher.Side; @@ -67,6 +71,7 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler imple private ConnectionType connectionType; private final Side side; private final EmbeddedChannel handshakeChannel; + private NetHandlerPlayServer serverHandler; public NetworkDispatcher(NetworkManager manager) { @@ -127,6 +132,12 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler imple // This will be ignored by vanilla clients this.state = ConnectionState.AWAITING_HANDSHAKE; this.manager.channel().pipeline().addFirst("fml:vanilla_detector", new VanillaTimeoutWaiter()); + // Need to start the handler here, so we can send custompayload packets + serverHandler = new NetHandlerPlayServer(scm.func_72365_p(), manager, player); + // NULL the play server here - we restore it further on. If not, there are packets sent before the login + player.field_71135_a = null; + // manually for the manager into the PLAY state, so we can send packets later + this.manager.func_150723_a(EnumConnectionState.PLAY); } void clientListenForServerHandshake() @@ -135,30 +146,19 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler imple this.state = ConnectionState.AWAITING_HANDSHAKE; } - void continueToClientPlayState() - { - this.state = ConnectionState.CONNECTED; - this.connectionType = ConnectionType.MODDED; - completeClientSideConnection(); - } - private void completeClientSideConnection() { - } - - void continueToServerPlayState() - { + FMLLog.info("[%s] Client side modded connection established", Thread.currentThread().getName()); this.state = ConnectionState.CONNECTED; this.connectionType = ConnectionType.MODDED; - completeServerSideConnection(); } private void completeServerSideConnection() { - NetHandlerPlayServer nethandler = new NetHandlerPlayServer(scm.func_72365_p(), manager, player); - // NULL the play server here - we restore it further on. If not, there are packets sent before the login - player.field_71135_a = null; - scm.func_72355_a(manager, player, nethandler); + FMLLog.info("[%s] Server side modded connection established", Thread.currentThread().getName()); + this.state = ConnectionState.CONNECTED; + this.connectionType = ConnectionType.MODDED; + scm.func_72355_a(manager, player, serverHandler); } @Override protected void channelRead0(ChannelHandlerContext ctx, Packet msg) throws Exception @@ -175,12 +175,11 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler imple else if (msg instanceof S40PacketDisconnect && state != ConnectionState.CONNECTED) { // Switch to play state to handle the disconnect message - continueToClientPlayState(); + completeClientSideConnection(); } else if (state != ConnectionState.CONNECTED) { - FMLLog.info("Unexpected packet during modded negotiation - assuming vanilla"); - kickVanilla(); + FMLLog.info("Unexpected packet during modded negotiation - assuming vanilla or keepalives : %s", msg.getClass().getName()); } if (!handled) { @@ -222,6 +221,18 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler imple { FMLProxyPacket proxy = new FMLProxyPacket(msg); handshakeChannel.writeInbound(proxy); + // forward any messages into the regular channel + for (Object push : handshakeChannel.inboundMessages()) + { + List messageResult = FMLNetworkHandler.forwardHandshake((FMLMessage.CompleteHandshake)push, this, Side.CLIENT); + for (FMLProxyPacket result: messageResult) + { + result.setTarget(Side.CLIENT); + result.payload().resetReaderIndex(); + context.fireChannelRead(result); + } + } + handshakeChannel.inboundMessages().clear(); return true; } else if (NetworkRegistry.INSTANCE.hasChannel(channelName, Side.CLIENT)) @@ -245,6 +256,17 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler imple { FMLProxyPacket proxy = new FMLProxyPacket(msg); handshakeChannel.writeInbound(proxy); + for (Object push : handshakeChannel.inboundMessages()) + { + List messageResult = FMLNetworkHandler.forwardHandshake((FMLMessage.CompleteHandshake)push, this, Side.SERVER); + for (FMLProxyPacket result: messageResult) + { + result.setTarget(Side.SERVER); + result.payload().resetReaderIndex(); + context.fireChannelRead(result); + } + } + handshakeChannel.inboundMessages().clear(); return true; } else if (NetworkRegistry.INSTANCE.hasChannel(channelName, Side.SERVER)) @@ -352,4 +374,20 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler imple { ctx.flush(); } + + public void completeHandshake(Side target) + { + if (state == ConnectionState.CONNECTED) + { + throw new FMLNetworkException("Attempt to double complete!"); + } + if (side == Side.CLIENT) + { + completeClientSideConnection(); + } + else + { + completeServerSideConnection(); + } + } } diff --git a/src/main/java/cpw/mods/fml/common/network/internal/FMLMessage.java b/src/main/java/cpw/mods/fml/common/network/internal/FMLMessage.java index cbe01130f5..edce8a5c00 100644 --- a/src/main/java/cpw/mods/fml/common/network/internal/FMLMessage.java +++ b/src/main/java/cpw/mods/fml/common/network/internal/FMLMessage.java @@ -16,8 +16,27 @@ import cpw.mods.fml.common.network.ByteBufUtils; import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration; import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData; import cpw.mods.fml.common.registry.IThrowableEntity; +import cpw.mods.fml.relauncher.Side; public abstract class FMLMessage { + public static class CompleteHandshake extends FMLMessage { + Side target; + public CompleteHandshake() {} + public CompleteHandshake(Side target) + { + this.target = target; + } + @Override + void fromBytes(ByteBuf buf) + { + target = Side.values()[buf.readByte()]; + } + @Override + void toBytes(ByteBuf buf) + { + buf.writeByte(target.ordinal()); + } + } public static class OpenGui extends FMLMessage { int windowId; int networkId; diff --git a/src/main/java/cpw/mods/fml/common/network/internal/FMLNetworkHandler.java b/src/main/java/cpw/mods/fml/common/network/internal/FMLNetworkHandler.java index 59c0a5b8f3..4a5fcc69de 100644 --- a/src/main/java/cpw/mods/fml/common/network/internal/FMLNetworkHandler.java +++ b/src/main/java/cpw/mods/fml/common/network/internal/FMLNetworkHandler.java @@ -14,6 +14,7 @@ package cpw.mods.fml.common.network.internal; import io.netty.channel.embedded.EmbeddedChannel; +import java.util.ArrayList; import java.util.EnumMap; import java.util.List; import java.util.Map; @@ -35,10 +36,11 @@ import cpw.mods.fml.common.FMLContainer; import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.ModContainer; import cpw.mods.fml.common.network.FMLOutboundHandler; -import cpw.mods.fml.common.network.NetworkRegistry; import cpw.mods.fml.common.network.FMLOutboundHandler.OutboundTarget; +import cpw.mods.fml.common.network.NetworkRegistry; import cpw.mods.fml.common.network.handshake.FMLHandshakeMessage; import cpw.mods.fml.common.network.handshake.NetworkDispatcher; +import cpw.mods.fml.common.network.internal.FMLMessage.CompleteHandshake; import cpw.mods.fml.common.registry.EntityRegistry; import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration; import cpw.mods.fml.relauncher.Side; @@ -508,7 +510,7 @@ public class FMLNetworkHandler } public static void registerChannel(FMLContainer container, Side side) { - channelPair = NetworkRegistry.INSTANCE.newChannel(container, "FML", new FMLRuntimeCodec()); + channelPair = NetworkRegistry.INSTANCE.newChannel(container, "FML", new FMLRuntimeCodec(), new HandshakeCompletionHandler()); EmbeddedChannel embeddedChannel = channelPair.get(Side.SERVER); embeddedChannel.attr(FMLOutboundHandler.FML_MESSAGETARGET).set(OutboundTarget.NOWHERE); @@ -518,4 +520,18 @@ public class FMLNetworkHandler } } + public static List forwardHandshake(CompleteHandshake push, NetworkDispatcher target, Side side) + { + channelPair.get(side).attr(NetworkDispatcher.FML_DISPATCHER).set(target); + channelPair.get(side).writeOutbound(push); + + ArrayList list = new ArrayList(); + for (Object o: channelPair.get(side).outboundMessages()) + { + list.add((FMLProxyPacket)o); + } + channelPair.get(side).outboundMessages().clear(); + return list; + } + } diff --git a/src/main/java/cpw/mods/fml/common/network/internal/FMLProxyPacket.java b/src/main/java/cpw/mods/fml/common/network/internal/FMLProxyPacket.java index 2459c4e7ff..e071443e40 100644 --- a/src/main/java/cpw/mods/fml/common/network/internal/FMLProxyPacket.java +++ b/src/main/java/cpw/mods/fml/common/network/internal/FMLProxyPacket.java @@ -86,4 +86,9 @@ public class FMLProxyPacket extends Packet { { return new S3FPacketCustomPayload(channel, payload.array()); } + + public void setTarget(Side target) + { + this.target = target; + } } diff --git a/src/main/java/cpw/mods/fml/common/network/internal/FMLRuntimeCodec.java b/src/main/java/cpw/mods/fml/common/network/internal/FMLRuntimeCodec.java index 899abde936..1d611a4eb5 100644 --- a/src/main/java/cpw/mods/fml/common/network/internal/FMLRuntimeCodec.java +++ b/src/main/java/cpw/mods/fml/common/network/internal/FMLRuntimeCodec.java @@ -7,6 +7,7 @@ import io.netty.channel.ChannelHandlerContext; public class FMLRuntimeCodec extends FMLIndexedMessageToMessageCodec { public FMLRuntimeCodec() { + addDiscriminator(0,FMLMessage.CompleteHandshake.class); addDiscriminator(1,FMLMessage.OpenGui.class); addDiscriminator(2,FMLMessage.EntitySpawnMessage.class); addDiscriminator(3,FMLMessage.EntityAdjustMessage.class); diff --git a/src/main/java/cpw/mods/fml/common/network/internal/HandshakeCompletionHandler.java b/src/main/java/cpw/mods/fml/common/network/internal/HandshakeCompletionHandler.java new file mode 100644 index 0000000000..37c3a56831 --- /dev/null +++ b/src/main/java/cpw/mods/fml/common/network/internal/HandshakeCompletionHandler.java @@ -0,0 +1,17 @@ +package cpw.mods.fml.common.network.internal; + +import cpw.mods.fml.common.network.handshake.NetworkDispatcher; +import cpw.mods.fml.common.network.internal.FMLMessage.CompleteHandshake; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.channel.ChannelHandler.Sharable; + +@Sharable +public class HandshakeCompletionHandler extends SimpleChannelInboundHandler { + @Override + protected void channelRead0(ChannelHandlerContext ctx, CompleteHandshake msg) throws Exception + { + NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).getAndRemove(); + dispatcher.completeHandshake(msg.target); + } +} diff --git a/src/main/resources/fml_at.cfg b/src/main/resources/fml_at.cfg index 7ecd66091c..54502ccb83 100644 --- a/src/main/resources/fml_at.cfg +++ b/src/main/resources/fml_at.cfg @@ -71,6 +71,8 @@ public net.minecraft.entity.passive.EntityVillager field_70958_bB public net.minecraft.entity.passive.EntityVillager field_70960_bC ## GuiButtonMerchant #public axx #CL:GuiButtonMerchant +# GuiScreen +public net.minecraft.client.gui.GuiScreen field_146297_k # minecraft instance - public because gui's outside access it # Minecraft #public atv.D #FD:Minecraft/field_71425_J #running public net.minecraft.client.Minecraft field_71446_o # textureManager