Something I meant to add a long time ago, but it got overlooked. My apologies. Presend the (int)

dimension ID in the serverhello packet. This should be 100% backward compatible with existing servers
but bumping a server to this version will allow clients with this version as well to now login in
dimensions outside the byte range. Probably fixes a bunch of mods that add dimensions.
This commit is contained in:
cpw 2015-03-20 14:19:54 -04:00
parent 278612ad98
commit 889c967a5b
6 changed files with 93 additions and 5 deletions

View file

@ -0,0 +1,42 @@
--- ../src-base/minecraft/net/minecraft/client/network/NetHandlerPlayClient.java
+++ ../src-work/minecraft/net/minecraft/client/network/NetHandlerPlayClient.java
@@ -2,11 +2,14 @@
import com.google.common.base.Charsets;
import com.mojang.authlib.GameProfile;
+
+import cpw.mods.fml.common.network.handshake.NetworkDispatcher;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.concurrent.GenericFutureListener;
+
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
@@ -17,6 +20,7 @@
import java.util.Map;
import java.util.Random;
import java.util.Map.Entry;
+
import net.minecraft.block.Block;
import net.minecraft.client.ClientBrandRetriever;
import net.minecraft.client.Minecraft;
@@ -195,6 +199,7 @@
import net.minecraft.world.storage.ISaveHandler;
import net.minecraft.world.storage.MapData;
import net.minecraft.world.storage.MapStorage;
+
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -232,7 +237,7 @@
public void func_147282_a(S01PacketJoinGame p_147282_1_)
{
this.field_147299_f.field_71442_b = new PlayerControllerMP(this.field_147299_f, this);
- this.field_147300_g = new WorldClient(this, new WorldSettings(0L, p_147282_1_.func_149198_e(), false, p_147282_1_.func_149195_d(), p_147282_1_.func_149196_i()), p_147282_1_.func_149194_f(), p_147282_1_.func_149192_g(), this.field_147299_f.field_71424_I);
+ this.field_147300_g = new WorldClient(this, new WorldSettings(0L, p_147282_1_.func_149198_e(), false, p_147282_1_.func_149195_d(), p_147282_1_.func_149196_i()), NetworkDispatcher.get(func_147298_b()).getOverrideDimension(p_147282_1_), p_147282_1_.func_149192_g(), this.field_147299_f.field_71424_I);
this.field_147300_g.field_72995_K = true;
this.field_147299_f.func_71403_a(this.field_147300_g);
this.field_147299_f.field_71439_g.field_71093_bK = p_147282_1_.func_149194_f();

View file

@ -63,7 +63,9 @@ public enum NetworkRegistry
public static final AttributeKey<ModContainer> MOD_CONTAINER = new AttributeKey<ModContainer>("fml:modContainer");
public static final AttributeKey<INetHandler> NET_HANDLER = new AttributeKey<INetHandler>("fml:netHandler");
public static final byte FML_PROTOCOL = 1;
// Version 1: ServerHello only contains this value as a byte
// Version 2: ServerHello additionally contains a 4 byte (int) dimension for the logging in client
public static final byte FML_PROTOCOL = 2;
private NetworkRegistry()
{

View file

@ -1,11 +1,13 @@
package cpw.mods.fml.common.network.handshake;
import java.util.List;
import io.netty.channel.ChannelFutureListener;
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.handshake.FMLHandshakeMessage.ServerHello;
import cpw.mods.fml.common.network.internal.FMLMessage;
import cpw.mods.fml.common.network.internal.FMLNetworkHandler;
import cpw.mods.fml.common.registry.GameData;
@ -49,7 +51,14 @@ enum FMLHandshakeClientState implements IHandshakeState<FMLHandshakeClientState>
return DONE;
}
FMLLog.info("Server protocol version %x", ((FMLHandshakeMessage.ServerHello)msg).protocolVersion());
ServerHello serverHelloPacket = (FMLHandshakeMessage.ServerHello)msg;
FMLLog.info("Server protocol version %x", serverHelloPacket.protocolVersion());
if (serverHelloPacket.protocolVersion() > 1)
{
// Server sent us an extra dimension for the logging in player - stash it for retrieval later
NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get();
dispatcher.setOverrideDimension(serverHelloPacket.overrideDim());
}
ctx.writeAndFlush(new FMLHandshakeMessage.ClientHello()).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
ctx.writeAndFlush(new FMLHandshakeMessage.ModList(Loader.instance().getActiveModList())).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
return WAITINGSERVERDATA;

View file

@ -15,6 +15,7 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.network.ByteBufUtils;
import cpw.mods.fml.common.network.NetworkRegistry;
@ -30,22 +31,42 @@ public abstract class FMLHandshakeMessage {
}
public static class ServerHello extends FMLHandshakeMessage {
private byte serverProtocolVersion;
private int overrideDimension;
public ServerHello(int overrideDim) {
this.overrideDimension = overrideDim;
}
@Override
public void toBytes(ByteBuf buffer)
{
buffer.writeByte(NetworkRegistry.FML_PROTOCOL);
buffer.writeInt(overrideDimension);
}
@Override
public void fromBytes(ByteBuf buffer)
{
serverProtocolVersion = buffer.readByte();
// Extended dimension support during login
if (serverProtocolVersion > 1)
{
overrideDimension = buffer.readInt();
FMLLog.fine("Server FML protocol version %d, 4 byte dimension received %d", serverProtocolVersion, overrideDimension);
}
else
{
FMLLog.info("Server FML protocol version %d, no additional data received", serverProtocolVersion);
}
}
public byte protocolVersion()
{
return serverProtocolVersion;
}
public int overrideDim() {
return overrideDimension;
}
}
public static class ClientHello extends FMLHandshakeMessage {
private byte serverProtocolVersion;

View file

@ -18,9 +18,9 @@ enum FMLHandshakeServerState implements IHandshakeState<FMLHandshakeServerState>
public FMLHandshakeServerState accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg)
{
NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get();
dispatcher.serverInitiateHandshake();
int overrideDim = dispatcher.serverInitiateHandshake();
ctx.writeAndFlush(FMLHandshakeMessage.makeCustomChannelRegistration(NetworkRegistry.INSTANCE.channelNamesFor(Side.SERVER))).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
ctx.writeAndFlush(new FMLHandshakeMessage.ServerHello()).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
ctx.writeAndFlush(new FMLHandshakeMessage.ServerHello(overrideDim)).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
return HELLO;
}
},

View file

@ -79,6 +79,7 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> imple
private final EmbeddedChannel handshakeChannel;
private NetHandlerPlayServer serverHandler;
private INetHandler netHandler;
private int overrideLoginDim;
public NetworkDispatcher(NetworkManager manager)
{
@ -133,7 +134,7 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> imple
this.manager.channel().config().setAutoRead(true);
}
void serverInitiateHandshake()
int serverInitiateHandshake()
{
// Send mod salutation to the client
// This will be ignored by vanilla clients
@ -146,6 +147,9 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> imple
player.playerNetServerHandler = null;
// manually for the manager into the PLAY state, so we can send packets later
this.manager.setConnectionState(EnumConnectionState.PLAY);
// Return the dimension the player is in, so it can be pre-sent to the client in the ServerHello v2 packet
return player.dimension;
}
void clientListenForServerHandshake()
@ -480,4 +484,14 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> imple
this.handshakeChannel.attr(FML_DISPATCHER).remove();
this.manager.channel().attr(FML_DISPATCHER).remove();
}
public void setOverrideDimension(int overrideDim) {
this.overrideLoginDim = overrideDim;
FMLLog.fine("Received override dimension %d", overrideDim);
}
public int getOverrideDimension(S01PacketJoinGame p_147282_1_) {
FMLLog.fine("Overriding dimension: using %d", this.overrideLoginDim);
return this.overrideLoginDim != 0 ? this.overrideLoginDim : p_147282_1_.func_149194_f();
}
}