Compare commits

..

6 Commits

Author SHA1 Message Date
87b3d814dd new event TabCompleteRequestEvent and deprecate TabCompleteEvent 2023-10-07 17:32:18 +02:00
7b45fdcf98 Add CommandsDeclareEvent to declare commands with brigadier API 2023-10-07 17:32:18 +02:00
4dde9b0e5e Server branding now includes the backend server name 2023-10-07 17:32:18 +02:00
7022c64432 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.
2023-10-07 17:32:18 +02:00
d2dd9089e3 Change projet configuration and POM for Pandacube 2023-10-07 17:32:18 +02:00
24f3f21386 Remove modules and startup delay
We don’t need them for Pandacube
2023-10-07 17:32:12 +02:00
61 changed files with 338 additions and 1210 deletions

View File

@ -105,13 +105,13 @@ public class ServerPing
@Deprecated @Deprecated
public ServerPing(Protocol version, Players players, String description, String favicon) public ServerPing(Protocol version, Players players, String description, String favicon)
{ {
this( version, players, TextComponent.fromLegacy( description ), favicon == null ? null : Favicon.create( favicon ) ); this( version, players, new TextComponent( TextComponent.fromLegacyText( description ) ), favicon == null ? null : Favicon.create( favicon ) );
} }
@Deprecated @Deprecated
public ServerPing(Protocol version, Players players, String description, Favicon favicon) public ServerPing(Protocol version, Players players, String description, Favicon favicon)
{ {
this( version, players, TextComponent.fromLegacy( description ), favicon ); this( version, players, new TextComponent( TextComponent.fromLegacyText( description ) ), favicon );
} }
@Deprecated @Deprecated
@ -139,7 +139,7 @@ public class ServerPing
@Deprecated @Deprecated
public void setDescription(String description) public void setDescription(String description)
{ {
this.description = TextComponent.fromLegacy( description ); this.description = new TextComponent( TextComponent.fromLegacyText( description ) );
} }
@Deprecated @Deprecated

View File

@ -334,9 +334,6 @@ public interface ProxiedPlayer extends Connection, CommandSender
* Get the {@link Scoreboard} that belongs to this player. * Get the {@link Scoreboard} that belongs to this player.
* *
* @return this player's {@link Scoreboard} * @return this player's {@link Scoreboard}
* @deprecated for internal use only, setters will not have the expected
* effect, will not update client state, and may corrupt proxy state
*/ */
@Deprecated
Scoreboard getScoreboard(); Scoreboard getScoreboard();
} }

View File

@ -1,7 +1,9 @@
package net.md_5.bungee.api.event; package net.md_5.bungee.api.event;
import lombok.AccessLevel;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import net.md_5.bungee.api.Callback; import net.md_5.bungee.api.Callback;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
@ -25,7 +27,8 @@ public class LoginEvent extends AsyncEvent<LoginEvent> implements Cancellable
/** /**
* Message to use when kicking if this event is canceled. * Message to use when kicking if this event is canceled.
*/ */
private BaseComponent reason; @Setter(AccessLevel.NONE)
private BaseComponent[] cancelReasonComponents;
/** /**
* Connection attempting to login. * Connection attempting to login.
*/ */
@ -39,44 +42,28 @@ public class LoginEvent extends AsyncEvent<LoginEvent> implements Cancellable
/** /**
* @return reason to be displayed * @return reason to be displayed
* @deprecated use component methods instead * @deprecated Use component methods instead.
*/ */
@Deprecated @Deprecated
public String getCancelReason() public String getCancelReason()
{ {
return TextComponent.toLegacyText( getReason() ); return BaseComponent.toLegacyText( getCancelReasonComponents() );
} }
/** /**
* @param cancelReason reason to be displayed * @param cancelReason reason to be displayed
* @deprecated use component methods instead * @deprecated Use
* {@link #setCancelReason(net.md_5.bungee.api.chat.BaseComponent...)}
* instead.
*/ */
@Deprecated @Deprecated
public void setCancelReason(String cancelReason) public void setCancelReason(String cancelReason)
{ {
setReason( TextComponent.fromLegacy( cancelReason ) ); setCancelReason( TextComponent.fromLegacyText( cancelReason ) );
} }
/**
* @return reason to be displayed
* @deprecated use single component methods instead
*/
@Deprecated
public BaseComponent[] getCancelReasonComponents()
{
return new BaseComponent[]
{
getReason()
};
}
/**
* @param cancelReason reason to be displayed
* @deprecated use single component methods instead
*/
@Deprecated
public void setCancelReason(BaseComponent... cancelReason) public void setCancelReason(BaseComponent... cancelReason)
{ {
setReason( TextComponent.fromArray( cancelReason ) ); this.cancelReasonComponents = cancelReason;
} }
} }

View File

@ -1,7 +1,9 @@
package net.md_5.bungee.api.event; package net.md_5.bungee.api.event;
import lombok.AccessLevel;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import net.md_5.bungee.api.Callback; import net.md_5.bungee.api.Callback;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
@ -30,7 +32,8 @@ public class PreLoginEvent extends AsyncEvent<PreLoginEvent> implements Cancella
/** /**
* Message to use when kicking if this event is canceled. * Message to use when kicking if this event is canceled.
*/ */
private BaseComponent reason; @Setter(AccessLevel.NONE)
private BaseComponent[] cancelReasonComponents;
/** /**
* Connection attempting to login. * Connection attempting to login.
*/ */
@ -44,44 +47,28 @@ public class PreLoginEvent extends AsyncEvent<PreLoginEvent> implements Cancella
/** /**
* @return reason to be displayed * @return reason to be displayed
* @deprecated use component methods instead * @deprecated Use component methods instead.
*/ */
@Deprecated @Deprecated
public String getCancelReason() public String getCancelReason()
{ {
return BaseComponent.toLegacyText( getReason() ); return BaseComponent.toLegacyText( getCancelReasonComponents() );
} }
/** /**
* @param cancelReason reason to be displayed * @param cancelReason reason to be displayed
* @deprecated Use component methods instead * @deprecated Use
* {@link #setCancelReason(net.md_5.bungee.api.chat.BaseComponent...)}
* instead.
*/ */
@Deprecated @Deprecated
public void setCancelReason(String cancelReason) public void setCancelReason(String cancelReason)
{ {
setReason( TextComponent.fromLegacy( cancelReason ) ); setCancelReason( TextComponent.fromLegacyText( cancelReason ) );
} }
/**
* @return reason to be displayed
* @deprecated use single component methods instead
*/
@Deprecated
public BaseComponent[] getCancelReasonComponents()
{
return new BaseComponent[]
{
getReason()
};
}
/**
* @param cancelReason reason to be displayed
* @deprecated use single component methods instead
*/
@Deprecated
public void setCancelReason(BaseComponent... cancelReason) public void setCancelReason(BaseComponent... cancelReason)
{ {
setReason( TextComponent.fromArray( cancelReason ) ); this.cancelReasonComponents = cancelReason;
} }
} }

View File

@ -35,7 +35,7 @@ public class ServerKickEvent extends Event implements Cancellable
/** /**
* Kick reason. * Kick reason.
*/ */
private BaseComponent reason; private BaseComponent[] kickReasonComponent;
/** /**
* Server to send player to if this event is cancelled. * Server to send player to if this event is cancelled.
*/ */
@ -63,61 +63,24 @@ public class ServerKickEvent extends Event implements Cancellable
this( player, player.getServer().getInfo(), kickReasonComponent, cancelServer, state ); this( player, player.getServer().getInfo(), kickReasonComponent, cancelServer, state );
} }
@Deprecated
public ServerKickEvent(ProxiedPlayer player, ServerInfo kickedFrom, BaseComponent[] kickReasonComponent, ServerInfo cancelServer, State state) public ServerKickEvent(ProxiedPlayer player, ServerInfo kickedFrom, BaseComponent[] kickReasonComponent, ServerInfo cancelServer, State state)
{
this( player, kickedFrom, TextComponent.fromArray( kickReasonComponent ), cancelServer, state );
}
public ServerKickEvent(ProxiedPlayer player, ServerInfo kickedFrom, BaseComponent reason, ServerInfo cancelServer, State state)
{ {
this.player = player; this.player = player;
this.kickedFrom = kickedFrom; this.kickedFrom = kickedFrom;
this.reason = reason; this.kickReasonComponent = kickReasonComponent;
this.cancelServer = cancelServer; this.cancelServer = cancelServer;
this.state = state; this.state = state;
} }
/**
* @return the kick reason
* @deprecated use component methods instead
*/
@Deprecated @Deprecated
public String getKickReason() public String getKickReason()
{ {
return BaseComponent.toLegacyText( getReason() ); return BaseComponent.toLegacyText( kickReasonComponent );
} }
/**
* @param reason the kick reason
* @deprecated use component methods instead
*/
@Deprecated @Deprecated
public void setKickReason(String reason) public void setKickReason(String reason)
{ {
this.setReason( TextComponent.fromLegacy( reason ) ); kickReasonComponent = TextComponent.fromLegacyText( reason );
}
/**
* @return the kick reason
* @deprecated use single component methods instead
*/
@Deprecated
public BaseComponent[] getKickReasonComponent()
{
return new BaseComponent[]
{
getReason()
};
}
/**
* @param kickReasonComponent the kick reason
* @deprecated use single component methods instead
*/
@Deprecated
public void setKickReasonComponent(BaseComponent[] kickReasonComponent)
{
this.setReason( TextComponent.fromArray( kickReasonComponent ) );
} }
} }

View File

@ -204,33 +204,6 @@ public final class ComponentBuilder
return this; return this;
} }
/**
* Appends the {@link TranslationProvider} object to the builder and makes
* the last element the current target for formatting. The components will
* have all the formatting from previous part.
*
* @param translatable the translatable object to append
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder append(TranslationProvider translatable)
{
return append( translatable, FormatRetention.ALL );
}
/**
* Appends the {@link TranslationProvider} object to the builder and makes
* the last element the current target for formatting. You can specify the
* amount of formatting retained from previous part.
*
* @param translatable the translatable object to append
* @param retention the formatting to retain
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder append(TranslationProvider translatable, FormatRetention retention)
{
return append( translatable.asTranslatableComponent(), retention );
}
/** /**
* Appends the text to the builder and makes it the current target for * Appends the text to the builder and makes it the current target for
* formatting. The text will have all the formatting from previous part. * formatting. The text will have all the formatting from previous part.
@ -482,8 +455,8 @@ public final class ComponentBuilder
} }
/** /**
* Returns the component built by this builder. If this builder is empty, an * Returns the component built by this builder. If this builder is
* empty text component will be returned. * empty, an empty text component will be returned.
* *
* @return the component * @return the component
*/ */
@ -505,8 +478,8 @@ public final class ComponentBuilder
* <p> * <p>
* <strong>NOTE:</strong> {@link #build()} is preferred as it will * <strong>NOTE:</strong> {@link #build()} is preferred as it will
* consolidate all components into a single BaseComponent with extra * consolidate all components into a single BaseComponent with extra
* contents as opposed to an array of components which is non-standard and * contents as opposed to an array of components which is non-standard
* may result in unexpected behavior. * and may result in unexpected behavior.
* *
* @return the created components * @return the created components
*/ */

View File

@ -2,7 +2,6 @@ package net.md_5.bungee.api.chat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.function.Consumer;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@ -28,41 +27,6 @@ public final class TextComponent extends BaseComponent
* @param message the text to convert * @param message the text to convert
* @return the components needed to print the message to the client * @return the components needed to print the message to the client
*/ */
public static BaseComponent fromLegacy(String message)
{
return fromLegacy( message, ChatColor.WHITE );
}
/**
* Converts the old formatting system that used
* {@link net.md_5.bungee.api.ChatColor#COLOR_CHAR} into the new json based
* system.
*
* @param message the text to convert
* @param defaultColor color to use when no formatting is to be applied
* (i.e. after ChatColor.RESET).
* @return the components needed to print the message to the client
*/
public static BaseComponent fromLegacy(String message, ChatColor defaultColor)
{
ComponentBuilder componentBuilder = new ComponentBuilder();
populateComponentStructure( message, defaultColor, componentBuilder::append );
return componentBuilder.build();
}
/**
* Converts the old formatting system that used
* {@link net.md_5.bungee.api.ChatColor#COLOR_CHAR} into the new json based
* system.
*
* @param message the text to convert
* @return the components needed to print the message to the client
* @deprecated {@link #fromLegacy(String)} is preferred as it will
* consolidate all components into a single BaseComponent with extra
* contents as opposed to an array of components which is non-standard and
* may result in unexpected behavior.
*/
@Deprecated
public static BaseComponent[] fromLegacyText(String message) public static BaseComponent[] fromLegacyText(String message)
{ {
return fromLegacyText( message, ChatColor.WHITE ); return fromLegacyText( message, ChatColor.WHITE );
@ -77,21 +41,10 @@ public final class TextComponent extends BaseComponent
* @param defaultColor color to use when no formatting is to be applied * @param defaultColor color to use when no formatting is to be applied
* (i.e. after ChatColor.RESET). * (i.e. after ChatColor.RESET).
* @return the components needed to print the message to the client * @return the components needed to print the message to the client
* @deprecated {@link #fromLegacy(String, ChatColor)} is preferred as it
* will consolidate all components into a single BaseComponent with extra
* contents as opposed to an array of components which is non-standard and
* may result in unexpected behavior.
*/ */
@Deprecated
public static BaseComponent[] fromLegacyText(String message, ChatColor defaultColor) public static BaseComponent[] fromLegacyText(String message, ChatColor defaultColor)
{ {
ArrayList<BaseComponent> components = new ArrayList<>(); ArrayList<BaseComponent> components = new ArrayList<>();
populateComponentStructure( message, defaultColor, components::add );
return components.toArray( new BaseComponent[ 0 ] );
}
private static void populateComponentStructure(String message, ChatColor defaultColor, Consumer<BaseComponent> appender)
{
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
TextComponent component = new TextComponent(); TextComponent component = new TextComponent();
Matcher matcher = url.matcher( message ); Matcher matcher = url.matcher( message );
@ -141,7 +94,7 @@ public final class TextComponent extends BaseComponent
component = new TextComponent( old ); component = new TextComponent( old );
old.setText( builder.toString() ); old.setText( builder.toString() );
builder = new StringBuilder(); builder = new StringBuilder();
appender.accept( old ); components.add( old );
} }
if ( format == ChatColor.BOLD ) if ( format == ChatColor.BOLD )
{ {
@ -184,7 +137,7 @@ public final class TextComponent extends BaseComponent
component = new TextComponent( old ); component = new TextComponent( old );
old.setText( builder.toString() ); old.setText( builder.toString() );
builder = new StringBuilder(); builder = new StringBuilder();
appender.accept( old ); components.add( old );
} }
TextComponent old = component; TextComponent old = component;
@ -193,7 +146,7 @@ public final class TextComponent extends BaseComponent
component.setText( urlString ); component.setText( urlString );
component.setClickEvent( new ClickEvent( ClickEvent.Action.OPEN_URL, component.setClickEvent( new ClickEvent( ClickEvent.Action.OPEN_URL,
urlString.startsWith( "http" ) ? urlString : "http://" + urlString ) ); urlString.startsWith( "http" ) ? urlString : "http://" + urlString ) );
appender.accept( component ); components.add( component );
i += pos - i - 1; i += pos - i - 1;
component = old; component = old;
continue; continue;
@ -202,29 +155,9 @@ public final class TextComponent extends BaseComponent
} }
component.setText( builder.toString() ); component.setText( builder.toString() );
appender.accept( component ); components.add( component );
}
/** return components.toArray( new BaseComponent[ 0 ] );
* Internal compatibility method to transform an array of components to a
* single component.
*
* @param components array
* @return single component
*/
public static BaseComponent fromArray(BaseComponent... components)
{
if ( components == null )
{
return null;
}
if ( components.length == 1 )
{
return components[0];
}
return new TextComponent( components );
} }
/** /**

View File

@ -86,21 +86,6 @@ public final class TranslatableComponent extends BaseComponent
} }
} }
/**
* Creates a translatable component with the passed substitutions
*
* @param translatable the translatable object
* @param with the {@link java.lang.String}s and
* {@link net.md_5.bungee.api.chat.BaseComponent}s to use into the
* translation
* @see #translate
* @see #setWith(java.util.List)
*/
public TranslatableComponent(TranslationProvider translatable, Object... with)
{
this( translatable.getTranslationKey(), with );
}
/** /**
* Creates a duplicate of this TranslatableComponent. * Creates a duplicate of this TranslatableComponent.
* *

View File

@ -1,38 +0,0 @@
package net.md_5.bungee.api.chat;
/**
* An object capable of being translated by the client in a
* {@link TranslatableComponent}.
*/
public interface TranslationProvider
{
/**
* Get the translation key.
*
* @return the translation key
*/
String getTranslationKey();
/**
* Get this translatable object as a {@link TranslatableComponent}.
*
* @return the translatable component
*/
default TranslatableComponent asTranslatableComponent()
{
return asTranslatableComponent( (Object[]) null );
}
/**
* Get this translatable object as a {@link TranslatableComponent}.
*
* @param with the {@link String Strings} and
* {@link BaseComponent BaseComponents} to use in the translation
* @return the translatable component
*/
default TranslatableComponent asTranslatableComponent(Object... with)
{
return new TranslatableComponent( this, with );
}
}

View File

@ -26,10 +26,7 @@ public class Text extends Content
public Text(BaseComponent value) public Text(BaseComponent value)
{ {
// For legacy serialization reasons, this has to be an array of components // For legacy serialization reasons, this has to be an array of components
this( new BaseComponent[] this( new BaseComponent[]{value} );
{
value
} );
} }
public Text(String value) public Text(String value)

View File

@ -5,7 +5,6 @@ import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializationContext;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -21,51 +20,27 @@ import net.md_5.bungee.api.chat.hover.content.Content;
public class BaseComponentSerializer public class BaseComponentSerializer
{ {
private static boolean getAsBoolean(JsonElement el)
{
if ( el.isJsonPrimitive() )
{
JsonPrimitive primitive = (JsonPrimitive) el;
if ( primitive.isBoolean() )
{
return primitive.getAsBoolean();
}
if ( primitive.isNumber() )
{
Number number = primitive.getAsNumber();
if ( number instanceof Byte )
{
return number.byteValue() != 0;
}
}
}
return false;
}
protected void deserialize(JsonObject object, BaseComponent component, JsonDeserializationContext context) protected void deserialize(JsonObject object, BaseComponent component, JsonDeserializationContext context)
{ {
if ( object.has( "bold" ) ) if ( object.has( "bold" ) )
{ {
component.setBold( getAsBoolean( object.get( "bold" ) ) ); component.setBold( object.get( "bold" ).getAsBoolean() );
} }
if ( object.has( "italic" ) ) if ( object.has( "italic" ) )
{ {
component.setItalic( getAsBoolean( object.get( "italic" ) ) ); component.setItalic( object.get( "italic" ).getAsBoolean() );
} }
if ( object.has( "underlined" ) ) if ( object.has( "underlined" ) )
{ {
component.setUnderlined( getAsBoolean( object.get( "underlined" ) ) ); component.setUnderlined( object.get( "underlined" ).getAsBoolean() );
} }
if ( object.has( "strikethrough" ) ) if ( object.has( "strikethrough" ) )
{ {
component.setStrikethrough( getAsBoolean( object.get( "strikethrough" ) ) ); component.setStrikethrough( object.get( "strikethrough" ).getAsBoolean() );
} }
if ( object.has( "obfuscated" ) ) if ( object.has( "obfuscated" ) )
{ {
component.setObfuscated( getAsBoolean( object.get( "obfuscated" ) ) ); component.setObfuscated( object.get( "obfuscated" ).getAsBoolean() );
} }
if ( object.has( "color" ) ) if ( object.has( "color" ) )
{ {

View File

@ -2,14 +2,12 @@ package net.md_5.bungee.chat;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer; import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Set; import java.util.Set;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
@ -46,17 +44,16 @@ public class ComponentSerializer implements JsonDeserializer<BaseComponent>
/** /**
* Parse a JSON-compliant String as an array of base components. The input * Parse a JSON-compliant String as an array of base components. The input
* can be one of either an array of components, or a single component * can be one of either an array of components, or a single component object.
* object. If the input is an array, each component will be parsed * If the input is an array, each component will be parsed individually and
* individually and returned in the order that they were parsed. If the * returned in the order that they were parsed. If the input is a single
* input is a single component object, a single-valued array with the * component object, a single-valued array with the component will be returned.
* component will be returned.
* <p> * <p>
* <strong>NOTE:</strong> {@link #deserialize(String)} is preferred as it * <strong>NOTE:</strong> {@link #deserialize(String)} is preferred as it will
* will parse only one component as opposed to an array of components which * parse only one component as opposed to an array of components which is non-
* is non- standard behavior. This method is still appropriate for parsing * standard behavior. This method is still appropriate for parsing multiple
* multiple components at once, although such use case is rarely (if at all) * components at once, although such use case is rarely (if at all) exhibited
* exhibited in vanilla Minecraft. * in vanilla Minecraft.
* *
* @param json the component json to parse * @param json the component json to parse
* @return an array of all parsed components * @return an array of all parsed components
@ -78,51 +75,25 @@ public class ComponentSerializer implements JsonDeserializer<BaseComponent>
} }
/** /**
* Deserialize a JSON-compliant String as a single component. * Deserialize a JSON-compliant String as a single component. The input is
* expected to be a JSON object that represents only one component.
* *
* @param json the component json to parse * @param json the component json to parse
* @return the deserialized component * @return the deserialized component
* @throws IllegalArgumentException if anything other than a valid JSON * @throws IllegalArgumentException if anything other than a JSON object is
* component string is passed as input * passed as input
*/ */
public static BaseComponent deserialize(String json) public static BaseComponent deserialize(String json)
{ {
JsonElement jsonElement = JsonParser.parseString( json ); JsonElement jsonElement = JsonParser.parseString( json );
if ( !jsonElement.isJsonObject() )
return deserialize( jsonElement );
}
/**
* Deserialize a JSON element as a single component.
*
* @param jsonElement the component json to parse
* @return the deserialized component
* @throws IllegalArgumentException if anything other than a valid JSON
* component is passed as input
*/
public static BaseComponent deserialize(JsonElement jsonElement)
{ {
if ( jsonElement instanceof JsonPrimitive ) throw new IllegalArgumentException( "Malformatted JSON. Expected object, got array for input \"" + json + "\"." );
{
JsonPrimitive primitive = (JsonPrimitive) jsonElement;
if ( primitive.isString() )
{
return new TextComponent( primitive.getAsString() );
}
} else if ( jsonElement instanceof JsonArray )
{
BaseComponent[] array = gson.fromJson( jsonElement, BaseComponent[].class );
return TextComponent.fromArray( array );
} }
return gson.fromJson( jsonElement, BaseComponent.class ); return gson.fromJson( jsonElement, BaseComponent.class );
} }
public static JsonElement toJson(BaseComponent component)
{
return gson.toJsonTree( component );
}
public static String toString(Object object) public static String toString(Object object)
{ {
return gson.toJson( object ); return gson.toJson( object );

View File

@ -18,10 +18,11 @@ public class TextComponentSerializer extends BaseComponentSerializer implements
{ {
TextComponent component = new TextComponent(); TextComponent component = new TextComponent();
JsonObject object = json.getAsJsonObject(); JsonObject object = json.getAsJsonObject();
if ( object.has( "text" ) ) if ( !object.has( "text" ) )
{ {
component.setText( object.get( "text" ).getAsString() ); throw new JsonParseException( "Could not parse JSON: missing 'text' property" );
} }
component.setText( object.get( "text" ).getAsString() );
deserialize( object, component, context ); deserialize( object, component, context );
return component; return component;
} }

View File

@ -1,11 +1,11 @@
package net.md_5.bungee.chat; package net.md_5.bungee.chat;
import com.google.common.base.Charsets;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -102,7 +102,7 @@ public final class TranslationRegistry
public JsonProvider(String resourcePath) throws IOException public JsonProvider(String resourcePath) throws IOException
{ {
try ( InputStreamReader rd = new InputStreamReader( JsonProvider.class.getResourceAsStream( resourcePath ), StandardCharsets.UTF_8 ) ) try ( InputStreamReader rd = new InputStreamReader( JsonProvider.class.getResourceAsStream( resourcePath ), Charsets.UTF_8 ) )
{ {
JsonObject obj = new Gson().fromJson( rd, JsonObject.class ); JsonObject obj = new Gson().fromJson( rd, JsonObject.class );
for ( Map.Entry<String, JsonElement> entries : obj.entrySet() ) for ( Map.Entry<String, JsonElement> entries : obj.entrySet() )

View File

@ -8,6 +8,7 @@ import java.util.function.Function;
import java.util.function.ObjIntConsumer; import java.util.function.ObjIntConsumer;
import java.util.function.Supplier; import java.util.function.Supplier;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.hover.content.Item;
import net.md_5.bungee.api.chat.hover.content.Text; import net.md_5.bungee.api.chat.hover.content.Text;
import net.md_5.bungee.chat.ComponentSerializer; import net.md_5.bungee.chat.ComponentSerializer;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -71,8 +72,6 @@ public class ComponentsTest
assertEquals( hoverVal, ComponentSerializer.toString( (BaseComponent[]) contentText.getValue() ) ); assertEquals( hoverVal, ComponentSerializer.toString( (BaseComponent[]) contentText.getValue() ) );
testDissembleReassemble( components ); testDissembleReassemble( components );
////////// //////////
// TODO: now ambiguous since "text" to distinguish Text from Item is not required
/*
TextComponent component1 = new TextComponent( "HoverableText" ); TextComponent component1 = new TextComponent( "HoverableText" );
String nbt = "{display:{Name:{text:Hello},Lore:[{text:Line_1},{text:Line_2}]},ench:[{id:49,lvl:5}],Unbreakable:1}}"; String nbt = "{display:{Name:{text:Hello},Lore:[{text:Line_1},{text:Line_2}]},ench:[{id:49,lvl:5}],Unbreakable:1}}";
Item contentItem = new Item( "minecraft:wood", 1, ItemTag.ofNbt( nbt ) ); Item contentItem = new Item( "minecraft:wood", 1, ItemTag.ofNbt( nbt ) );
@ -85,7 +84,6 @@ public class ComponentsTest
assertEquals( contentItem.getCount(), parsedContentItem.getCount() ); assertEquals( contentItem.getCount(), parsedContentItem.getCount() );
assertEquals( contentItem.getId(), parsedContentItem.getId() ); assertEquals( contentItem.getId(), parsedContentItem.getId() );
assertEquals( nbt, parsedContentItem.getTag().getNbt() ); assertEquals( nbt, parsedContentItem.getTag().getNbt() );
*/
} }
@Test @Test
@ -563,7 +561,8 @@ public class ComponentsTest
this.testBuilder( this.testBuilder(
ComponentBuilder::create, ComponentBuilder::create,
BaseComponent::toPlainText, BaseComponent::toPlainText,
ChatColor.RED + "Hello " + ChatColor.BLUE + ChatColor.BOLD + "World" + ChatColor.YELLOW + ChatColor.BOLD + "!", ChatColor.RED + "Hello " + ChatColor.BLUE + ChatColor.BOLD
+ "World" + ChatColor.YELLOW + ChatColor.BOLD + "!",
BaseComponent::toLegacyText BaseComponent::toLegacyText
); );
} }
@ -575,7 +574,8 @@ public class ComponentsTest
ComponentBuilder::build, ComponentBuilder::build,
(component) -> BaseComponent.toPlainText( component ), (component) -> BaseComponent.toPlainText( component ),
// An extra format code is appended to the beginning because there is an empty TextComponent at the start of every component // An extra format code is appended to the beginning because there is an empty TextComponent at the start of every component
ChatColor.WHITE.toString() + ChatColor.RED + "Hello " + ChatColor.BLUE + ChatColor.BOLD + "World" + ChatColor.YELLOW + ChatColor.BOLD + "!", ChatColor.WHITE.toString() + ChatColor.RED + "Hello " + ChatColor.BLUE + ChatColor.BOLD
+ "World" + ChatColor.YELLOW + ChatColor.BOLD + "!",
(component) -> BaseComponent.toLegacyText( component ) (component) -> BaseComponent.toLegacyText( component )
); );
} }

View File

@ -1,5 +1,6 @@
package net.md_5.bungee.config; package net.md_5.bungee.config;
import com.google.common.base.Charsets;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
@ -15,7 +16,6 @@ import java.io.OutputStreamWriter;
import java.io.Reader; import java.io.Reader;
import java.io.Writer; import java.io.Writer;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import lombok.AccessLevel; import lombok.AccessLevel;
@ -37,7 +37,7 @@ public class JsonConfiguration extends ConfigurationProvider
@Override @Override
public void save(Configuration config, File file) throws IOException public void save(Configuration config, File file) throws IOException
{ {
try ( Writer writer = new OutputStreamWriter( new FileOutputStream( file ), StandardCharsets.UTF_8 ) ) try ( Writer writer = new OutputStreamWriter( new FileOutputStream( file ), Charsets.UTF_8 ) )
{ {
save( config, writer ); save( config, writer );
} }
@ -91,7 +91,7 @@ public class JsonConfiguration extends ConfigurationProvider
@Override @Override
public Configuration load(InputStream is, Configuration defaults) public Configuration load(InputStream is, Configuration defaults)
{ {
return load( new InputStreamReader( is, StandardCharsets.UTF_8 ), defaults ); return load( new InputStreamReader( is, Charsets.UTF_8 ), defaults );
} }
@Override @Override

View File

@ -1,5 +1,6 @@
package net.md_5.bungee.config; package net.md_5.bungee.config;
import com.google.common.base.Charsets;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
@ -8,7 +9,6 @@ import java.io.InputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.Reader; import java.io.Reader;
import java.io.Writer; import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import lombok.AccessLevel; import lombok.AccessLevel;
@ -54,7 +54,7 @@ public class YamlConfiguration extends ConfigurationProvider
@Override @Override
public void save(Configuration config, File file) throws IOException public void save(Configuration config, File file) throws IOException
{ {
try ( Writer writer = new OutputStreamWriter( new FileOutputStream( file ), StandardCharsets.UTF_8 ) ) try ( Writer writer = new OutputStreamWriter( new FileOutputStream( file ), Charsets.UTF_8 ) )
{ {
save( config, writer ); save( config, writer );
} }

View File

@ -1,8 +1,8 @@
package net.md_5.bungee.log; package net.md_5.bungee.log;
import com.google.common.base.Charsets;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@ -19,7 +19,7 @@ public class LoggingOutputStream extends ByteArrayOutputStream
@Override @Override
public void flush() throws IOException public void flush() throws IOException
{ {
String contents = toString( StandardCharsets.UTF_8.name() ); String contents = toString( Charsets.UTF_8.name() );
super.reset(); super.reset();
if ( !contents.isEmpty() && !contents.equals( separator ) ) if ( !contents.isEmpty() && !contents.equals( separator ) )
{ {

View File

@ -82,7 +82,7 @@
<dependency> <dependency>
<groupId>io.netty</groupId> <groupId>io.netty</groupId>
<artifactId>netty-bom</artifactId> <artifactId>netty-bom</artifactId>
<version>4.1.100.Final</version> <version>4.1.99.Final</version>
<type>pom</type> <type>pom</type>
<scope>import</scope> <scope>import</scope>
</dependency> </dependency>
@ -92,7 +92,7 @@
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId> <artifactId>junit-jupiter</artifactId>
<version>5.10.1</version> <version>5.10.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -121,7 +121,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId> <artifactId>maven-javadoc-plugin</artifactId>
<version>3.6.2</version> <version>3.6.0</version>
</plugin> </plugin>
</plugins> </plugins>
</pluginManagement> </pluginManagement>
@ -150,7 +150,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId> <artifactId>maven-checkstyle-plugin</artifactId>
<version>3.3.1</version> <version>3.3.0</version>
<executions> <executions>
<execution> <execution>
<phase>process-classes</phase> <phase>process-classes</phase>

View File

@ -17,20 +17,26 @@
<name>BungeeCord-Protocol</name> <name>BungeeCord-Protocol</name>
<description>Minimal implementation of the Minecraft protocol for use in BungeeCord</description> <description>Minimal implementation of the Minecraft protocol for use in BungeeCord</description>
<!-- We really shouldn't depend on external repositories --> <!-- We really shouldn't depend on external repositories, but at least this is the Central staging one -->
<repositories> <repositories>
<repository> <repository>
<id>minecraft-libraries</id> <id>sonatype-nexus-snapshots</id>
<name>Minecraft Libraries</name> <name>Sonatype Nexus Snapshots</name>
<url>https://libraries.minecraft.net/</url> <url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository> </repository>
</repositories> </repositories>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>com.mojang</groupId> <groupId>net.md-5</groupId>
<artifactId>brigadier</artifactId> <artifactId>brigadier</artifactId>
<version>1.2.9</version> <version>1.0.16-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -34,7 +34,6 @@ import net.md_5.bungee.protocol.packet.Respawn;
import net.md_5.bungee.protocol.packet.ScoreboardDisplay; import net.md_5.bungee.protocol.packet.ScoreboardDisplay;
import net.md_5.bungee.protocol.packet.ScoreboardObjective; import net.md_5.bungee.protocol.packet.ScoreboardObjective;
import net.md_5.bungee.protocol.packet.ScoreboardScore; import net.md_5.bungee.protocol.packet.ScoreboardScore;
import net.md_5.bungee.protocol.packet.ScoreboardScoreReset;
import net.md_5.bungee.protocol.packet.ServerData; import net.md_5.bungee.protocol.packet.ServerData;
import net.md_5.bungee.protocol.packet.SetCompression; import net.md_5.bungee.protocol.packet.SetCompression;
import net.md_5.bungee.protocol.packet.StartConfiguration; import net.md_5.bungee.protocol.packet.StartConfiguration;
@ -144,10 +143,6 @@ public abstract class AbstractPacketHandler
{ {
} }
public void handle(ScoreboardScoreReset scoreboardScoreReset) throws Exception
{
}
public void handle(EncryptionRequest encryptionRequest) throws Exception public void handle(EncryptionRequest encryptionRequest) throws Exception
{ {
} }

View File

@ -1,25 +1,20 @@
package net.md_5.bungee.protocol; package net.md_5.bungee.protocol;
import com.google.common.base.Function; import com.google.common.base.Charsets;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.gson.JsonElement;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream; import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufOutputStream; import io.netty.buffer.ByteBufOutputStream;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.BitSet; import java.util.BitSet;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.function.BiConsumer;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import se.llbit.nbt.ErrorTag; import se.llbit.nbt.ErrorTag;
import se.llbit.nbt.NamedTag; import se.llbit.nbt.NamedTag;
import se.llbit.nbt.SpecificTag; import se.llbit.nbt.SpecificTag;
@ -29,23 +24,6 @@ import se.llbit.nbt.Tag;
public abstract class DefinedPacket public abstract class DefinedPacket
{ {
public <T> T readNullable(Function<ByteBuf, T> reader, ByteBuf buf)
{
return buf.readBoolean() ? reader.apply( buf ) : null;
}
public <T> void writeNullable(T t0, BiConsumer<T, ByteBuf> writer, ByteBuf buf)
{
if ( t0 != null )
{
buf.writeBoolean( true );
writer.accept( t0, buf );
} else
{
buf.writeBoolean( false );
}
}
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 );
@ -58,7 +36,7 @@ public abstract class DefinedPacket
throw new OverflowPacketException( "Cannot send string longer than " + maxLength + " (got " + s.length() + " characters)" ); throw new OverflowPacketException( "Cannot send string longer than " + maxLength + " (got " + s.length() + " characters)" );
} }
byte[] b = s.getBytes( StandardCharsets.UTF_8 ); byte[] b = s.getBytes( Charsets.UTF_8 );
if ( b.length > maxLength * 3 ) if ( b.length > maxLength * 3 )
{ {
throw new OverflowPacketException( "Cannot send string longer than " + ( maxLength * 3 ) + " (got " + b.length + " bytes)" ); throw new OverflowPacketException( "Cannot send string longer than " + ( maxLength * 3 ) + " (got " + b.length + " bytes)" );
@ -81,7 +59,7 @@ public abstract class DefinedPacket
throw new OverflowPacketException( "Cannot receive string longer than " + maxLen * 3 + " (got " + len + " bytes)" ); throw new OverflowPacketException( "Cannot receive string longer than " + maxLen * 3 + " (got " + len + " bytes)" );
} }
String s = buf.toString( buf.readerIndex(), len, StandardCharsets.UTF_8 ); String s = buf.toString( buf.readerIndex(), len, Charsets.UTF_8 );
buf.readerIndex( buf.readerIndex() + len ); buf.readerIndex( buf.readerIndex() + len );
if ( s.length() > maxLen ) if ( s.length() > maxLen )
@ -92,59 +70,6 @@ public abstract class DefinedPacket
return s; return s;
} }
public static Either<String, BaseComponent> readEitherBaseComponent(ByteBuf buf, int protocolVersion, boolean string)
{
return ( string ) ? Either.left( readString( buf ) ) : Either.right( readBaseComponent( buf, protocolVersion ) );
}
public static BaseComponent readBaseComponent(ByteBuf buf, int protocolVersion)
{
return readBaseComponent( buf, Short.MAX_VALUE, protocolVersion );
}
public static BaseComponent readBaseComponent(ByteBuf buf, int maxStringLength, int protocolVersion)
{
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_20_3 )
{
SpecificTag nbt = (SpecificTag) readTag( buf, protocolVersion );
JsonElement json = TagUtil.toJson( nbt );
return ComponentSerializer.deserialize( json );
} else
{
String string = readString( buf, maxStringLength );
return ComponentSerializer.deserialize( string );
}
}
public static void writeEitherBaseComponent(Either<String, BaseComponent> message, ByteBuf buf, int protocolVersion)
{
if ( message.isLeft() )
{
writeString( message.getLeft(), buf );
} else
{
writeBaseComponent( message.getRight(), buf, protocolVersion );
}
}
public static void writeBaseComponent(BaseComponent message, ByteBuf buf, int protocolVersion)
{
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_20_3 )
{
JsonElement json = ComponentSerializer.toJson( message );
SpecificTag nbt = TagUtil.fromJson( json );
writeTag( nbt, buf, protocolVersion );
} else
{
String string = ComponentSerializer.toString( message );
writeString( string, buf );
}
}
public static void writeArray(byte[] b, ByteBuf buf) public static void writeArray(byte[] b, ByteBuf buf)
{ {
if ( b.length > Short.MAX_VALUE ) if ( b.length > Short.MAX_VALUE )
@ -370,38 +295,6 @@ public abstract class DefinedPacket
return null; return null;
} }
public static void writeNumberFormat(NumberFormat format, ByteBuf buf, int protocolVersion)
{
writeVarInt( format.getType().ordinal(), buf );
switch ( format.getType() )
{
case BLANK:
break;
case STYLED:
writeBaseComponent( (BaseComponent) format.getValue(), buf, protocolVersion ); // TODO: style
break;
case FIXED:
writeBaseComponent( (BaseComponent) format.getValue(), buf, protocolVersion );
break;
}
}
public static NumberFormat readNumberFormat(ByteBuf buf, int protocolVersion)
{
int format = readVarInt( buf );
switch ( format )
{
case 0:
return new NumberFormat( NumberFormat.Type.BLANK, null );
case 1:
return new NumberFormat( NumberFormat.Type.STYLED, readBaseComponent( buf, protocolVersion ) ); // TODO: style
case 2:
return new NumberFormat( NumberFormat.Type.FIXED, readBaseComponent( buf, protocolVersion ) );
default:
throw new IllegalArgumentException( "Unknown number format " + format );
}
}
public static Tag readTag(ByteBuf input, int protocolVersion) public static Tag readTag(ByteBuf input, int protocolVersion)
{ {
DataInputStream in = new DataInputStream( new ByteBufInputStream( input ) ); DataInputStream in = new DataInputStream( new ByteBufInputStream( input ) );
@ -432,18 +325,9 @@ public abstract class DefinedPacket
public static void writeTag(Tag tag, ByteBuf output, int protocolVersion) public static void writeTag(Tag tag, ByteBuf output, int protocolVersion)
{ {
DataOutputStream out = new DataOutputStream( new ByteBufOutputStream( output ) );
try try
{ {
if ( tag instanceof SpecificTag ) tag.write( new DataOutputStream( new ByteBufOutputStream( output ) ) );
{
SpecificTag specificTag = (SpecificTag) tag;
specificTag.writeType( out );
specificTag.write( out );
} else
{
tag.write( out );
}
} catch ( IOException ex ) } catch ( IOException ex )
{ {
throw new RuntimeException( "Exception writing tag", ex ); throw new RuntimeException( "Exception writing tag", ex );
@ -502,11 +386,6 @@ public abstract class DefinedPacket
throw new UnsupportedOperationException( "Packet must implement read method" ); throw new UnsupportedOperationException( "Packet must implement read method" );
} }
public void read(ByteBuf buf, Protocol protocol, ProtocolConstants.Direction direction, int protocolVersion)
{
read( buf, direction, protocolVersion );
}
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{ {
read( buf ); read( buf );
@ -517,11 +396,6 @@ public abstract class DefinedPacket
throw new UnsupportedOperationException( "Packet must implement write method" ); throw new UnsupportedOperationException( "Packet must implement write method" );
} }
public void write(ByteBuf buf, Protocol protocol, ProtocolConstants.Direction direction, int protocolVersion)
{
write( buf, direction, protocolVersion );
}
public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{ {
write( buf ); write( buf );

View File

@ -1,34 +0,0 @@
package net.md_5.bungee.protocol;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public final class Either<L, R>
{
private final L left;
private final R right;
public boolean isLeft()
{
return this.left != null;
}
public boolean isRight()
{
return this.right != null;
}
public static <L, R> Either<L, R> left(L left)
{
return new Either<>( left, null );
}
public static <L, R> Either<L, R> right(R right)
{
return new Either<>( null, right );
}
}

View File

@ -39,7 +39,7 @@ public class MinecraftDecoder extends MessageToMessageDecoder<ByteBuf>
DefinedPacket packet = prot.createPacket( packetId, protocolVersion ); DefinedPacket packet = prot.createPacket( packetId, protocolVersion );
if ( packet != null ) if ( packet != null )
{ {
packet.read( in, protocol, prot.getDirection(), protocolVersion ); packet.read( in, prot.getDirection(), protocolVersion );
if ( in.isReadable() ) if ( in.isReadable() )
{ {

View File

@ -24,6 +24,6 @@ public class MinecraftEncoder extends MessageToByteEncoder<DefinedPacket>
{ {
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(), protocolVersion ), out ); DefinedPacket.writeVarInt( prot.getId( msg.getClass(), protocolVersion ), out );
msg.write( out, protocol, prot.getDirection(), protocolVersion ); msg.write( out, prot.getDirection(), protocolVersion );
} }
} }

View File

@ -1,18 +0,0 @@
package net.md_5.bungee.protocol;
import lombok.Data;
@Data
public class NumberFormat
{
private final Type type;
private final Object value;
public enum Type
{
BLANK,
STYLED,
FIXED;
}
}

View File

@ -40,7 +40,6 @@ import net.md_5.bungee.protocol.packet.Respawn;
import net.md_5.bungee.protocol.packet.ScoreboardDisplay; import net.md_5.bungee.protocol.packet.ScoreboardDisplay;
import net.md_5.bungee.protocol.packet.ScoreboardObjective; import net.md_5.bungee.protocol.packet.ScoreboardObjective;
import net.md_5.bungee.protocol.packet.ScoreboardScore; import net.md_5.bungee.protocol.packet.ScoreboardScore;
import net.md_5.bungee.protocol.packet.ScoreboardScoreReset;
import net.md_5.bungee.protocol.packet.ServerData; import net.md_5.bungee.protocol.packet.ServerData;
import net.md_5.bungee.protocol.packet.SetCompression; import net.md_5.bungee.protocol.packet.SetCompression;
import net.md_5.bungee.protocol.packet.StartConfiguration; import net.md_5.bungee.protocol.packet.StartConfiguration;
@ -135,8 +134,7 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_19_1, 0x3E ), map( ProtocolConstants.MINECRAFT_1_19_1, 0x3E ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x3D ), map( ProtocolConstants.MINECRAFT_1_19_3, 0x3D ),
map( ProtocolConstants.MINECRAFT_1_19_4, 0x41 ), map( ProtocolConstants.MINECRAFT_1_19_4, 0x41 ),
map( ProtocolConstants.MINECRAFT_1_20_2, 0x43 ), map( ProtocolConstants.MINECRAFT_1_20_2, 0x43 )
map( ProtocolConstants.MINECRAFT_1_20_3, 0x45 )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
BossBar.class, BossBar.class,
@ -194,8 +192,7 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_19_1, 0x56 ), map( ProtocolConstants.MINECRAFT_1_19_1, 0x56 ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x54 ), map( ProtocolConstants.MINECRAFT_1_19_3, 0x54 ),
map( ProtocolConstants.MINECRAFT_1_19_4, 0x58 ), map( ProtocolConstants.MINECRAFT_1_19_4, 0x58 ),
map( ProtocolConstants.MINECRAFT_1_20_2, 0x5A ), map( ProtocolConstants.MINECRAFT_1_20_2, 0x5A )
map( ProtocolConstants.MINECRAFT_1_20_3, 0x5C )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
ScoreboardScore.class, ScoreboardScore.class,
@ -211,13 +208,7 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_19_1, 0x59 ), map( ProtocolConstants.MINECRAFT_1_19_1, 0x59 ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x57 ), map( ProtocolConstants.MINECRAFT_1_19_3, 0x57 ),
map( ProtocolConstants.MINECRAFT_1_19_4, 0x5B ), map( ProtocolConstants.MINECRAFT_1_19_4, 0x5B ),
map( ProtocolConstants.MINECRAFT_1_20_2, 0x5D ), map( ProtocolConstants.MINECRAFT_1_20_2, 0x5D )
map( ProtocolConstants.MINECRAFT_1_20_3, 0x5F )
);
TO_CLIENT.registerPacket(
ScoreboardScoreReset.class,
ScoreboardScoreReset::new,
map( ProtocolConstants.MINECRAFT_1_20_3, 0x42 )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
ScoreboardDisplay.class, ScoreboardDisplay.class,
@ -233,8 +224,7 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_19_1, 0x4F ), map( ProtocolConstants.MINECRAFT_1_19_1, 0x4F ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x4D ), map( ProtocolConstants.MINECRAFT_1_19_3, 0x4D ),
map( ProtocolConstants.MINECRAFT_1_19_4, 0x51 ), map( ProtocolConstants.MINECRAFT_1_19_4, 0x51 ),
map( ProtocolConstants.MINECRAFT_1_20_2, 0x53 ), map( ProtocolConstants.MINECRAFT_1_20_2, 0x53 )
map( ProtocolConstants.MINECRAFT_1_20_3, 0x55 )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
Team.class, Team.class,
@ -250,8 +240,7 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_19_1, 0x58 ), map( ProtocolConstants.MINECRAFT_1_19_1, 0x58 ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x56 ), map( ProtocolConstants.MINECRAFT_1_19_3, 0x56 ),
map( ProtocolConstants.MINECRAFT_1_19_4, 0x5A ), map( ProtocolConstants.MINECRAFT_1_19_4, 0x5A ),
map( ProtocolConstants.MINECRAFT_1_20_2, 0x5C ), map( ProtocolConstants.MINECRAFT_1_20_2, 0x5C )
map( ProtocolConstants.MINECRAFT_1_20_3, 0x5E )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
PluginMessage.class, PluginMessage.class,
@ -302,8 +291,7 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_19_1, 0x5D ), map( ProtocolConstants.MINECRAFT_1_19_1, 0x5D ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x5B ), map( ProtocolConstants.MINECRAFT_1_19_3, 0x5B ),
map( ProtocolConstants.MINECRAFT_1_19_4, 0x5F ), map( ProtocolConstants.MINECRAFT_1_19_4, 0x5F ),
map( ProtocolConstants.MINECRAFT_1_20_2, 0x61 ), map( ProtocolConstants.MINECRAFT_1_20_2, 0x61 )
map( ProtocolConstants.MINECRAFT_1_20_3, 0x63 )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
ClearTitles.class, ClearTitles.class,
@ -322,8 +310,7 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_19_1, 0x5B ), map( ProtocolConstants.MINECRAFT_1_19_1, 0x5B ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x59 ), map( ProtocolConstants.MINECRAFT_1_19_3, 0x59 ),
map( ProtocolConstants.MINECRAFT_1_19_4, 0x5D ), map( ProtocolConstants.MINECRAFT_1_19_4, 0x5D ),
map( ProtocolConstants.MINECRAFT_1_20_2, 0x5F ), map( ProtocolConstants.MINECRAFT_1_20_2, 0x5F )
map( ProtocolConstants.MINECRAFT_1_20_3, 0x61 )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
TitleTimes.class, TitleTimes.class,
@ -333,8 +320,7 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_19_1, 0x5E ), map( ProtocolConstants.MINECRAFT_1_19_1, 0x5E ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x5C ), map( ProtocolConstants.MINECRAFT_1_19_3, 0x5C ),
map( ProtocolConstants.MINECRAFT_1_19_4, 0x60 ), map( ProtocolConstants.MINECRAFT_1_19_4, 0x60 ),
map( ProtocolConstants.MINECRAFT_1_20_2, 0x62 ), map( ProtocolConstants.MINECRAFT_1_20_2, 0x62 )
map( ProtocolConstants.MINECRAFT_1_20_3, 0x64 )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
SystemChat.class, SystemChat.class,
@ -343,8 +329,7 @@ public enum Protocol
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 ),
map( ProtocolConstants.MINECRAFT_1_19_4, 0x64 ), map( ProtocolConstants.MINECRAFT_1_19_4, 0x64 ),
map( ProtocolConstants.MINECRAFT_1_20_2, 0x67 ), map( ProtocolConstants.MINECRAFT_1_20_2, 0x67 )
map( ProtocolConstants.MINECRAFT_1_20_3, 0x69 )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
PlayerListHeaderFooter.class, PlayerListHeaderFooter.class,
@ -364,8 +349,7 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_19_1, 0x63 ), map( ProtocolConstants.MINECRAFT_1_19_1, 0x63 ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x61 ), map( ProtocolConstants.MINECRAFT_1_19_3, 0x61 ),
map( ProtocolConstants.MINECRAFT_1_19_4, 0x65 ), map( ProtocolConstants.MINECRAFT_1_19_4, 0x65 ),
map( ProtocolConstants.MINECRAFT_1_20_2, 0x68 ), map( ProtocolConstants.MINECRAFT_1_20_2, 0x68 )
map( ProtocolConstants.MINECRAFT_1_20_3, 0x6A )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
EntityStatus.class, EntityStatus.class,
@ -421,8 +405,7 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_19_1, 0x4C ), map( ProtocolConstants.MINECRAFT_1_19_1, 0x4C ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x4B ), map( ProtocolConstants.MINECRAFT_1_19_3, 0x4B ),
map( ProtocolConstants.MINECRAFT_1_19_4, 0x4F ), map( ProtocolConstants.MINECRAFT_1_19_4, 0x4F ),
map( ProtocolConstants.MINECRAFT_1_20_2, 0x51 ), map( ProtocolConstants.MINECRAFT_1_20_2, 0x51 )
map( ProtocolConstants.MINECRAFT_1_20_3, 0x53 )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
ServerData.class, ServerData.class,
@ -431,8 +414,7 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_19_1, 0x42 ), map( ProtocolConstants.MINECRAFT_1_19_1, 0x42 ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x41 ), map( ProtocolConstants.MINECRAFT_1_19_3, 0x41 ),
map( ProtocolConstants.MINECRAFT_1_19_4, 0x45 ), map( ProtocolConstants.MINECRAFT_1_19_4, 0x45 ),
map( ProtocolConstants.MINECRAFT_1_20_2, 0x47 ), map( ProtocolConstants.MINECRAFT_1_20_2, 0x47 )
map( ProtocolConstants.MINECRAFT_1_20_3, 0x49 )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
PlayerListItemRemove.class, PlayerListItemRemove.class,
@ -451,8 +433,7 @@ public enum Protocol
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
StartConfiguration.class, StartConfiguration.class,
StartConfiguration::new, StartConfiguration::new,
map( ProtocolConstants.MINECRAFT_1_20_2, 0x65 ), map( ProtocolConstants.MINECRAFT_1_20_2, 0x65 )
map( ProtocolConstants.MINECRAFT_1_20_3, 0x67 )
); );
TO_SERVER.registerPacket( TO_SERVER.registerPacket(
@ -470,8 +451,7 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_19_1, 0x12 ), map( ProtocolConstants.MINECRAFT_1_19_1, 0x12 ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x11 ), map( ProtocolConstants.MINECRAFT_1_19_3, 0x11 ),
map( ProtocolConstants.MINECRAFT_1_19_4, 0x12 ), map( ProtocolConstants.MINECRAFT_1_19_4, 0x12 ),
map( ProtocolConstants.MINECRAFT_1_20_2, 0x14 ), map( ProtocolConstants.MINECRAFT_1_20_2, 0x14 )
map( ProtocolConstants.MINECRAFT_1_20_3, 0x15 )
); );
TO_SERVER.registerPacket( Chat.class, TO_SERVER.registerPacket( Chat.class,
Chat::new, Chat::new,
@ -537,8 +517,7 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_19_1, 0x0D ), map( ProtocolConstants.MINECRAFT_1_19_1, 0x0D ),
map( ProtocolConstants.MINECRAFT_1_19_3, 0x0C ), map( ProtocolConstants.MINECRAFT_1_19_3, 0x0C ),
map( ProtocolConstants.MINECRAFT_1_19_4, 0x0D ), map( ProtocolConstants.MINECRAFT_1_19_4, 0x0D ),
map( ProtocolConstants.MINECRAFT_1_20_2, 0x0F ), map( ProtocolConstants.MINECRAFT_1_20_2, 0x0F )
map( ProtocolConstants.MINECRAFT_1_20_3, 0x10 )
); );
TO_SERVER.registerPacket( TO_SERVER.registerPacket(
StartConfiguration.class, StartConfiguration.class,

View File

@ -44,7 +44,6 @@ public class ProtocolConstants
public static final int MINECRAFT_1_19_4 = 762; public static final int MINECRAFT_1_19_4 = 762;
public static final int MINECRAFT_1_20 = 763; public static final int MINECRAFT_1_20 = 763;
public static final int MINECRAFT_1_20_2 = 764; public static final int MINECRAFT_1_20_2 = 764;
public static final int MINECRAFT_1_20_3 = 765;
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;
@ -102,14 +101,13 @@ public class ProtocolConstants
ProtocolConstants.MINECRAFT_1_19_3, ProtocolConstants.MINECRAFT_1_19_3,
ProtocolConstants.MINECRAFT_1_19_4, ProtocolConstants.MINECRAFT_1_19_4,
ProtocolConstants.MINECRAFT_1_20, ProtocolConstants.MINECRAFT_1_20,
ProtocolConstants.MINECRAFT_1_20_2, ProtocolConstants.MINECRAFT_1_20_2
ProtocolConstants.MINECRAFT_1_20_3
); );
if ( SNAPSHOT_SUPPORT ) if ( SNAPSHOT_SUPPORT )
{ {
// supportedVersions.add( "1.20.x" ); // supportedVersions.add( "1.20.x" );
// supportedVersionIds.add( ProtocolConstants.MINECRAFT_1_20_3 ); // supportedVersionIds.add( ProtocolConstants.MINECRAFT_1_20_2 );
} }
SUPPORTED_VERSIONS = supportedVersions.build(); SUPPORTED_VERSIONS = supportedVersions.build();

View File

@ -1,218 +0,0 @@
package net.md_5.bungee.protocol;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import se.llbit.nbt.ByteArrayTag;
import se.llbit.nbt.ByteTag;
import se.llbit.nbt.CompoundTag;
import se.llbit.nbt.DoubleTag;
import se.llbit.nbt.FloatTag;
import se.llbit.nbt.IntArrayTag;
import se.llbit.nbt.IntTag;
import se.llbit.nbt.ListTag;
import se.llbit.nbt.LongArrayTag;
import se.llbit.nbt.LongTag;
import se.llbit.nbt.NamedTag;
import se.llbit.nbt.ShortTag;
import se.llbit.nbt.SpecificTag;
import se.llbit.nbt.StringTag;
import se.llbit.nbt.Tag;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class TagUtil
{
public static SpecificTag fromJson(JsonElement json)
{
if ( json instanceof JsonPrimitive )
{
JsonPrimitive jsonPrimitive = (JsonPrimitive) json;
if ( jsonPrimitive.isNumber() )
{
Number number = json.getAsNumber();
if ( number instanceof Byte )
{
return new ByteTag( (Byte) number );
} else if ( number instanceof Short )
{
return new ShortTag( (Short) number );
} else if ( number instanceof Integer )
{
return new IntTag( (Integer) number );
} else if ( number instanceof Long )
{
return new LongTag( (Long) number );
} else if ( number instanceof Float )
{
return new FloatTag( (Float) number );
} else if ( number instanceof Double )
{
return new DoubleTag( (Double) number );
}
} else if ( jsonPrimitive.isString() )
{
return new StringTag( jsonPrimitive.getAsString() );
} else if ( jsonPrimitive.isBoolean() )
{
return new ByteTag( jsonPrimitive.getAsBoolean() ? 1 : 0 );
} else
{
throw new IllegalArgumentException( "Unknown JSON primitive: " + jsonPrimitive );
}
} else if ( json instanceof JsonObject )
{
CompoundTag compoundTag = new CompoundTag();
for ( Map.Entry<String, JsonElement> property : ( (JsonObject) json ).entrySet() )
{
compoundTag.add( property.getKey(), fromJson( property.getValue() ) );
}
return compoundTag;
} else if ( json instanceof JsonArray )
{
List<JsonElement> jsonArray = ( (JsonArray) json ).asList();
if ( jsonArray.isEmpty() )
{
return new ListTag( Tag.TAG_END, Collections.emptyList() );
}
SpecificTag listTag;
int listType = fromJson( jsonArray.get( 0 ) ).tagType();
switch ( listType )
{
case Tag.TAG_BYTE:
byte[] bytes = new byte[ jsonArray.size() ];
for ( int i = 0; i < bytes.length; i++ )
{
bytes[i] = (Byte) ( (JsonPrimitive) jsonArray.get( i ) ).getAsNumber();
}
listTag = new ByteArrayTag( bytes );
break;
case Tag.TAG_INT:
int[] ints = new int[ jsonArray.size() ];
for ( int i = 0; i < ints.length; i++ )
{
ints[i] = (Integer) ( (JsonPrimitive) jsonArray.get( i ) ).getAsNumber();
}
listTag = new IntArrayTag( ints );
break;
case Tag.TAG_LONG:
long[] longs = new long[ jsonArray.size() ];
for ( int i = 0; i < longs.length; i++ )
{
longs[i] = (Long) ( (JsonPrimitive) jsonArray.get( i ) ).getAsNumber();
}
listTag = new LongArrayTag( longs );
break;
default:
List<SpecificTag> tagItems = new ArrayList<>( jsonArray.size() );
for ( JsonElement jsonEl : jsonArray )
{
SpecificTag subTag = fromJson( jsonEl );
if ( subTag.tagType() != listType )
{
throw new IllegalArgumentException( "Cannot convert mixed JsonArray to Tag" );
}
tagItems.add( subTag );
}
listTag = new ListTag( listType, tagItems );
break;
}
return listTag;
} else if ( json instanceof JsonNull )
{
return Tag.END;
}
throw new IllegalArgumentException( "Unknown JSON element: " + json );
}
public static JsonElement toJson(SpecificTag tag)
{
switch ( tag.tagType() )
{
case Tag.TAG_BYTE:
return new JsonPrimitive( (byte) ( (ByteTag) tag ).getData() );
case Tag.TAG_SHORT:
return new JsonPrimitive( ( (ShortTag) tag ).getData() );
case Tag.TAG_INT:
return new JsonPrimitive( ( (IntTag) tag ).getData() );
case Tag.TAG_LONG:
return new JsonPrimitive( ( (LongTag) tag ).getData() );
case Tag.TAG_FLOAT:
return new JsonPrimitive( ( (FloatTag) tag ).getData() );
case Tag.TAG_DOUBLE:
return new JsonPrimitive( ( (DoubleTag) tag ).getData() );
case Tag.TAG_BYTE_ARRAY:
byte[] byteArray = ( (ByteArrayTag) tag ).getData();
JsonArray jsonByteArray = new JsonArray( byteArray.length );
for ( byte b : byteArray )
{
jsonByteArray.add( new JsonPrimitive( b ) );
}
return jsonByteArray;
case Tag.TAG_STRING:
return new JsonPrimitive( ( (StringTag) tag ).getData() );
case Tag.TAG_LIST:
List<SpecificTag> items = ( (ListTag) tag ).items;
JsonArray jsonList = new JsonArray( items.size() );
for ( SpecificTag subTag : items )
{
jsonList.add( toJson( subTag ) );
}
return jsonList;
case Tag.TAG_COMPOUND:
JsonObject jsonObject = new JsonObject();
for ( NamedTag subTag : (CompoundTag) tag )
{
jsonObject.add( subTag.name(), toJson( subTag.getTag() ) );
}
return jsonObject;
case Tag.TAG_INT_ARRAY:
int[] intArray = ( (IntArrayTag) tag ).getData();
JsonArray jsonIntArray = new JsonArray( intArray.length );
for ( int i : intArray )
{
jsonIntArray.add( new JsonPrimitive( i ) );
}
return jsonIntArray;
case Tag.TAG_LONG_ARRAY:
long[] longArray = ( (LongArrayTag) tag ).getData();
JsonArray jsonLongArray = new JsonArray( longArray.length );
for ( long l : longArray )
{
jsonLongArray.add( new JsonPrimitive( l ) );
}
return jsonLongArray;
default:
throw new IllegalArgumentException( "Unknown NBT tag: " + tag );
}
}
}

View File

@ -7,8 +7,7 @@ import io.netty.handler.codec.MessageToMessageEncoder;
import java.util.List; import java.util.List;
/** /**
* Prepend length of the message as a Varint21 using an extra buffer for the * Prepend length of the message as a Varint21 using an extra buffer for the length, avoiding copying packet data
* length, avoiding copying packet data
*/ */
@ChannelHandler.Sharable @ChannelHandler.Sharable
public class Varint21LengthFieldExtraBufPrepender extends MessageToMessageEncoder<ByteBuf> public class Varint21LengthFieldExtraBufPrepender extends MessageToMessageEncoder<ByteBuf>

View File

@ -6,8 +6,7 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder; import io.netty.handler.codec.MessageToByteEncoder;
/** /**
* Prepend length of the message as a Varint21 by writing length and data to a * Prepend length of the message as a Varint21 by writing length and data to a new buffer
* new buffer
*/ */
@ChannelHandler.Sharable @ChannelHandler.Sharable
public class Varint21LengthFieldPrepender extends MessageToByteEncoder<ByteBuf> public class Varint21LengthFieldPrepender extends MessageToByteEncoder<ByteBuf>

View File

@ -5,7 +5,6 @@ import java.util.UUID;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.protocol.AbstractPacketHandler; import net.md_5.bungee.protocol.AbstractPacketHandler;
import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.ProtocolConstants; import net.md_5.bungee.protocol.ProtocolConstants;
@ -18,7 +17,7 @@ public class BossBar extends DefinedPacket
private UUID uuid; private UUID uuid;
private int action; private int action;
private BaseComponent title; private String title;
private float health; private float health;
private int color; private int color;
private int division; private int division;
@ -40,7 +39,7 @@ public class BossBar extends DefinedPacket
{ {
// Add // Add
case 0: case 0:
title = readBaseComponent( buf, protocolVersion ); title = readString( buf );
health = buf.readFloat(); health = buf.readFloat();
color = readVarInt( buf ); color = readVarInt( buf );
division = readVarInt( buf ); division = readVarInt( buf );
@ -52,7 +51,7 @@ public class BossBar extends DefinedPacket
break; break;
// Title // Title
case 3: case 3:
title = readBaseComponent( buf, protocolVersion ); title = readString( buf );
break; break;
// Style // Style
case 4: case 4:
@ -76,7 +75,7 @@ public class BossBar extends DefinedPacket
{ {
// Add // Add
case 0: case 0:
writeBaseComponent( title, buf, protocolVersion ); writeString( title, buf );
buf.writeFloat( health ); buf.writeFloat( health );
writeVarInt( color, buf ); writeVarInt( color, buf );
writeVarInt( division, buf ); writeVarInt( division, buf );
@ -88,7 +87,7 @@ public class BossBar extends DefinedPacket
break; break;
// Title // Title
case 3: case 3:
writeBaseComponent( title, buf, protocolVersion ); writeString( title, buf );
break; break;
// Style // Style
case 4: case 4:

View File

@ -311,7 +311,6 @@ public class Commands extends DefinedPacket
private static final ArgumentSerializer[] IDS_1_19; private static final ArgumentSerializer[] IDS_1_19;
private static final ArgumentSerializer[] IDS_1_19_3; private static final ArgumentSerializer[] IDS_1_19_3;
private static final ArgumentSerializer[] IDS_1_19_4; private static final ArgumentSerializer[] IDS_1_19_4;
private static final ArgumentSerializer[] IDS_1_20_3;
private static final Map<Class<?>, ProperArgumentSerializer<?>> PROPER_PROVIDERS = new HashMap<>(); private static final Map<Class<?>, ProperArgumentSerializer<?>> PROPER_PROVIDERS = new HashMap<>();
// //
private static final ArgumentSerializer<Void> VOID = new ArgumentSerializer<Void>() private static final ArgumentSerializer<Void> VOID = new ArgumentSerializer<Void>()
@ -814,60 +813,6 @@ public class Commands extends DefinedPacket
get( "minecraft:uuid", VOID ), get( "minecraft:uuid", VOID ),
get( "minecraft:heightmap", VOID ) get( "minecraft:heightmap", VOID )
}; };
IDS_1_20_3 = new ArgumentSerializer[]
{
get( "brigadier:bool", VOID ),
get( "brigadier:float", FLOAT_RANGE ),
get( "brigadier:double", DOUBLE_RANGE ),
get( "brigadier:integer", INTEGER_RANGE ),
get( "brigadier:long", LONG_RANGE ),
get( "brigadier:string", STRING ),
get( "minecraft:entity", BYTE ),
get( "minecraft:game_profile", VOID ),
get( "minecraft:block_pos", VOID ),
get( "minecraft:column_pos", VOID ),
get( "minecraft:vec3", VOID ),
get( "minecraft:vec2", VOID ),
get( "minecraft:block_state", VOID ),
get( "minecraft:block_predicate", VOID ),
get( "minecraft:item_stack", VOID ),
get( "minecraft:item_predicate", VOID ),
get( "minecraft:color", VOID ),
get( "minecraft:component", VOID ),
get( "minecraft:style", VOID ),
get( "minecraft:message", VOID ),
get( "minecraft:nbt_compound_tag", VOID ),
get( "minecraft:nbt_tag", VOID ),
get( "minecraft:nbt_path", VOID ),
get( "minecraft:objective", VOID ),
get( "minecraft:objective_criteria", VOID ),
get( "minecraft:operation", VOID ),
get( "minecraft:particle", VOID ),
get( "minecraft:angle", VOID ),
get( "minecraft:rotation", VOID ),
get( "minecraft:scoreboard_slot", VOID ),
get( "minecraft:score_holder", BYTE ),
get( "minecraft:swizzle", VOID ),
get( "minecraft:team", VOID ),
get( "minecraft:item_slot", VOID ),
get( "minecraft:resource_location", VOID ),
get( "minecraft:function", VOID ),
get( "minecraft:entity_anchor", VOID ),
get( "minecraft:int_range", VOID ),
get( "minecraft:float_range", VOID ),
get( "minecraft:dimension", VOID ),
get( "minecraft:gamemode", VOID ),
get( "minecraft:time", INTEGER ),
get( "minecraft:resource_or_tag", RAW_STRING ),
get( "minecraft:resource_or_tag_key", RAW_STRING ),
get( "minecraft:resource", RAW_STRING ),
get( "minecraft:resource_key", RAW_STRING ),
get( "minecraft:template_mirror", VOID ),
get( "minecraft:template_rotation", VOID ),
get( "minecraft:uuid", VOID ),
get( "minecraft:heightmap", VOID )
};
} }
private static void register(String name, ArgumentSerializer serializer) private static void register(String name, ArgumentSerializer serializer)
@ -1287,10 +1232,7 @@ public class Commands extends DefinedPacket
{ {
key = readVarInt( buf ); key = readVarInt( buf );
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_20_3 ) if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_4 )
{
reader = IDS_1_20_3[(Integer) key];
} else if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_4 )
{ {
reader = IDS_1_19_4[(Integer) key]; reader = IDS_1_19_4[(Integer) key];
} else if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_3 ) } else if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_3 )

View File

@ -5,12 +5,8 @@ import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import net.md_5.bungee.protocol.AbstractPacketHandler; import net.md_5.bungee.protocol.AbstractPacketHandler;
import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.Protocol;
import net.md_5.bungee.protocol.ProtocolConstants;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@ -19,30 +15,18 @@ import net.md_5.bungee.protocol.ProtocolConstants;
public class Kick extends DefinedPacket public class Kick extends DefinedPacket
{ {
private BaseComponent message; private String message;
@Override @Override
public void read(ByteBuf buf, Protocol protocol, ProtocolConstants.Direction direction, int protocolVersion) public void read(ByteBuf buf)
{ {
if ( protocol == Protocol.LOGIN ) message = readString( buf );
{
message = ComponentSerializer.deserialize( readString( buf ) );
} else
{
message = readBaseComponent( buf, protocolVersion );
}
} }
@Override @Override
public void write(ByteBuf buf, Protocol protocol, ProtocolConstants.Direction direction, int protocolVersion) public void write(ByteBuf buf)
{ {
if ( protocol == Protocol.LOGIN ) writeString( message, buf );
{
writeString( ComponentSerializer.toString( message ), buf );
} else
{
writeBaseComponent( message, buf, protocolVersion );
}
} }
@Override @Override

View File

@ -5,7 +5,6 @@ import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.protocol.AbstractPacketHandler; import net.md_5.bungee.protocol.AbstractPacketHandler;
import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.ProtocolConstants; import net.md_5.bungee.protocol.ProtocolConstants;
@ -17,21 +16,21 @@ import net.md_5.bungee.protocol.ProtocolConstants;
public class PlayerListHeaderFooter extends DefinedPacket public class PlayerListHeaderFooter extends DefinedPacket
{ {
private BaseComponent header; private String header;
private BaseComponent footer; private String footer;
@Override @Override
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{ {
header = readBaseComponent( buf, protocolVersion ); header = readString( buf );
footer = readBaseComponent( buf, protocolVersion ); footer = readString( buf );
} }
@Override @Override
public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{ {
writeBaseComponent( header, buf, protocolVersion ); writeString( header, buf );
writeBaseComponent( footer, buf, protocolVersion ); writeString( footer, buf );
} }
@Override @Override

View File

@ -5,7 +5,6 @@ import java.util.UUID;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.protocol.AbstractPacketHandler; import net.md_5.bungee.protocol.AbstractPacketHandler;
import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.PlayerPublicKey; import net.md_5.bungee.protocol.PlayerPublicKey;
@ -39,7 +38,7 @@ public class PlayerListItem extends DefinedPacket
item.ping = DefinedPacket.readVarInt( buf ); item.ping = DefinedPacket.readVarInt( buf );
if ( buf.readBoolean() ) if ( buf.readBoolean() )
{ {
item.displayName = DefinedPacket.readBaseComponent( buf, protocolVersion ); item.displayName = DefinedPacket.readString( buf );
} }
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19 ) if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19 )
{ {
@ -55,7 +54,7 @@ public class PlayerListItem extends DefinedPacket
case UPDATE_DISPLAY_NAME: case UPDATE_DISPLAY_NAME:
if ( buf.readBoolean() ) if ( buf.readBoolean() )
{ {
item.displayName = DefinedPacket.readBaseComponent( buf, protocolVersion ); item.displayName = DefinedPacket.readString( buf );
} }
} }
} }
@ -79,7 +78,7 @@ public class PlayerListItem extends DefinedPacket
buf.writeBoolean( item.displayName != null ); buf.writeBoolean( item.displayName != null );
if ( item.displayName != null ) if ( item.displayName != null )
{ {
DefinedPacket.writeBaseComponent( item.displayName, buf, protocolVersion ); DefinedPacket.writeString( item.displayName, buf );
} }
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19 ) if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19 )
{ {
@ -96,7 +95,7 @@ public class PlayerListItem extends DefinedPacket
buf.writeBoolean( item.displayName != null ); buf.writeBoolean( item.displayName != null );
if ( item.displayName != null ) if ( item.displayName != null )
{ {
DefinedPacket.writeBaseComponent( item.displayName, buf, protocolVersion ); DefinedPacket.writeString( item.displayName, buf );
} }
break; break;
} }
@ -143,7 +142,7 @@ public class PlayerListItem extends DefinedPacket
Integer ping; Integer ping;
// ADD_PLAYER & UPDATE_DISPLAY_NAME // ADD_PLAYER & UPDATE_DISPLAY_NAME
BaseComponent displayName; String displayName;
} }
} }

View File

@ -58,7 +58,7 @@ public class PlayerListItemUpdate extends DefinedPacket
case UPDATE_DISPLAY_NAME: case UPDATE_DISPLAY_NAME:
if ( buf.readBoolean() ) if ( buf.readBoolean() )
{ {
item.displayName = DefinedPacket.readBaseComponent( buf, protocolVersion ); item.displayName = DefinedPacket.readString( buf );
} }
break; break;
} }
@ -106,7 +106,7 @@ public class PlayerListItemUpdate extends DefinedPacket
buf.writeBoolean( item.displayName != null ); buf.writeBoolean( item.displayName != null );
if ( item.displayName != null ) if ( item.displayName != null )
{ {
DefinedPacket.writeBaseComponent( item.displayName, buf, protocolVersion ); DefinedPacket.writeString( item.displayName, buf );
} }
break; break;
} }

View File

@ -6,11 +6,8 @@ import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.protocol.AbstractPacketHandler; import net.md_5.bungee.protocol.AbstractPacketHandler;
import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.Either;
import net.md_5.bungee.protocol.NumberFormat;
import net.md_5.bungee.protocol.ProtocolConstants; import net.md_5.bungee.protocol.ProtocolConstants;
@Data @Data
@ -21,13 +18,12 @@ public class ScoreboardObjective extends DefinedPacket
{ {
private String name; private String name;
private Either<String, BaseComponent> value; private String value;
private HealthDisplay type; private HealthDisplay type;
/** /**
* 0 to create, 1 to remove, 2 to update display text. * 0 to create, 1 to remove, 2 to update display text.
*/ */
private byte action; private byte action;
private NumberFormat numberFormat;
@Override @Override
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
@ -36,19 +32,14 @@ public class ScoreboardObjective extends DefinedPacket
action = buf.readByte(); action = buf.readByte();
if ( action == 0 || action == 2 ) if ( action == 0 || action == 2 )
{ {
value = readString( buf );
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 ) if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 )
{ {
value = readEitherBaseComponent( buf, protocolVersion, false );
type = HealthDisplay.values()[readVarInt( buf )]; type = HealthDisplay.values()[readVarInt( buf )];
} else } else
{ {
value = readEitherBaseComponent( buf, protocolVersion, true );
type = HealthDisplay.fromString( readString( buf ) ); type = HealthDisplay.fromString( readString( buf ) );
} }
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_20_3 )
{
numberFormat = readNullable( (b) -> readNumberFormat( b, protocolVersion ), buf );
}
} }
} }
@ -59,7 +50,7 @@ public class ScoreboardObjective extends DefinedPacket
buf.writeByte( action ); buf.writeByte( action );
if ( action == 0 || action == 2 ) if ( action == 0 || action == 2 )
{ {
writeEitherBaseComponent( value, buf, protocolVersion ); writeString( value, buf );
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 ) if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 )
{ {
writeVarInt( type.ordinal(), buf ); writeVarInt( type.ordinal(), buf );
@ -67,10 +58,6 @@ public class ScoreboardObjective extends DefinedPacket
{ {
writeString( type.toString(), buf ); writeString( type.toString(), buf );
} }
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_20_3 )
{
writeNullable( numberFormat, (s, b) -> DefinedPacket.writeNumberFormat( s, b, protocolVersion ), buf );
}
} }
} }

View File

@ -5,10 +5,8 @@ import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.protocol.AbstractPacketHandler; import net.md_5.bungee.protocol.AbstractPacketHandler;
import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.NumberFormat;
import net.md_5.bungee.protocol.ProtocolConstants; import net.md_5.bungee.protocol.ProtocolConstants;
@Data @Data
@ -25,50 +23,29 @@ public class ScoreboardScore extends DefinedPacket
private byte action; private byte action;
private String scoreName; private String scoreName;
private int value; private int value;
private BaseComponent displayName;
private NumberFormat numberFormat;
@Override @Override
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{ {
itemName = readString( buf ); itemName = readString( buf );
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_20_3 )
{
action = 0;
} else
{
action = buf.readByte(); action = buf.readByte();
}
scoreName = readString( buf ); scoreName = readString( buf );
if ( action != 1 ) if ( action != 1 )
{ {
value = readVarInt( buf ); value = readVarInt( buf );
} }
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_20_3 )
{
displayName = readNullable( (b) -> readBaseComponent( b, protocolVersion ), buf );
numberFormat = readNullable( (b) -> readNumberFormat( b, protocolVersion ), buf );
}
} }
@Override @Override
public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{ {
writeString( itemName, buf ); writeString( itemName, buf );
if ( protocolVersion < ProtocolConstants.MINECRAFT_1_20_3 )
{
buf.writeByte( action ); buf.writeByte( action );
}
writeString( scoreName, buf ); writeString( scoreName, buf );
if ( action != 1 || protocolVersion >= ProtocolConstants.MINECRAFT_1_20_3 ) if ( action != 1 )
{ {
writeVarInt( value, buf ); writeVarInt( value, buf );
} }
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_20_3 )
{
writeNullable( displayName, (s, b) -> DefinedPacket.writeBaseComponent( s, b, protocolVersion ), buf );
writeNullable( numberFormat, (s, b) -> DefinedPacket.writeNumberFormat( s, b, protocolVersion ), buf );
}
} }
@Override @Override

View File

@ -1,41 +0,0 @@
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;
import net.md_5.bungee.protocol.ProtocolConstants;
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class ScoreboardScoreReset extends DefinedPacket
{
private String itemName;
private String scoreName;
@Override
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{
itemName = readString( buf );
scoreName = readNullable( DefinedPacket::readString, buf );
}
@Override
public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{
writeString( itemName, buf );
writeNullable( scoreName, DefinedPacket::writeString, buf );
}
@Override
public void handle(AbstractPacketHandler handler) throws Exception
{
handler.handle( this );
}
}

View File

@ -5,7 +5,6 @@ import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.protocol.AbstractPacketHandler; import net.md_5.bungee.protocol.AbstractPacketHandler;
import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.ProtocolConstants; import net.md_5.bungee.protocol.ProtocolConstants;
@ -17,7 +16,7 @@ import net.md_5.bungee.protocol.ProtocolConstants;
public class ServerData extends DefinedPacket public class ServerData extends DefinedPacket
{ {
private BaseComponent motd; private String motd;
private Object icon; private Object icon;
private boolean preview; private boolean preview;
private boolean enforceSecure; private boolean enforceSecure;
@ -27,7 +26,7 @@ public class ServerData extends DefinedPacket
{ {
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_4 || buf.readBoolean() ) if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_4 || buf.readBoolean() )
{ {
motd = readBaseComponent( buf, protocolVersion ); motd = readString( buf, 262144 );
} }
if ( buf.readBoolean() ) if ( buf.readBoolean() )
{ {
@ -60,7 +59,7 @@ public class ServerData extends DefinedPacket
{ {
buf.writeBoolean( true ); buf.writeBoolean( true );
} }
writeBaseComponent( motd, buf, protocolVersion ); writeString( motd, buf, 262144 );
} else } else
{ {
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_4 ) if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_4 )

View File

@ -4,7 +4,6 @@ import io.netty.buffer.ByteBuf;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.protocol.AbstractPacketHandler; import net.md_5.bungee.protocol.AbstractPacketHandler;
import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.ProtocolConstants; import net.md_5.bungee.protocol.ProtocolConstants;
@ -15,18 +14,18 @@ import net.md_5.bungee.protocol.ProtocolConstants;
public class Subtitle extends DefinedPacket public class Subtitle extends DefinedPacket
{ {
private BaseComponent text; private String text;
@Override @Override
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{ {
text = readBaseComponent( buf, protocolVersion ); text = readString( buf );
} }
@Override @Override
public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{ {
writeBaseComponent( text, buf, protocolVersion ); writeString( text, buf );
} }
@Override @Override

View File

@ -6,7 +6,6 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.protocol.AbstractPacketHandler; import net.md_5.bungee.protocol.AbstractPacketHandler;
import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.ProtocolConstants; import net.md_5.bungee.protocol.ProtocolConstants;
@ -18,20 +17,20 @@ import net.md_5.bungee.protocol.ProtocolConstants;
public class SystemChat extends DefinedPacket public class SystemChat extends DefinedPacket
{ {
private BaseComponent message; private String message;
private int position; private int position;
@Override @Override
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{ {
message = readBaseComponent( buf, 262144, protocolVersion ); message = readString( buf, 262144 );
position = ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 ) ? ( ( buf.readBoolean() ) ? ChatMessageType.ACTION_BAR.ordinal() : 0 ) : readVarInt( buf ); position = ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 ) ? ( ( buf.readBoolean() ) ? ChatMessageType.ACTION_BAR.ordinal() : 0 ) : readVarInt( buf );
} }
@Override @Override
public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{ {
writeBaseComponent( message, buf, protocolVersion ); writeString( message, buf, 262144 );
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 ) if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 )
{ {
buf.writeBoolean( position == ChatMessageType.ACTION_BAR.ordinal() ); buf.writeBoolean( position == ChatMessageType.ACTION_BAR.ordinal() );

View File

@ -1,6 +1,6 @@
package net.md_5.bungee.protocol.packet; package net.md_5.bungee.protocol.packet;
import com.mojang.brigadier.Message; import com.mojang.brigadier.LiteralMessage;
import com.mojang.brigadier.context.StringRange; import com.mojang.brigadier.context.StringRange;
import com.mojang.brigadier.suggestion.Suggestion; import com.mojang.brigadier.suggestion.Suggestion;
import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.Suggestions;
@ -10,7 +10,6 @@ import java.util.List;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.protocol.AbstractPacketHandler; import net.md_5.bungee.protocol.AbstractPacketHandler;
import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.ProtocolConstants; import net.md_5.bungee.protocol.ProtocolConstants;
@ -52,9 +51,9 @@ public class TabCompleteResponse extends DefinedPacket
for ( int i = 0; i < cnt; i++ ) for ( int i = 0; i < cnt; i++ )
{ {
String match = readString( buf ); String match = readString( buf );
BaseComponent tooltip = buf.readBoolean() ? readBaseComponent( buf, protocolVersion ) : null; String tooltip = buf.readBoolean() ? readString( buf ) : null;
matches.add( new Suggestion( range, match, ( tooltip != null ) ? new ComponentMessage( tooltip ) : null ) ); matches.add( new Suggestion( range, match, new LiteralMessage( tooltip ) ) );
} }
suggestions = new Suggestions( range, matches ); suggestions = new Suggestions( range, matches );
@ -77,10 +76,10 @@ public class TabCompleteResponse extends DefinedPacket
for ( Suggestion suggestion : suggestions.getList() ) for ( Suggestion suggestion : suggestions.getList() )
{ {
writeString( suggestion.getText(), buf ); writeString( suggestion.getText(), buf );
buf.writeBoolean( suggestion.getTooltip() != null ); buf.writeBoolean( suggestion.getTooltip() != null && suggestion.getTooltip().getString() != null );
if ( suggestion.getTooltip() != null ) if ( suggestion.getTooltip() != null && suggestion.getTooltip().getString() != null )
{ {
writeBaseComponent( ( (ComponentMessage) suggestion.getTooltip() ).getComponent(), buf, protocolVersion ); writeString( suggestion.getTooltip().getString(), buf );
} }
} }
} else } else
@ -94,17 +93,4 @@ public class TabCompleteResponse extends DefinedPacket
{ {
handler.handle( this ); handler.handle( this );
} }
@Data
private static class ComponentMessage implements Message
{
private final BaseComponent component;
@Override
public String getString()
{
return component.toPlainText();
}
}
} }

View File

@ -5,10 +5,8 @@ import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.protocol.AbstractPacketHandler; import net.md_5.bungee.protocol.AbstractPacketHandler;
import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.Either;
import net.md_5.bungee.protocol.ProtocolConstants; import net.md_5.bungee.protocol.ProtocolConstants;
@Data @Data
@ -23,9 +21,9 @@ public class Team extends DefinedPacket
* 0 - create, 1 remove, 2 info update, 3 player add, 4 player remove. * 0 - create, 1 remove, 2 info update, 3 player add, 4 player remove.
*/ */
private byte mode; private byte mode;
private Either<String, BaseComponent> displayName; private String displayName;
private Either<String, BaseComponent> prefix; private String prefix;
private Either<String, BaseComponent> suffix; private String suffix;
private String nameTagVisibility; private String nameTagVisibility;
private String collisionRule; private String collisionRule;
private int color; private int color;
@ -50,14 +48,11 @@ public class Team extends DefinedPacket
mode = buf.readByte(); mode = buf.readByte();
if ( mode == 0 || mode == 2 ) if ( mode == 0 || mode == 2 )
{ {
displayName = readString( buf );
if ( protocolVersion < ProtocolConstants.MINECRAFT_1_13 ) if ( protocolVersion < ProtocolConstants.MINECRAFT_1_13 )
{ {
displayName = readEitherBaseComponent( buf, protocolVersion, true ); prefix = readString( buf );
prefix = readEitherBaseComponent( buf, protocolVersion, true ); suffix = readString( buf );
suffix = readEitherBaseComponent( buf, protocolVersion, true );
} else
{
displayName = readEitherBaseComponent( buf, protocolVersion, false );
} }
friendlyFire = buf.readByte(); friendlyFire = buf.readByte();
nameTagVisibility = readString( buf ); nameTagVisibility = readString( buf );
@ -68,8 +63,8 @@ public class Team extends DefinedPacket
color = ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 ) ? readVarInt( buf ) : buf.readByte(); color = ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 ) ? readVarInt( buf ) : buf.readByte();
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 ) if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 )
{ {
prefix = readEitherBaseComponent( buf, protocolVersion, false ); prefix = readString( buf );
suffix = readEitherBaseComponent( buf, protocolVersion, false ); suffix = readString( buf );
} }
} }
if ( mode == 0 || mode == 3 || mode == 4 ) if ( mode == 0 || mode == 3 || mode == 4 )
@ -90,11 +85,11 @@ public class Team extends DefinedPacket
buf.writeByte( mode ); buf.writeByte( mode );
if ( mode == 0 || mode == 2 ) if ( mode == 0 || mode == 2 )
{ {
writeEitherBaseComponent( displayName, buf, protocolVersion ); writeString( displayName, buf );
if ( protocolVersion < ProtocolConstants.MINECRAFT_1_13 ) if ( protocolVersion < ProtocolConstants.MINECRAFT_1_13 )
{ {
writeEitherBaseComponent( prefix, buf, protocolVersion ); writeString( prefix, buf );
writeEitherBaseComponent( suffix, buf, protocolVersion ); writeString( suffix, buf );
} }
buf.writeByte( friendlyFire ); buf.writeByte( friendlyFire );
writeString( nameTagVisibility, buf ); writeString( nameTagVisibility, buf );
@ -106,8 +101,8 @@ public class Team extends DefinedPacket
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 ) if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 )
{ {
writeVarInt( color, buf ); writeVarInt( color, buf );
writeEitherBaseComponent( prefix, buf, protocolVersion ); writeString( prefix, buf );
writeEitherBaseComponent( suffix, buf, protocolVersion ); writeString( suffix, buf );
} else } else
{ {
buf.writeByte( color ); buf.writeByte( color );

View File

@ -4,7 +4,6 @@ import io.netty.buffer.ByteBuf;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.protocol.AbstractPacketHandler; import net.md_5.bungee.protocol.AbstractPacketHandler;
import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.ProtocolConstants; import net.md_5.bungee.protocol.ProtocolConstants;
@ -18,7 +17,7 @@ public class Title extends DefinedPacket
private Action action; private Action action;
// TITLE & SUBTITLE // TITLE & SUBTITLE
private BaseComponent text; private String text;
// TIMES // TIMES
private int fadeIn; private int fadeIn;
@ -35,7 +34,7 @@ public class Title extends DefinedPacket
{ {
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_17 ) if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_17 )
{ {
text = readBaseComponent( buf, protocolVersion ); text = readString( buf );
return; return;
} }
@ -53,7 +52,7 @@ public class Title extends DefinedPacket
case TITLE: case TITLE:
case SUBTITLE: case SUBTITLE:
case ACTIONBAR: case ACTIONBAR:
text = readBaseComponent( buf, protocolVersion ); text = readString( buf );
break; break;
case TIMES: case TIMES:
fadeIn = buf.readInt(); fadeIn = buf.readInt();
@ -68,7 +67,7 @@ public class Title extends DefinedPacket
{ {
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_17 ) if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_17 )
{ {
writeBaseComponent( text, buf, protocolVersion ); writeString( text, buf );
return; return;
} }
@ -86,7 +85,7 @@ public class Title extends DefinedPacket
case TITLE: case TITLE:
case SUBTITLE: case SUBTITLE:
case ACTIONBAR: case ACTIONBAR:
writeBaseComponent( text, buf, protocolVersion ); writeString( text, buf );
break; break;
case TIMES: case TIMES:
buf.writeInt( fadeIn ); buf.writeInt( fadeIn );

View File

@ -1,5 +1,6 @@
package net.md_5.bungee; package net.md_5.bungee;
import com.google.common.base.Charsets;
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;
@ -23,7 +24,6 @@ import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
import java.text.Format; import java.text.Format;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
@ -685,10 +685,10 @@ public class BungeeCord extends ProxyServer
{ {
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 ) if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 )
{ {
return new PluginMessage( "minecraft:register", String.join( "\00", Iterables.transform( pluginChannels, PluginMessage.MODERNISE ) ).getBytes( StandardCharsets.UTF_8 ), false ); return new PluginMessage( "minecraft:register", String.join( "\00", Iterables.transform( pluginChannels, PluginMessage.MODERNISE ) ).getBytes( Charsets.UTF_8 ), false );
} }
return new PluginMessage( "REGISTER", String.join( "\00", pluginChannels ).getBytes( StandardCharsets.UTF_8 ), false ); return new PluginMessage( "REGISTER", String.join( "\00", pluginChannels ).getBytes( Charsets.UTF_8 ), false );
} }
@Override @Override
@ -724,13 +724,13 @@ public class BungeeCord extends ProxyServer
@Override @Override
public void broadcast(String message) public void broadcast(String message)
{ {
broadcast( TextComponent.fromLegacy( message ) ); broadcast( TextComponent.fromLegacyText( message ) );
} }
@Override @Override
public void broadcast(BaseComponent... message) public void broadcast(BaseComponent... message)
{ {
getConsole().sendMessage( message ); getConsole().sendMessage( BaseComponent.toLegacyText( message ) );
for ( ProxiedPlayer player : getPlayers() ) for ( ProxiedPlayer player : getPlayers() )
{ {
player.sendMessage( message ); player.sendMessage( message );
@ -740,14 +740,14 @@ public class BungeeCord extends ProxyServer
@Override @Override
public void broadcast(BaseComponent message) public void broadcast(BaseComponent message)
{ {
getConsole().sendMessage( message ); getConsole().sendMessage( message.toLegacyText() );
for ( ProxiedPlayer player : getPlayers() ) for ( ProxiedPlayer player : getPlayers() )
{ {
player.sendMessage( message ); player.sendMessage( message );
} }
} }
public boolean addConnection(UserConnection con) public void addConnection(UserConnection con)
{ {
UUID offlineId = con.getPendingConnection().getOfflineId(); UUID offlineId = con.getPendingConnection().getOfflineId();
if ( offlineId != null && offlineId.version() != 3 ) if ( offlineId != null && offlineId.version() != 3 )
@ -757,10 +757,6 @@ public class BungeeCord extends ProxyServer
connectionLock.writeLock().lock(); connectionLock.writeLock().lock();
try try
{ {
if ( connections.containsKey( con.getName() ) || connectionsByUUID.containsKey( con.getUniqueId() ) || connectionsByOfflineUUID.containsKey( offlineId ) )
{
return false;
}
connections.put( con.getName(), con ); connections.put( con.getName(), con );
connectionsByUUID.put( con.getUniqueId(), con ); connectionsByUUID.put( con.getUniqueId(), con );
connectionsByOfflineUUID.put( offlineId, con ); connectionsByOfflineUUID.put( offlineId, con );
@ -768,7 +764,6 @@ public class BungeeCord extends ProxyServer
{ {
connectionLock.writeLock().unlock(); connectionLock.writeLock().unlock();
} }
return true;
} }
public void removeConnection(UserConnection con) public void removeConnection(UserConnection con)

View File

@ -3,8 +3,8 @@ package net.md_5.bungee;
import lombok.Data; import lombok.Data;
import net.md_5.bungee.api.Title; import net.md_5.bungee.api.Title;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.chat.ComponentSerializer;
import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.ProtocolConstants; import net.md_5.bungee.protocol.ProtocolConstants;
import net.md_5.bungee.protocol.packet.ClearTitles; import net.md_5.bungee.protocol.packet.ClearTitles;
@ -53,14 +53,21 @@ public class BungeeTitle implements Title
title = new TitlePacketHolder<>( packet, packet ); title = new TitlePacketHolder<>( packet, packet );
} }
title.oldPacket.setText( text ); // = newPacket title.oldPacket.setText( ComponentSerializer.toString( text ) ); // = newPacket
return this; return this;
} }
@Override @Override
public Title title(BaseComponent... text) public Title title(BaseComponent... text)
{ {
return title( TextComponent.fromArray( text ) ); if ( title == null )
{
net.md_5.bungee.protocol.packet.Title packet = new net.md_5.bungee.protocol.packet.Title( Action.TITLE );
title = new TitlePacketHolder<>( packet, packet );
}
title.oldPacket.setText( ComponentSerializer.toString( text ) ); // = newPacket
return this;
} }
@Override @Override
@ -71,15 +78,24 @@ public class BungeeTitle implements Title
subtitle = new TitlePacketHolder<>( new net.md_5.bungee.protocol.packet.Title( Action.SUBTITLE ), new Subtitle() ); subtitle = new TitlePacketHolder<>( new net.md_5.bungee.protocol.packet.Title( Action.SUBTITLE ), new Subtitle() );
} }
subtitle.oldPacket.setText( text ); String serialized = ComponentSerializer.toString( text );
subtitle.newPacket.setText( text ); subtitle.oldPacket.setText( serialized );
subtitle.newPacket.setText( serialized );
return this; return this;
} }
@Override @Override
public Title subTitle(BaseComponent... text) public Title subTitle(BaseComponent... text)
{ {
return subTitle( TextComponent.fromArray( text ) ); if ( subtitle == null )
{
subtitle = new TitlePacketHolder<>( new net.md_5.bungee.protocol.packet.Title( Action.SUBTITLE ), new Subtitle() );
}
String serialized = ComponentSerializer.toString( text );
subtitle.oldPacket.setText( serialized );
subtitle.newPacket.setText( serialized );
return this;
} }
@Override @Override

View File

@ -14,7 +14,6 @@ import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.event.ServerConnectEvent; import net.md_5.bungee.api.event.ServerConnectEvent;
import net.md_5.bungee.api.event.ServerConnectedEvent; import net.md_5.bungee.api.event.ServerConnectedEvent;
@ -35,7 +34,6 @@ import net.md_5.bungee.netty.ChannelWrapper;
import net.md_5.bungee.netty.HandlerBoss; import net.md_5.bungee.netty.HandlerBoss;
import net.md_5.bungee.netty.PacketHandler; import net.md_5.bungee.netty.PacketHandler;
import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.Either;
import net.md_5.bungee.protocol.PacketWrapper; import net.md_5.bungee.protocol.PacketWrapper;
import net.md_5.bungee.protocol.Protocol; import net.md_5.bungee.protocol.Protocol;
import net.md_5.bungee.protocol.ProtocolConstants; import net.md_5.bungee.protocol.ProtocolConstants;
@ -53,7 +51,6 @@ import net.md_5.bungee.protocol.packet.PluginMessage;
import net.md_5.bungee.protocol.packet.Respawn; import net.md_5.bungee.protocol.packet.Respawn;
import net.md_5.bungee.protocol.packet.ScoreboardObjective; import net.md_5.bungee.protocol.packet.ScoreboardObjective;
import net.md_5.bungee.protocol.packet.ScoreboardScore; import net.md_5.bungee.protocol.packet.ScoreboardScore;
import net.md_5.bungee.protocol.packet.ScoreboardScoreReset;
import net.md_5.bungee.protocol.packet.SetCompression; import net.md_5.bungee.protocol.packet.SetCompression;
import net.md_5.bungee.protocol.packet.StartConfiguration; import net.md_5.bungee.protocol.packet.StartConfiguration;
import net.md_5.bungee.protocol.packet.ViewDistance; import net.md_5.bungee.protocol.packet.ViewDistance;
@ -281,22 +278,11 @@ public class ServerConnector extends PacketHandler
Scoreboard serverScoreboard = user.getServerSentScoreboard(); Scoreboard serverScoreboard = user.getServerSentScoreboard();
for ( Objective objective : serverScoreboard.getObjectives() ) for ( Objective objective : serverScoreboard.getObjectives() )
{ {
user.unsafe().sendPacket( new ScoreboardObjective( user.unsafe().sendPacket( new ScoreboardObjective( objective.getName(), objective.getValue(), ScoreboardObjective.HealthDisplay.fromString( objective.getType() ), (byte) 1 ) );
objective.getName(),
( user.getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_13 ) ? Either.right( ComponentSerializer.deserialize( objective.getValue() ) ) : Either.left( objective.getValue() ),
ScoreboardObjective.HealthDisplay.fromString( objective.getType() ),
(byte) 1, null )
);
} }
for ( Score score : serverScoreboard.getScores() ) for ( Score score : serverScoreboard.getScores() )
{ {
if ( user.getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_20_3 ) user.unsafe().sendPacket( new ScoreboardScore( score.getItemName(), (byte) 1, score.getScoreName(), score.getValue() ) );
{
user.unsafe().sendPacket( new ScoreboardScoreReset( score.getItemName(), null ) );
} else
{
user.unsafe().sendPacket( new ScoreboardScore( score.getItemName(), (byte) 1, score.getScoreName(), score.getValue(), null, null ) );
}
} }
for ( Team team : serverScoreboard.getTeams() ) for ( Team team : serverScoreboard.getTeams() )
{ {
@ -397,10 +383,7 @@ public class ServerConnector extends PacketHandler
public void handle(Kick kick) throws Exception public void handle(Kick kick) throws Exception
{ {
ServerInfo def = user.updateAndGetNextServer( target ); ServerInfo def = user.updateAndGetNextServer( target );
ServerKickEvent event = new ServerKickEvent( user, target, new BaseComponent[] ServerKickEvent event = new ServerKickEvent( user, target, ComponentSerializer.parse( kick.getMessage() ), def, ServerKickEvent.State.CONNECTING );
{
kick.getMessage()
}, def, ServerKickEvent.State.CONNECTING );
if ( event.getKickReason().toLowerCase( Locale.ROOT ).contains( "outdated" ) && def != null ) if ( event.getKickReason().toLowerCase( Locale.ROOT ).contains( "outdated" ) && def != null )
{ {
// Pre cancel the event if we are going to try another server // Pre cancel the event if we are going to try another server

View File

@ -153,7 +153,7 @@ public final class UserConnection implements ProxiedPlayer
} }
}; };
public boolean init() public void init()
{ {
this.entityRewrite = EntityMap.getEntityMap( getPendingConnection().getVersion() ); this.entityRewrite = EntityMap.getEntityMap( getPendingConnection().getVersion() );
@ -172,8 +172,6 @@ public final class UserConnection implements ProxiedPlayer
// Set whether the connection has a 1.8 FML marker in the handshake. // Set whether the connection has a 1.8 FML marker in the handshake.
forgeClientHandler.setFmlTokenInHandshake( this.getPendingConnection().getExtraDataInHandshake().contains( ForgeConstants.FML_HANDSHAKE_TOKEN ) ); forgeClientHandler.setFmlTokenInHandshake( this.getPendingConnection().getExtraDataInHandshake().contains( ForgeConstants.FML_HANDSHAKE_TOKEN ) );
return BungeeCord.getInstance().addConnection( this );
} }
public void sendPacket(PacketWrapper packet) public void sendPacket(PacketWrapper packet)
@ -408,13 +406,13 @@ public final class UserConnection implements ProxiedPlayer
@Override @Override
public void disconnect(String reason) public void disconnect(String reason)
{ {
disconnect( TextComponent.fromLegacy( reason ) ); disconnect0( TextComponent.fromLegacyText( reason ) );
} }
@Override @Override
public void disconnect(BaseComponent... reason) public void disconnect(BaseComponent... reason)
{ {
disconnect( TextComponent.fromArray( reason ) ); disconnect0( reason );
} }
@Override @Override
@ -423,7 +421,7 @@ public final class UserConnection implements ProxiedPlayer
disconnect0( reason ); disconnect0( reason );
} }
public void disconnect0(final BaseComponent reason) public void disconnect0(final BaseComponent... reason)
{ {
if ( !ch.isClosing() ) if ( !ch.isClosing() )
{ {
@ -432,7 +430,7 @@ public final class UserConnection implements ProxiedPlayer
getName(), BaseComponent.toLegacyText( reason ) getName(), BaseComponent.toLegacyText( reason )
} ); } );
ch.close( new Kick( reason ) ); ch.close( new Kick( ComponentSerializer.toString( reason ) ) );
if ( server != null ) if ( server != null )
{ {
@ -456,7 +454,7 @@ public final class UserConnection implements ProxiedPlayer
@Override @Override
public void sendMessage(String message) public void sendMessage(String message)
{ {
sendMessage( TextComponent.fromLegacy( message ) ); sendMessage( TextComponent.fromLegacyText( message ) );
} }
@Override @Override
@ -483,7 +481,7 @@ public final class UserConnection implements ProxiedPlayer
@Override @Override
public void sendMessage(ChatMessageType position, BaseComponent... message) public void sendMessage(ChatMessageType position, BaseComponent... message)
{ {
sendMessage( position, null, TextComponent.fromArray( message ) ); sendMessage( position, null, message );
} }
@Override @Override
@ -495,7 +493,7 @@ public final class UserConnection implements ProxiedPlayer
@Override @Override
public void sendMessage(UUID sender, BaseComponent... message) public void sendMessage(UUID sender, BaseComponent... message)
{ {
sendMessage( ChatMessageType.CHAT, sender, TextComponent.fromArray( message ) ); sendMessage( ChatMessageType.CHAT, sender, message );
} }
@Override @Override
@ -504,28 +502,8 @@ public final class UserConnection implements ProxiedPlayer
sendMessage( ChatMessageType.CHAT, sender, message ); sendMessage( ChatMessageType.CHAT, sender, message );
} }
private void sendMessage(ChatMessageType position, UUID sender, BaseComponent message) private void sendMessage(ChatMessageType position, UUID sender, String message)
{ {
// transform score components
message = ChatComponentTransformer.getInstance().transform( this, true, message );
if ( position == ChatMessageType.ACTION_BAR && getPendingConnection().getVersion() < ProtocolConstants.MINECRAFT_1_17 )
{
// Versions older than 1.11 cannot send the Action bar with the new JSON formattings
// Fix by converting to a legacy message, see https://bugs.mojang.com/browse/MC-119145
if ( getPendingConnection().getVersion() <= ProtocolConstants.MINECRAFT_1_10 )
{
message = new TextComponent( BaseComponent.toLegacyText( message ) );
} else
{
net.md_5.bungee.protocol.packet.Title title = new net.md_5.bungee.protocol.packet.Title();
title.setAction( net.md_5.bungee.protocol.packet.Title.Action.ACTIONBAR );
title.setText( message );
sendPacketQueued( title );
return;
}
}
if ( getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_19 ) if ( getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_19 )
{ {
// Align with Spigot and remove client side formatting for now // Align with Spigot and remove client side formatting for now
@ -537,7 +515,32 @@ public final class UserConnection implements ProxiedPlayer
sendPacketQueued( new SystemChat( message, position.ordinal() ) ); sendPacketQueued( new SystemChat( message, position.ordinal() ) );
} else } else
{ {
sendPacketQueued( new Chat( ComponentSerializer.toString( message ), (byte) position.ordinal(), sender ) ); sendPacketQueued( new Chat( message, (byte) position.ordinal(), sender ) );
}
}
private void sendMessage(ChatMessageType position, UUID sender, BaseComponent... message)
{
// transform score components
message = ChatComponentTransformer.getInstance().transform( this, true, message );
if ( position == ChatMessageType.ACTION_BAR && getPendingConnection().getVersion() < ProtocolConstants.MINECRAFT_1_17 )
{
// Versions older than 1.11 cannot send the Action bar with the new JSON formattings
// Fix by converting to a legacy message, see https://bugs.mojang.com/browse/MC-119145
if ( getPendingConnection().getVersion() <= ProtocolConstants.MINECRAFT_1_10 )
{
sendMessage( position, sender, ComponentSerializer.toString( new TextComponent( BaseComponent.toLegacyText( message ) ) ) );
} else
{
net.md_5.bungee.protocol.packet.Title title = new net.md_5.bungee.protocol.packet.Title();
title.setAction( net.md_5.bungee.protocol.packet.Title.Action.ACTIONBAR );
title.setText( ComponentSerializer.toString( message ) );
sendPacketQueued( title );
}
} else
{
sendMessage( position, sender, ComponentSerializer.toString( message ) );
} }
} }
@ -717,19 +720,25 @@ public final class UserConnection implements ProxiedPlayer
@Override @Override
public void setTabHeader(BaseComponent header, BaseComponent footer) public void setTabHeader(BaseComponent header, BaseComponent footer)
{ {
header = ChatComponentTransformer.getInstance().transform( this, true, header ); header = ChatComponentTransformer.getInstance().transform( this, true, header )[0];
footer = ChatComponentTransformer.getInstance().transform( this, true, footer ); footer = ChatComponentTransformer.getInstance().transform( this, true, footer )[0];
sendPacketQueued( new PlayerListHeaderFooter( sendPacketQueued( new PlayerListHeaderFooter(
header, ComponentSerializer.toString( header ),
footer ComponentSerializer.toString( footer )
) ); ) );
} }
@Override @Override
public void setTabHeader(BaseComponent[] header, BaseComponent[] footer) public void setTabHeader(BaseComponent[] header, BaseComponent[] footer)
{ {
setTabHeader( TextComponent.fromArray( header ), TextComponent.fromArray( footer ) ); header = ChatComponentTransformer.getInstance().transform( this, true, header );
footer = ChatComponentTransformer.getInstance().transform( this, true, footer );
sendPacketQueued( new PlayerListHeaderFooter(
ComponentSerializer.toString( header ),
ComponentSerializer.toString( footer )
) );
} }
@Override @Override

View File

@ -1,5 +1,6 @@
package net.md_5.bungee.conf; package net.md_5.bungee.conf;
import com.google.common.base.Charsets;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -9,7 +10,6 @@ import java.io.InputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.Writer; import java.io.Writer;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@ -176,7 +176,7 @@ public class YamlConfig implements ConfigurationAdapter
{ {
try try
{ {
try ( Writer wr = new OutputStreamWriter( new FileOutputStream( file ), StandardCharsets.UTF_8 ) ) try ( Writer wr = new OutputStreamWriter( new FileOutputStream( file ), Charsets.UTF_8 ) )
{ {
yaml.dump( config, wr ); yaml.dump( config, wr );
} }

View File

@ -72,7 +72,6 @@ import net.md_5.bungee.protocol.packet.Respawn;
import net.md_5.bungee.protocol.packet.ScoreboardDisplay; import net.md_5.bungee.protocol.packet.ScoreboardDisplay;
import net.md_5.bungee.protocol.packet.ScoreboardObjective; import net.md_5.bungee.protocol.packet.ScoreboardObjective;
import net.md_5.bungee.protocol.packet.ScoreboardScore; import net.md_5.bungee.protocol.packet.ScoreboardScore;
import net.md_5.bungee.protocol.packet.ScoreboardScoreReset;
import net.md_5.bungee.protocol.packet.ServerData; import net.md_5.bungee.protocol.packet.ServerData;
import net.md_5.bungee.protocol.packet.SetCompression; import net.md_5.bungee.protocol.packet.SetCompression;
import net.md_5.bungee.protocol.packet.TabCompleteResponse; import net.md_5.bungee.protocol.packet.TabCompleteResponse;
@ -189,7 +188,7 @@ public class DownstreamBridge extends PacketHandler
switch ( objective.getAction() ) switch ( objective.getAction() )
{ {
case 0: case 0:
serverScoreboard.addObjective( new Objective( objective.getName(), ( objective.getValue().isLeft() ) ? objective.getValue().getLeft() : ComponentSerializer.toString( objective.getValue().getRight() ), objective.getType().toString() ) ); serverScoreboard.addObjective( new Objective( objective.getName(), objective.getValue(), objective.getType().toString() ) );
break; break;
case 1: case 1:
serverScoreboard.removeObjective( objective.getName() ); serverScoreboard.removeObjective( objective.getName() );
@ -198,7 +197,7 @@ public class DownstreamBridge extends PacketHandler
Objective oldObjective = serverScoreboard.getObjective( objective.getName() ); Objective oldObjective = serverScoreboard.getObjective( objective.getName() );
if ( oldObjective != null ) if ( oldObjective != null )
{ {
oldObjective.setValue( ( objective.getValue().isLeft() ) ? objective.getValue().getLeft() : ComponentSerializer.toString( objective.getValue().getRight() ) ); oldObjective.setValue( objective.getValue() );
oldObjective.setType( objective.getType().toString() ); oldObjective.setType( objective.getType().toString() );
} }
break; break;
@ -226,18 +225,6 @@ public class DownstreamBridge extends PacketHandler
} }
} }
@Override
public void handle(ScoreboardScoreReset scoreboardScoreReset) throws Exception
{
Scoreboard serverScoreboard = con.getServerSentScoreboard();
// TODO: Expand score API to handle objective values. Shouldn't matter currently as only used for removing score entries.
if ( scoreboardScoreReset.getScoreName() == null )
{
serverScoreboard.removeScore( scoreboardScoreReset.getItemName() );
}
}
@Override @Override
public void handle(ScoreboardDisplay displayScoreboard) throws Exception public void handle(ScoreboardDisplay displayScoreboard) throws Exception
{ {
@ -272,9 +259,9 @@ public class DownstreamBridge extends PacketHandler
{ {
if ( team.getMode() == 0 || team.getMode() == 2 ) if ( team.getMode() == 0 || team.getMode() == 2 )
{ {
t.setDisplayName( ComponentSerializer.toString( team.getDisplayName() ) ); t.setDisplayName( team.getDisplayName() );
t.setPrefix( ComponentSerializer.toString( team.getPrefix() ) ); t.setPrefix( team.getPrefix() );
t.setSuffix( ComponentSerializer.toString( team.getSuffix() ) ); t.setSuffix( team.getSuffix() );
t.setFriendlyFire( team.getFriendlyFire() ); t.setFriendlyFire( team.getFriendlyFire() );
t.setNameTagVisibility( team.getNameTagVisibility() ); t.setNameTagVisibility( team.getNameTagVisibility() );
t.setCollisionRule( team.getCollisionRule() ); t.setCollisionRule( team.getCollisionRule() );
@ -638,16 +625,13 @@ public class DownstreamBridge extends PacketHandler
public void handle(Kick kick) throws Exception public void handle(Kick kick) throws Exception
{ {
ServerInfo def = con.updateAndGetNextServer( server.getInfo() ); ServerInfo def = con.updateAndGetNextServer( server.getInfo() );
ServerKickEvent event = bungee.getPluginManager().callEvent( new ServerKickEvent( con, server.getInfo(), new BaseComponent[] ServerKickEvent event = bungee.getPluginManager().callEvent( new ServerKickEvent( con, server.getInfo(), ComponentSerializer.parse( kick.getMessage() ), def, ServerKickEvent.State.CONNECTED ) );
{
kick.getMessage()
}, def, ServerKickEvent.State.CONNECTED ) );
if ( event.isCancelled() && event.getCancelServer() != null ) if ( event.isCancelled() && event.getCancelServer() != null )
{ {
con.connectNow( event.getCancelServer(), ServerConnectEvent.Reason.KICK_REDIRECT ); con.connectNow( event.getCancelServer(), ServerConnectEvent.Reason.KICK_REDIRECT );
} else } else
{ {
con.disconnect( event.getKickReasonComponent() ); // TODO: Prefix our own stuff. con.disconnect0( event.getKickReasonComponent() ); // TODO: Prefix our own stuff.
} }
server.setObsolete( true ); server.setObsolete( true );
throw CancelSendSignal.INSTANCE; throw CancelSendSignal.INSTANCE;

View File

@ -1,5 +1,6 @@
package net.md_5.bungee.connection; package net.md_5.bungee.connection;
import com.google.common.base.Charsets;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.gson.Gson; import com.google.gson.Gson;
import java.math.BigInteger; import java.math.BigInteger;
@ -38,6 +39,7 @@ import net.md_5.bungee.api.event.PostLoginEvent;
import net.md_5.bungee.api.event.PreLoginEvent; import net.md_5.bungee.api.event.PreLoginEvent;
import net.md_5.bungee.api.event.ProxyPingEvent; import net.md_5.bungee.api.event.ProxyPingEvent;
import net.md_5.bungee.api.event.ServerConnectEvent; import net.md_5.bungee.api.event.ServerConnectEvent;
import net.md_5.bungee.chat.ComponentSerializer;
import net.md_5.bungee.http.HttpClient; import net.md_5.bungee.http.HttpClient;
import net.md_5.bungee.jni.cipher.BungeeCipher; import net.md_5.bungee.jni.cipher.BungeeCipher;
import net.md_5.bungee.netty.ChannelWrapper; import net.md_5.bungee.netty.ChannelWrapper;
@ -434,8 +436,8 @@ public class InitialHandler extends PacketHandler implements PendingConnection
{ {
if ( result.isCancelled() ) if ( result.isCancelled() )
{ {
BaseComponent reason = result.getReason(); BaseComponent[] reason = result.getCancelReasonComponents();
disconnect( ( reason != null ) ? reason : TextComponent.fromLegacy( bungee.getTranslation( "kick_message" ) ) ); disconnect( ( reason != null ) ? reason : TextComponent.fromLegacyText( bungee.getTranslation( "kick_message" ) ) );
return; return;
} }
if ( ch.isClosed() ) if ( ch.isClosed() )
@ -603,8 +605,8 @@ public class InitialHandler extends PacketHandler implements PendingConnection
{ {
if ( result.isCancelled() ) if ( result.isCancelled() )
{ {
BaseComponent reason = result.getReason(); BaseComponent[] reason = result.getCancelReasonComponents();
disconnect( ( reason != null ) ? reason : TextComponent.fromLegacy( bungee.getTranslation( "kick_message" ) ) ); disconnect( ( reason != null ) ? reason : TextComponent.fromLegacyText( bungee.getTranslation( "kick_message" ) ) );
return; return;
} }
if ( ch.isClosed() ) if ( ch.isClosed() )
@ -640,11 +642,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
private void finish2() private void finish2()
{ {
if ( !userCon.init() ) userCon.init();
{
disconnect( bungee.getTranslation( "already_connected_proxy" ) );
return;
}
ch.getHandle().pipeline().get( HandlerBoss.class ).setHandler( new UpstreamBridge( bungee, userCon ) ); ch.getHandle().pipeline().get( HandlerBoss.class ).setHandler( new UpstreamBridge( bungee, userCon ) );
bungee.getPluginManager().callEvent( new PostLoginEvent( userCon ) ); bungee.getPluginManager().callEvent( new PostLoginEvent( userCon ) );
@ -675,7 +673,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
{ {
if ( canSendKickMessage() ) if ( canSendKickMessage() )
{ {
disconnect( TextComponent.fromLegacy( reason ) ); disconnect( TextComponent.fromLegacyText( reason ) );
} else } else
{ {
ch.close(); ch.close();
@ -685,19 +683,22 @@ public class InitialHandler extends PacketHandler implements PendingConnection
@Override @Override
public void disconnect(final BaseComponent... reason) public void disconnect(final BaseComponent... reason)
{ {
disconnect( TextComponent.fromArray( reason ) ); if ( canSendKickMessage() )
{
ch.delayedClose( new Kick( ComponentSerializer.toString( reason ) ) );
} else
{
ch.close();
}
} }
@Override @Override
public void disconnect(BaseComponent reason) public void disconnect(BaseComponent reason)
{ {
if ( canSendKickMessage() ) disconnect( new BaseComponent[]
{ {
ch.delayedClose( new Kick( reason ) ); reason
} else } );
{
ch.close();
}
} }
@Override @Override
@ -754,11 +755,6 @@ public class InitialHandler extends PacketHandler implements PendingConnection
return (int) ( duplicatedId.getMostSignificantBits() >> 8 ) & 0xF; return (int) ( duplicatedId.getMostSignificantBits() >> 8 ) & 0xF;
} }
private void updateOfflineId()
{
offlineId = UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + getName() ).getBytes( StandardCharsets.UTF_8 ) );
}
@Override @Override
public int getVersion() public int getVersion()
{ {
@ -798,6 +794,11 @@ public class InitialHandler extends PacketHandler implements PendingConnection
this.uniqueId = uuid; this.uniqueId = uuid;
} }
private void updateOfflineId()
{
offlineId = UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + getName() ).getBytes( Charsets.UTF_8 ) );
}
@Override @Override
public String getUUID() public String getUUID()
{ {

View File

@ -54,6 +54,7 @@ public class UpstreamBridge extends PacketHandler
this.bungee = bungee; this.bungee = bungee;
this.con = con; this.con = con;
BungeeCord.getInstance().addConnection( con );
con.getTabListHandler().onConnect(); con.getTabListHandler().onConnect();
} }

View File

@ -84,8 +84,6 @@ public abstract class EntityMap
return EntityMap_1_16_2.INSTANCE_1_19_4; return EntityMap_1_16_2.INSTANCE_1_19_4;
case ProtocolConstants.MINECRAFT_1_20_2: case ProtocolConstants.MINECRAFT_1_20_2:
return EntityMap_1_16_2.INSTANCE_1_20_2; return EntityMap_1_16_2.INSTANCE_1_20_2;
case ProtocolConstants.MINECRAFT_1_20_3:
return EntityMap_1_16_2.INSTANCE_1_20_3;
} }
throw new RuntimeException( "Version " + version + " has no entity map" ); throw new RuntimeException( "Version " + version + " has no entity map" );
} }

View File

@ -21,7 +21,6 @@ class EntityMap_1_16_2 extends EntityMap
static final EntityMap_1_16_2 INSTANCE_1_19_1 = new EntityMap_1_16_2( 0x02, 0x30 ); static final EntityMap_1_16_2 INSTANCE_1_19_1 = new EntityMap_1_16_2( 0x02, 0x30 );
static final EntityMap_1_16_2 INSTANCE_1_19_4 = new EntityMap_1_16_2( 0x03, 0x30 ); static final EntityMap_1_16_2 INSTANCE_1_19_4 = new EntityMap_1_16_2( 0x03, 0x30 );
static final EntityMap_1_16_2 INSTANCE_1_20_2 = new EntityMap_1_16_2( -1, 0x33 ); static final EntityMap_1_16_2 INSTANCE_1_20_2 = new EntityMap_1_16_2( -1, 0x33 );
static final EntityMap_1_16_2 INSTANCE_1_20_3 = new EntityMap_1_16_2( -1, 0x34 );
// //
private final int spawnPlayerId; private final int spawnPlayerId;
private final int spectateId; private final int spectateId;

View File

@ -1,9 +1,9 @@
package net.md_5.bungee.forge; package net.md_5.bungee.forge;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import java.nio.charset.StandardCharsets;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -22,7 +22,7 @@ public class ForgeUtils
*/ */
public static Set<String> readRegisteredChannels(PluginMessage pluginMessage) public static Set<String> readRegisteredChannels(PluginMessage pluginMessage)
{ {
String channels = new String( pluginMessage.getData(), StandardCharsets.UTF_8 ); String channels = new String( pluginMessage.getData(), Charsets.UTF_8 );
String[] split = channels.split( "\0" ); String[] split = channels.split( "\0" );
Set<String> channelSet = ImmutableSet.copyOf( split ); Set<String> channelSet = ImmutableSet.copyOf( split );
return channelSet; return channelSet;

View File

@ -172,7 +172,10 @@ public class HandlerBoss extends ChannelInboundHandlerAdapter
} ); } );
} else } else
{ {
ProxyServer.getInstance().getLogger().log( Level.WARNING, handler + " - could not decode packet!", cause ); ProxyServer.getInstance().getLogger().log( Level.WARNING, "{0} - could not decode packet! {1}", new Object[]
{
handler, cause
} );
} }
} else if ( cause instanceof IOException || ( cause instanceof IllegalStateException && handler instanceof InitialHandler ) ) } else if ( cause instanceof IOException || ( cause instanceof IllegalStateException && handler instanceof InitialHandler ) )
{ {

View File

@ -27,11 +27,6 @@ public final class AllowedCharacters
public static boolean isValidName(String name, boolean onlineMode) public static boolean isValidName(String name, boolean onlineMode)
{ {
if ( name.isEmpty() || name.length() > 16 )
{
return false;
}
for ( int index = 0, len = name.length(); index < len; index++ ) for ( int index = 0, len = name.length(); index < len; index++ )
{ {
if ( !isNameAllowedCharacter( name.charAt( index ), onlineMode ) ) if ( !isNameAllowedCharacter( name.charAt( index ), onlineMode ) )

View File

@ -1,9 +1,9 @@
package net.md_5.bungee.util; package net.md_5.bungee.util;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import java.util.List; import java.util.List;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
@ -34,13 +34,16 @@ public final class ChatComponentTransformer
*/ */
private static final Pattern SELECTOR_PATTERN = Pattern.compile( "^@([pares])(?:\\[([^ ]*)\\])?$" ); private static final Pattern SELECTOR_PATTERN = Pattern.compile( "^@([pares])(?:\\[([^ ]*)\\])?$" );
public BaseComponent legacyHoverTransform(ProxiedPlayer player, BaseComponent next) public BaseComponent[] legacyHoverTransform(ProxiedPlayer player, BaseComponent... components)
{ {
if ( player.getPendingConnection().getVersion() < ProtocolConstants.MINECRAFT_1_16 ) if ( player.getPendingConnection().getVersion() < ProtocolConstants.MINECRAFT_1_16 )
{ {
for ( int i = 0; i < components.length; i++ )
{
BaseComponent next = components[i];
if ( next.getHoverEvent() == null || next.getHoverEvent().isLegacy() ) if ( next.getHoverEvent() == null || next.getHoverEvent().isLegacy() )
{ {
return next; continue;
} }
next = next.duplicate(); next = next.duplicate();
next.getHoverEvent().setLegacy( true ); next.getHoverEvent().setLegacy( true );
@ -50,9 +53,11 @@ public final class ChatComponentTransformer
next.getHoverEvent().getContents().clear(); next.getHoverEvent().getContents().clear();
next.getHoverEvent().getContents().add( exception ); next.getHoverEvent().getContents().add( exception );
} }
components[i] = next;
}
} }
return next; return components;
} }
public static ChatComponentTransformer getInstance() public static ChatComponentTransformer getInstance()
@ -72,7 +77,7 @@ public final class ChatComponentTransformer
* TextComponent if the components are null or empty * TextComponent if the components are null or empty
* @throws IllegalArgumentException if an entity selector pattern is present * @throws IllegalArgumentException if an entity selector pattern is present
*/ */
public BaseComponent transform(ProxiedPlayer player, BaseComponent components) public BaseComponent[] transform(ProxiedPlayer player, BaseComponent... components)
{ {
return transform( player, false, components ); return transform( player, false, components );
} }
@ -86,26 +91,31 @@ public final class ChatComponentTransformer
* @param player player * @param player player
* @param transformHover if the hover event should replace contents with * @param transformHover if the hover event should replace contents with
* value * value
* @param root the component to transform * @param components the component to transform
* @return the transformed component, or an array containing a single empty * @return the transformed component, or an array containing a single empty
* TextComponent if the components are null or empty * TextComponent if the components are null or empty
* @throws IllegalArgumentException if an entity selector pattern is present * @throws IllegalArgumentException if an entity selector pattern is present
*/ */
public BaseComponent transform(ProxiedPlayer player, boolean transformHover, BaseComponent root) public BaseComponent[] transform(ProxiedPlayer player, boolean transformHover, BaseComponent... components)
{ {
if ( root == null ) if ( components == null || components.length < 1 || ( components.length == 1 && components[0] == null ) )
{ {
return new TextComponent( "" ); return new BaseComponent[]
{
new TextComponent( "" )
};
} }
if ( transformHover ) if ( transformHover )
{ {
root = legacyHoverTransform( player, root ); components = legacyHoverTransform( player, components );
} }
for ( BaseComponent root : components )
{
if ( root.getExtra() != null && !root.getExtra().isEmpty() ) if ( root.getExtra() != null && !root.getExtra().isEmpty() )
{ {
List<BaseComponent> list = root.getExtra().stream().map( (extra) -> transform( player, transformHover, extra ) ).collect( Collectors.toList() ); List<BaseComponent> list = Lists.newArrayList( transform( player, transformHover, root.getExtra().toArray( new BaseComponent[ 0 ] ) ) );
root.setExtra( list ); root.setExtra( list );
} }
@ -113,8 +123,8 @@ public final class ChatComponentTransformer
{ {
transformScoreComponent( player, (ScoreComponent) root ); transformScoreComponent( player, (ScoreComponent) root );
} }
}
return root; return components;
} }
/** /**