Move chat API into own submodule.
This commit is contained in:
@@ -20,9 +20,9 @@
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.2.4</version>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-chat</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@@ -1,191 +0,0 @@
|
||||
package net.md_5.bungee.api;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* Simplistic enumeration of all supported color values for chat.
|
||||
*/
|
||||
public enum ChatColor
|
||||
{
|
||||
|
||||
/**
|
||||
* Represents black.
|
||||
*/
|
||||
BLACK( '0', "black" ),
|
||||
/**
|
||||
* Represents dark blue.
|
||||
*/
|
||||
DARK_BLUE( '1', "dark_blue" ),
|
||||
/**
|
||||
* Represents dark green.
|
||||
*/
|
||||
DARK_GREEN( '2', "dark_green" ),
|
||||
/**
|
||||
* Represents dark blue (aqua).
|
||||
*/
|
||||
DARK_AQUA( '3', "dark_aqua" ),
|
||||
/**
|
||||
* Represents dark red.
|
||||
*/
|
||||
DARK_RED( '4', "dark_red" ),
|
||||
/**
|
||||
* Represents dark purple.
|
||||
*/
|
||||
DARK_PURPLE( '5', "dark_purple" ),
|
||||
/**
|
||||
* Represents gold.
|
||||
*/
|
||||
GOLD( '6', "gold" ),
|
||||
/**
|
||||
* Represents gray.
|
||||
*/
|
||||
GRAY( '7', "gray" ),
|
||||
/**
|
||||
* Represents dark gray.
|
||||
*/
|
||||
DARK_GRAY( '8', "dark_gray" ),
|
||||
/**
|
||||
* Represents blue.
|
||||
*/
|
||||
BLUE( '9', "blue" ),
|
||||
/**
|
||||
* Represents green.
|
||||
*/
|
||||
GREEN( 'a', "green" ),
|
||||
/**
|
||||
* Represents aqua.
|
||||
*/
|
||||
AQUA( 'b', "aqua" ),
|
||||
/**
|
||||
* Represents red.
|
||||
*/
|
||||
RED( 'c', "red" ),
|
||||
/**
|
||||
* Represents light purple.
|
||||
*/
|
||||
LIGHT_PURPLE( 'd', "light_purple" ),
|
||||
/**
|
||||
* Represents yellow.
|
||||
*/
|
||||
YELLOW( 'e', "yellow" ),
|
||||
/**
|
||||
* Represents white.
|
||||
*/
|
||||
WHITE( 'f', "white" ),
|
||||
/**
|
||||
* Represents magical characters that change around randomly.
|
||||
*/
|
||||
MAGIC( 'k', "obfuscated" ),
|
||||
/**
|
||||
* Makes the text bold.
|
||||
*/
|
||||
BOLD( 'l', "bold" ),
|
||||
/**
|
||||
* Makes a line appear through the text.
|
||||
*/
|
||||
STRIKETHROUGH( 'm', "strikethrough" ),
|
||||
/**
|
||||
* Makes the text appear underlined.
|
||||
*/
|
||||
UNDERLINE( 'n', "underline" ),
|
||||
/**
|
||||
* Makes the text italic.
|
||||
*/
|
||||
ITALIC( 'o', "italic" ),
|
||||
/**
|
||||
* Resets all previous chat colors or formats.
|
||||
*/
|
||||
RESET( 'r', "reset" );
|
||||
/**
|
||||
* The special character which prefixes all chat colour codes. Use this if
|
||||
* you need to dynamically convert colour codes from your custom format.
|
||||
*/
|
||||
public static final char COLOR_CHAR = '\u00A7';
|
||||
public static final String ALL_CODES = "0123456789AaBbCcDdEeFfKkLlMmNnOoRr";
|
||||
/**
|
||||
* Pattern to remove all colour codes.
|
||||
*/
|
||||
public static final Pattern STRIP_COLOR_PATTERN = Pattern.compile( "(?i)" + String.valueOf( COLOR_CHAR ) + "[0-9A-FK-OR]" );
|
||||
/**
|
||||
* Colour instances keyed by their active character.
|
||||
*/
|
||||
private static final Map<Character, ChatColor> BY_CHAR = new HashMap<>();
|
||||
/**
|
||||
* The code appended to {@link #COLOR_CHAR} to make usable colour.
|
||||
*/
|
||||
private final char code;
|
||||
/**
|
||||
* This colour's colour char prefixed by the {@link #COLOR_CHAR}.
|
||||
*/
|
||||
private final String toString;
|
||||
@Getter
|
||||
private final String name;
|
||||
|
||||
static
|
||||
{
|
||||
for ( ChatColor colour : values() )
|
||||
{
|
||||
BY_CHAR.put( colour.code, colour );
|
||||
}
|
||||
}
|
||||
|
||||
private ChatColor(char code, String name)
|
||||
{
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
this.toString = new String( new char[]
|
||||
{
|
||||
COLOR_CHAR, code
|
||||
} );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return toString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips the given message of all color codes
|
||||
*
|
||||
* @param input String to strip of color
|
||||
* @return A copy of the input string, without any coloring
|
||||
*/
|
||||
public static String stripColor(final String input)
|
||||
{
|
||||
if ( input == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return STRIP_COLOR_PATTERN.matcher( input ).replaceAll( "" );
|
||||
}
|
||||
|
||||
public static String translateAlternateColorCodes(char altColorChar, String textToTranslate)
|
||||
{
|
||||
char[] b = textToTranslate.toCharArray();
|
||||
for ( int i = 0; i < b.length - 1; i++ )
|
||||
{
|
||||
if ( b[i] == altColorChar && ALL_CODES.indexOf( b[i + 1] ) > -1 )
|
||||
{
|
||||
b[i] = ChatColor.COLOR_CHAR;
|
||||
b[i + 1] = Character.toLowerCase( b[i + 1] );
|
||||
}
|
||||
}
|
||||
return new String( b );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the colour represented by the specified code.
|
||||
*
|
||||
* @param code the code to search for
|
||||
* @return the mapped colour, or null if non exists
|
||||
*/
|
||||
public static ChatColor getByChar(char code)
|
||||
{
|
||||
return BY_CHAR.get( code );
|
||||
}
|
||||
}
|
@@ -1,391 +0,0 @@
|
||||
package net.md_5.bungee.api.chat;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.ToString;
|
||||
|
||||
@Setter
|
||||
@ToString
|
||||
@NoArgsConstructor
|
||||
public abstract class BaseComponent
|
||||
{
|
||||
|
||||
@Setter(AccessLevel.NONE)
|
||||
BaseComponent parent;
|
||||
|
||||
/**
|
||||
* The color of this component and any child components (unless overridden)
|
||||
*/
|
||||
private ChatColor color;
|
||||
/**
|
||||
* Whether this component and any child components (unless overridden) is
|
||||
* bold
|
||||
*/
|
||||
private Boolean bold;
|
||||
/**
|
||||
* Whether this component and any child components (unless overridden) is
|
||||
* italic
|
||||
*/
|
||||
private Boolean italic;
|
||||
/**
|
||||
* Whether this component and any child components (unless overridden) is
|
||||
* underlined
|
||||
*/
|
||||
private Boolean underlined;
|
||||
/**
|
||||
* Whether this component and any child components (unless overridden) is
|
||||
* strikethrough
|
||||
*/
|
||||
private Boolean strikethrough;
|
||||
/**
|
||||
* Whether this component and any child components (unless overridden) is
|
||||
* obfuscated
|
||||
*/
|
||||
private Boolean obfuscated;
|
||||
|
||||
/**
|
||||
* Appended components that inherit this component's formatting and events
|
||||
*/
|
||||
@Getter
|
||||
private List<BaseComponent> extra;
|
||||
|
||||
/**
|
||||
* The action to preform when this component (and child components) are
|
||||
* clicked
|
||||
*/
|
||||
@Getter
|
||||
private ClickEvent clickEvent;
|
||||
/**
|
||||
* The action to preform when this component (and child components) are
|
||||
* hovered over
|
||||
*/
|
||||
@Getter
|
||||
private HoverEvent hoverEvent;
|
||||
|
||||
BaseComponent(BaseComponent old)
|
||||
{
|
||||
setColor( old.getColorRaw() );
|
||||
setBold( old.isBoldRaw() );
|
||||
setItalic( old.isItalicRaw() );
|
||||
setUnderlined( old.isUnderlinedRaw() );
|
||||
setStrikethrough( old.isStrikethroughRaw() );
|
||||
setObfuscated( old.isObfuscatedRaw() );
|
||||
setClickEvent( old.getClickEvent() );
|
||||
setHoverEvent( old.getHoverEvent() );
|
||||
if ( extra != null )
|
||||
{
|
||||
for ( BaseComponent component : extra )
|
||||
{
|
||||
addExtra( component.duplicate() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones the BaseComponent and returns the clone.
|
||||
*
|
||||
* @return The duplicate of this BaseComponent
|
||||
*/
|
||||
public abstract BaseComponent duplicate();
|
||||
|
||||
/**
|
||||
* Converts the components to a string that uses the old formatting codes
|
||||
* ({@link net.md_5.bungee.api.ChatColor#COLOR_CHAR}
|
||||
*
|
||||
* @param components the components to convert
|
||||
* @return the string in the old format
|
||||
*/
|
||||
public static String toLegacyText(BaseComponent... components)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for ( BaseComponent msg : components )
|
||||
{
|
||||
builder.append( msg.toLegacyText() );
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the components into a string without any formatting
|
||||
*
|
||||
* @param components the components to convert
|
||||
* @return the string as plain text
|
||||
*/
|
||||
public static String toPlainText(BaseComponent... components)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for ( BaseComponent msg : components )
|
||||
{
|
||||
builder.append( msg.toPlainText() );
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the color of this component. This uses the parent's color if this
|
||||
* component doesn't have one. {@link net.md_5.bungee.api.ChatColor#WHITE}
|
||||
* is returned if no color is found.
|
||||
*
|
||||
* @return the color of this component
|
||||
*/
|
||||
public ChatColor getColor()
|
||||
{
|
||||
if ( color == null )
|
||||
{
|
||||
if ( parent == null )
|
||||
{
|
||||
return ChatColor.WHITE;
|
||||
}
|
||||
return parent.getColor();
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the color of this component without checking the parents color.
|
||||
* May return null
|
||||
*
|
||||
* @return the color of this component
|
||||
*/
|
||||
public ChatColor getColorRaw()
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this component is bold. This uses the parent's setting if
|
||||
* this component hasn't been set. false is returned if none of the parent
|
||||
* chain has been set.
|
||||
*
|
||||
* @return whether the component is bold
|
||||
*/
|
||||
public boolean isBold()
|
||||
{
|
||||
if ( bold == null )
|
||||
{
|
||||
return parent != null && parent.isBold();
|
||||
}
|
||||
return bold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this component is bold without checking the parents
|
||||
* setting. May return null
|
||||
*
|
||||
* @return whether the component is bold
|
||||
*/
|
||||
public Boolean isBoldRaw()
|
||||
{
|
||||
return bold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this component is italic. This uses the parent's setting
|
||||
* if this component hasn't been set. false is returned if none of the
|
||||
* parent chain has been set.
|
||||
*
|
||||
* @return whether the component is italic
|
||||
*/
|
||||
public boolean isItalic()
|
||||
{
|
||||
if ( italic == null )
|
||||
{
|
||||
return parent != null && parent.isItalic();
|
||||
}
|
||||
return italic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this component is italic without checking the parents
|
||||
* setting. May return null
|
||||
*
|
||||
* @return whether the component is italic
|
||||
*/
|
||||
public Boolean isItalicRaw()
|
||||
{
|
||||
return italic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this component is underlined. This uses the parent's
|
||||
* setting if this component hasn't been set. false is returned if none of
|
||||
* the parent chain has been set.
|
||||
*
|
||||
* @return whether the component is underlined
|
||||
*/
|
||||
public boolean isUnderlined()
|
||||
{
|
||||
if ( underlined == null )
|
||||
{
|
||||
return parent != null && parent.isUnderlined();
|
||||
}
|
||||
return underlined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this component is underlined without checking the parents
|
||||
* setting. May return null
|
||||
*
|
||||
* @return whether the component is underlined
|
||||
*/
|
||||
public Boolean isUnderlinedRaw()
|
||||
{
|
||||
return underlined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this component is strikethrough. This uses the parent's
|
||||
* setting if this component hasn't been set. false is returned if none of
|
||||
* the parent chain has been set.
|
||||
*
|
||||
* @return whether the component is strikethrough
|
||||
*/
|
||||
public boolean isStrikethrough()
|
||||
{
|
||||
if ( strikethrough == null )
|
||||
{
|
||||
return parent != null && parent.isStrikethrough();
|
||||
}
|
||||
return strikethrough;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this component is strikethrough without checking the
|
||||
* parents setting. May return null
|
||||
*
|
||||
* @return whether the component is strikethrough
|
||||
*/
|
||||
public Boolean isStrikethroughRaw()
|
||||
{
|
||||
return strikethrough;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this component is obfuscated. This uses the parent's
|
||||
* setting if this component hasn't been set. false is returned if none of
|
||||
* the parent chain has been set.
|
||||
*
|
||||
* @return whether the component is obfuscated
|
||||
*/
|
||||
public boolean isObfuscated()
|
||||
{
|
||||
if ( obfuscated == null )
|
||||
{
|
||||
return parent != null && parent.isObfuscated();
|
||||
}
|
||||
return obfuscated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this component is obfuscated without checking the parents
|
||||
* setting. May return null
|
||||
*
|
||||
* @return whether the component is obfuscated
|
||||
*/
|
||||
public Boolean isObfuscatedRaw()
|
||||
{
|
||||
return obfuscated;
|
||||
}
|
||||
|
||||
public void setExtra(List<BaseComponent> components)
|
||||
{
|
||||
for ( BaseComponent component : components )
|
||||
{
|
||||
component.parent = this;
|
||||
}
|
||||
extra = components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a text element to the component. The text will inherit this
|
||||
* component's formatting
|
||||
*
|
||||
* @param text the text to append
|
||||
*/
|
||||
public void addExtra(String text)
|
||||
{
|
||||
addExtra( new TextComponent( text ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a component to the component. The text will inherit this
|
||||
* component's formatting
|
||||
*
|
||||
* @param component the component to append
|
||||
*/
|
||||
public void addExtra(BaseComponent component)
|
||||
{
|
||||
if ( extra == null )
|
||||
{
|
||||
extra = new ArrayList<>();
|
||||
}
|
||||
component.parent = this;
|
||||
extra.add( component );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the component has any formatting or events applied to it
|
||||
*
|
||||
* @return Whether any formatting or events are applied
|
||||
*/
|
||||
public boolean hasFormatting()
|
||||
{
|
||||
return color != null || bold != null
|
||||
|| italic != null || underlined != null
|
||||
|| strikethrough != null || obfuscated != null
|
||||
|| hoverEvent != null || clickEvent != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the component into a string without any formatting
|
||||
*
|
||||
* @return the string as plain text
|
||||
*/
|
||||
public String toPlainText()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
toPlainText( builder );
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
void toPlainText(StringBuilder builder)
|
||||
{
|
||||
if ( extra != null )
|
||||
{
|
||||
for ( BaseComponent e : extra )
|
||||
{
|
||||
e.toPlainText( builder );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the component to a string that uses the old formatting codes
|
||||
* ({@link net.md_5.bungee.api.ChatColor#COLOR_CHAR}
|
||||
*
|
||||
* @return the string in the old format
|
||||
*/
|
||||
public String toLegacyText()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
toLegacyText( builder );
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
void toLegacyText(StringBuilder builder)
|
||||
{
|
||||
if ( extra != null )
|
||||
{
|
||||
for ( BaseComponent e : extra )
|
||||
{
|
||||
e.toLegacyText( builder );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,50 +0,0 @@
|
||||
package net.md_5.bungee.api.chat;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import net.md_5.bungee.api.chat.ClickEvent.Action;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@RequiredArgsConstructor
|
||||
public final class ClickEvent
|
||||
{
|
||||
|
||||
/**
|
||||
* The type of action to preform on click
|
||||
*/
|
||||
private final Action action;
|
||||
/**
|
||||
* Depends on action
|
||||
*
|
||||
* @see Action
|
||||
*/
|
||||
private final String value;
|
||||
|
||||
public enum Action
|
||||
{
|
||||
|
||||
/**
|
||||
* Open a url at the path given by
|
||||
* {@link net.md_5.bungee.api.chat.ClickEvent#value}
|
||||
*/
|
||||
OPEN_URL,
|
||||
/**
|
||||
* Open a file at the path given by
|
||||
* {@link net.md_5.bungee.api.chat.ClickEvent#value}
|
||||
*/
|
||||
OPEN_FILE,
|
||||
/**
|
||||
* Run the command given by
|
||||
* {@link net.md_5.bungee.api.chat.ClickEvent#value}
|
||||
*/
|
||||
RUN_COMMAND,
|
||||
/**
|
||||
* Inserts the string given by
|
||||
* {@link net.md_5.bungee.api.chat.ClickEvent#value} into the players
|
||||
* text box
|
||||
*/
|
||||
SUGGEST_COMMAND
|
||||
}
|
||||
}
|
@@ -1,178 +0,0 @@
|
||||
package net.md_5.bungee.api.chat;
|
||||
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* ComponentBuilder simplifies creating basic messages by allowing the use of a
|
||||
* chainable builder.
|
||||
* </p>
|
||||
* <pre>
|
||||
* new ComponentBuilder("Hello ").color(ChatColor.RED).
|
||||
* append("World").color(ChatColor.BLUE). append("!").bold(true).create();
|
||||
* </pre>
|
||||
* <p>
|
||||
* All methods (excluding {@link #append(String)} and {@link #create()} work on
|
||||
* the last part appended to the builder, so in the example above "Hello " would
|
||||
* be {@link net.md_5.bungee.api.ChatColor#RED} and "World" would be
|
||||
* {@link net.md_5.bungee.api.ChatColor#BLUE} but "!" would be bold and
|
||||
* {@link net.md_5.bungee.api.ChatColor#BLUE} because append copies the previous
|
||||
* part's formatting
|
||||
* </p>
|
||||
*/
|
||||
public class ComponentBuilder
|
||||
{
|
||||
|
||||
private TextComponent current;
|
||||
private final List<BaseComponent> parts = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Creates a ComponentBuilder from the other given ComponentBuilder to clone
|
||||
* it.
|
||||
*
|
||||
* @param original the original for the new ComponentBuilder.
|
||||
*/
|
||||
public ComponentBuilder(ComponentBuilder original)
|
||||
{
|
||||
current = new TextComponent( original.current );
|
||||
for ( BaseComponent baseComponent : original.parts )
|
||||
{
|
||||
parts.add( baseComponent.duplicate() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ComponentBuilder with the given text as the first part.
|
||||
*
|
||||
* @param text the first text element
|
||||
*/
|
||||
public ComponentBuilder(String text)
|
||||
{
|
||||
current = new TextComponent( text );
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the text to the builder and makes it the current target for
|
||||
* formatting. The text will have all the formatting from the previous part.
|
||||
*
|
||||
* @param text the text to append
|
||||
* @return this ComponentBuilder for chaining
|
||||
*/
|
||||
public ComponentBuilder append(String text)
|
||||
{
|
||||
parts.add( current );
|
||||
current = new TextComponent( current );
|
||||
current.setText( text );
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color of the current part.
|
||||
*
|
||||
* @param color the new color
|
||||
* @return this ComponentBuilder for chaining
|
||||
*/
|
||||
public ComponentBuilder color(ChatColor color)
|
||||
{
|
||||
current.setColor( color );
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the current part is bold.
|
||||
*
|
||||
* @param bold whether this part is bold
|
||||
* @return this ComponentBuilder for chaining
|
||||
*/
|
||||
public ComponentBuilder bold(boolean bold)
|
||||
{
|
||||
current.setBold( bold );
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the current part is italic.
|
||||
*
|
||||
* @param italic whether this part is italic
|
||||
* @return this ComponentBuilder for chaining
|
||||
*/
|
||||
public ComponentBuilder italic(boolean italic)
|
||||
{
|
||||
current.setItalic( italic );
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the current part is underlined.
|
||||
*
|
||||
* @param underlined whether this part is underlined
|
||||
* @return this ComponentBuilder for chaining
|
||||
*/
|
||||
public ComponentBuilder underlined(boolean underlined)
|
||||
{
|
||||
current.setUnderlined( underlined );
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the current part is strikethrough.
|
||||
*
|
||||
* @param strikethrough whether this part is strikethrough
|
||||
* @return this ComponentBuilder for chaining
|
||||
*/
|
||||
public ComponentBuilder strikethrough(boolean strikethrough)
|
||||
{
|
||||
current.setStrikethrough( strikethrough );
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the current part is obfuscated.
|
||||
*
|
||||
* @param obfuscated whether this part is obfuscated
|
||||
* @return this ComponentBuilder for chaining
|
||||
*/
|
||||
public ComponentBuilder obfuscated(boolean obfuscated)
|
||||
{
|
||||
current.setObfuscated( obfuscated );
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the click event for the current part.
|
||||
*
|
||||
* @param clickEvent the click event
|
||||
* @return this ComponentBuilder for chaining
|
||||
*/
|
||||
public ComponentBuilder event(ClickEvent clickEvent)
|
||||
{
|
||||
current.setClickEvent( clickEvent );
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hover event for the current part.
|
||||
*
|
||||
* @param hoverEvent the hover event
|
||||
* @return this ComponentBuilder for chaining
|
||||
*/
|
||||
public ComponentBuilder event(HoverEvent hoverEvent)
|
||||
{
|
||||
current.setHoverEvent( hoverEvent );
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the components needed to display the message created by this
|
||||
* builder.
|
||||
*
|
||||
* @return the created components
|
||||
*/
|
||||
public BaseComponent[] create()
|
||||
{
|
||||
parts.add( current );
|
||||
return parts.toArray( new BaseComponent[ parts.size() ] );
|
||||
}
|
||||
}
|
@@ -1,23 +0,0 @@
|
||||
package net.md_5.bungee.api.chat;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@RequiredArgsConstructor
|
||||
final public class HoverEvent
|
||||
{
|
||||
|
||||
private final Action action;
|
||||
private final BaseComponent[] value;
|
||||
|
||||
public enum Action
|
||||
{
|
||||
|
||||
SHOW_TEXT,
|
||||
SHOW_ACHIEVEMENT,
|
||||
SHOW_ITEM
|
||||
}
|
||||
}
|
@@ -1,213 +0,0 @@
|
||||
package net.md_5.bungee.api.chat;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class TextComponent extends BaseComponent
|
||||
{
|
||||
|
||||
private static final Pattern url = Pattern.compile( "^(?:(https?)://)?([-\\w_\\.]{2,}\\.[a-z]{2,4})(/\\S*)?$" );
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public static BaseComponent[] fromLegacyText(String message)
|
||||
{
|
||||
ArrayList<BaseComponent> components = new ArrayList<>();
|
||||
StringBuilder builder = new StringBuilder();
|
||||
TextComponent component = new TextComponent();
|
||||
Matcher matcher = url.matcher( message );
|
||||
|
||||
for ( int i = 0; i < message.length(); i++ )
|
||||
{
|
||||
char c = message.charAt( i );
|
||||
if ( c == ChatColor.COLOR_CHAR )
|
||||
{
|
||||
i++;
|
||||
c = message.charAt( i );
|
||||
if ( c >= 'A' && c <= 'Z' )
|
||||
{
|
||||
c += 32;
|
||||
}
|
||||
ChatColor format = ChatColor.getByChar( c );
|
||||
if ( format == null )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( builder.length() > 0 )
|
||||
{
|
||||
TextComponent old = component;
|
||||
component = new TextComponent( old );
|
||||
old.setText( builder.toString() );
|
||||
builder = new StringBuilder();
|
||||
components.add( old );
|
||||
}
|
||||
switch ( format )
|
||||
{
|
||||
case BOLD:
|
||||
component.setBold( true );
|
||||
break;
|
||||
case ITALIC:
|
||||
component.setItalic( true );
|
||||
break;
|
||||
case UNDERLINE:
|
||||
component.setUnderlined( true );
|
||||
break;
|
||||
case STRIKETHROUGH:
|
||||
component.setStrikethrough( true );
|
||||
break;
|
||||
case MAGIC:
|
||||
component.setObfuscated( true );
|
||||
break;
|
||||
case RESET:
|
||||
format = ChatColor.WHITE;
|
||||
default:
|
||||
component = new TextComponent();
|
||||
component.setColor( format );
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
int pos = message.indexOf( ' ', i );
|
||||
if ( pos == -1 )
|
||||
{
|
||||
pos = message.length();
|
||||
}
|
||||
if ( matcher.region( i, pos ).find() )
|
||||
{ //Web link handling
|
||||
|
||||
if ( builder.length() > 0 )
|
||||
{
|
||||
TextComponent old = component;
|
||||
component = new TextComponent( old );
|
||||
old.setText( builder.toString() );
|
||||
builder = new StringBuilder();
|
||||
components.add( old );
|
||||
}
|
||||
|
||||
TextComponent old = component;
|
||||
component = new TextComponent( old );
|
||||
String urlString = message.substring( i, pos );
|
||||
component.setText( urlString );
|
||||
component.setClickEvent( new ClickEvent( ClickEvent.Action.OPEN_URL,
|
||||
urlString.startsWith( "http" ) ? urlString : "http://" + urlString ) );
|
||||
components.add( component );
|
||||
i += pos - i - 1;
|
||||
component = old;
|
||||
continue;
|
||||
}
|
||||
builder.append( c );
|
||||
}
|
||||
if ( builder.length() > 0 )
|
||||
{
|
||||
component.setText( builder.toString() );
|
||||
components.add( component );
|
||||
}
|
||||
|
||||
// The client will crash if the array is empty
|
||||
if ( components.isEmpty() )
|
||||
{
|
||||
components.add( new TextComponent( "" ) );
|
||||
}
|
||||
|
||||
return components.toArray( new BaseComponent[ components.size() ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* The text of the component that will be displayed to the client
|
||||
*/
|
||||
private String text;
|
||||
|
||||
/**
|
||||
* Creates a TextComponent with formatting and text from the passed
|
||||
* component
|
||||
*
|
||||
* @param textComponent the component to copy from
|
||||
*/
|
||||
public TextComponent(TextComponent textComponent)
|
||||
{
|
||||
super( textComponent );
|
||||
setText( textComponent.getText() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a TextComponent with blank text and the extras set to the passed
|
||||
* array
|
||||
*
|
||||
* @param extras the extras to set
|
||||
*/
|
||||
public TextComponent(BaseComponent... extras)
|
||||
{
|
||||
setText( "" );
|
||||
setExtra( Arrays.asList( extras ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a duplicate of this TextComponent.
|
||||
*
|
||||
* @return the duplicate of this TextComponent.
|
||||
*/
|
||||
@Override
|
||||
public BaseComponent duplicate()
|
||||
{
|
||||
return new TextComponent( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toPlainText(StringBuilder builder)
|
||||
{
|
||||
builder.append( text );
|
||||
super.toPlainText( builder );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toLegacyText(StringBuilder builder)
|
||||
{
|
||||
builder.append( getColor() );
|
||||
if ( isBold() )
|
||||
{
|
||||
builder.append( ChatColor.BOLD );
|
||||
}
|
||||
if ( isItalic() )
|
||||
{
|
||||
builder.append( ChatColor.ITALIC );
|
||||
}
|
||||
if ( isUnderlined() )
|
||||
{
|
||||
builder.append( ChatColor.UNDERLINE );
|
||||
}
|
||||
if ( isStrikethrough() )
|
||||
{
|
||||
builder.append( ChatColor.STRIKETHROUGH );
|
||||
}
|
||||
if ( isObfuscated() )
|
||||
{
|
||||
builder.append( ChatColor.MAGIC );
|
||||
}
|
||||
builder.append( text );
|
||||
super.toLegacyText( builder );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format( "TextComponent{text=%s, %s}", text, super.toString() );
|
||||
}
|
||||
}
|
@@ -1,243 +0,0 @@
|
||||
package net.md_5.bungee.api.chat;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
@NoArgsConstructor
|
||||
public class TranslatableComponent extends BaseComponent
|
||||
{
|
||||
|
||||
private final ResourceBundle locales = ResourceBundle.getBundle( "mojang-translations/en_US" );
|
||||
private final Pattern format = Pattern.compile( "%(?:(\\d+)\\$)?([A-Za-z%]|$)" );
|
||||
|
||||
/**
|
||||
* The key into the Minecraft locale files to use for the translation. The
|
||||
* text depends on the client's locale setting. The console is always en_US
|
||||
*/
|
||||
private String translate;
|
||||
/**
|
||||
* The components to substitute into the translation
|
||||
*/
|
||||
private List<BaseComponent> with;
|
||||
|
||||
/**
|
||||
* Creates a translatable component from the original to clone it.
|
||||
*
|
||||
* @param original the original for the new translatable component.
|
||||
*/
|
||||
public TranslatableComponent(TranslatableComponent original)
|
||||
{
|
||||
super( original );
|
||||
setTranslate( original.getTranslate() );
|
||||
for ( BaseComponent baseComponent : original.getWith() )
|
||||
{
|
||||
with.add( baseComponent.duplicate() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a translatable component with the passed substitutions
|
||||
*
|
||||
* @see #translate
|
||||
* @see #setWith(java.util.List)
|
||||
* @param translate the translation key
|
||||
* @param with the {@link java.lang.String}s and
|
||||
* {@link net.md_5.bungee.api.chat.BaseComponent}s to use into the
|
||||
* translation
|
||||
*/
|
||||
public TranslatableComponent(String translate, Object... with)
|
||||
{
|
||||
setTranslate( translate );
|
||||
List<BaseComponent> temp = new ArrayList<>();
|
||||
for ( Object w : with )
|
||||
{
|
||||
if ( w instanceof String )
|
||||
{
|
||||
temp.add( new TextComponent( (String) w ) );
|
||||
} else
|
||||
{
|
||||
temp.add( (BaseComponent) w );
|
||||
}
|
||||
}
|
||||
setWith( temp );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a duplicate of this TranslatableComponent.
|
||||
*
|
||||
* @return the duplicate of this TranslatableComponent.
|
||||
*/
|
||||
@Override
|
||||
public BaseComponent duplicate()
|
||||
{
|
||||
return new TranslatableComponent( this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the translation substitutions to be used in this component. Removes
|
||||
* any previously set substitutions
|
||||
*
|
||||
* @param components the components to substitute
|
||||
*/
|
||||
public void setWith(List<BaseComponent> components)
|
||||
{
|
||||
for ( BaseComponent component : components )
|
||||
{
|
||||
component.parent = this;
|
||||
}
|
||||
with = components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a text substitution to the component. The text will inherit this
|
||||
* component's formatting
|
||||
*
|
||||
* @param text the text to substitute
|
||||
*/
|
||||
public void addWith(String text)
|
||||
{
|
||||
addWith( new TextComponent( text ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a component substitution to the component. The text will inherit
|
||||
* this component's formatting
|
||||
*
|
||||
* @param component the component to substitute
|
||||
*/
|
||||
public void addWith(BaseComponent component)
|
||||
{
|
||||
if ( with == null )
|
||||
{
|
||||
with = new ArrayList<>();
|
||||
}
|
||||
component.parent = this;
|
||||
with.add( component );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toPlainText(StringBuilder builder)
|
||||
{
|
||||
try
|
||||
{
|
||||
String trans = locales.getString( translate );
|
||||
Matcher matcher = format.matcher( trans );
|
||||
int position = 0;
|
||||
int i = 0;
|
||||
while ( matcher.find( position ) )
|
||||
{
|
||||
int pos = matcher.start();
|
||||
if ( pos != position )
|
||||
{
|
||||
builder.append( trans.substring( position, pos ) );
|
||||
}
|
||||
position = matcher.end();
|
||||
|
||||
String formatCode = matcher.group( 2 );
|
||||
switch ( formatCode.charAt( 0 ) )
|
||||
{
|
||||
case 's':
|
||||
case 'd':
|
||||
String withIndex = matcher.group( 1 );
|
||||
with.get( withIndex != null ? Integer.parseInt( withIndex ) - 1 : i++ ).toPlainText( builder );
|
||||
break;
|
||||
case '%':
|
||||
builder.append( '%' );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( trans.length() != position )
|
||||
{
|
||||
builder.append( trans.substring( position, trans.length() ) );
|
||||
}
|
||||
} catch ( MissingResourceException e )
|
||||
{
|
||||
builder.append( translate );
|
||||
}
|
||||
|
||||
super.toPlainText( builder );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toLegacyText(StringBuilder builder)
|
||||
{
|
||||
try
|
||||
{
|
||||
String trans = locales.getString( translate );
|
||||
Matcher matcher = format.matcher( trans );
|
||||
int position = 0;
|
||||
int i = 0;
|
||||
while ( matcher.find( position ) )
|
||||
{
|
||||
int pos = matcher.start();
|
||||
if ( pos != position )
|
||||
{
|
||||
addFormat( builder );
|
||||
builder.append( trans.substring( position, pos ) );
|
||||
}
|
||||
position = matcher.end();
|
||||
|
||||
String formatCode = matcher.group( 2 );
|
||||
switch ( formatCode.charAt( 0 ) )
|
||||
{
|
||||
case 's':
|
||||
case 'd':
|
||||
String withIndex = matcher.group( 1 );
|
||||
with.get( withIndex != null ? Integer.parseInt( withIndex ) - 1 : i++ ).toLegacyText( builder );
|
||||
break;
|
||||
case '%':
|
||||
addFormat( builder );
|
||||
builder.append( '%' );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( trans.length() != position )
|
||||
{
|
||||
addFormat( builder );
|
||||
builder.append( trans.substring( position, trans.length() ) );
|
||||
}
|
||||
} catch ( MissingResourceException e )
|
||||
{
|
||||
addFormat( builder );
|
||||
builder.append( translate );
|
||||
}
|
||||
super.toLegacyText( builder );
|
||||
}
|
||||
|
||||
private void addFormat(StringBuilder builder)
|
||||
{
|
||||
builder.append( getColor() );
|
||||
if ( isBold() )
|
||||
{
|
||||
builder.append( ChatColor.BOLD );
|
||||
}
|
||||
if ( isItalic() )
|
||||
{
|
||||
builder.append( ChatColor.ITALIC );
|
||||
}
|
||||
if ( isUnderlined() )
|
||||
{
|
||||
builder.append( ChatColor.UNDERLINE );
|
||||
}
|
||||
if ( isStrikethrough() )
|
||||
{
|
||||
builder.append( ChatColor.STRIKETHROUGH );
|
||||
}
|
||||
if ( isObfuscated() )
|
||||
{
|
||||
builder.append( ChatColor.MAGIC );
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user