Compare commits
	
		
			1 Commits
		
	
	
		
			18eae8a1a6
			...
			patch-loop
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 6949470e3b | 
							
								
								
									
										63
									
								
								.github/ISSUE_TEMPLATE/bug_report.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										63
									
								
								.github/ISSUE_TEMPLATE/bug_report.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,63 +0,0 @@ | |||||||
| name: Bug inside BungeeCord |  | ||||||
| description: Create a bug report about a problem inside BungeeCord. |  | ||||||
| body: |  | ||||||
|   - type: markdown |  | ||||||
|     attributes: |  | ||||||
|       value: | |  | ||||||
|         #### Report a bug inside bungeecord |  | ||||||
|         Issues happening with forks of BungeeCord should **not** be reported here. |  | ||||||
|   - type: input |  | ||||||
|     id: bungee-version |  | ||||||
|     attributes: |  | ||||||
|       label: Bungeecord version |  | ||||||
|       description: The output of the /bungee command (or just the bungee build number) (execute in bungeecord console for easy text copy) |  | ||||||
|       placeholder: e.g. git:BungeeCord-Bootstrap:1.xx-SNAPSHOT:xxxxxxx:xxxx |  | ||||||
|     validations: |  | ||||||
|       required: true |  | ||||||
|   - type: input |  | ||||||
|     id: server-version |  | ||||||
|     attributes: |  | ||||||
|       label: Server version |  | ||||||
|       description: The output of the /version command (execute in server console for easy text copy) |  | ||||||
|       placeholder: "e.g. git-Spigot-xxxxxxx-xxxxxxx (MC: 1.x.x)" |  | ||||||
|   - type: input |  | ||||||
|     id: client-version |  | ||||||
|     attributes: |  | ||||||
|       label: Client version |  | ||||||
|       description: Minecraft Client Version |  | ||||||
|       placeholder: e.g. 1.18.2 |  | ||||||
|   - type: textarea |  | ||||||
|     id: bungee-plugins |  | ||||||
|     attributes: |  | ||||||
|       label: Bungeecord plugins |  | ||||||
|       description: Please list all BungeeCord plugins you are using. |  | ||||||
|     validations: |  | ||||||
|       required: true |  | ||||||
|   - type: textarea |  | ||||||
|     id: the-bug |  | ||||||
|     attributes: |  | ||||||
|       label: The bug |  | ||||||
|       description: Please describe the bug. Include **details** you find neccessary. If you just have a question, please ask it in [SpigotMC Forums](https://www.spigotmc.org) and not here. |  | ||||||
|     validations: |  | ||||||
|       required: true |  | ||||||
|   - type: textarea |  | ||||||
|     id: logs |  | ||||||
|     attributes: |  | ||||||
|       label: Log output (links) |  | ||||||
|       description: Please put your log output inbetween three backticks (```` ``` ````). Upload your log files to [gist.github.com](https://gist.github.com) and put them in here. |  | ||||||
|       placeholder: | |  | ||||||
|         ``` |  | ||||||
|         log output |  | ||||||
|         ``` |  | ||||||
|   - type: checkboxes |  | ||||||
|     id: checkboxes |  | ||||||
|     attributes: |  | ||||||
|       label: Checking |  | ||||||
|       options: |  | ||||||
|         - label: I am using BungeeCord and **not a fork**. Issues with forks should not be reported here. |  | ||||||
|           required: true |  | ||||||
|         - label: I think this is **not** an issue with a bungeecord plugin. |  | ||||||
|           required: true |  | ||||||
|         - label: I have not read these checkboxes and therefore I just ticked them all. |  | ||||||
|         - label: This is not a question or plugin creation help request. |  | ||||||
|           required: true |  | ||||||
							
								
								
									
										14
									
								
								.github/ISSUE_TEMPLATE/config.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								.github/ISSUE_TEMPLATE/config.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,14 +0,0 @@ | |||||||
| blank_issues_enabled: false |  | ||||||
| contact_links: |  | ||||||
|   - name: Configuration help |  | ||||||
|     url: https://www.spigotmc.org/forums/bungeecord-help.70/create-thread |  | ||||||
|     about: Help for configuring bungeecord will only be answered in spigotmc.org forums. |  | ||||||
|   - name: I have a problem with a bungee plugin |  | ||||||
|     url: https://www.spigotmc.org/forums/bungeecord-plugin-help.71/create-thread |  | ||||||
|     about: Help about plugins can be recieved in spigotmc.org forums. |  | ||||||
|   - name: Questions and discussions |  | ||||||
|     url: https://www.spigotmc.org/forums/bungeecord-discussion.21/create-thread |  | ||||||
|     about: spigotmc.org forums are the best place to ask your questions regarding bungeecord. |  | ||||||
|   - name: Plugin creation help |  | ||||||
|     url: https://www.spigotmc.org/forums/bungeecord-plugin-development.23/create-thread |  | ||||||
|     about: Plugin creation help for bungee plugins can be recieved in spigotmc.org forums. |  | ||||||
							
								
								
									
										36
									
								
								.github/ISSUE_TEMPLATE/feature_request.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								.github/ISSUE_TEMPLATE/feature_request.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,36 +0,0 @@ | |||||||
| name: Feature request |  | ||||||
| description: Suggest a feature which bungeecord should include. |  | ||||||
| body: |  | ||||||
|   - type: textarea |  | ||||||
|     id: the-feature |  | ||||||
|     attributes: |  | ||||||
|       label: Feature description |  | ||||||
|       description: Please describe your feature or improvement. Please include **details**. |  | ||||||
|     validations: |  | ||||||
|       required: true |  | ||||||
|   - type: textarea |  | ||||||
|     id: goal |  | ||||||
|     attributes: |  | ||||||
|       label: Goal of the feature |  | ||||||
|       description: What is the goal of your feature? |  | ||||||
|     validations: |  | ||||||
|       required: true |  | ||||||
|   - type: textarea |  | ||||||
|     id: alternatives |  | ||||||
|     attributes: |  | ||||||
|       label: Unfitting alternatives |  | ||||||
|       description: What alternatives have you considered and why are they not sufficient for your use case? |  | ||||||
|     validations: |  | ||||||
|       required: true |  | ||||||
|   - type: checkboxes |  | ||||||
|     id: checkboxes |  | ||||||
|     attributes: |  | ||||||
|       label: Checking |  | ||||||
|       options: |  | ||||||
|         - label: This is not a question or plugin creation help request. |  | ||||||
|           required: true |  | ||||||
|         - label: This is a **feature or improvement request**. |  | ||||||
|           required: true |  | ||||||
|         - label: I have not read these checkboxes and therefore I just ticked them all. |  | ||||||
|         - label: I did not use this form to report a bug. |  | ||||||
|           required: true |  | ||||||
							
								
								
									
										27
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										27
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,27 +0,0 @@ | |||||||
| version: 2 |  | ||||||
|  |  | ||||||
| updates: |  | ||||||
|   - package-ecosystem: "maven" |  | ||||||
|     directory: "/" |  | ||||||
|     schedule: |  | ||||||
|       interval: "daily" |  | ||||||
|     open-pull-requests-limit: 50 |  | ||||||
|     ignore: |  | ||||||
|         # Synchronised with Minecraft |  | ||||||
|       - dependency-name: "com.google.code.gson:gson" |  | ||||||
|         # 9.x has performance issues (see, eg, checkstyle/checkstyle#10934) and 10.x is incompatible |  | ||||||
|       - dependency-name: "com.puppycrawl.tools:checkstyle" |  | ||||||
|         # Newer versions have issues, see #1909 and #2050 |  | ||||||
|       - dependency-name: "jline:jline" |  | ||||||
|         # Needs to be synchronised with maven-resolver-provider dependencies |  | ||||||
|       - dependency-name: "org.apache.maven.resolver:maven-resolver-connector-basic" |  | ||||||
|       - dependency-name: "org.apache.maven.resolver:maven-resolver-transport-http" |  | ||||||
|         # Used with maven-resolver dependencies; 2.0 update breaks other providers |  | ||||||
|       - dependency-name: "org.slf4j:slf4j-api" |  | ||||||
|         update-types: ["version-update:semver-major"] |  | ||||||
|  |  | ||||||
|   - package-ecosystem: "github-actions" |  | ||||||
|     directory: "/" |  | ||||||
|     schedule: |  | ||||||
|       interval: "daily" |  | ||||||
|     open-pull-requests-limit: 50 |  | ||||||
							
								
								
									
										10
									
								
								.github/workflows/maven.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								.github/workflows/maven.yml
									
									
									
									
										vendored
									
									
								
							| @@ -4,20 +4,18 @@ on: [push, pull_request] | |||||||
|  |  | ||||||
| jobs: | jobs: | ||||||
|   build: |   build: | ||||||
|     runs-on: ubuntu-22.04 |     runs-on: ubuntu-latest | ||||||
|  |  | ||||||
|     strategy: |     strategy: | ||||||
|       fail-fast: false |  | ||||||
|       matrix: |       matrix: | ||||||
|         java: [8, 11, 17, 21] |         java: [8, 11] | ||||||
|  |  | ||||||
|     name: Java ${{ matrix.java }} |     name: Java ${{ matrix.java }} | ||||||
|  |  | ||||||
|     steps: |     steps: | ||||||
|     - uses: actions/checkout@v4 |     - uses: actions/checkout@v2 | ||||||
|     - uses: actions/setup-java@v4 |     - uses: actions/setup-java@v1 | ||||||
|       with: |       with: | ||||||
|         distribution: zulu |  | ||||||
|         java-version: ${{ matrix.java }} |         java-version: ${{ matrix.java }} | ||||||
|     - run: java -version && mvn --version |     - run: java -version && mvn --version | ||||||
|     - run: mvn --activate-profiles dist --no-transfer-progress package |     - run: mvn --activate-profiles dist --no-transfer-progress package | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							| @@ -1,6 +0,0 @@ | |||||||
| [submodule "native/mbedtls"] |  | ||||||
| 	path = native/mbedtls |  | ||||||
| 	url = https://github.com/ARMmbed/mbedtls.git |  | ||||||
| [submodule "native/zlib"] |  | ||||||
| 	path = native/zlib |  | ||||||
| 	url = https://github.com/cloudflare/zlib.git |  | ||||||
| @@ -23,4 +23,4 @@ Binaries | |||||||
| -------- | -------- | ||||||
| Precompiled binaries are available for end users on [Jenkins](https://www.spigotmc.org/go/bungeecord-dl). | Precompiled binaries are available for end users on [Jenkins](https://www.spigotmc.org/go/bungeecord-dl). | ||||||
|  |  | ||||||
| (c) 2012-2024 SpigotMC Pty. Ltd. | (c) 2012-2020 SpigotMC Pty. Ltd. | ||||||
|   | |||||||
							
								
								
									
										28
									
								
								api/pom.xml
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								api/pom.xml
									
									
									
									
									
								
							| @@ -6,13 +6,13 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>net.md-5</groupId> |         <groupId>net.md-5</groupId> | ||||||
|         <artifactId>bungeecord-parent</artifactId> |         <artifactId>bungeecord-parent</artifactId> | ||||||
|         <version>1.20-R0.3-SNAPSHOT</version> |         <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|         <relativePath>../pom.xml</relativePath> |         <relativePath>../pom.xml</relativePath> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <groupId>net.md-5</groupId> |     <groupId>net.md-5</groupId> | ||||||
|     <artifactId>bungeecord-api</artifactId> |     <artifactId>bungeecord-api</artifactId> | ||||||
|     <version>1.20-R0.3-SNAPSHOT</version> |     <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|     <packaging>jar</packaging> |     <packaging>jar</packaging> | ||||||
|  |  | ||||||
|     <name>BungeeCord-API</name> |     <name>BungeeCord-API</name> | ||||||
| @@ -46,33 +46,13 @@ | |||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>io.netty</groupId> |             <groupId>io.netty</groupId> | ||||||
|             <artifactId>netty-transport-native-unix-common</artifactId> |             <artifactId>netty-transport-native-unix-common</artifactId> | ||||||
|  |             <version>${netty.version}</version> | ||||||
|             <scope>compile</scope> |             <scope>compile</scope> | ||||||
|         </dependency> |         </dependency> | ||||||
|         <dependency> |  | ||||||
|             <groupId>org.apache.maven</groupId> |  | ||||||
|             <artifactId>maven-resolver-provider</artifactId> |  | ||||||
|             <version>3.9.6</version> |  | ||||||
|             <!-- not part of the API proper --> |  | ||||||
|             <scope>provided</scope> |  | ||||||
|         </dependency> |  | ||||||
|         <dependency> |  | ||||||
|             <groupId>org.apache.maven.resolver</groupId> |  | ||||||
|             <artifactId>maven-resolver-connector-basic</artifactId> |  | ||||||
|             <version>1.9.18</version> |  | ||||||
|             <!-- not part of the API proper --> |  | ||||||
|             <scope>provided</scope> |  | ||||||
|         </dependency> |  | ||||||
|         <dependency> |  | ||||||
|             <groupId>org.apache.maven.resolver</groupId> |  | ||||||
|             <artifactId>maven-resolver-transport-http</artifactId> |  | ||||||
|             <version>1.9.18</version> |  | ||||||
|             <!-- not part of the API proper --> |  | ||||||
|             <scope>provided</scope> |  | ||||||
|         </dependency> |  | ||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>org.yaml</groupId> |             <groupId>org.yaml</groupId> | ||||||
|             <artifactId>snakeyaml</artifactId> |             <artifactId>snakeyaml</artifactId> | ||||||
|             <version>2.2</version> |             <version>1.26</version> | ||||||
|             <scope>compile</scope> |             <scope>compile</scope> | ||||||
|         </dependency> |         </dependency> | ||||||
|     </dependencies> |     </dependencies> | ||||||
|   | |||||||
| @@ -7,7 +7,6 @@ import java.net.InetSocketAddress; | |||||||
| import java.net.SocketAddress; | import java.net.SocketAddress; | ||||||
| import java.net.URI; | import java.net.URI; | ||||||
| import java.net.URISyntaxException; | import java.net.URISyntaxException; | ||||||
| import java.util.Locale; |  | ||||||
| import java.util.UUID; | import java.util.UUID; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -69,17 +68,6 @@ public class Util | |||||||
|         return String.format( "0x%02X", i ); |         return String.format( "0x%02X", i ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Formats an char as a unicode value. |  | ||||||
|      * |  | ||||||
|      * @param c the character to format |  | ||||||
|      * @return the unicode representation of the character |  | ||||||
|      */ |  | ||||||
|     public static String unicode(char c) |  | ||||||
|     { |  | ||||||
|         return "\\u" + String.format( "%04x", (int) c ).toUpperCase( Locale.ROOT ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Constructs a pretty one line version of a {@link Throwable}. Useful for |      * Constructs a pretty one line version of a {@link Throwable}. Useful for | ||||||
|      * debugging. |      * debugging. | ||||||
| @@ -88,24 +76,11 @@ public class Util | |||||||
|      * @return a string representing information about the {@link Throwable} |      * @return a string representing information about the {@link Throwable} | ||||||
|      */ |      */ | ||||||
|     public static String exception(Throwable t) |     public static String exception(Throwable t) | ||||||
|     { |  | ||||||
|         return exception( t, true ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Constructs a pretty one line version of a {@link Throwable}. Useful for |  | ||||||
|      * debugging. |  | ||||||
|      * |  | ||||||
|      * @param t the {@link Throwable} to format. |  | ||||||
|      * @param includeLineNumbers whether to include line numbers |  | ||||||
|      * @return a string representing information about the {@link Throwable} |  | ||||||
|      */ |  | ||||||
|     public static String exception(Throwable t, boolean includeLineNumbers) |  | ||||||
|     { |     { | ||||||
|         // TODO: We should use clear manually written exceptions |         // TODO: We should use clear manually written exceptions | ||||||
|         StackTraceElement[] trace = t.getStackTrace(); |         StackTraceElement[] trace = t.getStackTrace(); | ||||||
|         return t.getClass().getSimpleName() + " : " + t.getMessage() |         return t.getClass().getSimpleName() + " : " + t.getMessage() | ||||||
|                 + ( ( includeLineNumbers && trace.length > 0 ) ? " @ " + t.getStackTrace()[0].getClassName() + ":" + t.getStackTrace()[0].getLineNumber() : "" ); |                 + ( ( trace.length > 0 ) ? " @ " + t.getStackTrace()[0].getClassName() + ":" + t.getStackTrace()[0].getLineNumber() : "" ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static String csv(Iterable<?> objects) |     public static String csv(Iterable<?> objects) | ||||||
| @@ -113,16 +88,6 @@ public class Util | |||||||
|         return format( objects, ", " ); |         return format( objects, ", " ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Returns a string of objects, each separated by a separator. |  | ||||||
|      * |  | ||||||
|      * @param objects the objects to join |  | ||||||
|      * @param separators the separator |  | ||||||
|      * @return joined string |  | ||||||
|      * @see String#join(java.lang.CharSequence, java.lang.Iterable) |  | ||||||
|      * @deprecated use {@link String} join methods |  | ||||||
|      */ |  | ||||||
|     @Deprecated |  | ||||||
|     public static String format(Iterable<?> objects, String separators) |     public static String format(Iterable<?> objects, String separators) | ||||||
|     { |     { | ||||||
|         return Joiner.on( separators ).join( objects ); |         return Joiner.on( separators ).join( objects ); | ||||||
|   | |||||||
| @@ -28,13 +28,18 @@ public abstract class AbstractReconnectHandler implements ReconnectHandler | |||||||
|  |  | ||||||
|     public static ServerInfo getForcedHost(PendingConnection con) |     public static ServerInfo getForcedHost(PendingConnection con) | ||||||
|     { |     { | ||||||
|         String forced = ( con.getVirtualHost() == null ) ? null : con.getListener().getForcedHosts().get( con.getVirtualHost().getHostString() ); |         if ( con.getVirtualHost() == null ) | ||||||
|  |         { | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         String forced = con.getListener().getForcedHosts().get( con.getVirtualHost().getHostString() ); | ||||||
|  |  | ||||||
|         if ( forced == null && con.getListener().isForceDefault() ) |         if ( forced == null && con.getListener().isForceDefault() ) | ||||||
|         { |         { | ||||||
|             forced = con.getListener().getDefaultServer(); |             forced = con.getListener().getDefaultServer(); | ||||||
|         } |         } | ||||||
|         return ( forced == null ) ? null : ProxyServer.getInstance().getServerInfo( forced ); |         return ProxyServer.getInstance().getServerInfo( forced ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     protected abstract ServerInfo getStoredServer(ProxiedPlayer player); |     protected abstract ServerInfo getStoredServer(ProxiedPlayer player); | ||||||
|   | |||||||
| @@ -1,10 +1,9 @@ | |||||||
| package net.md_5.bungee.api; | package net.md_5.bungee.api; | ||||||
|  |  | ||||||
| import com.google.common.base.Preconditions; |  | ||||||
| import com.google.common.io.BaseEncoding; | import com.google.common.io.BaseEncoding; | ||||||
| import com.google.gson.TypeAdapter; | import com.google.gson.TypeAdapter; | ||||||
|  | import com.google.gson.internal.bind.TypeAdapters; | ||||||
| import com.google.gson.stream.JsonReader; | import com.google.gson.stream.JsonReader; | ||||||
| import com.google.gson.stream.JsonToken; |  | ||||||
| import com.google.gson.stream.JsonWriter; | import com.google.gson.stream.JsonWriter; | ||||||
| import java.awt.image.BufferedImage; | import java.awt.image.BufferedImage; | ||||||
| import java.io.ByteArrayOutputStream; | import java.io.ByteArrayOutputStream; | ||||||
| @@ -27,26 +26,13 @@ public class Favicon | |||||||
|         @Override |         @Override | ||||||
|         public void write(JsonWriter out, Favicon value) throws IOException |         public void write(JsonWriter out, Favicon value) throws IOException | ||||||
|         { |         { | ||||||
|             if ( value == null ) |             TypeAdapters.STRING.write( out, value == null ? null : value.getEncoded() ); | ||||||
|             { |  | ||||||
|                 out.nullValue(); |  | ||||||
|             } else |  | ||||||
|             { |  | ||||||
|                 out.value( value.getEncoded() ); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         @Override |         @Override | ||||||
|         public Favicon read(JsonReader in) throws IOException |         public Favicon read(JsonReader in) throws IOException | ||||||
|         { |         { | ||||||
|             JsonToken peek = in.peek(); |             String enc = TypeAdapters.STRING.read( in ); | ||||||
|             if ( peek == JsonToken.NULL ) |  | ||||||
|             { |  | ||||||
|                 in.nextNull(); |  | ||||||
|                 return null; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             String enc = in.nextString(); |  | ||||||
|             return enc == null ? null : create( enc ); |             return enc == null ? null : create( enc ); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| @@ -73,7 +59,6 @@ public class Favicon | |||||||
|      */ |      */ | ||||||
|     public static Favicon create(BufferedImage image) |     public static Favicon create(BufferedImage image) | ||||||
|     { |     { | ||||||
|         Preconditions.checkArgument( image != null, "image is null" ); |  | ||||||
|         // check size |         // check size | ||||||
|         if ( image.getWidth() != 64 || image.getHeight() != 64 ) |         if ( image.getWidth() != 64 || image.getHeight() != 64 ) | ||||||
|         { |         { | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -2,9 +2,7 @@ package net.md_5.bungee.api.connection; | |||||||
|  |  | ||||||
| import java.net.InetSocketAddress; | import java.net.InetSocketAddress; | ||||||
| import java.util.UUID; | import java.util.UUID; | ||||||
| import java.util.concurrent.CompletableFuture; |  | ||||||
| import net.md_5.bungee.api.config.ListenerInfo; | import net.md_5.bungee.api.config.ListenerInfo; | ||||||
| import org.jetbrains.annotations.ApiStatus; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Represents a user attempting to log into the proxy. |  * Represents a user attempting to log into the proxy. | ||||||
| @@ -91,26 +89,4 @@ public interface PendingConnection extends Connection | |||||||
|      * @return Whether the client is using a legacy client. |      * @return Whether the client is using a legacy client. | ||||||
|      */ |      */ | ||||||
|     boolean isLegacy(); |     boolean isLegacy(); | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Gets if this connection has been transferred from another server. |  | ||||||
|      * |  | ||||||
|      * @return true if the connection has been transferred |  | ||||||
|      */ |  | ||||||
|     @ApiStatus.Experimental |  | ||||||
|     boolean isTransferred(); |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Retrieves a cookie from this pending connection. |  | ||||||
|      * |  | ||||||
|      * @param cookie the resource location of the cookie, for example |  | ||||||
|      * "bungeecord:my_cookie" |  | ||||||
|      * @return a {@link CompletableFuture} that will be completed when the |  | ||||||
|      * Cookie response is received. If the cookie is not set in the client, the |  | ||||||
|      * {@link CompletableFuture} will complete with a null value |  | ||||||
|      * @throws IllegalStateException if the player's version is not at least |  | ||||||
|      * 1.20.5 |  | ||||||
|      */ |  | ||||||
|     @ApiStatus.Experimental |  | ||||||
|     CompletableFuture<byte[]> retrieveCookie(String cookie); |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,7 +3,6 @@ package net.md_5.bungee.api.connection; | |||||||
| import java.util.Locale; | import java.util.Locale; | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| import java.util.UUID; | import java.util.UUID; | ||||||
| import java.util.concurrent.CompletableFuture; |  | ||||||
| import net.md_5.bungee.api.Callback; | import net.md_5.bungee.api.Callback; | ||||||
| import net.md_5.bungee.api.ChatMessageType; | import net.md_5.bungee.api.ChatMessageType; | ||||||
| import net.md_5.bungee.api.CommandSender; | import net.md_5.bungee.api.CommandSender; | ||||||
| @@ -14,10 +13,9 @@ 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.score.Scoreboard; | import net.md_5.bungee.api.score.Scoreboard; | ||||||
| import org.jetbrains.annotations.ApiStatus; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Represents a player whose connection is being connected to somewhere else, |  * Represents a player who's connection is being connected to somewhere else, | ||||||
|  * whether it be a remote or embedded server. |  * whether it be a remote or embedded server. | ||||||
|  */ |  */ | ||||||
| public interface ProxiedPlayer extends Connection, CommandSender | public interface ProxiedPlayer extends Connection, CommandSender | ||||||
| @@ -59,7 +57,8 @@ public interface ProxiedPlayer extends Connection, CommandSender | |||||||
|     String getDisplayName(); |     String getDisplayName(); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Sets this player's display name to be used by proxy commands and plugins. |      * Sets this players display name to be used as their nametag and tab list | ||||||
|  |      * name. | ||||||
|      * |      * | ||||||
|      * @param name the name to set |      * @param name the name to set | ||||||
|      */ |      */ | ||||||
| @@ -336,50 +335,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(); | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Retrieves a cookie from this player. |  | ||||||
|      * |  | ||||||
|      * @param cookie the resource location of the cookie, for example |  | ||||||
|      * "bungeecord:my_cookie" |  | ||||||
|      * @return a {@link CompletableFuture} that will be completed when the |  | ||||||
|      * Cookie response is received. If the cookie is not set in the client, the |  | ||||||
|      * {@link CompletableFuture} will complete with a null value |  | ||||||
|      * @throws IllegalStateException if the player's version is not at least |  | ||||||
|      * 1.20.5 |  | ||||||
|      */ |  | ||||||
|     @ApiStatus.Experimental |  | ||||||
|     CompletableFuture<byte[]> retrieveCookie(String cookie); |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Stores a cookie in this player's client. |  | ||||||
|      * |  | ||||||
|      * @param cookie the resource location of the cookie, for example |  | ||||||
|      * "bungeecord:my_cookie" |  | ||||||
|      * @param data the data to store in the cookie |  | ||||||
|      * @throws IllegalStateException if the player's version is not at least |  | ||||||
|      * 1.20.5 |  | ||||||
|      */ |  | ||||||
|     @ApiStatus.Experimental |  | ||||||
|     void storeCookie(String cookie, byte[] data); |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Requests this player to connect to a different server specified by host |  | ||||||
|      * and port. |  | ||||||
|      * |  | ||||||
|      * This is a client-side transfer - host and port should not specify a |  | ||||||
|      * BungeeCord backend server. |  | ||||||
|      * |  | ||||||
|      * @param host the host of the server to transfer to |  | ||||||
|      * @param port the port of the server to transfer to |  | ||||||
|      * @throws IllegalStateException if the players version is not at least |  | ||||||
|      * 1.20.5 |  | ||||||
|      */ |  | ||||||
|     @ApiStatus.Experimental |  | ||||||
|     void transfer(String host, int port); |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -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; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,9 +3,8 @@ package net.md_5.bungee.api.event; | |||||||
| import lombok.Data; | import lombok.Data; | ||||||
| import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||||
| import lombok.ToString; | import lombok.ToString; | ||||||
| import net.md_5.bungee.api.Callback; |  | ||||||
| import net.md_5.bungee.api.config.ServerInfo; |  | ||||||
| import net.md_5.bungee.api.connection.ProxiedPlayer; | import net.md_5.bungee.api.connection.ProxiedPlayer; | ||||||
|  | import net.md_5.bungee.api.plugin.Event; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Event called as soon as a connection has a {@link ProxiedPlayer} and is ready |  * Event called as soon as a connection has a {@link ProxiedPlayer} and is ready | ||||||
| @@ -14,22 +13,11 @@ import net.md_5.bungee.api.connection.ProxiedPlayer; | |||||||
| @Data | @Data | ||||||
| @ToString(callSuper = false) | @ToString(callSuper = false) | ||||||
| @EqualsAndHashCode(callSuper = false) | @EqualsAndHashCode(callSuper = false) | ||||||
| public class PostLoginEvent extends AsyncEvent<PostLoginEvent> | public class PostLoginEvent extends Event | ||||||
| { | { | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * The player involved with this event. |      * The player involved with this event. | ||||||
|      */ |      */ | ||||||
|     private final ProxiedPlayer player; |     private final ProxiedPlayer player; | ||||||
|     /** |  | ||||||
|      * The server to which the player will initially be connected. |  | ||||||
|      */ |  | ||||||
|     private ServerInfo target; |  | ||||||
|  |  | ||||||
|     public PostLoginEvent(ProxiedPlayer player, ServerInfo target, Callback<PostLoginEvent> done) |  | ||||||
|     { |  | ||||||
|         super( done ); |  | ||||||
|         this.player = player; |  | ||||||
|         this.target = target; |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -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; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ import net.md_5.bungee.api.ServerPing; | |||||||
| import net.md_5.bungee.api.connection.PendingConnection; | import net.md_5.bungee.api.connection.PendingConnection; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Called when the proxy is queried for status from the server list. |  * Called when the proxy is pinged with packet 0xFE from the server list. | ||||||
|  */ |  */ | ||||||
| @Data | @Data | ||||||
| @ToString(callSuper = false) | @ToString(callSuper = false) | ||||||
|   | |||||||
| @@ -9,13 +9,6 @@ import net.md_5.bungee.api.config.ServerInfo; | |||||||
| import net.md_5.bungee.api.connection.ProxiedPlayer; | import net.md_5.bungee.api.connection.ProxiedPlayer; | ||||||
| import net.md_5.bungee.api.plugin.Event; | import net.md_5.bungee.api.plugin.Event; | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Called when the player is disconnected from a server, for example during |  | ||||||
|  * server switching. |  | ||||||
|  * |  | ||||||
|  * If the player is kicked from a server, {@link ServerKickEvent} will be called |  | ||||||
|  * instead. |  | ||||||
|  */ |  | ||||||
| @Data | @Data | ||||||
| @AllArgsConstructor | @AllArgsConstructor | ||||||
| @ToString(callSuper = false) | @ToString(callSuper = false) | ||||||
|   | |||||||
| @@ -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 ) ); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,128 +0,0 @@ | |||||||
| package net.md_5.bungee.api.plugin; |  | ||||||
|  |  | ||||||
| import java.io.File; |  | ||||||
| import java.net.MalformedURLException; |  | ||||||
| import java.net.URL; |  | ||||||
| import java.net.URLClassLoader; |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.Arrays; |  | ||||||
| import java.util.List; |  | ||||||
| import java.util.logging.Level; |  | ||||||
| import java.util.logging.Logger; |  | ||||||
| import org.apache.maven.repository.internal.MavenRepositorySystemUtils; |  | ||||||
| import org.eclipse.aether.DefaultRepositorySystemSession; |  | ||||||
| import org.eclipse.aether.RepositorySystem; |  | ||||||
| import org.eclipse.aether.artifact.Artifact; |  | ||||||
| import org.eclipse.aether.artifact.DefaultArtifact; |  | ||||||
| import org.eclipse.aether.collection.CollectRequest; |  | ||||||
| import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory; |  | ||||||
| import org.eclipse.aether.graph.Dependency; |  | ||||||
| import org.eclipse.aether.impl.DefaultServiceLocator; |  | ||||||
| import org.eclipse.aether.repository.LocalRepository; |  | ||||||
| import org.eclipse.aether.repository.RemoteRepository; |  | ||||||
| import org.eclipse.aether.repository.RepositoryPolicy; |  | ||||||
| import org.eclipse.aether.resolution.ArtifactResult; |  | ||||||
| import org.eclipse.aether.resolution.DependencyRequest; |  | ||||||
| import org.eclipse.aether.resolution.DependencyResolutionException; |  | ||||||
| import org.eclipse.aether.resolution.DependencyResult; |  | ||||||
| import org.eclipse.aether.spi.connector.RepositoryConnectorFactory; |  | ||||||
| import org.eclipse.aether.spi.connector.transport.TransporterFactory; |  | ||||||
| import org.eclipse.aether.transfer.AbstractTransferListener; |  | ||||||
| import org.eclipse.aether.transfer.TransferCancelledException; |  | ||||||
| import org.eclipse.aether.transfer.TransferEvent; |  | ||||||
| import org.eclipse.aether.transport.http.HttpTransporterFactory; |  | ||||||
|  |  | ||||||
| class LibraryLoader |  | ||||||
| { |  | ||||||
|  |  | ||||||
|     private final Logger logger; |  | ||||||
|     private final RepositorySystem repository; |  | ||||||
|     private final DefaultRepositorySystemSession session; |  | ||||||
|     private final List<RemoteRepository> repositories; |  | ||||||
|  |  | ||||||
|     public LibraryLoader(Logger logger) |  | ||||||
|     { |  | ||||||
|         this.logger = logger; |  | ||||||
|  |  | ||||||
|         DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator(); |  | ||||||
|         locator.addService( RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class ); |  | ||||||
|         locator.addService( TransporterFactory.class, HttpTransporterFactory.class ); |  | ||||||
|  |  | ||||||
|         this.repository = locator.getService( RepositorySystem.class ); |  | ||||||
|         this.session = MavenRepositorySystemUtils.newSession(); |  | ||||||
|  |  | ||||||
|         session.setChecksumPolicy( RepositoryPolicy.CHECKSUM_POLICY_FAIL ); |  | ||||||
|         session.setLocalRepositoryManager( repository.newLocalRepositoryManager( session, new LocalRepository( "libraries" ) ) ); |  | ||||||
|         session.setTransferListener( new AbstractTransferListener() |  | ||||||
|         { |  | ||||||
|             @Override |  | ||||||
|             public void transferStarted(TransferEvent event) throws TransferCancelledException |  | ||||||
|             { |  | ||||||
|                 logger.log( Level.INFO, "Downloading {0}", event.getResource().getRepositoryUrl() + event.getResource().getResourceName() ); |  | ||||||
|             } |  | ||||||
|         } ); |  | ||||||
|  |  | ||||||
|         // SPIGOT-7638: Add system properties, |  | ||||||
|         // since JdkVersionProfileActivator needs 'java.version' when a profile has the 'jdk' element |  | ||||||
|         // otherwise it will silently fail and not resolves the dependencies in the affected pom. |  | ||||||
|         session.setSystemProperties( System.getProperties() ); |  | ||||||
|         session.setReadOnly(); |  | ||||||
|  |  | ||||||
|         this.repositories = repository.newResolutionRepositories( session, Arrays.asList( new RemoteRepository.Builder( "central", "default", "https://repo.maven.apache.org/maven2" ).build() ) ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public ClassLoader createLoader(PluginDescription desc) |  | ||||||
|     { |  | ||||||
|         if ( desc.getLibraries().isEmpty() ) |  | ||||||
|         { |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
|         logger.log( Level.INFO, "[{0}] Loading {1} libraries... please wait", new Object[] |  | ||||||
|         { |  | ||||||
|             desc.getName(), desc.getLibraries().size() |  | ||||||
|         } ); |  | ||||||
|  |  | ||||||
|         List<Dependency> dependencies = new ArrayList<>(); |  | ||||||
|         for ( String library : desc.getLibraries() ) |  | ||||||
|         { |  | ||||||
|             Artifact artifact = new DefaultArtifact( library ); |  | ||||||
|             Dependency dependency = new Dependency( artifact, null ); |  | ||||||
|  |  | ||||||
|             dependencies.add( dependency ); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         DependencyResult result; |  | ||||||
|         try |  | ||||||
|         { |  | ||||||
|             result = repository.resolveDependencies( session, new DependencyRequest( new CollectRequest( (Dependency) null, dependencies, repositories ), null ) ); |  | ||||||
|         } catch ( DependencyResolutionException ex ) |  | ||||||
|         { |  | ||||||
|             throw new RuntimeException( "Error resolving libraries", ex ); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         List<URL> jarFiles = new ArrayList<>(); |  | ||||||
|         for ( ArtifactResult artifact : result.getArtifactResults() ) |  | ||||||
|         { |  | ||||||
|             File file = artifact.getArtifact().getFile(); |  | ||||||
|  |  | ||||||
|             URL url; |  | ||||||
|             try |  | ||||||
|             { |  | ||||||
|                 url = file.toURI().toURL(); |  | ||||||
|             } catch ( MalformedURLException ex ) |  | ||||||
|             { |  | ||||||
|                 throw new AssertionError( ex ); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             jarFiles.add( url ); |  | ||||||
|             logger.log( Level.INFO, "[{0}] Loaded library {1}", new Object[] |  | ||||||
|             { |  | ||||||
|                 desc.getName(), file |  | ||||||
|             } ); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         URLClassLoader loader = new URLClassLoader( jarFiles.toArray( new URL[ 0 ] ) ); |  | ||||||
|  |  | ||||||
|         return loader; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,23 +1,12 @@ | |||||||
| package net.md_5.bungee.api.plugin; | package net.md_5.bungee.api.plugin; | ||||||
|  |  | ||||||
| import com.google.common.base.Preconditions; | import com.google.common.base.Preconditions; | ||||||
| import com.google.common.io.ByteStreams; |  | ||||||
| import java.io.File; |  | ||||||
| import java.io.IOException; |  | ||||||
| import java.io.InputStream; |  | ||||||
| import java.net.URL; | import java.net.URL; | ||||||
| import java.net.URLClassLoader; | import java.net.URLClassLoader; | ||||||
| import java.security.CodeSigner; |  | ||||||
| import java.security.CodeSource; |  | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
| import java.util.concurrent.CopyOnWriteArraySet; | import java.util.concurrent.CopyOnWriteArraySet; | ||||||
| import java.util.jar.JarEntry; |  | ||||||
| import java.util.jar.JarFile; |  | ||||||
| import java.util.jar.Manifest; |  | ||||||
| import lombok.ToString; |  | ||||||
| import net.md_5.bungee.api.ProxyServer; | import net.md_5.bungee.api.ProxyServer; | ||||||
|  |  | ||||||
| @ToString(of = "desc") |  | ||||||
| final class PluginClassloader extends URLClassLoader | final class PluginClassloader extends URLClassLoader | ||||||
| { | { | ||||||
|  |  | ||||||
| @@ -25,10 +14,6 @@ final class PluginClassloader extends URLClassLoader | |||||||
|     // |     // | ||||||
|     private final ProxyServer proxy; |     private final ProxyServer proxy; | ||||||
|     private final PluginDescription desc; |     private final PluginDescription desc; | ||||||
|     private final JarFile jar; |  | ||||||
|     private final Manifest manifest; |  | ||||||
|     private final URL url; |  | ||||||
|     private final ClassLoader libraryLoader; |  | ||||||
|     // |     // | ||||||
|     private Plugin plugin; |     private Plugin plugin; | ||||||
|  |  | ||||||
| @@ -37,18 +22,11 @@ final class PluginClassloader extends URLClassLoader | |||||||
|         ClassLoader.registerAsParallelCapable(); |         ClassLoader.registerAsParallelCapable(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public PluginClassloader(ProxyServer proxy, PluginDescription desc, File file, ClassLoader libraryLoader) throws IOException |     public PluginClassloader(ProxyServer proxy, PluginDescription desc, URL[] urls) | ||||||
|     { |     { | ||||||
|         super( new URL[] |         super( urls ); | ||||||
|         { |  | ||||||
|             file.toURI().toURL() |  | ||||||
|         } ); |  | ||||||
|         this.proxy = proxy; |         this.proxy = proxy; | ||||||
|         this.desc = desc; |         this.desc = desc; | ||||||
|         this.jar = new JarFile( file ); |  | ||||||
|         this.manifest = jar.getManifest(); |  | ||||||
|         this.url = file.toURI().toURL(); |  | ||||||
|         this.libraryLoader = libraryLoader; |  | ||||||
|  |  | ||||||
|         allLoaders.add( this ); |         allLoaders.add( this ); | ||||||
|     } |     } | ||||||
| @@ -56,34 +34,17 @@ final class PluginClassloader extends URLClassLoader | |||||||
|     @Override |     @Override | ||||||
|     protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException |     protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException | ||||||
|     { |     { | ||||||
|         return loadClass0( name, resolve, true, true ); |         return loadClass0( name, resolve, true ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private Class<?> loadClass0(String name, boolean resolve, boolean checkOther, boolean checkLibraries) throws ClassNotFoundException |     private Class<?> loadClass0(String name, boolean resolve, boolean checkOther) throws ClassNotFoundException | ||||||
|     { |     { | ||||||
|         try |         try | ||||||
|         { |         { | ||||||
|             Class<?> result = super.loadClass( name, resolve ); |             return super.loadClass( name, resolve ); | ||||||
|  |  | ||||||
|             // SPIGOT-6749: Library classes will appear in the above, but we don't want to return them to other plugins |  | ||||||
|             if ( checkOther || result.getClassLoader() == this ) |  | ||||||
|             { |  | ||||||
|                 return result; |  | ||||||
|             } |  | ||||||
|         } catch ( ClassNotFoundException ex ) |         } catch ( ClassNotFoundException ex ) | ||||||
|         { |         { | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if ( checkLibraries && libraryLoader != null ) |  | ||||||
|         { |  | ||||||
|             try |  | ||||||
|             { |  | ||||||
|                 return libraryLoader.loadClass( name ); |  | ||||||
|             } catch ( ClassNotFoundException ex ) |  | ||||||
|             { |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if ( checkOther ) |         if ( checkOther ) | ||||||
|         { |         { | ||||||
|             for ( PluginClassloader loader : allLoaders ) |             for ( PluginClassloader loader : allLoaders ) | ||||||
| @@ -92,81 +53,16 @@ final class PluginClassloader extends URLClassLoader | |||||||
|                 { |                 { | ||||||
|                     try |                     try | ||||||
|                     { |                     { | ||||||
|                         return loader.loadClass0( name, resolve, false, proxy.getPluginManager().isTransitiveDepend( desc, loader.desc ) ); |                         return loader.loadClass0( name, resolve, false ); | ||||||
|                     } catch ( ClassNotFoundException ex ) |                     } catch ( ClassNotFoundException ex ) | ||||||
|                     { |                     { | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         throw new ClassNotFoundException( name ); |         throw new ClassNotFoundException( name ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     protected Class<?> findClass(String name) throws ClassNotFoundException |  | ||||||
|     { |  | ||||||
|         String path = name.replace( '.', '/' ).concat( ".class" ); |  | ||||||
|         JarEntry entry = jar.getJarEntry( path ); |  | ||||||
|  |  | ||||||
|         if ( entry != null ) |  | ||||||
|         { |  | ||||||
|             byte[] classBytes; |  | ||||||
|  |  | ||||||
|             try ( InputStream is = jar.getInputStream( entry ) ) |  | ||||||
|             { |  | ||||||
|                 classBytes = ByteStreams.toByteArray( is ); |  | ||||||
|             } catch ( IOException ex ) |  | ||||||
|             { |  | ||||||
|                 throw new ClassNotFoundException( name, ex ); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             int dot = name.lastIndexOf( '.' ); |  | ||||||
|             if ( dot != -1 ) |  | ||||||
|             { |  | ||||||
|                 String pkgName = name.substring( 0, dot ); |  | ||||||
|                 if ( getPackage( pkgName ) == null ) |  | ||||||
|                 { |  | ||||||
|                     try |  | ||||||
|                     { |  | ||||||
|                         if ( manifest != null ) |  | ||||||
|                         { |  | ||||||
|                             definePackage( pkgName, manifest, url ); |  | ||||||
|                         } else |  | ||||||
|                         { |  | ||||||
|                             definePackage( pkgName, null, null, null, null, null, null, null ); |  | ||||||
|                         } |  | ||||||
|                     } catch ( IllegalArgumentException ex ) |  | ||||||
|                     { |  | ||||||
|                         if ( getPackage( pkgName ) == null ) |  | ||||||
|                         { |  | ||||||
|                             throw new IllegalStateException( "Cannot find package " + pkgName ); |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             CodeSigner[] signers = entry.getCodeSigners(); |  | ||||||
|             CodeSource source = new CodeSource( url, signers ); |  | ||||||
|  |  | ||||||
|             return defineClass( name, classBytes, 0, classBytes.length, source ); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return super.findClass( name ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void close() throws IOException |  | ||||||
|     { |  | ||||||
|         try |  | ||||||
|         { |  | ||||||
|             super.close(); |  | ||||||
|         } finally |  | ||||||
|         { |  | ||||||
|             jar.close(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void init(Plugin plugin) |     void init(Plugin plugin) | ||||||
|     { |     { | ||||||
|         Preconditions.checkArgument( plugin != null, "plugin" ); |         Preconditions.checkArgument( plugin != null, "plugin" ); | ||||||
|   | |||||||
| @@ -2,8 +2,6 @@ package net.md_5.bungee.api.plugin; | |||||||
|  |  | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.util.HashSet; | import java.util.HashSet; | ||||||
| import java.util.LinkedList; |  | ||||||
| import java.util.List; |  | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
| import lombok.AllArgsConstructor; | import lombok.AllArgsConstructor; | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
| @@ -50,8 +48,4 @@ public class PluginDescription | |||||||
|      * Optional description. |      * Optional description. | ||||||
|      */ |      */ | ||||||
|     private String description = null; |     private String description = null; | ||||||
|     /** |  | ||||||
|      * Optional libraries. |  | ||||||
|      */ |  | ||||||
|     private List<String> libraries = new LinkedList<>(); |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -4,12 +4,10 @@ import com.google.common.base.Preconditions; | |||||||
| import com.google.common.collect.ArrayListMultimap; | import com.google.common.collect.ArrayListMultimap; | ||||||
| import com.google.common.collect.Multimap; | import com.google.common.collect.Multimap; | ||||||
| import com.google.common.eventbus.Subscribe; | import com.google.common.eventbus.Subscribe; | ||||||
| import com.google.common.graph.GraphBuilder; |  | ||||||
| import com.google.common.graph.Graphs; |  | ||||||
| import com.google.common.graph.MutableGraph; |  | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.io.InputStream; | import java.io.InputStream; | ||||||
| import java.lang.reflect.Method; | import java.lang.reflect.Method; | ||||||
|  | import java.net.URL; | ||||||
| import java.net.URLClassLoader; | import java.net.URLClassLoader; | ||||||
| import java.util.Arrays; | import java.util.Arrays; | ||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
| @@ -33,7 +31,6 @@ import net.md_5.bungee.api.ProxyServer; | |||||||
| import net.md_5.bungee.api.connection.ProxiedPlayer; | import net.md_5.bungee.api.connection.ProxiedPlayer; | ||||||
| import net.md_5.bungee.event.EventBus; | import net.md_5.bungee.event.EventBus; | ||||||
| import net.md_5.bungee.event.EventHandler; | import net.md_5.bungee.event.EventHandler; | ||||||
| import org.yaml.snakeyaml.LoaderOptions; |  | ||||||
| import org.yaml.snakeyaml.Yaml; | import org.yaml.snakeyaml.Yaml; | ||||||
| import org.yaml.snakeyaml.constructor.Constructor; | import org.yaml.snakeyaml.constructor.Constructor; | ||||||
| import org.yaml.snakeyaml.introspector.PropertyUtils; | import org.yaml.snakeyaml.introspector.PropertyUtils; | ||||||
| @@ -52,8 +49,6 @@ public final class PluginManager | |||||||
|     private final Yaml yaml; |     private final Yaml yaml; | ||||||
|     private final EventBus eventBus; |     private final EventBus eventBus; | ||||||
|     private final Map<String, Plugin> plugins = new LinkedHashMap<>(); |     private final Map<String, Plugin> plugins = new LinkedHashMap<>(); | ||||||
|     private final MutableGraph<String> dependencyGraph = GraphBuilder.directed().build(); |  | ||||||
|     private final LibraryLoader libraryLoader; |  | ||||||
|     private final Map<String, Command> commandMap = new HashMap<>(); |     private final Map<String, Command> commandMap = new HashMap<>(); | ||||||
|     private Map<String, PluginDescription> toLoad = new HashMap<>(); |     private Map<String, PluginDescription> toLoad = new HashMap<>(); | ||||||
|     private final Multimap<Plugin, Command> commandsByPlugin = ArrayListMultimap.create(); |     private final Multimap<Plugin, Command> commandsByPlugin = ArrayListMultimap.create(); | ||||||
| @@ -65,24 +60,13 @@ public final class PluginManager | |||||||
|         this.proxy = proxy; |         this.proxy = proxy; | ||||||
|  |  | ||||||
|         // Ignore unknown entries in the plugin descriptions |         // Ignore unknown entries in the plugin descriptions | ||||||
|         Constructor yamlConstructor = new Constructor( new LoaderOptions() ); |         Constructor yamlConstructor = new Constructor(); | ||||||
|         PropertyUtils propertyUtils = yamlConstructor.getPropertyUtils(); |         PropertyUtils propertyUtils = yamlConstructor.getPropertyUtils(); | ||||||
|         propertyUtils.setSkipMissingProperties( true ); |         propertyUtils.setSkipMissingProperties( true ); | ||||||
|         yamlConstructor.setPropertyUtils( propertyUtils ); |         yamlConstructor.setPropertyUtils( propertyUtils ); | ||||||
|         yaml = new Yaml( yamlConstructor ); |         yaml = new Yaml( yamlConstructor ); | ||||||
|  |  | ||||||
|         eventBus = new EventBus( proxy.getLogger() ); |         eventBus = new EventBus( proxy.getLogger() ); | ||||||
|  |  | ||||||
|         LibraryLoader libraryLoader = null; |  | ||||||
|         try |  | ||||||
|         { |  | ||||||
|             libraryLoader = new LibraryLoader( proxy.getLogger() ); |  | ||||||
|         } catch ( NoClassDefFoundError ex ) |  | ||||||
|         { |  | ||||||
|             // Provided depends were not added back |  | ||||||
|             proxy.getLogger().warning( "Could not initialize LibraryLoader (missing dependencies?)" ); |  | ||||||
|         } |  | ||||||
|         this.libraryLoader = libraryLoader; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -325,7 +309,6 @@ public final class PluginManager | |||||||
|                 status = false; |                 status = false; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             dependencyGraph.putEdge( plugin.getName(), dependName ); |  | ||||||
|             if ( !status ) |             if ( !status ) | ||||||
|             { |             { | ||||||
|                 break; |                 break; | ||||||
| @@ -337,7 +320,10 @@ public final class PluginManager | |||||||
|         { |         { | ||||||
|             try |             try | ||||||
|             { |             { | ||||||
|                 URLClassLoader loader = new PluginClassloader( proxy, plugin, plugin.getFile(), ( libraryLoader != null ) ? libraryLoader.createLoader( plugin ) : null ); |                 URLClassLoader loader = new PluginClassloader( proxy, plugin, new URL[] | ||||||
|  |                 { | ||||||
|  |                     plugin.getFile().toURI().toURL() | ||||||
|  |                 } ); | ||||||
|                 Class<?> main = loader.loadClass( plugin.getMain() ); |                 Class<?> main = loader.loadClass( plugin.getMain() ); | ||||||
|                 Plugin clazz = (Plugin) main.getDeclaredConstructor().newInstance(); |                 Plugin clazz = (Plugin) main.getDeclaredConstructor().newInstance(); | ||||||
|  |  | ||||||
| @@ -349,7 +335,7 @@ public final class PluginManager | |||||||
|                 } ); |                 } ); | ||||||
|             } catch ( Throwable t ) |             } catch ( Throwable t ) | ||||||
|             { |             { | ||||||
|                 proxy.getLogger().log( Level.WARNING, "Error loading plugin " + plugin.getName(), t ); |                 proxy.getLogger().log( Level.WARNING, "Error enabling plugin " + plugin.getName(), t ); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -477,19 +463,4 @@ public final class PluginManager | |||||||
|     { |     { | ||||||
|         return Collections.unmodifiableCollection( commandMap.entrySet() ); |         return Collections.unmodifiableCollection( commandMap.entrySet() ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     boolean isTransitiveDepend(PluginDescription plugin, PluginDescription depend) |  | ||||||
|     { |  | ||||||
|         Preconditions.checkArgument( plugin != null, "plugin" ); |  | ||||||
|         Preconditions.checkArgument( depend != null, "depend" ); |  | ||||||
|  |  | ||||||
|         if ( dependencyGraph.nodes().contains( plugin.getName() ) ) |  | ||||||
|         { |  | ||||||
|             if ( Graphs.reachableNodes( dependencyGraph, plugin.getName() ).contains( depend.getName() ) ) |  | ||||||
|             { |  | ||||||
|                 return true; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,13 +1,12 @@ | |||||||
| package net.md_5.bungee.api; | package net.md_5.bungee.api; | ||||||
|  |  | ||||||
| import static org.junit.jupiter.api.Assertions.*; |  | ||||||
| import java.net.InetSocketAddress; | import java.net.InetSocketAddress; | ||||||
| import java.net.SocketAddress; | import java.net.SocketAddress; | ||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
| import net.md_5.bungee.api.config.ServerInfo; | import net.md_5.bungee.api.config.ServerInfo; | ||||||
| import net.md_5.bungee.api.connection.ProxiedPlayer; | import net.md_5.bungee.api.connection.ProxiedPlayer; | ||||||
| import net.md_5.bungee.api.event.ServerConnectEvent; | import net.md_5.bungee.api.event.ServerConnectEvent; | ||||||
| import org.junit.jupiter.api.Test; | import org.junit.Test; | ||||||
|  |  | ||||||
| public class ServerConnectRequestTest | public class ServerConnectRequestTest | ||||||
| { | { | ||||||
| @@ -79,15 +78,15 @@ public class ServerConnectRequestTest | |||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     @Test |     @Test(expected = NullPointerException.class) | ||||||
|     public void testNullTarget() |     public void testNullTarget() | ||||||
|     { |     { | ||||||
|         assertThrows( NullPointerException.class, () -> ServerConnectRequest.builder().target( null ).reason( ServerConnectEvent.Reason.JOIN_PROXY ).build() ); |         ServerConnectRequest.builder().target( null ).reason( ServerConnectEvent.Reason.JOIN_PROXY ).build(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test(expected = NullPointerException.class) | ||||||
|     public void testNullReason() |     public void testNullReason() | ||||||
|     { |     { | ||||||
|         assertThrows( NullPointerException.class, () -> ServerConnectRequest.builder().target( DUMMY_INFO ).reason( null ).build() ); |         ServerConnectRequest.builder().target( DUMMY_INFO ).reason( null ).build(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,38 +1,63 @@ | |||||||
| package net.md_5.bungee.util; | package net.md_5.bungee.util; | ||||||
|  |  | ||||||
| import static org.junit.jupiter.api.Assertions.*; |  | ||||||
| import io.netty.channel.unix.DomainSocketAddress; | import io.netty.channel.unix.DomainSocketAddress; | ||||||
| import java.net.InetSocketAddress; | import java.net.InetSocketAddress; | ||||||
| import java.net.SocketAddress; | import java.net.SocketAddress; | ||||||
| import java.util.stream.Stream; | import java.util.Arrays; | ||||||
|  | import java.util.Collection; | ||||||
| import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||||
| import net.md_5.bungee.Util; | import net.md_5.bungee.Util; | ||||||
| import org.junit.jupiter.params.ParameterizedTest; | import org.junit.Assert; | ||||||
| import org.junit.jupiter.params.provider.Arguments; | import org.junit.Test; | ||||||
| import org.junit.jupiter.params.provider.MethodSource; | import org.junit.runner.RunWith; | ||||||
|  | import org.junit.runners.Parameterized; | ||||||
|  | import org.junit.runners.Parameterized.Parameters; | ||||||
|  |  | ||||||
| @RequiredArgsConstructor | @RequiredArgsConstructor | ||||||
|  | @RunWith(Parameterized.class) | ||||||
| public class AddressParseTest | public class AddressParseTest | ||||||
| { | { | ||||||
|  |  | ||||||
|     public static Stream<Arguments> data() |     @Parameters | ||||||
|  |     public static Collection<Object[]> data() | ||||||
|     { |     { | ||||||
|         return Stream.of( |         return Arrays.asList( new Object[][] | ||||||
|                 Arguments.of( "127.0.0.1", "127.0.0.1", Util.DEFAULT_PORT ), |         { | ||||||
|                 Arguments.of( "127.0.0.1:1337", "127.0.0.1", 1337 ), |             { | ||||||
|                 Arguments.of( "[::1]", "0:0:0:0:0:0:0:1", Util.DEFAULT_PORT ), |                 "127.0.0.1", "127.0.0.1", Util.DEFAULT_PORT | ||||||
|                 Arguments.of( "[0:0:0:0::1]", "0:0:0:0:0:0:0:1", Util.DEFAULT_PORT ), |             }, | ||||||
|                 Arguments.of( "[0:0:0:0:0:0:0:1]", "0:0:0:0:0:0:0:1", Util.DEFAULT_PORT ), |             { | ||||||
|                 Arguments.of( "[::1]:1337", "0:0:0:0:0:0:0:1", 1337 ), |                 "127.0.0.1:1337", "127.0.0.1", 1337 | ||||||
|                 Arguments.of( "[0:0:0:0::1]:1337", "0:0:0:0:0:0:0:1", 1337 ), |             }, | ||||||
|                 Arguments.of( "[0:0:0:0:0:0:0:1]:1337", "0:0:0:0:0:0:0:1", 1337 ), |             { | ||||||
|                 Arguments.of( "unix:///var/run/bungee.sock", "/var/run/bungee.sock", -1 ) |                 "[::1]", "0:0:0:0:0:0:0:1", Util.DEFAULT_PORT | ||||||
|         ); |             }, | ||||||
|  |             { | ||||||
|  |                 "[0:0:0:0::1]", "0:0:0:0:0:0:0:1", Util.DEFAULT_PORT | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |                 "[0:0:0:0:0:0:0:1]", "0:0:0:0:0:0:0:1", Util.DEFAULT_PORT | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |                 "[::1]:1337", "0:0:0:0:0:0:0:1", 1337 | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |                 "[0:0:0:0::1]:1337", "0:0:0:0:0:0:0:1", 1337 | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |                 "[0:0:0:0:0:0:0:1]:1337", "0:0:0:0:0:0:0:1", 1337 | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |                 "unix:///var/run/bungee.sock", "/var/run/bungee.sock", -1 | ||||||
|             } |             } | ||||||
|  |         } ); | ||||||
|  |     } | ||||||
|  |     private final String line; | ||||||
|  |     private final String host; | ||||||
|  |     private final int port; | ||||||
|  |  | ||||||
|     @ParameterizedTest |     @Test | ||||||
|     @MethodSource("data") |     public void test() | ||||||
|     public void test(String line, String host, int port) |  | ||||||
|     { |     { | ||||||
|         SocketAddress parsed = Util.getAddr( line ); |         SocketAddress parsed = Util.getAddr( line ); | ||||||
|  |  | ||||||
| @@ -40,14 +65,14 @@ public class AddressParseTest | |||||||
|         { |         { | ||||||
|             InetSocketAddress tcp = (InetSocketAddress) parsed; |             InetSocketAddress tcp = (InetSocketAddress) parsed; | ||||||
|  |  | ||||||
|             assertEquals( host, tcp.getHostString() ); |             Assert.assertEquals( host, tcp.getHostString() ); | ||||||
|             assertEquals( port, tcp.getPort() ); |             Assert.assertEquals( port, tcp.getPort() ); | ||||||
|         } else if ( parsed instanceof DomainSocketAddress ) |         } else if ( parsed instanceof DomainSocketAddress ) | ||||||
|         { |         { | ||||||
|             DomainSocketAddress unix = (DomainSocketAddress) parsed; |             DomainSocketAddress unix = (DomainSocketAddress) parsed; | ||||||
|  |  | ||||||
|             assertEquals( host, unix.path() ); |             Assert.assertEquals( host, unix.path() ); | ||||||
|             assertEquals( -1, port ); |             Assert.assertEquals( -1, port ); | ||||||
|         } else |         } else | ||||||
|         { |         { | ||||||
|             throw new AssertionError( "Unknown socket " + parsed ); |             throw new AssertionError( "Unknown socket " + parsed ); | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| package net.md_5.bungee.util; | package net.md_5.bungee.util; | ||||||
|  |  | ||||||
| import static org.junit.jupiter.api.Assertions.*; | import org.junit.Assert; | ||||||
| import org.junit.jupiter.api.Test; | import org.junit.Test; | ||||||
|  |  | ||||||
| public class CaseInsensitiveTest | public class CaseInsensitiveTest | ||||||
| { | { | ||||||
| @@ -13,12 +13,12 @@ public class CaseInsensitiveTest | |||||||
|         CaseInsensitiveMap<Object> map = new CaseInsensitiveMap<>(); |         CaseInsensitiveMap<Object> map = new CaseInsensitiveMap<>(); | ||||||
|  |  | ||||||
|         map.put( "FOO", obj ); |         map.put( "FOO", obj ); | ||||||
|         assertTrue( map.contains( "foo" ) ); // Assert that contains is case insensitive |         Assert.assertTrue( map.contains( "foo" ) ); // Assert that contains is case insensitive | ||||||
|         assertTrue( map.entrySet().iterator().next().getKey().equals( "FOO" ) ); // Assert that case is preserved |         Assert.assertTrue( map.entrySet().iterator().next().getKey().equals( "FOO" ) ); // Assert that case is preserved | ||||||
|  |  | ||||||
|         // Assert that remove is case insensitive |         // Assert that remove is case insensitive | ||||||
|         map.remove( "FoO" ); |         map.remove( "FoO" ); | ||||||
|         assertFalse( map.contains( "foo" ) ); |         Assert.assertFalse( map.contains( "foo" ) ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
| @@ -27,8 +27,8 @@ public class CaseInsensitiveTest | |||||||
|         CaseInsensitiveSet set = new CaseInsensitiveSet(); |         CaseInsensitiveSet set = new CaseInsensitiveSet(); | ||||||
|  |  | ||||||
|         set.add( "FOO" ); |         set.add( "FOO" ); | ||||||
|         assertTrue( set.contains( "foo" ) ); // Assert that contains is case insensitive |         Assert.assertTrue( set.contains( "foo" ) ); // Assert that contains is case insensitive | ||||||
|         set.remove( "FoO" ); |         set.remove( "FoO" ); | ||||||
|         assertFalse( set.contains( "foo" ) ); // Assert that remove is case insensitive |         Assert.assertFalse( set.contains( "foo" ) ); // Assert that remove is case insensitive | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,9 +1,9 @@ | |||||||
| package net.md_5.bungee.util; | package net.md_5.bungee.util; | ||||||
|  |  | ||||||
| import static org.junit.jupiter.api.Assertions.*; |  | ||||||
| import java.util.UUID; | import java.util.UUID; | ||||||
| import net.md_5.bungee.Util; | import net.md_5.bungee.Util; | ||||||
| import org.junit.jupiter.api.Test; | import org.junit.Assert; | ||||||
|  | import org.junit.Test; | ||||||
|  |  | ||||||
| public class UUIDTest | public class UUIDTest | ||||||
| { | { | ||||||
| @@ -13,7 +13,7 @@ public class UUIDTest | |||||||
|     { |     { | ||||||
|         UUID uuid = UUID.fromString( "af74a02d-19cb-445b-b07f-6866a861f783" ); |         UUID uuid = UUID.fromString( "af74a02d-19cb-445b-b07f-6866a861f783" ); | ||||||
|         UUID uuid1 = Util.getUUID( "af74a02d19cb445bb07f6866a861f783" ); |         UUID uuid1 = Util.getUUID( "af74a02d19cb445bb07f6866a861f783" ); | ||||||
|         assertEquals( uuid, uuid1 ); |         Assert.assertEquals( uuid, uuid1 ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
| @@ -23,7 +23,7 @@ public class UUIDTest | |||||||
|         { |         { | ||||||
|             UUID expected = UUID.randomUUID(); |             UUID expected = UUID.randomUUID(); | ||||||
|             UUID actual = Util.getUUID( expected.toString().replace( "-", "" ) ); |             UUID actual = Util.getUUID( expected.toString().replace( "-", "" ) ); | ||||||
|             assertEquals( expected, actual, "Could not parse UUID " + expected ); |             Assert.assertEquals( "Could not parse UUID " + expected, expected, actual ); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -6,13 +6,13 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>net.md-5</groupId> |         <groupId>net.md-5</groupId> | ||||||
|         <artifactId>bungeecord-parent</artifactId> |         <artifactId>bungeecord-parent</artifactId> | ||||||
|         <version>1.20-R0.3-SNAPSHOT</version> |         <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|         <relativePath>../pom.xml</relativePath> |         <relativePath>../pom.xml</relativePath> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <groupId>net.md-5</groupId> |     <groupId>net.md-5</groupId> | ||||||
|     <artifactId>bungeecord-bootstrap</artifactId> |     <artifactId>bungeecord-bootstrap</artifactId> | ||||||
|     <version>1.20-R0.3-SNAPSHOT</version> |     <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|     <packaging>jar</packaging> |     <packaging>jar</packaging> | ||||||
|  |  | ||||||
|     <name>BungeeCord-Bootstrap</name> |     <name>BungeeCord-Bootstrap</name> | ||||||
| @@ -41,7 +41,7 @@ | |||||||
|             <plugin> |             <plugin> | ||||||
|                 <groupId>org.apache.maven.plugins</groupId> |                 <groupId>org.apache.maven.plugins</groupId> | ||||||
|                 <artifactId>maven-jar-plugin</artifactId> |                 <artifactId>maven-jar-plugin</artifactId> | ||||||
|                 <version>3.4.1</version> |                 <version>3.2.0</version> | ||||||
|                 <configuration> |                 <configuration> | ||||||
|                     <archive> |                     <archive> | ||||||
|                         <manifestEntries> |                         <manifestEntries> | ||||||
| @@ -55,7 +55,7 @@ | |||||||
|             <plugin> |             <plugin> | ||||||
|                 <groupId>org.apache.maven.plugins</groupId> |                 <groupId>org.apache.maven.plugins</groupId> | ||||||
|                 <artifactId>maven-shade-plugin</artifactId> |                 <artifactId>maven-shade-plugin</artifactId> | ||||||
|                 <version>3.5.3</version> |                 <version>3.2.3</version> | ||||||
|                 <executions> |                 <executions> | ||||||
|                     <execution> |                     <execution> | ||||||
|                         <phase>package</phase> |                         <phase>package</phase> | ||||||
| @@ -79,34 +79,4 @@ | |||||||
|             </plugin> |             </plugin> | ||||||
|         </plugins> |         </plugins> | ||||||
|     </build> |     </build> | ||||||
|  |  | ||||||
|     <profiles> |  | ||||||
|         <profile> |  | ||||||
|             <id>jdk-9-release</id> |  | ||||||
|             <activation> |  | ||||||
|                 <jdk>[9,)</jdk> |  | ||||||
|             </activation> |  | ||||||
|             <properties> |  | ||||||
|                 <maven.compiler.release>6</maven.compiler.release> |  | ||||||
|             </properties> |  | ||||||
|         </profile> |  | ||||||
|         <profile> |  | ||||||
|             <id>jdk-12-release</id> |  | ||||||
|             <activation> |  | ||||||
|                 <jdk>[12,)</jdk> |  | ||||||
|             </activation> |  | ||||||
|             <properties> |  | ||||||
|                 <maven.compiler.release>7</maven.compiler.release> |  | ||||||
|             </properties> |  | ||||||
|         </profile> |  | ||||||
|         <profile> |  | ||||||
|             <id>jdk-20-release</id> |  | ||||||
|             <activation> |  | ||||||
|                 <jdk>[20,)</jdk> |  | ||||||
|             </activation> |  | ||||||
|             <properties> |  | ||||||
|                 <maven.compiler.release>8</maven.compiler.release> |  | ||||||
|             </properties> |  | ||||||
|         </profile> |  | ||||||
|     </profiles> |  | ||||||
| </project> | </project> | ||||||
|   | |||||||
| @@ -6,13 +6,13 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>net.md-5</groupId> |         <groupId>net.md-5</groupId> | ||||||
|         <artifactId>bungeecord-parent</artifactId> |         <artifactId>bungeecord-parent</artifactId> | ||||||
|         <version>1.20-R0.3-SNAPSHOT</version> |         <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|         <relativePath>../pom.xml</relativePath> |         <relativePath>../pom.xml</relativePath> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <groupId>net.md-5</groupId> |     <groupId>net.md-5</groupId> | ||||||
|     <artifactId>bungeecord-chat</artifactId> |     <artifactId>bungeecord-chat</artifactId> | ||||||
|     <version>1.20-R0.3-SNAPSHOT</version> |     <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|     <packaging>jar</packaging> |     <packaging>jar</packaging> | ||||||
|  |  | ||||||
|     <name>BungeeCord-Chat</name> |     <name>BungeeCord-Chat</name> | ||||||
| @@ -22,7 +22,7 @@ | |||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>com.google.code.gson</groupId> |             <groupId>com.google.code.gson</groupId> | ||||||
|             <artifactId>gson</artifactId> |             <artifactId>gson</artifactId> | ||||||
|             <version>2.10.1</version> |             <version>2.8.0</version> | ||||||
|             <scope>compile</scope> |             <scope>compile</scope> | ||||||
|         </dependency> |         </dependency> | ||||||
|     </dependencies> |     </dependencies> | ||||||
|   | |||||||
| @@ -244,7 +244,7 @@ public final class ChatColor | |||||||
|     public static ChatColor of(String string) |     public static ChatColor of(String string) | ||||||
|     { |     { | ||||||
|         Preconditions.checkArgument( string != null, "string cannot be null" ); |         Preconditions.checkArgument( string != null, "string cannot be null" ); | ||||||
|         if ( string.length() == 7 && string.charAt( 0 ) == '#' ) |         if ( string.startsWith( "#" ) && string.length() == 7 ) | ||||||
|         { |         { | ||||||
|             int rgb; |             int rgb; | ||||||
|             try |             try | ||||||
| @@ -300,7 +300,7 @@ public final class ChatColor | |||||||
|     @Deprecated |     @Deprecated | ||||||
|     public static ChatColor[] values() |     public static ChatColor[] values() | ||||||
|     { |     { | ||||||
|         return BY_CHAR.values().toArray( new ChatColor[ 0 ] ); |         return BY_CHAR.values().toArray( new ChatColor[ BY_CHAR.values().size() ] ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|   | |||||||
| @@ -20,10 +20,38 @@ public abstract class BaseComponent | |||||||
|     BaseComponent parent; |     BaseComponent parent; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * The component's style. |      * The color of this component and any child components (unless overridden) | ||||||
|      */ |      */ | ||||||
|     @Getter |     private ChatColor color; | ||||||
|     private ComponentStyle style = new ComponentStyle(); |     /** | ||||||
|  |      * The font of this component and any child components (unless overridden) | ||||||
|  |      */ | ||||||
|  |     private String font; | ||||||
|  |     /** | ||||||
|  |      * 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; | ||||||
|     /** |     /** | ||||||
|      * The text to insert into the chat when this component (and child |      * The text to insert into the chat when this component (and child | ||||||
|      * components) are clicked while pressing the shift key |      * components) are clicked while pressing the shift key | ||||||
| @@ -50,12 +78,6 @@ public abstract class BaseComponent | |||||||
|     @Getter |     @Getter | ||||||
|     private HoverEvent hoverEvent; |     private HoverEvent hoverEvent; | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Whether this component rejects previous formatting |  | ||||||
|      */ |  | ||||||
|     @Getter |  | ||||||
|     private transient boolean reset; |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Default constructor. |      * Default constructor. | ||||||
|      * |      * | ||||||
| @@ -125,31 +147,31 @@ public abstract class BaseComponent | |||||||
|         } |         } | ||||||
|         if ( retention == FormatRetention.FORMATTING || retention == FormatRetention.ALL ) |         if ( retention == FormatRetention.FORMATTING || retention == FormatRetention.ALL ) | ||||||
|         { |         { | ||||||
|             if ( replace || !style.hasColor() ) |             if ( replace || color == null ) | ||||||
|             { |             { | ||||||
|                 setColor( component.getColorRaw() ); |                 setColor( component.getColorRaw() ); | ||||||
|             } |             } | ||||||
|             if ( replace || !style.hasFont() ) |             if ( replace || font == null ) | ||||||
|             { |             { | ||||||
|                 setFont( component.getFontRaw() ); |                 setFont( component.getFontRaw() ); | ||||||
|             } |             } | ||||||
|             if ( replace || style.isBoldRaw() == null ) |             if ( replace || bold == null ) | ||||||
|             { |             { | ||||||
|                 setBold( component.isBoldRaw() ); |                 setBold( component.isBoldRaw() ); | ||||||
|             } |             } | ||||||
|             if ( replace || style.isItalicRaw() == null ) |             if ( replace || italic == null ) | ||||||
|             { |             { | ||||||
|                 setItalic( component.isItalicRaw() ); |                 setItalic( component.isItalicRaw() ); | ||||||
|             } |             } | ||||||
|             if ( replace || style.isUnderlinedRaw() == null ) |             if ( replace || underlined == null ) | ||||||
|             { |             { | ||||||
|                 setUnderlined( component.isUnderlinedRaw() ); |                 setUnderlined( component.isUnderlinedRaw() ); | ||||||
|             } |             } | ||||||
|             if ( replace || style.isStrikethroughRaw() == null ) |             if ( replace || strikethrough == null ) | ||||||
|             { |             { | ||||||
|                 setStrikethrough( component.isStrikethroughRaw() ); |                 setStrikethrough( component.isStrikethroughRaw() ); | ||||||
|             } |             } | ||||||
|             if ( replace || style.isObfuscatedRaw() == null ) |             if ( replace || obfuscated == null ) | ||||||
|             { |             { | ||||||
|                 setObfuscated( component.isObfuscatedRaw() ); |                 setObfuscated( component.isObfuscatedRaw() ); | ||||||
|             } |             } | ||||||
| @@ -238,32 +260,6 @@ public abstract class BaseComponent | |||||||
|         return builder.toString(); |         return builder.toString(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Set the {@link ComponentStyle} for this component. |  | ||||||
|      * <p> |  | ||||||
|      * Unlike {@link #applyStyle(ComponentStyle)}, this method will overwrite |  | ||||||
|      * all style values on this component. |  | ||||||
|      * |  | ||||||
|      * @param style the style to set, or null to set all style values to default |  | ||||||
|      */ |  | ||||||
|     public void setStyle(ComponentStyle style) |  | ||||||
|     { |  | ||||||
|         this.style = ( style != null ) ? style.clone() : new ComponentStyle(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Set this component's color. |  | ||||||
|      * <p> |  | ||||||
|      * <b>Warning: This should be a color, not formatting code (ie, |  | ||||||
|      * {@link ChatColor#color} should not be null).</b> |  | ||||||
|      * |  | ||||||
|      * @param color the component color, or null to use the default |  | ||||||
|      */ |  | ||||||
|     public void setColor(ChatColor color) |  | ||||||
|     { |  | ||||||
|         this.style.setColor( color ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Returns the color of this component. This uses the parent's color if this |      * 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} |      * component doesn't have one. {@link net.md_5.bungee.api.ChatColor#WHITE} | ||||||
| @@ -273,7 +269,7 @@ public abstract class BaseComponent | |||||||
|      */ |      */ | ||||||
|     public ChatColor getColor() |     public ChatColor getColor() | ||||||
|     { |     { | ||||||
|         if ( !style.hasColor() ) |         if ( color == null ) | ||||||
|         { |         { | ||||||
|             if ( parent == null ) |             if ( parent == null ) | ||||||
|             { |             { | ||||||
| @@ -281,7 +277,7 @@ public abstract class BaseComponent | |||||||
|             } |             } | ||||||
|             return parent.getColor(); |             return parent.getColor(); | ||||||
|         } |         } | ||||||
|         return style.getColor(); |         return color; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -292,17 +288,7 @@ public abstract class BaseComponent | |||||||
|      */ |      */ | ||||||
|     public ChatColor getColorRaw() |     public ChatColor getColorRaw() | ||||||
|     { |     { | ||||||
|         return style.getColor(); |         return color; | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Set this component's font. |  | ||||||
|      * |  | ||||||
|      * @param font the font to set, or null to use the default |  | ||||||
|      */ |  | ||||||
|     public void setFont(String font) |  | ||||||
|     { |  | ||||||
|         this.style.setFont( font ); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -313,7 +299,7 @@ public abstract class BaseComponent | |||||||
|      */ |      */ | ||||||
|     public String getFont() |     public String getFont() | ||||||
|     { |     { | ||||||
|         if ( !style.hasFont() ) |         if ( font == null ) | ||||||
|         { |         { | ||||||
|             if ( parent == null ) |             if ( parent == null ) | ||||||
|             { |             { | ||||||
| @@ -321,7 +307,7 @@ public abstract class BaseComponent | |||||||
|             } |             } | ||||||
|             return parent.getFont(); |             return parent.getFont(); | ||||||
|         } |         } | ||||||
|         return style.getFont(); |         return font; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -332,17 +318,7 @@ public abstract class BaseComponent | |||||||
|      */ |      */ | ||||||
|     public String getFontRaw() |     public String getFontRaw() | ||||||
|     { |     { | ||||||
|         return style.getFont(); |         return font; | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Set whether or not this component is bold. |  | ||||||
|      * |  | ||||||
|      * @param bold the new bold state, or null to use the default |  | ||||||
|      */ |  | ||||||
|     public void setBold(Boolean bold) |  | ||||||
|     { |  | ||||||
|         this.style.setBold( bold ); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -354,11 +330,11 @@ public abstract class BaseComponent | |||||||
|      */ |      */ | ||||||
|     public boolean isBold() |     public boolean isBold() | ||||||
|     { |     { | ||||||
|         if ( style.isBoldRaw() == null ) |         if ( bold == null ) | ||||||
|         { |         { | ||||||
|             return parent != null && parent.isBold(); |             return parent != null && parent.isBold(); | ||||||
|         } |         } | ||||||
|         return style.isBold(); |         return bold; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -369,17 +345,7 @@ public abstract class BaseComponent | |||||||
|      */ |      */ | ||||||
|     public Boolean isBoldRaw() |     public Boolean isBoldRaw() | ||||||
|     { |     { | ||||||
|         return style.isBoldRaw(); |         return bold; | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Set whether or not this component is italic. |  | ||||||
|      * |  | ||||||
|      * @param italic the new italic state, or null to use the default |  | ||||||
|      */ |  | ||||||
|     public void setItalic(Boolean italic) |  | ||||||
|     { |  | ||||||
|         this.style.setItalic( italic ); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -391,11 +357,11 @@ public abstract class BaseComponent | |||||||
|      */ |      */ | ||||||
|     public boolean isItalic() |     public boolean isItalic() | ||||||
|     { |     { | ||||||
|         if ( style.isItalicRaw() == null ) |         if ( italic == null ) | ||||||
|         { |         { | ||||||
|             return parent != null && parent.isItalic(); |             return parent != null && parent.isItalic(); | ||||||
|         } |         } | ||||||
|         return style.isItalic(); |         return italic; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -406,17 +372,7 @@ public abstract class BaseComponent | |||||||
|      */ |      */ | ||||||
|     public Boolean isItalicRaw() |     public Boolean isItalicRaw() | ||||||
|     { |     { | ||||||
|         return style.isItalicRaw(); |         return italic; | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Set whether or not this component is underlined. |  | ||||||
|      * |  | ||||||
|      * @param underlined the new underlined state, or null to use the default |  | ||||||
|      */ |  | ||||||
|     public void setUnderlined(Boolean underlined) |  | ||||||
|     { |  | ||||||
|         this.style.setUnderlined( underlined ); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -428,11 +384,11 @@ public abstract class BaseComponent | |||||||
|      */ |      */ | ||||||
|     public boolean isUnderlined() |     public boolean isUnderlined() | ||||||
|     { |     { | ||||||
|         if ( style.isUnderlinedRaw() == null ) |         if ( underlined == null ) | ||||||
|         { |         { | ||||||
|             return parent != null && parent.isUnderlined(); |             return parent != null && parent.isUnderlined(); | ||||||
|         } |         } | ||||||
|         return style.isUnderlined(); |         return underlined; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -443,18 +399,7 @@ public abstract class BaseComponent | |||||||
|      */ |      */ | ||||||
|     public Boolean isUnderlinedRaw() |     public Boolean isUnderlinedRaw() | ||||||
|     { |     { | ||||||
|         return style.isUnderlinedRaw(); |         return underlined; | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Set whether or not this component is strikethrough. |  | ||||||
|      * |  | ||||||
|      * @param strikethrough the new strikethrough state, or null to use the |  | ||||||
|      * default |  | ||||||
|      */ |  | ||||||
|     public void setStrikethrough(Boolean strikethrough) |  | ||||||
|     { |  | ||||||
|         this.style.setStrikethrough( strikethrough ); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -466,11 +411,11 @@ public abstract class BaseComponent | |||||||
|      */ |      */ | ||||||
|     public boolean isStrikethrough() |     public boolean isStrikethrough() | ||||||
|     { |     { | ||||||
|         if ( style.isStrikethroughRaw() == null ) |         if ( strikethrough == null ) | ||||||
|         { |         { | ||||||
|             return parent != null && parent.isStrikethrough(); |             return parent != null && parent.isStrikethrough(); | ||||||
|         } |         } | ||||||
|         return style.isStrikethrough(); |         return strikethrough; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -481,17 +426,7 @@ public abstract class BaseComponent | |||||||
|      */ |      */ | ||||||
|     public Boolean isStrikethroughRaw() |     public Boolean isStrikethroughRaw() | ||||||
|     { |     { | ||||||
|         return style.isStrikethroughRaw(); |         return strikethrough; | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Set whether or not this component is obfuscated. |  | ||||||
|      * |  | ||||||
|      * @param obfuscated the new obfuscated state, or null to use the default |  | ||||||
|      */ |  | ||||||
|     public void setObfuscated(Boolean obfuscated) |  | ||||||
|     { |  | ||||||
|         this.style.setObfuscated( obfuscated ); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -503,11 +438,11 @@ public abstract class BaseComponent | |||||||
|      */ |      */ | ||||||
|     public boolean isObfuscated() |     public boolean isObfuscated() | ||||||
|     { |     { | ||||||
|         if ( style.isObfuscatedRaw() == null ) |         if ( obfuscated == null ) | ||||||
|         { |         { | ||||||
|             return parent != null && parent.isObfuscated(); |             return parent != null && parent.isObfuscated(); | ||||||
|         } |         } | ||||||
|         return style.isObfuscated(); |         return obfuscated; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -518,48 +453,7 @@ public abstract class BaseComponent | |||||||
|      */ |      */ | ||||||
|     public Boolean isObfuscatedRaw() |     public Boolean isObfuscatedRaw() | ||||||
|     { |     { | ||||||
|         return style.isObfuscatedRaw(); |         return obfuscated; | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Apply the style from the given {@link ComponentStyle} to this component. |  | ||||||
|      * <p> |  | ||||||
|      * Any style values that have been explicitly set in the style will be |  | ||||||
|      * applied to this component. If a value is not set in the style, it will |  | ||||||
|      * not override the style set in this component. |  | ||||||
|      * |  | ||||||
|      * @param style the style to apply |  | ||||||
|      */ |  | ||||||
|     public void applyStyle(ComponentStyle style) |  | ||||||
|     { |  | ||||||
|         if ( style.hasColor() ) |  | ||||||
|         { |  | ||||||
|             setColor( style.getColor() ); |  | ||||||
|         } |  | ||||||
|         if ( style.hasFont() ) |  | ||||||
|         { |  | ||||||
|             setFont( style.getFont() ); |  | ||||||
|         } |  | ||||||
|         if ( style.isBoldRaw() != null ) |  | ||||||
|         { |  | ||||||
|             setBold( style.isBoldRaw() ); |  | ||||||
|         } |  | ||||||
|         if ( style.isItalicRaw() != null ) |  | ||||||
|         { |  | ||||||
|             setItalic( style.isItalicRaw() ); |  | ||||||
|         } |  | ||||||
|         if ( style.isUnderlinedRaw() != null ) |  | ||||||
|         { |  | ||||||
|             setUnderlined( style.isUnderlinedRaw() ); |  | ||||||
|         } |  | ||||||
|         if ( style.isStrikethroughRaw() != null ) |  | ||||||
|         { |  | ||||||
|             setStrikethrough( style.isStrikethroughRaw() ); |  | ||||||
|         } |  | ||||||
|         if ( style.isObfuscatedRaw() != null ) |  | ||||||
|         { |  | ||||||
|             setObfuscated( style.isObfuscatedRaw() ); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void setExtra(List<BaseComponent> components) |     public void setExtra(List<BaseComponent> components) | ||||||
| @@ -598,16 +492,6 @@ public abstract class BaseComponent | |||||||
|         extra.add( component ); |         extra.add( component ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Returns whether the component has any styling applied to it. |  | ||||||
|      * |  | ||||||
|      * @return Whether any styling is applied |  | ||||||
|      */ |  | ||||||
|     public boolean hasStyle() |  | ||||||
|     { |  | ||||||
|         return !style.isEmpty(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Returns whether the component has any formatting or events applied to it |      * Returns whether the component has any formatting or events applied to it | ||||||
|      * |      * | ||||||
| @@ -615,8 +499,10 @@ public abstract class BaseComponent | |||||||
|      */ |      */ | ||||||
|     public boolean hasFormatting() |     public boolean hasFormatting() | ||||||
|     { |     { | ||||||
|         return hasStyle() || insertion != null |         return color != null || font != null || bold != null | ||||||
|                 || hoverEvent != null || clickEvent != null; |                 || italic != null || underlined != null | ||||||
|  |                 || strikethrough != null || obfuscated != null | ||||||
|  |                 || insertion != null || hoverEvent != null || clickEvent != null; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|   | |||||||
| @@ -57,7 +57,7 @@ public final class ComponentBuilder | |||||||
|      */ |      */ | ||||||
|     public ComponentBuilder(ComponentBuilder original) |     public ComponentBuilder(ComponentBuilder original) | ||||||
|     { |     { | ||||||
|         this( original.parts.toArray( new BaseComponent[ 0 ] ) ); |         this( original.parts.toArray( new BaseComponent[ original.parts.size() ] ) ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -161,7 +161,7 @@ public final class ComponentBuilder | |||||||
|             previous = dummy; |             previous = dummy; | ||||||
|             dummy = null; |             dummy = null; | ||||||
|         } |         } | ||||||
|         if ( previous != null && !component.isReset() ) |         if ( previous != null ) | ||||||
|         { |         { | ||||||
|             component.copyFormatting( previous, retention, false ); |             component.copyFormatting( previous, retention, false ); | ||||||
|         } |         } | ||||||
| @@ -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. | ||||||
| @@ -423,18 +396,6 @@ public final class ComponentBuilder | |||||||
|         return this; |         return this; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Applies the provided {@link ComponentStyle} to the current part. |  | ||||||
|      * |  | ||||||
|      * @param style the style to apply |  | ||||||
|      * @return this ComponentBuilder for chaining |  | ||||||
|      */ |  | ||||||
|     public ComponentBuilder style(ComponentStyle style) |  | ||||||
|     { |  | ||||||
|         getCurrentComponent().applyStyle( style ); |  | ||||||
|         return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Sets the insertion text for the current part. |      * Sets the insertion text for the current part. | ||||||
|      * |      * | ||||||
| @@ -493,32 +454,9 @@ public final class ComponentBuilder | |||||||
|         return this; |         return this; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Returns the component built by this builder. If this builder is empty, an |  | ||||||
|      * empty text component will be returned. |  | ||||||
|      * |  | ||||||
|      * @return the component |  | ||||||
|      */ |  | ||||||
|     public BaseComponent build() |  | ||||||
|     { |  | ||||||
|         TextComponent base = new TextComponent(); |  | ||||||
|         if ( !parts.isEmpty() ) |  | ||||||
|         { |  | ||||||
|             List<BaseComponent> cloned = new ArrayList<>( parts ); |  | ||||||
|             cloned.replaceAll( BaseComponent::duplicate ); |  | ||||||
|             base.setExtra( cloned ); |  | ||||||
|         } |  | ||||||
|         return base; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Returns the components needed to display the message created by this |      * Returns the components needed to display the message created by this | ||||||
|      * builder.git |      * builder.git | ||||||
|      * <p> |  | ||||||
|      * <strong>NOTE:</strong> {@link #build()} 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. |  | ||||||
|      * |      * | ||||||
|      * @return the created components |      * @return the created components | ||||||
|      */ |      */ | ||||||
|   | |||||||
| @@ -1,237 +0,0 @@ | |||||||
| package net.md_5.bungee.api.chat; |  | ||||||
|  |  | ||||||
| import lombok.AllArgsConstructor; |  | ||||||
| import lombok.EqualsAndHashCode; |  | ||||||
| import lombok.NoArgsConstructor; |  | ||||||
| import lombok.Setter; |  | ||||||
| import net.md_5.bungee.api.ChatColor; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Represents a style that may be applied to a {@link BaseComponent}. |  | ||||||
|  */ |  | ||||||
| @Setter |  | ||||||
| @AllArgsConstructor |  | ||||||
| @NoArgsConstructor |  | ||||||
| @EqualsAndHashCode |  | ||||||
| public final class ComponentStyle implements Cloneable |  | ||||||
| { |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * The color of this style. |  | ||||||
|      * <p> |  | ||||||
|      * <b>Warning: This should be a color, not formatting code (ie, |  | ||||||
|      * {@link ChatColor#color} should not be null).</b> |  | ||||||
|      */ |  | ||||||
|     private ChatColor color; |  | ||||||
|     /** |  | ||||||
|      * The font of this style. |  | ||||||
|      */ |  | ||||||
|     private String font; |  | ||||||
|     /** |  | ||||||
|      * Whether this style is bold. |  | ||||||
|      */ |  | ||||||
|     private Boolean bold; |  | ||||||
|     /** |  | ||||||
|      * Whether this style is italic. |  | ||||||
|      */ |  | ||||||
|     private Boolean italic; |  | ||||||
|     /** |  | ||||||
|      * Whether this style is underlined. |  | ||||||
|      */ |  | ||||||
|     private Boolean underlined; |  | ||||||
|     /** |  | ||||||
|      * Whether this style is strikethrough. |  | ||||||
|      */ |  | ||||||
|     private Boolean strikethrough; |  | ||||||
|     /** |  | ||||||
|      * Whether this style is obfuscated. |  | ||||||
|      */ |  | ||||||
|     private Boolean obfuscated; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Returns the color of this style. May return null. |  | ||||||
|      * |  | ||||||
|      * @return the color of this style, or null if default color |  | ||||||
|      */ |  | ||||||
|     public ChatColor getColor() |  | ||||||
|     { |  | ||||||
|         return color; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Returns whether or not this style has a color set. |  | ||||||
|      * |  | ||||||
|      * @return whether a color is set |  | ||||||
|      */ |  | ||||||
|     public boolean hasColor() |  | ||||||
|     { |  | ||||||
|         return ( color != null ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Returns the font of this style. May return null. |  | ||||||
|      * |  | ||||||
|      * @return the font of this style, or null if default font |  | ||||||
|      */ |  | ||||||
|     public String getFont() |  | ||||||
|     { |  | ||||||
|         return font; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Returns whether or not this style has a font set. |  | ||||||
|      * |  | ||||||
|      * @return whether a font is set |  | ||||||
|      */ |  | ||||||
|     public boolean hasFont() |  | ||||||
|     { |  | ||||||
|         return ( font != null ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Returns whether this style is bold. |  | ||||||
|      * |  | ||||||
|      * @return whether the style is bold |  | ||||||
|      */ |  | ||||||
|     public boolean isBold() |  | ||||||
|     { |  | ||||||
|         return ( bold != null ) && bold.booleanValue(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Returns whether this style is bold. May return null. |  | ||||||
|      * |  | ||||||
|      * @return whether the style is bold, or null if not set |  | ||||||
|      */ |  | ||||||
|     public Boolean isBoldRaw() |  | ||||||
|     { |  | ||||||
|         return bold; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Returns whether this style is italic. May return null. |  | ||||||
|      * |  | ||||||
|      * @return whether the style is italic |  | ||||||
|      */ |  | ||||||
|     public boolean isItalic() |  | ||||||
|     { |  | ||||||
|         return ( italic != null ) && italic.booleanValue(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Returns whether this style is italic. May return null. |  | ||||||
|      * |  | ||||||
|      * @return whether the style is italic, or null if not set |  | ||||||
|      */ |  | ||||||
|     public Boolean isItalicRaw() |  | ||||||
|     { |  | ||||||
|         return italic; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Returns whether this style is underlined. |  | ||||||
|      * |  | ||||||
|      * @return whether the style is underlined |  | ||||||
|      */ |  | ||||||
|     public boolean isUnderlined() |  | ||||||
|     { |  | ||||||
|         return ( underlined != null ) && underlined.booleanValue(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Returns whether this style is underlined. May return null. |  | ||||||
|      * |  | ||||||
|      * @return whether the style is underlined, or null if not set |  | ||||||
|      */ |  | ||||||
|     public Boolean isUnderlinedRaw() |  | ||||||
|     { |  | ||||||
|         return underlined; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Returns whether this style is strikethrough |  | ||||||
|      * |  | ||||||
|      * @return whether the style is strikethrough |  | ||||||
|      */ |  | ||||||
|     public boolean isStrikethrough() |  | ||||||
|     { |  | ||||||
|         return ( strikethrough != null ) && strikethrough.booleanValue(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Returns whether this style is strikethrough. May return null. |  | ||||||
|      * |  | ||||||
|      * @return whether the style is strikethrough, or null if not set |  | ||||||
|      */ |  | ||||||
|     public Boolean isStrikethroughRaw() |  | ||||||
|     { |  | ||||||
|         return strikethrough; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Returns whether this style is obfuscated. |  | ||||||
|      * |  | ||||||
|      * @return whether the style is obfuscated |  | ||||||
|      */ |  | ||||||
|     public boolean isObfuscated() |  | ||||||
|     { |  | ||||||
|         return ( obfuscated != null ) && obfuscated.booleanValue(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Returns whether this style is obfuscated. May return null. |  | ||||||
|      * |  | ||||||
|      * @return whether the style is obfuscated, or null if not set |  | ||||||
|      */ |  | ||||||
|     public Boolean isObfuscatedRaw() |  | ||||||
|     { |  | ||||||
|         return obfuscated; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Returns whether this style has no formatting explicitly set. |  | ||||||
|      * |  | ||||||
|      * @return true if no value is set, false if at least one is set |  | ||||||
|      */ |  | ||||||
|     public boolean isEmpty() |  | ||||||
|     { |  | ||||||
|         return color == null && font == null && bold == null |  | ||||||
|                 && italic == null && underlined == null |  | ||||||
|                 && strikethrough == null && obfuscated == null; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public ComponentStyle clone() |  | ||||||
|     { |  | ||||||
|         return new ComponentStyle( color, font, bold, italic, underlined, strikethrough, obfuscated ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Get a new {@link ComponentStyleBuilder}. |  | ||||||
|      * |  | ||||||
|      * @return the builder |  | ||||||
|      */ |  | ||||||
|     public static ComponentStyleBuilder builder() |  | ||||||
|     { |  | ||||||
|         return new ComponentStyleBuilder(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Get a new {@link ComponentStyleBuilder} with values initialized to the |  | ||||||
|      * style values of the supplied {@link ComponentStyle}. |  | ||||||
|      * |  | ||||||
|      * @param other the component style whose values to copy into the builder |  | ||||||
|      * @return the builder |  | ||||||
|      */ |  | ||||||
|     public static ComponentStyleBuilder builder(ComponentStyle other) |  | ||||||
|     { |  | ||||||
|         return new ComponentStyleBuilder() |  | ||||||
|                 .color( other.color ) |  | ||||||
|                 .font( other.font ) |  | ||||||
|                 .bold( other.bold ) |  | ||||||
|                 .italic( other.italic ) |  | ||||||
|                 .underlined( other.underlined ) |  | ||||||
|                 .strikethrough( other.strikethrough ) |  | ||||||
|                 .obfuscated( other.obfuscated ); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,126 +0,0 @@ | |||||||
| package net.md_5.bungee.api.chat; |  | ||||||
|  |  | ||||||
| import net.md_5.bungee.api.ChatColor; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * <p> |  | ||||||
|  * ComponentStyleBuilder simplifies creating component styles by allowing the |  | ||||||
|  * use of a chainable builder. |  | ||||||
|  * </p> |  | ||||||
|  * <pre> |  | ||||||
|  * ComponentStyle style = ComponentStyle.builder() |  | ||||||
|  *     .color(ChatColor.RED) |  | ||||||
|  *     .font("custom:font") |  | ||||||
|  *     .bold(true).italic(true).create(); |  | ||||||
|  * |  | ||||||
|  * BaseComponent component = new ComponentBuilder("Hello world").style(style).create(); |  | ||||||
|  * // Or it can be used directly on a component |  | ||||||
|  * TextComponent text = new TextComponent("Hello world"); |  | ||||||
|  * text.applyStyle(style); |  | ||||||
|  * </pre> |  | ||||||
|  * |  | ||||||
|  * @see ComponentStyle#builder() |  | ||||||
|  * @see ComponentStyle#builder(ComponentStyle) |  | ||||||
|  */ |  | ||||||
| public final class ComponentStyleBuilder |  | ||||||
| { |  | ||||||
|  |  | ||||||
|     private ChatColor color; |  | ||||||
|     private String font; |  | ||||||
|     private Boolean bold, italic, underlined, strikethrough, obfuscated; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Set the style color. |  | ||||||
|      * |  | ||||||
|      * @param color the color to set, or null to use the default |  | ||||||
|      * @return this ComponentStyleBuilder for chaining |  | ||||||
|      */ |  | ||||||
|     public ComponentStyleBuilder color(ChatColor color) |  | ||||||
|     { |  | ||||||
|         this.color = color; |  | ||||||
|         return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Set the style font. |  | ||||||
|      * |  | ||||||
|      * @param font the font key to set, or null to use the default |  | ||||||
|      * @return this ComponentStyleBuilder for chaining |  | ||||||
|      */ |  | ||||||
|     public ComponentStyleBuilder font(String font) |  | ||||||
|     { |  | ||||||
|         this.font = font; |  | ||||||
|         return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Set the style's bold property. |  | ||||||
|      * |  | ||||||
|      * @param bold the bold value to set, or null to use the default |  | ||||||
|      * @return this ComponentStyleBuilder for chaining |  | ||||||
|      */ |  | ||||||
|     public ComponentStyleBuilder bold(Boolean bold) |  | ||||||
|     { |  | ||||||
|         this.bold = bold; |  | ||||||
|         return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Set the style's italic property. |  | ||||||
|      * |  | ||||||
|      * @param italic the italic value to set, or null to use the default |  | ||||||
|      * @return this ComponentStyleBuilder for chaining |  | ||||||
|      */ |  | ||||||
|     public ComponentStyleBuilder italic(Boolean italic) |  | ||||||
|     { |  | ||||||
|         this.italic = italic; |  | ||||||
|         return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Set the style's underlined property. |  | ||||||
|      * |  | ||||||
|      * @param underlined the underlined value to set, or null to use the default |  | ||||||
|      * @return this ComponentStyleBuilder for chaining |  | ||||||
|      */ |  | ||||||
|     public ComponentStyleBuilder underlined(Boolean underlined) |  | ||||||
|     { |  | ||||||
|         this.underlined = underlined; |  | ||||||
|         return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Set the style's strikethrough property. |  | ||||||
|      * |  | ||||||
|      * @param strikethrough the strikethrough value to set, or null to use the |  | ||||||
|      * default |  | ||||||
|      * @return this ComponentStyleBuilder for chaining |  | ||||||
|      */ |  | ||||||
|     public ComponentStyleBuilder strikethrough(Boolean strikethrough) |  | ||||||
|     { |  | ||||||
|         this.strikethrough = strikethrough; |  | ||||||
|         return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Set the style's obfuscated property. |  | ||||||
|      * |  | ||||||
|      * @param obfuscated the obfuscated value to set, or null to use the default |  | ||||||
|      * @return this ComponentStyleBuilder for chaining |  | ||||||
|      */ |  | ||||||
|     public ComponentStyleBuilder obfuscated(Boolean obfuscated) |  | ||||||
|     { |  | ||||||
|         this.obfuscated = obfuscated; |  | ||||||
|         return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Build the {@link ComponentStyle} using the values set in this builder. |  | ||||||
|      * |  | ||||||
|      * @return the created ComponentStyle |  | ||||||
|      */ |  | ||||||
|     public ComponentStyle build() |  | ||||||
|     { |  | ||||||
|         return new ComponentStyle( color, font, bold, italic, underlined, strikethrough, obfuscated ); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -33,13 +33,6 @@ public final class SelectorComponent extends BaseComponent | |||||||
|      */ |      */ | ||||||
|     private String selector; |     private String selector; | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * The separator of multiple selected entities. |  | ||||||
|      * <br> |  | ||||||
|      * The default is {@code {"color": "gray", "text": ", "}}. |  | ||||||
|      */ |  | ||||||
|     private BaseComponent separator; |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Creates a selector component from the original to clone it. |      * Creates a selector component from the original to clone it. | ||||||
|      * |      * | ||||||
| @@ -49,17 +42,6 @@ public final class SelectorComponent extends BaseComponent | |||||||
|     { |     { | ||||||
|         super( original ); |         super( original ); | ||||||
|         setSelector( original.getSelector() ); |         setSelector( original.getSelector() ); | ||||||
|         setSeparator( original.getSeparator() ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Creates a selector component from the selector |  | ||||||
|      * |  | ||||||
|      * @param selector the selector as a String |  | ||||||
|      */ |  | ||||||
|     public SelectorComponent(String selector) |  | ||||||
|     { |  | ||||||
|         setSelector( selector ); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|   | |||||||
| @@ -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<BaseComponent>(); | ||||||
|         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 ) | ||||||
|                 { |                 { | ||||||
| @@ -158,15 +111,15 @@ public final class TextComponent extends BaseComponent | |||||||
|                 } else if ( format == ChatColor.MAGIC ) |                 } else if ( format == ChatColor.MAGIC ) | ||||||
|                 { |                 { | ||||||
|                     component.setObfuscated( true ); |                     component.setObfuscated( true ); | ||||||
|                 } else |                 } else if ( format == ChatColor.RESET ) | ||||||
|                 { |  | ||||||
|                     if ( format == ChatColor.RESET ) |  | ||||||
|                 { |                 { | ||||||
|                     format = defaultColor; |                     format = defaultColor; | ||||||
|                     } |  | ||||||
|                     component = new TextComponent(); |                     component = new TextComponent(); | ||||||
|                     component.setColor( format ); |                     component.setColor( format ); | ||||||
|                     component.setReset( true ); |                 } else | ||||||
|  |                 { | ||||||
|  |                     component = new TextComponent(); | ||||||
|  |                     component.setColor( format ); | ||||||
|                 } |                 } | ||||||
|                 continue; |                 continue; | ||||||
|             } |             } | ||||||
| @@ -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[ components.size() ] ); | ||||||
|      * 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 ); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -297,6 +230,6 @@ public final class TextComponent extends BaseComponent | |||||||
|     @Override |     @Override | ||||||
|     public String toString() |     public String toString() | ||||||
|     { |     { | ||||||
|         return "TextComponent{text=" + text + ", " + super.toString() + '}'; |         return String.format( "TextComponent{text=%s, %s}", text, super.toString() ); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ import net.md_5.bungee.chat.TranslationRegistry; | |||||||
| public final class TranslatableComponent extends BaseComponent | public final class TranslatableComponent extends BaseComponent | ||||||
| { | { | ||||||
|  |  | ||||||
|     private static final Pattern FORMAT = Pattern.compile( "%(?:(\\d+)\\$)?([A-Za-z%]|$)" ); |     private final Pattern format = Pattern.compile( "%(?:(\\d+)\\$)?([A-Za-z%]|$)" ); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * The key into the Minecraft locale files to use for the translation. The |      * The key into the Minecraft locale files to use for the translation. The | ||||||
| @@ -30,10 +30,6 @@ public final class TranslatableComponent extends BaseComponent | |||||||
|      * The components to substitute into the translation |      * The components to substitute into the translation | ||||||
|      */ |      */ | ||||||
|     private List<BaseComponent> with; |     private List<BaseComponent> with; | ||||||
|     /** |  | ||||||
|      * The fallback, if the translation is not found |  | ||||||
|      */ |  | ||||||
|     private String fallback; |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Creates a translatable component from the original to clone it. |      * Creates a translatable component from the original to clone it. | ||||||
| @@ -44,11 +40,10 @@ public final class TranslatableComponent extends BaseComponent | |||||||
|     { |     { | ||||||
|         super( original ); |         super( original ); | ||||||
|         setTranslate( original.getTranslate() ); |         setTranslate( original.getTranslate() ); | ||||||
|         setFallback( original.getFallback() ); |  | ||||||
|  |  | ||||||
|         if ( original.getWith() != null ) |         if ( original.getWith() != null ) | ||||||
|         { |         { | ||||||
|             List<BaseComponent> temp = new ArrayList<>(); |             List<BaseComponent> temp = new ArrayList<BaseComponent>(); | ||||||
|             for ( BaseComponent baseComponent : original.getWith() ) |             for ( BaseComponent baseComponent : original.getWith() ) | ||||||
|             { |             { | ||||||
|                 temp.add( baseComponent.duplicate() ); |                 temp.add( baseComponent.duplicate() ); | ||||||
| @@ -87,21 +82,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. | ||||||
|      * |      * | ||||||
| @@ -173,12 +153,7 @@ public final class TranslatableComponent extends BaseComponent | |||||||
|     { |     { | ||||||
|         String trans = TranslationRegistry.INSTANCE.translate( translate ); |         String trans = TranslationRegistry.INSTANCE.translate( translate ); | ||||||
|  |  | ||||||
|         if ( trans.equals( translate ) && fallback != null ) |         Matcher matcher = format.matcher( trans ); | ||||||
|         { |  | ||||||
|             trans = fallback; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         Matcher matcher = FORMAT.matcher( trans ); |  | ||||||
|         int position = 0; |         int position = 0; | ||||||
|         int i = 0; |         int i = 0; | ||||||
|         while ( matcher.find( position ) ) |         while ( matcher.find( position ) ) | ||||||
|   | |||||||
| @@ -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 ); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -8,7 +8,6 @@ import com.google.gson.JsonParseException; | |||||||
| import com.google.gson.JsonSerializationContext; | import com.google.gson.JsonSerializationContext; | ||||||
| import com.google.gson.JsonSerializer; | import com.google.gson.JsonSerializer; | ||||||
| import java.lang.reflect.Type; | import java.lang.reflect.Type; | ||||||
| import java.util.UUID; |  | ||||||
| import net.md_5.bungee.api.chat.BaseComponent; | import net.md_5.bungee.api.chat.BaseComponent; | ||||||
|  |  | ||||||
| public class EntitySerializer implements JsonSerializer<Entity>, JsonDeserializer<Entity> | public class EntitySerializer implements JsonSerializer<Entity>, JsonDeserializer<Entity> | ||||||
| @@ -19,19 +18,9 @@ public class EntitySerializer implements JsonSerializer<Entity>, JsonDeserialize | |||||||
|     { |     { | ||||||
|         JsonObject value = element.getAsJsonObject(); |         JsonObject value = element.getAsJsonObject(); | ||||||
|  |  | ||||||
|         String idString; |  | ||||||
|         JsonElement id = value.get( "id" ); |  | ||||||
|         if ( id.isJsonArray() ) |  | ||||||
|         { |  | ||||||
|             idString = parseUUID( context.deserialize( id, int[].class ) ).toString(); |  | ||||||
|         } else |  | ||||||
|         { |  | ||||||
|             idString = id.getAsString(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return new Entity( |         return new Entity( | ||||||
|                 ( value.has( "type" ) ) ? value.get( "type" ).getAsString() : null, |                 ( value.has( "type" ) ) ? value.get( "type" ).getAsString() : null, | ||||||
|                 idString, |                 value.get( "id" ).getAsString(), | ||||||
|                 ( value.has( "name" ) ) ? context.deserialize( value.get( "name" ), BaseComponent.class ) : null |                 ( value.has( "name" ) ) ? context.deserialize( value.get( "name" ), BaseComponent.class ) : null | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
| @@ -48,9 +37,4 @@ public class EntitySerializer implements JsonSerializer<Entity>, JsonDeserialize | |||||||
|         } |         } | ||||||
|         return object; |         return object; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private static UUID parseUUID(int[] array) |  | ||||||
|     { |  | ||||||
|         return new UUID( (long) array[0] << 32 | (long) array[1] & 0XFFFFFFFFL, (long) array[2] << 32 | (long) array[3] & 0XFFFFFFFFL ); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -23,15 +23,6 @@ public class Text extends Content | |||||||
|         this.value = value; |         this.value = value; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public Text(BaseComponent value) |  | ||||||
|     { |  | ||||||
|         // For legacy serialization reasons, this has to be an array of components |  | ||||||
|         this( new BaseComponent[] |  | ||||||
|         { |  | ||||||
|             value |  | ||||||
|         } ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public Text(String value) |     public Text(String value) | ||||||
|     { |     { | ||||||
|         this.value = value; |         this.value = value; | ||||||
|   | |||||||
| @@ -4,15 +4,16 @@ import com.google.common.base.Preconditions; | |||||||
| import com.google.gson.JsonDeserializationContext; | 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.JsonSerializationContext; | import com.google.gson.JsonSerializationContext; | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.Arrays; | import java.util.Arrays; | ||||||
| import java.util.Collections; | import java.util.Collections; | ||||||
| import java.util.IdentityHashMap; | import java.util.IdentityHashMap; | ||||||
| import java.util.Locale; | import java.util.Locale; | ||||||
|  | import net.md_5.bungee.api.ChatColor; | ||||||
| import net.md_5.bungee.api.chat.BaseComponent; | import net.md_5.bungee.api.chat.BaseComponent; | ||||||
| import net.md_5.bungee.api.chat.ClickEvent; | import net.md_5.bungee.api.chat.ClickEvent; | ||||||
| import net.md_5.bungee.api.chat.ComponentStyle; |  | ||||||
| import net.md_5.bungee.api.chat.HoverEvent; | import net.md_5.bungee.api.chat.HoverEvent; | ||||||
| import net.md_5.bungee.api.chat.hover.content.Content; | import net.md_5.bungee.api.chat.hover.content.Content; | ||||||
|  |  | ||||||
| @@ -21,50 +22,82 @@ public class BaseComponentSerializer | |||||||
|  |  | ||||||
|     protected void deserialize(JsonObject object, BaseComponent component, JsonDeserializationContext context) |     protected void deserialize(JsonObject object, BaseComponent component, JsonDeserializationContext context) | ||||||
|     { |     { | ||||||
|         component.applyStyle( context.deserialize( object, ComponentStyle.class ) ); |         if ( object.has( "color" ) ) | ||||||
|  |  | ||||||
|         JsonElement insertion = object.get( "insertion" ); |  | ||||||
|         if ( insertion != null ) |  | ||||||
|         { |         { | ||||||
|             component.setInsertion( insertion.getAsString() ); |             component.setColor( ChatColor.of( object.get( "color" ).getAsString() ) ); | ||||||
|  |         } | ||||||
|  |         if ( object.has( "font" ) ) | ||||||
|  |         { | ||||||
|  |             component.setFont( object.get( "font" ).getAsString() ); | ||||||
|  |         } | ||||||
|  |         if ( object.has( "bold" ) ) | ||||||
|  |         { | ||||||
|  |             component.setBold( object.get( "bold" ).getAsBoolean() ); | ||||||
|  |         } | ||||||
|  |         if ( object.has( "italic" ) ) | ||||||
|  |         { | ||||||
|  |             component.setItalic( object.get( "italic" ).getAsBoolean() ); | ||||||
|  |         } | ||||||
|  |         if ( object.has( "underlined" ) ) | ||||||
|  |         { | ||||||
|  |             component.setUnderlined( object.get( "underlined" ).getAsBoolean() ); | ||||||
|  |         } | ||||||
|  |         if ( object.has( "strikethrough" ) ) | ||||||
|  |         { | ||||||
|  |             component.setStrikethrough( object.get( "strikethrough" ).getAsBoolean() ); | ||||||
|  |         } | ||||||
|  |         if ( object.has( "obfuscated" ) ) | ||||||
|  |         { | ||||||
|  |             component.setObfuscated( object.get( "obfuscated" ).getAsBoolean() ); | ||||||
|  |         } | ||||||
|  |         if ( object.has( "insertion" ) ) | ||||||
|  |         { | ||||||
|  |             component.setInsertion( object.get( "insertion" ).getAsString() ); | ||||||
|  |         } | ||||||
|  |         if ( object.has( "extra" ) ) | ||||||
|  |         { | ||||||
|  |             component.setExtra( Arrays.asList( context.<BaseComponent[]>deserialize( object.get( "extra" ), BaseComponent[].class ) ) ); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         //Events |         //Events | ||||||
|         JsonObject clickEvent = object.getAsJsonObject( "clickEvent" ); |         if ( object.has( "clickEvent" ) ) | ||||||
|         if ( clickEvent != null ) |  | ||||||
|         { |         { | ||||||
|  |             JsonObject event = object.getAsJsonObject( "clickEvent" ); | ||||||
|             component.setClickEvent( new ClickEvent( |             component.setClickEvent( new ClickEvent( | ||||||
|                     ClickEvent.Action.valueOf( clickEvent.get( "action" ).getAsString().toUpperCase( Locale.ROOT ) ), |                     ClickEvent.Action.valueOf( event.get( "action" ).getAsString().toUpperCase( Locale.ROOT ) ), | ||||||
|                     ( clickEvent.has( "value" ) ) ? clickEvent.get( "value" ).getAsString() : "" ) ); |                     ( event.has( "value" ) ) ? event.get( "value" ).getAsString() : "" ) ); | ||||||
|         } |         } | ||||||
|         JsonObject hoverEventJson = object.getAsJsonObject( "hoverEvent" ); |         if ( object.has( "hoverEvent" ) ) | ||||||
|         if ( hoverEventJson != null ) |  | ||||||
|         { |         { | ||||||
|  |             JsonObject event = object.getAsJsonObject( "hoverEvent" ); | ||||||
|             HoverEvent hoverEvent = null; |             HoverEvent hoverEvent = null; | ||||||
|             HoverEvent.Action action = HoverEvent.Action.valueOf( hoverEventJson.get( "action" ).getAsString().toUpperCase( Locale.ROOT ) ); |             HoverEvent.Action action = HoverEvent.Action.valueOf( event.get( "action" ).getAsString().toUpperCase( Locale.ROOT ) ); | ||||||
|  |  | ||||||
|             JsonElement value = hoverEventJson.get( "value" ); |             for ( String type : Arrays.asList( "value", "contents" ) ) | ||||||
|             if ( value != null ) |             { | ||||||
|  |                 if ( !event.has( type ) ) | ||||||
|  |                 { | ||||||
|  |                     continue; | ||||||
|  |                 } | ||||||
|  |                 JsonElement contents = event.get( type ); | ||||||
|  |                 try | ||||||
|                 { |                 { | ||||||
|  |  | ||||||
|                     // Plugins previously had support to pass BaseComponent[] into any action. |                     // Plugins previously had support to pass BaseComponent[] into any action. | ||||||
|                     // If the GSON is possible to be parsed as BaseComponent, attempt to parse as so. |                     // If the GSON is possible to be parsed as BaseComponent, attempt to parse as so. | ||||||
|                     BaseComponent[] components; |                     BaseComponent[] components; | ||||||
|                 if ( value.isJsonArray() ) |                     if ( contents.isJsonArray() ) | ||||||
|                     { |                     { | ||||||
|                     components = context.deserialize( value, BaseComponent[].class ); |                         components = context.deserialize( contents, BaseComponent[].class ); | ||||||
|                     } else |                     } else | ||||||
|                     { |                     { | ||||||
|                         components = new BaseComponent[] |                         components = new BaseComponent[] | ||||||
|                         { |                         { | ||||||
|                         context.deserialize( value, BaseComponent.class ) |                                 context.deserialize( contents, BaseComponent.class ) | ||||||
|                         }; |                         }; | ||||||
|                     } |                     } | ||||||
|                     hoverEvent = new HoverEvent( action, components ); |                     hoverEvent = new HoverEvent( action, components ); | ||||||
|             } else |                 } catch ( JsonParseException ex ) | ||||||
|             { |  | ||||||
|                 JsonElement contents = hoverEventJson.get( "contents" ); |  | ||||||
|                 if ( contents != null ) |  | ||||||
|                 { |                 { | ||||||
|                     Content[] list; |                     Content[] list; | ||||||
|                     if ( contents.isJsonArray() ) |                     if ( contents.isJsonArray() ) | ||||||
| @@ -79,19 +112,15 @@ public class BaseComponentSerializer | |||||||
|                     } |                     } | ||||||
|                     hoverEvent = new HoverEvent( action, new ArrayList<>( Arrays.asList( list ) ) ); |                     hoverEvent = new HoverEvent( action, new ArrayList<>( Arrays.asList( list ) ) ); | ||||||
|                 } |                 } | ||||||
|             } |  | ||||||
|  |  | ||||||
|  |                 // stop the loop as soon as either one is found | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|             if ( hoverEvent != null ) |             if ( hoverEvent != null ) | ||||||
|             { |             { | ||||||
|                 component.setHoverEvent( hoverEvent ); |                 component.setHoverEvent( hoverEvent ); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         JsonElement extra = object.get( "extra" ); |  | ||||||
|         if ( extra != null ) |  | ||||||
|         { |  | ||||||
|             component.setExtra( Arrays.asList( context.deserialize( extra, BaseComponent[].class ) ) ); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     protected void serialize(JsonObject object, BaseComponent component, JsonSerializationContext context) |     protected void serialize(JsonObject object, BaseComponent component, JsonSerializationContext context) | ||||||
| @@ -106,14 +135,44 @@ public class BaseComponentSerializer | |||||||
|         { |         { | ||||||
|             Preconditions.checkArgument( !ComponentSerializer.serializedComponents.get().contains( component ), "Component loop" ); |             Preconditions.checkArgument( !ComponentSerializer.serializedComponents.get().contains( component ), "Component loop" ); | ||||||
|             ComponentSerializer.serializedComponents.get().add( component ); |             ComponentSerializer.serializedComponents.get().add( component ); | ||||||
|  |             if ( component.getColorRaw() != null ) | ||||||
|             ComponentStyleSerializer.serializeTo( component.getStyle(), object ); |             { | ||||||
|  |                 object.addProperty( "color", component.getColorRaw().getName() ); | ||||||
|  |             } | ||||||
|  |             if ( component.getFontRaw() != null ) | ||||||
|  |             { | ||||||
|  |                 object.addProperty( "font", component.getFontRaw() ); | ||||||
|  |             } | ||||||
|  |             if ( component.isBoldRaw() != null ) | ||||||
|  |             { | ||||||
|  |                 object.addProperty( "bold", component.isBoldRaw() ); | ||||||
|  |             } | ||||||
|  |             if ( component.isItalicRaw() != null ) | ||||||
|  |             { | ||||||
|  |                 object.addProperty( "italic", component.isItalicRaw() ); | ||||||
|  |             } | ||||||
|  |             if ( component.isUnderlinedRaw() != null ) | ||||||
|  |             { | ||||||
|  |                 object.addProperty( "underlined", component.isUnderlinedRaw() ); | ||||||
|  |             } | ||||||
|  |             if ( component.isStrikethroughRaw() != null ) | ||||||
|  |             { | ||||||
|  |                 object.addProperty( "strikethrough", component.isStrikethroughRaw() ); | ||||||
|  |             } | ||||||
|  |             if ( component.isObfuscatedRaw() != null ) | ||||||
|  |             { | ||||||
|  |                 object.addProperty( "obfuscated", component.isObfuscatedRaw() ); | ||||||
|  |             } | ||||||
|             if ( component.getInsertion() != null ) |             if ( component.getInsertion() != null ) | ||||||
|             { |             { | ||||||
|                 object.addProperty( "insertion", component.getInsertion() ); |                 object.addProperty( "insertion", component.getInsertion() ); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  |             if ( component.getExtra() != null ) | ||||||
|  |             { | ||||||
|  |                 object.add( "extra", context.serialize( component.getExtra() ) ); | ||||||
|  |             } | ||||||
|  |  | ||||||
|             //Events |             //Events | ||||||
|             if ( component.getClickEvent() != null ) |             if ( component.getClickEvent() != null ) | ||||||
|             { |             { | ||||||
| @@ -136,11 +195,6 @@ public class BaseComponentSerializer | |||||||
|                 } |                 } | ||||||
|                 object.add( "hoverEvent", hoverEvent ); |                 object.add( "hoverEvent", hoverEvent ); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if ( component.getExtra() != null ) |  | ||||||
|             { |  | ||||||
|                 object.add( "extra", context.serialize( component.getExtra() ) ); |  | ||||||
|             } |  | ||||||
|         } finally |         } finally | ||||||
|         { |         { | ||||||
|             ComponentSerializer.serializedComponents.get().remove( component ); |             ComponentSerializer.serializedComponents.get().remove( component ); | ||||||
|   | |||||||
| @@ -2,18 +2,15 @@ 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; | ||||||
| import net.md_5.bungee.api.chat.ComponentStyle; |  | ||||||
| import net.md_5.bungee.api.chat.ItemTag; | import net.md_5.bungee.api.chat.ItemTag; | ||||||
| import net.md_5.bungee.api.chat.KeybindComponent; | import net.md_5.bungee.api.chat.KeybindComponent; | ||||||
| import net.md_5.bungee.api.chat.ScoreComponent; | import net.md_5.bungee.api.chat.ScoreComponent; | ||||||
| @@ -30,6 +27,7 @@ import net.md_5.bungee.api.chat.hover.content.TextSerializer; | |||||||
| public class ComponentSerializer implements JsonDeserializer<BaseComponent> | public class ComponentSerializer implements JsonDeserializer<BaseComponent> | ||||||
| { | { | ||||||
|  |  | ||||||
|  |     private static final JsonParser JSON_PARSER = new JsonParser(); | ||||||
|     private static final Gson gson = new GsonBuilder(). |     private static final Gson gson = new GsonBuilder(). | ||||||
|             registerTypeAdapter( BaseComponent.class, new ComponentSerializer() ). |             registerTypeAdapter( BaseComponent.class, new ComponentSerializer() ). | ||||||
|             registerTypeAdapter( TextComponent.class, new TextComponentSerializer() ). |             registerTypeAdapter( TextComponent.class, new TextComponentSerializer() ). | ||||||
| @@ -37,7 +35,6 @@ public class ComponentSerializer implements JsonDeserializer<BaseComponent> | |||||||
|             registerTypeAdapter( KeybindComponent.class, new KeybindComponentSerializer() ). |             registerTypeAdapter( KeybindComponent.class, new KeybindComponentSerializer() ). | ||||||
|             registerTypeAdapter( ScoreComponent.class, new ScoreComponentSerializer() ). |             registerTypeAdapter( ScoreComponent.class, new ScoreComponentSerializer() ). | ||||||
|             registerTypeAdapter( SelectorComponent.class, new SelectorComponentSerializer() ). |             registerTypeAdapter( SelectorComponent.class, new SelectorComponentSerializer() ). | ||||||
|             registerTypeAdapter( ComponentStyle.class, new ComponentStyleSerializer() ). |  | ||||||
|             registerTypeAdapter( Entity.class, new EntitySerializer() ). |             registerTypeAdapter( Entity.class, new EntitySerializer() ). | ||||||
|             registerTypeAdapter( Text.class, new TextSerializer() ). |             registerTypeAdapter( Text.class, new TextSerializer() ). | ||||||
|             registerTypeAdapter( Item.class, new ItemSerializer() ). |             registerTypeAdapter( Item.class, new ItemSerializer() ). | ||||||
| @@ -46,26 +43,9 @@ public class ComponentSerializer implements JsonDeserializer<BaseComponent> | |||||||
|  |  | ||||||
|     public static final ThreadLocal<Set<BaseComponent>> serializedComponents = new ThreadLocal<Set<BaseComponent>>(); |     public static final ThreadLocal<Set<BaseComponent>> serializedComponents = new ThreadLocal<Set<BaseComponent>>(); | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 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 |  | ||||||
|      * object. If the input is an array, each component will be parsed |  | ||||||
|      * individually and returned in the order that they were parsed. If the |  | ||||||
|      * input is a single component object, a single-valued array with the |  | ||||||
|      * component will be returned. |  | ||||||
|      * <p> |  | ||||||
|      * <strong>NOTE:</strong> {@link #deserialize(String)} is preferred as it |  | ||||||
|      * will parse only one component as opposed to an array of components which |  | ||||||
|      * is non- standard behavior. This method is still appropriate for parsing |  | ||||||
|      * multiple components at once, although such use case is rarely (if at all) |  | ||||||
|      * exhibited in vanilla Minecraft. |  | ||||||
|      * |  | ||||||
|      * @param json the component json to parse |  | ||||||
|      * @return an array of all parsed components |  | ||||||
|      */ |  | ||||||
|     public static BaseComponent[] parse(String json) |     public static BaseComponent[] parse(String json) | ||||||
|     { |     { | ||||||
|         JsonElement jsonElement = JsonParser.parseString( json ); |         JsonElement jsonElement = JSON_PARSER.parse( json ); | ||||||
|  |  | ||||||
|         if ( jsonElement.isJsonArray() ) |         if ( jsonElement.isJsonArray() ) | ||||||
|         { |         { | ||||||
| @@ -79,85 +59,6 @@ public class ComponentSerializer implements JsonDeserializer<BaseComponent> | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Deserialize a JSON-compliant String as a single component. |  | ||||||
|      * |  | ||||||
|      * @param json the component json to parse |  | ||||||
|      * @return the deserialized component |  | ||||||
|      * @throws IllegalArgumentException if anything other than a valid JSON |  | ||||||
|      * component string is passed as input |  | ||||||
|      */ |  | ||||||
|     public static BaseComponent deserialize(String json) |  | ||||||
|     { |  | ||||||
|         JsonElement jsonElement = JsonParser.parseString( json ); |  | ||||||
|  |  | ||||||
|         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 ) |  | ||||||
|         { |  | ||||||
|             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 ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Deserialize a JSON-compliant String as a component style. |  | ||||||
|      * |  | ||||||
|      * @param json the component style json to parse |  | ||||||
|      * @return the deserialized component style |  | ||||||
|      * @throws IllegalArgumentException if anything other than a valid JSON |  | ||||||
|      * component style string is passed as input |  | ||||||
|      */ |  | ||||||
|     public static ComponentStyle deserializeStyle(String json) |  | ||||||
|     { |  | ||||||
|         JsonElement jsonElement = JsonParser.parseString( json ); |  | ||||||
|  |  | ||||||
|         return deserializeStyle( jsonElement ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Deserialize a JSON element as a component style. |  | ||||||
|      * |  | ||||||
|      * @param jsonElement the component style json to parse |  | ||||||
|      * @return the deserialized component style |  | ||||||
|      * @throws IllegalArgumentException if anything other than a valid JSON |  | ||||||
|      * component style is passed as input |  | ||||||
|      */ |  | ||||||
|     public static ComponentStyle deserializeStyle(JsonElement jsonElement) |  | ||||||
|     { |  | ||||||
|         return gson.fromJson( jsonElement, ComponentStyle.class ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public static JsonElement toJson(BaseComponent component) |  | ||||||
|     { |  | ||||||
|         return gson.toJsonTree( component ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public static JsonElement toJson(ComponentStyle style) |  | ||||||
|     { |  | ||||||
|         return gson.toJsonTree( style ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public static String toString(Object object) |     public static String toString(Object object) | ||||||
|     { |     { | ||||||
|         return gson.toJson( object ); |         return gson.toJson( object ); | ||||||
| @@ -179,11 +80,6 @@ public class ComponentSerializer implements JsonDeserializer<BaseComponent> | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static String toString(ComponentStyle style) |  | ||||||
|     { |  | ||||||
|         return gson.toJson( style ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public BaseComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException |     public BaseComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException | ||||||
|     { |     { | ||||||
|   | |||||||
| @@ -1,120 +0,0 @@ | |||||||
| package net.md_5.bungee.chat; |  | ||||||
|  |  | ||||||
| import com.google.gson.JsonDeserializationContext; |  | ||||||
| import com.google.gson.JsonDeserializer; |  | ||||||
| import com.google.gson.JsonElement; |  | ||||||
| import com.google.gson.JsonObject; |  | ||||||
| import com.google.gson.JsonParseException; |  | ||||||
| import com.google.gson.JsonPrimitive; |  | ||||||
| import com.google.gson.JsonSerializationContext; |  | ||||||
| import com.google.gson.JsonSerializer; |  | ||||||
| import java.lang.reflect.Type; |  | ||||||
| import java.util.Map; |  | ||||||
| import net.md_5.bungee.api.ChatColor; |  | ||||||
| import net.md_5.bungee.api.chat.ComponentStyle; |  | ||||||
| import net.md_5.bungee.api.chat.ComponentStyleBuilder; |  | ||||||
|  |  | ||||||
| public class ComponentStyleSerializer implements JsonSerializer<ComponentStyle>, JsonDeserializer<ComponentStyle> |  | ||||||
| { |  | ||||||
|  |  | ||||||
|     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; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     static void serializeTo(ComponentStyle style, JsonObject object) |  | ||||||
|     { |  | ||||||
|         if ( style.isBoldRaw() != null ) |  | ||||||
|         { |  | ||||||
|             object.addProperty( "bold", style.isBoldRaw() ); |  | ||||||
|         } |  | ||||||
|         if ( style.isItalicRaw() != null ) |  | ||||||
|         { |  | ||||||
|             object.addProperty( "italic", style.isItalicRaw() ); |  | ||||||
|         } |  | ||||||
|         if ( style.isUnderlinedRaw() != null ) |  | ||||||
|         { |  | ||||||
|             object.addProperty( "underlined", style.isUnderlinedRaw() ); |  | ||||||
|         } |  | ||||||
|         if ( style.isStrikethroughRaw() != null ) |  | ||||||
|         { |  | ||||||
|             object.addProperty( "strikethrough", style.isStrikethroughRaw() ); |  | ||||||
|         } |  | ||||||
|         if ( style.isObfuscatedRaw() != null ) |  | ||||||
|         { |  | ||||||
|             object.addProperty( "obfuscated", style.isObfuscatedRaw() ); |  | ||||||
|         } |  | ||||||
|         if ( style.hasColor() && style.getColor().getColor() != null ) |  | ||||||
|         { |  | ||||||
|             object.addProperty( "color", style.getColor().getName() ); |  | ||||||
|         } |  | ||||||
|         if ( style.hasFont() ) |  | ||||||
|         { |  | ||||||
|             object.addProperty( "font", style.getFont() ); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public ComponentStyle deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException |  | ||||||
|     { |  | ||||||
|         ComponentStyleBuilder builder = ComponentStyle.builder(); |  | ||||||
|         JsonObject object = json.getAsJsonObject(); |  | ||||||
|         for ( Map.Entry<String, JsonElement> entry : object.entrySet() ) |  | ||||||
|         { |  | ||||||
|             String name = entry.getKey(); |  | ||||||
|             JsonElement value = entry.getValue(); |  | ||||||
|             switch ( name ) |  | ||||||
|             { |  | ||||||
|                 case "bold": |  | ||||||
|                     builder.bold( getAsBoolean( value ) ); |  | ||||||
|                     break; |  | ||||||
|                 case "italic": |  | ||||||
|                     builder.italic( getAsBoolean( value ) ); |  | ||||||
|                     break; |  | ||||||
|                 case "underlined": |  | ||||||
|                     builder.underlined( getAsBoolean( value ) ); |  | ||||||
|                     break; |  | ||||||
|                 case "strikethrough": |  | ||||||
|                     builder.strikethrough( getAsBoolean( value ) ); |  | ||||||
|                     break; |  | ||||||
|                 case "obfuscated": |  | ||||||
|                     builder.obfuscated( getAsBoolean( value ) ); |  | ||||||
|                     break; |  | ||||||
|                 case "color": |  | ||||||
|                     builder.color( ChatColor.of( value.getAsString() ) ); |  | ||||||
|                     break; |  | ||||||
|                 case "font": |  | ||||||
|                     builder.font( value.getAsString() ); |  | ||||||
|                     break; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return builder.build(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public JsonElement serialize(ComponentStyle src, Type typeOfSrc, JsonSerializationContext context) |  | ||||||
|     { |  | ||||||
|         JsonObject object = new JsonObject(); |  | ||||||
|         serializeTo( src, object ); |  | ||||||
|         return object; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -17,14 +17,13 @@ public class KeybindComponentSerializer extends BaseComponentSerializer implemen | |||||||
|     public KeybindComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException |     public KeybindComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException | ||||||
|     { |     { | ||||||
|         JsonObject object = json.getAsJsonObject(); |         JsonObject object = json.getAsJsonObject(); | ||||||
|         JsonElement keybind = object.get( "keybind" ); |         if ( !object.has( "keybind" ) ) | ||||||
|         if ( keybind == null ) |  | ||||||
|         { |         { | ||||||
|             throw new JsonParseException( "Could not parse JSON: missing 'keybind' property" ); |             throw new JsonParseException( "Could not parse JSON: missing 'keybind' property" ); | ||||||
|         } |         } | ||||||
|         KeybindComponent component = new KeybindComponent(); |         KeybindComponent component = new KeybindComponent(); | ||||||
|         deserialize( object, component, context ); |         deserialize( object, component, context ); | ||||||
|         component.setKeybind( keybind.getAsString() ); |         component.setKeybind( object.get( "keybind" ).getAsString() ); | ||||||
|         return component; |         return component; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -17,29 +17,22 @@ public class ScoreComponentSerializer extends BaseComponentSerializer implements | |||||||
|     public ScoreComponent deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException |     public ScoreComponent deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException | ||||||
|     { |     { | ||||||
|         JsonObject json = element.getAsJsonObject(); |         JsonObject json = element.getAsJsonObject(); | ||||||
|         JsonObject score = json.getAsJsonObject( "score" ); |         if ( !json.has( "score" ) ) | ||||||
|         if ( score == null ) |  | ||||||
|         { |         { | ||||||
|             throw new JsonParseException( "Could not parse JSON: missing 'score' property" ); |             throw new JsonParseException( "Could not parse JSON: missing 'score' property" ); | ||||||
|         } |         } | ||||||
|         JsonElement nameJson = score.get( "name" ); |         JsonObject score = json.get( "score" ).getAsJsonObject(); | ||||||
|         if ( nameJson == null ) |         if ( !score.has( "name" ) || !score.has( "objective" ) ) | ||||||
|         { |  | ||||||
|             throw new JsonParseException( "A score component needs at least a name (and an objective)" ); |  | ||||||
|         } |  | ||||||
|         JsonElement objectiveJson = score.get( "objective" ); |  | ||||||
|         if ( objectiveJson == null ) |  | ||||||
|         { |         { | ||||||
|             throw new JsonParseException( "A score component needs at least a name and an objective" ); |             throw new JsonParseException( "A score component needs at least a name and an objective" ); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         String name = nameJson.getAsString(); |         String name = score.get( "name" ).getAsString(); | ||||||
|         String objective = objectiveJson.getAsString(); |         String objective = score.get( "objective" ).getAsString(); | ||||||
|         ScoreComponent component = new ScoreComponent( name, objective ); |         ScoreComponent component = new ScoreComponent( name, objective ); | ||||||
|         JsonElement value = score.get( "value" ); |         if ( score.has( "value" ) && !score.get( "value" ).getAsString().isEmpty() ) | ||||||
|         if ( value != null && !value.getAsString().isEmpty() ) |  | ||||||
|         { |         { | ||||||
|             component.setValue( value.getAsString() ); |             component.setValue( score.get( "value" ).getAsString() ); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         deserialize( json, component, context ); |         deserialize( json, component, context ); | ||||||
|   | |||||||
| @@ -17,19 +17,11 @@ public class SelectorComponentSerializer extends BaseComponentSerializer impleme | |||||||
|     public SelectorComponent deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException |     public SelectorComponent deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException | ||||||
|     { |     { | ||||||
|         JsonObject object = element.getAsJsonObject(); |         JsonObject object = element.getAsJsonObject(); | ||||||
|         JsonElement selector = object.get( "selector" ); |         if ( !object.has( "selector" ) ) | ||||||
|         if ( selector == null ) |  | ||||||
|         { |         { | ||||||
|             throw new JsonParseException( "Could not parse JSON: missing 'selector' property" ); |             throw new JsonParseException( "Could not parse JSON: missing 'selector' property" ); | ||||||
|         } |         } | ||||||
|         SelectorComponent component = new SelectorComponent( selector.getAsString() ); |         SelectorComponent component = new SelectorComponent( object.get( "selector" ).getAsString() ); | ||||||
|  |  | ||||||
|         JsonElement separator = object.get( "separator" ); |  | ||||||
|         if ( separator != null ) |  | ||||||
|         { |  | ||||||
|             component.setSeparator( ComponentSerializer.deserialize( separator.getAsString() ) ); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         deserialize( object, component, context ); |         deserialize( object, component, context ); | ||||||
|         return component; |         return component; | ||||||
|     } |     } | ||||||
| @@ -40,11 +32,6 @@ public class SelectorComponentSerializer extends BaseComponentSerializer impleme | |||||||
|         JsonObject object = new JsonObject(); |         JsonObject object = new JsonObject(); | ||||||
|         serialize( object, component, context ); |         serialize( object, component, context ); | ||||||
|         object.addProperty( "selector", component.getSelector() ); |         object.addProperty( "selector", component.getSelector() ); | ||||||
|  |  | ||||||
|         if ( component.getSeparator() != null ) |  | ||||||
|         { |  | ||||||
|             object.addProperty( "separator", ComponentSerializer.toString( component.getSeparator() ) ); |  | ||||||
|         } |  | ||||||
|         return object; |         return object; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -8,6 +8,8 @@ import com.google.gson.JsonParseException; | |||||||
| import com.google.gson.JsonSerializationContext; | import com.google.gson.JsonSerializationContext; | ||||||
| import com.google.gson.JsonSerializer; | import com.google.gson.JsonSerializer; | ||||||
| import java.lang.reflect.Type; | import java.lang.reflect.Type; | ||||||
|  | import java.util.List; | ||||||
|  | import net.md_5.bungee.api.chat.BaseComponent; | ||||||
| import net.md_5.bungee.api.chat.TextComponent; | import net.md_5.bungee.api.chat.TextComponent; | ||||||
|  |  | ||||||
| public class TextComponentSerializer extends BaseComponentSerializer implements JsonSerializer<TextComponent>, JsonDeserializer<TextComponent> | public class TextComponentSerializer extends BaseComponentSerializer implements JsonSerializer<TextComponent>, JsonDeserializer<TextComponent> | ||||||
| @@ -18,11 +20,11 @@ public class TextComponentSerializer extends BaseComponentSerializer implements | |||||||
|     { |     { | ||||||
|         TextComponent component = new TextComponent(); |         TextComponent component = new TextComponent(); | ||||||
|         JsonObject object = json.getAsJsonObject(); |         JsonObject object = json.getAsJsonObject(); | ||||||
|         JsonElement text = object.get( "text" ); |         if ( !object.has( "text" ) ) | ||||||
|         if ( text != null ) |  | ||||||
|         { |         { | ||||||
|             component.setText( 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; | ||||||
|     } |     } | ||||||
| @@ -30,9 +32,13 @@ public class TextComponentSerializer extends BaseComponentSerializer implements | |||||||
|     @Override |     @Override | ||||||
|     public JsonElement serialize(TextComponent src, Type typeOfSrc, JsonSerializationContext context) |     public JsonElement serialize(TextComponent src, Type typeOfSrc, JsonSerializationContext context) | ||||||
|     { |     { | ||||||
|  |         List<BaseComponent> extra = src.getExtra(); | ||||||
|         JsonObject object = new JsonObject(); |         JsonObject object = new JsonObject(); | ||||||
|         serialize( object, src, context ); |  | ||||||
|         object.addProperty( "text", src.getText() ); |         object.addProperty( "text", src.getText() ); | ||||||
|  |         if ( src.hasFormatting() || ( extra != null && !extra.isEmpty() ) ) | ||||||
|  |         { | ||||||
|  |             serialize( object, src, context ); | ||||||
|  |         } | ||||||
|         return object; |         return object; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -21,21 +21,14 @@ public class TranslatableComponentSerializer extends BaseComponentSerializer imp | |||||||
|         TranslatableComponent component = new TranslatableComponent(); |         TranslatableComponent component = new TranslatableComponent(); | ||||||
|         JsonObject object = json.getAsJsonObject(); |         JsonObject object = json.getAsJsonObject(); | ||||||
|         deserialize( object, component, context ); |         deserialize( object, component, context ); | ||||||
|         JsonElement translate = object.get( "translate" ); |         if ( !object.has( "translate" ) ) | ||||||
|         if ( translate == null ) |  | ||||||
|         { |         { | ||||||
|             throw new JsonParseException( "Could not parse JSON: missing 'translate' property" ); |             throw new JsonParseException( "Could not parse JSON: missing 'translate' property" ); | ||||||
|         } |         } | ||||||
|         component.setTranslate( translate.getAsString() ); |         component.setTranslate( object.get( "translate" ).getAsString() ); | ||||||
|         JsonElement with = object.get( "with" ); |         if ( object.has( "with" ) ) | ||||||
|         if ( with != null ) |  | ||||||
|         { |         { | ||||||
|             component.setWith( Arrays.asList( context.deserialize( with, BaseComponent[].class ) ) ); |             component.setWith( Arrays.asList( context.<BaseComponent[]>deserialize( object.get( "with" ), BaseComponent[].class ) ) ); | ||||||
|         } |  | ||||||
|         JsonElement fallback = object.get( "fallback" ); |  | ||||||
|         if ( fallback != null ) |  | ||||||
|         { |  | ||||||
|             component.setFallback( fallback.getAsString() ); |  | ||||||
|         } |         } | ||||||
|         return component; |         return component; | ||||||
|     } |     } | ||||||
| @@ -50,10 +43,6 @@ public class TranslatableComponentSerializer extends BaseComponentSerializer imp | |||||||
|         { |         { | ||||||
|             object.add( "with", context.serialize( src.getWith() ) ); |             object.add( "with", context.serialize( src.getWith() ) ); | ||||||
|         } |         } | ||||||
|         if ( src.getFallback() != null ) |  | ||||||
|         { |  | ||||||
|             object.addProperty( "fallback", src.getFallback() ); |  | ||||||
|         } |  | ||||||
|         return object; |         return object; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -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() ) | ||||||
|   | |||||||
| @@ -1,17 +1,12 @@ | |||||||
| package net.md_5.bungee.api.chat; | package net.md_5.bungee.api.chat; | ||||||
|  |  | ||||||
| import static net.md_5.bungee.api.ChatColor.*; |  | ||||||
| import static org.junit.jupiter.api.Assertions.*; |  | ||||||
| import java.awt.Color; | import java.awt.Color; | ||||||
| import java.util.function.BiFunction; | import net.md_5.bungee.api.ChatColor; | ||||||
| import java.util.function.Consumer; | import net.md_5.bungee.api.chat.hover.content.Item; | ||||||
| import java.util.function.Function; |  | ||||||
| import java.util.function.ObjIntConsumer; |  | ||||||
| import java.util.function.Supplier; |  | ||||||
| import net.md_5.bungee.api.chat.hover.content.Entity; |  | ||||||
| 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.Assert; | ||||||
|  | import org.junit.Test; | ||||||
|  |  | ||||||
| public class ComponentsTest | public class ComponentsTest | ||||||
| { | { | ||||||
| @@ -20,27 +15,13 @@ public class ComponentsTest | |||||||
|     { |     { | ||||||
|         String json = ComponentSerializer.toString( components ); |         String json = ComponentSerializer.toString( components ); | ||||||
|         BaseComponent[] parsed = ComponentSerializer.parse( json ); |         BaseComponent[] parsed = ComponentSerializer.parse( json ); | ||||||
|         assertEquals( BaseComponent.toLegacyText( parsed ), BaseComponent.toLegacyText( components ) ); |         Assert.assertEquals( TextComponent.toLegacyText( parsed ), TextComponent.toLegacyText( components ) ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static void testDissembleReassemble(BaseComponent component) |     public static void testDissembleReassemble(String json) | ||||||
|     { |  | ||||||
|         String json = ComponentSerializer.toString( component ); |  | ||||||
|         BaseComponent[] parsed = ComponentSerializer.parse( json ); |  | ||||||
|         assertEquals( BaseComponent.toLegacyText( parsed ), BaseComponent.toLegacyText( component ) ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public static void testAssembleDissemble(String json, boolean modern) |  | ||||||
|     { |  | ||||||
|         if ( modern ) |  | ||||||
|         { |  | ||||||
|             BaseComponent deserialized = ComponentSerializer.deserialize( json ); |  | ||||||
|             assertEquals( json, ComponentSerializer.toString( deserialized ) ); |  | ||||||
|         } else |  | ||||||
|     { |     { | ||||||
|         BaseComponent[] parsed = ComponentSerializer.parse( json ); |         BaseComponent[] parsed = ComponentSerializer.parse( json ); | ||||||
|             assertEquals( json, ComponentSerializer.toString( parsed ) ); |         Assert.assertEquals( json, ComponentSerializer.toString( parsed ) ); | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
| @@ -60,20 +41,16 @@ public class ComponentsTest | |||||||
|         { |         { | ||||||
|             textComponent |             textComponent | ||||||
|         } ); |         } ); | ||||||
|         testDissembleReassemble( textComponent ); |         json = "{\"text\":\"Test\",\"hoverEvent\":{\"action\":\"show_item\",\"value\":[{\"text\":\"{id:\\\"minecraft:netherrack\\\",Count:47b}\"}]}}"; | ||||||
|         json = "{\"hoverEvent\":{\"action\":\"show_item\",\"value\":[{\"text\":\"{id:\\\"minecraft:netherrack\\\",Count:47b}\"}]},\"text\":\"Test\"}"; |         testDissembleReassemble( json ); | ||||||
|         testAssembleDissemble( json, false ); |  | ||||||
|         testAssembleDissemble( json, true ); |  | ||||||
|         ////////// |         ////////// | ||||||
|         String hoverVal = "{\"text\":\"{id:\\\"minecraft:dirt\\\",Count:1b}\"}"; |         String hoverVal = "{\"text\":\"{id:\\\"minecraft:dirt\\\",Count:1b}\"}"; | ||||||
|         json = "{\"extra\":[{\"text\":\"[\"},{\"extra\":[{\"translate\":\"block.minecraft.dirt\"}],\"text\":\"\"},{\"text\":\"]\"}],\"hoverEvent\":{\"action\":\"show_item\",\"value\":[" + hoverVal + "]},\"text\":\"\"}"; |         json = "{\"extra\":[{\"text\":\"[\"},{\"extra\":[{\"translate\":\"block.minecraft.dirt\"}],\"text\":\"\"},{\"text\":\"]\"}],\"hoverEvent\":{\"action\":\"show_item\",\"value\":[" + hoverVal + "]},\"text\":\"\"}"; | ||||||
|         components = ComponentSerializer.parse( json ); |         components = ComponentSerializer.parse( json ); | ||||||
|         Text contentText = ( (Text) components[0].getHoverEvent().getContents().get( 0 ) ); |         Text contentText = ( (Text) components[0].getHoverEvent().getContents().get( 0 ) ); | ||||||
|         assertEquals( hoverVal, ComponentSerializer.toString( (BaseComponent[]) contentText.getValue() ) ); |         Assert.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 ) ); | ||||||
| @@ -82,53 +59,25 @@ public class ComponentsTest | |||||||
|         json = ComponentSerializer.toString( component1 ); |         json = ComponentSerializer.toString( component1 ); | ||||||
|         components = ComponentSerializer.parse( json ); |         components = ComponentSerializer.parse( json ); | ||||||
|         Item parsedContentItem = ( (Item) components[0].getHoverEvent().getContents().get( 0 ) ); |         Item parsedContentItem = ( (Item) components[0].getHoverEvent().getContents().get( 0 ) ); | ||||||
|         assertEquals( contentItem, parsedContentItem ); |         Assert.assertEquals( contentItem, parsedContentItem ); | ||||||
|         assertEquals( contentItem.getCount(), parsedContentItem.getCount() ); |         Assert.assertEquals( contentItem.getCount(), parsedContentItem.getCount() ); | ||||||
|         assertEquals( contentItem.getId(), parsedContentItem.getId() ); |         Assert.assertEquals( contentItem.getId(), parsedContentItem.getId() ); | ||||||
|         assertEquals( nbt, parsedContentItem.getTag().getNbt() ); |         Assert.assertEquals( nbt, parsedContentItem.getTag().getNbt() ); | ||||||
|          */ |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     public void testArrayUUIDParse() |     public void testEmptyComponentBuilder() | ||||||
|     { |  | ||||||
|         BaseComponent[] uuidComponent = ComponentSerializer.parse( "{\"translate\":\"multiplayer.player.joined\",\"with\":[{\"text\":\"Rexcantor64\",\"hoverEvent\":{\"contents\":{\"type\":\"minecraft:player\",\"id\":[1328556382,-2138814985,-1895806765,-1039963041],\"name\":\"Rexcantor64\"},\"action\":\"show_entity\"},\"insertion\":\"Rexcantor64\",\"clickEvent\":{\"action\":\"suggest_command\",\"value\":\"/tell Rexcantor64 \"}}],\"color\":\"yellow\"}" ); |  | ||||||
|         assertEquals( "4f30295e-8084-45f7-8f00-48d3c2036c5f", ( (Entity) ( (TranslatableComponent) uuidComponent[0] ).getWith().get( 0 ).getHoverEvent().getContents().get( 0 ) ).getId() ); |  | ||||||
|         testDissembleReassemble( uuidComponent ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Test |  | ||||||
|     public void testEmptyComponentBuilderCreate() |  | ||||||
|     { |  | ||||||
|         testEmptyComponentBuilder( |  | ||||||
|                 ComponentBuilder::create, |  | ||||||
|                 (components) -> assertEquals( components.length, 0 ), |  | ||||||
|                 (components, size) -> assertEquals( size, components.length ) |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Test |  | ||||||
|     public void testEmptyComponentBuilderBuild() |  | ||||||
|     { |  | ||||||
|         testEmptyComponentBuilder( |  | ||||||
|                 ComponentBuilder::build, |  | ||||||
|                 (component) -> assertNull( component.getExtra() ), |  | ||||||
|                 (component, size) -> assertEquals( component.getExtra().size(), size ) |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private static <T> void testEmptyComponentBuilder(Function<ComponentBuilder, T> componentBuilder, Consumer<T> emptyAssertion, ObjIntConsumer<T> sizedAssertion) |  | ||||||
|     { |     { | ||||||
|         ComponentBuilder builder = new ComponentBuilder(); |         ComponentBuilder builder = new ComponentBuilder(); | ||||||
|  |  | ||||||
|         T component = componentBuilder.apply( builder ); |         BaseComponent[] parts = builder.create(); | ||||||
|         emptyAssertion.accept( component ); |         Assert.assertEquals( parts.length, 0 ); | ||||||
|  |  | ||||||
|         for ( int i = 0; i < 3; i++ ) |         for ( int i = 0; i < 3; i++ ) | ||||||
|         { |         { | ||||||
|             builder.append( "part:" + i ); |             builder.append( "part:" + i ); | ||||||
|             component = componentBuilder.apply( builder ); |             parts = builder.create(); | ||||||
|             sizedAssertion.accept( component, i + 1 ); |             Assert.assertEquals( parts.length, i + 1 ); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -136,34 +85,23 @@ public class ComponentsTest | |||||||
|     public void testDummyRetaining() |     public void testDummyRetaining() | ||||||
|     { |     { | ||||||
|         ComponentBuilder builder = new ComponentBuilder(); |         ComponentBuilder builder = new ComponentBuilder(); | ||||||
|         assertNotNull( builder.getCurrentComponent() ); |         Assert.assertNotNull( builder.getCurrentComponent() ); | ||||||
|         builder.color( GREEN ); |         builder.color( ChatColor.GREEN ); | ||||||
|         builder.append( "test ", ComponentBuilder.FormatRetention.ALL ); |         builder.append( "test ", ComponentBuilder.FormatRetention.ALL ); | ||||||
|         assertEquals( builder.getCurrentComponent().getColor(), GREEN ); |         Assert.assertEquals( builder.getCurrentComponent().getColor(), ChatColor.GREEN ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test(expected = IndexOutOfBoundsException.class) | ||||||
|     public void testComponentGettingExceptions() |     public void testComponentGettingExceptions() | ||||||
|     { |     { | ||||||
|         ComponentBuilder builder = new ComponentBuilder(); |         ComponentBuilder builder = new ComponentBuilder(); | ||||||
|         assertThrows( IndexOutOfBoundsException.class, () -> builder.getComponent( -1 ) ); |         builder.getComponent( -1 ); | ||||||
|         assertThrows( IndexOutOfBoundsException.class, () -> builder.getComponent( 0 ) ); |         builder.getComponent( 0 ); | ||||||
|         assertThrows( IndexOutOfBoundsException.class, () -> builder.getComponent( 1 ) ); |         builder.getComponent( 1 ); | ||||||
|         BaseComponent component = new TextComponent( "Hello" ); |         BaseComponent component = new TextComponent( "Hello" ); | ||||||
|         builder.append( component ); |         builder.append( component ); | ||||||
|         assertEquals( builder.getComponent( 0 ), component ); |         Assert.assertEquals( builder.getComponent( 0 ), component ); | ||||||
|         assertThrows( IndexOutOfBoundsException.class, () -> builder.getComponent( 1 ) ); |         builder.getComponent( 1 ); | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Test |  | ||||||
|     public void testFormatNotColor() |  | ||||||
|     { |  | ||||||
|         BaseComponent[] component = new ComponentBuilder().color( BOLD ).append( "Test" ).create(); |  | ||||||
|  |  | ||||||
|         String json = ComponentSerializer.toString( component ); |  | ||||||
|         BaseComponent[] parsed = ComponentSerializer.parse( json ); |  | ||||||
|  |  | ||||||
|         assertNull( parsed[0].getColorRaw(), "Format should not be preserved as color" ); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
| @@ -172,33 +110,33 @@ public class ComponentsTest | |||||||
|         ComponentBuilder builder = new ComponentBuilder(); |         ComponentBuilder builder = new ComponentBuilder(); | ||||||
|         TextComponent apple = new TextComponent( "apple" ); |         TextComponent apple = new TextComponent( "apple" ); | ||||||
|         builder.append( apple ); |         builder.append( apple ); | ||||||
|         assertEquals( builder.getCurrentComponent(), apple ); |         Assert.assertEquals( builder.getCurrentComponent(), apple ); | ||||||
|         assertEquals( builder.getComponent( 0 ), apple ); |         Assert.assertEquals( builder.getComponent( 0 ), apple ); | ||||||
|  |  | ||||||
|         TextComponent mango = new TextComponent( "mango" ); |         TextComponent mango = new TextComponent( "mango" ); | ||||||
|         TextComponent orange = new TextComponent( "orange" ); |         TextComponent orange = new TextComponent( "orange" ); | ||||||
|         builder.append( mango ); |         builder.append( mango ); | ||||||
|         builder.append( orange ); |         builder.append( orange ); | ||||||
|         builder.removeComponent( 1 ); // Removing mango |         builder.removeComponent( 1 ); // Removing mango | ||||||
|         assertEquals( builder.getComponent( 0 ), apple ); |         Assert.assertEquals( builder.getComponent( 0 ), apple ); | ||||||
|         assertEquals( builder.getComponent( 1 ), orange ); |         Assert.assertEquals( builder.getComponent( 1 ), orange ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     public void testToLegacyFromLegacy() |     public void testToLegacyFromLegacy() | ||||||
|     { |     { | ||||||
|         String text = "" + GREEN + BOLD + "Hello " + WHITE + MAGIC + "world" + GRAY + "!"; |         String text = "§a§lHello §f§kworld§7!"; | ||||||
|         assertEquals( text, BaseComponent.toLegacyText( TextComponent.fromLegacyText( text ) ) ); |         Assert.assertEquals( text, TextComponent.toLegacyText( TextComponent.fromLegacyText( text ) ) ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test(expected = IndexOutOfBoundsException.class) | ||||||
|     public void testComponentBuilderCursorInvalidPos() |     public void testComponentBuilderCursorInvalidPos() | ||||||
|     { |     { | ||||||
|         ComponentBuilder builder = new ComponentBuilder(); |         ComponentBuilder builder = new ComponentBuilder(); | ||||||
|         builder.append( new TextComponent( "Apple, " ) ); |         builder.append( new TextComponent( "Apple, " ) ); | ||||||
|         builder.append( new TextComponent( "Orange, " ) ); |         builder.append( new TextComponent( "Orange, " ) ); | ||||||
|         assertThrows( IndexOutOfBoundsException.class, () -> builder.setCursor( -1 ) ); |         builder.setCursor( -1 ); | ||||||
|         assertThrows( IndexOutOfBoundsException.class, () -> builder.setCursor( 2 ) ); |         builder.setCursor( 2 ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
| @@ -206,33 +144,33 @@ public class ComponentsTest | |||||||
|     { |     { | ||||||
|         TextComponent t1, t2, t3; |         TextComponent t1, t2, t3; | ||||||
|         ComponentBuilder builder = new ComponentBuilder(); |         ComponentBuilder builder = new ComponentBuilder(); | ||||||
|         assertEquals( builder.getCursor(), -1 ); |         Assert.assertEquals( builder.getCursor(), -1 ); | ||||||
|         builder.append( t1 = new TextComponent( "Apple, " ) ); |         builder.append( t1 = new TextComponent( "Apple, " ) ); | ||||||
|         assertEquals( builder.getCursor(), 0 ); |         Assert.assertEquals( builder.getCursor(), 0 ); | ||||||
|         builder.append( t2 = new TextComponent( "Orange, " ) ); |         builder.append( t2 = new TextComponent( "Orange, " ) ); | ||||||
|         builder.append( t3 = new TextComponent( "Mango, " ) ); |         builder.append( t3 = new TextComponent( "Mango, " ) ); | ||||||
|         assertEquals( builder.getCursor(), 2 ); |         Assert.assertEquals( builder.getCursor(), 2 ); | ||||||
|  |  | ||||||
|         builder.setCursor( 0 ); |         builder.setCursor( 0 ); | ||||||
|         assertEquals( builder.getCurrentComponent(), t1 ); |         Assert.assertEquals( builder.getCurrentComponent(), t1 ); | ||||||
|  |  | ||||||
|         // Test that appending new components updates the position to the new list size |         // Test that appending new components updates the position to the new list size | ||||||
|         // after having previously set it to 0 (first component) |         // after having previously set it to 0 (first component) | ||||||
|         builder.append( new TextComponent( "and Grapefruit" ) ); |         builder.append( new TextComponent( "and Grapefruit" ) ); | ||||||
|         assertEquals( builder.getCursor(), 3 ); |         Assert.assertEquals( builder.getCursor(), 3 ); | ||||||
|  |  | ||||||
|         builder.setCursor( 0 ); |         builder.setCursor( 0 ); | ||||||
|         builder.resetCursor(); |         builder.resetCursor(); | ||||||
|         assertEquals( builder.getCursor(), 3 ); |         Assert.assertEquals( builder.getCursor(), 3 ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     public void testLegacyComponentBuilderAppend() |     public void testLegacyComponentBuilderAppend() | ||||||
|     { |     { | ||||||
|         String text = "" + GREEN + BOLD + "Hello " + RESET + MAGIC + "world" + GRAY + "!"; |         String text = "§a§lHello §r§kworld§7!"; | ||||||
|         BaseComponent[] components = TextComponent.fromLegacyText( text ); |         BaseComponent[] components = TextComponent.fromLegacyText( text ); | ||||||
|         BaseComponent[] builderComponents = new ComponentBuilder().append( components ).create(); |         BaseComponent[] builderComponents = new ComponentBuilder().append( components ).create(); | ||||||
|         assertArrayEquals( components, builderComponents ); |         Assert.assertArrayEquals( components, builderComponents ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /* |     /* | ||||||
| @@ -254,7 +192,7 @@ public class ComponentsTest | |||||||
|         component.setHoverEvent( event ); |         component.setHoverEvent( event ); | ||||||
|         String serialised = ComponentSerializer.toString( component ); |         String serialised = ComponentSerializer.toString( component ); | ||||||
|         BaseComponent[] deserialised = ComponentSerializer.parse( serialised ); |         BaseComponent[] deserialised = ComponentSerializer.parse( serialised ); | ||||||
|         assertEquals( TextComponent.toLegacyText( deserialised ), TextComponent.toLegacyText( component ) ); |         Assert.assertEquals( TextComponent.toLegacyText( deserialised ), TextComponent.toLegacyText( component ) ); | ||||||
|     } |     } | ||||||
|      */ |      */ | ||||||
|  |  | ||||||
| @@ -269,13 +207,13 @@ public class ComponentsTest | |||||||
|         ); |         ); | ||||||
|         TextComponent component = new TextComponent( "test" ); |         TextComponent component = new TextComponent( "test" ); | ||||||
|         component.setHoverEvent( hoverEvent ); |         component.setHoverEvent( hoverEvent ); | ||||||
|         assertEquals( component.getHoverEvent().getContents().size(), 1 ); |         Assert.assertEquals( component.getHoverEvent().getContents().size(), 1 ); | ||||||
|         assertTrue( component.getHoverEvent().getContents().get( 0 ) instanceof Text ); |         Assert.assertTrue( component.getHoverEvent().getContents().get( 0 ) instanceof Text ); | ||||||
|         assertEquals( ( (Text) component.getHoverEvent().getContents().get( 0 ) ).getValue(), advancement ); |         Assert.assertEquals( ( (Text) component.getHoverEvent().getContents().get( 0 ) ).getValue(), advancement ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     public void testHoverEventContentsCreate() |     public void testHoverEventContents() | ||||||
|     { |     { | ||||||
|         // First do the text using the newer contents system |         // First do the text using the newer contents system | ||||||
|         HoverEvent hoverEvent = new HoverEvent( |         HoverEvent hoverEvent = new HoverEvent( | ||||||
| @@ -284,53 +222,21 @@ public class ComponentsTest | |||||||
|                 new Text( new ComponentBuilder( "Second" ).create() ) |                 new Text( new ComponentBuilder( "Second" ).create() ) | ||||||
|         ); |         ); | ||||||
|  |  | ||||||
|         this.testHoverEventContents( |         TextComponent component = new TextComponent( "Sample text" ); | ||||||
|                 hoverEvent, |         component.setHoverEvent( hoverEvent ); | ||||||
|                 ComponentSerializer::parse, |         Assert.assertEquals( hoverEvent.getContents().size(), 2 ); | ||||||
|                 (components) -> components[0].getHoverEvent(), |         Assert.assertFalse( hoverEvent.isLegacy() ); | ||||||
|                 ComponentsTest::testDissembleReassemble // BaseComponent |         String serialized = ComponentSerializer.toString( component ); | ||||||
|         ); |         BaseComponent[] deserialized = ComponentSerializer.parse( serialized ); | ||||||
|  |         Assert.assertEquals( component.getHoverEvent(), deserialized[0].getHoverEvent() ); | ||||||
|  |  | ||||||
|         // check the test still works with the value method |         // check the test still works with the value method | ||||||
|         hoverEvent = new HoverEvent( HoverEvent.Action.SHOW_TEXT, new ComponentBuilder( "Sample text" ).create() ); |         hoverEvent = new HoverEvent( HoverEvent.Action.SHOW_TEXT, new ComponentBuilder( "Sample text" ).create() ); | ||||||
|         TextComponent component = new TextComponent( "Sample text" ); |         Assert.assertEquals( hoverEvent.getContents().size(), 1 ); | ||||||
|         component.setHoverEvent( hoverEvent ); |         Assert.assertTrue( hoverEvent.isLegacy() ); | ||||||
|  |         serialized = ComponentSerializer.toString( component ); | ||||||
|         assertEquals( hoverEvent.getContents().size(), 1 ); |         deserialized = ComponentSerializer.parse( serialized ); | ||||||
|         assertTrue( hoverEvent.isLegacy() ); |         Assert.assertEquals( component.getHoverEvent(), deserialized[0].getHoverEvent() ); | ||||||
|         String serialized = ComponentSerializer.toString( component ); |  | ||||||
|         BaseComponent[] deserialized = ComponentSerializer.parse( serialized ); |  | ||||||
|         assertEquals( component.getHoverEvent(), deserialized[0].getHoverEvent() ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Test |  | ||||||
|     public void testHoverEventContentsBuild() |  | ||||||
|     { |  | ||||||
|         // First do the text using the newer contents system |  | ||||||
|         HoverEvent hoverEvent = new HoverEvent( |  | ||||||
|                 HoverEvent.Action.SHOW_TEXT, |  | ||||||
|                 new Text( new ComponentBuilder( "First" ).build() ), |  | ||||||
|                 new Text( new ComponentBuilder( "Second" ).build() ) |  | ||||||
|         ); |  | ||||||
|  |  | ||||||
|         this.testHoverEventContents( |  | ||||||
|                 hoverEvent, |  | ||||||
|                 ComponentSerializer::deserialize, |  | ||||||
|                 BaseComponent::getHoverEvent, |  | ||||||
|                 ComponentsTest::testDissembleReassemble // BaseComponent |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private <T> void testHoverEventContents(HoverEvent hoverEvent, Function<String, T> deserializer, Function<T, HoverEvent> hoverEventGetter, Consumer<T> dissembleReassembleTest) |  | ||||||
|     { |  | ||||||
|         TextComponent component = new TextComponent( "Sample text" ); |  | ||||||
|         component.setHoverEvent( hoverEvent ); |  | ||||||
|         assertEquals( hoverEvent.getContents().size(), 2 ); |  | ||||||
|         assertFalse( hoverEvent.isLegacy() ); |  | ||||||
|  |  | ||||||
|         String serialized = ComponentSerializer.toString( component ); |  | ||||||
|         T deserialized = deserializer.apply( serialized ); |  | ||||||
|         assertEquals( component.getHoverEvent(), hoverEventGetter.apply( deserialized ) ); |  | ||||||
|  |  | ||||||
|         // Test single content: |         // Test single content: | ||||||
|         String json = "{\"italic\":true,\"color\":\"gray\",\"translate\":\"chat.type.admin\",\"with\":[{\"text\":\"@\"}" |         String json = "{\"italic\":true,\"color\":\"gray\",\"translate\":\"chat.type.admin\",\"with\":[{\"text\":\"@\"}" | ||||||
| @@ -342,76 +248,37 @@ public class ComponentsTest | |||||||
|                 + "\"/tell Name \"},\"hoverEvent\":{\"action\":\"show_entity\",\"contents\":" |                 + "\"/tell Name \"},\"hoverEvent\":{\"action\":\"show_entity\",\"contents\":" | ||||||
|                 + "{\"type\":\"minecraft:player\",\"id\":\"00000000-0000-0000-0000-00000000000000\",\"name\":" |                 + "{\"type\":\"minecraft:player\",\"id\":\"00000000-0000-0000-0000-00000000000000\",\"name\":" | ||||||
|                 + "{\"text\":\"Name\"}}},\"text\":\"Name\"}]}]}"; |                 + "{\"text\":\"Name\"}}},\"text\":\"Name\"}]}]}"; | ||||||
|         dissembleReassembleTest.accept( deserializer.apply( json ) ); |         testDissembleReassemble( ComponentSerializer.parse( json ) ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     public void testFormatRetentionCopyFormattingCreate() |     public void testFormatRetentionCopyFormatting() | ||||||
|     { |  | ||||||
|         testFormatRetentionCopyFormatting( () -> new HoverEvent( HoverEvent.Action.SHOW_TEXT, new ComponentBuilder( "Test" ).create() ) ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Test |  | ||||||
|     public void testFormatRetentionCopyFormattingBuild() |  | ||||||
|     { |  | ||||||
|         testFormatRetentionCopyFormatting( () -> new HoverEvent( HoverEvent.Action.SHOW_TEXT, new Text( new ComponentBuilder( "Test" ).build() ) ) ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private static void testFormatRetentionCopyFormatting(Supplier<HoverEvent> hoverEventSupplier) |  | ||||||
|     { |     { | ||||||
|         TextComponent first = new TextComponent( "Hello" ); |         TextComponent first = new TextComponent( "Hello" ); | ||||||
|         first.setBold( true ); |         first.setBold( true ); | ||||||
|         first.setColor( RED ); |         first.setColor( ChatColor.RED ); | ||||||
|         first.setClickEvent( new ClickEvent( ClickEvent.Action.RUN_COMMAND, "test" ) ); |         first.setClickEvent( new ClickEvent( ClickEvent.Action.RUN_COMMAND, "test" ) ); | ||||||
|         first.setHoverEvent( hoverEventSupplier.get() ); |         first.setHoverEvent( new HoverEvent( HoverEvent.Action.SHOW_TEXT, new ComponentBuilder( "Test" ).create() ) ); | ||||||
|  |  | ||||||
|         TextComponent second = new TextComponent( " world" ); |         TextComponent second = new TextComponent( " world" ); | ||||||
|         second.copyFormatting( first, ComponentBuilder.FormatRetention.ALL, true ); |         second.copyFormatting( first, ComponentBuilder.FormatRetention.ALL, true ); | ||||||
|         assertEquals( first.isBold(), second.isBold() ); |         Assert.assertEquals( first.isBold(), second.isBold() ); | ||||||
|         assertEquals( first.getColor(), second.getColor() ); |         Assert.assertEquals( first.getColor(), second.getColor() ); | ||||||
|         assertEquals( first.getClickEvent(), second.getClickEvent() ); |         Assert.assertEquals( first.getClickEvent(), second.getClickEvent() ); | ||||||
|         assertEquals( first.getHoverEvent(), second.getHoverEvent() ); |         Assert.assertEquals( first.getHoverEvent(), second.getHoverEvent() ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     public void testBuilderCloneCreate() |     public void testBuilderClone() | ||||||
|     { |     { | ||||||
|         testBuilderClone( (builder) -> BaseComponent.toLegacyText( builder.create() ) ); |         ComponentBuilder builder = new ComponentBuilder( "Hello " ).color( ChatColor.RED ).append( "world" ).color( ChatColor.DARK_RED ); | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Test |  | ||||||
|     public void testBuilderCloneBuild() |  | ||||||
|     { |  | ||||||
|         testBuilderClone( (builder) -> BaseComponent.toLegacyText( builder.build() ) ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private static void testBuilderClone(Function<ComponentBuilder, String> legacyTextFunction) |  | ||||||
|     { |  | ||||||
|         ComponentBuilder builder = new ComponentBuilder( "Hello " ).color( RED ).append( "world" ).color( DARK_RED ); |  | ||||||
|         ComponentBuilder cloned = new ComponentBuilder( builder ); |         ComponentBuilder cloned = new ComponentBuilder( builder ); | ||||||
|  |  | ||||||
|         assertEquals( legacyTextFunction.apply( builder ), legacyTextFunction.apply( cloned ) ); |         Assert.assertEquals( TextComponent.toLegacyText( builder.create() ), TextComponent.toLegacyText( cloned.create() ) ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     public void testBuilderAppendCreateMixedComponents() |     public void testBuilderAppendMixedComponents() | ||||||
|     { |  | ||||||
|         testBuilderAppendMixedComponents( |  | ||||||
|                 ComponentBuilder::create, |  | ||||||
|                 (components, index) -> components[index] |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Test |  | ||||||
|     public void testBuilderAppendBuildMixedComponents() |  | ||||||
|     { |  | ||||||
|         testBuilderAppendMixedComponents( |  | ||||||
|                 ComponentBuilder::build, |  | ||||||
|                 (component, index) -> component.getExtra().get( index ) |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private static <T> void testBuilderAppendMixedComponents(Function<ComponentBuilder, T> componentBuilder, BiFunction<T, Integer, BaseComponent> extraGetter) |  | ||||||
|     { |     { | ||||||
|         ComponentBuilder builder = new ComponentBuilder( "Hello " ); |         ComponentBuilder builder = new ComponentBuilder( "Hello " ); | ||||||
|         TextComponent textComponent = new TextComponent( "world " ); |         TextComponent textComponent = new TextComponent( "world " ); | ||||||
| @@ -424,11 +291,11 @@ public class ComponentsTest | |||||||
|         } ); |         } ); | ||||||
|         ScoreComponent scoreComponent = new ScoreComponent( "myscore", "myobjective" ); |         ScoreComponent scoreComponent = new ScoreComponent( "myscore", "myobjective" ); | ||||||
|         builder.append( scoreComponent ); // non array based BaseComponent append |         builder.append( scoreComponent ); // non array based BaseComponent append | ||||||
|         T component = componentBuilder.apply( builder ); |         BaseComponent[] components = builder.create(); | ||||||
|         assertEquals( "Hello ", extraGetter.apply( component, 0 ).toPlainText() ); |         Assert.assertEquals( "Hello ", components[0].toPlainText() ); | ||||||
|         assertEquals( textComponent.toPlainText(), extraGetter.apply( component, 1 ).toPlainText() ); |         Assert.assertEquals( textComponent.toPlainText(), components[1].toPlainText() ); | ||||||
|         assertEquals( translatableComponent.toPlainText(), extraGetter.apply( component, 2 ).toPlainText() ); |         Assert.assertEquals( translatableComponent.toPlainText(), components[2].toPlainText() ); | ||||||
|         assertEquals( scoreComponent.toPlainText(), extraGetter.apply( component, 3 ).toPlainText() ); |         Assert.assertEquals( scoreComponent.toPlainText(), components[3].toPlainText() ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
| @@ -438,261 +305,171 @@ public class ComponentsTest | |||||||
|         String text = ComponentSerializer.toString( component ); |         String text = ComponentSerializer.toString( component ); | ||||||
|         BaseComponent[] reparsed = ComponentSerializer.parse( text ); |         BaseComponent[] reparsed = ComponentSerializer.parse( text ); | ||||||
|  |  | ||||||
|         assertArrayEquals( component, reparsed ); |         Assert.assertArrayEquals( component, reparsed ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     public void testStyle() |     public void testBuilderAppend() | ||||||
|     { |  | ||||||
|         ComponentStyle style = ComponentSerializer.deserializeStyle( "{\"color\":\"red\",\"font\":\"minecraft:example\",\"bold\":true,\"italic\":false,\"obfuscated\":true}" ); |  | ||||||
|         String text = ComponentSerializer.toString( style ); |  | ||||||
|         ComponentStyle reparsed = ComponentSerializer.deserializeStyle( text ); |  | ||||||
|  |  | ||||||
|         assertEquals( style, reparsed ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Test |  | ||||||
|     public void testBuilderAppendCreate() |  | ||||||
|     { |  | ||||||
|         testBuilderAppend( |  | ||||||
|                 () -> new HoverEvent( HoverEvent.Action.SHOW_TEXT, new ComponentBuilder( "Hello world" ).create() ), |  | ||||||
|                 ComponentBuilder::create, |  | ||||||
|                 (components, index) -> components[index], |  | ||||||
|                 BaseComponent::toPlainText, |  | ||||||
|                 YELLOW + "Hello " + GREEN + "world!", |  | ||||||
|                 BaseComponent::toLegacyText |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Test |  | ||||||
|     public void testBuilderAppendBuild() |  | ||||||
|     { |  | ||||||
|         testBuilderAppend( |  | ||||||
|                 () -> new HoverEvent( HoverEvent.Action.SHOW_TEXT, new Text( new ComponentBuilder( "Hello world" ).build() ) ), |  | ||||||
|                 ComponentBuilder::build, |  | ||||||
|                 (component, index) -> component.getExtra().get( index ), |  | ||||||
|                 (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 |  | ||||||
|                 WHITE.toString() + YELLOW + "Hello " + GREEN + "world!", |  | ||||||
|                 (component) -> BaseComponent.toLegacyText( component ) |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private static <T> void testBuilderAppend(Supplier<HoverEvent> hoverEventSupplier, Function<ComponentBuilder, T> componentBuilder, BiFunction<T, Integer, BaseComponent> extraGetter, Function<T, String> toPlainTextFunction, String expectedLegacyText, Function<T, String> toLegacyTextFunction) |  | ||||||
|     { |     { | ||||||
|         ClickEvent clickEvent = new ClickEvent( ClickEvent.Action.RUN_COMMAND, "/help " ); |         ClickEvent clickEvent = new ClickEvent( ClickEvent.Action.RUN_COMMAND, "/help " ); | ||||||
|         HoverEvent hoverEvent = hoverEventSupplier.get(); |         HoverEvent hoverEvent = new HoverEvent( HoverEvent.Action.SHOW_TEXT, new ComponentBuilder( "Hello world" ).create() ); | ||||||
|  |  | ||||||
|         ComponentBuilder builder = new ComponentBuilder( "Hello " ).color( YELLOW ); |         ComponentBuilder builder = new ComponentBuilder( "Hello " ).color( ChatColor.YELLOW ); | ||||||
|         builder.append( new ComponentBuilder( "world!" ).color( GREEN ).event( hoverEvent ).event( clickEvent ).create() ); // Intentionally using create() to append multiple individual components |         builder.append( new ComponentBuilder( "world!" ).color( ChatColor.GREEN ).event( hoverEvent ).event( clickEvent ).create() ); | ||||||
|  |  | ||||||
|         T component = componentBuilder.apply( builder ); |         BaseComponent[] components = builder.create(); | ||||||
|  |  | ||||||
|         assertEquals( extraGetter.apply( component, 1 ).getHoverEvent(), hoverEvent ); |         Assert.assertEquals( components[1].getHoverEvent(), hoverEvent ); | ||||||
|         assertEquals( extraGetter.apply( component, 1 ).getClickEvent(), clickEvent ); |         Assert.assertEquals( components[1].getClickEvent(), clickEvent ); | ||||||
|         assertEquals( "Hello world!", toPlainTextFunction.apply( component ) ); |         Assert.assertEquals( "Hello world!", BaseComponent.toPlainText( components ) ); | ||||||
|         assertEquals( expectedLegacyText, toLegacyTextFunction.apply( component ) ); |         Assert.assertEquals( ChatColor.YELLOW + "Hello " + ChatColor.GREEN + "world!", BaseComponent.toLegacyText( components ) ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     public void testBuilderAppendLegacyCreate() |     public void testBuilderAppendLegacy() | ||||||
|     { |     { | ||||||
|         testBuilderAppendLegacy( |         ComponentBuilder builder = new ComponentBuilder( "Hello " ).color( ChatColor.YELLOW ); | ||||||
|                 ComponentBuilder::create, |         builder.appendLegacy( "§aworld!" ); | ||||||
|                 BaseComponent::toPlainText, |  | ||||||
|                 YELLOW + "Hello " + GREEN + "world!", |  | ||||||
|                 BaseComponent::toLegacyText |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Test |         BaseComponent[] components = builder.create(); | ||||||
|     public void testBuilderAppendLegacyBuild() |  | ||||||
|     { |  | ||||||
|         testBuilderAppendLegacy( |  | ||||||
|                 ComponentBuilder::build, |  | ||||||
|                 (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 |  | ||||||
|                 WHITE.toString() + YELLOW + "Hello " + GREEN + "world!", |  | ||||||
|                 (component) -> BaseComponent.toLegacyText( component ) |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private static <T> void testBuilderAppendLegacy(Function<ComponentBuilder, T> componentBuilder, Function<T, String> toPlainTextFunction, String expectedLegacyString, Function<T, String> toLegacyTextFunction) |         Assert.assertEquals( "Hello world!", BaseComponent.toPlainText( components ) ); | ||||||
|     { |         Assert.assertEquals( ChatColor.YELLOW + "Hello " + ChatColor.GREEN + "world!", BaseComponent.toLegacyText( components ) ); | ||||||
|         ComponentBuilder builder = new ComponentBuilder( "Hello " ).color( YELLOW ); |  | ||||||
|         builder.appendLegacy( GREEN + "world!" ); |  | ||||||
|  |  | ||||||
|         T component = componentBuilder.apply( builder ); |  | ||||||
|  |  | ||||||
|         assertEquals( "Hello world!", toPlainTextFunction.apply( component ) ); |  | ||||||
|         assertEquals( expectedLegacyString, toLegacyTextFunction.apply( component ) ); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     public void testBasicComponent() |     public void testBasicComponent() | ||||||
|     { |     { | ||||||
|         TextComponent textComponent = new TextComponent( "Hello world" ); |         TextComponent textComponent = new TextComponent( "Hello world" ); | ||||||
|         textComponent.setColor( RED ); |         textComponent.setColor( ChatColor.RED ); | ||||||
|  |  | ||||||
|         assertEquals( "Hello world", textComponent.toPlainText() ); |         Assert.assertEquals( "Hello world", textComponent.toPlainText() ); | ||||||
|         assertEquals( RED + "Hello world", textComponent.toLegacyText() ); |         Assert.assertEquals( ChatColor.RED + "Hello world", textComponent.toLegacyText() ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     public void testLegacyConverter() |     public void testLegacyConverter() | ||||||
|     { |     { | ||||||
|         BaseComponent[] test1 = TextComponent.fromLegacyText( AQUA + "Aqua " + RED + BOLD + "RedBold" ); |         BaseComponent[] test1 = TextComponent.fromLegacyText( ChatColor.AQUA + "Aqua " + ChatColor.RED + ChatColor.BOLD + "RedBold" ); | ||||||
|  |  | ||||||
|         assertEquals( "Aqua RedBold", BaseComponent.toPlainText( test1 ) ); |         Assert.assertEquals( "Aqua RedBold", BaseComponent.toPlainText( test1 ) ); | ||||||
|         assertEquals( AQUA + "Aqua " + RED + BOLD + "RedBold", BaseComponent.toLegacyText( test1 ) ); |         Assert.assertEquals( ChatColor.AQUA + "Aqua " + ChatColor.RED + ChatColor.BOLD + "RedBold", BaseComponent.toLegacyText( test1 ) ); | ||||||
|  |  | ||||||
|         BaseComponent[] test2 = TextComponent.fromLegacyText( "Text http://spigotmc.org " + GREEN + "google.com/test" ); |         BaseComponent[] test2 = TextComponent.fromLegacyText( "Text http://spigotmc.org " + ChatColor.GREEN + "google.com/test" ); | ||||||
|  |  | ||||||
|         assertEquals( "Text http://spigotmc.org google.com/test", BaseComponent.toPlainText( test2 ) ); |         Assert.assertEquals( "Text http://spigotmc.org google.com/test", BaseComponent.toPlainText( test2 ) ); | ||||||
|         //The extra ChatColor instances are sometimes inserted when not needed but it doesn't change the result |         //The extra ChatColor instances are sometimes inserted when not needed but it doesn't change the result | ||||||
|         assertEquals( WHITE + "Text " + WHITE + "http://spigotmc.org" + WHITE |         Assert.assertEquals( ChatColor.WHITE + "Text " + ChatColor.WHITE + "http://spigotmc.org" + ChatColor.WHITE | ||||||
|                 + " " + GREEN + "google.com/test" + GREEN, BaseComponent.toLegacyText( test2 ) ); |                 + " " + ChatColor.GREEN + "google.com/test" + ChatColor.GREEN, BaseComponent.toLegacyText( test2 ) ); | ||||||
|  |  | ||||||
|         ClickEvent url1 = test2[1].getClickEvent(); |         ClickEvent url1 = test2[1].getClickEvent(); | ||||||
|         assertNotNull( url1 ); |         Assert.assertNotNull( url1 ); | ||||||
|         assertTrue( url1.getAction() == ClickEvent.Action.OPEN_URL ); |         Assert.assertTrue( url1.getAction() == ClickEvent.Action.OPEN_URL ); | ||||||
|         assertEquals( "http://spigotmc.org", url1.getValue() ); |         Assert.assertEquals( "http://spigotmc.org", url1.getValue() ); | ||||||
|  |  | ||||||
|         ClickEvent url2 = test2[3].getClickEvent(); |         ClickEvent url2 = test2[3].getClickEvent(); | ||||||
|         assertNotNull( url2 ); |         Assert.assertNotNull( url2 ); | ||||||
|         assertTrue( url2.getAction() == ClickEvent.Action.OPEN_URL ); |         Assert.assertTrue( url2.getAction() == ClickEvent.Action.OPEN_URL ); | ||||||
|         assertEquals( "http://google.com/test", url2.getValue() ); |         Assert.assertEquals( "http://google.com/test", url2.getValue() ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     public void testBuilderCreate() |     public void testTranslateComponent() | ||||||
|     { |     { | ||||||
|         testBuilder( |         TranslatableComponent item = new TranslatableComponent( "item.swordGold.name" ); | ||||||
|                 ComponentBuilder::create, |         item.setColor( ChatColor.AQUA ); | ||||||
|                 BaseComponent::toPlainText, |         TranslatableComponent translatableComponent = new TranslatableComponent( "commands.give.success", | ||||||
|                 RED + "Hello " + BLUE + BOLD + "World" + YELLOW + BOLD + "!", |                 item, "5", | ||||||
|                 BaseComponent::toLegacyText |                 "thinkofdeath" ); | ||||||
|         ); |  | ||||||
|  |         Assert.assertEquals( "Given Golden Sword * 5 to thinkofdeath", translatableComponent.toPlainText() ); | ||||||
|  |         Assert.assertEquals( ChatColor.WHITE + "Given " + ChatColor.AQUA + "Golden Sword" + ChatColor.WHITE | ||||||
|  |                 + " * " + ChatColor.WHITE + "5" + ChatColor.WHITE + " to " + ChatColor.WHITE + "thinkofdeath", | ||||||
|  |                 translatableComponent.toLegacyText() ); | ||||||
|  |  | ||||||
|  |         TranslatableComponent positional = new TranslatableComponent( "book.pageIndicator", "5", "50" ); | ||||||
|  |  | ||||||
|  |         Assert.assertEquals( "Page 5 of 50", positional.toPlainText() ); | ||||||
|  |         Assert.assertEquals( ChatColor.WHITE + "Page " + ChatColor.WHITE + "5" + ChatColor.WHITE + " of " + ChatColor.WHITE + "50", positional.toLegacyText() ); | ||||||
|  |  | ||||||
|  |         TranslatableComponent one_four_two = new TranslatableComponent( "filled_map.buried_treasure" ); | ||||||
|  |         Assert.assertEquals( "Buried Treasure Map", one_four_two.toPlainText() ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     public void testBuilderBuild() |     public void testBuilder() | ||||||
|     { |     { | ||||||
|         testBuilder( |         BaseComponent[] components = new ComponentBuilder( "Hello " ).color( ChatColor.RED ). | ||||||
|                 ComponentBuilder::build, |                 append( "World" ).bold( true ).color( ChatColor.BLUE ). | ||||||
|                 (component) -> BaseComponent.toPlainText( component ), |                 append( "!" ).color( ChatColor.YELLOW ).create(); | ||||||
|                 // An extra format code is appended to the beginning because there is an empty TextComponent at the start of every component |  | ||||||
|                 WHITE.toString() + RED + "Hello " + BLUE + BOLD + "World" + YELLOW + BOLD + "!", |  | ||||||
|                 (component) -> BaseComponent.toLegacyText( component ) |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private static <T> void testBuilder(Function<ComponentBuilder, T> componentBuilder, Function<T, String> toPlainTextFunction, String expectedLegacyString, Function<T, String> toLegacyTextFunction) |         Assert.assertEquals( "Hello World!", BaseComponent.toPlainText( components ) ); | ||||||
|     { |         Assert.assertEquals( ChatColor.RED + "Hello " + ChatColor.BLUE + ChatColor.BOLD | ||||||
|         T component = componentBuilder.apply( new ComponentBuilder( "Hello " ).color( RED ). |                 + "World" + ChatColor.YELLOW + ChatColor.BOLD + "!", BaseComponent.toLegacyText( components ) ); | ||||||
|                 append( "World" ).bold( true ).color( BLUE ). |  | ||||||
|                 append( "!" ).color( YELLOW ) ); |  | ||||||
|  |  | ||||||
|         assertEquals( "Hello World!", toPlainTextFunction.apply( component ) ); |  | ||||||
|         assertEquals( expectedLegacyString, toLegacyTextFunction.apply( component ) ); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     public void testBuilderCreateReset() |     public void testBuilderReset() | ||||||
|     { |     { | ||||||
|         testBuilderReset( |         BaseComponent[] components = new ComponentBuilder( "Hello " ).color( ChatColor.RED ) | ||||||
|                 ComponentBuilder::create, |                 .append( "World" ).reset().create(); | ||||||
|                 (components, index) -> components[index] |  | ||||||
|         ); |         Assert.assertEquals( components[0].getColor(), ChatColor.RED ); | ||||||
|  |         Assert.assertEquals( components[1].getColor(), ChatColor.WHITE ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     public void testBuilderBuildReset() |     public void testBuilderFormatRetention() | ||||||
|     { |     { | ||||||
|         testBuilderReset( |         BaseComponent[] noneRetention = new ComponentBuilder( "Hello " ).color( ChatColor.RED ) | ||||||
|                 ComponentBuilder::build, |                 .append( "World", ComponentBuilder.FormatRetention.NONE ).create(); | ||||||
|                 (component, index) -> component.getExtra().get( index ) |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private static <T> void testBuilderReset(Function<ComponentBuilder, T> componentBuilder, BiFunction<T, Integer, BaseComponent> extraGetter) |         Assert.assertEquals( noneRetention[0].getColor(), ChatColor.RED ); | ||||||
|     { |         Assert.assertEquals( noneRetention[1].getColor(), ChatColor.WHITE ); | ||||||
|         T component = componentBuilder.apply( new ComponentBuilder( "Hello " ).color( RED ) |  | ||||||
|                 .append( "World" ).reset() ); |  | ||||||
|  |  | ||||||
|         assertEquals( RED, extraGetter.apply( component, 0 ).getColor() ); |         HoverEvent testEvent = new HoverEvent( HoverEvent.Action.SHOW_TEXT, new ComponentBuilder( "test" ).create() ); | ||||||
|         assertEquals( WHITE, extraGetter.apply( component, 1 ).getColor() ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Test |         BaseComponent[] formattingRetention = new ComponentBuilder( "Hello " ).color( ChatColor.RED ) | ||||||
|     public void testBuilderCreateFormatRetention() |                 .event( testEvent ).append( "World", ComponentBuilder.FormatRetention.FORMATTING ).create(); | ||||||
|     { |  | ||||||
|         testBuilderFormatRetention( |  | ||||||
|                 ComponentBuilder::create, |  | ||||||
|                 (components, index) -> components[index] |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Test |         Assert.assertEquals( formattingRetention[0].getColor(), ChatColor.RED ); | ||||||
|     public void testBuilderBuildFormatRetention() |         Assert.assertEquals( formattingRetention[0].getHoverEvent(), testEvent ); | ||||||
|     { |         Assert.assertEquals( formattingRetention[1].getColor(), ChatColor.RED ); | ||||||
|         testBuilderFormatRetention( |         Assert.assertNull( formattingRetention[1].getHoverEvent() ); | ||||||
|                 ComponentBuilder::build, |  | ||||||
|                 (component, index) -> component.getExtra().get( index ) |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private static <T> void testBuilderFormatRetention(Function<ComponentBuilder, T> componentBuilder, BiFunction<T, Integer, BaseComponent> extraGetter) |  | ||||||
|     { |  | ||||||
|         T noneRetention = componentBuilder.apply( new ComponentBuilder( "Hello " ).color( RED ) |  | ||||||
|                 .append( "World", ComponentBuilder.FormatRetention.NONE ) ); |  | ||||||
|  |  | ||||||
|         assertEquals( RED, extraGetter.apply( noneRetention, 0 ).getColor() ); |  | ||||||
|         assertEquals( WHITE, extraGetter.apply( noneRetention, 1 ).getColor() ); |  | ||||||
|  |  | ||||||
|         HoverEvent testEvent = new HoverEvent( HoverEvent.Action.SHOW_TEXT, new Text( new ComponentBuilder( "test" ).build() ) ); |  | ||||||
|  |  | ||||||
|         T formattingRetention = componentBuilder.apply( new ComponentBuilder( "Hello " ).color( RED ) |  | ||||||
|                 .event( testEvent ).append( "World", ComponentBuilder.FormatRetention.FORMATTING ) ); |  | ||||||
|  |  | ||||||
|         assertEquals( RED, extraGetter.apply( formattingRetention, 0 ).getColor() ); |  | ||||||
|         assertEquals( testEvent, extraGetter.apply( formattingRetention, 0 ).getHoverEvent() ); |  | ||||||
|         assertEquals( RED, extraGetter.apply( formattingRetention, 1 ).getColor() ); |  | ||||||
|         assertNull( extraGetter.apply( formattingRetention, 1 ).getHoverEvent() ); |  | ||||||
|  |  | ||||||
|         ClickEvent testClickEvent = new ClickEvent( ClickEvent.Action.OPEN_URL, "http://www.example.com" ); |         ClickEvent testClickEvent = new ClickEvent( ClickEvent.Action.OPEN_URL, "http://www.example.com" ); | ||||||
|  |  | ||||||
|         T eventRetention = componentBuilder.apply( new ComponentBuilder( "Hello " ).color( RED ) |         BaseComponent[] eventRetention = new ComponentBuilder( "Hello " ).color( ChatColor.RED ) | ||||||
|                 .event( testEvent ).event( testClickEvent ).append( "World", ComponentBuilder.FormatRetention.EVENTS ) ); |                 .event( testEvent ).event( testClickEvent ).append( "World", ComponentBuilder.FormatRetention.EVENTS ).create(); | ||||||
|  |  | ||||||
|         assertEquals( RED, extraGetter.apply( eventRetention, 0 ).getColor() ); |         Assert.assertEquals( eventRetention[0].getColor(), ChatColor.RED ); | ||||||
|         assertEquals( testEvent, extraGetter.apply( eventRetention, 0 ).getHoverEvent() ); |         Assert.assertEquals( eventRetention[0].getHoverEvent(), testEvent ); | ||||||
|         assertEquals( testClickEvent, extraGetter.apply( eventRetention, 0 ).getClickEvent() ); |         Assert.assertEquals( eventRetention[0].getClickEvent(), testClickEvent ); | ||||||
|         assertEquals( WHITE, extraGetter.apply( eventRetention, 1 ).getColor() ); |         Assert.assertEquals( eventRetention[1].getColor(), ChatColor.WHITE ); | ||||||
|         assertEquals( testEvent, extraGetter.apply( eventRetention, 1 ).getHoverEvent() ); |         Assert.assertEquals( eventRetention[1].getHoverEvent(), testEvent ); | ||||||
|         assertEquals( testClickEvent, extraGetter.apply( eventRetention, 1 ).getClickEvent() ); |         Assert.assertEquals( eventRetention[1].getClickEvent(), testClickEvent ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test(expected = IllegalArgumentException.class) | ||||||
|     public void testLoopSimple() |     public void testLoopSimple() | ||||||
|     { |     { | ||||||
|         TextComponent component = new TextComponent( "Testing" ); |         TextComponent component = new TextComponent( "Testing" ); | ||||||
|         component.addExtra( component ); |         component.addExtra( component ); | ||||||
|         assertThrows( IllegalArgumentException.class, () -> ComponentSerializer.toString( component ) ); |         ComponentSerializer.toString( component ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test(expected = IllegalArgumentException.class) | ||||||
|     public void testLoopComplex() |     public void testLoopComplex() | ||||||
|     { |     { | ||||||
|         TextComponent a = new TextComponent( "A" ); |         TextComponent a = new TextComponent( "A" ); | ||||||
|         TextComponent b = new TextComponent( "B" ); |         TextComponent b = new TextComponent( "B" ); | ||||||
|         b.setColor( AQUA ); |         b.setColor( ChatColor.AQUA ); | ||||||
|         TextComponent c = new TextComponent( "C" ); |         TextComponent c = new TextComponent( "C" ); | ||||||
|         c.setColor( RED ); |         c.setColor( ChatColor.RED ); | ||||||
|         a.addExtra( b ); |         a.addExtra( b ); | ||||||
|         b.addExtra( c ); |         b.addExtra( c ); | ||||||
|         c.addExtra( a ); |         c.addExtra( a ); | ||||||
|         assertThrows( IllegalArgumentException.class, () -> ComponentSerializer.toString( a ) ); |         ComponentSerializer.toString( a ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
| @@ -700,25 +477,25 @@ public class ComponentsTest | |||||||
|     { |     { | ||||||
|         TextComponent a = new TextComponent( "A" ); |         TextComponent a = new TextComponent( "A" ); | ||||||
|         TextComponent b = new TextComponent( "B" ); |         TextComponent b = new TextComponent( "B" ); | ||||||
|         b.setColor( AQUA ); |         b.setColor( ChatColor.AQUA ); | ||||||
|         a.addExtra( b ); |         a.addExtra( b ); | ||||||
|         a.addExtra( b ); |         a.addExtra( b ); | ||||||
|         ComponentSerializer.toString( a ); |         ComponentSerializer.toString( a ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test(expected = IllegalArgumentException.class) | ||||||
|     public void testRepeatedError() |     public void testRepeatedError() | ||||||
|     { |     { | ||||||
|         TextComponent a = new TextComponent( "A" ); |         TextComponent a = new TextComponent( "A" ); | ||||||
|         TextComponent b = new TextComponent( "B" ); |         TextComponent b = new TextComponent( "B" ); | ||||||
|         b.setColor( AQUA ); |         b.setColor( ChatColor.AQUA ); | ||||||
|         TextComponent c = new TextComponent( "C" ); |         TextComponent c = new TextComponent( "C" ); | ||||||
|         c.setColor( RED ); |         c.setColor( ChatColor.RED ); | ||||||
|         a.addExtra( b ); |         a.addExtra( b ); | ||||||
|         a.addExtra( c ); |         a.addExtra( c ); | ||||||
|         c.addExtra( a ); |         c.addExtra( a ); | ||||||
|         a.addExtra( b ); |         a.addExtra( b ); | ||||||
|         assertThrows( IllegalArgumentException.class, () -> ComponentSerializer.toString( a ) ); |         ComponentSerializer.toString( a ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
| @@ -729,35 +506,35 @@ public class ComponentsTest | |||||||
|         // collect all invalid color codes (e.g. §z, §g, ...) |         // collect all invalid color codes (e.g. §z, §g, ...) | ||||||
|         for ( char alphChar : "0123456789abcdefghijklmnopqrstuvwxyz".toCharArray() ) |         for ( char alphChar : "0123456789abcdefghijklmnopqrstuvwxyz".toCharArray() ) | ||||||
|         { |         { | ||||||
|             if ( ALL_CODES.indexOf( alphChar ) == -1 ) |             if ( ChatColor.ALL_CODES.indexOf( alphChar ) == -1 ) | ||||||
|             { |             { | ||||||
|                 allInvalidColorCodes.append( COLOR_CHAR ); |                 allInvalidColorCodes.append( ChatColor.COLOR_CHAR ); | ||||||
|                 allInvalidColorCodes.append( alphChar ); |                 allInvalidColorCodes.append( alphChar ); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // last char is a single '§' |         // last char is a single '§' | ||||||
|         allInvalidColorCodes.append( COLOR_CHAR ); |         allInvalidColorCodes.append( ChatColor.COLOR_CHAR ); | ||||||
|  |  | ||||||
|         String invalidColorCodesLegacyText = fromAndToLegacyText( allInvalidColorCodes.toString() ); |         String invalidColorCodesLegacyText = fromAndToLegacyText( allInvalidColorCodes.toString() ); | ||||||
|         String emptyLegacyText = fromAndToLegacyText( "" ); |         String emptyLegacyText = fromAndToLegacyText( "" ); | ||||||
|  |  | ||||||
|         // all invalid color codes and the trailing '§' should be ignored |         // all invalid color codes and the trailing '§' should be ignored | ||||||
|         assertEquals( emptyLegacyText, invalidColorCodesLegacyText ); |         Assert.assertEquals( emptyLegacyText, invalidColorCodesLegacyText ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     public void testFormattingOnlyTextConversion() |     public void testFormattingOnlyTextConversion() | ||||||
|     { |     { | ||||||
|         String text = "" + GREEN; |         String text = "§a"; | ||||||
|  |  | ||||||
|         BaseComponent[] converted = TextComponent.fromLegacyText( text ); |         BaseComponent[] converted = TextComponent.fromLegacyText( text ); | ||||||
|         assertEquals( GREEN, converted[0].getColor() ); |         Assert.assertEquals( ChatColor.GREEN, converted[0].getColor() ); | ||||||
|  |  | ||||||
|         String roundtripLegacyText = BaseComponent.toLegacyText( converted ); |         String roundtripLegacyText = BaseComponent.toLegacyText( converted ); | ||||||
|  |  | ||||||
|         // color code should not be lost during conversion |         // color code should not be lost during conversion | ||||||
|         assertEquals( text, roundtripLegacyText ); |         Assert.assertEquals( text, roundtripLegacyText ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
| @@ -769,7 +546,7 @@ public class ComponentsTest | |||||||
|         TextComponent second = new TextComponent( "Hello, " ); |         TextComponent second = new TextComponent( "Hello, " ); | ||||||
|         second.addExtra( new TextComponent( "World!" ) ); |         second.addExtra( new TextComponent( "World!" ) ); | ||||||
|  |  | ||||||
|         assertEquals( first, second ); |         Assert.assertEquals( first, second ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
| @@ -781,90 +558,21 @@ public class ComponentsTest | |||||||
|         TextComponent second = new TextComponent( "Hello, " ); |         TextComponent second = new TextComponent( "Hello, " ); | ||||||
|         second.addExtra( new TextComponent( "World!" ) ); |         second.addExtra( new TextComponent( "World!" ) ); | ||||||
|  |  | ||||||
|         assertNotEquals( first, second ); |         Assert.assertNotEquals( first, second ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     public void testLegacyHack() |     public void testLegacyHack() | ||||||
|     { |     { | ||||||
|         BaseComponent[] hexColored = new ComponentBuilder().color( of( Color.GRAY ) ).append( "Test" ).create(); |         BaseComponent[] hexColored = new ComponentBuilder().color( ChatColor.of( Color.GRAY ) ).append( "Test" ).create(); | ||||||
|         String legacy = BaseComponent.toLegacyText( hexColored ); |         String legacy = TextComponent.toLegacyText( hexColored ); | ||||||
|  |  | ||||||
|         BaseComponent[] reColored = TextComponent.fromLegacyText( legacy ); |         BaseComponent[] reColored = TextComponent.fromLegacyText( legacy ); | ||||||
|  |  | ||||||
|         assertArrayEquals( hexColored, reColored ); |         Assert.assertArrayEquals( hexColored, reColored ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     private String fromAndToLegacyText(String legacyText) | ||||||
|     public void testLegacyResetInBuilderCreate() |  | ||||||
|     { |  | ||||||
|         testLegacyResetInBuilder( |  | ||||||
|                 ComponentBuilder::create, |  | ||||||
|                 ComponentSerializer::toString |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Test |  | ||||||
|     public void testLegacyResetInBuilderBuild() |  | ||||||
|     { |  | ||||||
|         testLegacyResetInBuilder( |  | ||||||
|                 ComponentBuilder::build, |  | ||||||
|                 ComponentSerializer::toString |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Test |  | ||||||
|     public void testHasFormatting() |  | ||||||
|     { |  | ||||||
|         BaseComponent component = new TextComponent(); |  | ||||||
|         assertFalse( component.hasFormatting() ); |  | ||||||
|  |  | ||||||
|         component.setBold( true ); |  | ||||||
|         assertTrue( component.hasFormatting() ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Test |  | ||||||
|     public void testStyleIsEmpty() |  | ||||||
|     { |  | ||||||
|         ComponentStyle style = ComponentStyle.builder().build(); |  | ||||||
|         assertTrue( style.isEmpty() ); |  | ||||||
|  |  | ||||||
|         style = ComponentStyle.builder() |  | ||||||
|                 .bold( true ) |  | ||||||
|                 .build(); |  | ||||||
|         assertFalse( style.isEmpty() ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /* |  | ||||||
|      * In legacy chat, colors and reset both reset all formatting. |  | ||||||
|      * Make sure it works in combination with ComponentBuilder. |  | ||||||
|      */ |  | ||||||
|     private static <T> void testLegacyResetInBuilder(Function<ComponentBuilder, T> componentBuilder, Function<T, String> componentSerializer) |  | ||||||
|     { |  | ||||||
|         ComponentBuilder builder = new ComponentBuilder(); |  | ||||||
|         BaseComponent[] a = TextComponent.fromLegacyText( "" + DARK_RED + UNDERLINE + "44444" + RESET + "dd" + GOLD + BOLD + "6666" ); |  | ||||||
|  |  | ||||||
|         String expected = "{\"extra\":[{\"underlined\":true,\"color\":\"dark_red\",\"text\":\"44444\"},{\"color\":" |  | ||||||
|                 + "\"white\",\"text\":\"dd\"},{\"bold\":true,\"color\":\"gold\",\"text\":\"6666\"}],\"text\":\"\"}"; |  | ||||||
|         assertEquals( expected, ComponentSerializer.toString( a ) ); |  | ||||||
|  |  | ||||||
|         builder.append( a ); |  | ||||||
|  |  | ||||||
|         String test1 = componentSerializer.apply( componentBuilder.apply( builder ) ); |  | ||||||
|         assertEquals( expected, test1 ); |  | ||||||
|  |  | ||||||
|         BaseComponent[] b = TextComponent.fromLegacyText( RESET + "rrrr" ); |  | ||||||
|         builder.append( b ); |  | ||||||
|  |  | ||||||
|         String test2 = componentSerializer.apply( componentBuilder.apply( builder ) ); |  | ||||||
|         assertEquals( |  | ||||||
|                 "{\"extra\":[{\"underlined\":true,\"color\":\"dark_red\",\"text\":\"44444\"}," |  | ||||||
|                 + "{\"color\":\"white\",\"text\":\"dd\"},{\"bold\":true,\"color\":\"gold\",\"text\":\"6666\"}," |  | ||||||
|                 + "{\"color\":\"white\",\"text\":\"rrrr\"}],\"text\":\"\"}", |  | ||||||
|                 test2 ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private static String fromAndToLegacyText(String legacyText) |  | ||||||
|     { |     { | ||||||
|         return BaseComponent.toLegacyText( TextComponent.fromLegacyText( legacyText ) ); |         return BaseComponent.toLegacyText( TextComponent.fromLegacyText( legacyText ) ); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,9 +1,8 @@ | |||||||
| package net.md_5.bungee.api.chat; | package net.md_5.bungee.api.chat; | ||||||
|  |  | ||||||
| import static net.md_5.bungee.api.ChatColor.*; |  | ||||||
| import static org.junit.jupiter.api.Assertions.*; |  | ||||||
| import net.md_5.bungee.chat.ComponentSerializer; | import net.md_5.bungee.chat.ComponentSerializer; | ||||||
| import org.junit.jupiter.api.Test; | import org.junit.Assert; | ||||||
|  | import org.junit.Test; | ||||||
|  |  | ||||||
| public class TranslatableComponentTest | public class TranslatableComponentTest | ||||||
| { | { | ||||||
| @@ -12,8 +11,8 @@ public class TranslatableComponentTest | |||||||
|     public void testMissingPlaceholdersAdded() |     public void testMissingPlaceholdersAdded() | ||||||
|     { |     { | ||||||
|         TranslatableComponent testComponent = new TranslatableComponent( "Test string with %s placeholders: %s", 2, "aoeu" ); |         TranslatableComponent testComponent = new TranslatableComponent( "Test string with %s placeholders: %s", 2, "aoeu" ); | ||||||
|         assertEquals( "Test string with 2 placeholders: aoeu", testComponent.toPlainText() ); |         Assert.assertEquals( "Test string with 2 placeholders: aoeu", testComponent.toPlainText() ); | ||||||
|         assertEquals( WHITE + "Test string with " + WHITE + "2" + WHITE + " placeholders: " + WHITE + "aoeu", testComponent.toLegacyText() ); |         Assert.assertEquals( "§fTest string with §f2§f placeholders: §faoeu", testComponent.toLegacyText() ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
| @@ -23,29 +22,7 @@ public class TranslatableComponentTest | |||||||
|         String jsonString = ComponentSerializer.toString( testComponent ); |         String jsonString = ComponentSerializer.toString( testComponent ); | ||||||
|         BaseComponent[] baseComponents = ComponentSerializer.parse( jsonString ); |         BaseComponent[] baseComponents = ComponentSerializer.parse( jsonString ); | ||||||
|  |  | ||||||
|         assertEquals( "Test string with a placeholder", BaseComponent.toPlainText( baseComponents ) ); |         Assert.assertEquals( "Test string with a placeholder", TextComponent.toPlainText( baseComponents ) ); | ||||||
|         assertEquals( WHITE + "Test string with " + WHITE + "a" + WHITE + " placeholder", BaseComponent.toLegacyText( baseComponents ) ); |         Assert.assertEquals( "§fTest string with §fa§f placeholder", TextComponent.toLegacyText( baseComponents ) ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |  | ||||||
|     public void testTranslateComponent() |  | ||||||
|     { |  | ||||||
|         TranslatableComponent item = new TranslatableComponent( "item.swordGold.name" ); |  | ||||||
|         item.setColor( AQUA ); |  | ||||||
|         TranslatableComponent translatableComponent = new TranslatableComponent( "commands.give.success", |  | ||||||
|                 item, "5", "thinkofdeath" ); |  | ||||||
|  |  | ||||||
|         assertEquals( "Given Golden Sword * 5 to thinkofdeath", translatableComponent.toPlainText() ); |  | ||||||
|         assertEquals( WHITE + "Given " + AQUA + "Golden Sword" + WHITE + " * " + WHITE + "5" + WHITE + " to " + WHITE + "thinkofdeath", |  | ||||||
|                 translatableComponent.toLegacyText() ); |  | ||||||
|  |  | ||||||
|         TranslatableComponent positional = new TranslatableComponent( "book.pageIndicator", "5", "50" ); |  | ||||||
|  |  | ||||||
|         assertEquals( "Page 5 of 50", positional.toPlainText() ); |  | ||||||
|         assertEquals( WHITE + "Page " + WHITE + "5" + WHITE + " of " + WHITE + "50", positional.toLegacyText() ); |  | ||||||
|  |  | ||||||
|         TranslatableComponent one_four_two = new TranslatableComponent( "filled_map.buried_treasure" ); |  | ||||||
|         assertEquals( "Buried Treasure Map", one_four_two.toPlainText() ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -33,9 +33,9 @@ | |||||||
|  |  | ||||||
|         <!-- See http://checkstyle.sourceforge.net/config_filters.html --> |         <!-- See http://checkstyle.sourceforge.net/config_filters.html --> | ||||||
|         <module name="SuppressionCommentFilter"/> |         <module name="SuppressionCommentFilter"/> | ||||||
|         <module name="SuppressWarningsHolder"/> |  | ||||||
|  |  | ||||||
|         <!-- See http://checkstyle.sourceforge.net/config_imports.html --> |         <!-- See http://checkstyle.sourceforge.net/config_imports.html --> | ||||||
|  |         <module name="AvoidStarImport"/> | ||||||
|         <module name="ImportOrder"> |         <module name="ImportOrder"> | ||||||
|             <property name="option" value="above"/> |             <property name="option" value="above"/> | ||||||
|             <property name="ordered" value="true"/> |             <property name="ordered" value="true"/> | ||||||
| @@ -54,11 +54,11 @@ | |||||||
|         <module name="OperatorWrap"/> |         <module name="OperatorWrap"/> | ||||||
|         <module name="ParenPad"> |         <module name="ParenPad"> | ||||||
|             <property name="option" value="nospace"/> |             <property name="option" value="nospace"/> | ||||||
|             <property name="tokens" value="ANNOTATION, CTOR_DEF, METHOD_DEF, LAMBDA"/> |             <property name="tokens" value="ANNOTATION, CTOR_DEF, METHOD_DEF"/> | ||||||
|         </module> |         </module> | ||||||
|         <module name="ParenPad"> |         <module name="ParenPad"> | ||||||
|             <property name="option" value="space"/> |             <property name="option" value="space"/> | ||||||
|             <property name="tokens" value="ANNOTATION_FIELD_DEF, CTOR_CALL, DOT, ENUM_CONSTANT_DEF, EXPR, LITERAL_CATCH, LITERAL_DO, LITERAL_FOR, LITERAL_IF, LITERAL_NEW, LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_WHILE, METHOD_CALL, QUESTION, RESOURCE_SPECIFICATION, SUPER_CTOR_CALL, RECORD_DEF"/> |             <property name="tokens" value="ANNOTATION_FIELD_DEF, CTOR_CALL, DOT, ENUM_CONSTANT_DEF, EXPR, LITERAL_CATCH, LITERAL_DO, LITERAL_FOR, LITERAL_IF, LITERAL_NEW, LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_WHILE, METHOD_CALL, QUESTION, RESOURCE_SPECIFICATION, SUPER_CTOR_CALL, LAMBDA"/> | ||||||
|         </module> |         </module> | ||||||
|         <module name="SingleSpaceSeparator"/> |         <module name="SingleSpaceSeparator"/> | ||||||
|         <module name="TypecastParenPad"/> |         <module name="TypecastParenPad"/> | ||||||
| @@ -84,6 +84,4 @@ | |||||||
|         <module name="Indentation"/> |         <module name="Indentation"/> | ||||||
|         <module name="UpperEll"/> |         <module name="UpperEll"/> | ||||||
|     </module> |     </module> | ||||||
|  |  | ||||||
|     <module name="SuppressWarningsFilter"/> |  | ||||||
| </module> | </module> | ||||||
|   | |||||||
| @@ -6,13 +6,13 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>net.md-5</groupId> |         <groupId>net.md-5</groupId> | ||||||
|         <artifactId>bungeecord-parent</artifactId> |         <artifactId>bungeecord-parent</artifactId> | ||||||
|         <version>1.20-R0.3-SNAPSHOT</version> |         <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|         <relativePath>../pom.xml</relativePath> |         <relativePath>../pom.xml</relativePath> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <groupId>net.md-5</groupId> |     <groupId>net.md-5</groupId> | ||||||
|     <artifactId>bungeecord-config</artifactId> |     <artifactId>bungeecord-config</artifactId> | ||||||
|     <version>1.20-R0.3-SNAPSHOT</version> |     <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|     <packaging>jar</packaging> |     <packaging>jar</packaging> | ||||||
|  |  | ||||||
|     <name>BungeeCord-Config</name> |     <name>BungeeCord-Config</name> | ||||||
| @@ -22,14 +22,14 @@ | |||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>com.google.code.gson</groupId> |             <groupId>com.google.code.gson</groupId> | ||||||
|             <artifactId>gson</artifactId> |             <artifactId>gson</artifactId> | ||||||
|             <version>2.10.1</version> |             <version>2.8.0</version> | ||||||
|             <scope>compile</scope> |             <scope>compile</scope> | ||||||
|             <optional>true</optional> |             <optional>true</optional> | ||||||
|         </dependency> |         </dependency> | ||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>org.yaml</groupId> |             <groupId>org.yaml</groupId> | ||||||
|             <artifactId>snakeyaml</artifactId> |             <artifactId>snakeyaml</artifactId> | ||||||
|             <version>2.2</version> |             <version>1.26</version> | ||||||
|             <scope>compile</scope> |             <scope>compile</scope> | ||||||
|             <optional>true</optional> |             <optional>true</optional> | ||||||
|         </dependency> |         </dependency> | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -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,13 +9,11 @@ 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; | ||||||
| import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||||
| import org.yaml.snakeyaml.DumperOptions; | import org.yaml.snakeyaml.DumperOptions; | ||||||
| import org.yaml.snakeyaml.LoaderOptions; |  | ||||||
| import org.yaml.snakeyaml.Yaml; | import org.yaml.snakeyaml.Yaml; | ||||||
| import org.yaml.snakeyaml.constructor.Constructor; | import org.yaml.snakeyaml.constructor.Constructor; | ||||||
| import org.yaml.snakeyaml.nodes.Node; | import org.yaml.snakeyaml.nodes.Node; | ||||||
| @@ -30,10 +29,7 @@ public class YamlConfiguration extends ConfigurationProvider | |||||||
|         @Override |         @Override | ||||||
|         protected Yaml initialValue() |         protected Yaml initialValue() | ||||||
|         { |         { | ||||||
|             DumperOptions options = new DumperOptions(); |             Representer representer = new Representer() | ||||||
|             options.setDefaultFlowStyle( DumperOptions.FlowStyle.BLOCK ); |  | ||||||
|  |  | ||||||
|             Representer representer = new Representer( options ) |  | ||||||
|             { |             { | ||||||
|                 { |                 { | ||||||
|                     representers.put( Configuration.class, new Represent() |                     representers.put( Configuration.class, new Represent() | ||||||
| @@ -47,14 +43,17 @@ public class YamlConfiguration extends ConfigurationProvider | |||||||
|                 } |                 } | ||||||
|             }; |             }; | ||||||
|  |  | ||||||
|             return new Yaml( new Constructor( new LoaderOptions() ), representer, options ); |             DumperOptions options = new DumperOptions(); | ||||||
|  |             options.setDefaultFlowStyle( DumperOptions.FlowStyle.BLOCK ); | ||||||
|  |  | ||||||
|  |             return new Yaml( new Constructor(), representer, options ); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     @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 ); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -1,25 +1,30 @@ | |||||||
| package net.md_5.bungee.config; | package net.md_5.bungee.config; | ||||||
|  |  | ||||||
| import static org.junit.jupiter.api.Assertions.*; |  | ||||||
| import java.io.StringReader; | import java.io.StringReader; | ||||||
| import java.io.StringWriter; | import java.io.StringWriter; | ||||||
|  | import java.util.Arrays; | ||||||
| import java.util.Collections; | import java.util.Collections; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| import java.util.stream.Stream; |  | ||||||
| import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||||
| import org.junit.jupiter.params.ParameterizedTest; | import org.junit.Assert; | ||||||
| import org.junit.jupiter.params.provider.Arguments; | import org.junit.Test; | ||||||
| import org.junit.jupiter.params.provider.MethodSource; | import org.junit.runner.RunWith; | ||||||
|  | import org.junit.runners.Parameterized; | ||||||
|  | import org.junit.runners.Parameterized.Parameters; | ||||||
|  |  | ||||||
| @RequiredArgsConstructor | @RequiredArgsConstructor | ||||||
|  | @RunWith(Parameterized.class) | ||||||
| public class CompoundConfigurationTest | public class CompoundConfigurationTest | ||||||
| { | { | ||||||
|  |  | ||||||
|     public static Stream<Arguments> data() |     @Parameters(name = "{0}") | ||||||
|  |     public static Iterable<Object[]> data() | ||||||
|  |     { | ||||||
|  |         // CHECKSTYLE:OFF | ||||||
|  |         return Arrays.asList( new Object[][] | ||||||
|  |         { | ||||||
|             { |             { | ||||||
|         return Stream.of( |  | ||||||
|                 Arguments.of( |  | ||||||
|                 // provider |                 // provider | ||||||
|                 YamlConfiguration.class, |                 YamlConfiguration.class, | ||||||
|                 // testDocument |                 // testDocument | ||||||
| @@ -68,8 +73,8 @@ public class CompoundConfigurationTest | |||||||
|                 + "null:\n" |                 + "null:\n" | ||||||
|                 + "    null: object\n" |                 + "    null: object\n" | ||||||
|                 + "    object: null\n" |                 + "    object: null\n" | ||||||
|                 ), |             }, | ||||||
|                 Arguments.of( |             { | ||||||
|                 // provider |                 // provider | ||||||
|                 JsonConfiguration.class, |                 JsonConfiguration.class, | ||||||
|                 // testDocument |                 // testDocument | ||||||
| @@ -126,13 +131,18 @@ public class CompoundConfigurationTest | |||||||
|                 + "    \"object\": null\n" |                 + "    \"object\": null\n" | ||||||
|                 + "  }\n" |                 + "  }\n" | ||||||
|                 + "}" |                 + "}" | ||||||
|                 ) |  | ||||||
|         ); |  | ||||||
|             } |             } | ||||||
|  |         } ); | ||||||
|  |         // CHECKSTYLE:ON | ||||||
|  |     } | ||||||
|  |     // | ||||||
|  |     private final Class<? extends ConfigurationProvider> provider; | ||||||
|  |     private final String testDocument; | ||||||
|  |     private final String numberTest; | ||||||
|  |     private final String nullTest; | ||||||
|  |  | ||||||
|     @ParameterizedTest |     @Test | ||||||
|     @MethodSource("data") |     public void testConfig() throws Exception | ||||||
|     public void testConfig(Class<? extends ConfigurationProvider> provider, String testDocument, String numberTest, String nullTest) throws Exception |  | ||||||
|     { |     { | ||||||
|         Configuration conf = ConfigurationProvider.getProvider( provider ).load( testDocument ); |         Configuration conf = ConfigurationProvider.getProvider( provider ).load( testDocument ); | ||||||
|         testSection( conf ); |         testSection( conf ); | ||||||
| @@ -141,7 +151,7 @@ public class CompoundConfigurationTest | |||||||
|         ConfigurationProvider.getProvider( provider ).save( conf, sw ); |         ConfigurationProvider.getProvider( provider ).save( conf, sw ); | ||||||
|  |  | ||||||
|         // Check nulls were saved, see #1094 |         // Check nulls were saved, see #1094 | ||||||
|         assertFalse( sw.toString().contains( "null" ), "Config contains null" ); |         Assert.assertFalse( "Config contains null", sw.toString().contains( "null" ) ); | ||||||
|  |  | ||||||
|         conf = ConfigurationProvider.getProvider( provider ).load( new StringReader( sw.toString() ) ); |         conf = ConfigurationProvider.getProvider( provider ).load( new StringReader( sw.toString() ) ); | ||||||
|         conf.set( "receipt", "Oz-Ware Purchase Invoice" ); // Add it back |         conf.set( "receipt", "Oz-Ware Purchase Invoice" ); // Add it back | ||||||
| @@ -150,38 +160,37 @@ public class CompoundConfigurationTest | |||||||
|  |  | ||||||
|     private void testSection(Configuration conf) |     private void testSection(Configuration conf) | ||||||
|     { |     { | ||||||
|         assertEquals( "Oz-Ware Purchase Invoice", conf.getString( "receipt" ), "receipt" ); |         Assert.assertEquals( "receipt", "Oz-Ware Purchase Invoice", conf.getString( "receipt" ) ); | ||||||
|         // assertEquals( "2012-08-06", conf.get( "date" ).toString(), "date" ); |         // Assert.assertEquals( "date", "2012-08-06", conf.get( "date" ).toString() ); | ||||||
|  |  | ||||||
|         Configuration customer = conf.getSection( "customer" ); |         Configuration customer = conf.getSection( "customer" ); | ||||||
|         assertEquals( "Dorothy", customer.getString( "given" ), "customer.given" ); |         Assert.assertEquals( "customer.given", "Dorothy", customer.getString( "given" ) ); | ||||||
|         assertEquals( "Dorothy", conf.getString( "customer.given" ), "customer.given" ); |         Assert.assertEquals( "customer.given", "Dorothy", conf.getString( "customer.given" ) ); | ||||||
|  |  | ||||||
|         List items = conf.getList( "items" ); |         List items = conf.getList( "items" ); | ||||||
|         Map item = (Map) items.get( 0 ); |         Map item = (Map) items.get( 0 ); | ||||||
|         assertEquals( "A4786", item.get( "part_no" ), "items[0].part_no" ); |         Assert.assertEquals( "items[0].part_no", "A4786", item.get( "part_no" ) ); | ||||||
|  |  | ||||||
|         conf.set( "receipt", null ); |         conf.set( "receipt", null ); | ||||||
|         assertEquals( null, conf.get( "receipt" ) ); |         Assert.assertEquals( null, conf.get( "receipt" ) ); | ||||||
|         assertEquals( "foo", conf.get( "receipt", "foo" ) ); |         Assert.assertEquals( "foo", conf.get( "receipt", "foo" ) ); | ||||||
|  |  | ||||||
|         Configuration newSection = conf.getSection( "new.section" ); |         Configuration newSection = conf.getSection( "new.section" ); | ||||||
|         newSection.set( "value", "foo" ); |         newSection.set( "value", "foo" ); | ||||||
|         assertEquals( "foo", conf.get( "new.section.value" ) ); |         Assert.assertEquals( "foo", conf.get( "new.section.value" ) ); | ||||||
|  |  | ||||||
|         conf.set( "other.new.section", "bar" ); |         conf.set( "other.new.section", "bar" ); | ||||||
|         assertEquals( "bar", conf.get( "other.new.section" ) ); |         Assert.assertEquals( "bar", conf.get( "other.new.section" ) ); | ||||||
|  |  | ||||||
|         assertTrue( conf.contains( "customer.given" ) ); |         Assert.assertTrue( conf.contains( "customer.given" ) ); | ||||||
|         assertTrue( customer.contains( "given" ) ); |         Assert.assertTrue( customer.contains( "given" ) ); | ||||||
|  |  | ||||||
|         assertFalse( conf.contains( "customer.foo" ) ); |         Assert.assertFalse( conf.contains( "customer.foo" ) ); | ||||||
|         assertFalse( customer.contains( "foo" ) ); |         Assert.assertFalse( customer.contains( "foo" ) ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @ParameterizedTest |     @Test | ||||||
|     @MethodSource("data") |     public void testNumberedKeys() | ||||||
|     public void testNumberedKeys(Class<? extends ConfigurationProvider> provider, String testDocument, String numberTest, String nullTest) |  | ||||||
|     { |     { | ||||||
|         Configuration conf = ConfigurationProvider.getProvider( provider ).load( numberTest ); |         Configuration conf = ConfigurationProvider.getProvider( provider ).load( numberTest ); | ||||||
|  |  | ||||||
| @@ -192,31 +201,29 @@ public class CompoundConfigurationTest | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @ParameterizedTest |     @Test | ||||||
|     @MethodSource("data") |     public void testNull() | ||||||
|     public void testNull(Class<? extends ConfigurationProvider> provider, String testDocument, String numberTest, String nullTest) |  | ||||||
|     { |     { | ||||||
|         Configuration conf = ConfigurationProvider.getProvider( provider ).load( nullTest ); |         Configuration conf = ConfigurationProvider.getProvider( provider ).load( nullTest ); | ||||||
|  |  | ||||||
|         assertEquals( "object", conf.get( "null.null" ) ); |         Assert.assertEquals( "object", conf.get( "null.null" ) ); | ||||||
|         assertEquals( "object", conf.getSection( "null" ).get( "null" ) ); |         Assert.assertEquals( "object", conf.getSection( "null" ).get( "null" ) ); | ||||||
|  |  | ||||||
|         assertEquals( null, conf.get( "null.object" ) ); |         Assert.assertEquals( null, conf.get( "null.object" ) ); | ||||||
|         assertEquals( "", conf.getString( "null.object" ) ); |         Assert.assertEquals( "", conf.getString( "null.object" ) ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @ParameterizedTest |     @Test | ||||||
|     @MethodSource("data") |     public void testMapAddition() | ||||||
|     public void testMapAddition(Class<? extends ConfigurationProvider> provider, String testDocument, String numberTest, String nullTest) |  | ||||||
|     { |     { | ||||||
|         Configuration conf = ConfigurationProvider.getProvider( provider ).load( testDocument ); |         Configuration conf = ConfigurationProvider.getProvider( provider ).load( testDocument ); | ||||||
|  |  | ||||||
|         conf.set( "addition", Collections.singletonMap( "foo", "bar" ) ); |         conf.set( "addition", Collections.singletonMap( "foo", "bar" ) ); | ||||||
|  |  | ||||||
|         // Order matters |         // Order matters | ||||||
|         assertEquals( "bar", conf.getSection( "addition" ).getString( "foo" ) ); |         Assert.assertEquals( "bar", conf.getSection( "addition" ).getString( "foo" ) ); | ||||||
|         assertEquals( "bar", conf.getString( "addition.foo" ) ); |         Assert.assertEquals( "bar", conf.getString( "addition.foo" ) ); | ||||||
|  |  | ||||||
|         assertTrue( conf.get( "addition" ) instanceof Configuration ); |         Assert.assertTrue( conf.get( "addition" ) instanceof Configuration ); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| package net.md_5.bungee.config; | package net.md_5.bungee.config; | ||||||
|  |  | ||||||
| import static org.junit.jupiter.api.Assertions.*; | import org.junit.Assert; | ||||||
| import org.junit.jupiter.api.Test; | import org.junit.Test; | ||||||
|  |  | ||||||
| public class DefaultConfigurationTest | public class DefaultConfigurationTest | ||||||
| { | { | ||||||
| @@ -16,8 +16,8 @@ public class DefaultConfigurationTest | |||||||
|  |  | ||||||
|         Configuration actualConfig = new Configuration( defaultConfig ); |         Configuration actualConfig = new Configuration( defaultConfig ); | ||||||
|  |  | ||||||
|         assertEquals( 10, actualConfig.getInt( "setting" ) ); |         Assert.assertEquals( 10, actualConfig.getInt( "setting" ) ); | ||||||
|         assertEquals( 11, actualConfig.getInt( "nested.setting" ) ); |         Assert.assertEquals( 11, actualConfig.getInt( "nested.setting" ) ); | ||||||
|         assertEquals( 12, actualConfig.getInt( "double.nested.setting" ) ); |         Assert.assertEquals( 12, actualConfig.getInt( "double.nested.setting" ) ); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -6,13 +6,13 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>net.md-5</groupId> |         <groupId>net.md-5</groupId> | ||||||
|         <artifactId>bungeecord-parent</artifactId> |         <artifactId>bungeecord-parent</artifactId> | ||||||
|         <version>1.20-R0.3-SNAPSHOT</version> |         <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|         <relativePath>../pom.xml</relativePath> |         <relativePath>../pom.xml</relativePath> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <groupId>net.md-5</groupId> |     <groupId>net.md-5</groupId> | ||||||
|     <artifactId>bungeecord-event</artifactId> |     <artifactId>bungeecord-event</artifactId> | ||||||
|     <version>1.20-R0.3-SNAPSHOT</version> |     <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|     <packaging>jar</packaging> |     <packaging>jar</packaging> | ||||||
|  |  | ||||||
|     <name>BungeeCord-Event</name> |     <name>BungeeCord-Event</name> | ||||||
|   | |||||||
| @@ -1,6 +1,5 @@ | |||||||
| package net.md_5.bungee.event; | package net.md_5.bungee.event; | ||||||
|  |  | ||||||
| import com.google.common.collect.ImmutableSet; |  | ||||||
| import java.lang.reflect.InvocationTargetException; | import java.lang.reflect.InvocationTargetException; | ||||||
| import java.lang.reflect.Method; | import java.lang.reflect.Method; | ||||||
| import java.text.MessageFormat; | import java.text.MessageFormat; | ||||||
| @@ -42,8 +41,6 @@ public class EventBus | |||||||
|         { |         { | ||||||
|             for ( EventHandlerMethod method : handlers ) |             for ( EventHandlerMethod method : handlers ) | ||||||
|             { |             { | ||||||
|                 long start = System.nanoTime(); |  | ||||||
|  |  | ||||||
|                 try |                 try | ||||||
|                 { |                 { | ||||||
|                     method.invoke( event ); |                     method.invoke( event ); | ||||||
| @@ -57,15 +54,6 @@ public class EventBus | |||||||
|                 { |                 { | ||||||
|                     logger.log( Level.WARNING, MessageFormat.format( "Error dispatching event {0} to listener {1}", event, method.getListener() ), ex.getCause() ); |                     logger.log( Level.WARNING, MessageFormat.format( "Error dispatching event {0} to listener {1}", event, method.getListener() ), ex.getCause() ); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 long elapsed = System.nanoTime() - start; |  | ||||||
|                 if ( elapsed > 50000000 ) |  | ||||||
|                 { |  | ||||||
|                     logger.log( Level.WARNING, "Plugin listener {0} took {1}ms to process event {2}!", new Object[] |  | ||||||
|                     { |  | ||||||
|                         method.getListener().getClass().getName(), elapsed / 1000000, event |  | ||||||
|                     } ); |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -73,8 +61,7 @@ public class EventBus | |||||||
|     private Map<Class<?>, Map<Byte, Set<Method>>> findHandlers(Object listener) |     private Map<Class<?>, Map<Byte, Set<Method>>> findHandlers(Object listener) | ||||||
|     { |     { | ||||||
|         Map<Class<?>, Map<Byte, Set<Method>>> handler = new HashMap<>(); |         Map<Class<?>, Map<Byte, Set<Method>>> handler = new HashMap<>(); | ||||||
|         Set<Method> methods = ImmutableSet.<Method>builder().add( listener.getClass().getMethods() ).add( listener.getClass().getDeclaredMethods() ).build(); |         for ( Method m : listener.getClass().getDeclaredMethods() ) | ||||||
|         for ( final Method m : methods ) |  | ||||||
|         { |         { | ||||||
|             EventHandler annotation = m.getAnnotation( EventHandler.class ); |             EventHandler annotation = m.getAnnotation( EventHandler.class ); | ||||||
|             if ( annotation != null ) |             if ( annotation != null ) | ||||||
| @@ -88,8 +75,18 @@ public class EventBus | |||||||
|                     } ); |                     } ); | ||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
|                 Map<Byte, Set<Method>> prioritiesMap = handler.computeIfAbsent( params[0], k -> new HashMap<>() ); |                 Map<Byte, Set<Method>> prioritiesMap = handler.get( params[0] ); | ||||||
|                 Set<Method> priority = prioritiesMap.computeIfAbsent( annotation.priority(), k -> new HashSet<>() ); |                 if ( prioritiesMap == null ) | ||||||
|  |                 { | ||||||
|  |                     prioritiesMap = new HashMap<>(); | ||||||
|  |                     handler.put( params[0], prioritiesMap ); | ||||||
|  |                 } | ||||||
|  |                 Set<Method> priority = prioritiesMap.get( annotation.priority() ); | ||||||
|  |                 if ( priority == null ) | ||||||
|  |                 { | ||||||
|  |                     priority = new HashSet<>(); | ||||||
|  |                     prioritiesMap.put( annotation.priority(), priority ); | ||||||
|  |                 } | ||||||
|                 priority.add( m ); |                 priority.add( m ); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @@ -104,11 +101,22 @@ public class EventBus | |||||||
|         { |         { | ||||||
|             for ( Map.Entry<Class<?>, Map<Byte, Set<Method>>> e : handler.entrySet() ) |             for ( Map.Entry<Class<?>, Map<Byte, Set<Method>>> e : handler.entrySet() ) | ||||||
|             { |             { | ||||||
|                 Map<Byte, Map<Object, Method[]>> prioritiesMap = byListenerAndPriority.computeIfAbsent( e.getKey(), k -> new HashMap<>() ); |                 Map<Byte, Map<Object, Method[]>> prioritiesMap = byListenerAndPriority.get( e.getKey() ); | ||||||
|  |                 if ( prioritiesMap == null ) | ||||||
|  |                 { | ||||||
|  |                     prioritiesMap = new HashMap<>(); | ||||||
|  |                     byListenerAndPriority.put( e.getKey(), prioritiesMap ); | ||||||
|  |                 } | ||||||
|                 for ( Map.Entry<Byte, Set<Method>> entry : e.getValue().entrySet() ) |                 for ( Map.Entry<Byte, Set<Method>> entry : e.getValue().entrySet() ) | ||||||
|                 { |                 { | ||||||
|                     Map<Object, Method[]> currentPriorityMap = prioritiesMap.computeIfAbsent( entry.getKey(), k -> new HashMap<>() ); |                     Map<Object, Method[]> currentPriorityMap = prioritiesMap.get( entry.getKey() ); | ||||||
|                     currentPriorityMap.put( listener, entry.getValue().toArray( new Method[ 0 ] ) ); |                     if ( currentPriorityMap == null ) | ||||||
|  |                     { | ||||||
|  |                         currentPriorityMap = new HashMap<>(); | ||||||
|  |                         prioritiesMap.put( entry.getKey(), currentPriorityMap ); | ||||||
|  |                     } | ||||||
|  |                     Method[] baked = new Method[ entry.getValue().size() ]; | ||||||
|  |                     currentPriorityMap.put( listener, entry.getValue().toArray( baked ) ); | ||||||
|                 } |                 } | ||||||
|                 bakeHandlers( e.getKey() ); |                 bakeHandlers( e.getKey() ); | ||||||
|             } |             } | ||||||
| @@ -186,7 +194,7 @@ public class EventBus | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } while ( value++ < Byte.MAX_VALUE ); |             } while ( value++ < Byte.MAX_VALUE ); | ||||||
|             byEventBaked.put( eventClass, handlersList.toArray( new EventHandlerMethod[ 0 ] ) ); |             byEventBaked.put( eventClass, handlersList.toArray( new EventHandlerMethod[ handlersList.size() ] ) ); | ||||||
|         } else |         } else | ||||||
|         { |         { | ||||||
|             byEventBaked.remove( eventClass ); |             byEventBaked.remove( eventClass ); | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| package net.md_5.bungee.event; | package net.md_5.bungee.event; | ||||||
|  |  | ||||||
| import static org.junit.jupiter.api.Assertions.*; |  | ||||||
| import java.util.concurrent.CountDownLatch; | import java.util.concurrent.CountDownLatch; | ||||||
| import org.junit.jupiter.api.Test; | import org.junit.Assert; | ||||||
|  | import org.junit.Test; | ||||||
|  |  | ||||||
| public class EventBusTest | public class EventBusTest | ||||||
| { | { | ||||||
| @@ -15,14 +15,14 @@ public class EventBusTest | |||||||
|     { |     { | ||||||
|         bus.register( this ); |         bus.register( this ); | ||||||
|         bus.post( new FirstEvent() ); |         bus.post( new FirstEvent() ); | ||||||
|         assertEquals( 0, latch.getCount() ); |         Assert.assertEquals( 0, latch.getCount() ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @EventHandler |     @EventHandler | ||||||
|     public void firstListener(FirstEvent event) |     public void firstListener(FirstEvent event) | ||||||
|     { |     { | ||||||
|         bus.post( new SecondEvent() ); |         bus.post( new SecondEvent() ); | ||||||
|         assertEquals( 1, latch.getCount() ); |         Assert.assertEquals( 1, latch.getCount() ); | ||||||
|         latch.countDown(); |         latch.countDown(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| package net.md_5.bungee.event; | package net.md_5.bungee.event; | ||||||
|  |  | ||||||
| import static org.junit.jupiter.api.Assertions.*; |  | ||||||
| import java.util.concurrent.CountDownLatch; | import java.util.concurrent.CountDownLatch; | ||||||
| import org.junit.jupiter.api.Test; | import org.junit.Assert; | ||||||
|  | import org.junit.Test; | ||||||
|  |  | ||||||
| public class EventPriorityTest | public class EventPriorityTest | ||||||
| { | { | ||||||
| @@ -16,41 +16,41 @@ public class EventPriorityTest | |||||||
|         bus.register( this ); |         bus.register( this ); | ||||||
|         bus.register( new EventPriorityListenerPartner() ); |         bus.register( new EventPriorityListenerPartner() ); | ||||||
|         bus.post( new PriorityTestEvent() ); |         bus.post( new PriorityTestEvent() ); | ||||||
|         assertEquals( 0, latch.getCount() ); |         Assert.assertEquals( 0, latch.getCount() ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @EventHandler(priority = Byte.MIN_VALUE) |     @EventHandler(priority = Byte.MIN_VALUE) | ||||||
|     public void onMinPriority(PriorityTestEvent event) |     public void onMinPriority(PriorityTestEvent event) | ||||||
|     { |     { | ||||||
|         assertEquals( 7, latch.getCount() ); |         Assert.assertEquals( 7, latch.getCount() ); | ||||||
|         latch.countDown(); |         latch.countDown(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @EventHandler(priority = EventPriority.LOWEST) |     @EventHandler(priority = EventPriority.LOWEST) | ||||||
|     public void onLowestPriority(PriorityTestEvent event) |     public void onLowestPriority(PriorityTestEvent event) | ||||||
|     { |     { | ||||||
|         assertEquals( 6, latch.getCount() ); |         Assert.assertEquals( 6, latch.getCount() ); | ||||||
|         latch.countDown(); |         latch.countDown(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @EventHandler |     @EventHandler | ||||||
|     public void onNormalPriority(PriorityTestEvent event) |     public void onNormalPriority(PriorityTestEvent event) | ||||||
|     { |     { | ||||||
|         assertEquals( 4, latch.getCount() ); |         Assert.assertEquals( 4, latch.getCount() ); | ||||||
|         latch.countDown(); |         latch.countDown(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @EventHandler(priority = EventPriority.HIGHEST) |     @EventHandler(priority = EventPriority.HIGHEST) | ||||||
|     public void onHighestPriority(PriorityTestEvent event) |     public void onHighestPriority(PriorityTestEvent event) | ||||||
|     { |     { | ||||||
|         assertEquals( 2, latch.getCount() ); |         Assert.assertEquals( 2, latch.getCount() ); | ||||||
|         latch.countDown(); |         latch.countDown(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @EventHandler(priority = Byte.MAX_VALUE) |     @EventHandler(priority = Byte.MAX_VALUE) | ||||||
|     public void onMaxPriority(PriorityTestEvent event) |     public void onMaxPriority(PriorityTestEvent event) | ||||||
|     { |     { | ||||||
|         assertEquals( 1, latch.getCount() ); |         Assert.assertEquals( 1, latch.getCount() ); | ||||||
|         latch.countDown(); |         latch.countDown(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -64,14 +64,14 @@ public class EventPriorityTest | |||||||
|         @EventHandler(priority = EventPriority.HIGH) |         @EventHandler(priority = EventPriority.HIGH) | ||||||
|         public void onHighPriority(PriorityTestEvent event) |         public void onHighPriority(PriorityTestEvent event) | ||||||
|         { |         { | ||||||
|             assertEquals( 3, latch.getCount() ); |             Assert.assertEquals( 3, latch.getCount() ); | ||||||
|             latch.countDown(); |             latch.countDown(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         @EventHandler(priority = EventPriority.LOW) |         @EventHandler(priority = EventPriority.LOW) | ||||||
|         public void onLowPriority(PriorityTestEvent event) |         public void onLowPriority(PriorityTestEvent event) | ||||||
|         { |         { | ||||||
|             assertEquals( 5, latch.getCount() ); |             Assert.assertEquals( 5, latch.getCount() ); | ||||||
|             latch.countDown(); |             latch.countDown(); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,26 +0,0 @@ | |||||||
| package net.md_5.bungee.event; |  | ||||||
|  |  | ||||||
| import static org.junit.jupiter.api.Assertions.*; |  | ||||||
| import java.util.concurrent.CountDownLatch; |  | ||||||
| import org.junit.jupiter.api.Test; |  | ||||||
|  |  | ||||||
| public class SubclassTest extends EventBusTest |  | ||||||
| { |  | ||||||
|  |  | ||||||
|     private final CountDownLatch latch = new CountDownLatch( 1 ); |  | ||||||
|  |  | ||||||
|     @Test |  | ||||||
|     @Override |  | ||||||
|     public void testNestedEvents() |  | ||||||
|     { |  | ||||||
|         super.testNestedEvents(); |  | ||||||
|         assertEquals( 0, latch.getCount() ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @EventHandler |  | ||||||
|     protected void extraListener(FirstEvent event) |  | ||||||
|     { |  | ||||||
|         assertEquals( 1, latch.getCount() ); |  | ||||||
|         latch.countDown(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,7 +1,7 @@ | |||||||
| package net.md_5.bungee.event; | package net.md_5.bungee.event; | ||||||
|  |  | ||||||
| import static org.junit.jupiter.api.Assertions.fail; | import org.junit.Assert; | ||||||
| import org.junit.jupiter.api.Test; | import org.junit.Test; | ||||||
|  |  | ||||||
| public class UnregisteringListenerTest | public class UnregisteringListenerTest | ||||||
| { | { | ||||||
| @@ -19,7 +19,7 @@ public class UnregisteringListenerTest | |||||||
|     @EventHandler |     @EventHandler | ||||||
|     public void onEvent(TestEvent evt) |     public void onEvent(TestEvent evt) | ||||||
|     { |     { | ||||||
|         fail( "Event listener wasn't unregistered" ); |         Assert.fail( "Event listener wasn't unregistered" ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static class TestEvent |     public static class TestEvent | ||||||
|   | |||||||
| @@ -6,13 +6,13 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>net.md-5</groupId> |         <groupId>net.md-5</groupId> | ||||||
|         <artifactId>bungeecord-parent</artifactId> |         <artifactId>bungeecord-parent</artifactId> | ||||||
|         <version>1.20-R0.3-SNAPSHOT</version> |         <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|         <relativePath>../pom.xml</relativePath> |         <relativePath>../pom.xml</relativePath> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <groupId>net.md-5</groupId> |     <groupId>net.md-5</groupId> | ||||||
|     <artifactId>bungeecord-log</artifactId> |     <artifactId>bungeecord-log</artifactId> | ||||||
|     <version>1.20-R0.3-SNAPSHOT</version> |     <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|     <packaging>jar</packaging> |     <packaging>jar</packaging> | ||||||
|  |  | ||||||
|     <name>BungeeCord-Log</name> |     <name>BungeeCord-Log</name> | ||||||
|   | |||||||
| @@ -13,23 +13,19 @@ public class BungeeLogger extends Logger | |||||||
|  |  | ||||||
|     private final LogDispatcher dispatcher = new LogDispatcher( this ); |     private final LogDispatcher dispatcher = new LogDispatcher( this ); | ||||||
|  |  | ||||||
|     // CHECKSTYLE:OFF |  | ||||||
|     @SuppressWarnings( |     @SuppressWarnings( | ||||||
|             { |             { | ||||||
|                 "CallToPrintStackTrace", "CallToThreadStartDuringObjectConstruction" |                 "CallToPrintStackTrace", "CallToThreadStartDuringObjectConstruction" | ||||||
|             }) |             }) | ||||||
|     // CHECKSTYLE:ON |  | ||||||
|     @SuppressFBWarnings("SC_START_IN_CTOR") |     @SuppressFBWarnings("SC_START_IN_CTOR") | ||||||
|     public BungeeLogger(String loggerName, String filePattern, ConsoleReader reader) |     public BungeeLogger(String loggerName, String filePattern, ConsoleReader reader) | ||||||
|     { |     { | ||||||
|         super( loggerName, null ); |         super( loggerName, null ); | ||||||
|         setLevel( Level.ALL ); |         setLevel( Level.ALL ); | ||||||
|         setUseParentHandlers( false ); |  | ||||||
|  |  | ||||||
|         try |         try | ||||||
|         { |         { | ||||||
|             FileHandler fileHandler = new FileHandler( filePattern, 1 << 24, 8, true ); |             FileHandler fileHandler = new FileHandler( filePattern, 1 << 24, 8, true ); | ||||||
|             fileHandler.setLevel( Level.parse( System.getProperty( "net.md_5.bungee.file-log-level", "INFO" ) ) ); |  | ||||||
|             fileHandler.setFormatter( new ConciseFormatter( false ) ); |             fileHandler.setFormatter( new ConciseFormatter( false ) ); | ||||||
|             addHandler( fileHandler ); |             addHandler( fileHandler ); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,29 +0,0 @@ | |||||||
| package net.md_5.bungee.log; |  | ||||||
|  |  | ||||||
| import java.util.logging.Handler; |  | ||||||
| import java.util.logging.LogRecord; |  | ||||||
| import java.util.logging.Logger; |  | ||||||
| import lombok.RequiredArgsConstructor; |  | ||||||
|  |  | ||||||
| @RequiredArgsConstructor |  | ||||||
| public class LoggingForwardHandler extends Handler |  | ||||||
| { |  | ||||||
|  |  | ||||||
|     private final Logger logger; |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void publish(LogRecord record) |  | ||||||
|     { |  | ||||||
|         logger.log( record ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void flush() |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void close() throws SecurityException |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -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 ) ) | ||||||
|         { |         { | ||||||
|   | |||||||
| @@ -6,13 +6,13 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>net.md-5</groupId> |         <groupId>net.md-5</groupId> | ||||||
|         <artifactId>bungeecord-module</artifactId> |         <artifactId>bungeecord-module</artifactId> | ||||||
|         <version>1.20-R0.3-SNAPSHOT</version> |         <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|         <relativePath>../pom.xml</relativePath> |         <relativePath>../pom.xml</relativePath> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <groupId>net.md-5</groupId> |     <groupId>net.md-5</groupId> | ||||||
|     <artifactId>bungeecord-module-cmd-alert</artifactId> |     <artifactId>bungeecord-module-cmd-alert</artifactId> | ||||||
|     <version>1.20-R0.3-SNAPSHOT</version> |     <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|     <packaging>jar</packaging> |     <packaging>jar</packaging> | ||||||
|  |  | ||||||
|     <name>cmd_alert</name> |     <name>cmd_alert</name> | ||||||
|   | |||||||
| @@ -1,6 +1,5 @@ | |||||||
| package net.md_5.bungee.module.cmd.alert; | package net.md_5.bungee.module.cmd.alert; | ||||||
|  |  | ||||||
| import java.util.Locale; |  | ||||||
| import net.md_5.bungee.api.ChatColor; | import net.md_5.bungee.api.ChatColor; | ||||||
| import net.md_5.bungee.api.CommandSender; | import net.md_5.bungee.api.CommandSender; | ||||||
| import net.md_5.bungee.api.ProxyServer; | import net.md_5.bungee.api.ProxyServer; | ||||||
| @@ -24,10 +23,10 @@ public class CommandAlert extends Command | |||||||
|         } else |         } else | ||||||
|         { |         { | ||||||
|             StringBuilder builder = new StringBuilder(); |             StringBuilder builder = new StringBuilder(); | ||||||
|             if ( args[0].toLowerCase( Locale.ROOT ).startsWith( "&h" ) ) |             if ( args[0].startsWith( "&h" ) ) | ||||||
|             { |             { | ||||||
|                 // Remove &h |                 // Remove &h | ||||||
|                 args[0] = args[0].substring( 2 ); |                 args[0] = args[0].substring( 2, args[0].length() ); | ||||||
|             } else |             } else | ||||||
|             { |             { | ||||||
|                 builder.append( ProxyServer.getInstance().getTranslation( "alert" ) ); |                 builder.append( ProxyServer.getInstance().getTranslation( "alert" ) ); | ||||||
| @@ -41,7 +40,7 @@ public class CommandAlert extends Command | |||||||
|  |  | ||||||
|             String message = builder.substring( 0, builder.length() - 1 ); |             String message = builder.substring( 0, builder.length() - 1 ); | ||||||
|  |  | ||||||
|             ProxyServer.getInstance().broadcast( TextComponent.fromLegacy( message ) ); |             ProxyServer.getInstance().broadcast( TextComponent.fromLegacyText( message ) ); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -6,13 +6,13 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>net.md-5</groupId> |         <groupId>net.md-5</groupId> | ||||||
|         <artifactId>bungeecord-module</artifactId> |         <artifactId>bungeecord-module</artifactId> | ||||||
|         <version>1.20-R0.3-SNAPSHOT</version> |         <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|         <relativePath>../pom.xml</relativePath> |         <relativePath>../pom.xml</relativePath> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <groupId>net.md-5</groupId> |     <groupId>net.md-5</groupId> | ||||||
|     <artifactId>bungeecord-module-cmd-find</artifactId> |     <artifactId>bungeecord-module-cmd-find</artifactId> | ||||||
|     <version>1.20-R0.3-SNAPSHOT</version> |     <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|     <packaging>jar</packaging> |     <packaging>jar</packaging> | ||||||
|  |  | ||||||
|     <name>cmd_find</name> |     <name>cmd_find</name> | ||||||
|   | |||||||
| @@ -1,12 +1,7 @@ | |||||||
| package net.md_5.bungee.module.cmd.find; | package net.md_5.bungee.module.cmd.find; | ||||||
|  |  | ||||||
| import java.util.Collections; |  | ||||||
| import net.md_5.bungee.api.CommandSender; | import net.md_5.bungee.api.CommandSender; | ||||||
| import net.md_5.bungee.api.ProxyServer; | import net.md_5.bungee.api.ProxyServer; | ||||||
| import net.md_5.bungee.api.chat.ClickEvent; |  | ||||||
| import net.md_5.bungee.api.chat.ComponentBuilder; |  | ||||||
| import net.md_5.bungee.api.chat.HoverEvent; |  | ||||||
| import net.md_5.bungee.api.config.ServerInfo; |  | ||||||
| import net.md_5.bungee.api.connection.ProxiedPlayer; | import net.md_5.bungee.api.connection.ProxiedPlayer; | ||||||
| import net.md_5.bungee.command.PlayerCommand; | import net.md_5.bungee.command.PlayerCommand; | ||||||
|  |  | ||||||
| @@ -32,27 +27,8 @@ public class CommandFind extends PlayerCommand | |||||||
|                 sender.sendMessage( ProxyServer.getInstance().getTranslation( "user_not_online" ) ); |                 sender.sendMessage( ProxyServer.getInstance().getTranslation( "user_not_online" ) ); | ||||||
|             } else |             } else | ||||||
|             { |             { | ||||||
|                 boolean moduleLoaded = ProxyServer.getInstance().getPluginManager().getPlugin( "cmd_server" ) != null; |                 sender.sendMessage( ProxyServer.getInstance().getTranslation( "user_online_at", player.getName(), player.getServer().getInfo().getName() ) ); | ||||||
|                 ServerInfo server = player.getServer().getInfo(); |  | ||||||
|                 ComponentBuilder componentBuilder = new ComponentBuilder().appendLegacy( ProxyServer.getInstance().getTranslation( "user_online_at", player.getName(), server.getName() ) ); |  | ||||||
|  |  | ||||||
|                 if ( moduleLoaded && server.canAccess( sender ) ) |  | ||||||
|                 { |  | ||||||
|                     componentBuilder.event( new HoverEvent( |  | ||||||
|                             HoverEvent.Action.SHOW_TEXT, |  | ||||||
|                             new ComponentBuilder().appendLegacy( ProxyServer.getInstance().getTranslation( "click_to_connect" ) ).create() ) |  | ||||||
|                     ); |  | ||||||
|                     componentBuilder.event( new ClickEvent( ClickEvent.Action.RUN_COMMAND, "/server " + server.getName() ) ); |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 sender.sendMessage( componentBuilder.create() ); |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public Iterable<String> onTabComplete(CommandSender sender, String[] args) |  | ||||||
|     { |  | ||||||
|         return args.length == 1 ? super.onTabComplete( sender, args ) : Collections.emptyList(); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,31 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <project-shared-configuration> |  | ||||||
|     <!-- |  | ||||||
|     This file contains additional configuration written by modules in the NetBeans IDE. |  | ||||||
|     The configuration is intended to be shared among all the users of project and |  | ||||||
|     therefore it is assumed to be part of version control checkout. |  | ||||||
|     Without this configuration present, some functionality in the IDE may be limited or fail altogether. |  | ||||||
|     --> |  | ||||||
|     <properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1"> |  | ||||||
|         <!-- |  | ||||||
|         Properties that influence various parts of the IDE, especially code formatting and the like.  |  | ||||||
|         You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up. |  | ||||||
|         That way multiple projects can share the same settings (useful for formatting rules for example). |  | ||||||
|         Any value defined here will override the pom.xml file value but is only applicable to the current project. |  | ||||||
|         --> |  | ||||||
|         <org-netbeans-modules-editor-indent.CodeStyle.usedProfile>project</org-netbeans-modules-editor-indent.CodeStyle.usedProfile> |  | ||||||
|         <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement> |  | ||||||
|         <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement> |  | ||||||
|         <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement> |  | ||||||
|         <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens> |  | ||||||
|         <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens> |  | ||||||
|         <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens> |  | ||||||
|         <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens> |  | ||||||
|         <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens> |  | ||||||
|         <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets> |  | ||||||
|         <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens> |  | ||||||
|         <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens> |  | ||||||
|         <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens> |  | ||||||
|         <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens> |  | ||||||
|     </properties> |  | ||||||
| </project-shared-configuration> |  | ||||||
| @@ -1,20 +0,0 @@ | |||||||
|  |  | ||||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |  | ||||||
|          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |  | ||||||
|     <modelVersion>4.0.0</modelVersion> |  | ||||||
|  |  | ||||||
|     <parent> |  | ||||||
|         <groupId>net.md-5</groupId> |  | ||||||
|         <artifactId>bungeecord-module</artifactId> |  | ||||||
|         <version>1.20-R0.3-SNAPSHOT</version> |  | ||||||
|         <relativePath>../pom.xml</relativePath> |  | ||||||
|     </parent> |  | ||||||
|  |  | ||||||
|     <groupId>net.md-5</groupId> |  | ||||||
|     <artifactId>bungeecord-module-cmd-kick</artifactId> |  | ||||||
|     <version>1.20-R0.3-SNAPSHOT</version> |  | ||||||
|     <packaging>jar</packaging> |  | ||||||
|  |  | ||||||
|     <name>cmd_kick</name> |  | ||||||
|     <description>Provides the gkick command</description> |  | ||||||
| </project> |  | ||||||
| @@ -1,72 +0,0 @@ | |||||||
| package net.md_5.bungee.module.cmd.kick; |  | ||||||
|  |  | ||||||
| import com.google.common.base.Joiner; |  | ||||||
| import com.google.common.collect.ImmutableSet; |  | ||||||
| import java.util.HashSet; |  | ||||||
| import java.util.Locale; |  | ||||||
| import java.util.Set; |  | ||||||
| import net.md_5.bungee.api.ChatColor; |  | ||||||
| import net.md_5.bungee.api.CommandSender; |  | ||||||
| import net.md_5.bungee.api.ProxyServer; |  | ||||||
| import net.md_5.bungee.api.chat.TextComponent; |  | ||||||
| import net.md_5.bungee.api.connection.ProxiedPlayer; |  | ||||||
| import net.md_5.bungee.api.plugin.Command; |  | ||||||
| import net.md_5.bungee.api.plugin.TabExecutor; |  | ||||||
|  |  | ||||||
| public class CommandKick extends Command implements TabExecutor |  | ||||||
| { |  | ||||||
|  |  | ||||||
|     public CommandKick() |  | ||||||
|     { |  | ||||||
|         super( "gkick", "bungeecord.command.kick" ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void execute(CommandSender sender, String[] args) |  | ||||||
|     { |  | ||||||
|         if ( args.length == 0 ) |  | ||||||
|         { |  | ||||||
|             sender.sendMessage( ProxyServer.getInstance().getTranslation( "username_needed" ) ); |  | ||||||
|         } else |  | ||||||
|         { |  | ||||||
|             ProxiedPlayer player = ProxyServer.getInstance().getPlayer( args[0] ); |  | ||||||
|  |  | ||||||
|             if ( player == null ) |  | ||||||
|             { |  | ||||||
|                 sender.sendMessage( TextComponent.fromLegacy( ProxyServer.getInstance().getTranslation( "user_not_online" ) ) ); |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if ( args.length == 1 ) |  | ||||||
|             { |  | ||||||
|                 player.disconnect( TextComponent.fromLegacy( ProxyServer.getInstance().getTranslation( "kick_message" ) ) ); |  | ||||||
|             } else |  | ||||||
|             { |  | ||||||
|                 String[] reason = new String[ args.length - 1 ]; |  | ||||||
|                 System.arraycopy( args, 1, reason, 0, reason.length ); |  | ||||||
|                 player.disconnect( TextComponent.fromLegacy( ChatColor.translateAlternateColorCodes( '&', Joiner.on( ' ' ).join( reason ) ) ) ); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public Iterable<String> onTabComplete(CommandSender sender, String[] args) |  | ||||||
|     { |  | ||||||
|         if ( args.length == 1 ) |  | ||||||
|         { |  | ||||||
|             Set<String> matches = new HashSet<>(); |  | ||||||
|             String search = args[0].toLowerCase( Locale.ROOT ); |  | ||||||
|             for ( ProxiedPlayer player : ProxyServer.getInstance().getPlayers() ) |  | ||||||
|             { |  | ||||||
|                 if ( player.getName().toLowerCase( Locale.ROOT ).startsWith( search ) ) |  | ||||||
|                 { |  | ||||||
|                     matches.add( player.getName() ); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             return matches; |  | ||||||
|         } else |  | ||||||
|         { |  | ||||||
|             return ImmutableSet.of(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| package net.md_5.bungee.module.cmd.kick; |  | ||||||
|  |  | ||||||
| import net.md_5.bungee.api.plugin.Plugin; |  | ||||||
|  |  | ||||||
| public class PluginKick extends Plugin |  | ||||||
| { |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void onEnable() |  | ||||||
|     { |  | ||||||
|         getProxy().getPluginManager().registerCommand( this, new CommandKick() ); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,5 +0,0 @@ | |||||||
| name: ${project.name} |  | ||||||
| main: net.md_5.bungee.module.cmd.kick.PluginKick |  | ||||||
| version: ${describe} |  | ||||||
| description: ${project.description} |  | ||||||
| author: ${module.author} |  | ||||||
| @@ -6,13 +6,13 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>net.md-5</groupId> |         <groupId>net.md-5</groupId> | ||||||
|         <artifactId>bungeecord-module</artifactId> |         <artifactId>bungeecord-module</artifactId> | ||||||
|         <version>1.20-R0.3-SNAPSHOT</version> |         <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|         <relativePath>../pom.xml</relativePath> |         <relativePath>../pom.xml</relativePath> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <groupId>net.md-5</groupId> |     <groupId>net.md-5</groupId> | ||||||
|     <artifactId>bungeecord-module-cmd-list</artifactId> |     <artifactId>bungeecord-module-cmd-list</artifactId> | ||||||
|     <version>1.20-R0.3-SNAPSHOT</version> |     <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|     <packaging>jar</packaging> |     <packaging>jar</packaging> | ||||||
|  |  | ||||||
|     <name>cmd_list</name> |     <name>cmd_list</name> | ||||||
|   | |||||||
| @@ -1,26 +1,20 @@ | |||||||
| package net.md_5.bungee.module.cmd.list; | package net.md_5.bungee.module.cmd.list; | ||||||
|  |  | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.Collection; |  | ||||||
| import java.util.Collections; | import java.util.Collections; | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  | import net.md_5.bungee.Util; | ||||||
| import net.md_5.bungee.api.ChatColor; | import net.md_5.bungee.api.ChatColor; | ||||||
| import net.md_5.bungee.api.CommandSender; | import net.md_5.bungee.api.CommandSender; | ||||||
| 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.chat.ClickEvent; |  | ||||||
| import net.md_5.bungee.api.chat.ComponentBuilder; |  | ||||||
| import net.md_5.bungee.api.chat.HoverEvent; |  | ||||||
| import net.md_5.bungee.api.chat.hover.content.Text; |  | ||||||
| import net.md_5.bungee.api.config.ServerInfo; | import net.md_5.bungee.api.config.ServerInfo; | ||||||
| import net.md_5.bungee.api.connection.ProxiedPlayer; | import net.md_5.bungee.api.connection.ProxiedPlayer; | ||||||
| import net.md_5.bungee.api.plugin.Command; | import net.md_5.bungee.api.plugin.Command; | ||||||
| import net.md_5.bungee.api.plugin.TabExecutor; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Command to list all players connected to the proxy. |  * Command to list all players connected to the proxy. | ||||||
|  */ |  */ | ||||||
| public class CommandList extends Command implements TabExecutor | public class CommandList extends Command | ||||||
| { | { | ||||||
|  |  | ||||||
|     public CommandList() |     public CommandList() | ||||||
| @@ -31,9 +25,6 @@ public class CommandList extends Command implements TabExecutor | |||||||
|     @Override |     @Override | ||||||
|     public void execute(CommandSender sender, String[] args) |     public void execute(CommandSender sender, String[] args) | ||||||
|     { |     { | ||||||
|         boolean hideEmptyServers = ( args.length == 0 ) || !args[0].equalsIgnoreCase( "all" ); |  | ||||||
|         boolean moduleLoaded = ProxyServer.getInstance().getPluginManager().getPlugin( "cmd_server" ) != null; |  | ||||||
|  |  | ||||||
|         for ( ServerInfo server : ProxyServer.getInstance().getServers().values() ) |         for ( ServerInfo server : ProxyServer.getInstance().getServers().values() ) | ||||||
|         { |         { | ||||||
|             if ( !server.canAccess( sender ) ) |             if ( !server.canAccess( sender ) ) | ||||||
| @@ -41,39 +32,16 @@ public class CommandList extends Command implements TabExecutor | |||||||
|                 continue; |                 continue; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             Collection<ProxiedPlayer> serverPlayers = server.getPlayers(); |  | ||||||
|             if ( hideEmptyServers && serverPlayers.isEmpty() ) |  | ||||||
|             { |  | ||||||
|                 continue; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             List<String> players = new ArrayList<>(); |             List<String> players = new ArrayList<>(); | ||||||
|             for ( ProxiedPlayer player : serverPlayers ) |             for ( ProxiedPlayer player : server.getPlayers() ) | ||||||
|             { |             { | ||||||
|                 players.add( player.getDisplayName() ); |                 players.add( player.getDisplayName() ); | ||||||
|             } |             } | ||||||
|             Collections.sort( players, String.CASE_INSENSITIVE_ORDER ); |             Collections.sort( players, String.CASE_INSENSITIVE_ORDER ); | ||||||
|  |  | ||||||
|             BaseComponent baseComponent = new ComponentBuilder().appendLegacy( ProxyServer.getInstance().getTranslation( "command_list", server.getName(), players.size(), String.join( ChatColor.RESET + ", ", players ) ) ).build(); |             sender.sendMessage( ProxyServer.getInstance().getTranslation( "command_list", server.getName(), server.getPlayers().size(), Util.format( players, ChatColor.RESET + ", " ) ) ); | ||||||
|  |  | ||||||
|             if ( moduleLoaded ) |  | ||||||
|             { |  | ||||||
|                 baseComponent.setHoverEvent( new HoverEvent( |  | ||||||
|                         HoverEvent.Action.SHOW_TEXT, |  | ||||||
|                         new Text( new ComponentBuilder().appendLegacy( ProxyServer.getInstance().getTranslation( "click_to_connect" ) ).create() ) ) |  | ||||||
|                 ); |  | ||||||
|                 baseComponent.setClickEvent( new ClickEvent( ClickEvent.Action.RUN_COMMAND, "/server " + server.getName() ) ); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             sender.sendMessage( baseComponent ); |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         sender.sendMessage( ProxyServer.getInstance().getTranslation( "total_players", ProxyServer.getInstance().getOnlineCount() ) ); |         sender.sendMessage( ProxyServer.getInstance().getTranslation( "total_players", ProxyServer.getInstance().getOnlineCount() ) ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public Iterable<String> onTabComplete(CommandSender sender, String[] args) |  | ||||||
|     { |  | ||||||
|         return ( args.length > 1 ) ? Collections.emptyList() : Collections.singletonList( "all" ); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -6,13 +6,13 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>net.md-5</groupId> |         <groupId>net.md-5</groupId> | ||||||
|         <artifactId>bungeecord-module</artifactId> |         <artifactId>bungeecord-module</artifactId> | ||||||
|         <version>1.20-R0.3-SNAPSHOT</version> |         <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|         <relativePath>../pom.xml</relativePath> |         <relativePath>../pom.xml</relativePath> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <groupId>net.md-5</groupId> |     <groupId>net.md-5</groupId> | ||||||
|     <artifactId>bungeecord-module-cmd-send</artifactId> |     <artifactId>bungeecord-module-cmd-send</artifactId> | ||||||
|     <version>1.20-R0.3-SNAPSHOT</version> |     <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|     <packaging>jar</packaging> |     <packaging>jar</packaging> | ||||||
|  |  | ||||||
|     <name>cmd_send</name> |     <name>cmd_send</name> | ||||||
|   | |||||||
| @@ -38,7 +38,7 @@ public class CommandSend extends Command implements TabExecutor | |||||||
|             this.sender = sender; |             this.sender = sender; | ||||||
|             for ( ServerConnectRequest.Result result : ServerConnectRequest.Result.values() ) |             for ( ServerConnectRequest.Result result : ServerConnectRequest.Result.values() ) | ||||||
|             { |             { | ||||||
|                 results.put( result, Collections.synchronizedList( new ArrayList<>() ) ); |                 results.put( result, new ArrayList<String>() ); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,13 +6,13 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>net.md-5</groupId> |         <groupId>net.md-5</groupId> | ||||||
|         <artifactId>bungeecord-module</artifactId> |         <artifactId>bungeecord-module</artifactId> | ||||||
|         <version>1.20-R0.3-SNAPSHOT</version> |         <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|         <relativePath>../pom.xml</relativePath> |         <relativePath>../pom.xml</relativePath> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <groupId>net.md-5</groupId> |     <groupId>net.md-5</groupId> | ||||||
|     <artifactId>bungeecord-module-cmd-server</artifactId> |     <artifactId>bungeecord-module-cmd-server</artifactId> | ||||||
|     <version>1.20-R0.3-SNAPSHOT</version> |     <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|     <packaging>jar</packaging> |     <packaging>jar</packaging> | ||||||
|  |  | ||||||
|     <name>cmd_server</name> |     <name>cmd_server</name> | ||||||
|   | |||||||
| @@ -6,13 +6,13 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>net.md-5</groupId> |         <groupId>net.md-5</groupId> | ||||||
|         <artifactId>bungeecord-parent</artifactId> |         <artifactId>bungeecord-parent</artifactId> | ||||||
|         <version>1.20-R0.3-SNAPSHOT</version> |         <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|         <relativePath>../pom.xml</relativePath> |         <relativePath>../pom.xml</relativePath> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <groupId>net.md-5</groupId> |     <groupId>net.md-5</groupId> | ||||||
|     <artifactId>bungeecord-module</artifactId> |     <artifactId>bungeecord-module</artifactId> | ||||||
|     <version>1.20-R0.3-SNAPSHOT</version> |     <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|     <packaging>pom</packaging> |     <packaging>pom</packaging> | ||||||
|  |  | ||||||
|     <name>BungeeCord Modules</name> |     <name>BungeeCord Modules</name> | ||||||
| @@ -21,7 +21,6 @@ | |||||||
|     <modules> |     <modules> | ||||||
|         <module>cmd-alert</module> |         <module>cmd-alert</module> | ||||||
|         <module>cmd-find</module> |         <module>cmd-find</module> | ||||||
|         <module>cmd-kick</module> |  | ||||||
|         <module>cmd-list</module> |         <module>cmd-list</module> | ||||||
|         <module>cmd-send</module> |         <module>cmd-send</module> | ||||||
|         <module>cmd-server</module> |         <module>cmd-server</module> | ||||||
|   | |||||||
| @@ -6,13 +6,13 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>net.md-5</groupId> |         <groupId>net.md-5</groupId> | ||||||
|         <artifactId>bungeecord-module</artifactId> |         <artifactId>bungeecord-module</artifactId> | ||||||
|         <version>1.20-R0.3-SNAPSHOT</version> |         <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|         <relativePath>../pom.xml</relativePath> |         <relativePath>../pom.xml</relativePath> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <groupId>net.md-5</groupId> |     <groupId>net.md-5</groupId> | ||||||
|     <artifactId>bungeecord-module-reconnect-yaml</artifactId> |     <artifactId>bungeecord-module-reconnect-yaml</artifactId> | ||||||
|     <version>1.20-R0.3-SNAPSHOT</version> |     <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|     <packaging>jar</packaging> |     <packaging>jar</packaging> | ||||||
|  |  | ||||||
|     <name>reconnect_yaml</name> |     <name>reconnect_yaml</name> | ||||||
|   | |||||||
| @@ -1,14 +1,6 @@ | |||||||
| #!/bin/sh | #!/bin/sh | ||||||
|  |  | ||||||
| set -eu |  | ||||||
|  |  | ||||||
| echo "Compiling mbedtls" |  | ||||||
| (cd mbedtls && make no_test) |  | ||||||
|  |  | ||||||
| echo "Compiling zlib" |  | ||||||
| (cd zlib && CFLAGS=-fPIC ./configure --static && make) |  | ||||||
|  |  | ||||||
| CXX="g++ -shared -fPIC -O3 -Wall -Werror -I$JAVA_HOME/include/ -I$JAVA_HOME/include/linux/" | CXX="g++ -shared -fPIC -O3 -Wall -Werror -I$JAVA_HOME/include/ -I$JAVA_HOME/include/linux/" | ||||||
|  |  | ||||||
| $CXX -Imbedtls/include src/main/c/NativeCipherImpl.cpp -o src/main/resources/native-cipher.so mbedtls/library/libmbedcrypto.a | $CXX src/main/c/NativeCipherImpl.cpp -o src/main/resources/native-cipher.so -lcrypto | ||||||
| $CXX -Izlib src/main/c/NativeCompressImpl.cpp -o src/main/resources/native-compress.so zlib/libz.a | $CXX src/main/c/NativeCompressImpl.cpp -o src/main/resources/native-compress.so -lz | ||||||
|   | |||||||
 Submodule native/mbedtls deleted from 2ca6c285a0
									
								
							| @@ -6,13 +6,13 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>net.md-5</groupId> |         <groupId>net.md-5</groupId> | ||||||
|         <artifactId>bungeecord-parent</artifactId> |         <artifactId>bungeecord-parent</artifactId> | ||||||
|         <version>1.20-R0.3-SNAPSHOT</version> |         <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|         <relativePath>../pom.xml</relativePath> |         <relativePath>../pom.xml</relativePath> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <groupId>net.md-5</groupId> |     <groupId>net.md-5</groupId> | ||||||
|     <artifactId>bungeecord-native</artifactId> |     <artifactId>bungeecord-native</artifactId> | ||||||
|     <version>1.20-R0.3-SNAPSHOT</version> |     <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|     <packaging>jar</packaging> |     <packaging>jar</packaging> | ||||||
|  |  | ||||||
|     <name>BungeeCord-Native</name> |     <name>BungeeCord-Native</name> | ||||||
| @@ -22,6 +22,7 @@ | |||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>io.netty</groupId> |             <groupId>io.netty</groupId> | ||||||
|             <artifactId>netty-transport</artifactId> |             <artifactId>netty-transport</artifactId> | ||||||
|  |             <version>${netty.version}</version> | ||||||
|             <scope>compile</scope> |             <scope>compile</scope> | ||||||
|         </dependency> |         </dependency> | ||||||
|     </dependencies> |     </dependencies> | ||||||
|   | |||||||
| @@ -1,3 +1,6 @@ | |||||||
|  | // Support for CentOS 6 | ||||||
|  | __asm__(".symver memcpy,memcpy@GLIBC_2.2.5"); | ||||||
|  |  | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,4 @@ | |||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> |  | ||||||
|  |  | ||||||
| #include <zlib.h> | #include <zlib.h> | ||||||
| #include "net_md_5_bungee_jni_zlib_NativeCompressImpl.h" | #include "net_md_5_bungee_jni_zlib_NativeCompressImpl.h" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,19 +6,18 @@ import java.io.FileOutputStream; | |||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.io.InputStream; | import java.io.InputStream; | ||||||
| import java.io.OutputStream; | import java.io.OutputStream; | ||||||
| import java.util.function.Supplier; |  | ||||||
| import net.md_5.bungee.jni.cipher.BungeeCipher; | import net.md_5.bungee.jni.cipher.BungeeCipher; | ||||||
|  |  | ||||||
| public final class NativeCode<T> | public final class NativeCode<T> | ||||||
| { | { | ||||||
|  |  | ||||||
|     private final String name; |     private final String name; | ||||||
|     private final Supplier<? extends T> javaImpl; |     private final Class<? extends T> javaImpl; | ||||||
|     private final Supplier<? extends T> nativeImpl; |     private final Class<? extends T> nativeImpl; | ||||||
|     // |     // | ||||||
|     private boolean loaded; |     private boolean loaded; | ||||||
|  |  | ||||||
|     public NativeCode(String name, Supplier<? extends T> javaImpl, Supplier<? extends T> nativeImpl) |     public NativeCode(String name, Class<? extends T> javaImpl, Class<? extends T> nativeImpl) | ||||||
|     { |     { | ||||||
|         this.name = name; |         this.name = name; | ||||||
|         this.javaImpl = javaImpl; |         this.javaImpl = javaImpl; | ||||||
| @@ -27,7 +26,13 @@ public final class NativeCode<T> | |||||||
|  |  | ||||||
|     public T newInstance() |     public T newInstance() | ||||||
|     { |     { | ||||||
|         return ( loaded ) ? nativeImpl.get() : javaImpl.get(); |         try | ||||||
|  |         { | ||||||
|  |             return ( loaded ) ? nativeImpl.getDeclaredConstructor().newInstance() : javaImpl.getDeclaredConstructor().newInstance(); | ||||||
|  |         } catch ( ReflectiveOperationException ex ) | ||||||
|  |         { | ||||||
|  |             throw new RuntimeException( "Error getting instance", ex ); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public boolean load() |     public boolean load() | ||||||
|   | |||||||
| @@ -25,15 +25,9 @@ public class JavaCipher implements BungeeCipher | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public JavaCipher() |     public JavaCipher() throws GeneralSecurityException | ||||||
|     { |  | ||||||
|         try |  | ||||||
|     { |     { | ||||||
|         this.cipher = Cipher.getInstance( "AES/CFB8/NoPadding" ); |         this.cipher = Cipher.getInstance( "AES/CFB8/NoPadding" ); | ||||||
|         } catch ( GeneralSecurityException ex ) |  | ||||||
|         { |  | ||||||
|             throw new RuntimeException( ex ); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|   | |||||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -1,6 +1,5 @@ | |||||||
| package net.md_5.bungee; | package net.md_5.bungee; | ||||||
|  |  | ||||||
| import static org.junit.jupiter.api.Assertions.*; |  | ||||||
| import io.netty.buffer.ByteBuf; | import io.netty.buffer.ByteBuf; | ||||||
| import io.netty.buffer.Unpooled; | import io.netty.buffer.Unpooled; | ||||||
| import java.util.Random; | import java.util.Random; | ||||||
| @@ -10,11 +9,12 @@ import net.md_5.bungee.jni.NativeCode; | |||||||
| import net.md_5.bungee.jni.cipher.BungeeCipher; | import net.md_5.bungee.jni.cipher.BungeeCipher; | ||||||
| import net.md_5.bungee.jni.cipher.JavaCipher; | import net.md_5.bungee.jni.cipher.JavaCipher; | ||||||
| import net.md_5.bungee.jni.cipher.NativeCipher; | import net.md_5.bungee.jni.cipher.NativeCipher; | ||||||
| import org.junit.jupiter.api.MethodOrderer; | import org.junit.Assert; | ||||||
| import org.junit.jupiter.api.Test; | import org.junit.FixMethodOrder; | ||||||
| import org.junit.jupiter.api.TestMethodOrder; | import org.junit.Test; | ||||||
|  | import org.junit.runners.MethodSorters; | ||||||
|  |  | ||||||
| @TestMethodOrder(MethodOrderer.MethodName.class) | @FixMethodOrder(MethodSorters.NAME_ASCENDING) | ||||||
| public class NativeCipherTest | public class NativeCipherTest | ||||||
| { | { | ||||||
|  |  | ||||||
| @@ -26,7 +26,7 @@ public class NativeCipherTest | |||||||
|     private final SecretKey secret = new SecretKeySpec( new byte[ 16 ], "AES" ); |     private final SecretKey secret = new SecretKeySpec( new byte[ 16 ], "AES" ); | ||||||
|     private static final int BENCHMARK_COUNT = 4096; |     private static final int BENCHMARK_COUNT = 4096; | ||||||
|     // |     // | ||||||
|     private static final NativeCode<BungeeCipher> factory = new NativeCode<>( "native-cipher", JavaCipher::new, NativeCipher::new ); |     private static final NativeCode<BungeeCipher> factory = new NativeCode<>( "native-cipher", JavaCipher.class, NativeCipher.class ); | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     public void testNative() throws Exception |     public void testNative() throws Exception | ||||||
| @@ -34,7 +34,7 @@ public class NativeCipherTest | |||||||
|         if ( NativeCode.isSupported() ) |         if ( NativeCode.isSupported() ) | ||||||
|         { |         { | ||||||
|             boolean loaded = factory.load(); |             boolean loaded = factory.load(); | ||||||
|             assertTrue( loaded, "Native cipher failed to load!" ); |             Assert.assertTrue( "Native cipher failed to load!", loaded ); | ||||||
|  |  | ||||||
|             NativeCipher cipher = new NativeCipher(); |             NativeCipher cipher = new NativeCipher(); | ||||||
|             System.out.println( "Testing native cipher..." ); |             System.out.println( "Testing native cipher..." ); | ||||||
| @@ -48,7 +48,7 @@ public class NativeCipherTest | |||||||
|         if ( NativeCode.isSupported() ) |         if ( NativeCode.isSupported() ) | ||||||
|         { |         { | ||||||
|             boolean loaded = factory.load(); |             boolean loaded = factory.load(); | ||||||
|             assertTrue( loaded, "Native cipher failed to load!" ); |             Assert.assertTrue( "Native cipher failed to load!", loaded ); | ||||||
|  |  | ||||||
|             NativeCipher cipher = new NativeCipher(); |             NativeCipher cipher = new NativeCipher(); | ||||||
|  |  | ||||||
| @@ -98,7 +98,7 @@ public class NativeCipherTest | |||||||
|         // Encrypt |         // Encrypt | ||||||
|         cipher.init( true, secret ); |         cipher.init( true, secret ); | ||||||
|         cipher.cipher( nativePlain, out ); |         cipher.cipher( nativePlain, out ); | ||||||
|         assertEquals( nativeCiphered, out ); |         Assert.assertEquals( nativeCiphered, out ); | ||||||
|  |  | ||||||
|         out.clear(); |         out.clear(); | ||||||
|  |  | ||||||
| @@ -106,7 +106,7 @@ public class NativeCipherTest | |||||||
|         cipher.init( false, secret ); |         cipher.init( false, secret ); | ||||||
|         cipher.cipher( nativeCiphered, out ); |         cipher.cipher( nativeCiphered, out ); | ||||||
|         nativePlain.resetReaderIndex(); |         nativePlain.resetReaderIndex(); | ||||||
|         assertEquals( nativePlain, out ); |         Assert.assertEquals( nativePlain, out ); | ||||||
|  |  | ||||||
|         System.out.println( "This cipher works correctly!" ); |         System.out.println( "This cipher works correctly!" ); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,6 +1,5 @@ | |||||||
| package net.md_5.bungee; | package net.md_5.bungee; | ||||||
|  |  | ||||||
| import static org.junit.jupiter.api.Assertions.*; |  | ||||||
| import io.netty.buffer.ByteBuf; | import io.netty.buffer.ByteBuf; | ||||||
| import io.netty.buffer.Unpooled; | import io.netty.buffer.Unpooled; | ||||||
| import java.util.Arrays; | import java.util.Arrays; | ||||||
| @@ -10,19 +9,20 @@ import net.md_5.bungee.jni.NativeCode; | |||||||
| import net.md_5.bungee.jni.zlib.BungeeZlib; | import net.md_5.bungee.jni.zlib.BungeeZlib; | ||||||
| import net.md_5.bungee.jni.zlib.JavaZlib; | import net.md_5.bungee.jni.zlib.JavaZlib; | ||||||
| import net.md_5.bungee.jni.zlib.NativeZlib; | import net.md_5.bungee.jni.zlib.NativeZlib; | ||||||
| import org.junit.jupiter.api.Test; | import org.junit.Assert; | ||||||
|  | import org.junit.Test; | ||||||
|  |  | ||||||
| public class NativeZlibTest | public class NativeZlibTest | ||||||
| { | { | ||||||
|  |  | ||||||
|     private final NativeCode<BungeeZlib> factory = new NativeCode<>( "native-compress", JavaZlib::new, NativeZlib::new ); |     private final NativeCode<BungeeZlib> factory = new NativeCode<>( "native-compress", JavaZlib.class, NativeZlib.class ); | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     public void doTest() throws DataFormatException |     public void doTest() throws DataFormatException | ||||||
|     { |     { | ||||||
|         if ( NativeCode.isSupported() ) |         if ( NativeCode.isSupported() ) | ||||||
|         { |         { | ||||||
|             assertTrue( factory.load(), "Native code failed to load!" ); |             Assert.assertTrue( "Native code failed to load!", factory.load() ); | ||||||
|             test( factory.newInstance() ); |             test( factory.newInstance() ); | ||||||
|         } |         } | ||||||
|         test( new JavaZlib() ); |         test( new JavaZlib() ); | ||||||
| @@ -64,6 +64,6 @@ public class NativeZlibTest | |||||||
|         long elapsed = System.currentTimeMillis() - start; |         long elapsed = System.currentTimeMillis() - start; | ||||||
|         System.out.println( "Took: " + elapsed + "ms" ); |         System.out.println( "Took: " + elapsed + "ms" ); | ||||||
|  |  | ||||||
|         assertTrue( Arrays.equals( dataBuf, check ), "Results do not match" ); |         Assert.assertTrue( "Results do not match", Arrays.equals( dataBuf, check ) ); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
 Submodule native/zlib deleted from 92530568d2
									
								
							
							
								
								
									
										140
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										140
									
								
								pom.xml
									
									
									
									
									
								
							| @@ -5,7 +5,7 @@ | |||||||
|  |  | ||||||
|     <groupId>net.md-5</groupId> |     <groupId>net.md-5</groupId> | ||||||
|     <artifactId>bungeecord-parent</artifactId> |     <artifactId>bungeecord-parent</artifactId> | ||||||
|     <version>1.20-R0.3-SNAPSHOT</version> |     <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|     <packaging>pom</packaging> |     <packaging>pom</packaging> | ||||||
|  |  | ||||||
|     <name>BungeeCord-Parent</name> |     <name>BungeeCord-Parent</name> | ||||||
| @@ -41,7 +41,6 @@ | |||||||
|         <module>protocol</module> |         <module>protocol</module> | ||||||
|         <module>proxy</module> |         <module>proxy</module> | ||||||
|         <module>query</module> |         <module>query</module> | ||||||
|         <module>slf4j</module> |  | ||||||
|         <module>native</module> |         <module>native</module> | ||||||
|     </modules> |     </modules> | ||||||
|  |  | ||||||
| @@ -72,34 +71,23 @@ | |||||||
|  |  | ||||||
|     <properties> |     <properties> | ||||||
|         <build.number>unknown</build.number> |         <build.number>unknown</build.number> | ||||||
|         <lombok.version>1.18.32</lombok.version> |         <netty.version>4.1.53.Final</netty.version> | ||||||
|         <maven.compiler.source>1.8</maven.compiler.source> |         <maven.compiler.source>1.8</maven.compiler.source> | ||||||
|         <maven.compiler.target>1.8</maven.compiler.target> |         <maven.compiler.target>1.8</maven.compiler.target> | ||||||
|         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||||||
|     </properties> |     </properties> | ||||||
|  |  | ||||||
|     <dependencyManagement> |  | ||||||
|     <dependencies> |     <dependencies> | ||||||
|         <dependency> |         <dependency> | ||||||
|                 <groupId>io.netty</groupId> |             <groupId>junit</groupId> | ||||||
|                 <artifactId>netty-bom</artifactId> |             <artifactId>junit</artifactId> | ||||||
|                 <version>4.1.109.Final</version> |             <version>4.13.1</version> | ||||||
|                 <type>pom</type> |  | ||||||
|                 <scope>import</scope> |  | ||||||
|             </dependency> |  | ||||||
|         </dependencies> |  | ||||||
|     </dependencyManagement> |  | ||||||
|     <dependencies> |  | ||||||
|         <dependency> |  | ||||||
|             <groupId>org.junit.jupiter</groupId> |  | ||||||
|             <artifactId>junit-jupiter</artifactId> |  | ||||||
|             <version>5.10.2</version> |  | ||||||
|             <scope>test</scope> |             <scope>test</scope> | ||||||
|         </dependency> |         </dependency> | ||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>com.google.guava</groupId> |             <groupId>com.google.guava</groupId> | ||||||
|             <artifactId>guava</artifactId> |             <artifactId>guava</artifactId> | ||||||
|             <version>32.1.2-jre</version> |             <version>21.0</version> | ||||||
|             <scope>compile</scope> |             <scope>compile</scope> | ||||||
|         </dependency> |         </dependency> | ||||||
|         <dependency> |         <dependency> | ||||||
| @@ -108,35 +96,20 @@ | |||||||
|             <version>3.0.1</version> |             <version>3.0.1</version> | ||||||
|             <scope>provided</scope> |             <scope>provided</scope> | ||||||
|         </dependency> |         </dependency> | ||||||
|         <dependency> |  | ||||||
|             <groupId>org.jetbrains</groupId> |  | ||||||
|             <artifactId>annotations-java5</artifactId> |  | ||||||
|             <version>24.1.0</version> |  | ||||||
|             <scope>provided</scope> |  | ||||||
|         </dependency> |  | ||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>org.projectlombok</groupId> |             <groupId>org.projectlombok</groupId> | ||||||
|             <artifactId>lombok</artifactId> |             <artifactId>lombok</artifactId> | ||||||
|             <version>${lombok.version}</version> |             <version>1.18.10</version> | ||||||
|             <scope>provided</scope> |             <scope>provided</scope> | ||||||
|         </dependency> |         </dependency> | ||||||
|     </dependencies> |     </dependencies> | ||||||
|  |  | ||||||
|     <build> |     <build> | ||||||
|         <pluginManagement> |  | ||||||
|             <plugins> |  | ||||||
|                 <plugin> |  | ||||||
|                     <groupId>org.apache.maven.plugins</groupId> |  | ||||||
|                     <artifactId>maven-javadoc-plugin</artifactId> |  | ||||||
|                     <version>3.6.3</version> |  | ||||||
|                 </plugin> |  | ||||||
|             </plugins> |  | ||||||
|         </pluginManagement> |  | ||||||
|         <plugins> |         <plugins> | ||||||
|             <plugin> |             <plugin> | ||||||
|                 <groupId>net.md-5</groupId> |                 <groupId>net.md-5</groupId> | ||||||
|                 <artifactId>scriptus</artifactId> |                 <artifactId>scriptus</artifactId> | ||||||
|                 <version>0.5.0</version> |                 <version>0.4.1</version> | ||||||
|                 <configuration> |                 <configuration> | ||||||
|                     <format>git:${project.name}:${project.version}:%s:${build.number}</format> |                     <format>git:${project.name}:${project.version}:%s:${build.number}</format> | ||||||
|                 </configuration> |                 </configuration> | ||||||
| @@ -149,15 +122,10 @@ | |||||||
|                     </execution> |                     </execution> | ||||||
|                 </executions> |                 </executions> | ||||||
|             </plugin> |             </plugin> | ||||||
|             <plugin> |  | ||||||
|                 <groupId>org.apache.maven.plugins</groupId> |  | ||||||
|                 <artifactId>maven-compiler-plugin</artifactId> |  | ||||||
|                 <version>3.13.0</version> |  | ||||||
|             </plugin> |  | ||||||
|             <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.1.1</version> | ||||||
|                 <executions> |                 <executions> | ||||||
|                     <execution> |                     <execution> | ||||||
|                         <phase>process-classes</phase> |                         <phase>process-classes</phase> | ||||||
| @@ -175,14 +143,14 @@ | |||||||
|                     <dependency> |                     <dependency> | ||||||
|                         <groupId>com.puppycrawl.tools</groupId> |                         <groupId>com.puppycrawl.tools</groupId> | ||||||
|                         <artifactId>checkstyle</artifactId> |                         <artifactId>checkstyle</artifactId> | ||||||
|                         <version>8.45.1</version> |                         <version>8.36.2</version> | ||||||
|                     </dependency> |                     </dependency> | ||||||
|                 </dependencies> |                 </dependencies> | ||||||
|             </plugin> |             </plugin> | ||||||
|             <plugin> |             <plugin> | ||||||
|                 <groupId>org.codehaus.mojo</groupId> |                 <groupId>org.codehaus.mojo</groupId> | ||||||
|                 <artifactId>animal-sniffer-maven-plugin</artifactId> |                 <artifactId>animal-sniffer-maven-plugin</artifactId> | ||||||
|                 <version>1.23</version> |                 <version>1.19</version> | ||||||
|                 <executions> |                 <executions> | ||||||
|                     <execution> |                     <execution> | ||||||
|                         <phase>process-classes</phase> |                         <phase>process-classes</phase> | ||||||
| @@ -199,82 +167,10 @@ | |||||||
|                     </signature> |                     </signature> | ||||||
|                 </configuration> |                 </configuration> | ||||||
|             </plugin> |             </plugin> | ||||||
|             <plugin> |  | ||||||
|                 <groupId>org.apache.maven.plugins</groupId> |  | ||||||
|                 <artifactId>maven-enforcer-plugin</artifactId> |  | ||||||
|                 <version>3.4.1</version> |  | ||||||
|                 <executions> |  | ||||||
|                     <execution> |  | ||||||
|                         <id>enforce</id> |  | ||||||
|                         <configuration> |  | ||||||
|                             <rules> |  | ||||||
|                                 <dependencyConvergence> |  | ||||||
|                                     <excludes> |  | ||||||
|                                         <!-- org.apache.maven:maven-resolver-provider is inconsistent --> |  | ||||||
|                                         <exclude>org.apache.commons:commons-lang3</exclude> |  | ||||||
|                                         <!-- org.apache.maven:maven-resolver-transport-http is inconsistent --> |  | ||||||
|                                         <exclude>org.apache.httpcomponents:httpcore</exclude> |  | ||||||
|                                     </excludes> |  | ||||||
|                                 </dependencyConvergence> |  | ||||||
|                             </rules> |  | ||||||
|                         </configuration> |  | ||||||
|                         <goals> |  | ||||||
|                             <!--<goal>enforce</goal>--> <!-- Disabled until maven-resolver is upgraded again. --> |  | ||||||
|                         </goals> |  | ||||||
|                     </execution> |  | ||||||
|                 </executions> |  | ||||||
|             </plugin> |  | ||||||
|         </plugins> |         </plugins> | ||||||
|     </build> |     </build> | ||||||
|  |  | ||||||
|     <profiles> |     <profiles> | ||||||
|         <profile> |  | ||||||
|             <id>jdk-9-release</id> |  | ||||||
|             <activation> |  | ||||||
|                 <jdk>[9,)</jdk> |  | ||||||
|             </activation> |  | ||||||
|             <properties> |  | ||||||
|                 <maven.compiler.release>8</maven.compiler.release> |  | ||||||
|             </properties> |  | ||||||
|         </profile> |  | ||||||
|         <profile> |  | ||||||
|             <id>jdk-9-javadoc</id> |  | ||||||
|             <activation> |  | ||||||
|                 <jdk>[9,)</jdk> |  | ||||||
|             </activation> |  | ||||||
|             <build> |  | ||||||
|                 <pluginManagement> |  | ||||||
|                     <plugins> |  | ||||||
|                         <plugin> |  | ||||||
|                             <groupId>org.apache.maven.plugins</groupId> |  | ||||||
|                             <artifactId>maven-javadoc-plugin</artifactId> |  | ||||||
|                             <configuration> |  | ||||||
|                                 <additionalOptions>-html5</additionalOptions> |  | ||||||
|                             </configuration> |  | ||||||
|                         </plugin> |  | ||||||
|                     </plugins> |  | ||||||
|                 </pluginManagement> |  | ||||||
|             </build> |  | ||||||
|         </profile> |  | ||||||
|         <profile> |  | ||||||
|             <id>jdk-15-javadoc</id> |  | ||||||
|             <activation> |  | ||||||
|                 <jdk>[15,)</jdk> |  | ||||||
|             </activation> |  | ||||||
|             <build> |  | ||||||
|                 <pluginManagement> |  | ||||||
|                     <plugins> |  | ||||||
|                         <plugin> |  | ||||||
|                             <groupId>org.apache.maven.plugins</groupId> |  | ||||||
|                             <artifactId>maven-javadoc-plugin</artifactId> |  | ||||||
|                             <configuration> |  | ||||||
|                                 <doclint>none</doclint> |  | ||||||
|                             </configuration> |  | ||||||
|                         </plugin> |  | ||||||
|                     </plugins> |  | ||||||
|                 </pluginManagement> |  | ||||||
|             </build> |  | ||||||
|         </profile> |  | ||||||
|         <profile> |         <profile> | ||||||
|             <id>dist</id> |             <id>dist</id> | ||||||
|             <build> |             <build> | ||||||
| @@ -282,7 +178,7 @@ | |||||||
|                     <plugin> |                     <plugin> | ||||||
|                         <groupId>org.apache.maven.plugins</groupId> |                         <groupId>org.apache.maven.plugins</groupId> | ||||||
|                         <artifactId>maven-source-plugin</artifactId> |                         <artifactId>maven-source-plugin</artifactId> | ||||||
|                         <version>3.3.1</version> |                         <version>3.2.1</version> | ||||||
|                         <executions> |                         <executions> | ||||||
|                             <execution> |                             <execution> | ||||||
|                                 <phase>package</phase> |                                 <phase>package</phase> | ||||||
| @@ -295,7 +191,7 @@ | |||||||
|                     <plugin> |                     <plugin> | ||||||
|                         <groupId>org.projectlombok</groupId> |                         <groupId>org.projectlombok</groupId> | ||||||
|                         <artifactId>lombok-maven-plugin</artifactId> |                         <artifactId>lombok-maven-plugin</artifactId> | ||||||
|                         <version>1.18.20.0</version> |                         <version>1.18.10.0</version> | ||||||
|                         <executions> |                         <executions> | ||||||
|                             <execution> |                             <execution> | ||||||
|                                 <phase>package</phase> |                                 <phase>package</phase> | ||||||
| @@ -309,17 +205,11 @@ | |||||||
|                             <outputDirectory>${project.build.directory}/delombok</outputDirectory> |                             <outputDirectory>${project.build.directory}/delombok</outputDirectory> | ||||||
|                             <sourceDirectory>${project.build.sourceDirectory}</sourceDirectory> |                             <sourceDirectory>${project.build.sourceDirectory}</sourceDirectory> | ||||||
|                         </configuration> |                         </configuration> | ||||||
|                         <dependencies> |  | ||||||
|                             <dependency> |  | ||||||
|                                 <groupId>org.projectlombok</groupId> |  | ||||||
|                                 <artifactId>lombok</artifactId> |  | ||||||
|                                 <version>${lombok.version}</version> |  | ||||||
|                             </dependency> |  | ||||||
|                         </dependencies> |  | ||||||
|                     </plugin> |                     </plugin> | ||||||
|                     <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.2.0</version> | ||||||
|                         <executions> |                         <executions> | ||||||
|                             <!-- Execute Javadoc once normally to catch any warnings --> |                             <!-- Execute Javadoc once normally to catch any warnings --> | ||||||
|                             <execution> |                             <execution> | ||||||
| @@ -357,7 +247,7 @@ | |||||||
|                     <plugin> |                     <plugin> | ||||||
|                         <groupId>org.apache.maven.plugins</groupId> |                         <groupId>org.apache.maven.plugins</groupId> | ||||||
|                         <artifactId>maven-gpg-plugin</artifactId> |                         <artifactId>maven-gpg-plugin</artifactId> | ||||||
|                         <version>3.2.4</version> |                         <version>1.6</version> | ||||||
|                         <executions> |                         <executions> | ||||||
|                             <execution> |                             <execution> | ||||||
|                                 <phase>verify</phase> |                                 <phase>verify</phase> | ||||||
|   | |||||||
| @@ -6,32 +6,38 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>net.md-5</groupId> |         <groupId>net.md-5</groupId> | ||||||
|         <artifactId>bungeecord-parent</artifactId> |         <artifactId>bungeecord-parent</artifactId> | ||||||
|         <version>1.20-R0.3-SNAPSHOT</version> |         <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|         <relativePath>../pom.xml</relativePath> |         <relativePath>../pom.xml</relativePath> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <groupId>net.md-5</groupId> |     <groupId>net.md-5</groupId> | ||||||
|     <artifactId>bungeecord-protocol</artifactId> |     <artifactId>bungeecord-protocol</artifactId> | ||||||
|     <version>1.20-R0.3-SNAPSHOT</version> |     <version>1.16-R0.4-SNAPSHOT</version> | ||||||
|     <packaging>jar</packaging> |     <packaging>jar</packaging> | ||||||
|  |  | ||||||
|     <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> | ||||||
| @@ -43,6 +49,7 @@ | |||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>io.netty</groupId> |             <groupId>io.netty</groupId> | ||||||
|             <artifactId>netty-codec</artifactId> |             <artifactId>netty-codec</artifactId> | ||||||
|  |             <version>${netty.version}</version> | ||||||
|             <scope>compile</scope> |             <scope>compile</scope> | ||||||
|         </dependency> |         </dependency> | ||||||
|         <dependency> |         <dependency> | ||||||
|   | |||||||
| @@ -2,18 +2,12 @@ package net.md_5.bungee.protocol; | |||||||
|  |  | ||||||
| import net.md_5.bungee.protocol.packet.BossBar; | import net.md_5.bungee.protocol.packet.BossBar; | ||||||
| import net.md_5.bungee.protocol.packet.Chat; | import net.md_5.bungee.protocol.packet.Chat; | ||||||
| import net.md_5.bungee.protocol.packet.ClearTitles; |  | ||||||
| import net.md_5.bungee.protocol.packet.ClientChat; |  | ||||||
| import net.md_5.bungee.protocol.packet.ClientCommand; |  | ||||||
| import net.md_5.bungee.protocol.packet.ClientSettings; | import net.md_5.bungee.protocol.packet.ClientSettings; | ||||||
| import net.md_5.bungee.protocol.packet.ClientStatus; | import net.md_5.bungee.protocol.packet.ClientStatus; | ||||||
| import net.md_5.bungee.protocol.packet.Commands; | import net.md_5.bungee.protocol.packet.Commands; | ||||||
| import net.md_5.bungee.protocol.packet.CookieRequest; |  | ||||||
| import net.md_5.bungee.protocol.packet.CookieResponse; |  | ||||||
| import net.md_5.bungee.protocol.packet.EncryptionRequest; | import net.md_5.bungee.protocol.packet.EncryptionRequest; | ||||||
| import net.md_5.bungee.protocol.packet.EncryptionResponse; | import net.md_5.bungee.protocol.packet.EncryptionResponse; | ||||||
| import net.md_5.bungee.protocol.packet.EntityStatus; | import net.md_5.bungee.protocol.packet.EntityStatus; | ||||||
| import net.md_5.bungee.protocol.packet.FinishConfiguration; |  | ||||||
| import net.md_5.bungee.protocol.packet.GameState; | import net.md_5.bungee.protocol.packet.GameState; | ||||||
| import net.md_5.bungee.protocol.packet.Handshake; | import net.md_5.bungee.protocol.packet.Handshake; | ||||||
| import net.md_5.bungee.protocol.packet.KeepAlive; | import net.md_5.bungee.protocol.packet.KeepAlive; | ||||||
| @@ -21,7 +15,6 @@ import net.md_5.bungee.protocol.packet.Kick; | |||||||
| import net.md_5.bungee.protocol.packet.LegacyHandshake; | import net.md_5.bungee.protocol.packet.LegacyHandshake; | ||||||
| import net.md_5.bungee.protocol.packet.LegacyPing; | import net.md_5.bungee.protocol.packet.LegacyPing; | ||||||
| import net.md_5.bungee.protocol.packet.Login; | import net.md_5.bungee.protocol.packet.Login; | ||||||
| import net.md_5.bungee.protocol.packet.LoginAcknowledged; |  | ||||||
| import net.md_5.bungee.protocol.packet.LoginPayloadRequest; | import net.md_5.bungee.protocol.packet.LoginPayloadRequest; | ||||||
| import net.md_5.bungee.protocol.packet.LoginPayloadResponse; | import net.md_5.bungee.protocol.packet.LoginPayloadResponse; | ||||||
| import net.md_5.bungee.protocol.packet.LoginRequest; | import net.md_5.bungee.protocol.packet.LoginRequest; | ||||||
| @@ -29,29 +22,18 @@ import net.md_5.bungee.protocol.packet.LoginSuccess; | |||||||
| import net.md_5.bungee.protocol.packet.PingPacket; | import net.md_5.bungee.protocol.packet.PingPacket; | ||||||
| import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter; | import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter; | ||||||
| import net.md_5.bungee.protocol.packet.PlayerListItem; | import net.md_5.bungee.protocol.packet.PlayerListItem; | ||||||
| import net.md_5.bungee.protocol.packet.PlayerListItemRemove; |  | ||||||
| import net.md_5.bungee.protocol.packet.PlayerListItemUpdate; |  | ||||||
| import net.md_5.bungee.protocol.packet.PluginMessage; | import net.md_5.bungee.protocol.packet.PluginMessage; | ||||||
| import net.md_5.bungee.protocol.packet.Respawn; | 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.SetCompression; | import net.md_5.bungee.protocol.packet.SetCompression; | ||||||
| import net.md_5.bungee.protocol.packet.StartConfiguration; |  | ||||||
| import net.md_5.bungee.protocol.packet.StatusRequest; | import net.md_5.bungee.protocol.packet.StatusRequest; | ||||||
| import net.md_5.bungee.protocol.packet.StatusResponse; | import net.md_5.bungee.protocol.packet.StatusResponse; | ||||||
| import net.md_5.bungee.protocol.packet.StoreCookie; |  | ||||||
| import net.md_5.bungee.protocol.packet.Subtitle; |  | ||||||
| import net.md_5.bungee.protocol.packet.SystemChat; |  | ||||||
| import net.md_5.bungee.protocol.packet.TabCompleteRequest; | import net.md_5.bungee.protocol.packet.TabCompleteRequest; | ||||||
| import net.md_5.bungee.protocol.packet.TabCompleteResponse; | import net.md_5.bungee.protocol.packet.TabCompleteResponse; | ||||||
| import net.md_5.bungee.protocol.packet.Team; | import net.md_5.bungee.protocol.packet.Team; | ||||||
| import net.md_5.bungee.protocol.packet.Title; | import net.md_5.bungee.protocol.packet.Title; | ||||||
| import net.md_5.bungee.protocol.packet.TitleTimes; |  | ||||||
| import net.md_5.bungee.protocol.packet.Transfer; |  | ||||||
| import net.md_5.bungee.protocol.packet.UnsignedClientCommand; |  | ||||||
| import net.md_5.bungee.protocol.packet.ViewDistance; | import net.md_5.bungee.protocol.packet.ViewDistance; | ||||||
|  |  | ||||||
| public abstract class AbstractPacketHandler | public abstract class AbstractPacketHandler | ||||||
| @@ -93,22 +75,6 @@ public abstract class AbstractPacketHandler | |||||||
|     { |     { | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void handle(ClientChat chat) throws Exception |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public void handle(SystemChat chat) throws Exception |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public void handle(ClientCommand command) throws Exception |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public void handle(UnsignedClientCommand command) throws Exception |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public void handle(Respawn respawn) throws Exception |     public void handle(Respawn respawn) throws Exception | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| @@ -129,14 +95,6 @@ public abstract class AbstractPacketHandler | |||||||
|     { |     { | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void handle(PlayerListItemRemove playerListItem) throws Exception |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public void handle(PlayerListItemUpdate playerListItem) throws Exception |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public void handle(PlayerListHeaderFooter playerListHeaderFooter) throws Exception |     public void handle(PlayerListHeaderFooter playerListHeaderFooter) throws Exception | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| @@ -153,10 +111,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 | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| @@ -173,18 +127,6 @@ public abstract class AbstractPacketHandler | |||||||
|     { |     { | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void handle(Subtitle title) throws Exception |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public void handle(TitleTimes title) throws Exception |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public void handle(ClearTitles title) throws Exception |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public void handle(PluginMessage pluginMessage) throws Exception |     public void handle(PluginMessage pluginMessage) throws Exception | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| @@ -236,36 +178,4 @@ public abstract class AbstractPacketHandler | |||||||
|     public void handle(GameState gameState) throws Exception |     public void handle(GameState gameState) throws Exception | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void handle(ServerData serverData) throws Exception |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public void handle(LoginAcknowledged loginAcknowledged) throws Exception |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public void handle(StartConfiguration startConfiguration) throws Exception |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public void handle(FinishConfiguration finishConfiguration) throws Exception |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public void handle(Transfer transfer) throws Exception |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public void handle(StoreCookie storeCookie) throws Exception |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public void handle(CookieRequest cookieRequest) throws Exception |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public void handle(CookieResponse cookieResponse) throws Exception |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,82 +0,0 @@ | |||||||
| package net.md_5.bungee.protocol; |  | ||||||
|  |  | ||||||
| import com.google.common.base.Preconditions; |  | ||||||
| import io.netty.buffer.ByteBuf; |  | ||||||
| import java.util.LinkedList; |  | ||||||
| import java.util.List; |  | ||||||
| import java.util.UUID; |  | ||||||
| import lombok.AllArgsConstructor; |  | ||||||
| import lombok.Data; |  | ||||||
| import lombok.EqualsAndHashCode; |  | ||||||
| import lombok.NoArgsConstructor; |  | ||||||
|  |  | ||||||
| @Data |  | ||||||
| @NoArgsConstructor |  | ||||||
| @AllArgsConstructor |  | ||||||
| @EqualsAndHashCode(callSuper = false) |  | ||||||
| public class ChatChain extends DefinedPacket |  | ||||||
| { |  | ||||||
|  |  | ||||||
|     private List<ChainLink> seen; |  | ||||||
|     private List<ChainLink> received; |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) |  | ||||||
|     { |  | ||||||
|         seen = readLinks( buf ); |  | ||||||
|         if ( buf.readBoolean() ) |  | ||||||
|         { |  | ||||||
|             received = readLinks( buf ); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private static List<ChainLink> readLinks(ByteBuf buf) |  | ||||||
|     { |  | ||||||
|         int cnt = readVarInt( buf ); |  | ||||||
|         Preconditions.checkArgument( cnt <= 5, "Too many entries" ); |  | ||||||
|         List<ChainLink> chain = new LinkedList<>(); |  | ||||||
|         for ( int i = 0; i < cnt; i++ ) |  | ||||||
|         { |  | ||||||
|             chain.add( new ChainLink( readUUID( buf ), readArray( buf ) ) ); |  | ||||||
|         } |  | ||||||
|         return chain; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) |  | ||||||
|     { |  | ||||||
|         writeLinks( seen, buf ); |  | ||||||
|         if ( received != null ) |  | ||||||
|         { |  | ||||||
|             buf.writeBoolean( true ); |  | ||||||
|             writeLinks( received, buf ); |  | ||||||
|         } else |  | ||||||
|         { |  | ||||||
|             buf.writeBoolean( false ); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private static void writeLinks(List<ChainLink> links, ByteBuf buf) |  | ||||||
|     { |  | ||||||
|         writeVarInt( links.size(), buf ); |  | ||||||
|         for ( ChainLink link : links ) |  | ||||||
|         { |  | ||||||
|             writeUUID( link.sender, buf ); |  | ||||||
|             writeArray( link.signature, buf ); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void handle(AbstractPacketHandler handler) throws Exception |  | ||||||
|     { |  | ||||||
|         throw new UnsupportedOperationException( "Not supported." ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Data |  | ||||||
|     public static class ChainLink |  | ||||||
|     { |  | ||||||
|  |  | ||||||
|         private final UUID sender; |  | ||||||
|         private final byte[] signature; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user