Add support for 15w33c and multiple fallback servers
This commit is contained in:
parent
dfaa687f71
commit
12a7b7afc3
@ -27,7 +27,7 @@ public class MinecraftDecoder extends MessageToMessageDecoder<ByteBuf>
|
|||||||
{
|
{
|
||||||
int packetId = DefinedPacket.readVarInt( in );
|
int packetId = DefinedPacket.readVarInt( in );
|
||||||
|
|
||||||
DefinedPacket packet = prot.createPacket( packetId );
|
DefinedPacket packet = prot.createPacket( packetId, protocolVersion );
|
||||||
if ( packet != null )
|
if ( packet != null )
|
||||||
{
|
{
|
||||||
packet.read( in, prot.getDirection(), protocolVersion );
|
packet.read( in, prot.getDirection(), protocolVersion );
|
||||||
|
@ -20,7 +20,7 @@ public class MinecraftEncoder extends MessageToByteEncoder<DefinedPacket>
|
|||||||
protected void encode(ChannelHandlerContext ctx, DefinedPacket msg, ByteBuf out) throws Exception
|
protected void encode(ChannelHandlerContext ctx, DefinedPacket msg, ByteBuf out) throws Exception
|
||||||
{
|
{
|
||||||
Protocol.DirectionData prot = ( server ) ? protocol.TO_CLIENT : protocol.TO_SERVER;
|
Protocol.DirectionData prot = ( server ) ? protocol.TO_CLIENT : protocol.TO_SERVER;
|
||||||
DefinedPacket.writeVarInt( prot.getId( msg.getClass() ), out );
|
DefinedPacket.writeVarInt( prot.getId( msg.getClass(), protocolVersion ), out );
|
||||||
msg.write( out, prot.getDirection(), protocolVersion );
|
msg.write( out, prot.getDirection(), protocolVersion );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
package net.md_5.bungee.protocol;
|
package net.md_5.bungee.protocol;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
import gnu.trove.map.TIntIntMap;
|
||||||
|
import gnu.trove.map.TIntObjectMap;
|
||||||
import gnu.trove.map.TObjectIntMap;
|
import gnu.trove.map.TObjectIntMap;
|
||||||
|
import gnu.trove.map.hash.TIntIntHashMap;
|
||||||
|
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||||
import gnu.trove.map.hash.TObjectIntHashMap;
|
import gnu.trove.map.hash.TObjectIntHashMap;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -68,9 +72,9 @@ public enum Protocol
|
|||||||
|
|
||||||
TO_SERVER.registerPacket( 0x00, KeepAlive.class );
|
TO_SERVER.registerPacket( 0x00, KeepAlive.class );
|
||||||
TO_SERVER.registerPacket( 0x01, Chat.class );
|
TO_SERVER.registerPacket( 0x01, Chat.class );
|
||||||
TO_SERVER.registerPacket( 0x14, TabCompleteRequest.class );
|
TO_SERVER.registerPacket( 0x14, 0x15, TabCompleteRequest.class );
|
||||||
TO_SERVER.registerPacket( 0x15, ClientSettings.class );
|
TO_SERVER.registerPacket( 0x15, 0x16, ClientSettings.class );
|
||||||
TO_SERVER.registerPacket( 0x17, PluginMessage.class );
|
TO_SERVER.registerPacket( 0x17, 0x18, PluginMessage.class );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 1
|
// 1
|
||||||
@ -119,8 +123,27 @@ public enum Protocol
|
|||||||
private final Class<? extends DefinedPacket>[] packetClasses = new Class[ MAX_PACKET_ID ];
|
private final Class<? extends DefinedPacket>[] packetClasses = new Class[ MAX_PACKET_ID ];
|
||||||
private final Constructor<? extends DefinedPacket>[] packetConstructors = new Constructor[ MAX_PACKET_ID ];
|
private final Constructor<? extends DefinedPacket>[] packetConstructors = new Constructor[ MAX_PACKET_ID ];
|
||||||
|
|
||||||
public final DefinedPacket createPacket(int id)
|
private final TIntObjectMap<TIntIntMap> packetRemap = new TIntObjectHashMap<>();
|
||||||
|
private final TIntObjectMap<TIntIntMap> packetRemapInv = new TIntObjectHashMap<>();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
packetRemap.put( ProtocolConstants.MINECRAFT_1_8, new TIntIntHashMap() );
|
||||||
|
packetRemapInv.put( ProtocolConstants.MINECRAFT_1_8, new TIntIntHashMap() );
|
||||||
|
packetRemap.put( ProtocolConstants.MINECRAFT_SNAPSHOT, new TIntIntHashMap() );
|
||||||
|
packetRemapInv.put( ProtocolConstants.MINECRAFT_SNAPSHOT, new TIntIntHashMap() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public final DefinedPacket createPacket(int id, int protocol)
|
||||||
|
{
|
||||||
|
TIntIntMap remap = packetRemap.get( protocol );
|
||||||
|
if ( remap != null )
|
||||||
|
{
|
||||||
|
if ( !remap.containsKey( id ) )
|
||||||
|
{
|
||||||
|
throw new BadPacketException( "No packet with id " + id );
|
||||||
|
}
|
||||||
|
id = remap.get( id );
|
||||||
|
}
|
||||||
if ( id > MAX_PACKET_ID )
|
if ( id > MAX_PACKET_ID )
|
||||||
{
|
{
|
||||||
throw new BadPacketException( "Packet with id " + id + " outside of range " );
|
throw new BadPacketException( "Packet with id " + id + " outside of range " );
|
||||||
@ -137,6 +160,11 @@ public enum Protocol
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected final void registerPacket(int id, Class<? extends DefinedPacket> packetClass)
|
protected final void registerPacket(int id, Class<? extends DefinedPacket> packetClass)
|
||||||
|
{
|
||||||
|
registerPacket( id, id, packetClass );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final void registerPacket(int id, int newId, Class<? extends DefinedPacket> packetClass)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -147,6 +175,11 @@ public enum Protocol
|
|||||||
}
|
}
|
||||||
packetClasses[id] = packetClass;
|
packetClasses[id] = packetClass;
|
||||||
packetMap.put( packetClass, id );
|
packetMap.put( packetClass, id );
|
||||||
|
|
||||||
|
packetRemap.get( ProtocolConstants.MINECRAFT_1_8 ).put( id, id );
|
||||||
|
packetRemapInv.get( ProtocolConstants.MINECRAFT_1_8 ).put(id, id);
|
||||||
|
packetRemap.get( ProtocolConstants.MINECRAFT_SNAPSHOT ).put( newId, id );
|
||||||
|
packetRemapInv.get( ProtocolConstants.MINECRAFT_SNAPSHOT ).put( id, newId );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final void unregisterPacket(int id)
|
protected final void unregisterPacket(int id)
|
||||||
@ -156,11 +189,17 @@ public enum Protocol
|
|||||||
packetConstructors[id] = null;
|
packetConstructors[id] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int getId(Class<? extends DefinedPacket> packet)
|
final int getId(Class<? extends DefinedPacket> packet, int protocol)
|
||||||
{
|
{
|
||||||
Preconditions.checkArgument( packetMap.containsKey( packet ), "Cannot get ID for packet " + packet );
|
Preconditions.checkArgument(packetMap.containsKey(packet), "Cannot get ID for packet " + packet);
|
||||||
|
|
||||||
return packetMap.get( packet );
|
int id = packetMap.get( packet );
|
||||||
|
TIntIntMap remap = packetRemapInv.get( protocol );
|
||||||
|
if ( remap != null )
|
||||||
|
{
|
||||||
|
return remap.get( id );
|
||||||
|
}
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,16 @@
|
|||||||
package net.md_5.bungee.protocol;
|
package net.md_5.bungee.protocol;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class ProtocolConstants
|
public class ProtocolConstants
|
||||||
{
|
{
|
||||||
public static final int MINECRAFT_1_8 = 47;
|
public static final int MINECRAFT_1_8 = 47;
|
||||||
public static final int MINECRAFT_SNAPSHOT = 54;
|
public static final int MINECRAFT_SNAPSHOT = 57;
|
||||||
|
public static final List<String> SUPPORTED_VERSIONS = Arrays.asList(
|
||||||
|
"1.8.X",
|
||||||
|
"15w33c"
|
||||||
|
);
|
||||||
|
|
||||||
public enum Direction
|
public enum Direction
|
||||||
{
|
{
|
||||||
|
@ -18,19 +18,24 @@ public class ClientSettings extends DefinedPacket
|
|||||||
|
|
||||||
private String locale;
|
private String locale;
|
||||||
private byte viewDistance;
|
private byte viewDistance;
|
||||||
private byte chatFlags;
|
private int chatFlags;
|
||||||
private boolean chatColours;
|
private boolean chatColours;
|
||||||
private byte difficulty;
|
private byte difficulty;
|
||||||
private byte skinParts;
|
private byte skinParts;
|
||||||
|
private int mainHand;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
|
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
|
||||||
{
|
{
|
||||||
locale = readString( buf );
|
locale = readString( buf );
|
||||||
viewDistance = buf.readByte();
|
viewDistance = buf.readByte();
|
||||||
chatFlags = buf.readByte();
|
chatFlags = protocolVersion >= ProtocolConstants.MINECRAFT_SNAPSHOT ? DefinedPacket.readVarInt( buf ) : buf.readUnsignedByte();
|
||||||
chatColours = buf.readBoolean();
|
chatColours = buf.readBoolean();
|
||||||
skinParts = buf.readByte();
|
skinParts = buf.readByte();
|
||||||
|
if ( protocolVersion >= ProtocolConstants.MINECRAFT_SNAPSHOT )
|
||||||
|
{
|
||||||
|
mainHand = DefinedPacket.readVarInt( buf );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -38,9 +43,19 @@ public class ClientSettings extends DefinedPacket
|
|||||||
{
|
{
|
||||||
writeString( locale, buf );
|
writeString( locale, buf );
|
||||||
buf.writeByte( viewDistance );
|
buf.writeByte( viewDistance );
|
||||||
buf.writeByte( chatFlags );
|
if ( protocolVersion >= ProtocolConstants.MINECRAFT_SNAPSHOT )
|
||||||
|
{
|
||||||
|
DefinedPacket.writeVarInt( chatFlags, buf );
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
buf.writeByte( chatFlags );
|
||||||
|
}
|
||||||
buf.writeBoolean( chatColours );
|
buf.writeBoolean( chatColours );
|
||||||
buf.writeByte( skinParts );
|
buf.writeByte( skinParts );
|
||||||
|
if ( protocolVersion >= ProtocolConstants.MINECRAFT_SNAPSHOT )
|
||||||
|
{
|
||||||
|
DefinedPacket.writeVarInt(mainHand, buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.md_5.bungee;
|
package net.md_5.bungee;
|
||||||
|
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
@ -575,7 +576,7 @@ public class BungeeCord extends ProxyServer
|
|||||||
@Override
|
@Override
|
||||||
public String getGameVersion()
|
public String getGameVersion()
|
||||||
{
|
{
|
||||||
return "1.8";
|
return Joiner.on(", ").join(ProtocolConstants.SUPPORTED_VERSIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -4,6 +4,8 @@ import com.google.common.base.Objects;
|
|||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufAllocator;
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@ -255,12 +257,24 @@ public class ServerConnector extends PacketHandler
|
|||||||
@Override
|
@Override
|
||||||
public void handle(Kick kick) throws Exception
|
public void handle(Kick kick) throws Exception
|
||||||
{
|
{
|
||||||
ServerInfo def = bungee.getServerInfo( user.getPendingConnection().getListener().getFallbackServer() );
|
user.setLastServerJoined(user.getLastServerJoined() + 1);
|
||||||
|
String serverName = "";
|
||||||
|
List<String> servers = user.getPendingConnection().getListener().getServerPriority();
|
||||||
|
if ( user.getLastServerJoined() < servers.size() ) {
|
||||||
|
serverName = servers.get( user.getLastServerJoined() );
|
||||||
|
}
|
||||||
|
ServerInfo def = ProxyServer.getInstance().getServers().get( serverName );
|
||||||
if ( Objects.equal( target, def ) )
|
if ( Objects.equal( target, def ) )
|
||||||
{
|
{
|
||||||
def = null;
|
def = null;
|
||||||
}
|
}
|
||||||
ServerKickEvent event = bungee.getPluginManager().callEvent( new ServerKickEvent( user, target, ComponentSerializer.parse( kick.getMessage() ), def, ServerKickEvent.State.CONNECTING ) );
|
ServerKickEvent event = new ServerKickEvent(user, target, ComponentSerializer.parse(kick.getMessage()), def, ServerKickEvent.State.CONNECTING);
|
||||||
|
if ( event.getKickReason().toLowerCase().contains( "outdated" ) && def != null )
|
||||||
|
{
|
||||||
|
// Pre cancel the event if we are going to try another server
|
||||||
|
event.setCancelled( true );
|
||||||
|
}
|
||||||
|
bungee.getPluginManager().callEvent( event );
|
||||||
if ( event.isCancelled() && event.getCancelServer() != null )
|
if ( event.isCancelled() && event.getCancelServer() != null )
|
||||||
{
|
{
|
||||||
user.connect( event.getCancelServer() );
|
user.connect( event.getCancelServer() );
|
||||||
@ -314,11 +328,6 @@ public class ServerConnector extends PacketHandler
|
|||||||
if ( pluginMessage.getTag().equals( ForgeConstants.FML_HANDSHAKE_TAG ) || pluginMessage.getTag().equals( ForgeConstants.FORGE_REGISTER ) )
|
if ( pluginMessage.getTag().equals( ForgeConstants.FML_HANDSHAKE_TAG ) || pluginMessage.getTag().equals( ForgeConstants.FORGE_REGISTER ) )
|
||||||
{
|
{
|
||||||
this.handshakeHandler.handle( pluginMessage );
|
this.handshakeHandler.handle( pluginMessage );
|
||||||
if ( user.getForgeClientHandler().checkUserOutdated() )
|
|
||||||
{
|
|
||||||
ch.close();
|
|
||||||
user.getPendingConnects().remove( target );
|
|
||||||
}
|
|
||||||
|
|
||||||
// We send the message as part of the handler, so don't send it here.
|
// We send the message as part of the handler, so don't send it here.
|
||||||
throw CancelSendSignal.INSTANCE;
|
throw CancelSendSignal.INSTANCE;
|
||||||
|
@ -14,6 +14,7 @@ import java.net.InetSocketAddress;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -55,6 +56,8 @@ import net.md_5.bungee.protocol.packet.Kick;
|
|||||||
import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter;
|
import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter;
|
||||||
import net.md_5.bungee.protocol.packet.PluginMessage;
|
import net.md_5.bungee.protocol.packet.PluginMessage;
|
||||||
import net.md_5.bungee.protocol.packet.SetCompression;
|
import net.md_5.bungee.protocol.packet.SetCompression;
|
||||||
|
import net.md_5.bungee.tab.Global;
|
||||||
|
import net.md_5.bungee.tab.GlobalPing;
|
||||||
import net.md_5.bungee.tab.ServerUnique;
|
import net.md_5.bungee.tab.ServerUnique;
|
||||||
import net.md_5.bungee.tab.TabList;
|
import net.md_5.bungee.tab.TabList;
|
||||||
import net.md_5.bungee.util.CaseInsensitiveSet;
|
import net.md_5.bungee.util.CaseInsensitiveSet;
|
||||||
@ -102,6 +105,10 @@ public final class UserConnection implements ProxiedPlayer
|
|||||||
private int gamemode;
|
private int gamemode;
|
||||||
@Getter
|
@Getter
|
||||||
private int compressionThreshold = -1;
|
private int compressionThreshold = -1;
|
||||||
|
// Used for trying multiple servers in order
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private int lastServerJoined = 0;
|
||||||
/*========================================================================*/
|
/*========================================================================*/
|
||||||
private final Collection<String> groups = new CaseInsensitiveSet();
|
private final Collection<String> groups = new CaseInsensitiveSet();
|
||||||
private final Collection<String> permissions = new CaseInsensitiveSet();
|
private final Collection<String> permissions = new CaseInsensitiveSet();
|
||||||
@ -145,20 +152,18 @@ public final class UserConnection implements ProxiedPlayer
|
|||||||
|
|
||||||
this.displayName = name;
|
this.displayName = name;
|
||||||
|
|
||||||
// Blame Mojang for this one
|
switch ( getPendingConnection().getListener().getTabListType() )
|
||||||
/*switch ( getPendingConnection().getListener().getTabListType() )
|
{
|
||||||
{
|
case "GLOBAL":
|
||||||
case "GLOBAL":
|
tabListHandler = new Global( this );
|
||||||
tabListHandler = new Global( this );
|
break;
|
||||||
break;
|
case "SERVER":
|
||||||
case "SERVER":
|
tabListHandler = new ServerUnique( this );
|
||||||
tabListHandler = new ServerUnique( this );
|
break;
|
||||||
break;
|
default:
|
||||||
default:
|
tabListHandler = new GlobalPing( this );
|
||||||
tabListHandler = new GlobalPing( this );
|
break;
|
||||||
break;
|
}
|
||||||
}*/
|
|
||||||
tabListHandler = new ServerUnique( this );
|
|
||||||
|
|
||||||
Collection<String> g = bungee.getConfigurationAdapter().getGroups( name );
|
Collection<String> g = bungee.getConfigurationAdapter().getGroups( name );
|
||||||
g.addAll( bungee.getConfigurationAdapter().getGroups( getUniqueId().toString() ) );
|
g.addAll( bungee.getConfigurationAdapter().getGroups( getUniqueId().toString() ) );
|
||||||
@ -187,7 +192,7 @@ public final class UserConnection implements ProxiedPlayer
|
|||||||
@Override
|
@Override
|
||||||
public void setDisplayName(String name)
|
public void setDisplayName(String name)
|
||||||
{
|
{
|
||||||
Preconditions.checkNotNull( name, "displayName" );
|
Preconditions.checkNotNull(name, "displayName");
|
||||||
Preconditions.checkArgument( name.length() <= 16, "Display name cannot be longer than 16 characters" );
|
Preconditions.checkArgument( name.length() <= 16, "Display name cannot be longer than 16 characters" );
|
||||||
displayName = name;
|
displayName = name;
|
||||||
}
|
}
|
||||||
@ -267,9 +272,16 @@ public final class UserConnection implements ProxiedPlayer
|
|||||||
if ( !future.isSuccess() )
|
if ( !future.isSuccess() )
|
||||||
{
|
{
|
||||||
future.channel().close();
|
future.channel().close();
|
||||||
pendingConnects.remove( target );
|
pendingConnects.remove(target);
|
||||||
|
|
||||||
ServerInfo def = ProxyServer.getInstance().getServers().get( getPendingConnection().getListener().getFallbackServer() );
|
lastServerJoined++;
|
||||||
|
String serverName = "";
|
||||||
|
List<String> servers = getPendingConnection().getListener().getServerPriority();
|
||||||
|
if ( lastServerJoined < servers.size() ) {
|
||||||
|
serverName = servers.get( lastServerJoined );
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerInfo def = ProxyServer.getInstance().getServers().get( serverName );
|
||||||
if ( retry && target != def && ( getServer() == null || def != getServer().getInfo() ) )
|
if ( retry && target != def && ( getServer() == null || def != getServer().getInfo() ) )
|
||||||
{
|
{
|
||||||
sendMessage( bungee.getTranslation( "fallback_lobby" ) );
|
sendMessage( bungee.getTranslation( "fallback_lobby" ) );
|
||||||
@ -281,6 +293,8 @@ public final class UserConnection implements ProxiedPlayer
|
|||||||
{
|
{
|
||||||
sendMessage( bungee.getTranslation( "fallback_kick", future.cause().getClass().getName() ) );
|
sendMessage( bungee.getTranslation( "fallback_kick", future.cause().getClass().getName() ) );
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
lastServerJoined = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -27,6 +27,8 @@ public abstract class EntityMap
|
|||||||
{
|
{
|
||||||
case ProtocolConstants.MINECRAFT_1_8:
|
case ProtocolConstants.MINECRAFT_1_8:
|
||||||
return EntityMap_1_8.INSTANCE;
|
return EntityMap_1_8.INSTANCE;
|
||||||
|
case ProtocolConstants.MINECRAFT_SNAPSHOT:
|
||||||
|
return EntityMap_1_SNAPSHOT.INSTANCE;
|
||||||
}
|
}
|
||||||
throw new RuntimeException( "Version " + version + " has no entity map" );
|
throw new RuntimeException( "Version " + version + " has no entity map" );
|
||||||
}
|
}
|
||||||
|
@ -97,28 +97,12 @@ class EntityMap_1_8 extends EntityMap
|
|||||||
packet.skipBytes( 14 );
|
packet.skipBytes( 14 );
|
||||||
int position = packet.readerIndex();
|
int position = packet.readerIndex();
|
||||||
int readId = packet.readInt();
|
int readId = packet.readInt();
|
||||||
int changedId = -1;
|
|
||||||
if ( readId == oldId )
|
if ( readId == oldId )
|
||||||
{
|
{
|
||||||
packet.setInt( position, newId );
|
packet.setInt( position, newId );
|
||||||
changedId = newId;
|
|
||||||
} else if ( readId == newId )
|
} else if ( readId == newId )
|
||||||
{
|
{
|
||||||
packet.setInt( position, oldId );
|
packet.setInt( position, oldId );
|
||||||
changedId = oldId;
|
|
||||||
}
|
|
||||||
if ( changedId != -1 )
|
|
||||||
{
|
|
||||||
if ( changedId == 0 && readId != 0 )
|
|
||||||
{ // Trim off the extra data
|
|
||||||
packet.readerIndex( readerIndex );
|
|
||||||
packet.writerIndex( packet.readableBytes() - 6 );
|
|
||||||
} else if ( changedId != 0 && readId == 0 )
|
|
||||||
{ // Add on the extra data
|
|
||||||
packet.readerIndex( readerIndex );
|
|
||||||
packet.capacity( packet.readableBytes() + 6 );
|
|
||||||
packet.writerIndex( packet.readableBytes() + 6 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ( packetId == 0x0C /* Spawn Player */ )
|
} else if ( packetId == 0x0C /* Spawn Player */ )
|
||||||
|
@ -0,0 +1,181 @@
|
|||||||
|
package net.md_5.bungee.entitymap;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import net.md_5.bungee.BungeeCord;
|
||||||
|
import net.md_5.bungee.UserConnection;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
import net.md_5.bungee.protocol.DefinedPacket;
|
||||||
|
import net.md_5.bungee.protocol.ProtocolConstants;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
class EntityMap_SNAPSHOT extends EntityMap
|
||||||
|
{
|
||||||
|
static final EntityMap_SNAPSHOT INSTANCE = new EntityMap_SNAPSHOT();
|
||||||
|
|
||||||
|
EntityMap_SNAPSHOT()
|
||||||
|
{
|
||||||
|
addRewrite( 0x04, ProtocolConstants.Direction.TO_CLIENT, true ); // Entity Equipment
|
||||||
|
addRewrite( 0x0A, ProtocolConstants.Direction.TO_CLIENT, true ); // Use bed
|
||||||
|
addRewrite( 0x0B, ProtocolConstants.Direction.TO_CLIENT, true ); // Animation
|
||||||
|
addRewrite( 0x0C, ProtocolConstants.Direction.TO_CLIENT, true ); // Spawn Player
|
||||||
|
addRewrite( 0x0D, ProtocolConstants.Direction.TO_CLIENT, true ); // Collect Item
|
||||||
|
addRewrite( 0x0E, ProtocolConstants.Direction.TO_CLIENT, true ); // Spawn Object
|
||||||
|
addRewrite( 0x0F, ProtocolConstants.Direction.TO_CLIENT, true ); // Spawn Mob
|
||||||
|
addRewrite( 0x10, ProtocolConstants.Direction.TO_CLIENT, true ); // Spawn Painting
|
||||||
|
addRewrite( 0x11, ProtocolConstants.Direction.TO_CLIENT, true ); // Spawn Experience Orb
|
||||||
|
addRewrite( 0x12, ProtocolConstants.Direction.TO_CLIENT, true ); // Entity Velocity
|
||||||
|
addRewrite( 0x14, ProtocolConstants.Direction.TO_CLIENT, true ); // Entity
|
||||||
|
addRewrite( 0x15, ProtocolConstants.Direction.TO_CLIENT, true ); // Entity Relative Move
|
||||||
|
addRewrite( 0x16, ProtocolConstants.Direction.TO_CLIENT, true ); // Entity Look
|
||||||
|
addRewrite( 0x17, ProtocolConstants.Direction.TO_CLIENT, true ); // Entity Look and Relative Move
|
||||||
|
addRewrite( 0x18, ProtocolConstants.Direction.TO_CLIENT, true ); // Entity Teleport
|
||||||
|
addRewrite( 0x19, ProtocolConstants.Direction.TO_CLIENT, true ); // Entity Head Look
|
||||||
|
addRewrite( 0x1A, ProtocolConstants.Direction.TO_CLIENT, false ); // Entity Status
|
||||||
|
addRewrite( 0x1B, ProtocolConstants.Direction.TO_CLIENT, false ); // Attach Entity
|
||||||
|
addRewrite( 0x1C, ProtocolConstants.Direction.TO_CLIENT, true ); // Entity Metadata
|
||||||
|
addRewrite( 0x1D, ProtocolConstants.Direction.TO_CLIENT, true ); // Entity Effect
|
||||||
|
addRewrite( 0x1E, ProtocolConstants.Direction.TO_CLIENT, true ); // Remove Entity Effect
|
||||||
|
addRewrite( 0x20, ProtocolConstants.Direction.TO_CLIENT, true ); // Entity Properties
|
||||||
|
addRewrite( 0x25, ProtocolConstants.Direction.TO_CLIENT, true ); // Block Break Animation
|
||||||
|
addRewrite( 0x2C, ProtocolConstants.Direction.TO_CLIENT, true ); // Spawn Global Entity
|
||||||
|
addRewrite( 0x43, ProtocolConstants.Direction.TO_CLIENT, true ); // Camera
|
||||||
|
addRewrite( 0x49, ProtocolConstants.Direction.TO_CLIENT, true ); // Update Entity NBT
|
||||||
|
|
||||||
|
addRewrite( 0x02, ProtocolConstants.Direction.TO_SERVER, true ); // Use Entity
|
||||||
|
addRewrite( 0x0C, ProtocolConstants.Direction.TO_SERVER, true ); // Entity Action
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressFBWarnings("DLS_DEAD_LOCAL_STORE")
|
||||||
|
public void rewriteClientbound(ByteBuf packet, int oldId, int newId)
|
||||||
|
{
|
||||||
|
super.rewriteClientbound( packet, oldId, newId );
|
||||||
|
|
||||||
|
//Special cases
|
||||||
|
int readerIndex = packet.readerIndex();
|
||||||
|
int packetId = DefinedPacket.readVarInt( packet );
|
||||||
|
int packetIdLength = packet.readerIndex() - readerIndex;
|
||||||
|
if ( packetId == 0x0D /* Collect Item */ )
|
||||||
|
{
|
||||||
|
DefinedPacket.readVarInt( packet );
|
||||||
|
rewriteVarInt( packet, oldId, newId, packet.readerIndex() );
|
||||||
|
} else if ( packetId == 0x1B /* Attach Entity */ )
|
||||||
|
{
|
||||||
|
rewriteInt( packet, oldId, newId, readerIndex + packetIdLength + 4 );
|
||||||
|
} else if ( packetId == 0x13 /* Destroy Entities */ )
|
||||||
|
{
|
||||||
|
int count = DefinedPacket.readVarInt( packet );
|
||||||
|
int[] ids = new int[ count ];
|
||||||
|
for ( int i = 0; i < count; i++ )
|
||||||
|
{
|
||||||
|
ids[ i ] = DefinedPacket.readVarInt( packet );
|
||||||
|
}
|
||||||
|
packet.readerIndex( readerIndex + packetIdLength );
|
||||||
|
packet.writerIndex( readerIndex + packetIdLength );
|
||||||
|
DefinedPacket.writeVarInt( count, packet );
|
||||||
|
for ( int id : ids )
|
||||||
|
{
|
||||||
|
if ( id == oldId )
|
||||||
|
{
|
||||||
|
id = newId;
|
||||||
|
} else if ( id == newId )
|
||||||
|
{
|
||||||
|
id = oldId;
|
||||||
|
}
|
||||||
|
DefinedPacket.writeVarInt( id, packet );
|
||||||
|
}
|
||||||
|
} else if ( packetId == 0x0E /* Spawn Object */ )
|
||||||
|
{
|
||||||
|
|
||||||
|
DefinedPacket.readVarInt( packet );
|
||||||
|
int type = packet.readUnsignedByte();
|
||||||
|
|
||||||
|
if ( type == 60 || type == 90 )
|
||||||
|
{
|
||||||
|
packet.skipBytes( 14 );
|
||||||
|
int position = packet.readerIndex();
|
||||||
|
int readId = packet.readInt();
|
||||||
|
int changedId = -1;
|
||||||
|
if ( readId == oldId )
|
||||||
|
{
|
||||||
|
packet.setInt( position, newId );
|
||||||
|
changedId = newId;
|
||||||
|
} else if ( readId == newId )
|
||||||
|
{
|
||||||
|
packet.setInt( position, oldId );
|
||||||
|
changedId = oldId;
|
||||||
|
}
|
||||||
|
if ( changedId != -1 )
|
||||||
|
{
|
||||||
|
if ( changedId == 0 && readId != 0 )
|
||||||
|
{ // Trim off the extra data
|
||||||
|
packet.readerIndex( readerIndex );
|
||||||
|
packet.writerIndex( packet.readableBytes() - 6 );
|
||||||
|
} else if ( changedId != 0 && readId == 0 )
|
||||||
|
{ // Add on the extra data
|
||||||
|
packet.readerIndex( readerIndex );
|
||||||
|
packet.capacity( packet.readableBytes() + 6 );
|
||||||
|
packet.writerIndex( packet.readableBytes() + 6 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ( packetId == 0x0C /* Spawn Player */ )
|
||||||
|
{
|
||||||
|
DefinedPacket.readVarInt( packet ); // Entity ID
|
||||||
|
int idLength = packet.readerIndex() - readerIndex - packetIdLength;
|
||||||
|
UUID uuid = DefinedPacket.readUUID( packet );
|
||||||
|
ProxiedPlayer player;
|
||||||
|
if ( ( player = BungeeCord.getInstance().getPlayerByOfflineUUID( uuid ) ) != null )
|
||||||
|
{
|
||||||
|
int previous = packet.writerIndex();
|
||||||
|
packet.readerIndex( readerIndex );
|
||||||
|
packet.writerIndex( readerIndex + packetIdLength + idLength );
|
||||||
|
DefinedPacket.writeUUID( player.getUniqueId(), packet );
|
||||||
|
packet.writerIndex( previous );
|
||||||
|
}
|
||||||
|
} else if ( packetId == 0x42 /* Combat Event */ )
|
||||||
|
{
|
||||||
|
int event = packet.readUnsignedByte();
|
||||||
|
if ( event == 1 /* End Combat*/ )
|
||||||
|
{
|
||||||
|
DefinedPacket.readVarInt( packet );
|
||||||
|
rewriteInt( packet, oldId, newId, packet.readerIndex() );
|
||||||
|
} else if ( event == 2 /* Entity Dead */ )
|
||||||
|
{
|
||||||
|
int position = packet.readerIndex();
|
||||||
|
rewriteVarInt( packet, oldId, newId, packet.readerIndex() );
|
||||||
|
packet.readerIndex( position );
|
||||||
|
DefinedPacket.readVarInt( packet );
|
||||||
|
rewriteInt( packet, oldId, newId, packet.readerIndex() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
packet.readerIndex( readerIndex );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void rewriteServerbound(ByteBuf packet, int oldId, int newId)
|
||||||
|
{
|
||||||
|
super.rewriteServerbound( packet, oldId, newId );
|
||||||
|
//Special cases
|
||||||
|
int readerIndex = packet.readerIndex();
|
||||||
|
int packetId = DefinedPacket.readVarInt( packet );
|
||||||
|
int packetIdLength = packet.readerIndex() - readerIndex;
|
||||||
|
|
||||||
|
if ( packetId == 0x19 /* Spectate */ && !BungeeCord.getInstance().getConfig().isIpForward() )
|
||||||
|
{
|
||||||
|
UUID uuid = DefinedPacket.readUUID( packet );
|
||||||
|
ProxiedPlayer player;
|
||||||
|
if ( ( player = BungeeCord.getInstance().getPlayer( uuid ) ) != null )
|
||||||
|
{
|
||||||
|
int previous = packet.writerIndex();
|
||||||
|
packet.readerIndex( readerIndex );
|
||||||
|
packet.writerIndex( readerIndex + packetIdLength );
|
||||||
|
DefinedPacket.writeUUID( ( (UserConnection) player ).getPendingConnection().getOfflineId(), packet );
|
||||||
|
packet.writerIndex( previous );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
packet.readerIndex( readerIndex );
|
||||||
|
}
|
||||||
|
}
|
@ -21,10 +21,6 @@ public class ForgeClientHandler
|
|||||||
@NonNull
|
@NonNull
|
||||||
private final UserConnection con;
|
private final UserConnection con;
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter(AccessLevel.PACKAGE)
|
|
||||||
private boolean forgeOutdated = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The users' mod list.
|
* The users' mod list.
|
||||||
*/
|
*/
|
||||||
@ -160,28 +156,4 @@ public class ForgeClientHandler
|
|||||||
{
|
{
|
||||||
return fmlTokenInHandshake || clientModList != null;
|
return fmlTokenInHandshake || clientModList != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks to see if a user is using an outdated FML build, and takes
|
|
||||||
* appropriate action on the User side. This should only be called during a
|
|
||||||
* server connection, by the ServerConnector
|
|
||||||
*
|
|
||||||
* @return <code>true</code> if the user's FML build is outdated, otherwise
|
|
||||||
* <code>false</code>
|
|
||||||
*/
|
|
||||||
public boolean checkUserOutdated()
|
|
||||||
{
|
|
||||||
if ( forgeOutdated )
|
|
||||||
{
|
|
||||||
if ( con.isDimensionChange() )
|
|
||||||
{
|
|
||||||
con.disconnect( BungeeCord.getInstance().getTranslation( "connect_kick_outdated_forge" ) );
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
con.sendMessage( BungeeCord.getInstance().getTranslation( "connect_kick_outdated_forge" ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return forgeOutdated;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -86,17 +86,6 @@ enum ForgeClientHandshakeState implements IForgeClientPacketHandler<ForgeClientH
|
|||||||
// Once we've done it, no point doing it again.
|
// Once we've done it, no point doing it again.
|
||||||
Map<String, String> clientModList = ForgeUtils.readModList( message );
|
Map<String, String> clientModList = ForgeUtils.readModList( message );
|
||||||
con.getForgeClientHandler().setClientModList( clientModList );
|
con.getForgeClientHandler().setClientModList( clientModList );
|
||||||
|
|
||||||
// Get the version from the mod list.
|
|
||||||
int buildNumber = ForgeUtils.getFmlBuildNumber( clientModList );
|
|
||||||
|
|
||||||
// If we get 0, we're probably using a testing build, so let it though. Otherwise, check the build number.
|
|
||||||
if ( buildNumber < ForgeConstants.FML_MIN_BUILD_VERSION && buildNumber != 0 )
|
|
||||||
{
|
|
||||||
// Mark the user as an old Forge user. This will then cause any Forge ServerConnectors to cancel any
|
|
||||||
// connections to it.
|
|
||||||
con.getForgeClientHandler().setForgeOutdated( true );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return WAITINGSERVERDATA;
|
return WAITINGSERVERDATA;
|
||||||
|
Loading…
Reference in New Issue
Block a user