Compare commits

..

8 Commits

Author SHA1 Message Date
dc1b540470
new event TabCompleteRequestEvent and deprecate TabCompleteEvent 2022-12-08 16:25:35 +01:00
d4af112fdd
Add CommandsDeclareEvent to declare commands with brigadier API 2022-12-08 16:25:35 +01:00
a09a19a9f0
Server branding now includes the backend server name 2022-12-08 16:25:35 +01:00
3e5b1b2aa1
Multi-session with same Minecraft account with specific permission
Players with permission bungeecord.multiple_connect can have multiple connections with the same Minecraft account.
The UUID and player name is altered to avoid collision with other player:
UUID : xxxxxxxx-xxxx-VIxx-xxxx-xxxxxxxxxxxx
- The UUID version (V above) is now the provided version + 8 (for online player, it is 4, so it becomes C).
- The I digit will follow the index of the duplicated player : first duplicated player is 1, second one is 2.
- The name of the player will be the real player name, followed by the character "." (dot) followed by the duplication index.

Bedrock accounts connected using the Floodgate plugin will not be able to connect multiple times due to the risk of xUID collision.
2022-12-08 16:25:35 +01:00
cd62426fe8
Change projet configuration and POM for Pandacube 2022-12-08 16:25:35 +01:00
31dea191c9
Remove modules and startup delay
We don’t need them for Pandacube
2022-12-08 16:25:35 +01:00
md_5
e71767688d
#3408: ConcurrentModificationException when player quits 2022-12-08 07:09:20 +11:00
md_5
5467e3a842
Minecraft 1.19.3 support 2022-12-08 03:00:00 +11:00
23 changed files with 712 additions and 90 deletions

View File

@ -21,7 +21,7 @@
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version>
<version>2.10</version>
<scope>compile</scope>
</dependency>
</dependencies>

View File

@ -21,7 +21,7 @@
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version>
<version>2.10</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>

View File

@ -88,7 +88,7 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
<version>31.1-jre</version>
<scope>compile</scope>
</dependency>
<dependency>

View File

@ -25,6 +25,8 @@ import net.md_5.bungee.protocol.packet.LoginSuccess;
import net.md_5.bungee.protocol.packet.PingPacket;
import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter;
import net.md_5.bungee.protocol.packet.PlayerListItem;
import net.md_5.bungee.protocol.packet.PlayerListItemRemove;
import net.md_5.bungee.protocol.packet.PlayerListItemUpdate;
import net.md_5.bungee.protocol.packet.PluginMessage;
import net.md_5.bungee.protocol.packet.Respawn;
import net.md_5.bungee.protocol.packet.ScoreboardDisplay;
@ -114,6 +116,14 @@ public abstract class AbstractPacketHandler
{
}
public void handle(PlayerListItemRemove playerListItem) throws Exception
{
}
public void handle(PlayerListItemUpdate playerListItem) throws Exception
{
}
public void handle(PlayerListHeaderFooter playerListHeaderFooter) throws Exception
{
}

View File

@ -9,6 +9,9 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.EnumSet;
import java.util.List;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
@ -308,6 +311,53 @@ public abstract class DefinedPacket
}
}
public static <E extends Enum<E>> void writeEnumSet(EnumSet<E> enumset, Class<E> oclass, ByteBuf buf)
{
E[] enums = oclass.getEnumConstants();
BitSet bits = new BitSet( enums.length );
for ( int i = 0; i < enums.length; ++i )
{
bits.set( i, enumset.contains( enums[i] ) );
}
writeFixedBitSet( bits, enums.length, buf );
}
public static <E extends Enum<E>> EnumSet<E> readEnumSet(Class<E> oclass, ByteBuf buf)
{
E[] enums = oclass.getEnumConstants();
BitSet bits = readFixedBitSet( enums.length, buf );
EnumSet<E> set = EnumSet.noneOf( oclass );
for ( int i = 0; i < enums.length; ++i )
{
if ( bits.get( i ) )
{
set.add( enums[i] );
}
}
return set;
}
public static BitSet readFixedBitSet(int i, ByteBuf buf)
{
byte[] bits = new byte[ ( i + 8 ) >> 3 ];
buf.readBytes( bits );
return BitSet.valueOf( bits );
}
public static void writeFixedBitSet(BitSet bits, int size, ByteBuf buf)
{
if ( bits.length() > size )
{
throw new OverflowPacketException( "BitSet too large (expected " + size + " got " + bits.size() + ")" );
}
buf.writeBytes( Arrays.copyOf( bits.toByteArray(), ( size + 8 ) >> 3 ) );
}
public void read(ByteBuf buf)
{
throw new UnsupportedOperationException( "Packet must implement read method" );

View File

@ -31,6 +31,8 @@ import net.md_5.bungee.protocol.packet.LoginSuccess;
import net.md_5.bungee.protocol.packet.PingPacket;
import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter;
import net.md_5.bungee.protocol.packet.PlayerListItem;
import net.md_5.bungee.protocol.packet.PlayerListItemRemove;
import net.md_5.bungee.protocol.packet.PlayerListItemUpdate;
import net.md_5.bungee.protocol.packet.PluginMessage;
import net.md_5.bungee.protocol.packet.Respawn;
import net.md_5.bungee.protocol.packet.ScoreboardDisplay;
@ -81,7 +83,8 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_16_2, 0x1F ),
map( ProtocolConstants.MINECRAFT_1_17, 0x21 ),
map( ProtocolConstants.MINECRAFT_1_19, 0x1E ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x20 )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x20 ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x1F )
);
TO_CLIENT.registerPacket(
Login.class,
@ -94,7 +97,8 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_16_2, 0x24 ),
map( ProtocolConstants.MINECRAFT_1_17, 0x26 ),
map( ProtocolConstants.MINECRAFT_1_19, 0x23 ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x25 )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x25 ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x24 )
);
TO_CLIENT.registerPacket( Chat.class,
Chat::new,
@ -120,7 +124,8 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_16_2, 0x39 ),
map( ProtocolConstants.MINECRAFT_1_17, 0x3D ),
map( ProtocolConstants.MINECRAFT_1_19, 0x3B ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x3E )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x3E ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x3D )
);
TO_CLIENT.registerPacket(
BossBar.class,
@ -144,7 +149,8 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_16_2, 0x32 ),
map( ProtocolConstants.MINECRAFT_1_17, 0x36 ),
map( ProtocolConstants.MINECRAFT_1_19, 0x34 ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x37 )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x37 ),
map( ProtocolConstants.MINECRAFT_1_19_3, -1 )
);
TO_CLIENT.registerPacket(
TabCompleteResponse.class,
@ -156,7 +162,8 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_16, 0x10 ),
map( ProtocolConstants.MINECRAFT_1_16_2, 0x0F ),
map( ProtocolConstants.MINECRAFT_1_17, 0x11 ),
map( ProtocolConstants.MINECRAFT_1_19, 0x0E )
map( ProtocolConstants.MINECRAFT_1_19, 0x0E ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x0D )
);
TO_CLIENT.registerPacket(
ScoreboardObjective.class,
@ -169,7 +176,8 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_14, 0x49 ),
map( ProtocolConstants.MINECRAFT_1_15, 0x4A ),
map( ProtocolConstants.MINECRAFT_1_17, 0x53 ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x56 )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x56 ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x54 )
);
TO_CLIENT.registerPacket(
ScoreboardScore.class,
@ -182,7 +190,8 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_14, 0x4C ),
map( ProtocolConstants.MINECRAFT_1_15, 0x4D ),
map( ProtocolConstants.MINECRAFT_1_17, 0x56 ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x59 )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x59 ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x57 )
);
TO_CLIENT.registerPacket(
ScoreboardDisplay.class,
@ -195,7 +204,8 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_14, 0x42 ),
map( ProtocolConstants.MINECRAFT_1_15, 0x43 ),
map( ProtocolConstants.MINECRAFT_1_17, 0x4C ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x4F )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x4F ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x4D )
);
TO_CLIENT.registerPacket(
Team.class,
@ -208,7 +218,8 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_14, 0x4B ),
map( ProtocolConstants.MINECRAFT_1_15, 0x4C ),
map( ProtocolConstants.MINECRAFT_1_17, 0x55 ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x58 )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x58 ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x56 )
);
TO_CLIENT.registerPacket(
PluginMessage.class,
@ -222,7 +233,8 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_16_2, 0x17 ),
map( ProtocolConstants.MINECRAFT_1_17, 0x18 ),
map( ProtocolConstants.MINECRAFT_1_19, 0x15 ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x16 )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x16 ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x15 )
);
TO_CLIENT.registerPacket(
Kick.class,
@ -236,7 +248,8 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_16_2, 0x19 ),
map( ProtocolConstants.MINECRAFT_1_17, 0x1A ),
map( ProtocolConstants.MINECRAFT_1_19, 0x17 ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x19 )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x19 ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x17 )
);
TO_CLIENT.registerPacket(
Title.class,
@ -250,33 +263,38 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_16, 0x4F ),
map( ProtocolConstants.MINECRAFT_1_17, 0x59 ),
map( ProtocolConstants.MINECRAFT_1_18, 0x5A ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x5D )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x5D ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x5B )
);
TO_CLIENT.registerPacket(
ClearTitles.class,
ClearTitles::new,
map( ProtocolConstants.MINECRAFT_1_17, 0x10 ),
map( ProtocolConstants.MINECRAFT_1_19, 0x0D )
map( ProtocolConstants.MINECRAFT_1_19, 0x0D ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x0C )
);
TO_CLIENT.registerPacket(
Subtitle.class,
Subtitle::new,
map( ProtocolConstants.MINECRAFT_1_17, 0x57 ),
map( ProtocolConstants.MINECRAFT_1_18, 0x58 ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x5B )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x5B ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x59 )
);
TO_CLIENT.registerPacket(
TitleTimes.class,
TitleTimes::new,
map( ProtocolConstants.MINECRAFT_1_17, 0x5A ),
map( ProtocolConstants.MINECRAFT_1_18, 0x5B ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x5E )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x5E ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x5C )
);
TO_CLIENT.registerPacket(
SystemChat.class,
SystemChat::new,
map( ProtocolConstants.MINECRAFT_1_19, 0x5F ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x62 )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x62 ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x60 )
);
TO_CLIENT.registerPacket(
PlayerListHeaderFooter.class,
@ -293,7 +311,8 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_17, 0x5E ),
map( ProtocolConstants.MINECRAFT_1_18, 0x5F ),
map( ProtocolConstants.MINECRAFT_1_19, 0x60 ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x63 )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x63 ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x61 )
);
TO_CLIENT.registerPacket(
EntityStatus.class,
@ -307,7 +326,8 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_16_2, 0x1A ),
map( ProtocolConstants.MINECRAFT_1_17, 0x1B ),
map( ProtocolConstants.MINECRAFT_1_19, 0x18 ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x1A )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x1A ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x19 )
);
TO_CLIENT.registerPacket(
Commands.class,
@ -317,7 +337,8 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_16, 0x11 ),
map( ProtocolConstants.MINECRAFT_1_16_2, 0x10 ),
map( ProtocolConstants.MINECRAFT_1_17, 0x12 ),
map( ProtocolConstants.MINECRAFT_1_19, 0x0F )
map( ProtocolConstants.MINECRAFT_1_19, 0x0F ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x0E )
);
TO_CLIENT.registerPacket(
GameState.class,
@ -327,7 +348,8 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_16_2, 0x1D ),
map( ProtocolConstants.MINECRAFT_1_17, 0x1E ),
map( ProtocolConstants.MINECRAFT_1_19, 0x1B ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x1D )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x1D ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x1C )
);
TO_CLIENT.registerPacket(
ViewDistance.class,
@ -337,13 +359,25 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_16, 0x41 ),
map( ProtocolConstants.MINECRAFT_1_17, 0x4A ),
map( ProtocolConstants.MINECRAFT_1_19, 0x49 ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x4C )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x4C ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x4B )
);
TO_CLIENT.registerPacket(
ServerData.class,
ServerData::new,
map( ProtocolConstants.MINECRAFT_1_19, 0x3F ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x42 )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x42 ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x41 )
);
TO_CLIENT.registerPacket(
PlayerListItemRemove.class,
PlayerListItemRemove::new,
map( ProtocolConstants.MINECRAFT_1_19_3, 0x35 )
);
TO_CLIENT.registerPacket(
PlayerListItemUpdate.class,
PlayerListItemUpdate::new,
map( ProtocolConstants.MINECRAFT_1_19_3, 0x36 )
);
TO_SERVER.registerPacket(
@ -358,7 +392,8 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_16, 0x10 ),
map( ProtocolConstants.MINECRAFT_1_17, 0x0F ),
map( ProtocolConstants.MINECRAFT_1_19, 0x11 ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x12 )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x12 ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x11 )
);
TO_SERVER.registerPacket( Chat.class,
Chat::new,
@ -391,7 +426,8 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_13, 0x05 ),
map( ProtocolConstants.MINECRAFT_1_14, 0x06 ),
map( ProtocolConstants.MINECRAFT_1_19, 0x08 ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x09 )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x09 ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x08 )
);
TO_SERVER.registerPacket(
ClientSettings.class,
@ -402,7 +438,8 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_12_1, 0x04 ),
map( ProtocolConstants.MINECRAFT_1_14, 0x05 ),
map( ProtocolConstants.MINECRAFT_1_19, 0x07 ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x08 )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x08 ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x07 )
);
TO_SERVER.registerPacket(
PluginMessage.class,
@ -415,7 +452,8 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_14, 0x0B ),
map( ProtocolConstants.MINECRAFT_1_17, 0x0A ),
map( ProtocolConstants.MINECRAFT_1_19, 0x0C ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x0D )
map( ProtocolConstants.MINECRAFT_1_19_1, 0x0D ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x0C )
);
}
},

View File

@ -40,6 +40,7 @@ public class ProtocolConstants
public static final int MINECRAFT_1_18_2 = 758;
public static final int MINECRAFT_1_19 = 759;
public static final int MINECRAFT_1_19_1 = 760;
public static final int MINECRAFT_1_19_3 = 761;
public static final List<String> SUPPORTED_VERSIONS;
public static final List<Integer> SUPPORTED_VERSION_IDS;
@ -92,7 +93,8 @@ public class ProtocolConstants
ProtocolConstants.MINECRAFT_1_18,
ProtocolConstants.MINECRAFT_1_18_2,
ProtocolConstants.MINECRAFT_1_19,
ProtocolConstants.MINECRAFT_1_19_1
ProtocolConstants.MINECRAFT_1_19_1,
ProtocolConstants.MINECRAFT_1_19_3
);
if ( SNAPSHOT_SUPPORT )

View File

@ -0,0 +1,39 @@
package net.md_5.bungee.protocol;
import io.netty.buffer.ByteBuf;
import java.util.BitSet;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class SeenMessages extends DefinedPacket
{
private int offset;
private BitSet acknowledged;
@Override
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{
offset = DefinedPacket.readVarInt( buf );
acknowledged = DefinedPacket.readFixedBitSet( 20, buf );
}
@Override
public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{
DefinedPacket.writeVarInt( offset, buf );
DefinedPacket.writeFixedBitSet( acknowledged, 20, buf );
}
@Override
public void handle(AbstractPacketHandler handler) throws Exception
{
throw new UnsupportedOperationException( "Not supported." );
}
}

View File

@ -9,6 +9,7 @@ import net.md_5.bungee.protocol.AbstractPacketHandler;
import net.md_5.bungee.protocol.ChatChain;
import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.ProtocolConstants;
import net.md_5.bungee.protocol.SeenMessages;
@Data
@NoArgsConstructor
@ -23,6 +24,7 @@ public class ClientChat extends DefinedPacket
private byte[] signature;
private boolean signedPreview;
private ChatChain chain;
private SeenMessages seenMessages;
@Override
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
@ -30,9 +32,27 @@ public class ClientChat extends DefinedPacket
message = readString( buf, 256 );
timestamp = buf.readLong();
salt = buf.readLong();
signature = readArray( buf );
signedPreview = buf.readBoolean();
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 )
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_3 )
{
if ( buf.readBoolean() )
{
signature = new byte[ 256 ];
buf.readBytes( signature );
}
} else
{
signature = readArray( buf );
}
if ( protocolVersion < ProtocolConstants.MINECRAFT_1_19_3 )
{
signedPreview = buf.readBoolean();
}
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_3 )
{
seenMessages = new SeenMessages();
seenMessages.read( buf, direction, protocolVersion );
} else if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 )
{
chain = new ChatChain();
chain.read( buf, direction, protocolVersion );
@ -45,9 +65,25 @@ public class ClientChat extends DefinedPacket
writeString( message, buf );
buf.writeLong( timestamp );
buf.writeLong( salt );
writeArray( signature, buf );
buf.writeBoolean( signedPreview );
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 )
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_3 )
{
buf.writeBoolean( signature != null );
if ( signature != null )
{
buf.writeBytes( signature );
}
} else
{
writeArray( signature, buf );
}
if ( protocolVersion < ProtocolConstants.MINECRAFT_1_19_3 )
{
buf.writeBoolean( signedPreview );
}
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_3 )
{
seenMessages.write( buf, direction, protocolVersion );
} else if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 )
{
chain.write( buf, direction, protocolVersion );
}

View File

@ -12,6 +12,7 @@ import net.md_5.bungee.protocol.AbstractPacketHandler;
import net.md_5.bungee.protocol.ChatChain;
import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.ProtocolConstants;
import net.md_5.bungee.protocol.SeenMessages;
@Data
@NoArgsConstructor
@ -26,6 +27,7 @@ public class ClientCommand extends DefinedPacket
private Map<String, byte[]> signatures;
private boolean signedPreview;
private ChatChain chain;
private SeenMessages seenMessages;
@Override
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
@ -39,11 +41,29 @@ public class ClientCommand extends DefinedPacket
signatures = new HashMap<>( cnt );
for ( int i = 0; i < cnt; i++ )
{
signatures.put( readString( buf, 16 ), readArray( buf ) );
String name = readString( buf, 16 );
byte[] signature;
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_3 )
{
signature = new byte[ 256 ];
buf.readBytes( signature );
} else
{
signature = readArray( buf );
}
signatures.put( name, signature );
}
signedPreview = buf.readBoolean();
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 )
if ( protocolVersion < ProtocolConstants.MINECRAFT_1_19_3 )
{
signedPreview = buf.readBoolean();
}
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_3 )
{
seenMessages = new SeenMessages();
seenMessages.read( buf, direction, protocolVersion );
} else if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 )
{
chain = new ChatChain();
chain.read( buf, direction, protocolVersion );
@ -61,11 +81,23 @@ public class ClientCommand extends DefinedPacket
for ( Map.Entry<String, byte[]> entry : signatures.entrySet() )
{
writeString( entry.getKey(), buf );
writeArray( entry.getValue(), buf );
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_3 )
{
buf.writeBytes( entry.getValue() );
} else
{
writeArray( entry.getValue(), buf );
}
}
buf.writeBoolean( signedPreview );
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 )
if ( protocolVersion < ProtocolConstants.MINECRAFT_1_19_3 )
{
buf.writeBoolean( signedPreview );
}
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_3 )
{
seenMessages.write( buf, direction, protocolVersion );
} else if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 )
{
chain.write( buf, direction, protocolVersion );
}

View File

@ -24,13 +24,11 @@ import com.mojang.brigadier.tree.LiteralCommandNode;
import com.mojang.brigadier.tree.RootCommandNode;
import io.netty.buffer.ByteBuf;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Deque;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import lombok.AllArgsConstructor;
@ -310,7 +308,8 @@ public class Commands extends DefinedPacket
{
private static final Map<String, ArgumentSerializer> PROVIDERS = new HashMap<>();
private static final List<ArgumentSerializer> PROVIDER_LIST = new ArrayList<>();
private static final ArgumentSerializer[] IDS_1_19;
private static final ArgumentSerializer[] IDS_1_19_3;
private static final Map<Class<?>, ProperArgumentSerializer<?>> PROPER_PROVIDERS = new HashMap<>();
//
private static final ArgumentSerializer<Void> VOID = new ArgumentSerializer<Void>()
@ -644,13 +643,124 @@ public class Commands extends DefinedPacket
register( "minecraft:template_rotation", VOID ); // 1.19
register( "minecraft:uuid", VOID ); // 1.16
register( "minecraft:gamemode", VOID ); // 1.19.3
register( "minecraft:resource_or_tag_key", RAW_STRING ); // 1.19.3
register( "minecraft:resource_key", RAW_STRING ); // 1.19.3
register( "minecraft:nbt", VOID ); // 1.13 // removed
IDS_1_19 = new ArgumentSerializer[]
{
get( "brigadier:bool" ),
get( "brigadier:float" ),
get( "brigadier:double" ),
get( "brigadier:integer" ),
get( "brigadier:long" ),
get( "brigadier:string" ),
get( "minecraft:entity" ),
get( "minecraft:game_profile" ),
get( "minecraft:block_pos" ),
get( "minecraft:column_pos" ),
get( "minecraft:vec3" ),
get( "minecraft:vec2" ),
get( "minecraft:block_state" ),
get( "minecraft:block_predicate" ),
get( "minecraft:item_stack" ),
get( "minecraft:item_predicate" ),
get( "minecraft:color" ),
get( "minecraft:component" ),
get( "minecraft:message" ),
get( "minecraft:nbt_compound_tag" ),
get( "minecraft:nbt_tag" ),
get( "minecraft:nbt_path" ),
get( "minecraft:objective" ),
get( "minecraft:objective_criteria" ),
get( "minecraft:operation" ),
get( "minecraft:particle" ),
get( "minecraft:angle" ),
get( "minecraft:rotation" ),
get( "minecraft:scoreboard_slot" ),
get( "minecraft:score_holder" ),
get( "minecraft:swizzle" ),
get( "minecraft:team" ),
get( "minecraft:item_slot" ),
get( "minecraft:resource_location" ),
get( "minecraft:mob_effect" ),
get( "minecraft:function" ),
get( "minecraft:entity_anchor" ),
get( "minecraft:int_range" ),
get( "minecraft:float_range" ),
get( "minecraft:item_enchantment" ),
get( "minecraft:entity_summon" ),
get( "minecraft:dimension" ),
get( "minecraft:time" ),
get( "minecraft:resource_or_tag" ),
get( "minecraft:resource" ),
get( "minecraft:template_mirror" ),
get( "minecraft:template_rotation" ),
get( "minecraft:uuid" )
};
IDS_1_19_3 = new ArgumentSerializer[]
{
get( "brigadier:bool" ),
get( "brigadier:float" ),
get( "brigadier:double" ),
get( "brigadier:integer" ),
get( "brigadier:long" ),
get( "brigadier:string" ),
get( "minecraft:entity" ),
get( "minecraft:game_profile" ),
get( "minecraft:block_pos" ),
get( "minecraft:column_pos" ),
get( "minecraft:vec3" ),
get( "minecraft:vec2" ),
get( "minecraft:block_state" ),
get( "minecraft:block_predicate" ),
get( "minecraft:item_stack" ),
get( "minecraft:item_predicate" ),
get( "minecraft:color" ),
get( "minecraft:component" ),
get( "minecraft:message" ),
get( "minecraft:nbt_compound_tag" ),
get( "minecraft:nbt_tag" ),
get( "minecraft:nbt_path" ),
get( "minecraft:objective" ),
get( "minecraft:objective_criteria" ),
get( "minecraft:operation" ),
get( "minecraft:particle" ),
get( "minecraft:angle" ),
get( "minecraft:rotation" ),
get( "minecraft:scoreboard_slot" ),
get( "minecraft:score_holder" ),
get( "minecraft:swizzle" ),
get( "minecraft:team" ),
get( "minecraft:item_slot" ),
get( "minecraft:resource_location" ),
get( "minecraft:function" ),
get( "minecraft:entity_anchor" ),
get( "minecraft:int_range" ),
get( "minecraft:float_range" ),
get( "minecraft:dimension" ),
get( "minecraft:gamemode" ),
get( "minecraft:time" ),
get( "minecraft:resource_or_tag" ),
get( "minecraft:resource_or_tag_key" ),
get( "minecraft:resource" ),
get( "minecraft:resource_key" ),
get( "minecraft:template_mirror" ),
get( "minecraft:template_rotation" ),
get( "minecraft:uuid" )
};
}
private static void register(String name, ArgumentSerializer serializer)
{
PROVIDERS.put( name, serializer );
PROVIDER_LIST.add( serializer );
}
private static ArgumentSerializer get(String name)
{
return PROVIDERS.get( name );
}
/**
@ -1059,7 +1169,14 @@ public class Commands extends DefinedPacket
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19 )
{
key = readVarInt( buf );
reader = PROVIDER_LIST.get( (Integer) key );
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_3 )
{
reader = IDS_1_19_3[(Integer) key];
} else
{
reader = IDS_1_19[(Integer) key];
}
} else
{
key = readString( buf );

View File

@ -23,7 +23,7 @@ public class EncryptionResponse extends DefinedPacket
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{
sharedSecret = readArray( buf, 128 );
if ( protocolVersion < ProtocolConstants.MINECRAFT_1_19 || buf.readBoolean() )
if ( protocolVersion < ProtocolConstants.MINECRAFT_1_19 || protocolVersion >= ProtocolConstants.MINECRAFT_1_19_3 || buf.readBoolean() )
{
verifyToken = readArray( buf, 128 );
} else
@ -38,7 +38,7 @@ public class EncryptionResponse extends DefinedPacket
writeArray( sharedSecret, buf );
if ( verifyToken != null )
{
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19 )
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19 && protocolVersion <= ProtocolConstants.MINECRAFT_1_19_3 )
{
buf.writeBoolean( true );
}

View File

@ -26,7 +26,7 @@ public class LoginRequest extends DefinedPacket
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{
data = readString( buf, 16 );
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19 )
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19 && protocolVersion < ProtocolConstants.MINECRAFT_1_19_3 )
{
publicKey = readPublicKey( buf );
}
@ -43,7 +43,7 @@ public class LoginRequest extends DefinedPacket
public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{
writeString( data, buf );
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19 )
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19 && protocolVersion < ProtocolConstants.MINECRAFT_1_19_3 )
{
writePublicKey( publicKey, buf );
}

View File

@ -123,21 +123,26 @@ public class PlayerListItem extends DefinedPacket
{
// ALL
private UUID uuid;
UUID uuid;
// ADD_PLAYER
private String username;
private Property[] properties;
private PlayerPublicKey publicKey;
String username;
Property[] properties;
UUID chatSessionId;
PlayerPublicKey publicKey;
// UPDATE_LISTED
Boolean listed;
// ADD_PLAYER & UPDATE_GAMEMODE
private int gamemode;
Integer gamemode;
// ADD_PLAYER & UPDATE_LATENCY
private int ping;
Integer ping;
// ADD_PLAYER & UPDATE_DISPLAY_NAME
private String displayName;
String displayName;
}
}

View File

@ -0,0 +1,45 @@
package net.md_5.bungee.protocol.packet;
import io.netty.buffer.ByteBuf;
import java.util.UUID;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import net.md_5.bungee.protocol.AbstractPacketHandler;
import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.ProtocolConstants;
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class PlayerListItemRemove extends DefinedPacket
{
private UUID[] uuids;
@Override
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{
uuids = new UUID[ DefinedPacket.readVarInt( buf ) ];
for ( int i = 0; i < uuids.length; i++ )
{
uuids[i] = DefinedPacket.readUUID( buf );
}
}
@Override
public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{
DefinedPacket.writeVarInt( uuids.length, buf );
for ( UUID uuid : uuids )
{
DefinedPacket.writeUUID( uuid, buf );
}
}
@Override
public void handle(AbstractPacketHandler handler) throws Exception
{
handler.handle( this );
}
}

View File

@ -0,0 +1,133 @@
package net.md_5.bungee.protocol.packet;
import io.netty.buffer.ByteBuf;
import java.util.EnumSet;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import net.md_5.bungee.protocol.AbstractPacketHandler;
import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.PlayerPublicKey;
import net.md_5.bungee.protocol.ProtocolConstants;
import net.md_5.bungee.protocol.packet.PlayerListItem.Item;
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class PlayerListItemUpdate extends DefinedPacket
{
private EnumSet<Action> actions;
private Item[] items;
@Override
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{
actions = readEnumSet( PlayerListItemUpdate.Action.class, buf );
items = new Item[ DefinedPacket.readVarInt( buf ) ];
for ( int i = 0; i < items.length; i++ )
{
Item item = items[i] = new Item();
item.setUuid( DefinedPacket.readUUID( buf ) );
for ( Action action : actions )
{
switch ( action )
{
case ADD_PLAYER:
item.username = DefinedPacket.readString( buf );
item.properties = DefinedPacket.readProperties( buf );
break;
case INITIALIZE_CHAT:
if ( buf.readBoolean() )
{
item.chatSessionId = readUUID( buf );
item.publicKey = new PlayerPublicKey( buf.readLong(), readArray( buf, 512 ), readArray( buf, 4096 ) );
}
break;
case UPDATE_GAMEMODE:
item.gamemode = DefinedPacket.readVarInt( buf );
break;
case UPDATE_LISTED:
item.listed = buf.readBoolean();
break;
case UPDATE_LATENCY:
item.ping = DefinedPacket.readVarInt( buf );
break;
case UPDATE_DISPLAY_NAME:
if ( buf.readBoolean() )
{
item.displayName = DefinedPacket.readString( buf );
}
break;
}
}
}
}
@Override
public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{
DefinedPacket.writeEnumSet( actions, PlayerListItemUpdate.Action.class, buf );
DefinedPacket.writeVarInt( items.length, buf );
for ( Item item : items )
{
DefinedPacket.writeUUID( item.uuid, buf );
for ( Action action : actions )
{
switch ( action )
{
case ADD_PLAYER:
DefinedPacket.writeString( item.username, buf );
DefinedPacket.writeProperties( item.properties, buf );
break;
case INITIALIZE_CHAT:
buf.writeBoolean( item.chatSessionId != null );
if ( item.chatSessionId != null )
{
writeUUID( item.chatSessionId, buf );
buf.writeLong( item.publicKey.getExpiry() );
writeArray( item.publicKey.getKey(), buf );
writeArray( item.publicKey.getSignature(), buf );
}
break;
case UPDATE_GAMEMODE:
DefinedPacket.writeVarInt( item.gamemode, buf );
break;
case UPDATE_LISTED:
buf.writeBoolean( item.listed );
break;
case UPDATE_LATENCY:
DefinedPacket.writeVarInt( item.ping, buf );
break;
case UPDATE_DISPLAY_NAME:
buf.writeBoolean( item.displayName != null );
if ( item.displayName != null )
{
DefinedPacket.writeString( item.displayName, buf );
}
break;
}
}
}
}
@Override
public void handle(AbstractPacketHandler handler) throws Exception
{
handler.handle( this );
}
public static enum Action
{
ADD_PLAYER,
INITIALIZE_CHAT,
UPDATE_GAMEMODE,
UPDATE_LISTED,
UPDATE_LATENCY,
UPDATE_DISPLAY_NAME;
}
}

View File

@ -33,7 +33,10 @@ public class ServerData extends DefinedPacket
icon = readString( buf );
}
preview = buf.readBoolean();
if ( protocolVersion < ProtocolConstants.MINECRAFT_1_19_3 )
{
preview = buf.readBoolean();
}
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 )
{
@ -62,7 +65,10 @@ public class ServerData extends DefinedPacket
buf.writeBoolean( false );
}
buf.writeBoolean( preview );
if ( protocolVersion < ProtocolConstants.MINECRAFT_1_19_3 )
{
buf.writeBoolean( preview );
}
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 )
{

View File

@ -59,6 +59,8 @@ import net.md_5.bungee.protocol.packet.Commands;
import net.md_5.bungee.protocol.packet.KeepAlive;
import net.md_5.bungee.protocol.packet.Kick;
import net.md_5.bungee.protocol.packet.PlayerListItem;
import net.md_5.bungee.protocol.packet.PlayerListItemRemove;
import net.md_5.bungee.protocol.packet.PlayerListItemUpdate;
import net.md_5.bungee.protocol.packet.PluginMessage;
import net.md_5.bungee.protocol.packet.Respawn;
import net.md_5.bungee.protocol.packet.ScoreboardDisplay;
@ -158,6 +160,20 @@ public class DownstreamBridge extends PacketHandler
throw CancelSendSignal.INSTANCE; // Always throw because of profile rewriting
}
@Override
public void handle(PlayerListItemRemove playerList) throws Exception
{
con.getTabListHandler().onUpdate( TabList.rewrite( playerList ) );
throw CancelSendSignal.INSTANCE; // Always throw because of profile rewriting
}
@Override
public void handle(PlayerListItemUpdate playerList) throws Exception
{
con.getTabListHandler().onUpdate( TabList.rewrite( playerList ) );
throw CancelSendSignal.INSTANCE; // Always throw because of profile rewriting
}
@Override
public void handle(ScoreboardObjective objective) throws Exception
{

View File

@ -392,7 +392,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
return;
}
if ( BungeeCord.getInstance().config.isEnforceSecureProfile() )
if ( BungeeCord.getInstance().config.isEnforceSecureProfile() && getVersion() < ProtocolConstants.MINECRAFT_1_19_3 )
{
PlayerPublicKey publicKey = loginRequest.getPublicKey();
if ( publicKey == null )
@ -549,7 +549,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
if ( BungeeCord.getInstance().config.isEnforceSecureProfile() )
{
if ( getVersion() >= ProtocolConstants.MINECRAFT_1_19_1 )
if ( getVersion() >= ProtocolConstants.MINECRAFT_1_19_1 && getVersion() < ProtocolConstants.MINECRAFT_1_19_3 )
{
boolean secure = false;
try

View File

@ -7,6 +7,7 @@ import com.mojang.brigadier.suggestion.Suggestions;
import io.netty.channel.Channel;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import net.md_5.bungee.BungeeCord;
import net.md_5.bungee.ServerConnection.KeepAliveData;
import net.md_5.bungee.UserConnection;
@ -31,6 +32,7 @@ import net.md_5.bungee.protocol.packet.ClientCommand;
import net.md_5.bungee.protocol.packet.ClientSettings;
import net.md_5.bungee.protocol.packet.KeepAlive;
import net.md_5.bungee.protocol.packet.PlayerListItem;
import net.md_5.bungee.protocol.packet.PlayerListItemRemove;
import net.md_5.bungee.protocol.packet.PluginMessage;
import net.md_5.bungee.protocol.packet.TabCompleteRequest;
import net.md_5.bungee.protocol.packet.TabCompleteResponse;
@ -75,17 +77,30 @@ public class UpstreamBridge extends PacketHandler
// TODO: This should only done with server_unique
// tab list (which is the only one supported
// currently)
PlayerListItem packet = new PlayerListItem();
packet.setAction( PlayerListItem.Action.REMOVE_PLAYER );
PlayerListItem oldPacket = new PlayerListItem();
oldPacket.setAction( PlayerListItem.Action.REMOVE_PLAYER );
PlayerListItem.Item item = new PlayerListItem.Item();
item.setUuid( con.getUniqueId() );
packet.setItems( new PlayerListItem.Item[]
oldPacket.setItems( new PlayerListItem.Item[]
{
item
} );
PlayerListItemRemove newPacket = new PlayerListItemRemove();
newPacket.setUuids( new UUID[]
{
con.getUniqueId()
} );
for ( ProxiedPlayer player : con.getServer().getInfo().getPlayers() )
{
player.unsafe().sendPacket( packet );
if ( player.getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_19_3 )
{
player.unsafe().sendPacket( newPacket );
} else
{
player.unsafe().sendPacket( oldPacket );
}
}
con.getServer().disconnect( "Quitting" );
}

View File

@ -77,6 +77,7 @@ public abstract class EntityMap
case ProtocolConstants.MINECRAFT_1_19:
return EntityMap_1_16_2.INSTANCE_1_19;
case ProtocolConstants.MINECRAFT_1_19_1:
case ProtocolConstants.MINECRAFT_1_19_3:
return EntityMap_1_16_2.INSTANCE_1_19_1;
}
throw new RuntimeException( "Version " + version + " has no entity map" );

View File

@ -4,7 +4,10 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.UUID;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.protocol.ProtocolConstants;
import net.md_5.bungee.protocol.packet.PlayerListItem;
import net.md_5.bungee.protocol.packet.PlayerListItemRemove;
import net.md_5.bungee.protocol.packet.PlayerListItemUpdate;
public class ServerUnique extends TabList
{
@ -32,6 +35,32 @@ public class ServerUnique extends TabList
player.unsafe().sendPacket( playerListItem );
}
@Override
public void onUpdate(PlayerListItemRemove playerListItem)
{
for ( UUID uuid : playerListItem.getUuids() )
{
uuids.remove( uuid );
}
player.unsafe().sendPacket( playerListItem );
}
@Override
public void onUpdate(PlayerListItemUpdate playerListItem)
{
for ( PlayerListItem.Item item : playerListItem.getItems() )
{
for ( PlayerListItemUpdate.Action action : playerListItem.getActions() )
{
if ( action == PlayerListItemUpdate.Action.ADD_PLAYER )
{
uuids.add( item.getUuid() );
}
}
}
player.unsafe().sendPacket( playerListItem );
}
@Override
public void onPingChange(int ping)
{
@ -41,17 +70,25 @@ public class ServerUnique extends TabList
@Override
public void onServerChange()
{
PlayerListItem packet = new PlayerListItem();
packet.setAction( PlayerListItem.Action.REMOVE_PLAYER );
PlayerListItem.Item[] items = new PlayerListItem.Item[ uuids.size() ];
int i = 0;
for ( UUID uuid : uuids )
if ( player.getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_19_3 )
{
PlayerListItem.Item item = items[i++] = new PlayerListItem.Item();
item.setUuid( uuid );
PlayerListItemRemove packet = new PlayerListItemRemove();
packet.setUuids( uuids.stream().toArray( UUID[]::new ) );
player.unsafe().sendPacket( packet );
} else
{
PlayerListItem packet = new PlayerListItem();
packet.setAction( PlayerListItem.Action.REMOVE_PLAYER );
PlayerListItem.Item[] items = new PlayerListItem.Item[ uuids.size() ];
int i = 0;
for ( UUID uuid : uuids )
{
PlayerListItem.Item item = items[i++] = new PlayerListItem.Item();
item.setUuid( uuid );
}
packet.setItems( items );
player.unsafe().sendPacket( packet );
}
packet.setItems( items );
player.unsafe().sendPacket( packet );
uuids.clear();
}
@ -66,4 +103,5 @@ public class ServerUnique extends TabList
{
}
}

View File

@ -7,6 +7,8 @@ import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.connection.LoginResult;
import net.md_5.bungee.protocol.Property;
import net.md_5.bungee.protocol.packet.PlayerListItem;
import net.md_5.bungee.protocol.packet.PlayerListItemRemove;
import net.md_5.bungee.protocol.packet.PlayerListItemUpdate;
@RequiredArgsConstructor
public abstract class TabList
@ -16,6 +18,10 @@ public abstract class TabList
public abstract void onUpdate(PlayerListItem playerListItem);
public abstract void onUpdate(PlayerListItemRemove playerListItem);
public abstract void onUpdate(PlayerListItemUpdate playerListItem);
public abstract void onPingChange(int ping);
public abstract void onServerChange();
@ -28,14 +34,48 @@ public abstract class TabList
{
for ( PlayerListItem.Item item : playerListItem.getItems() )
{
if ( item.getUuid() == null ) // Old style ping
{
continue;
}
UserConnection player = BungeeCord.getInstance().getPlayerByOfflineUUID( item.getUuid() );
rewrite( item );
}
return playerListItem;
}
public static PlayerListItemRemove rewrite(PlayerListItemRemove playerListItem)
{
for ( int i = 0; i < playerListItem.getUuids().length; i++ )
{
UserConnection player = BungeeCord.getInstance().getPlayerByOfflineUUID( playerListItem.getUuids()[i] );
if ( player != null )
{
item.setUuid( player.getUniqueId() );
playerListItem.getUuids()[i] = player.getUniqueId();
}
}
return playerListItem;
}
public static PlayerListItemUpdate rewrite(PlayerListItemUpdate playerListItem)
{
for ( PlayerListItem.Item item : playerListItem.getItems() )
{
rewrite( item );
}
return playerListItem;
}
private static void rewrite(PlayerListItem.Item item)
{
if ( item.getUuid() == null ) // Old style ping
{
return;
}
UserConnection player = BungeeCord.getInstance().getPlayerByOfflineUUID( item.getUuid() );
if ( player != null )
{
item.setUuid( player.getUniqueId() );
if ( item.getProperties() != null )
{
LoginResult loginResult = player.getPendingConnection().getLoginProfile();
if ( loginResult != null && loginResult.getProperties() != null )
{
@ -49,16 +89,15 @@ public abstract class TabList
{
item.setProperties( new Property[ 0 ] );
}
if ( playerListItem.getAction() == PlayerListItem.Action.ADD_PLAYER || playerListItem.getAction() == PlayerListItem.Action.UPDATE_GAMEMODE )
{
player.setGamemode( item.getGamemode() );
}
if ( playerListItem.getAction() == PlayerListItem.Action.ADD_PLAYER || playerListItem.getAction() == PlayerListItem.Action.UPDATE_LATENCY )
{
player.setPing( item.getPing() );
}
}
if ( item.getGamemode() != null )
{
player.setGamemode( item.getGamemode() );
}
if ( item.getPing() != null )
{
player.setPing( item.getPing() );
}
}
return playerListItem;
}
}