Compare commits

..

6 Commits

Author SHA1 Message Date
346aea9958 new event TabCompleteRequestEvent and deprecate TabCompleteEvent 2025-06-21 17:20:23 +02:00
971da19de6 Add CommandsDeclareEvent to declare commands with brigadier API 2025-06-21 17:20:23 +02:00
6d0eec208f Server branding now includes the backend server name 2025-06-21 17:20:23 +02:00
63ccfe34da 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.
2025-06-21 17:20:23 +02:00
084819d375 Change projet configuration and POM for Pandacube 2025-06-21 17:20:19 +02:00
216fe4de3f Remove modules and startup delay
We don’t need them for Pandacube
2025-06-21 16:50:04 +02:00
11 changed files with 111 additions and 133 deletions

View File

@ -8,6 +8,7 @@ import net.md_5.bungee.protocol.packet.ClearTitles;
import net.md_5.bungee.protocol.packet.ClientChat; import net.md_5.bungee.protocol.packet.ClientChat;
import net.md_5.bungee.protocol.packet.ClientCommand; import net.md_5.bungee.protocol.packet.ClientCommand;
import net.md_5.bungee.protocol.packet.ClientSettings; import net.md_5.bungee.protocol.packet.ClientSettings;
import net.md_5.bungee.protocol.packet.ClientStatus;
import net.md_5.bungee.protocol.packet.Commands; import net.md_5.bungee.protocol.packet.Commands;
import net.md_5.bungee.protocol.packet.CookieRequest; import net.md_5.bungee.protocol.packet.CookieRequest;
import net.md_5.bungee.protocol.packet.CookieResponse; import net.md_5.bungee.protocol.packet.CookieResponse;
@ -127,6 +128,10 @@ public abstract class AbstractPacketHandler
{ {
} }
public void handle(ClientStatus clientStatus) throws Exception
{
}
public void handle(PlayerListItem playerListItem) throws Exception public void handle(PlayerListItem playerListItem) throws Exception
{ {
} }

View File

@ -48,38 +48,6 @@ public abstract class DefinedPacket
} }
} }
public <T> T readLengthPrefixed(Function<ByteBuf, T> reader, ByteBuf buf, int maxSize)
{
int size = readVarInt( buf );
if ( size > maxSize )
{
throw new OverflowPacketException( "Cannot read length prefixed with limit " + maxSize + " (got size of " + size + ")" );
}
return reader.apply( buf.readSlice( size ) );
}
public <T> void writeLengthPrefixed(T value, BiConsumer<T, ByteBuf> writer, ByteBuf buf, int maxSize)
{
ByteBuf tempBuffer = buf.alloc().buffer();
try
{
writer.accept( value, tempBuffer );
if ( tempBuffer.readableBytes() > maxSize )
{
throw new OverflowPacketException( "Cannot write length prefixed with limit " + maxSize + " (got size of " + tempBuffer.readableBytes() + ")" );
}
writeVarInt( tempBuffer.readableBytes(), buf );
buf.writeBytes( tempBuffer );
} finally
{
tempBuffer.release();
}
}
public static void writeString(String s, ByteBuf buf) public static void writeString(String s, ByteBuf buf)
{ {
writeString( s, buf, Short.MAX_VALUE ); writeString( s, buf, Short.MAX_VALUE );

View File

@ -131,8 +131,7 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_21_2, 0x2C ), map( ProtocolConstants.MINECRAFT_1_21_2, 0x2C ),
map( ProtocolConstants.MINECRAFT_1_21_5, 0x2B ) map( ProtocolConstants.MINECRAFT_1_21_5, 0x2B )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket( Chat.class,
Chat.class,
Chat::new, Chat::new,
map( ProtocolConstants.MINECRAFT_1_8, 0x02 ), map( ProtocolConstants.MINECRAFT_1_8, 0x02 ),
map( ProtocolConstants.MINECRAFT_1_9, 0x0F ), map( ProtocolConstants.MINECRAFT_1_9, 0x0F ),
@ -338,7 +337,6 @@ public enum Protocol
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
Title.class, Title.class,
Title::new, Title::new,
RegisterType.ENCODE,
map( ProtocolConstants.MINECRAFT_1_8, 0x45 ), map( ProtocolConstants.MINECRAFT_1_8, 0x45 ),
map( ProtocolConstants.MINECRAFT_1_12, 0x47 ), map( ProtocolConstants.MINECRAFT_1_12, 0x47 ),
map( ProtocolConstants.MINECRAFT_1_12_1, 0x48 ), map( ProtocolConstants.MINECRAFT_1_12_1, 0x48 ),
@ -360,7 +358,6 @@ public enum Protocol
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
ClearTitles.class, ClearTitles.class,
ClearTitles::new, ClearTitles::new,
RegisterType.ENCODE,
map( ProtocolConstants.MINECRAFT_1_17, 0x10 ), 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 ), map( ProtocolConstants.MINECRAFT_1_19_3, 0x0C ),
@ -371,7 +368,6 @@ public enum Protocol
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
Subtitle.class, Subtitle.class,
Subtitle::new, Subtitle::new,
RegisterType.ENCODE,
map( ProtocolConstants.MINECRAFT_1_17, 0x57 ), map( ProtocolConstants.MINECRAFT_1_17, 0x57 ),
map( ProtocolConstants.MINECRAFT_1_18, 0x58 ), map( ProtocolConstants.MINECRAFT_1_18, 0x58 ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x5B ), map( ProtocolConstants.MINECRAFT_1_19_1, 0x5B ),
@ -386,7 +382,6 @@ public enum Protocol
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
TitleTimes.class, TitleTimes.class,
TitleTimes::new, TitleTimes::new,
RegisterType.ENCODE,
map( ProtocolConstants.MINECRAFT_1_17, 0x5A ), map( ProtocolConstants.MINECRAFT_1_17, 0x5A ),
map( ProtocolConstants.MINECRAFT_1_18, 0x5B ), map( ProtocolConstants.MINECRAFT_1_18, 0x5B ),
map( ProtocolConstants.MINECRAFT_1_19_1, 0x5E ), map( ProtocolConstants.MINECRAFT_1_19_1, 0x5E ),
@ -401,7 +396,6 @@ public enum Protocol
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
SystemChat.class, SystemChat.class,
SystemChat::new, SystemChat::new,
RegisterType.ENCODE,
map( ProtocolConstants.MINECRAFT_1_19, 0x5F ), 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 ), map( ProtocolConstants.MINECRAFT_1_19_3, 0x60 ),
@ -415,7 +409,6 @@ public enum Protocol
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
PlayerListHeaderFooter.class, PlayerListHeaderFooter.class,
PlayerListHeaderFooter::new, PlayerListHeaderFooter::new,
RegisterType.ENCODE,
map( ProtocolConstants.MINECRAFT_1_8, 0x47 ), map( ProtocolConstants.MINECRAFT_1_8, 0x47 ),
map( ProtocolConstants.MINECRAFT_1_9, 0x48 ), map( ProtocolConstants.MINECRAFT_1_9, 0x48 ),
map( ProtocolConstants.MINECRAFT_1_9_4, 0x47 ), map( ProtocolConstants.MINECRAFT_1_9_4, 0x47 ),
@ -440,7 +433,6 @@ public enum Protocol
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
EntityStatus.class, EntityStatus.class,
EntityStatus::new, EntityStatus::new,
RegisterType.ENCODE,
map( ProtocolConstants.MINECRAFT_1_8, 0x1A ), map( ProtocolConstants.MINECRAFT_1_8, 0x1A ),
map( ProtocolConstants.MINECRAFT_1_9, 0x1B ), map( ProtocolConstants.MINECRAFT_1_9, 0x1B ),
map( ProtocolConstants.MINECRAFT_1_13, 0x1C ), map( ProtocolConstants.MINECRAFT_1_13, 0x1C ),
@ -474,7 +466,6 @@ public enum Protocol
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
GameState.class, GameState.class,
GameState::new, GameState::new,
RegisterType.ENCODE,
map( ProtocolConstants.MINECRAFT_1_15, 0x1F ), map( ProtocolConstants.MINECRAFT_1_15, 0x1F ),
map( ProtocolConstants.MINECRAFT_1_16, 0x1E ), map( ProtocolConstants.MINECRAFT_1_16, 0x1E ),
map( ProtocolConstants.MINECRAFT_1_16_2, 0x1D ), map( ProtocolConstants.MINECRAFT_1_16_2, 0x1D ),
@ -491,7 +482,6 @@ public enum Protocol
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
ViewDistance.class, ViewDistance.class,
ViewDistance::new, ViewDistance::new,
RegisterType.ENCODE,
map( ProtocolConstants.MINECRAFT_1_14, 0x41 ), map( ProtocolConstants.MINECRAFT_1_14, 0x41 ),
map( ProtocolConstants.MINECRAFT_1_15, 0x42 ), map( ProtocolConstants.MINECRAFT_1_15, 0x42 ),
map( ProtocolConstants.MINECRAFT_1_16, 0x41 ), map( ProtocolConstants.MINECRAFT_1_16, 0x41 ),
@ -557,7 +547,6 @@ public enum Protocol
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
StoreCookie.class, StoreCookie.class,
StoreCookie::new, StoreCookie::new,
RegisterType.ENCODE,
map( ProtocolConstants.MINECRAFT_1_20_5, 0x6B ), map( ProtocolConstants.MINECRAFT_1_20_5, 0x6B ),
map( ProtocolConstants.MINECRAFT_1_21_2, 0x72 ), map( ProtocolConstants.MINECRAFT_1_21_2, 0x72 ),
map( ProtocolConstants.MINECRAFT_1_21_5, 0x71 ) map( ProtocolConstants.MINECRAFT_1_21_5, 0x71 )
@ -565,34 +554,29 @@ public enum Protocol
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
Transfer.class, Transfer.class,
Transfer::new, Transfer::new,
RegisterType.ENCODE,
map( ProtocolConstants.MINECRAFT_1_20_5, 0x73 ), map( ProtocolConstants.MINECRAFT_1_20_5, 0x73 ),
map( ProtocolConstants.MINECRAFT_1_21_2, 0x7A ) map( ProtocolConstants.MINECRAFT_1_21_2, 0x7A )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
DisconnectReportDetails.class, DisconnectReportDetails.class,
DisconnectReportDetails::new, DisconnectReportDetails::new,
RegisterType.ENCODE,
map( ProtocolConstants.MINECRAFT_1_21, 0x7A ), map( ProtocolConstants.MINECRAFT_1_21, 0x7A ),
map( ProtocolConstants.MINECRAFT_1_21_2, 0x81 ) map( ProtocolConstants.MINECRAFT_1_21_2, 0x81 )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
ServerLinks.class, ServerLinks.class,
ServerLinks::new, ServerLinks::new,
RegisterType.ENCODE,
map( ProtocolConstants.MINECRAFT_1_21, 0x7B ), map( ProtocolConstants.MINECRAFT_1_21, 0x7B ),
map( ProtocolConstants.MINECRAFT_1_21_2, 0x82 ) map( ProtocolConstants.MINECRAFT_1_21_2, 0x82 )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
ClearDialog.class, ClearDialog.class,
ClearDialog::new, ClearDialog::new,
RegisterType.ENCODE,
map( ProtocolConstants.MINECRAFT_1_21_6, 0x84 ) map( ProtocolConstants.MINECRAFT_1_21_6, 0x84 )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
ShowDialog.class, ShowDialog.class,
ShowDialog::new, ShowDialog::new,
RegisterType.ENCODE,
map( ProtocolConstants.MINECRAFT_1_21_6, 0x85 ) map( ProtocolConstants.MINECRAFT_1_21_6, 0x85 )
); );
@ -857,37 +841,31 @@ public enum Protocol
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
StoreCookie.class, StoreCookie.class,
StoreCookie::new, StoreCookie::new,
RegisterType.ENCODE,
map( ProtocolConstants.MINECRAFT_1_20_5, 0x0A ) map( ProtocolConstants.MINECRAFT_1_20_5, 0x0A )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
Transfer.class, Transfer.class,
Transfer::new, Transfer::new,
RegisterType.ENCODE,
map( ProtocolConstants.MINECRAFT_1_20_5, 0x0B ) map( ProtocolConstants.MINECRAFT_1_20_5, 0x0B )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
DisconnectReportDetails.class, DisconnectReportDetails.class,
DisconnectReportDetails::new, DisconnectReportDetails::new,
RegisterType.ENCODE,
map( ProtocolConstants.MINECRAFT_1_21, 0x0F ) map( ProtocolConstants.MINECRAFT_1_21, 0x0F )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
ServerLinks.class, ServerLinks.class,
ServerLinks::new, ServerLinks::new,
RegisterType.ENCODE,
map( ProtocolConstants.MINECRAFT_1_21, 0x10 ) map( ProtocolConstants.MINECRAFT_1_21, 0x10 )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
ClearDialog.class, ClearDialog.class,
ClearDialog::new, ClearDialog::new,
RegisterType.ENCODE,
map( ProtocolConstants.MINECRAFT_1_21_6, 0x11 ) map( ProtocolConstants.MINECRAFT_1_21_6, 0x11 )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
ShowDialogDirect.class, ShowDialogDirect.class,
ShowDialogDirect::new, ShowDialogDirect::new,
RegisterType.ENCODE,
map( ProtocolConstants.MINECRAFT_1_21_6, 0x12 ) map( ProtocolConstants.MINECRAFT_1_21_6, 0x12 )
); );
@ -979,26 +957,6 @@ public enum Protocol
private final int packetID; private final int packetID;
} }
private enum RegisterType
{
// packet is registered to be encoded (only sent, never handled)
ENCODE,
// packet is registered to be decoded (only handled never modified)
DECODE,
// packet is registered to be both, encoded and decoded
BOTH;
public boolean encode()
{
return this == BOTH || this == ENCODE;
}
public boolean decode()
{
return this == BOTH || this == DECODE;
}
}
// Helper method // Helper method
private static ProtocolMapping map(int protocol, int id) private static ProtocolMapping map(int protocol, int id)
{ {
@ -1052,11 +1010,6 @@ public enum Protocol
} }
private void registerPacket(Class<? extends DefinedPacket> packetClass, Supplier<? extends DefinedPacket> constructor, ProtocolMapping... mappings) private void registerPacket(Class<? extends DefinedPacket> packetClass, Supplier<? extends DefinedPacket> constructor, ProtocolMapping... mappings)
{
registerPacket( packetClass, constructor, RegisterType.BOTH, mappings );
}
private void registerPacket(Class<? extends DefinedPacket> packetClass, Supplier<? extends DefinedPacket> constructor, RegisterType registerType, ProtocolMapping... mappings)
{ {
int mappingIndex = 0; int mappingIndex = 0;
ProtocolMapping mapping = mappings[mappingIndex]; ProtocolMapping mapping = mappings[mappingIndex];
@ -1089,18 +1042,11 @@ public enum Protocol
ProtocolData data = protocols.get( protocol ); ProtocolData data = protocols.get( protocol );
Preconditions.checkState( data.packetConstructors[mapping.packetID] == null, "Duplicate packet mapping (%s)", mapping.packetID ); Preconditions.checkState( data.packetConstructors[mapping.packetID] == null, "Duplicate packet mapping (%s)", mapping.packetID );
Preconditions.checkState( !data.packetMap.containsKey( packetClass ), "Duplicate packet mapping (%s)", mapping.packetID );
if ( registerType.encode() )
{
data.packetMap.put( packetClass, mapping.packetID ); data.packetMap.put( packetClass, mapping.packetID );
}
if ( registerType.decode() )
{
data.packetConstructors[mapping.packetID] = constructor; data.packetConstructors[mapping.packetID] = constructor;
} }
} }
}
public boolean hasPacket(Class<? extends DefinedPacket> packet, int version) public boolean hasPacket(Class<? extends DefinedPacket> packet, int version)
{ {

View File

@ -51,7 +51,6 @@ public class ProtocolConstants
public static final int MINECRAFT_1_21_4 = 769; public static final int MINECRAFT_1_21_4 = 769;
public static final int MINECRAFT_1_21_5 = 770; public static final int MINECRAFT_1_21_5 = 770;
public static final int MINECRAFT_1_21_6 = 771; public static final int MINECRAFT_1_21_6 = 771;
public static final int MINECRAFT_1_21_7 = 772;
public static final List<String> SUPPORTED_VERSIONS; public static final List<String> SUPPORTED_VERSIONS;
public static final List<Integer> SUPPORTED_VERSION_IDS; public static final List<Integer> SUPPORTED_VERSION_IDS;
@ -117,8 +116,7 @@ public class ProtocolConstants
ProtocolConstants.MINECRAFT_1_21_2, ProtocolConstants.MINECRAFT_1_21_2,
ProtocolConstants.MINECRAFT_1_21_4, ProtocolConstants.MINECRAFT_1_21_4,
ProtocolConstants.MINECRAFT_1_21_5, ProtocolConstants.MINECRAFT_1_21_5,
ProtocolConstants.MINECRAFT_1_21_6, ProtocolConstants.MINECRAFT_1_21_6
ProtocolConstants.MINECRAFT_1_21_7
); );
if ( SNAPSHOT_SUPPORT ) if ( SNAPSHOT_SUPPORT )

View File

@ -323,8 +323,6 @@ public final class TagUtil
} }
return jsonLongArray; return jsonLongArray;
case Tag.END:
return JsonNull.INSTANCE;
default: default:
throw new IllegalArgumentException( "Unknown NBT tag: " + tag ); throw new IllegalArgumentException( "Unknown NBT tag: " + tag );
} }

View File

@ -0,0 +1,37 @@
package net.md_5.bungee.protocol.packet;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import net.md_5.bungee.protocol.AbstractPacketHandler;
import net.md_5.bungee.protocol.DefinedPacket;
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class ClientStatus extends DefinedPacket
{
private byte payload;
@Override
public void read(ByteBuf buf)
{
payload = buf.readByte();
}
@Override
public void write(ByteBuf buf)
{
buf.writeByte( payload );
}
@Override
public void handle(AbstractPacketHandler handler) throws Exception
{
handler.handle( this );
}
}

View File

@ -26,14 +26,19 @@ public class CustomClickAction extends DefinedPacket
public void read(ByteBuf buf, Protocol protocol, ProtocolConstants.Direction direction, int protocolVersion) public void read(ByteBuf buf, Protocol protocol, ProtocolConstants.Direction direction, int protocolVersion)
{ {
id = readString( buf ); id = readString( buf );
data = readLengthPrefixed( (buf0) -> (TypedTag) readTag( buf0, protocolVersion, new NBTLimiter( 32768L, 16 ) ), buf, 65536 ); data = readNullable( (buf0) -> (TypedTag) readTag( buf0, protocolVersion, new NBTLimiter( 32768L, 16 ) ), buf );
} }
@Override @Override
public void write(ByteBuf buf, Protocol protocol, ProtocolConstants.Direction direction, int protocolVersion) public void write(ByteBuf buf, Protocol protocol, ProtocolConstants.Direction direction, int protocolVersion)
{ {
writeString( id, buf ); writeString( id, buf );
writeLengthPrefixed( data, (data0, buf0) -> writeTag( data0, buf0, protocolVersion ), buf, 65536 ); writeNullable( data, (data0, buf0) -> writeTag( data0, buf0, protocolVersion ), buf );
}
@Override
public void write(ByteBuf buf)
{
} }
@Override @Override

View File

@ -1,6 +1,9 @@
package net.md_5.bungee.protocol.packet; package net.md_5.bungee.protocol.packet;
import com.google.common.collect.ImmutableMap;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import java.util.Arrays;
import java.util.Map;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -28,10 +31,8 @@ public class Team extends DefinedPacket
private Either<String, BaseComponent> displayName; private Either<String, BaseComponent> displayName;
private Either<String, BaseComponent> prefix; private Either<String, BaseComponent> prefix;
private Either<String, BaseComponent> suffix; private Either<String, BaseComponent> suffix;
// private NameTagVisibility nameTagVisibility;
private Either<String, NameTagVisibility> nameTagVisibility; private CollisionRule collisionRule;
private Either<String, CollisionRule> collisionRule;
//
private int color; private int color;
private byte friendlyFire; private byte friendlyFire;
private String[] players; private String[] players;
@ -66,14 +67,15 @@ public class Team extends DefinedPacket
friendlyFire = buf.readByte(); friendlyFire = buf.readByte();
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_21_5 ) if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_21_5 )
{ {
nameTagVisibility = Either.right( NameTagVisibility.BY_ID[readVarInt( buf )] ); nameTagVisibility = NameTagVisibility.BY_ID[readVarInt( buf )];
collisionRule = Either.right( CollisionRule.BY_ID[readVarInt( buf )] ); collisionRule = CollisionRule.BY_ID[readVarInt( buf )];
} else } else
{ {
nameTagVisibility = Either.left( readString( buf ) ); nameTagVisibility = readStringMapKey( buf, NameTagVisibility.BY_NAME );
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_9 ) if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_9 )
{ {
collisionRule = Either.left( readString( buf ) ); collisionRule = readStringMapKey( buf, CollisionRule.BY_NAME );
} }
} }
color = ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 ) ? readVarInt( buf ) : buf.readByte(); color = ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 ) ? readVarInt( buf ) : buf.readByte();
@ -110,14 +112,14 @@ public class Team extends DefinedPacket
buf.writeByte( friendlyFire ); buf.writeByte( friendlyFire );
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_21_5 ) if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_21_5 )
{ {
writeVarInt( nameTagVisibility.getRight().ordinal(), buf ); writeVarInt( nameTagVisibility.ordinal(), buf );
writeVarInt( collisionRule.getRight().ordinal(), buf ); writeVarInt( collisionRule.ordinal(), buf );
} else } else
{ {
writeString( nameTagVisibility.getLeft(), buf ); writeString( nameTagVisibility.getKey(), buf );
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_9 ) if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_9 )
{ {
writeString( collisionRule.getLeft(), buf ); writeString( collisionRule.getKey(), buf );
} }
} }
@ -155,11 +157,29 @@ public class Team extends DefinedPacket
ALWAYS( "always" ), ALWAYS( "always" ),
NEVER( "never" ), NEVER( "never" ),
HIDE_FOR_OTHER_TEAMS( "hideForOtherTeams" ), HIDE_FOR_OTHER_TEAMS( "hideForOtherTeams" ),
HIDE_FOR_OWN_TEAM( "hideForOwnTeam" ); HIDE_FOR_OWN_TEAM( "hideForOwnTeam" ),
// 1.9 (and possibly other versions) appear to treat unknown values differently (always render rather than subject to spectator mode, friendly invisibles, etc).
// we allow the empty value to achieve this in case it is potentially useful even though this is unsupported and its usage may be a bug (#3780).
UNKNOWN( "" );
// //
private final String key; private final String key;
// //
private static final NameTagVisibility[] BY_ID = values(); private static final Map<String, NameTagVisibility> BY_NAME;
private static final NameTagVisibility[] BY_ID;
static
{
NameTagVisibility[] values = NameTagVisibility.values();
ImmutableMap.Builder<String, NameTagVisibility> builder = ImmutableMap.builderWithExpectedSize( values.length );
for ( NameTagVisibility e : values )
{
builder.put( e.key, e );
}
BY_NAME = builder.build();
BY_ID = Arrays.copyOf( values, values.length - 1 ); // Ignore dummy UNKNOWN value
}
} }
@Getter @Getter
@ -174,6 +194,20 @@ public class Team extends DefinedPacket
// //
private final String key; private final String key;
// //
private static final CollisionRule[] BY_ID = CollisionRule.values(); private static final Map<String, CollisionRule> BY_NAME;
private static final CollisionRule[] BY_ID;
static
{
CollisionRule[] values = BY_ID = CollisionRule.values();
ImmutableMap.Builder<String, CollisionRule> builder = ImmutableMap.builderWithExpectedSize( values.length );
for ( CollisionRule e : values )
{
builder.put( e.key, e );
}
BY_NAME = builder.build();
}
} }
} }

View File

@ -289,11 +289,11 @@ public class DownstreamBridge extends PacketHandler
t.setPrefix( team.getPrefix().getLeftOrCompute( (component) -> con.getChatSerializer().toString( component ) ) ); t.setPrefix( team.getPrefix().getLeftOrCompute( (component) -> con.getChatSerializer().toString( component ) ) );
t.setSuffix( team.getSuffix().getLeftOrCompute( (component) -> con.getChatSerializer().toString( component ) ) ); t.setSuffix( team.getSuffix().getLeftOrCompute( (component) -> con.getChatSerializer().toString( component ) ) );
t.setFriendlyFire( team.getFriendlyFire() ); t.setFriendlyFire( team.getFriendlyFire() );
t.setNameTagVisibility( team.getNameTagVisibility().isLeft() ? team.getNameTagVisibility().getLeft() : team.getNameTagVisibility().getRight().getKey() ); t.setNameTagVisibility( team.getNameTagVisibility().getKey() );
t.setColor( team.getColor() ); t.setColor( team.getColor() );
if ( team.getCollisionRule() != null ) if ( team.getCollisionRule() != null )
{ {
t.setCollisionRule( team.getCollisionRule().isLeft() ? team.getCollisionRule().getLeft() : team.getCollisionRule().getRight().getKey() ); t.setCollisionRule( team.getCollisionRule().getKey() );
} }
} }
if ( team.getPlayers() != null ) if ( team.getPlayers() != null )

View File

@ -121,7 +121,6 @@ public class DialogSerializer implements JsonDeserializer<Dialog>, JsonSerialize
JsonObject base = (JsonObject) context.serialize( src.getBase() ); JsonObject base = (JsonObject) context.serialize( src.getBase() );
object.asMap().putAll( base.asMap() ); object.asMap().putAll( base.asMap() );
object.remove( "base" );
return object; return object;
} finally } finally

View File

@ -1,6 +1,5 @@
package net.md_5.bungee.dialog; package net.md_5.bungee.dialog;
import static org.junit.jupiter.api.Assertions.*;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.ComponentBuilder; import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.dialog.Dialog; import net.md_5.bungee.api.dialog.Dialog;
@ -12,26 +11,15 @@ import org.junit.jupiter.api.Test;
public class SimpleTest public class SimpleTest
{ {
public static void testDissembleReassemble(Dialog notice)
{
String json = VersionedComponentSerializer.getDefault().getDialogSerializer().toString( notice );
Dialog parsed = VersionedComponentSerializer.getDefault().getDialogSerializer().deserialize( json );
assertEquals( notice, parsed );
}
@Test
public void testSimple()
{
String json = "{type:\"minecraft:notice\",title:\"Hello\"}";
Dialog deserialized = VersionedComponentSerializer.getDefault().getDialogSerializer().deserialize( json );
String serialized = VersionedComponentSerializer.getDefault().getDialogSerializer().toString( deserialized );
assertEquals( "{\"type\":\"minecraft:notice\",\"title\":{\"text\":\"Hello\"}}", serialized );
}
@Test @Test
public void testNotice() public void testNotice()
{ {
testDissembleReassemble( new NoticeDialog( new DialogBase( new ComponentBuilder( "Hello" ).color( ChatColor.RED ).build() ) ) ); String json = "{type:\"minecraft:notice\",title:\"Hello\"}";
Dialog deserialized = VersionedComponentSerializer.getDefault().getDialogSerializer().deserialize( json );
System.err.println( deserialized );
Dialog notice = new NoticeDialog( new DialogBase( new ComponentBuilder( "Hello" ).color( ChatColor.RED ).build() ) );
String newJson = VersionedComponentSerializer.getDefault().getDialogSerializer().toString( notice );
System.err.println( newJson );
} }
} }