Compare commits
	
		
			11 Commits
		
	
	
		
			ec963ef691
			...
			cf36174de7
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| cf36174de7 | |||
| b7f0cc4217 | |||
| a0f6d000ec | |||
| ca3323c00f | |||
| f52180c385 | |||
| 949cde9e2b | |||
|   | 497c6879e0 | ||
|   | 7b27dfaf5e | ||
|   | f9b75c4a3a | ||
|   | 0509303fd3 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | f486a251f3 | 
							
								
								
									
										11
									
								
								api/pom.xml
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								api/pom.xml
									
									
									
									
									
								
							| @@ -4,13 +4,12 @@ | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|  | ||||
|     <parent> | ||||
|         <groupId>net.md-5</groupId> | ||||
|         <groupId>fr.pandacube.bungeecord</groupId> | ||||
|         <artifactId>bungeecord-parent</artifactId> | ||||
|         <version>1.20-R0.2-SNAPSHOT</version> | ||||
|         <relativePath>../pom.xml</relativePath> | ||||
|     </parent> | ||||
|  | ||||
|     <groupId>net.md-5</groupId> | ||||
|     <artifactId>bungeecord-api</artifactId> | ||||
|     <version>1.20-R0.2-SNAPSHOT</version> | ||||
|     <packaging>jar</packaging> | ||||
| @@ -20,25 +19,25 @@ | ||||
|  | ||||
|     <dependencies> | ||||
|         <dependency> | ||||
|             <groupId>net.md-5</groupId> | ||||
|             <groupId>fr.pandacube.bungeecord</groupId> | ||||
|             <artifactId>bungeecord-chat</artifactId> | ||||
|             <version>${project.version}</version> | ||||
|             <scope>compile</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>net.md-5</groupId> | ||||
|             <groupId>fr.pandacube.bungeecord</groupId> | ||||
|             <artifactId>bungeecord-config</artifactId> | ||||
|             <version>${project.version}</version> | ||||
|             <scope>compile</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>net.md-5</groupId> | ||||
|             <groupId>fr.pandacube.bungeecord</groupId> | ||||
|             <artifactId>bungeecord-event</artifactId> | ||||
|             <version>${project.version}</version> | ||||
|             <scope>compile</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>net.md-5</groupId> | ||||
|             <groupId>fr.pandacube.bungeecord</groupId> | ||||
|             <artifactId>bungeecord-protocol</artifactId> | ||||
|             <version>${project.version}</version> | ||||
|             <scope>compile</scope> | ||||
|   | ||||
| @@ -0,0 +1,157 @@ | ||||
| package net.md_5.bungee.api.event; | ||||
|  | ||||
| import com.mojang.brigadier.arguments.ArgumentType; | ||||
| import com.mojang.brigadier.arguments.IntegerArgumentType; | ||||
| import com.mojang.brigadier.arguments.StringArgumentType; | ||||
| import com.mojang.brigadier.builder.ArgumentBuilder; | ||||
| import com.mojang.brigadier.builder.RequiredArgumentBuilder; | ||||
| import com.mojang.brigadier.suggestion.SuggestionProvider; | ||||
| import com.mojang.brigadier.tree.CommandNode; | ||||
| import com.mojang.brigadier.tree.RootCommandNode; | ||||
| import lombok.AccessLevel; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| import lombok.Setter; | ||||
| import lombok.ToString; | ||||
| import net.md_5.bungee.api.CommandSender; | ||||
| import net.md_5.bungee.api.connection.Connection; | ||||
| import net.md_5.bungee.api.plugin.Command; | ||||
| import net.md_5.bungee.api.plugin.Plugin; | ||||
| import net.md_5.bungee.api.plugin.PluginManager; | ||||
| import net.md_5.bungee.api.plugin.TabExecutor; | ||||
|  | ||||
| /** | ||||
|  * Event called when a downstream server (on 1.13+) sends the command structure | ||||
|  * to a player, but before BungeeCord adds the dummy command nodes of | ||||
|  * registered commands. | ||||
|  * <p> | ||||
|  * BungeeCord will not overwrite the modifications made by the listeners. | ||||
|  * | ||||
|  * <h2>Usage example</h2> | ||||
|  * Here is a usage example of this event, to declare a command structure. | ||||
|  * This illustrates the commands /server and /send of Bungee. | ||||
|  * <pre> | ||||
|  * event.getRoot().addChild( LiteralArgumentBuilder.<CommandSender>literal( "server" ) | ||||
|  *         .requires( sender -> sender.hasPermission( "bungeecord.command.server" ) ) | ||||
|  *         .executes( a -> 0 ) | ||||
|  *         .then( RequiredArgumentBuilder.argument( "serverName", StringArgumentType.greedyString() ) | ||||
|  *                 .suggests( SuggestionRegistry.ASK_SERVER ) | ||||
|  *         ) | ||||
|  *         .build() | ||||
|  * ); | ||||
|  * event.getRoot().addChild( LiteralArgumentBuilder.<CommandSender>literal( "send" ) | ||||
|  *         .requires( sender -> sender.hasPermission( "bungeecord.command.send" ) ) | ||||
|  *         .then( RequiredArgumentBuilder.argument( "playerName", StringArgumentType.word() ) | ||||
|  *                 .suggests( SuggestionRegistry.ASK_SERVER ) | ||||
|  *                 .then( RequiredArgumentBuilder.argument( "serverName", StringArgumentType.greedyString() ) | ||||
|  *                         .suggests( SuggestionRegistry.ASK_SERVER ) | ||||
|  *                 ) | ||||
|  *         ) | ||||
|  *         .build() | ||||
|  * ); | ||||
|  * </pre> | ||||
|  * | ||||
|  * <h2>Flag a {@link CommandNode} as executable or not</h2> | ||||
|  * The implementation of a {@link com.mojang.brigadier.Command Command} used in | ||||
|  * {@link ArgumentBuilder#executes(com.mojang.brigadier.Command)} will never be | ||||
|  * executed. This will only tell to the client if the current node is | ||||
|  * executable or not. | ||||
|  * <ul> | ||||
|  *     <li> | ||||
|  *         {@code builder.executes(null)} (default) to mark the node as not | ||||
|  *         executable. | ||||
|  *     </li> | ||||
|  *     <li> | ||||
|  *         {@code builder.executes(a -> 0)}, or any non null argument, to mark | ||||
|  *         the node as executable (the child arguments are displayed as | ||||
|  *         optional). | ||||
|  *     </li> | ||||
|  * </ul> | ||||
|  * | ||||
|  * <h2>{@link CommandNode}’s suggestions management</h2> | ||||
|  * The implementation of a SuggestionProvider used in | ||||
|  * {@link RequiredArgumentBuilder#suggests(SuggestionProvider)} will never be | ||||
|  * executed. This will only tell to the client how to deal with the | ||||
|  * auto-completion of the argument. | ||||
|  * <ul> | ||||
|  *     <li> | ||||
|  *         {@code builder.suggests(null)} (default) to disable auto-completion | ||||
|  *         for this argument. | ||||
|  *     </li> | ||||
|  *     <li> | ||||
|  *         {@code builder.suggests(SuggestionRegistry.ALL_RECIPES)} to suggest | ||||
|  *         Minecraft’s recipes. | ||||
|  *     </li> | ||||
|  *     <li> | ||||
|  *         {@code builder.suggests(SuggestionRegistry.AVAILABLE_SOUNDS)} to | ||||
|  *         suggest Minecraft’s default sound identifiers. | ||||
|  *     </li> | ||||
|  *     <li> | ||||
|  *         {@code builder.suggests(SuggestionRegistry.SUMMONABLE_ENTITIES)} to | ||||
|  *         suggest Minecraft’s default summonable entities identifiers. | ||||
|  *     </li> | ||||
|  *     <li> | ||||
|  *         {@code builder.suggests(SuggestionRegistry.ASK_SERVER)}, or any | ||||
|  *         other non null argument, to make the Minecraft client ask | ||||
|  *         auto-completion to the server. Any specified implementation of | ||||
|  *         {@link SuggestionProvider} will never be executed. | ||||
|  *     </li> | ||||
|  * </ul> | ||||
|  * | ||||
|  * <h2>Argument types</h2> | ||||
|  * When building a new argument command node using | ||||
|  * {@link RequiredArgumentBuilder#argument(String, ArgumentType)}, you have to | ||||
|  * specify an {@link ArgumentType}. You can use all subclasses of | ||||
|  * {@link ArgumentType} provided with brigadier (for instance, | ||||
|  * {@link StringArgumentType} or {@link IntegerArgumentType}), or call any | ||||
|  * {@code ArgumentRegistry.minecraft*()} methods to use a {@code minecraft:*} | ||||
|  * argument type. | ||||
|  * | ||||
|  * <h2>Limitations with brigadier API</h2> | ||||
|  * This event is only used for the client to show command syntax, suggest | ||||
|  * sub-commands and color the arguments in the chat box. The command execution | ||||
|  * needs to be implemented using {@link PluginManager#registerCommand(Plugin, | ||||
|  * Command)} and the server-side tab-completion using {@link TabCompleteEvent} | ||||
|  * or {@link TabExecutor}. | ||||
|  */ | ||||
| @Data | ||||
| @ToString(callSuper = true) | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
| public class CommandsDeclareEvent extends TargetedEvent | ||||
| { | ||||
|     /** | ||||
|      * Wether or not the command tree is modified by this event. | ||||
|      * | ||||
|      * If this value is set to true, BungeeCord will ensure that the | ||||
|      * modifications made in the command tree, will be sent to the player. | ||||
|      * If this is false, the modifications may not be taken into account. | ||||
|      * | ||||
|      * When calling {@link #getRoot()}, this value is automatically set | ||||
|      * to true. | ||||
|      */ | ||||
|     @Setter(value = AccessLevel.NONE) | ||||
|     private boolean modified = false; | ||||
|  | ||||
|     /** | ||||
|      * The root command node of the command structure that will be send to the | ||||
|      * player. | ||||
|      */ | ||||
|     private final RootCommandNode<CommandSender> root; | ||||
|  | ||||
|     public CommandsDeclareEvent(Connection sender, Connection receiver, RootCommandNode<CommandSender> root) | ||||
|     { | ||||
|         super( sender, receiver ); | ||||
|         this.root = root; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The root command node of the command structure that will be send to the | ||||
|      * player. | ||||
|      * @return The root command node | ||||
|      */ | ||||
|     public RootCommandNode<CommandSender> getRoot() | ||||
|     { | ||||
|         modified = true; | ||||
|         return root; | ||||
|     } | ||||
| } | ||||
| @@ -9,7 +9,9 @@ import net.md_5.bungee.api.plugin.Cancellable; | ||||
|  | ||||
| /** | ||||
|  * Event called when a player uses tab completion. | ||||
|  * @deprecated please use {@link TabCompleteRequestEvent} to support 1.13+ suggestions. | ||||
|  */ | ||||
| @Deprecated | ||||
| @Data | ||||
| @ToString(callSuper = true) | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
|   | ||||
| @@ -0,0 +1,85 @@ | ||||
| package net.md_5.bungee.api.event; | ||||
|  | ||||
| import com.google.common.base.Preconditions; | ||||
| import com.mojang.brigadier.context.StringRange; | ||||
| import com.mojang.brigadier.suggestion.Suggestions; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| import lombok.ToString; | ||||
| import net.md_5.bungee.api.connection.Connection; | ||||
| import net.md_5.bungee.api.connection.ProxiedPlayer; | ||||
| import net.md_5.bungee.api.plugin.Cancellable; | ||||
| import net.md_5.bungee.protocol.ProtocolConstants; | ||||
|  | ||||
| /** | ||||
|  * Event called when a player uses tab completion. | ||||
|  */ | ||||
| @Data | ||||
| @ToString(callSuper = true) | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
| public class TabCompleteRequestEvent extends TargetedEvent implements Cancellable | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * Cancelled state. | ||||
|      */ | ||||
|     private boolean cancelled; | ||||
|     /** | ||||
|      * The message the player has already entered. | ||||
|      */ | ||||
|     private final String cursor; | ||||
|     /** | ||||
|      * Range corresponding to the last word of {@link #getCursor()}. | ||||
|      * If you want your suggestions to be compatible with 1.12 and older | ||||
|      * clients, you need to {@link #setSuggestions(Suggestions)} with | ||||
|      * a range equals to this one. | ||||
|      * For 1.13 and newer clients, any other range that cover any part of | ||||
|      * {@link #getCursor()} is fine.<br> | ||||
|      * To check if the client supports custom ranges, use | ||||
|      * {@link #supportsCustomRange()}. | ||||
|      */ | ||||
|     private final StringRange legacyCompatibleRange; | ||||
|     /** | ||||
|      * The suggestions that will be sent to the client. If this list is empty, | ||||
|      * the request will be forwarded to the server. | ||||
|      */ | ||||
|     private Suggestions suggestions; | ||||
|  | ||||
|     public TabCompleteRequestEvent(Connection sender, Connection receiver, String cursor, StringRange legacyCompatibleRange, Suggestions suggestions) | ||||
|     { | ||||
|         super( sender, receiver ); | ||||
|         this.cursor = cursor; | ||||
|         this.legacyCompatibleRange = legacyCompatibleRange; | ||||
|         this.suggestions = suggestions; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets the suggestions that will be sent to the client. | ||||
|      * If this list is empty, the request will be forwarded to the server. | ||||
|      * @param suggestions the new Suggestions. Cannot be null. | ||||
|      * @throws IllegalArgumentException if the client is on 1.12 or lower and | ||||
|      * {@code suggestions.getRange()} is not equals to {@link #legacyCompatibleRange}. | ||||
|      */ | ||||
|     public void setSuggestions(Suggestions suggestions) | ||||
|     { | ||||
|         Preconditions.checkNotNull( suggestions ); | ||||
|         Preconditions.checkArgument( supportsCustomRange() || legacyCompatibleRange.equals( suggestions.getRange() ), | ||||
|                 "Clients on 1.12 or lower versions don't support the provided range for tab-completion: " + suggestions.getRange() | ||||
|                 + ". Please use TabCompleteRequestEvent.getLegacyCompatibleRange() for legacy clients." ); | ||||
|         this.suggestions = suggestions; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Convenient method to tell if the client supports custom range for | ||||
|      * suggestions. | ||||
|      * If the client is on 1.13 or above, this methods returns true, and any | ||||
|      * range can be used for {@link #setSuggestions(Suggestions)}. Otherwise, | ||||
|      * it returns false and the defined range must be equals to | ||||
|      * {@link #legacyCompatibleRange}. | ||||
|      * @return true if the client is on 1.13 or newer version, false otherwise. | ||||
|      */ | ||||
|     public boolean supportsCustomRange() | ||||
|     { | ||||
|         return ( (ProxiedPlayer) getSender() ).getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_13; | ||||
|     } | ||||
| } | ||||
| @@ -1,12 +1,13 @@ | ||||
| package net.md_5.bungee.api; | ||||
|  | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
| import java.net.InetSocketAddress; | ||||
| import java.net.SocketAddress; | ||||
| import java.util.Collection; | ||||
| import net.md_5.bungee.api.config.ServerInfo; | ||||
| import net.md_5.bungee.api.connection.ProxiedPlayer; | ||||
| import net.md_5.bungee.api.event.ServerConnectEvent; | ||||
| import org.junit.Test; | ||||
| import org.junit.jupiter.api.Test; | ||||
|  | ||||
| public class ServerConnectRequestTest | ||||
| { | ||||
| @@ -78,15 +79,15 @@ public class ServerConnectRequestTest | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     @Test(expected = NullPointerException.class) | ||||
|     @Test | ||||
|     public void testNullTarget() | ||||
|     { | ||||
|         ServerConnectRequest.builder().target( null ).reason( ServerConnectEvent.Reason.JOIN_PROXY ).build(); | ||||
|         assertThrows( NullPointerException.class, () -> ServerConnectRequest.builder().target( null ).reason( ServerConnectEvent.Reason.JOIN_PROXY ).build() ); | ||||
|     } | ||||
|  | ||||
|     @Test(expected = NullPointerException.class) | ||||
|     @Test | ||||
|     public void testNullReason() | ||||
|     { | ||||
|         ServerConnectRequest.builder().target( DUMMY_INFO ).reason( null ).build(); | ||||
|         assertThrows( NullPointerException.class, () -> ServerConnectRequest.builder().target( DUMMY_INFO ).reason( null ).build() ); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,63 +1,38 @@ | ||||
| package net.md_5.bungee.util; | ||||
|  | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
| import io.netty.channel.unix.DomainSocketAddress; | ||||
| import java.net.InetSocketAddress; | ||||
| import java.net.SocketAddress; | ||||
| import java.util.Arrays; | ||||
| import java.util.Collection; | ||||
| import java.util.stream.Stream; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import net.md_5.bungee.Util; | ||||
| import org.junit.Assert; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.junit.runners.Parameterized; | ||||
| import org.junit.runners.Parameterized.Parameters; | ||||
| import org.junit.jupiter.params.ParameterizedTest; | ||||
| import org.junit.jupiter.params.provider.Arguments; | ||||
| import org.junit.jupiter.params.provider.MethodSource; | ||||
|  | ||||
| @RequiredArgsConstructor | ||||
| @RunWith(Parameterized.class) | ||||
| public class AddressParseTest | ||||
| { | ||||
|  | ||||
|     @Parameters | ||||
|     public static Collection<Object[]> data() | ||||
|     public static Stream<Arguments> data() | ||||
|     { | ||||
|         return Arrays.asList( new Object[][] | ||||
|         { | ||||
|             { | ||||
|                 "127.0.0.1", "127.0.0.1", Util.DEFAULT_PORT | ||||
|             }, | ||||
|             { | ||||
|                 "127.0.0.1:1337", "127.0.0.1", 1337 | ||||
|             }, | ||||
|             { | ||||
|                 "[::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 | ||||
|             } | ||||
|         } ); | ||||
|         return Stream.of( | ||||
|                 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 ), | ||||
|                 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 ), | ||||
|                 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 ) | ||||
|         ); | ||||
|     } | ||||
|     private final String line; | ||||
|     private final String host; | ||||
|     private final int port; | ||||
|  | ||||
|     @Test | ||||
|     public void test() | ||||
|     @ParameterizedTest | ||||
|     @MethodSource("data") | ||||
|     public void test(String line, String host, int port) | ||||
|     { | ||||
|         SocketAddress parsed = Util.getAddr( line ); | ||||
|  | ||||
| @@ -65,14 +40,14 @@ public class AddressParseTest | ||||
|         { | ||||
|             InetSocketAddress tcp = (InetSocketAddress) parsed; | ||||
|  | ||||
|             Assert.assertEquals( host, tcp.getHostString() ); | ||||
|             Assert.assertEquals( port, tcp.getPort() ); | ||||
|             assertEquals( host, tcp.getHostString() ); | ||||
|             assertEquals( port, tcp.getPort() ); | ||||
|         } else if ( parsed instanceof DomainSocketAddress ) | ||||
|         { | ||||
|             DomainSocketAddress unix = (DomainSocketAddress) parsed; | ||||
|  | ||||
|             Assert.assertEquals( host, unix.path() ); | ||||
|             Assert.assertEquals( -1, port ); | ||||
|             assertEquals( host, unix.path() ); | ||||
|             assertEquals( -1, port ); | ||||
|         } else | ||||
|         { | ||||
|             throw new AssertionError( "Unknown socket " + parsed ); | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| package net.md_5.bungee.util; | ||||
|  | ||||
| import org.junit.Assert; | ||||
| import org.junit.Test; | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
| import org.junit.jupiter.api.Test; | ||||
|  | ||||
| public class CaseInsensitiveTest | ||||
| { | ||||
| @@ -13,12 +13,12 @@ public class CaseInsensitiveTest | ||||
|         CaseInsensitiveMap<Object> map = new CaseInsensitiveMap<>(); | ||||
|  | ||||
|         map.put( "FOO", obj ); | ||||
|         Assert.assertTrue( map.contains( "foo" ) ); // Assert that contains is case insensitive | ||||
|         Assert.assertTrue( map.entrySet().iterator().next().getKey().equals( "FOO" ) ); // Assert that case is preserved | ||||
|         assertTrue( map.contains( "foo" ) ); // Assert that contains is case insensitive | ||||
|         assertTrue( map.entrySet().iterator().next().getKey().equals( "FOO" ) ); // Assert that case is preserved | ||||
|  | ||||
|         // Assert that remove is case insensitive | ||||
|         map.remove( "FoO" ); | ||||
|         Assert.assertFalse( map.contains( "foo" ) ); | ||||
|         assertFalse( map.contains( "foo" ) ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -27,8 +27,8 @@ public class CaseInsensitiveTest | ||||
|         CaseInsensitiveSet set = new CaseInsensitiveSet(); | ||||
|  | ||||
|         set.add( "FOO" ); | ||||
|         Assert.assertTrue( set.contains( "foo" ) ); // Assert that contains is case insensitive | ||||
|         assertTrue( set.contains( "foo" ) ); // Assert that contains is case insensitive | ||||
|         set.remove( "FoO" ); | ||||
|         Assert.assertFalse( set.contains( "foo" ) ); // Assert that remove is case insensitive | ||||
|         assertFalse( set.contains( "foo" ) ); // Assert that remove is case insensitive | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| package net.md_5.bungee.util; | ||||
|  | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
| import java.util.UUID; | ||||
| import net.md_5.bungee.Util; | ||||
| import org.junit.Assert; | ||||
| import org.junit.Test; | ||||
| import org.junit.jupiter.api.Test; | ||||
|  | ||||
| public class UUIDTest | ||||
| { | ||||
| @@ -13,7 +13,7 @@ public class UUIDTest | ||||
|     { | ||||
|         UUID uuid = UUID.fromString( "af74a02d-19cb-445b-b07f-6866a861f783" ); | ||||
|         UUID uuid1 = Util.getUUID( "af74a02d19cb445bb07f6866a861f783" ); | ||||
|         Assert.assertEquals( uuid, uuid1 ); | ||||
|         assertEquals( uuid, uuid1 ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -23,7 +23,7 @@ public class UUIDTest | ||||
|         { | ||||
|             UUID expected = UUID.randomUUID(); | ||||
|             UUID actual = Util.getUUID( expected.toString().replace( "-", "" ) ); | ||||
|             Assert.assertEquals( "Could not parse UUID " + expected, expected, actual ); | ||||
|             assertEquals( expected, actual, "Could not parse UUID " + expected ); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -4,13 +4,12 @@ | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|  | ||||
|     <parent> | ||||
|         <groupId>net.md-5</groupId> | ||||
|         <groupId>fr.pandacube.bungeecord</groupId> | ||||
|         <artifactId>bungeecord-parent</artifactId> | ||||
|         <version>1.20-R0.2-SNAPSHOT</version> | ||||
|         <relativePath>../pom.xml</relativePath> | ||||
|     </parent> | ||||
|  | ||||
|     <groupId>net.md-5</groupId> | ||||
|     <artifactId>bungeecord-bootstrap</artifactId> | ||||
|     <version>1.20-R0.2-SNAPSHOT</version> | ||||
|     <packaging>jar</packaging> | ||||
| @@ -21,14 +20,12 @@ | ||||
|     <properties> | ||||
|         <maven.deploy.skip>true</maven.deploy.skip> | ||||
|         <maven.javadoc.skip>true</maven.javadoc.skip> | ||||
|         <maven.compiler.source>1.6</maven.compiler.source> | ||||
|         <maven.compiler.target>1.6</maven.compiler.target> | ||||
|         <maven.build.timestamp.format>yyyyMMdd</maven.build.timestamp.format> | ||||
|     </properties> | ||||
|  | ||||
|     <dependencies> | ||||
|         <dependency> | ||||
|             <groupId>net.md-5</groupId> | ||||
|             <groupId>fr.pandacube.bungeecord</groupId> | ||||
|             <artifactId>bungeecord-proxy</artifactId> | ||||
|             <version>${project.version}</version> | ||||
|             <scope>compile</scope> | ||||
|   | ||||
| @@ -4,13 +4,12 @@ | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|  | ||||
|     <parent> | ||||
|         <groupId>net.md-5</groupId> | ||||
|         <groupId>fr.pandacube.bungeecord</groupId> | ||||
|         <artifactId>bungeecord-parent</artifactId> | ||||
|         <version>1.20-R0.2-SNAPSHOT</version> | ||||
|         <relativePath>../pom.xml</relativePath> | ||||
|     </parent> | ||||
|  | ||||
|     <groupId>net.md-5</groupId> | ||||
|     <artifactId>bungeecord-chat</artifactId> | ||||
|     <version>1.20-R0.2-SNAPSHOT</version> | ||||
|     <packaging>jar</packaging> | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| package net.md_5.bungee.api.chat; | ||||
|  | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
| import java.awt.Color; | ||||
| import java.util.function.BiFunction; | ||||
| import java.util.function.Consumer; | ||||
| @@ -10,8 +11,7 @@ import net.md_5.bungee.api.ChatColor; | ||||
| import net.md_5.bungee.api.chat.hover.content.Item; | ||||
| import net.md_5.bungee.api.chat.hover.content.Text; | ||||
| import net.md_5.bungee.chat.ComponentSerializer; | ||||
| import org.junit.Assert; | ||||
| import org.junit.Test; | ||||
| import org.junit.jupiter.api.Test; | ||||
|  | ||||
| public class ComponentsTest | ||||
| { | ||||
| @@ -20,14 +20,14 @@ public class ComponentsTest | ||||
|     { | ||||
|         String json = ComponentSerializer.toString( components ); | ||||
|         BaseComponent[] parsed = ComponentSerializer.parse( json ); | ||||
|         Assert.assertEquals( TextComponent.toLegacyText( parsed ), TextComponent.toLegacyText( components ) ); | ||||
|         assertEquals( TextComponent.toLegacyText( parsed ), TextComponent.toLegacyText( components ) ); | ||||
|     } | ||||
|  | ||||
|     public static void testDissembleReassemble(BaseComponent component) | ||||
|     { | ||||
|         String json = ComponentSerializer.toString( component ); | ||||
|         BaseComponent[] parsed = ComponentSerializer.parse( json ); | ||||
|         Assert.assertEquals( TextComponent.toLegacyText( parsed ), TextComponent.toLegacyText( component ) ); | ||||
|         assertEquals( TextComponent.toLegacyText( parsed ), TextComponent.toLegacyText( component ) ); | ||||
|     } | ||||
|  | ||||
|     public static void testAssembleDissemble(String json, boolean modern) | ||||
| @@ -35,11 +35,11 @@ public class ComponentsTest | ||||
|         if ( modern ) | ||||
|         { | ||||
|             BaseComponent deserialized = ComponentSerializer.deserialize( json ); | ||||
|             Assert.assertEquals( json, ComponentSerializer.toString( deserialized ) ); | ||||
|             assertEquals( json, ComponentSerializer.toString( deserialized ) ); | ||||
|         } else | ||||
|         { | ||||
|             BaseComponent[] parsed = ComponentSerializer.parse( json ); | ||||
|             Assert.assertEquals( json, ComponentSerializer.toString( parsed ) ); | ||||
|             assertEquals( json, ComponentSerializer.toString( parsed ) ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -69,7 +69,7 @@ public class ComponentsTest | ||||
|         json = "{\"extra\":[{\"text\":\"[\"},{\"extra\":[{\"translate\":\"block.minecraft.dirt\"}],\"text\":\"\"},{\"text\":\"]\"}],\"hoverEvent\":{\"action\":\"show_item\",\"value\":[" + hoverVal + "]},\"text\":\"\"}"; | ||||
|         components = ComponentSerializer.parse( json ); | ||||
|         Text contentText = ( (Text) components[0].getHoverEvent().getContents().get( 0 ) ); | ||||
|         Assert.assertEquals( hoverVal, ComponentSerializer.toString( (BaseComponent[]) contentText.getValue() ) ); | ||||
|         assertEquals( hoverVal, ComponentSerializer.toString( (BaseComponent[]) contentText.getValue() ) ); | ||||
|         testDissembleReassemble( components ); | ||||
|         ////////// | ||||
|         TextComponent component1 = new TextComponent( "HoverableText" ); | ||||
| @@ -80,10 +80,10 @@ public class ComponentsTest | ||||
|         json = ComponentSerializer.toString( component1 ); | ||||
|         components = ComponentSerializer.parse( json ); | ||||
|         Item parsedContentItem = ( (Item) components[0].getHoverEvent().getContents().get( 0 ) ); | ||||
|         Assert.assertEquals( contentItem, parsedContentItem ); | ||||
|         Assert.assertEquals( contentItem.getCount(), parsedContentItem.getCount() ); | ||||
|         Assert.assertEquals( contentItem.getId(), parsedContentItem.getId() ); | ||||
|         Assert.assertEquals( nbt, parsedContentItem.getTag().getNbt() ); | ||||
|         assertEquals( contentItem, parsedContentItem ); | ||||
|         assertEquals( contentItem.getCount(), parsedContentItem.getCount() ); | ||||
|         assertEquals( contentItem.getId(), parsedContentItem.getId() ); | ||||
|         assertEquals( nbt, parsedContentItem.getTag().getNbt() ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -91,8 +91,8 @@ public class ComponentsTest | ||||
|     { | ||||
|         this.testEmptyComponentBuilder( | ||||
|                 ComponentBuilder::create, | ||||
|                 (components) -> Assert.assertEquals( components.length, 0 ), | ||||
|                 (components, size) -> Assert.assertEquals( size, components.length ) | ||||
|                 (components) -> assertEquals( components.length, 0 ), | ||||
|                 (components, size) -> assertEquals( size, components.length ) | ||||
|         ); | ||||
|     } | ||||
|  | ||||
| @@ -101,8 +101,8 @@ public class ComponentsTest | ||||
|     { | ||||
|         this.testEmptyComponentBuilder( | ||||
|                 ComponentBuilder::build, | ||||
|                 (component) -> Assert.assertNull( component.getExtra() ), | ||||
|                 (component, size) -> Assert.assertEquals( component.getExtra().size(), size ) | ||||
|                 (component) -> assertNull( component.getExtra() ), | ||||
|                 (component, size) -> assertEquals( component.getExtra().size(), size ) | ||||
|         ); | ||||
|     } | ||||
|  | ||||
| @@ -125,23 +125,23 @@ public class ComponentsTest | ||||
|     public void testDummyRetaining() | ||||
|     { | ||||
|         ComponentBuilder builder = new ComponentBuilder(); | ||||
|         Assert.assertNotNull( builder.getCurrentComponent() ); | ||||
|         assertNotNull( builder.getCurrentComponent() ); | ||||
|         builder.color( ChatColor.GREEN ); | ||||
|         builder.append( "test ", ComponentBuilder.FormatRetention.ALL ); | ||||
|         Assert.assertEquals( builder.getCurrentComponent().getColor(), ChatColor.GREEN ); | ||||
|         assertEquals( builder.getCurrentComponent().getColor(), ChatColor.GREEN ); | ||||
|     } | ||||
|  | ||||
|     @Test(expected = IndexOutOfBoundsException.class) | ||||
|     @Test | ||||
|     public void testComponentGettingExceptions() | ||||
|     { | ||||
|         ComponentBuilder builder = new ComponentBuilder(); | ||||
|         builder.getComponent( -1 ); | ||||
|         builder.getComponent( 0 ); | ||||
|         builder.getComponent( 1 ); | ||||
|         assertThrows( IndexOutOfBoundsException.class, () -> builder.getComponent( -1 ) ); | ||||
|         assertThrows( IndexOutOfBoundsException.class, () -> builder.getComponent( 0 ) ); | ||||
|         assertThrows( IndexOutOfBoundsException.class, () -> builder.getComponent( 1 ) ); | ||||
|         BaseComponent component = new TextComponent( "Hello" ); | ||||
|         builder.append( component ); | ||||
|         Assert.assertEquals( builder.getComponent( 0 ), component ); | ||||
|         builder.getComponent( 1 ); | ||||
|         assertEquals( builder.getComponent( 0 ), component ); | ||||
|         assertThrows( IndexOutOfBoundsException.class, () -> builder.getComponent( 1 ) ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -150,33 +150,33 @@ public class ComponentsTest | ||||
|         ComponentBuilder builder = new ComponentBuilder(); | ||||
|         TextComponent apple = new TextComponent( "apple" ); | ||||
|         builder.append( apple ); | ||||
|         Assert.assertEquals( builder.getCurrentComponent(), apple ); | ||||
|         Assert.assertEquals( builder.getComponent( 0 ), apple ); | ||||
|         assertEquals( builder.getCurrentComponent(), apple ); | ||||
|         assertEquals( builder.getComponent( 0 ), apple ); | ||||
|  | ||||
|         TextComponent mango = new TextComponent( "mango" ); | ||||
|         TextComponent orange = new TextComponent( "orange" ); | ||||
|         builder.append( mango ); | ||||
|         builder.append( orange ); | ||||
|         builder.removeComponent( 1 ); // Removing mango | ||||
|         Assert.assertEquals( builder.getComponent( 0 ), apple ); | ||||
|         Assert.assertEquals( builder.getComponent( 1 ), orange ); | ||||
|         assertEquals( builder.getComponent( 0 ), apple ); | ||||
|         assertEquals( builder.getComponent( 1 ), orange ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testToLegacyFromLegacy() | ||||
|     { | ||||
|         String text = "§a§lHello §f§kworld§7!"; | ||||
|         Assert.assertEquals( text, TextComponent.toLegacyText( TextComponent.fromLegacyText( text ) ) ); | ||||
|         assertEquals( text, TextComponent.toLegacyText( TextComponent.fromLegacyText( text ) ) ); | ||||
|     } | ||||
|  | ||||
|     @Test(expected = IndexOutOfBoundsException.class) | ||||
|     @Test | ||||
|     public void testComponentBuilderCursorInvalidPos() | ||||
|     { | ||||
|         ComponentBuilder builder = new ComponentBuilder(); | ||||
|         builder.append( new TextComponent( "Apple, " ) ); | ||||
|         builder.append( new TextComponent( "Orange, " ) ); | ||||
|         builder.setCursor( -1 ); | ||||
|         builder.setCursor( 2 ); | ||||
|         assertThrows( IndexOutOfBoundsException.class, () -> builder.setCursor( -1 ) ); | ||||
|         assertThrows( IndexOutOfBoundsException.class, () -> builder.setCursor( 2 ) ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -184,24 +184,24 @@ public class ComponentsTest | ||||
|     { | ||||
|         TextComponent t1, t2, t3; | ||||
|         ComponentBuilder builder = new ComponentBuilder(); | ||||
|         Assert.assertEquals( builder.getCursor(), -1 ); | ||||
|         assertEquals( builder.getCursor(), -1 ); | ||||
|         builder.append( t1 = new TextComponent( "Apple, " ) ); | ||||
|         Assert.assertEquals( builder.getCursor(), 0 ); | ||||
|         assertEquals( builder.getCursor(), 0 ); | ||||
|         builder.append( t2 = new TextComponent( "Orange, " ) ); | ||||
|         builder.append( t3 = new TextComponent( "Mango, " ) ); | ||||
|         Assert.assertEquals( builder.getCursor(), 2 ); | ||||
|         assertEquals( builder.getCursor(), 2 ); | ||||
|  | ||||
|         builder.setCursor( 0 ); | ||||
|         Assert.assertEquals( builder.getCurrentComponent(), t1 ); | ||||
|         assertEquals( builder.getCurrentComponent(), t1 ); | ||||
|  | ||||
|         // Test that appending new components updates the position to the new list size | ||||
|         // after having previously set it to 0 (first component) | ||||
|         builder.append( new TextComponent( "and Grapefruit" ) ); | ||||
|         Assert.assertEquals( builder.getCursor(), 3 ); | ||||
|         assertEquals( builder.getCursor(), 3 ); | ||||
|  | ||||
|         builder.setCursor( 0 ); | ||||
|         builder.resetCursor(); | ||||
|         Assert.assertEquals( builder.getCursor(), 3 ); | ||||
|         assertEquals( builder.getCursor(), 3 ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -210,7 +210,7 @@ public class ComponentsTest | ||||
|         String text = "§a§lHello §r§kworld§7!"; | ||||
|         BaseComponent[] components = TextComponent.fromLegacyText( text ); | ||||
|         BaseComponent[] builderComponents = new ComponentBuilder().append( components ).create(); | ||||
|         Assert.assertArrayEquals( components, builderComponents ); | ||||
|         assertArrayEquals( components, builderComponents ); | ||||
|     } | ||||
|  | ||||
|     /* | ||||
| @@ -232,7 +232,7 @@ public class ComponentsTest | ||||
|         component.setHoverEvent( event ); | ||||
|         String serialised = ComponentSerializer.toString( component ); | ||||
|         BaseComponent[] deserialised = ComponentSerializer.parse( serialised ); | ||||
|         Assert.assertEquals( TextComponent.toLegacyText( deserialised ), TextComponent.toLegacyText( component ) ); | ||||
|         assertEquals( TextComponent.toLegacyText( deserialised ), TextComponent.toLegacyText( component ) ); | ||||
|     } | ||||
|      */ | ||||
|  | ||||
| @@ -247,9 +247,9 @@ public class ComponentsTest | ||||
|         ); | ||||
|         TextComponent component = new TextComponent( "test" ); | ||||
|         component.setHoverEvent( hoverEvent ); | ||||
|         Assert.assertEquals( component.getHoverEvent().getContents().size(), 1 ); | ||||
|         Assert.assertTrue( component.getHoverEvent().getContents().get( 0 ) instanceof Text ); | ||||
|         Assert.assertEquals( ( (Text) component.getHoverEvent().getContents().get( 0 ) ).getValue(), advancement ); | ||||
|         assertEquals( component.getHoverEvent().getContents().size(), 1 ); | ||||
|         assertTrue( component.getHoverEvent().getContents().get( 0 ) instanceof Text ); | ||||
|         assertEquals( ( (Text) component.getHoverEvent().getContents().get( 0 ) ).getValue(), advancement ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -274,11 +274,11 @@ public class ComponentsTest | ||||
|         TextComponent component = new TextComponent( "Sample text" ); | ||||
|         component.setHoverEvent( hoverEvent ); | ||||
|  | ||||
|         Assert.assertEquals( hoverEvent.getContents().size(), 1 ); | ||||
|         Assert.assertTrue( hoverEvent.isLegacy() ); | ||||
|         assertEquals( hoverEvent.getContents().size(), 1 ); | ||||
|         assertTrue( hoverEvent.isLegacy() ); | ||||
|         String serialized = ComponentSerializer.toString( component ); | ||||
|         BaseComponent[] deserialized = ComponentSerializer.parse( serialized ); | ||||
|         Assert.assertEquals( component.getHoverEvent(), deserialized[0].getHoverEvent() ); | ||||
|         assertEquals( component.getHoverEvent(), deserialized[0].getHoverEvent() ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -303,12 +303,12 @@ public class ComponentsTest | ||||
|     { | ||||
|         TextComponent component = new TextComponent( "Sample text" ); | ||||
|         component.setHoverEvent( hoverEvent ); | ||||
|         Assert.assertEquals( hoverEvent.getContents().size(), 2 ); | ||||
|         Assert.assertFalse( hoverEvent.isLegacy() ); | ||||
|         assertEquals( hoverEvent.getContents().size(), 2 ); | ||||
|         assertFalse( hoverEvent.isLegacy() ); | ||||
|  | ||||
|         String serialized = ComponentSerializer.toString( component ); | ||||
|         T deserialized = deserializer.apply( serialized ); | ||||
|         Assert.assertEquals( component.getHoverEvent(), hoverEventGetter.apply( deserialized ) ); | ||||
|         assertEquals( component.getHoverEvent(), hoverEventGetter.apply( deserialized ) ); | ||||
|  | ||||
|         // Test single content: | ||||
|         String json = "{\"italic\":true,\"color\":\"gray\",\"translate\":\"chat.type.admin\",\"with\":[{\"text\":\"@\"}" | ||||
| @@ -345,10 +345,10 @@ public class ComponentsTest | ||||
|  | ||||
|         TextComponent second = new TextComponent( " world" ); | ||||
|         second.copyFormatting( first, ComponentBuilder.FormatRetention.ALL, true ); | ||||
|         Assert.assertEquals( first.isBold(), second.isBold() ); | ||||
|         Assert.assertEquals( first.getColor(), second.getColor() ); | ||||
|         Assert.assertEquals( first.getClickEvent(), second.getClickEvent() ); | ||||
|         Assert.assertEquals( first.getHoverEvent(), second.getHoverEvent() ); | ||||
|         assertEquals( first.isBold(), second.isBold() ); | ||||
|         assertEquals( first.getColor(), second.getColor() ); | ||||
|         assertEquals( first.getClickEvent(), second.getClickEvent() ); | ||||
|         assertEquals( first.getHoverEvent(), second.getHoverEvent() ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -368,7 +368,7 @@ public class ComponentsTest | ||||
|         ComponentBuilder builder = new ComponentBuilder( "Hello " ).color( ChatColor.RED ).append( "world" ).color( ChatColor.DARK_RED ); | ||||
|         ComponentBuilder cloned = new ComponentBuilder( builder ); | ||||
|  | ||||
|         Assert.assertEquals( legacyTextFunction.apply( builder ), legacyTextFunction.apply( cloned ) ); | ||||
|         assertEquals( legacyTextFunction.apply( builder ), legacyTextFunction.apply( cloned ) ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -403,10 +403,10 @@ public class ComponentsTest | ||||
|         ScoreComponent scoreComponent = new ScoreComponent( "myscore", "myobjective" ); | ||||
|         builder.append( scoreComponent ); // non array based BaseComponent append | ||||
|         T component = componentBuilder.apply( builder ); | ||||
|         Assert.assertEquals( "Hello ", extraGetter.apply( component, 0 ).toPlainText() ); | ||||
|         Assert.assertEquals( textComponent.toPlainText(), extraGetter.apply( component, 1 ).toPlainText() ); | ||||
|         Assert.assertEquals( translatableComponent.toPlainText(), extraGetter.apply( component, 2 ).toPlainText() ); | ||||
|         Assert.assertEquals( scoreComponent.toPlainText(), extraGetter.apply( component, 3 ).toPlainText() ); | ||||
|         assertEquals( "Hello ", extraGetter.apply( component, 0 ).toPlainText() ); | ||||
|         assertEquals( textComponent.toPlainText(), extraGetter.apply( component, 1 ).toPlainText() ); | ||||
|         assertEquals( translatableComponent.toPlainText(), extraGetter.apply( component, 2 ).toPlainText() ); | ||||
|         assertEquals( scoreComponent.toPlainText(), extraGetter.apply( component, 3 ).toPlainText() ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -416,7 +416,7 @@ public class ComponentsTest | ||||
|         String text = ComponentSerializer.toString( component ); | ||||
|         BaseComponent[] reparsed = ComponentSerializer.parse( text ); | ||||
|  | ||||
|         Assert.assertArrayEquals( component, reparsed ); | ||||
|         assertArrayEquals( component, reparsed ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -456,10 +456,10 @@ public class ComponentsTest | ||||
|  | ||||
|         T component = componentBuilder.apply( builder ); | ||||
|  | ||||
|         Assert.assertEquals( extraGetter.apply( component, 1 ).getHoverEvent(), hoverEvent ); | ||||
|         Assert.assertEquals( extraGetter.apply( component, 1 ).getClickEvent(), clickEvent ); | ||||
|         Assert.assertEquals( "Hello world!", toPlainTextFunction.apply( component ) ); | ||||
|         Assert.assertEquals( expectedLegacyText, toLegacyTextFunction.apply( component ) ); | ||||
|         assertEquals( extraGetter.apply( component, 1 ).getHoverEvent(), hoverEvent ); | ||||
|         assertEquals( extraGetter.apply( component, 1 ).getClickEvent(), clickEvent ); | ||||
|         assertEquals( "Hello world!", toPlainTextFunction.apply( component ) ); | ||||
|         assertEquals( expectedLegacyText, toLegacyTextFunction.apply( component ) ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -492,8 +492,8 @@ public class ComponentsTest | ||||
|  | ||||
|         T component = componentBuilder.apply( builder ); | ||||
|  | ||||
|         Assert.assertEquals( "Hello world!", toPlainTextFunction.apply( component ) ); | ||||
|         Assert.assertEquals( expectedLegacyString, toLegacyTextFunction.apply( component ) ); | ||||
|         assertEquals( "Hello world!", toPlainTextFunction.apply( component ) ); | ||||
|         assertEquals( expectedLegacyString, toLegacyTextFunction.apply( component ) ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -502,8 +502,8 @@ public class ComponentsTest | ||||
|         TextComponent textComponent = new TextComponent( "Hello world" ); | ||||
|         textComponent.setColor( ChatColor.RED ); | ||||
|  | ||||
|         Assert.assertEquals( "Hello world", textComponent.toPlainText() ); | ||||
|         Assert.assertEquals( ChatColor.RED + "Hello world", textComponent.toLegacyText() ); | ||||
|         assertEquals( "Hello world", textComponent.toPlainText() ); | ||||
|         assertEquals( ChatColor.RED + "Hello world", textComponent.toLegacyText() ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -511,25 +511,25 @@ public class ComponentsTest | ||||
|     { | ||||
|         BaseComponent[] test1 = TextComponent.fromLegacyText( ChatColor.AQUA + "Aqua " + ChatColor.RED + ChatColor.BOLD + "RedBold" ); | ||||
|  | ||||
|         Assert.assertEquals( "Aqua RedBold", BaseComponent.toPlainText( test1 ) ); | ||||
|         Assert.assertEquals( ChatColor.AQUA + "Aqua " + ChatColor.RED + ChatColor.BOLD + "RedBold", BaseComponent.toLegacyText( test1 ) ); | ||||
|         assertEquals( "Aqua RedBold", BaseComponent.toPlainText( test1 ) ); | ||||
|         assertEquals( ChatColor.AQUA + "Aqua " + ChatColor.RED + ChatColor.BOLD + "RedBold", BaseComponent.toLegacyText( test1 ) ); | ||||
|  | ||||
|         BaseComponent[] test2 = TextComponent.fromLegacyText( "Text http://spigotmc.org " + ChatColor.GREEN + "google.com/test" ); | ||||
|  | ||||
|         Assert.assertEquals( "Text http://spigotmc.org google.com/test", BaseComponent.toPlainText( test2 ) ); | ||||
|         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 | ||||
|         Assert.assertEquals( ChatColor.WHITE + "Text " + ChatColor.WHITE + "http://spigotmc.org" + ChatColor.WHITE | ||||
|         assertEquals( ChatColor.WHITE + "Text " + ChatColor.WHITE + "http://spigotmc.org" + ChatColor.WHITE | ||||
|                 + " " + ChatColor.GREEN + "google.com/test" + ChatColor.GREEN, BaseComponent.toLegacyText( test2 ) ); | ||||
|  | ||||
|         ClickEvent url1 = test2[1].getClickEvent(); | ||||
|         Assert.assertNotNull( url1 ); | ||||
|         Assert.assertTrue( url1.getAction() == ClickEvent.Action.OPEN_URL ); | ||||
|         Assert.assertEquals( "http://spigotmc.org", url1.getValue() ); | ||||
|         assertNotNull( url1 ); | ||||
|         assertTrue( url1.getAction() == ClickEvent.Action.OPEN_URL ); | ||||
|         assertEquals( "http://spigotmc.org", url1.getValue() ); | ||||
|  | ||||
|         ClickEvent url2 = test2[3].getClickEvent(); | ||||
|         Assert.assertNotNull( url2 ); | ||||
|         Assert.assertTrue( url2.getAction() == ClickEvent.Action.OPEN_URL ); | ||||
|         Assert.assertEquals( "http://google.com/test", url2.getValue() ); | ||||
|         assertNotNull( url2 ); | ||||
|         assertTrue( url2.getAction() == ClickEvent.Action.OPEN_URL ); | ||||
|         assertEquals( "http://google.com/test", url2.getValue() ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -541,18 +541,18 @@ public class ComponentsTest | ||||
|                 item, "5", | ||||
|                 "thinkofdeath" ); | ||||
|  | ||||
|         Assert.assertEquals( "Given Golden Sword * 5 to thinkofdeath", translatableComponent.toPlainText() ); | ||||
|         Assert.assertEquals( ChatColor.WHITE + "Given " + ChatColor.AQUA + "Golden Sword" + ChatColor.WHITE | ||||
|         assertEquals( "Given Golden Sword * 5 to thinkofdeath", translatableComponent.toPlainText() ); | ||||
|         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() ); | ||||
|         assertEquals( "Page 5 of 50", positional.toPlainText() ); | ||||
|         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() ); | ||||
|         assertEquals( "Buried Treasure Map", one_four_two.toPlainText() ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -586,8 +586,8 @@ public class ComponentsTest | ||||
|                 append( "World" ).bold( true ).color( ChatColor.BLUE ). | ||||
|                 append( "!" ).color( ChatColor.YELLOW ) ); | ||||
|  | ||||
|         Assert.assertEquals( "Hello World!", toPlainTextFunction.apply( component ) ); | ||||
|         Assert.assertEquals( expectedLegacyString, toLegacyTextFunction.apply( component ) ); | ||||
|         assertEquals( "Hello World!", toPlainTextFunction.apply( component ) ); | ||||
|         assertEquals( expectedLegacyString, toLegacyTextFunction.apply( component ) ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -613,8 +613,8 @@ public class ComponentsTest | ||||
|         T component = componentBuilder.apply( new ComponentBuilder( "Hello " ).color( ChatColor.RED ) | ||||
|                 .append( "World" ).reset() ); | ||||
|  | ||||
|         Assert.assertEquals( ChatColor.RED, extraGetter.apply( component, 0 ).getColor() ); | ||||
|         Assert.assertEquals( ChatColor.WHITE, extraGetter.apply( component, 1 ).getColor() ); | ||||
|         assertEquals( ChatColor.RED, extraGetter.apply( component, 0 ).getColor() ); | ||||
|         assertEquals( ChatColor.WHITE, extraGetter.apply( component, 1 ).getColor() ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -640,41 +640,41 @@ public class ComponentsTest | ||||
|         T noneRetention = componentBuilder.apply( new ComponentBuilder( "Hello " ).color( ChatColor.RED ) | ||||
|                 .append( "World", ComponentBuilder.FormatRetention.NONE ) ); | ||||
|  | ||||
|         Assert.assertEquals( ChatColor.RED, extraGetter.apply( noneRetention, 0 ).getColor() ); | ||||
|         Assert.assertEquals( ChatColor.WHITE, extraGetter.apply( noneRetention, 1 ).getColor() ); | ||||
|         assertEquals( ChatColor.RED, extraGetter.apply( noneRetention, 0 ).getColor() ); | ||||
|         assertEquals( ChatColor.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( ChatColor.RED ) | ||||
|                 .event( testEvent ).append( "World", ComponentBuilder.FormatRetention.FORMATTING ) ); | ||||
|  | ||||
|         Assert.assertEquals( ChatColor.RED, extraGetter.apply( formattingRetention, 0 ).getColor() ); | ||||
|         Assert.assertEquals( testEvent, extraGetter.apply( formattingRetention, 0 ).getHoverEvent() ); | ||||
|         Assert.assertEquals( ChatColor.RED, extraGetter.apply( formattingRetention, 1 ).getColor() ); | ||||
|         Assert.assertNull( extraGetter.apply( formattingRetention, 1 ).getHoverEvent() ); | ||||
|         assertEquals( ChatColor.RED, extraGetter.apply( formattingRetention, 0 ).getColor() ); | ||||
|         assertEquals( testEvent, extraGetter.apply( formattingRetention, 0 ).getHoverEvent() ); | ||||
|         assertEquals( ChatColor.RED, extraGetter.apply( formattingRetention, 1 ).getColor() ); | ||||
|         assertNull( extraGetter.apply( formattingRetention, 1 ).getHoverEvent() ); | ||||
|  | ||||
|         ClickEvent testClickEvent = new ClickEvent( ClickEvent.Action.OPEN_URL, "http://www.example.com" ); | ||||
|  | ||||
|         T eventRetention = componentBuilder.apply( new ComponentBuilder( "Hello " ).color( ChatColor.RED ) | ||||
|                 .event( testEvent ).event( testClickEvent ).append( "World", ComponentBuilder.FormatRetention.EVENTS ) ); | ||||
|  | ||||
|         Assert.assertEquals( ChatColor.RED, extraGetter.apply( eventRetention, 0 ).getColor() ); | ||||
|         Assert.assertEquals( testEvent, extraGetter.apply( eventRetention, 0 ).getHoverEvent() ); | ||||
|         Assert.assertEquals( testClickEvent, extraGetter.apply( eventRetention, 0 ).getClickEvent() ); | ||||
|         Assert.assertEquals( ChatColor.WHITE, extraGetter.apply( eventRetention, 1 ).getColor() ); | ||||
|         Assert.assertEquals( testEvent, extraGetter.apply( eventRetention, 1 ).getHoverEvent() ); | ||||
|         Assert.assertEquals( testClickEvent, extraGetter.apply( eventRetention, 1 ).getClickEvent() ); | ||||
|         assertEquals( ChatColor.RED, extraGetter.apply( eventRetention, 0 ).getColor() ); | ||||
|         assertEquals( testEvent, extraGetter.apply( eventRetention, 0 ).getHoverEvent() ); | ||||
|         assertEquals( testClickEvent, extraGetter.apply( eventRetention, 0 ).getClickEvent() ); | ||||
|         assertEquals( ChatColor.WHITE, extraGetter.apply( eventRetention, 1 ).getColor() ); | ||||
|         assertEquals( testEvent, extraGetter.apply( eventRetention, 1 ).getHoverEvent() ); | ||||
|         assertEquals( testClickEvent, extraGetter.apply( eventRetention, 1 ).getClickEvent() ); | ||||
|     } | ||||
|  | ||||
|     @Test(expected = IllegalArgumentException.class) | ||||
|     @Test | ||||
|     public void testLoopSimple() | ||||
|     { | ||||
|         TextComponent component = new TextComponent( "Testing" ); | ||||
|         component.addExtra( component ); | ||||
|         ComponentSerializer.toString( component ); | ||||
|         assertThrows( IllegalArgumentException.class, () -> ComponentSerializer.toString( component ) ); | ||||
|     } | ||||
|  | ||||
|     @Test(expected = IllegalArgumentException.class) | ||||
|     @Test | ||||
|     public void testLoopComplex() | ||||
|     { | ||||
|         TextComponent a = new TextComponent( "A" ); | ||||
| @@ -685,7 +685,7 @@ public class ComponentsTest | ||||
|         a.addExtra( b ); | ||||
|         b.addExtra( c ); | ||||
|         c.addExtra( a ); | ||||
|         ComponentSerializer.toString( a ); | ||||
|         assertThrows( IllegalArgumentException.class, () -> ComponentSerializer.toString( a ) ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -699,7 +699,7 @@ public class ComponentsTest | ||||
|         ComponentSerializer.toString( a ); | ||||
|     } | ||||
|  | ||||
|     @Test(expected = IllegalArgumentException.class) | ||||
|     @Test | ||||
|     public void testRepeatedError() | ||||
|     { | ||||
|         TextComponent a = new TextComponent( "A" ); | ||||
| @@ -711,7 +711,7 @@ public class ComponentsTest | ||||
|         a.addExtra( c ); | ||||
|         c.addExtra( a ); | ||||
|         a.addExtra( b ); | ||||
|         ComponentSerializer.toString( a ); | ||||
|         assertThrows( IllegalArgumentException.class, () -> ComponentSerializer.toString( a ) ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -736,7 +736,7 @@ public class ComponentsTest | ||||
|         String emptyLegacyText = fromAndToLegacyText( "" ); | ||||
|  | ||||
|         // all invalid color codes and the trailing '§' should be ignored | ||||
|         Assert.assertEquals( emptyLegacyText, invalidColorCodesLegacyText ); | ||||
|         assertEquals( emptyLegacyText, invalidColorCodesLegacyText ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -745,12 +745,12 @@ public class ComponentsTest | ||||
|         String text = "§a"; | ||||
|  | ||||
|         BaseComponent[] converted = TextComponent.fromLegacyText( text ); | ||||
|         Assert.assertEquals( ChatColor.GREEN, converted[0].getColor() ); | ||||
|         assertEquals( ChatColor.GREEN, converted[0].getColor() ); | ||||
|  | ||||
|         String roundtripLegacyText = BaseComponent.toLegacyText( converted ); | ||||
|  | ||||
|         // color code should not be lost during conversion | ||||
|         Assert.assertEquals( text, roundtripLegacyText ); | ||||
|         assertEquals( text, roundtripLegacyText ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -762,7 +762,7 @@ public class ComponentsTest | ||||
|         TextComponent second = new TextComponent( "Hello, " ); | ||||
|         second.addExtra( new TextComponent( "World!" ) ); | ||||
|  | ||||
|         Assert.assertEquals( first, second ); | ||||
|         assertEquals( first, second ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -774,7 +774,7 @@ public class ComponentsTest | ||||
|         TextComponent second = new TextComponent( "Hello, " ); | ||||
|         second.addExtra( new TextComponent( "World!" ) ); | ||||
|  | ||||
|         Assert.assertNotEquals( first, second ); | ||||
|         assertNotEquals( first, second ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -785,7 +785,7 @@ public class ComponentsTest | ||||
|  | ||||
|         BaseComponent[] reColored = TextComponent.fromLegacyText( legacy ); | ||||
|  | ||||
|         Assert.assertArrayEquals( hexColored, reColored ); | ||||
|         assertArrayEquals( hexColored, reColored ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -817,18 +817,18 @@ public class ComponentsTest | ||||
|  | ||||
|         String expected = "{\"extra\":[{\"underlined\":true,\"color\":\"dark_red\",\"text\":\"44444\"},{\"color\":" | ||||
|                 + "\"white\",\"text\":\"dd\"},{\"bold\":true,\"color\":\"gold\",\"text\":\"6666\"}],\"text\":\"\"}"; | ||||
|         Assert.assertEquals( expected, ComponentSerializer.toString( a ) ); | ||||
|         assertEquals( expected, ComponentSerializer.toString( a ) ); | ||||
|  | ||||
|         builder.append( a ); | ||||
|  | ||||
|         String test1 = componentSerializer.apply( componentBuilder.apply( builder ) ); | ||||
|         Assert.assertEquals( expected, test1 ); | ||||
|         assertEquals( expected, test1 ); | ||||
|  | ||||
|         BaseComponent[] b = TextComponent.fromLegacyText( "§rrrrr" ); | ||||
|         builder.append( b ); | ||||
|  | ||||
|         String test2 = componentSerializer.apply( componentBuilder.apply( builder ) ); | ||||
|         Assert.assertEquals( | ||||
|         assertEquals( | ||||
|                 "{\"extra\":[{\"underlined\":true,\"color\":\"dark_red\",\"text\":\"44444\"}," | ||||
|                         + "{\"color\":\"white\",\"text\":\"dd\"},{\"bold\":true,\"color\":\"gold\",\"text\":\"6666\"}," | ||||
|                         + "{\"color\":\"white\",\"text\":\"rrrr\"}],\"text\":\"\"}", | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| package net.md_5.bungee.api.chat; | ||||
|  | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
| import net.md_5.bungee.chat.ComponentSerializer; | ||||
| import org.junit.Assert; | ||||
| import org.junit.Test; | ||||
| import org.junit.jupiter.api.Test; | ||||
|  | ||||
| public class TranslatableComponentTest | ||||
| { | ||||
| @@ -11,8 +11,8 @@ public class TranslatableComponentTest | ||||
|     public void testMissingPlaceholdersAdded() | ||||
|     { | ||||
|         TranslatableComponent testComponent = new TranslatableComponent( "Test string with %s placeholders: %s", 2, "aoeu" ); | ||||
|         Assert.assertEquals( "Test string with 2 placeholders: aoeu", testComponent.toPlainText() ); | ||||
|         Assert.assertEquals( "§fTest string with §f2§f placeholders: §faoeu", testComponent.toLegacyText() ); | ||||
|         assertEquals( "Test string with 2 placeholders: aoeu", testComponent.toPlainText() ); | ||||
|         assertEquals( "§fTest string with §f2§f placeholders: §faoeu", testComponent.toLegacyText() ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -22,7 +22,7 @@ public class TranslatableComponentTest | ||||
|         String jsonString = ComponentSerializer.toString( testComponent ); | ||||
|         BaseComponent[] baseComponents = ComponentSerializer.parse( jsonString ); | ||||
|  | ||||
|         Assert.assertEquals( "Test string with a placeholder", TextComponent.toPlainText( baseComponents ) ); | ||||
|         Assert.assertEquals( "§fTest string with §fa§f placeholder", TextComponent.toLegacyText( baseComponents ) ); | ||||
|         assertEquals( "Test string with a placeholder", TextComponent.toPlainText( baseComponents ) ); | ||||
|         assertEquals( "§fTest string with §fa§f placeholder", TextComponent.toLegacyText( baseComponents ) ); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -36,7 +36,6 @@ | ||||
|         <module name="SuppressWarningsHolder"/> | ||||
|  | ||||
|         <!-- See http://checkstyle.sourceforge.net/config_imports.html --> | ||||
|         <module name="AvoidStarImport"/> | ||||
|         <module name="ImportOrder"> | ||||
|             <property name="option" value="above"/> | ||||
|             <property name="ordered" value="true"/> | ||||
|   | ||||
| @@ -4,13 +4,12 @@ | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|  | ||||
|     <parent> | ||||
|         <groupId>net.md-5</groupId> | ||||
|         <groupId>fr.pandacube.bungeecord</groupId> | ||||
|         <artifactId>bungeecord-parent</artifactId> | ||||
|         <version>1.20-R0.2-SNAPSHOT</version> | ||||
|         <relativePath>../pom.xml</relativePath> | ||||
|     </parent> | ||||
|  | ||||
|     <groupId>net.md-5</groupId> | ||||
|     <artifactId>bungeecord-config</artifactId> | ||||
|     <version>1.20-R0.2-SNAPSHOT</version> | ||||
|     <packaging>jar</packaging> | ||||
|   | ||||
| @@ -1,148 +1,138 @@ | ||||
| package net.md_5.bungee.config; | ||||
|  | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
| import java.io.StringReader; | ||||
| import java.io.StringWriter; | ||||
| import java.util.Arrays; | ||||
| import java.util.Collections; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.stream.Stream; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import org.junit.Assert; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.junit.runners.Parameterized; | ||||
| import org.junit.runners.Parameterized.Parameters; | ||||
| import org.junit.jupiter.params.ParameterizedTest; | ||||
| import org.junit.jupiter.params.provider.Arguments; | ||||
| import org.junit.jupiter.params.provider.MethodSource; | ||||
|  | ||||
| @RequiredArgsConstructor | ||||
| @RunWith(Parameterized.class) | ||||
| public class CompoundConfigurationTest | ||||
| { | ||||
|  | ||||
|     @Parameters(name = "{0}") | ||||
|     public static Iterable<Object[]> data() | ||||
|     public static Stream<Arguments> data() | ||||
|     { | ||||
|         // CHECKSTYLE:OFF | ||||
|         return Arrays.asList( new Object[][] | ||||
|         { | ||||
|             { | ||||
|                 // provider | ||||
|                 YamlConfiguration.class, | ||||
|                 // testDocument | ||||
|                 "" | ||||
|                 + "receipt:     Oz-Ware Purchase Invoice\n" | ||||
|                 + "date:        2012-08-06\n" | ||||
|                 + "customer:\n" | ||||
|                 + "    given:   Dorothy\n" | ||||
|                 + "    family:  Gale\n" | ||||
|                 + "\n" | ||||
|                 + "items:\n" | ||||
|                 + "    - part_no:   A4786\n" | ||||
|                 + "      descrip:   Water Bucket (Filled)\n" | ||||
|                 + "      price:     1.47\n" | ||||
|                 + "      quantity:  4\n" | ||||
|                 + "\n" | ||||
|                 + "    - part_no:   E1628\n" | ||||
|                 + "      descrip:   High Heeled \"Ruby\" Slippers\n" | ||||
|                 + "      size:      8\n" | ||||
|                 + "      price:     100.27\n" | ||||
|                 + "      quantity:  1\n" | ||||
|                 + "\n" | ||||
|                 + "bill-to:  &id001\n" | ||||
|                 + "    street: |\n" | ||||
|                 + "            123 Tornado Alley\n" | ||||
|                 + "            Suite 16\n" | ||||
|                 + "    city:   East Centerville\n" | ||||
|                 + "    state:  KS\n" | ||||
|                 + "\n" | ||||
|                 + "ship-to:  *id001\n" | ||||
|                 + "\n" | ||||
|                 + "specialDelivery:  >\n" | ||||
|                 + "    Follow the Yellow Brick\n" | ||||
|                 + "    Road to the Emerald City.\n" | ||||
|                 + "    Pay no attention to the\n" | ||||
|                 + "    man behind the curtain.", | ||||
|                 // numberTest | ||||
|                 "" | ||||
|                 + "someKey:\n" | ||||
|                 + "    1: 1\n" | ||||
|                 + "    2: 2\n" | ||||
|                 + "    3: 3\n" | ||||
|                 + "    4: 4", | ||||
|                 // nullTest | ||||
|                 "" | ||||
|                 + "null:\n" | ||||
|                 + "    null: object\n" | ||||
|                 + "    object: null\n" | ||||
|             }, | ||||
|             { | ||||
|                 // provider | ||||
|                 JsonConfiguration.class, | ||||
|                 // testDocument | ||||
|                 "" | ||||
|                 + "{\n" | ||||
|                 + "  \"customer\": {\n" | ||||
|                 + "    \"given\": \"Dorothy\", \n" | ||||
|                 + "    \"family\": \"Gale\"\n" | ||||
|                 + "  }, \n" | ||||
|                 + "  \"ship-to\": {\n" | ||||
|                 + "    \"city\": \"East Centerville\", \n" | ||||
|                 + "    \"state\": \"KS\", \n" | ||||
|                 + "    \"street\": \"123 Tornado Alley\\nSuite 16\\n\"\n" | ||||
|                 + "  }, \n" | ||||
|                 + "  \"bill-to\": {\n" | ||||
|                 + "    \"city\": \"East Centerville\", \n" | ||||
|                 + "    \"state\": \"KS\", \n" | ||||
|                 + "    \"street\": \"123 Tornado Alley\\nSuite 16\\n\"\n" | ||||
|                 + "  }, \n" | ||||
|                 + "  \"date\": \"2012-08-06\", \n" | ||||
|                 + "  \"items\": [\n" | ||||
|                 + "    {\n" | ||||
|                 + "      \"part_no\": \"A4786\", \n" | ||||
|                 + "      \"price\": 1.47, \n" | ||||
|                 + "      \"descrip\": \"Water Bucket (Filled)\", \n" | ||||
|                 + "      \"quantity\": 4\n" | ||||
|                 + "    }, \n" | ||||
|                 + "    {\n" | ||||
|                 + "      \"part_no\": \"E1628\", \n" | ||||
|                 + "      \"descrip\": \"High Heeled \\\"Ruby\\\" Slippers\", \n" | ||||
|                 + "      \"price\": 100.27, \n" | ||||
|                 + "      \"quantity\": 1, \n" | ||||
|                 + "      \"size\": 8\n" | ||||
|                 + "    }\n" | ||||
|                 + "  ], \n" | ||||
|                 + "  \"receipt\": \"Oz-Ware Purchase Invoice\", \n" | ||||
|                 + "  \"specialDelivery\": \"Follow the Yellow Brick Road to the Emerald City. Pay no attention to the man behind the curtain.\"\n" | ||||
|                 + "}", | ||||
|                 // numberTest | ||||
|                 "" | ||||
|                 + "{\n" | ||||
|                 + "  \"someKey\": {\n" | ||||
|                 + "    \"1\": 1, \n" | ||||
|                 + "    \"2\": 2, \n" | ||||
|                 + "    \"3\": 3, \n" | ||||
|                 + "    \"4\": 4\n" | ||||
|                 + "  }\n" | ||||
|                 + "}", | ||||
|                 // nullTest | ||||
|                 "" | ||||
|                 + "{\n" | ||||
|                 + "  \"null\": {\n" | ||||
|                 + "    \"null\": \"object\", \n" | ||||
|                 + "    \"object\": null\n" | ||||
|                 + "  }\n" | ||||
|                 + "}" | ||||
|             } | ||||
|         } ); | ||||
|         // CHECKSTYLE:ON | ||||
|         return Stream.of( | ||||
|                 Arguments.of( | ||||
|                         // provider | ||||
|                         YamlConfiguration.class, | ||||
|                         // testDocument | ||||
|                         "" | ||||
|                         + "receipt:     Oz-Ware Purchase Invoice\n" | ||||
|                         + "date:        2012-08-06\n" | ||||
|                         + "customer:\n" | ||||
|                         + "    given:   Dorothy\n" | ||||
|                         + "    family:  Gale\n" | ||||
|                         + "\n" | ||||
|                         + "items:\n" | ||||
|                         + "    - part_no:   A4786\n" | ||||
|                         + "      descrip:   Water Bucket (Filled)\n" | ||||
|                         + "      price:     1.47\n" | ||||
|                         + "      quantity:  4\n" | ||||
|                         + "\n" | ||||
|                         + "    - part_no:   E1628\n" | ||||
|                         + "      descrip:   High Heeled \"Ruby\" Slippers\n" | ||||
|                         + "      size:      8\n" | ||||
|                         + "      price:     100.27\n" | ||||
|                         + "      quantity:  1\n" | ||||
|                         + "\n" | ||||
|                         + "bill-to:  &id001\n" | ||||
|                         + "    street: |\n" | ||||
|                         + "            123 Tornado Alley\n" | ||||
|                         + "            Suite 16\n" | ||||
|                         + "    city:   East Centerville\n" | ||||
|                         + "    state:  KS\n" | ||||
|                         + "\n" | ||||
|                         + "ship-to:  *id001\n" | ||||
|                         + "\n" | ||||
|                         + "specialDelivery:  >\n" | ||||
|                         + "    Follow the Yellow Brick\n" | ||||
|                         + "    Road to the Emerald City.\n" | ||||
|                         + "    Pay no attention to the\n" | ||||
|                         + "    man behind the curtain.", | ||||
|                         // numberTest | ||||
|                         "" | ||||
|                         + "someKey:\n" | ||||
|                         + "    1: 1\n" | ||||
|                         + "    2: 2\n" | ||||
|                         + "    3: 3\n" | ||||
|                         + "    4: 4", | ||||
|                         // nullTest | ||||
|                         "" | ||||
|                         + "null:\n" | ||||
|                         + "    null: object\n" | ||||
|                         + "    object: null\n" | ||||
|                 ), | ||||
|                 Arguments.of( | ||||
|                         // provider | ||||
|                         JsonConfiguration.class, | ||||
|                         // testDocument | ||||
|                         "" | ||||
|                         + "{\n" | ||||
|                         + "  \"customer\": {\n" | ||||
|                         + "    \"given\": \"Dorothy\", \n" | ||||
|                         + "    \"family\": \"Gale\"\n" | ||||
|                         + "  }, \n" | ||||
|                         + "  \"ship-to\": {\n" | ||||
|                         + "    \"city\": \"East Centerville\", \n" | ||||
|                         + "    \"state\": \"KS\", \n" | ||||
|                         + "    \"street\": \"123 Tornado Alley\\nSuite 16\\n\"\n" | ||||
|                         + "  }, \n" | ||||
|                         + "  \"bill-to\": {\n" | ||||
|                         + "    \"city\": \"East Centerville\", \n" | ||||
|                         + "    \"state\": \"KS\", \n" | ||||
|                         + "    \"street\": \"123 Tornado Alley\\nSuite 16\\n\"\n" | ||||
|                         + "  }, \n" | ||||
|                         + "  \"date\": \"2012-08-06\", \n" | ||||
|                         + "  \"items\": [\n" | ||||
|                         + "    {\n" | ||||
|                         + "      \"part_no\": \"A4786\", \n" | ||||
|                         + "      \"price\": 1.47, \n" | ||||
|                         + "      \"descrip\": \"Water Bucket (Filled)\", \n" | ||||
|                         + "      \"quantity\": 4\n" | ||||
|                         + "    }, \n" | ||||
|                         + "    {\n" | ||||
|                         + "      \"part_no\": \"E1628\", \n" | ||||
|                         + "      \"descrip\": \"High Heeled \\\"Ruby\\\" Slippers\", \n" | ||||
|                         + "      \"price\": 100.27, \n" | ||||
|                         + "      \"quantity\": 1, \n" | ||||
|                         + "      \"size\": 8\n" | ||||
|                         + "    }\n" | ||||
|                         + "  ], \n" | ||||
|                         + "  \"receipt\": \"Oz-Ware Purchase Invoice\", \n" | ||||
|                         + "  \"specialDelivery\": \"Follow the Yellow Brick Road to the Emerald City. Pay no attention to the man behind the curtain.\"\n" | ||||
|                         + "}", | ||||
|                         // numberTest | ||||
|                         "" | ||||
|                         + "{\n" | ||||
|                         + "  \"someKey\": {\n" | ||||
|                         + "    \"1\": 1, \n" | ||||
|                         + "    \"2\": 2, \n" | ||||
|                         + "    \"3\": 3, \n" | ||||
|                         + "    \"4\": 4\n" | ||||
|                         + "  }\n" | ||||
|                         + "}", | ||||
|                         // nullTest | ||||
|                         "" | ||||
|                         + "{\n" | ||||
|                         + "  \"null\": {\n" | ||||
|                         + "    \"null\": \"object\", \n" | ||||
|                         + "    \"object\": null\n" | ||||
|                         + "  }\n" | ||||
|                         + "}" | ||||
|                 ) | ||||
|         ); | ||||
|     } | ||||
|     // | ||||
|     private final Class<? extends ConfigurationProvider> provider; | ||||
|     private final String testDocument; | ||||
|     private final String numberTest; | ||||
|     private final String nullTest; | ||||
|  | ||||
|     @Test | ||||
|     public void testConfig() throws Exception | ||||
|     @ParameterizedTest | ||||
|     @MethodSource("data") | ||||
|     public void testConfig(Class<? extends ConfigurationProvider> provider, String testDocument, String numberTest, String nullTest) throws Exception | ||||
|     { | ||||
|         Configuration conf = ConfigurationProvider.getProvider( provider ).load( testDocument ); | ||||
|         testSection( conf ); | ||||
| @@ -151,7 +141,7 @@ public class CompoundConfigurationTest | ||||
|         ConfigurationProvider.getProvider( provider ).save( conf, sw ); | ||||
|  | ||||
|         // Check nulls were saved, see #1094 | ||||
|         Assert.assertFalse( "Config contains null", sw.toString().contains( "null" ) ); | ||||
|         assertFalse( sw.toString().contains( "null" ), "Config contains null" ); | ||||
|  | ||||
|         conf = ConfigurationProvider.getProvider( provider ).load( new StringReader( sw.toString() ) ); | ||||
|         conf.set( "receipt", "Oz-Ware Purchase Invoice" ); // Add it back | ||||
| @@ -160,37 +150,38 @@ public class CompoundConfigurationTest | ||||
|  | ||||
|     private void testSection(Configuration conf) | ||||
|     { | ||||
|         Assert.assertEquals( "receipt", "Oz-Ware Purchase Invoice", conf.getString( "receipt" ) ); | ||||
|         // Assert.assertEquals( "date", "2012-08-06", conf.get( "date" ).toString() ); | ||||
|         assertEquals( "Oz-Ware Purchase Invoice", conf.getString( "receipt" ), "receipt" ); | ||||
|         // assertEquals( "2012-08-06", conf.get( "date" ).toString(), "date" ); | ||||
|  | ||||
|         Configuration customer = conf.getSection( "customer" ); | ||||
|         Assert.assertEquals( "customer.given", "Dorothy", customer.getString( "given" ) ); | ||||
|         Assert.assertEquals( "customer.given", "Dorothy", conf.getString( "customer.given" ) ); | ||||
|         assertEquals( "Dorothy", customer.getString( "given" ), "customer.given" ); | ||||
|         assertEquals( "Dorothy", conf.getString( "customer.given" ), "customer.given" ); | ||||
|  | ||||
|         List items = conf.getList( "items" ); | ||||
|         Map item = (Map) items.get( 0 ); | ||||
|         Assert.assertEquals( "items[0].part_no", "A4786", item.get( "part_no" ) ); | ||||
|         assertEquals( "A4786", item.get( "part_no" ), "items[0].part_no" ); | ||||
|  | ||||
|         conf.set( "receipt", null ); | ||||
|         Assert.assertEquals( null, conf.get( "receipt" ) ); | ||||
|         Assert.assertEquals( "foo", conf.get( "receipt", "foo" ) ); | ||||
|         assertEquals( null, conf.get( "receipt" ) ); | ||||
|         assertEquals( "foo", conf.get( "receipt", "foo" ) ); | ||||
|  | ||||
|         Configuration newSection = conf.getSection( "new.section" ); | ||||
|         newSection.set( "value", "foo" ); | ||||
|         Assert.assertEquals( "foo", conf.get( "new.section.value" ) ); | ||||
|         assertEquals( "foo", conf.get( "new.section.value" ) ); | ||||
|  | ||||
|         conf.set( "other.new.section", "bar" ); | ||||
|         Assert.assertEquals( "bar", conf.get( "other.new.section" ) ); | ||||
|         assertEquals( "bar", conf.get( "other.new.section" ) ); | ||||
|  | ||||
|         Assert.assertTrue( conf.contains( "customer.given" ) ); | ||||
|         Assert.assertTrue( customer.contains( "given" ) ); | ||||
|         assertTrue( conf.contains( "customer.given" ) ); | ||||
|         assertTrue( customer.contains( "given" ) ); | ||||
|  | ||||
|         Assert.assertFalse( conf.contains( "customer.foo" ) ); | ||||
|         Assert.assertFalse( customer.contains( "foo" ) ); | ||||
|         assertFalse( conf.contains( "customer.foo" ) ); | ||||
|         assertFalse( customer.contains( "foo" ) ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testNumberedKeys() | ||||
|     @ParameterizedTest | ||||
|     @MethodSource("data") | ||||
|     public void testNumberedKeys(Class<? extends ConfigurationProvider> provider, String testDocument, String numberTest, String nullTest) | ||||
|     { | ||||
|         Configuration conf = ConfigurationProvider.getProvider( provider ).load( numberTest ); | ||||
|  | ||||
| @@ -201,29 +192,31 @@ public class CompoundConfigurationTest | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testNull() | ||||
|     @ParameterizedTest | ||||
|     @MethodSource("data") | ||||
|     public void testNull(Class<? extends ConfigurationProvider> provider, String testDocument, String numberTest, String nullTest) | ||||
|     { | ||||
|         Configuration conf = ConfigurationProvider.getProvider( provider ).load( nullTest ); | ||||
|  | ||||
|         Assert.assertEquals( "object", conf.get( "null.null" ) ); | ||||
|         Assert.assertEquals( "object", conf.getSection( "null" ).get( "null" ) ); | ||||
|         assertEquals( "object", conf.get( "null.null" ) ); | ||||
|         assertEquals( "object", conf.getSection( "null" ).get( "null" ) ); | ||||
|  | ||||
|         Assert.assertEquals( null, conf.get( "null.object" ) ); | ||||
|         Assert.assertEquals( "", conf.getString( "null.object" ) ); | ||||
|         assertEquals( null, conf.get( "null.object" ) ); | ||||
|         assertEquals( "", conf.getString( "null.object" ) ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testMapAddition() | ||||
|     @ParameterizedTest | ||||
|     @MethodSource("data") | ||||
|     public void testMapAddition(Class<? extends ConfigurationProvider> provider, String testDocument, String numberTest, String nullTest) | ||||
|     { | ||||
|         Configuration conf = ConfigurationProvider.getProvider( provider ).load( testDocument ); | ||||
|  | ||||
|         conf.set( "addition", Collections.singletonMap( "foo", "bar" ) ); | ||||
|  | ||||
|         // Order matters | ||||
|         Assert.assertEquals( "bar", conf.getSection( "addition" ).getString( "foo" ) ); | ||||
|         Assert.assertEquals( "bar", conf.getString( "addition.foo" ) ); | ||||
|         assertEquals( "bar", conf.getSection( "addition" ).getString( "foo" ) ); | ||||
|         assertEquals( "bar", conf.getString( "addition.foo" ) ); | ||||
|  | ||||
|         Assert.assertTrue( conf.get( "addition" ) instanceof Configuration ); | ||||
|         assertTrue( conf.get( "addition" ) instanceof Configuration ); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| package net.md_5.bungee.config; | ||||
|  | ||||
| import org.junit.Assert; | ||||
| import org.junit.Test; | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
| import org.junit.jupiter.api.Test; | ||||
|  | ||||
| public class DefaultConfigurationTest | ||||
| { | ||||
| @@ -16,8 +16,8 @@ public class DefaultConfigurationTest | ||||
|  | ||||
|         Configuration actualConfig = new Configuration( defaultConfig ); | ||||
|  | ||||
|         Assert.assertEquals( 10, actualConfig.getInt( "setting" ) ); | ||||
|         Assert.assertEquals( 11, actualConfig.getInt( "nested.setting" ) ); | ||||
|         Assert.assertEquals( 12, actualConfig.getInt( "double.nested.setting" ) ); | ||||
|         assertEquals( 10, actualConfig.getInt( "setting" ) ); | ||||
|         assertEquals( 11, actualConfig.getInt( "nested.setting" ) ); | ||||
|         assertEquals( 12, actualConfig.getInt( "double.nested.setting" ) ); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -4,13 +4,12 @@ | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|  | ||||
|     <parent> | ||||
|         <groupId>net.md-5</groupId> | ||||
|         <groupId>fr.pandacube.bungeecord</groupId> | ||||
|         <artifactId>bungeecord-parent</artifactId> | ||||
|         <version>1.20-R0.2-SNAPSHOT</version> | ||||
|         <relativePath>../pom.xml</relativePath> | ||||
|     </parent> | ||||
|  | ||||
|     <groupId>net.md-5</groupId> | ||||
|     <artifactId>bungeecord-event</artifactId> | ||||
|     <version>1.20-R0.2-SNAPSHOT</version> | ||||
|     <packaging>jar</packaging> | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| package net.md_5.bungee.event; | ||||
|  | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
| import java.util.concurrent.CountDownLatch; | ||||
| import org.junit.Assert; | ||||
| import org.junit.Test; | ||||
| import org.junit.jupiter.api.Test; | ||||
|  | ||||
| public class EventBusTest | ||||
| { | ||||
| @@ -15,14 +15,14 @@ public class EventBusTest | ||||
|     { | ||||
|         bus.register( this ); | ||||
|         bus.post( new FirstEvent() ); | ||||
|         Assert.assertEquals( 0, latch.getCount() ); | ||||
|         assertEquals( 0, latch.getCount() ); | ||||
|     } | ||||
|  | ||||
|     @EventHandler | ||||
|     public void firstListener(FirstEvent event) | ||||
|     { | ||||
|         bus.post( new SecondEvent() ); | ||||
|         Assert.assertEquals( 1, latch.getCount() ); | ||||
|         assertEquals( 1, latch.getCount() ); | ||||
|         latch.countDown(); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| package net.md_5.bungee.event; | ||||
|  | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
| import java.util.concurrent.CountDownLatch; | ||||
| import org.junit.Assert; | ||||
| import org.junit.Test; | ||||
| import org.junit.jupiter.api.Test; | ||||
|  | ||||
| public class EventPriorityTest | ||||
| { | ||||
| @@ -16,41 +16,41 @@ public class EventPriorityTest | ||||
|         bus.register( this ); | ||||
|         bus.register( new EventPriorityListenerPartner() ); | ||||
|         bus.post( new PriorityTestEvent() ); | ||||
|         Assert.assertEquals( 0, latch.getCount() ); | ||||
|         assertEquals( 0, latch.getCount() ); | ||||
|     } | ||||
|  | ||||
|     @EventHandler(priority = Byte.MIN_VALUE) | ||||
|     public void onMinPriority(PriorityTestEvent event) | ||||
|     { | ||||
|         Assert.assertEquals( 7, latch.getCount() ); | ||||
|         assertEquals( 7, latch.getCount() ); | ||||
|         latch.countDown(); | ||||
|     } | ||||
|  | ||||
|     @EventHandler(priority = EventPriority.LOWEST) | ||||
|     public void onLowestPriority(PriorityTestEvent event) | ||||
|     { | ||||
|         Assert.assertEquals( 6, latch.getCount() ); | ||||
|         assertEquals( 6, latch.getCount() ); | ||||
|         latch.countDown(); | ||||
|     } | ||||
|  | ||||
|     @EventHandler | ||||
|     public void onNormalPriority(PriorityTestEvent event) | ||||
|     { | ||||
|         Assert.assertEquals( 4, latch.getCount() ); | ||||
|         assertEquals( 4, latch.getCount() ); | ||||
|         latch.countDown(); | ||||
|     } | ||||
|  | ||||
|     @EventHandler(priority = EventPriority.HIGHEST) | ||||
|     public void onHighestPriority(PriorityTestEvent event) | ||||
|     { | ||||
|         Assert.assertEquals( 2, latch.getCount() ); | ||||
|         assertEquals( 2, latch.getCount() ); | ||||
|         latch.countDown(); | ||||
|     } | ||||
|  | ||||
|     @EventHandler(priority = Byte.MAX_VALUE) | ||||
|     public void onMaxPriority(PriorityTestEvent event) | ||||
|     { | ||||
|         Assert.assertEquals( 1, latch.getCount() ); | ||||
|         assertEquals( 1, latch.getCount() ); | ||||
|         latch.countDown(); | ||||
|     } | ||||
|  | ||||
| @@ -64,14 +64,14 @@ public class EventPriorityTest | ||||
|         @EventHandler(priority = EventPriority.HIGH) | ||||
|         public void onHighPriority(PriorityTestEvent event) | ||||
|         { | ||||
|             Assert.assertEquals( 3, latch.getCount() ); | ||||
|             assertEquals( 3, latch.getCount() ); | ||||
|             latch.countDown(); | ||||
|         } | ||||
|  | ||||
|         @EventHandler(priority = EventPriority.LOW) | ||||
|         public void onLowPriority(PriorityTestEvent event) | ||||
|         { | ||||
|             Assert.assertEquals( 5, latch.getCount() ); | ||||
|             assertEquals( 5, latch.getCount() ); | ||||
|             latch.countDown(); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| package net.md_5.bungee.event; | ||||
|  | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
| import java.util.concurrent.CountDownLatch; | ||||
| import org.junit.Assert; | ||||
| import org.junit.Test; | ||||
| import org.junit.jupiter.api.Test; | ||||
|  | ||||
| public class SubclassTest extends EventBusTest | ||||
| { | ||||
| @@ -14,13 +14,13 @@ public class SubclassTest extends EventBusTest | ||||
|     public void testNestedEvents() | ||||
|     { | ||||
|         super.testNestedEvents(); | ||||
|         Assert.assertEquals( 0, latch.getCount() ); | ||||
|         assertEquals( 0, latch.getCount() ); | ||||
|     } | ||||
|  | ||||
|     @EventHandler | ||||
|     protected void extraListener(FirstEvent event) | ||||
|     { | ||||
|         Assert.assertEquals( 1, latch.getCount() ); | ||||
|         assertEquals( 1, latch.getCount() ); | ||||
|         latch.countDown(); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| package net.md_5.bungee.event; | ||||
|  | ||||
| import org.junit.Assert; | ||||
| import org.junit.Test; | ||||
| import static org.junit.jupiter.api.Assertions.fail; | ||||
| import org.junit.jupiter.api.Test; | ||||
|  | ||||
| public class UnregisteringListenerTest | ||||
| { | ||||
| @@ -19,7 +19,7 @@ public class UnregisteringListenerTest | ||||
|     @EventHandler | ||||
|     public void onEvent(TestEvent evt) | ||||
|     { | ||||
|         Assert.fail( "Event listener wasn't unregistered" ); | ||||
|         fail( "Event listener wasn't unregistered" ); | ||||
|     } | ||||
|  | ||||
|     public static class TestEvent | ||||
|   | ||||
| @@ -4,13 +4,12 @@ | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|  | ||||
|     <parent> | ||||
|         <groupId>net.md-5</groupId> | ||||
|         <groupId>fr.pandacube.bungeecord</groupId> | ||||
|         <artifactId>bungeecord-parent</artifactId> | ||||
|         <version>1.20-R0.2-SNAPSHOT</version> | ||||
|         <relativePath>../pom.xml</relativePath> | ||||
|     </parent> | ||||
|  | ||||
|     <groupId>net.md-5</groupId> | ||||
|     <artifactId>bungeecord-log</artifactId> | ||||
|     <version>1.20-R0.2-SNAPSHOT</version> | ||||
|     <packaging>jar</packaging> | ||||
| @@ -26,7 +25,7 @@ | ||||
|             <scope>compile</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>net.md-5</groupId> | ||||
|             <groupId>fr.pandacube.bungeecord</groupId> | ||||
|             <artifactId>bungeecord-chat</artifactId> | ||||
|             <version>${project.version}</version> | ||||
|             <scope>compile</scope> | ||||
|   | ||||
| @@ -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.2-SNAPSHOT</version> | ||||
|         <relativePath>../pom.xml</relativePath> | ||||
|     </parent> | ||||
|  | ||||
|     <groupId>net.md-5</groupId> | ||||
|     <artifactId>bungeecord-module-cmd-alert</artifactId> | ||||
|     <version>1.20-R0.2-SNAPSHOT</version> | ||||
|     <packaging>jar</packaging> | ||||
|  | ||||
|     <name>cmd_alert</name> | ||||
|     <description>Provides the alert and alertraw commands</description> | ||||
| </project> | ||||
| @@ -1,47 +0,0 @@ | ||||
| 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.CommandSender; | ||||
| import net.md_5.bungee.api.ProxyServer; | ||||
| import net.md_5.bungee.api.chat.TextComponent; | ||||
| import net.md_5.bungee.api.plugin.Command; | ||||
|  | ||||
| public class CommandAlert extends Command | ||||
| { | ||||
|  | ||||
|     public CommandAlert() | ||||
|     { | ||||
|         super( "alert", "bungeecord.command.alert" ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void execute(CommandSender sender, String[] args) | ||||
|     { | ||||
|         if ( args.length == 0 ) | ||||
|         { | ||||
|             sender.sendMessage( ProxyServer.getInstance().getTranslation( "message_needed" ) ); | ||||
|         } else | ||||
|         { | ||||
|             StringBuilder builder = new StringBuilder(); | ||||
|             if ( args[0].toLowerCase( Locale.ROOT ).startsWith( "&h" ) ) | ||||
|             { | ||||
|                 // Remove &h | ||||
|                 args[0] = args[0].substring( 2 ); | ||||
|             } else | ||||
|             { | ||||
|                 builder.append( ProxyServer.getInstance().getTranslation( "alert" ) ); | ||||
|             } | ||||
|  | ||||
|             for ( String s : args ) | ||||
|             { | ||||
|                 builder.append( ChatColor.translateAlternateColorCodes( '&', s ) ); | ||||
|                 builder.append( " " ); | ||||
|             } | ||||
|  | ||||
|             String message = builder.substring( 0, builder.length() - 1 ); | ||||
|  | ||||
|             ProxyServer.getInstance().broadcast( TextComponent.fromLegacyText( message ) ); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,56 +0,0 @@ | ||||
| package net.md_5.bungee.module.cmd.alert; | ||||
|  | ||||
| import com.google.common.base.Joiner; | ||||
| 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.ComponentBuilder; | ||||
| import net.md_5.bungee.api.chat.HoverEvent; | ||||
| import net.md_5.bungee.api.connection.ProxiedPlayer; | ||||
| import net.md_5.bungee.api.plugin.Command; | ||||
| import net.md_5.bungee.chat.ComponentSerializer; | ||||
|  | ||||
| public class CommandAlertRaw extends Command | ||||
| { | ||||
|  | ||||
|     public CommandAlertRaw() | ||||
|     { | ||||
|         super( "alertraw", "bungeecord.command.alert" ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void execute(CommandSender sender, String[] args) | ||||
|     { | ||||
|         if ( args.length == 0 ) | ||||
|         { | ||||
|             sender.sendMessage( ProxyServer.getInstance().getTranslation( "message_needed" ) ); | ||||
|         } else | ||||
|         { | ||||
|             String message = Joiner.on( ' ' ).join( args ); | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 ProxyServer.getInstance().broadcast( ComponentSerializer.parse( message ) ); | ||||
|             } catch ( Exception e ) | ||||
|             { | ||||
|                 Throwable error = e; | ||||
|                 while ( error.getCause() != null ) | ||||
|                 { | ||||
|                     error = error.getCause(); | ||||
|                 } | ||||
|                 if ( sender instanceof ProxiedPlayer ) | ||||
|                 { | ||||
|                     sender.sendMessage( new ComponentBuilder( ProxyServer.getInstance().getTranslation( "error_occurred_player" ) ) | ||||
|                             .event( new HoverEvent( HoverEvent.Action.SHOW_TEXT, new ComponentBuilder( error.getMessage() ) | ||||
|                                     .color( ChatColor.RED ) | ||||
|                                     .create() ) ) | ||||
|                             .create() | ||||
|                     ); | ||||
|                 } else | ||||
|                 { | ||||
|                     sender.sendMessage( ProxyServer.getInstance().getTranslation( "error_occurred_console", error.getMessage() ) ); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,14 +0,0 @@ | ||||
| package net.md_5.bungee.module.cmd.alert; | ||||
|  | ||||
| import net.md_5.bungee.api.plugin.Plugin; | ||||
|  | ||||
| public class PluginAlert extends Plugin | ||||
| { | ||||
|  | ||||
|     @Override | ||||
|     public void onEnable() | ||||
|     { | ||||
|         getProxy().getPluginManager().registerCommand( this, new CommandAlert() ); | ||||
|         getProxy().getPluginManager().registerCommand( this, new CommandAlertRaw() ); | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +0,0 @@ | ||||
| name: ${project.name} | ||||
| main: net.md_5.bungee.module.cmd.alert.PluginAlert | ||||
| version: ${describe} | ||||
| description: ${project.description} | ||||
| author: ${module.author} | ||||
| @@ -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.2-SNAPSHOT</version> | ||||
|         <relativePath>../pom.xml</relativePath> | ||||
|     </parent> | ||||
|  | ||||
|     <groupId>net.md-5</groupId> | ||||
|     <artifactId>bungeecord-module-cmd-find</artifactId> | ||||
|     <version>1.20-R0.2-SNAPSHOT</version> | ||||
|     <packaging>jar</packaging> | ||||
|  | ||||
|     <name>cmd_find</name> | ||||
|     <description>Provides the find command</description> | ||||
| </project> | ||||
| @@ -1,58 +0,0 @@ | ||||
| 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.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.command.PlayerCommand; | ||||
|  | ||||
| public class CommandFind extends PlayerCommand | ||||
| { | ||||
|  | ||||
|     public CommandFind() | ||||
|     { | ||||
|         super( "find", "bungeecord.command.find" ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void execute(CommandSender sender, String[] args) | ||||
|     { | ||||
|         if ( args.length != 1 ) | ||||
|         { | ||||
|             sender.sendMessage( ProxyServer.getInstance().getTranslation( "username_needed" ) ); | ||||
|         } else | ||||
|         { | ||||
|             ProxiedPlayer player = ProxyServer.getInstance().getPlayer( args[0] ); | ||||
|             if ( player == null || player.getServer() == null ) | ||||
|             { | ||||
|                 sender.sendMessage( ProxyServer.getInstance().getTranslation( "user_not_online" ) ); | ||||
|             } else | ||||
|             { | ||||
|                 boolean moduleLoaded = ProxyServer.getInstance().getPluginManager().getPlugin( "cmd_server" ) != null; | ||||
|                 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,13 +0,0 @@ | ||||
| package net.md_5.bungee.module.cmd.find; | ||||
|  | ||||
| import net.md_5.bungee.api.plugin.Plugin; | ||||
|  | ||||
| public class PluginFind extends Plugin | ||||
| { | ||||
|  | ||||
|     @Override | ||||
|     public void onEnable() | ||||
|     { | ||||
|         getProxy().getPluginManager().registerCommand( this, new CommandFind() ); | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +0,0 @@ | ||||
| name: ${project.name} | ||||
| main: net.md_5.bungee.module.cmd.find.PluginFind | ||||
| version: ${describe} | ||||
| description: ${project.description} | ||||
| author: ${module.author} | ||||
| @@ -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.2-SNAPSHOT</version> | ||||
|         <relativePath>../pom.xml</relativePath> | ||||
|     </parent> | ||||
|  | ||||
|     <groupId>net.md-5</groupId> | ||||
|     <artifactId>bungeecord-module-cmd-kick</artifactId> | ||||
|     <version>1.20-R0.2-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.fromLegacyText( ProxyServer.getInstance().getTranslation( "user_not_online" ) ) ); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             if ( args.length == 1 ) | ||||
|             { | ||||
|                 player.disconnect( TextComponent.fromLegacyText( ProxyServer.getInstance().getTranslation( "kick_message" ) ) ); | ||||
|             } else | ||||
|             { | ||||
|                 String[] reason = new String[ args.length - 1 ]; | ||||
|                 System.arraycopy( args, 1, reason, 0, reason.length ); | ||||
|                 player.disconnect( TextComponent.fromLegacyText( 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} | ||||
| @@ -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.2-SNAPSHOT</version> | ||||
|         <relativePath>../pom.xml</relativePath> | ||||
|     </parent> | ||||
|  | ||||
|     <groupId>net.md-5</groupId> | ||||
|     <artifactId>bungeecord-module-cmd-list</artifactId> | ||||
|     <version>1.20-R0.2-SNAPSHOT</version> | ||||
|     <packaging>jar</packaging> | ||||
|  | ||||
|     <name>cmd_list</name> | ||||
|     <description>Provides the glist command</description> | ||||
| </project> | ||||
| @@ -1,62 +0,0 @@ | ||||
| package net.md_5.bungee.module.cmd.list; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collection; | ||||
| import java.util.Collections; | ||||
| import java.util.List; | ||||
| 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.config.ServerInfo; | ||||
| import net.md_5.bungee.api.connection.ProxiedPlayer; | ||||
| 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. | ||||
|  */ | ||||
| public class CommandList extends Command implements TabExecutor | ||||
| { | ||||
|  | ||||
|     public CommandList() | ||||
|     { | ||||
|         super( "glist", "bungeecord.command.list" ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void execute(CommandSender sender, String[] args) | ||||
|     { | ||||
|         boolean hideEmptyServers = ( args.length == 0 ) || !args[0].equalsIgnoreCase( "all" ); | ||||
|  | ||||
|         for ( ServerInfo server : ProxyServer.getInstance().getServers().values() ) | ||||
|         { | ||||
|             if ( !server.canAccess( sender ) ) | ||||
|             { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             Collection<ProxiedPlayer> serverPlayers = server.getPlayers(); | ||||
|             if ( hideEmptyServers && serverPlayers.isEmpty() ) | ||||
|             { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             List<String> players = new ArrayList<>(); | ||||
|             for ( ProxiedPlayer player : serverPlayers ) | ||||
|             { | ||||
|                 players.add( player.getDisplayName() ); | ||||
|             } | ||||
|             Collections.sort( players, String.CASE_INSENSITIVE_ORDER ); | ||||
|  | ||||
|             sender.sendMessage( ProxyServer.getInstance().getTranslation( "command_list", server.getName(), players.size(), String.join( ChatColor.RESET + ", ", players ) ) ); | ||||
|         } | ||||
|  | ||||
|         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" ); | ||||
|     } | ||||
| } | ||||
| @@ -1,13 +0,0 @@ | ||||
| package net.md_5.bungee.module.cmd.list; | ||||
|  | ||||
| import net.md_5.bungee.api.plugin.Plugin; | ||||
|  | ||||
| public class PluginList extends Plugin | ||||
| { | ||||
|  | ||||
|     @Override | ||||
|     public void onEnable() | ||||
|     { | ||||
|         getProxy().getPluginManager().registerCommand( this, new CommandList() ); | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +0,0 @@ | ||||
| name: ${project.name} | ||||
| main: net.md_5.bungee.module.cmd.list.PluginList | ||||
| version: ${describe} | ||||
| description: ${project.description} | ||||
| author: ${module.author} | ||||
| @@ -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.2-SNAPSHOT</version> | ||||
|         <relativePath>../pom.xml</relativePath> | ||||
|     </parent> | ||||
|  | ||||
|     <groupId>net.md-5</groupId> | ||||
|     <artifactId>bungeecord-module-cmd-send</artifactId> | ||||
|     <version>1.20-R0.2-SNAPSHOT</version> | ||||
|     <packaging>jar</packaging> | ||||
|  | ||||
|     <name>cmd_send</name> | ||||
|     <description>Provides the gsend command</description> | ||||
| </project> | ||||
| @@ -1,200 +0,0 @@ | ||||
| package net.md_5.bungee.module.cmd.send; | ||||
|  | ||||
| import com.google.common.base.Joiner; | ||||
| import com.google.common.collect.ImmutableSet; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collections; | ||||
| import java.util.HashMap; | ||||
| import java.util.HashSet; | ||||
| import java.util.List; | ||||
| import java.util.Locale; | ||||
| import java.util.Map; | ||||
| import java.util.Set; | ||||
| import net.md_5.bungee.api.Callback; | ||||
| 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.ServerConnectRequest; | ||||
| 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.event.ServerConnectEvent; | ||||
| import net.md_5.bungee.api.plugin.Command; | ||||
| import net.md_5.bungee.api.plugin.TabExecutor; | ||||
|  | ||||
| public class CommandSend extends Command implements TabExecutor | ||||
| { | ||||
|  | ||||
|     protected static class SendCallback | ||||
|     { | ||||
|  | ||||
|         private final Map<ServerConnectRequest.Result, List<String>> results = new HashMap<>(); | ||||
|         private final CommandSender sender; | ||||
|         private int count = 0; | ||||
|  | ||||
|         public SendCallback(CommandSender sender) | ||||
|         { | ||||
|             this.sender = sender; | ||||
|             for ( ServerConnectRequest.Result result : ServerConnectRequest.Result.values() ) | ||||
|             { | ||||
|                 results.put( result, new ArrayList<String>() ); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public void lastEntryDone() | ||||
|         { | ||||
|             sender.sendMessage( ChatColor.GREEN.toString() + ChatColor.BOLD + "Send Results:" ); | ||||
|             for ( Map.Entry<ServerConnectRequest.Result, List<String>> entry : results.entrySet() ) | ||||
|             { | ||||
|                 ComponentBuilder builder = new ComponentBuilder( "" ); | ||||
|                 if ( !entry.getValue().isEmpty() ) | ||||
|                 { | ||||
|                     builder.event( new HoverEvent( HoverEvent.Action.SHOW_TEXT, | ||||
|                             new ComponentBuilder( Joiner.on( ", " ).join( entry.getValue() ) ).color( ChatColor.YELLOW ).create() ) ); | ||||
|                 } | ||||
|                 builder.append( entry.getKey().name() + ": " ).color( ChatColor.GREEN ); | ||||
|                 builder.append( "" + entry.getValue().size() ).bold( true ); | ||||
|                 sender.sendMessage( builder.create() ); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public static class Entry implements Callback<ServerConnectRequest.Result> | ||||
|         { | ||||
|  | ||||
|             private final SendCallback callback; | ||||
|             private final ProxiedPlayer player; | ||||
|             private final ServerInfo target; | ||||
|  | ||||
|             public Entry(SendCallback callback, ProxiedPlayer player, ServerInfo target) | ||||
|             { | ||||
|                 this.callback = callback; | ||||
|                 this.player = player; | ||||
|                 this.target = target; | ||||
|                 this.callback.count++; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void done(ServerConnectRequest.Result result, Throwable error) | ||||
|             { | ||||
|                 callback.results.get( result ).add( player.getName() ); | ||||
|                 if ( result == ServerConnectRequest.Result.SUCCESS ) | ||||
|                 { | ||||
|                     player.sendMessage( ProxyServer.getInstance().getTranslation( "you_got_summoned", target.getName(), callback.sender.getName() ) ); | ||||
|                 } | ||||
|  | ||||
|                 if ( --callback.count == 0 ) | ||||
|                 { | ||||
|                     callback.lastEntryDone(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public CommandSend() | ||||
|     { | ||||
|         super( "send", "bungeecord.command.send" ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void execute(CommandSender sender, String[] args) | ||||
|     { | ||||
|         if ( args.length != 2 ) | ||||
|         { | ||||
|             sender.sendMessage( ProxyServer.getInstance().getTranslation( "send_cmd_usage" ) ); | ||||
|             return; | ||||
|         } | ||||
|         ServerInfo server = ProxyServer.getInstance().getServerInfo( args[1] ); | ||||
|         if ( server == null ) | ||||
|         { | ||||
|             sender.sendMessage( ProxyServer.getInstance().getTranslation( "no_server" ) ); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         List<ProxiedPlayer> targets; | ||||
|         if ( args[0].equalsIgnoreCase( "all" ) ) | ||||
|         { | ||||
|             targets = new ArrayList<>( ProxyServer.getInstance().getPlayers() ); | ||||
|         } else if ( args[0].equalsIgnoreCase( "current" ) ) | ||||
|         { | ||||
|             if ( !( sender instanceof ProxiedPlayer ) ) | ||||
|             { | ||||
|                 sender.sendMessage( ProxyServer.getInstance().getTranslation( "player_only" ) ); | ||||
|                 return; | ||||
|             } | ||||
|             ProxiedPlayer player = (ProxiedPlayer) sender; | ||||
|             targets = new ArrayList<>( player.getServer().getInfo().getPlayers() ); | ||||
|         } else | ||||
|         { | ||||
|             // If we use a server name, send the entire server. This takes priority over players. | ||||
|             ServerInfo serverTarget = ProxyServer.getInstance().getServerInfo( args[0] ); | ||||
|             if ( serverTarget != null ) | ||||
|             { | ||||
|                 targets = new ArrayList<>( serverTarget.getPlayers() ); | ||||
|             } else | ||||
|             { | ||||
|                 ProxiedPlayer player = ProxyServer.getInstance().getPlayer( args[0] ); | ||||
|                 if ( player == null ) | ||||
|                 { | ||||
|                     sender.sendMessage( ProxyServer.getInstance().getTranslation( "user_not_online" ) ); | ||||
|                     return; | ||||
|                 } | ||||
|                 targets = Collections.singletonList( player ); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         final SendCallback callback = new SendCallback( sender ); | ||||
|         for ( ProxiedPlayer player : targets ) | ||||
|         { | ||||
|             ServerConnectRequest request = ServerConnectRequest.builder() | ||||
|                     .target( server ) | ||||
|                     .reason( ServerConnectEvent.Reason.COMMAND ) | ||||
|                     .callback( new SendCallback.Entry( callback, player, server ) ) | ||||
|                     .build(); | ||||
|             player.connect( request ); | ||||
|         } | ||||
|  | ||||
|         sender.sendMessage( ChatColor.DARK_GREEN + "Attempting to send " + targets.size() + " players to " + server.getName() ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Iterable<String> onTabComplete(CommandSender sender, String[] args) | ||||
|     { | ||||
|         if ( args.length > 2 || args.length == 0 ) | ||||
|         { | ||||
|             return ImmutableSet.of(); | ||||
|         } | ||||
|  | ||||
|         Set<String> matches = new HashSet<>(); | ||||
|         if ( args.length == 1 ) | ||||
|         { | ||||
|             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() ); | ||||
|                 } | ||||
|             } | ||||
|             if ( "all".startsWith( search ) ) | ||||
|             { | ||||
|                 matches.add( "all" ); | ||||
|             } | ||||
|             if ( "current".startsWith( search ) ) | ||||
|             { | ||||
|                 matches.add( "current" ); | ||||
|             } | ||||
|         } else | ||||
|         { | ||||
|             String search = args[1].toLowerCase( Locale.ROOT ); | ||||
|             for ( String server : ProxyServer.getInstance().getServers().keySet() ) | ||||
|             { | ||||
|                 if ( server.toLowerCase( Locale.ROOT ).startsWith( search ) ) | ||||
|                 { | ||||
|                     matches.add( server ); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return matches; | ||||
|     } | ||||
| } | ||||
| @@ -1,13 +0,0 @@ | ||||
| package net.md_5.bungee.module.cmd.send; | ||||
|  | ||||
| import net.md_5.bungee.api.plugin.Plugin; | ||||
|  | ||||
| public class PluginSend extends Plugin | ||||
| { | ||||
|  | ||||
|     @Override | ||||
|     public void onEnable() | ||||
|     { | ||||
|         getProxy().getPluginManager().registerCommand( this, new CommandSend() ); | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +0,0 @@ | ||||
| name: ${project.name} | ||||
| main: net.md_5.bungee.module.cmd.send.PluginSend | ||||
| version: ${describe} | ||||
| description: ${project.description} | ||||
| author: ${module.author} | ||||
| @@ -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.2-SNAPSHOT</version> | ||||
|         <relativePath>../pom.xml</relativePath> | ||||
|     </parent> | ||||
|  | ||||
|     <groupId>net.md-5</groupId> | ||||
|     <artifactId>bungeecord-module-cmd-server</artifactId> | ||||
|     <version>1.20-R0.2-SNAPSHOT</version> | ||||
|     <packaging>jar</packaging> | ||||
|  | ||||
|     <name>cmd_server</name> | ||||
|     <description>Provides the server command</description> | ||||
| </project> | ||||
| @@ -1,104 +0,0 @@ | ||||
| package net.md_5.bungee.module.cmd.server; | ||||
|  | ||||
| import com.google.common.base.Function; | ||||
| import com.google.common.base.Predicate; | ||||
| import com.google.common.collect.Iterables; | ||||
| import java.util.Collections; | ||||
| import java.util.Locale; | ||||
| import java.util.Map; | ||||
| import net.md_5.bungee.api.CommandSender; | ||||
| 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.chat.TextComponent; | ||||
| import net.md_5.bungee.api.config.ServerInfo; | ||||
| import net.md_5.bungee.api.connection.ProxiedPlayer; | ||||
| import net.md_5.bungee.api.event.ServerConnectEvent; | ||||
| import net.md_5.bungee.api.plugin.Command; | ||||
| import net.md_5.bungee.api.plugin.TabExecutor; | ||||
|  | ||||
| /** | ||||
|  * Command to list and switch a player between available servers. | ||||
|  */ | ||||
| public class CommandServer extends Command implements TabExecutor | ||||
| { | ||||
|  | ||||
|     public CommandServer() | ||||
|     { | ||||
|         super( "server", "bungeecord.command.server" ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void execute(CommandSender sender, String[] args) | ||||
|     { | ||||
|         Map<String, ServerInfo> servers = ProxyServer.getInstance().getServers(); | ||||
|         if ( args.length == 0 ) | ||||
|         { | ||||
|             if ( sender instanceof ProxiedPlayer ) | ||||
|             { | ||||
|                 sender.sendMessage( ProxyServer.getInstance().getTranslation( "current_server", ( (ProxiedPlayer) sender ).getServer().getInfo().getName() ) ); | ||||
|             } | ||||
|  | ||||
|             ComponentBuilder serverList = new ComponentBuilder().appendLegacy( ProxyServer.getInstance().getTranslation( "server_list" ) ); | ||||
|             boolean first = true; | ||||
|             for ( ServerInfo server : servers.values() ) | ||||
|             { | ||||
|                 if ( server.canAccess( sender ) ) | ||||
|                 { | ||||
|                     TextComponent serverTextComponent = new TextComponent( first ? server.getName() : ", " + server.getName() ); | ||||
|                     int count = server.getPlayers().size(); | ||||
|                     serverTextComponent.setHoverEvent( new HoverEvent( | ||||
|                             HoverEvent.Action.SHOW_TEXT, | ||||
|                             new ComponentBuilder( count + ( count == 1 ? " player" : " players" ) + "\n" ).appendLegacy( ProxyServer.getInstance().getTranslation( "click_to_connect" ) ).create() ) | ||||
|                     ); | ||||
|                     serverTextComponent.setClickEvent( new ClickEvent( ClickEvent.Action.RUN_COMMAND, "/server " + server.getName() ) ); | ||||
|                     serverList.append( serverTextComponent ); | ||||
|                     first = false; | ||||
|                 } | ||||
|             } | ||||
|             sender.sendMessage( serverList.create() ); | ||||
|         } else | ||||
|         { | ||||
|             if ( !( sender instanceof ProxiedPlayer ) ) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             ProxiedPlayer player = (ProxiedPlayer) sender; | ||||
|  | ||||
|             ServerInfo server = servers.get( args[0] ); | ||||
|             if ( server == null ) | ||||
|             { | ||||
|                 player.sendMessage( ProxyServer.getInstance().getTranslation( "no_server" ) ); | ||||
|             } else if ( !server.canAccess( player ) ) | ||||
|             { | ||||
|                 player.sendMessage( ProxyServer.getInstance().getTranslation( "no_server_permission" ) ); | ||||
|             } else | ||||
|             { | ||||
|                 player.connect( server, ServerConnectEvent.Reason.COMMAND ); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Iterable<String> onTabComplete(final CommandSender sender, final String[] args) | ||||
|     { | ||||
|         return ( args.length > 1 ) ? Collections.EMPTY_LIST : Iterables.transform( Iterables.filter( ProxyServer.getInstance().getServers().values(), new Predicate<ServerInfo>() | ||||
|         { | ||||
|             private final String lower = ( args.length == 0 ) ? "" : args[0].toLowerCase( Locale.ROOT ); | ||||
|  | ||||
|             @Override | ||||
|             public boolean apply(ServerInfo input) | ||||
|             { | ||||
|                 return input.getName().toLowerCase( Locale.ROOT ).startsWith( lower ) && input.canAccess( sender ); | ||||
|             } | ||||
|         } ), new Function<ServerInfo, String>() | ||||
|         { | ||||
|             @Override | ||||
|             public String apply(ServerInfo input) | ||||
|             { | ||||
|                 return input.getName(); | ||||
|             } | ||||
|         } ); | ||||
|     } | ||||
| } | ||||
| @@ -1,13 +0,0 @@ | ||||
| package net.md_5.bungee.module.cmd.server; | ||||
|  | ||||
| import net.md_5.bungee.api.plugin.Plugin; | ||||
|  | ||||
| public class PluginServer extends Plugin | ||||
| { | ||||
|  | ||||
|     @Override | ||||
|     public void onEnable() | ||||
|     { | ||||
|         getProxy().getPluginManager().registerCommand( this, new CommandServer() ); | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +0,0 @@ | ||||
| name: ${project.name} | ||||
| main: net.md_5.bungee.module.cmd.server.PluginServer | ||||
| version: ${describe} | ||||
| description: ${project.description} | ||||
| author: ${module.author} | ||||
| @@ -1,55 +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-parent</artifactId> | ||||
|         <version>1.20-R0.2-SNAPSHOT</version> | ||||
|         <relativePath>../pom.xml</relativePath> | ||||
|     </parent> | ||||
|  | ||||
|     <groupId>net.md-5</groupId> | ||||
|     <artifactId>bungeecord-module</artifactId> | ||||
|     <version>1.20-R0.2-SNAPSHOT</version> | ||||
|     <packaging>pom</packaging> | ||||
|  | ||||
|     <name>BungeeCord Modules</name> | ||||
|     <description>Parent project for all BungeeCord modules.</description> | ||||
|  | ||||
|     <modules> | ||||
|         <module>cmd-alert</module> | ||||
|         <module>cmd-find</module> | ||||
|         <module>cmd-kick</module> | ||||
|         <module>cmd-list</module> | ||||
|         <module>cmd-send</module> | ||||
|         <module>cmd-server</module> | ||||
|         <module>reconnect-yaml</module> | ||||
|     </modules> | ||||
|  | ||||
|     <properties> | ||||
|         <module.author>SpigotMC</module.author> | ||||
|         <maven.deploy.skip>true</maven.deploy.skip> | ||||
|         <maven.javadoc.skip>true</maven.javadoc.skip> | ||||
|     </properties> | ||||
|  | ||||
|     <dependencies> | ||||
|         <dependency> | ||||
|             <groupId>net.md-5</groupId> | ||||
|             <artifactId>bungeecord-api</artifactId> | ||||
|             <version>${project.version}</version> | ||||
|             <scope>compile</scope> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
|  | ||||
|     <build> | ||||
|         <finalName>${project.name}</finalName> | ||||
|         <resources> | ||||
|             <resource> | ||||
|                 <filtering>true</filtering> | ||||
|                 <directory>${basedir}/src/main/resources</directory> | ||||
|             </resource> | ||||
|         </resources> | ||||
|     </build> | ||||
| </project> | ||||
| @@ -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.2-SNAPSHOT</version> | ||||
|         <relativePath>../pom.xml</relativePath> | ||||
|     </parent> | ||||
|  | ||||
|     <groupId>net.md-5</groupId> | ||||
|     <artifactId>bungeecord-module-reconnect-yaml</artifactId> | ||||
|     <version>1.20-R0.2-SNAPSHOT</version> | ||||
|     <packaging>jar</packaging> | ||||
|  | ||||
|     <name>reconnect_yaml</name> | ||||
|     <description>Provides reconnect location functionality in locations.yml</description> | ||||
| </project> | ||||
| @@ -1,22 +0,0 @@ | ||||
| package net.md_5.bungee.module.reconnect.yaml; | ||||
|  | ||||
| import net.md_5.bungee.api.config.ListenerInfo; | ||||
| import net.md_5.bungee.api.plugin.Plugin; | ||||
|  | ||||
| public class PluginYaml extends Plugin | ||||
| { | ||||
|  | ||||
|     @Override | ||||
|     public void onEnable() | ||||
|     { | ||||
|         // TODO: Abstract this for other reconnect modules | ||||
|         for ( ListenerInfo info : getProxy().getConfig().getListeners() ) | ||||
|         { | ||||
|             if ( !info.isForceDefault() && getProxy().getReconnectHandler() == null ) | ||||
|             { | ||||
|                 getProxy().setReconnectHandler( new YamlReconnectHandler() ); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,115 +0,0 @@ | ||||
| package net.md_5.bungee.module.reconnect.yaml; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.FileReader; | ||||
| import java.io.FileWriter; | ||||
| import java.io.IOException; | ||||
| import java.net.InetSocketAddress; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| import java.util.concurrent.locks.ReadWriteLock; | ||||
| import java.util.concurrent.locks.ReentrantReadWriteLock; | ||||
| import java.util.logging.Level; | ||||
| import net.md_5.bungee.api.AbstractReconnectHandler; | ||||
| import net.md_5.bungee.api.ProxyServer; | ||||
| import net.md_5.bungee.api.config.ServerInfo; | ||||
| import net.md_5.bungee.api.connection.ProxiedPlayer; | ||||
| import net.md_5.bungee.util.CaseInsensitiveMap; | ||||
| import org.yaml.snakeyaml.Yaml; | ||||
|  | ||||
| public class YamlReconnectHandler extends AbstractReconnectHandler | ||||
| { | ||||
|  | ||||
|     private final Yaml yaml = new Yaml(); | ||||
|     private final File file = new File( "locations.yml" ); | ||||
|     private final ReadWriteLock lock = new ReentrantReadWriteLock(); | ||||
|     /*========================================================================*/ | ||||
|     private CaseInsensitiveMap<String> data; | ||||
|  | ||||
|     @SuppressWarnings("unchecked") | ||||
|     public YamlReconnectHandler() | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             file.createNewFile(); | ||||
|             try ( FileReader rd = new FileReader( file ) ) | ||||
|             { | ||||
|                 Map map = yaml.loadAs( rd, Map.class ); | ||||
|                 if ( map != null ) | ||||
|                 { | ||||
|                     data = new CaseInsensitiveMap<>( map ); | ||||
|                 } | ||||
|             } | ||||
|         } catch ( Exception ex ) | ||||
|         { | ||||
|             file.renameTo( new File( "locations.yml.old" ) ); | ||||
|             ProxyServer.getInstance().getLogger().log( Level.WARNING, "Could not load reconnect locations, resetting them" ); | ||||
|         } | ||||
|  | ||||
|         if ( data == null ) | ||||
|         { | ||||
|             data = new CaseInsensitiveMap<>(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected ServerInfo getStoredServer(ProxiedPlayer player) | ||||
|     { | ||||
|         ServerInfo server = null; | ||||
|         lock.readLock().lock(); | ||||
|         try | ||||
|         { | ||||
|             server = ProxyServer.getInstance().getServerInfo( data.get( key( player ) ) ); | ||||
|         } finally | ||||
|         { | ||||
|             lock.readLock().unlock(); | ||||
|         } | ||||
|         return server; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void setServer(ProxiedPlayer player) | ||||
|     { | ||||
|         lock.writeLock().lock(); | ||||
|         try | ||||
|         { | ||||
|             data.put( key( player ), ( player.getReconnectServer() != null ) ? player.getReconnectServer().getName() : player.getServer().getInfo().getName() ); | ||||
|         } finally | ||||
|         { | ||||
|             lock.writeLock().unlock(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private String key(ProxiedPlayer player) | ||||
|     { | ||||
|         InetSocketAddress host = player.getPendingConnection().getVirtualHost(); | ||||
|         return player.getName() + ";" + host.getHostString() + ":" + host.getPort(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void save() | ||||
|     { | ||||
|         Map<String, String> copy = new HashMap<>(); | ||||
|         lock.readLock().lock(); | ||||
|         try | ||||
|         { | ||||
|             copy.putAll( data ); | ||||
|         } finally | ||||
|         { | ||||
|             lock.readLock().unlock(); | ||||
|         } | ||||
|  | ||||
|         try ( FileWriter wr = new FileWriter( file ) ) | ||||
|         { | ||||
|             yaml.dump( copy, wr ); | ||||
|         } catch ( IOException ex ) | ||||
|         { | ||||
|             ProxyServer.getInstance().getLogger().log( Level.WARNING, "Could not save reconnect locations", ex ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void close() | ||||
|     { | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +0,0 @@ | ||||
| name: ${project.name} | ||||
| main: net.md_5.bungee.module.reconnect.yaml.PluginYaml | ||||
| version: ${describe} | ||||
| description: ${project.description} | ||||
| author: ${module.author} | ||||
| @@ -4,13 +4,12 @@ | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|  | ||||
|     <parent> | ||||
|         <groupId>net.md-5</groupId> | ||||
|         <groupId>fr.pandacube.bungeecord</groupId> | ||||
|         <artifactId>bungeecord-parent</artifactId> | ||||
|         <version>1.20-R0.2-SNAPSHOT</version> | ||||
|         <relativePath>../pom.xml</relativePath> | ||||
|     </parent> | ||||
|  | ||||
|     <groupId>net.md-5</groupId> | ||||
|     <artifactId>bungeecord-native</artifactId> | ||||
|     <version>1.20-R0.2-SNAPSHOT</version> | ||||
|     <packaging>jar</packaging> | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| package net.md_5.bungee; | ||||
|  | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
| import io.netty.buffer.ByteBuf; | ||||
| import io.netty.buffer.Unpooled; | ||||
| import java.util.Random; | ||||
| @@ -9,12 +10,11 @@ import net.md_5.bungee.jni.NativeCode; | ||||
| import net.md_5.bungee.jni.cipher.BungeeCipher; | ||||
| import net.md_5.bungee.jni.cipher.JavaCipher; | ||||
| import net.md_5.bungee.jni.cipher.NativeCipher; | ||||
| import org.junit.Assert; | ||||
| import org.junit.FixMethodOrder; | ||||
| import org.junit.Test; | ||||
| import org.junit.runners.MethodSorters; | ||||
| import org.junit.jupiter.api.MethodOrderer; | ||||
| import org.junit.jupiter.api.Test; | ||||
| import org.junit.jupiter.api.TestMethodOrder; | ||||
|  | ||||
| @FixMethodOrder(MethodSorters.NAME_ASCENDING) | ||||
| @TestMethodOrder(MethodOrderer.MethodName.class) | ||||
| public class NativeCipherTest | ||||
| { | ||||
|  | ||||
| @@ -34,7 +34,7 @@ public class NativeCipherTest | ||||
|         if ( NativeCode.isSupported() ) | ||||
|         { | ||||
|             boolean loaded = factory.load(); | ||||
|             Assert.assertTrue( "Native cipher failed to load!", loaded ); | ||||
|             assertTrue( loaded, "Native cipher failed to load!" ); | ||||
|  | ||||
|             NativeCipher cipher = new NativeCipher(); | ||||
|             System.out.println( "Testing native cipher..." ); | ||||
| @@ -48,7 +48,7 @@ public class NativeCipherTest | ||||
|         if ( NativeCode.isSupported() ) | ||||
|         { | ||||
|             boolean loaded = factory.load(); | ||||
|             Assert.assertTrue( "Native cipher failed to load!", loaded ); | ||||
|             assertTrue( loaded, "Native cipher failed to load!" ); | ||||
|  | ||||
|             NativeCipher cipher = new NativeCipher(); | ||||
|  | ||||
| @@ -98,7 +98,7 @@ public class NativeCipherTest | ||||
|         // Encrypt | ||||
|         cipher.init( true, secret ); | ||||
|         cipher.cipher( nativePlain, out ); | ||||
|         Assert.assertEquals( nativeCiphered, out ); | ||||
|         assertEquals( nativeCiphered, out ); | ||||
|  | ||||
|         out.clear(); | ||||
|  | ||||
| @@ -106,7 +106,7 @@ public class NativeCipherTest | ||||
|         cipher.init( false, secret ); | ||||
|         cipher.cipher( nativeCiphered, out ); | ||||
|         nativePlain.resetReaderIndex(); | ||||
|         Assert.assertEquals( nativePlain, out ); | ||||
|         assertEquals( nativePlain, out ); | ||||
|  | ||||
|         System.out.println( "This cipher works correctly!" ); | ||||
|     } | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| package net.md_5.bungee; | ||||
|  | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
| import io.netty.buffer.ByteBuf; | ||||
| import io.netty.buffer.Unpooled; | ||||
| import java.util.Arrays; | ||||
| @@ -9,8 +10,7 @@ import net.md_5.bungee.jni.NativeCode; | ||||
| import net.md_5.bungee.jni.zlib.BungeeZlib; | ||||
| import net.md_5.bungee.jni.zlib.JavaZlib; | ||||
| import net.md_5.bungee.jni.zlib.NativeZlib; | ||||
| import org.junit.Assert; | ||||
| import org.junit.Test; | ||||
| import org.junit.jupiter.api.Test; | ||||
|  | ||||
| public class NativeZlibTest | ||||
| { | ||||
| @@ -22,7 +22,7 @@ public class NativeZlibTest | ||||
|     { | ||||
|         if ( NativeCode.isSupported() ) | ||||
|         { | ||||
|             Assert.assertTrue( "Native code failed to load!", factory.load() ); | ||||
|             assertTrue( factory.load(), "Native code failed to load!" ); | ||||
|             test( factory.newInstance() ); | ||||
|         } | ||||
|         test( new JavaZlib() ); | ||||
| @@ -64,6 +64,6 @@ public class NativeZlibTest | ||||
|         long elapsed = System.currentTimeMillis() - start; | ||||
|         System.out.println( "Took: " + elapsed + "ms" ); | ||||
|  | ||||
|         Assert.assertTrue( "Results do not match", Arrays.equals( dataBuf, check ) ); | ||||
|         assertTrue( Arrays.equals( dataBuf, check ), "Results do not match" ); | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										11
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								pom.xml
									
									
									
									
									
								
							| @@ -3,7 +3,7 @@ | ||||
|          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> | ||||
|  | ||||
|     <groupId>net.md-5</groupId> | ||||
|     <groupId>fr.pandacube.bungeecord</groupId> | ||||
|     <artifactId>bungeecord-parent</artifactId> | ||||
|     <version>1.20-R0.2-SNAPSHOT</version> | ||||
|     <packaging>pom</packaging> | ||||
| @@ -37,7 +37,6 @@ | ||||
|         <module>config</module> | ||||
|         <module>event</module> | ||||
|         <module>log</module> | ||||
|         <module>module</module> | ||||
|         <module>protocol</module> | ||||
|         <module>proxy</module> | ||||
|         <module>query</module> | ||||
| @@ -91,9 +90,9 @@ | ||||
|     </dependencyManagement> | ||||
|     <dependencies> | ||||
|         <dependency> | ||||
|             <groupId>junit</groupId> | ||||
|             <artifactId>junit</artifactId> | ||||
|             <version>4.13.2</version> | ||||
|             <groupId>org.junit.jupiter</groupId> | ||||
|             <artifactId>junit-jupiter</artifactId> | ||||
|             <version>5.10.0</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
| @@ -132,7 +131,7 @@ | ||||
|                 <artifactId>scriptus</artifactId> | ||||
|                 <version>0.5.0</version> | ||||
|                 <configuration> | ||||
|                     <format>git:${project.name}:${project.version}:%s:${build.number}</format> | ||||
|                     <format>git:${project.name}-Pandacube:${project.version}:%s:${build.number}</format> | ||||
|                 </configuration> | ||||
|                 <executions> | ||||
|                     <execution> | ||||
|   | ||||
| @@ -4,13 +4,12 @@ | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|  | ||||
|     <parent> | ||||
|         <groupId>net.md-5</groupId> | ||||
|         <groupId>fr.pandacube.bungeecord</groupId> | ||||
|         <artifactId>bungeecord-parent</artifactId> | ||||
|         <version>1.20-R0.2-SNAPSHOT</version> | ||||
|         <relativePath>../pom.xml</relativePath> | ||||
|     </parent> | ||||
|  | ||||
|     <groupId>net.md-5</groupId> | ||||
|     <artifactId>bungeecord-protocol</artifactId> | ||||
|     <version>1.20-R0.2-SNAPSHOT</version> | ||||
|     <packaging>jar</packaging> | ||||
| @@ -41,7 +40,7 @@ | ||||
|             <scope>compile</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>net.md-5</groupId> | ||||
|             <groupId>fr.pandacube.bungeecord</groupId> | ||||
|             <artifactId>bungeecord-chat</artifactId> | ||||
|             <version>${project.version}</version> | ||||
|             <scope>compile</scope> | ||||
|   | ||||
| @@ -15,6 +15,7 @@ public class MinecraftEncoder extends MessageToByteEncoder<DefinedPacket> | ||||
|     @Setter | ||||
|     private Protocol protocol; | ||||
|     private boolean server; | ||||
|     @Getter | ||||
|     @Setter | ||||
|     private int protocolVersion; | ||||
|  | ||||
|   | ||||
| @@ -658,8 +658,8 @@ public enum Protocol | ||||
|     /*========================================================================*/ | ||||
|     public static final int MAX_PACKET_ID = 0xFF; | ||||
|     /*========================================================================*/ | ||||
|     final DirectionData TO_SERVER = new DirectionData( this, ProtocolConstants.Direction.TO_SERVER ); | ||||
|     final DirectionData TO_CLIENT = new DirectionData( this, ProtocolConstants.Direction.TO_CLIENT ); | ||||
|     public final DirectionData TO_SERVER = new DirectionData( this, ProtocolConstants.Direction.TO_SERVER ); | ||||
|     public final DirectionData TO_CLIENT = new DirectionData( this, ProtocolConstants.Direction.TO_CLIENT ); | ||||
|  | ||||
|     public static void main(String[] args) | ||||
|     { | ||||
| @@ -719,7 +719,7 @@ public enum Protocol | ||||
|         return new ProtocolMapping( protocol, id ); | ||||
|     } | ||||
|  | ||||
|     static final class DirectionData | ||||
|     public static final class DirectionData | ||||
|     { | ||||
|  | ||||
|         private final TIntObjectMap<ProtocolData> protocols = new TIntObjectHashMap<>(); | ||||
| @@ -802,6 +802,17 @@ public enum Protocol | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public boolean hasPacket(Class<? extends DefinedPacket> packet, int version) | ||||
|         { | ||||
|             ProtocolData protocolData = getProtocolData( version ); | ||||
|             if ( protocolData == null ) | ||||
|             { | ||||
|                 throw new BadPacketException( "Unsupported protocol version" ); | ||||
|             } | ||||
|  | ||||
|             return protocolData.packetMap.containsKey( packet ); | ||||
|         } | ||||
|  | ||||
|         final int getId(Class<? extends DefinedPacket> packet, int version) | ||||
|         { | ||||
|  | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import com.google.common.base.Preconditions; | ||||
| import com.mojang.brigadier.Command; | ||||
| import com.mojang.brigadier.StringReader; | ||||
| import com.mojang.brigadier.arguments.ArgumentType; | ||||
| import com.mojang.brigadier.arguments.BoolArgumentType; | ||||
| import com.mojang.brigadier.arguments.DoubleArgumentType; | ||||
| import com.mojang.brigadier.arguments.FloatArgumentType; | ||||
| import com.mojang.brigadier.arguments.IntegerArgumentType; | ||||
| @@ -303,7 +304,7 @@ public class Commands extends DefinedPacket | ||||
|     } | ||||
|  | ||||
|     @Data | ||||
|     private static class ArgumentRegistry | ||||
|     public static class ArgumentRegistry | ||||
|     { | ||||
|  | ||||
|         private static final Map<String, ArgumentSerializer> PROVIDERS = new HashMap<>(); | ||||
| @@ -325,18 +326,29 @@ public class Commands extends DefinedPacket | ||||
|             { | ||||
|             } | ||||
|         }; | ||||
|         private static final ArgumentSerializer<Boolean> BOOLEAN = new ArgumentSerializer<Boolean>() | ||||
|         private static final ProperArgumentSerializer<BoolArgumentType> BOOLEAN = new ProperArgumentSerializer<BoolArgumentType>() | ||||
|         { | ||||
|             @Override | ||||
|             protected Boolean read(ByteBuf buf) | ||||
|             protected BoolArgumentType read(ByteBuf buf) | ||||
|             { | ||||
|                 return buf.readBoolean(); | ||||
|                 return BoolArgumentType.bool(); | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             protected void write(ByteBuf buf, Boolean t) | ||||
|             protected void write(ByteBuf buf, BoolArgumentType t) | ||||
|             { | ||||
|                 buf.writeBoolean( t ); | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             protected int getIntKey() | ||||
|             { | ||||
|                 return 0; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             protected String getKey() | ||||
|             { | ||||
|                 return "brigadier:bool"; | ||||
|             } | ||||
|         }; | ||||
|         private static final ArgumentSerializer<Byte> BYTE = new ArgumentSerializer<Byte>() | ||||
| @@ -353,7 +365,7 @@ public class Commands extends DefinedPacket | ||||
|                 buf.writeByte( t ); | ||||
|             } | ||||
|         }; | ||||
|         private static final ArgumentSerializer<FloatArgumentType> FLOAT_RANGE = new ArgumentSerializer<FloatArgumentType>() | ||||
|         private static final ProperArgumentSerializer<FloatArgumentType> FLOAT_RANGE = new ProperArgumentSerializer<FloatArgumentType>() | ||||
|         { | ||||
|             @Override | ||||
|             protected FloatArgumentType read(ByteBuf buf) | ||||
| @@ -381,8 +393,20 @@ public class Commands extends DefinedPacket | ||||
|                     buf.writeFloat( t.getMaximum() ); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             protected int getIntKey() | ||||
|             { | ||||
|                 return 1; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             protected String getKey() | ||||
|             { | ||||
|                 return "brigadier:float"; | ||||
|             } | ||||
|         }; | ||||
|         private static final ArgumentSerializer<DoubleArgumentType> DOUBLE_RANGE = new ArgumentSerializer<DoubleArgumentType>() | ||||
|         private static final ProperArgumentSerializer<DoubleArgumentType> DOUBLE_RANGE = new ProperArgumentSerializer<DoubleArgumentType>() | ||||
|         { | ||||
|             @Override | ||||
|             protected DoubleArgumentType read(ByteBuf buf) | ||||
| @@ -410,8 +434,20 @@ public class Commands extends DefinedPacket | ||||
|                     buf.writeDouble( t.getMaximum() ); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             protected int getIntKey() | ||||
|             { | ||||
|                 return 2; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             protected String getKey() | ||||
|             { | ||||
|                 return "brigadier:double"; | ||||
|             } | ||||
|         }; | ||||
|         private static final ArgumentSerializer<IntegerArgumentType> INTEGER_RANGE = new ArgumentSerializer<IntegerArgumentType>() | ||||
|         private static final ProperArgumentSerializer<IntegerArgumentType> INTEGER_RANGE = new ProperArgumentSerializer<IntegerArgumentType>() | ||||
|         { | ||||
|             @Override | ||||
|             protected IntegerArgumentType read(ByteBuf buf) | ||||
| @@ -439,6 +475,18 @@ public class Commands extends DefinedPacket | ||||
|                     buf.writeInt( t.getMaximum() ); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             protected int getIntKey() | ||||
|             { | ||||
|                 return 3; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             protected String getKey() | ||||
|             { | ||||
|                 return "brigadier:integer"; | ||||
|             } | ||||
|         }; | ||||
|         private static final ArgumentSerializer<Integer> INTEGER = new ArgumentSerializer<Integer>() | ||||
|         { | ||||
| @@ -454,7 +502,7 @@ public class Commands extends DefinedPacket | ||||
|                 buf.writeInt( t ); | ||||
|             } | ||||
|         }; | ||||
|         private static final ArgumentSerializer<LongArgumentType> LONG_RANGE = new ArgumentSerializer<LongArgumentType>() | ||||
|         private static final ProperArgumentSerializer<LongArgumentType> LONG_RANGE = new ProperArgumentSerializer<LongArgumentType>() | ||||
|         { | ||||
|             @Override | ||||
|             protected LongArgumentType read(ByteBuf buf) | ||||
| @@ -482,6 +530,18 @@ public class Commands extends DefinedPacket | ||||
|                     buf.writeLong( t.getMaximum() ); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             protected int getIntKey() | ||||
|             { | ||||
|                 return 4; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             protected String getKey() | ||||
|             { | ||||
|                 return "brigadier:long"; | ||||
|             } | ||||
|         }; | ||||
|         private static final ProperArgumentSerializer<StringArgumentType> STRING = new ProperArgumentSerializer<StringArgumentType>() | ||||
|         { | ||||
| @@ -537,11 +597,20 @@ public class Commands extends DefinedPacket | ||||
|  | ||||
|         static | ||||
|         { | ||||
|             register( "brigadier:bool", VOID ); | ||||
|             register( "brigadier:bool", BOOLEAN ); | ||||
|             PROPER_PROVIDERS.put( BoolArgumentType.class, BOOLEAN ); | ||||
|  | ||||
|             register( "brigadier:float", FLOAT_RANGE ); | ||||
|             PROPER_PROVIDERS.put( FloatArgumentType.class, FLOAT_RANGE ); | ||||
|  | ||||
|             register( "brigadier:double", DOUBLE_RANGE ); | ||||
|             PROPER_PROVIDERS.put( DoubleArgumentType.class, DOUBLE_RANGE ); | ||||
|  | ||||
|             register( "brigadier:integer", INTEGER_RANGE ); | ||||
|             register( "brigadier:long", LONG_RANGE ); | ||||
|             PROPER_PROVIDERS.put( IntegerArgumentType.class, INTEGER_RANGE ); | ||||
|  | ||||
|             register( "brigadier:long", LONG_RANGE ); // 1.14+ | ||||
|             PROPER_PROVIDERS.put( LongArgumentType.class, LONG_RANGE ); | ||||
|  | ||||
|             register( "brigadier:string", STRING ); | ||||
|             PROPER_PROVIDERS.put( StringArgumentType.class, STRING ); | ||||
| @@ -756,6 +825,404 @@ public class Commands extends DefinedPacket | ||||
|             return serializer; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:entity}. | ||||
|          * @param singleEntity if the argument restrict to only one entity | ||||
|          * @param onlyPlayers if the argument restrict to players only | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftEntity(boolean singleEntity, boolean onlyPlayers) | ||||
|         { | ||||
|             byte flags = 0; | ||||
|             if ( singleEntity ) | ||||
|             { | ||||
|                 flags |= 1; | ||||
|             } | ||||
|             if ( onlyPlayers ) | ||||
|             { | ||||
|                 flags |= 2; | ||||
|             } | ||||
|  | ||||
|             return minecraftArgumentType( "minecraft:entity", flags ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:game_profile}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftGameProfile() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:game_profile", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:block_pos}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftBlockPos() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:block_pos", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:column_pos}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftColumnPos() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:column_pos", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:vec3}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftVec3() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:vec3", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:vec2}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftVec2() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:vec2", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:block_state}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftBlockState() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:block_state", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:block_predicate}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftBlockPredicate() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:block_predicate", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:item_stack}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftItemStack() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:item_stack", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:item_predicate}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftItemPredicate() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:item_predicate", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:color}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftColor() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:color", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:component}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftComponent() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:component", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:message}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftMessage() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:message", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:nbt_compound_tag}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftNBTCompoundTag() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:nbt_compound_tag", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:nbt_tag}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftNBTTag() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:nbt_tag", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:nbt}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftNBT() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:nbt", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:nbt_path}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftNBTPath() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:nbt_path", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:objective}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftObjective() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:objective", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:objective_criteria}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftObjectiveCriteria() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:objective_criteria", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:operation}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftOperation() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:operation", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:particle}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftParticle() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:particle", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:rotation}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftRotation() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:rotation", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:scoreboard_slot}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftScoreboardSlot() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:scoreboard_slot", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:score_holder}. | ||||
|          * @param allowMultiple if the argument allows multiple entities | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftScoreHolder(boolean allowMultiple) | ||||
|         { | ||||
|             byte flags = 0; | ||||
|             if ( allowMultiple ) | ||||
|             { | ||||
|                 flags |= 1; | ||||
|             } | ||||
|  | ||||
|             return minecraftArgumentType( "minecraft:score_holder", flags ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:swizzle}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftSwizzle() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:swizzle", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:team}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftTeam() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:team", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:item_slot}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftItemSlot() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:item_slot", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:resource_location}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftResourceLocation() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:resource_location", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:mob_effect}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftMobEffect() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:mob_effect", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:function}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftFunction() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:function", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:entity_anchor}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftEntityAnchor() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:entity_anchor", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:int_range}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftIntRange() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:int_range", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:float_range}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftFloatRange() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:float_range", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:item_enchantment}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftItemEnchantment() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:item_enchantment", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:entity_summon}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftEntitySummon() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:entity_summon", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:dimension}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftDimension() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:dimension", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:time}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftTime() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:time", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:uuid}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftUUID() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:uuid", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:angle}. | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftAngle() | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:angle", null ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:resource}. | ||||
|          * @param rawString the raw string for the argument | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftResource(String rawString) | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:resource", rawString ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the Minecraft ArgumentType {@code minecraft:resource_or_tag}. | ||||
|          * @param rawString the raw string for the argument | ||||
|          * @return an ArgumentType instance | ||||
|          */ | ||||
|         public static ArgumentType<?> minecraftResourceOrTag(String rawString) | ||||
|         { | ||||
|             return minecraftArgumentType( "minecraft:resource_or_tag", rawString ); | ||||
|         } | ||||
|  | ||||
|         private static ArgumentType<?> minecraftArgumentType(String key, Object rawValue) | ||||
|         { | ||||
|             ArgumentSerializer reader = PROVIDERS.get( key ); | ||||
|             Preconditions.checkArgument( reader != null, "No provider for argument " + key ); | ||||
|  | ||||
|             return new DummyType( key, reader, rawValue ); | ||||
|         } | ||||
|  | ||||
|         private static ArgumentType<?> read(ByteBuf buf, int protocolVersion) | ||||
|         { | ||||
|             Object key; | ||||
| @@ -879,9 +1346,13 @@ public class Commands extends DefinedPacket | ||||
|  | ||||
|         private static String getKey(SuggestionProvider<DummyProvider> provider) | ||||
|         { | ||||
|             Preconditions.checkArgument( provider instanceof DummyProvider, "Non dummy provider " + provider ); | ||||
|             Preconditions.checkNotNull( provider ); | ||||
|             if ( provider instanceof DummyProvider ) | ||||
|             { | ||||
|                 return ( (DummyProvider) provider ).key; | ||||
|             } | ||||
|  | ||||
|             return ( (DummyProvider) provider ).key; | ||||
|             return ( (DummyProvider) ASK_SERVER ).key; | ||||
|         } | ||||
|  | ||||
|         @Data | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| package net.md_5.bungee.protocol.packet; | ||||
|  | ||||
| import org.junit.Assert; | ||||
| import org.junit.Test; | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
| import org.junit.jupiter.api.Test; | ||||
|  | ||||
| public class PluginMessageTest | ||||
| { | ||||
| @@ -9,9 +9,9 @@ public class PluginMessageTest | ||||
|     @Test | ||||
|     public void testModerniseChannel() | ||||
|     { | ||||
|         Assert.assertEquals( "bungeecord:main", PluginMessage.MODERNISE.apply( "BungeeCord" ) ); | ||||
|         Assert.assertEquals( "BungeeCord", PluginMessage.MODERNISE.apply( "bungeecord:main" ) ); | ||||
|         Assert.assertEquals( "legacy:foo", PluginMessage.MODERNISE.apply( "FoO" ) ); | ||||
|         Assert.assertEquals( "foo:bar", PluginMessage.MODERNISE.apply( "foo:bar" ) ); | ||||
|         assertEquals( "bungeecord:main", PluginMessage.MODERNISE.apply( "BungeeCord" ) ); | ||||
|         assertEquals( "BungeeCord", PluginMessage.MODERNISE.apply( "bungeecord:main" ) ); | ||||
|         assertEquals( "legacy:foo", PluginMessage.MODERNISE.apply( "FoO" ) ); | ||||
|         assertEquals( "foo:bar", PluginMessage.MODERNISE.apply( "foo:bar" ) ); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -4,13 +4,12 @@ | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|  | ||||
|     <parent> | ||||
|         <groupId>net.md-5</groupId> | ||||
|         <groupId>fr.pandacube.bungeecord</groupId> | ||||
|         <artifactId>bungeecord-parent</artifactId> | ||||
|         <version>1.20-R0.2-SNAPSHOT</version> | ||||
|         <relativePath>../pom.xml</relativePath> | ||||
|     </parent> | ||||
|  | ||||
|     <groupId>net.md-5</groupId> | ||||
|     <artifactId>bungeecord-proxy</artifactId> | ||||
|     <version>1.20-R0.2-SNAPSHOT</version> | ||||
|     <packaging>jar</packaging> | ||||
| @@ -52,37 +51,37 @@ | ||||
|             <scope>compile</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>net.md-5</groupId> | ||||
|             <groupId>fr.pandacube.bungeecord</groupId> | ||||
|             <artifactId>bungeecord-api</artifactId> | ||||
|             <version>${project.version}</version> | ||||
|             <scope>compile</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>net.md-5</groupId> | ||||
|             <groupId>fr.pandacube.bungeecord</groupId> | ||||
|             <artifactId>bungeecord-log</artifactId> | ||||
|             <version>${project.version}</version> | ||||
|             <scope>compile</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>net.md-5</groupId> | ||||
|             <groupId>fr.pandacube.bungeecord</groupId> | ||||
|             <artifactId>bungeecord-native</artifactId> | ||||
|             <version>${project.version}</version> | ||||
|             <scope>compile</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>net.md-5</groupId> | ||||
|             <groupId>fr.pandacube.bungeecord</groupId> | ||||
|             <artifactId>bungeecord-protocol</artifactId> | ||||
|             <version>${project.version}</version> | ||||
|             <scope>compile</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>net.md-5</groupId> | ||||
|             <groupId>fr.pandacube.bungeecord</groupId> | ||||
|             <artifactId>bungeecord-query</artifactId> | ||||
|             <version>${project.version}</version> | ||||
|             <scope>compile</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>net.md-5</groupId> | ||||
|             <groupId>fr.pandacube.bungeecord</groupId> | ||||
|             <artifactId>bungeecord-slf4j</artifactId> | ||||
|             <version>${project.version}</version> | ||||
|             <scope>compile</scope> | ||||
|   | ||||
| @@ -89,7 +89,6 @@ import net.md_5.bungee.forge.ForgeConstants; | ||||
| import net.md_5.bungee.log.BungeeLogger; | ||||
| import net.md_5.bungee.log.LoggingForwardHandler; | ||||
| import net.md_5.bungee.log.LoggingOutputStream; | ||||
| import net.md_5.bungee.module.ModuleManager; | ||||
| import net.md_5.bungee.netty.PipelineUtils; | ||||
| import net.md_5.bungee.protocol.DefinedPacket; | ||||
| import net.md_5.bungee.protocol.ProtocolConstants; | ||||
| @@ -173,7 +172,6 @@ public class BungeeCord extends ProxyServer | ||||
|             .registerTypeAdapter( Favicon.class, Favicon.getFaviconTypeAdapter() ).create(); | ||||
|     @Getter | ||||
|     private ConnectionThrottle connectionThrottle; | ||||
|     private final ModuleManager moduleManager = new ModuleManager(); | ||||
|  | ||||
|     { | ||||
|         // TODO: Proper fallback when we interface the manager | ||||
| @@ -271,10 +269,6 @@ public class BungeeCord extends ProxyServer | ||||
|  | ||||
|         eventLoops = PipelineUtils.newEventLoopGroup( 0, new ThreadFactoryBuilder().setNameFormat( "Netty IO Thread #%1$d" ).build() ); | ||||
|  | ||||
|         File moduleDirectory = new File( "modules" ); | ||||
|         moduleManager.load( this, moduleDirectory ); | ||||
|         pluginManager.detectPlugins( moduleDirectory ); | ||||
|  | ||||
|         pluginsFolder.mkdir(); | ||||
|         pluginManager.detectPlugins( pluginsFolder ); | ||||
|  | ||||
|   | ||||
| @@ -5,7 +5,6 @@ import java.text.SimpleDateFormat; | ||||
| import java.util.Arrays; | ||||
| import java.util.Calendar; | ||||
| import java.util.Date; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| import joptsimple.OptionParser; | ||||
| import joptsimple.OptionSet; | ||||
| import net.md_5.bungee.api.ChatColor; | ||||
| @@ -56,8 +55,7 @@ public class BungeeCordLauncher | ||||
|                 System.err.println( "*** Warning, this build is outdated ***" ); | ||||
|                 System.err.println( "*** Please download a new build from http://ci.md-5.net/job/BungeeCord ***" ); | ||||
|                 System.err.println( "*** You will get NO support regarding this build ***" ); | ||||
|                 System.err.println( "*** Server will start in 10 seconds ***" ); | ||||
|                 Thread.sleep( TimeUnit.SECONDS.toMillis( 10 ) ); | ||||
|  | ||||
|             } | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -5,6 +5,7 @@ import java.net.InetSocketAddress; | ||||
| import java.net.SocketAddress; | ||||
| import java.util.ArrayDeque; | ||||
| import java.util.Queue; | ||||
| import java.util.concurrent.ConcurrentLinkedQueue; | ||||
| import lombok.Data; | ||||
| import lombok.Getter; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| @@ -13,6 +14,7 @@ import net.md_5.bungee.api.chat.BaseComponent; | ||||
| import net.md_5.bungee.api.connection.Server; | ||||
| import net.md_5.bungee.netty.ChannelWrapper; | ||||
| import net.md_5.bungee.protocol.DefinedPacket; | ||||
| import net.md_5.bungee.protocol.Protocol; | ||||
| import net.md_5.bungee.protocol.packet.PluginMessage; | ||||
|  | ||||
| @RequiredArgsConstructor | ||||
| @@ -30,6 +32,7 @@ public class ServerConnection implements Server | ||||
|     private final boolean forgeServer = false; | ||||
|     @Getter | ||||
|     private final Queue<KeepAliveData> keepAlives = new ArrayDeque<>(); | ||||
|     private final Queue<DefinedPacket> packetQueue = new ConcurrentLinkedQueue<>(); | ||||
|  | ||||
|     private final Unsafe unsafe = new Unsafe() | ||||
|     { | ||||
| @@ -40,10 +43,31 @@ public class ServerConnection implements Server | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     public void sendPacketQueued(DefinedPacket packet) | ||||
|     { | ||||
|         Protocol encodeProtocol = ch.getEncodeProtocol(); | ||||
|         if ( !encodeProtocol.TO_SERVER.hasPacket( packet.getClass(), ch.getEncodeVersion() ) ) | ||||
|         { | ||||
|             packetQueue.add( packet ); | ||||
|         } else | ||||
|         { | ||||
|             unsafe().sendPacket( packet ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void sendQueuedPackets() | ||||
|     { | ||||
|         DefinedPacket packet; | ||||
|         while ( ( packet = packetQueue.poll() ) != null ) | ||||
|         { | ||||
|             unsafe().sendPacket( packet ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void sendData(String channel, byte[] data) | ||||
|     { | ||||
|         unsafe().sendPacket( new PluginMessage( channel, data, forgeServer ) ); | ||||
|         sendPacketQueued( new PluginMessage( channel, data, forgeServer ) ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -20,6 +20,7 @@ import java.util.Map; | ||||
| import java.util.Objects; | ||||
| import java.util.Queue; | ||||
| import java.util.UUID; | ||||
| import java.util.concurrent.ConcurrentLinkedQueue; | ||||
| import java.util.logging.Level; | ||||
| import lombok.Getter; | ||||
| import lombok.NonNull; | ||||
| @@ -142,6 +143,7 @@ public final class UserConnection implements ProxiedPlayer | ||||
|     @Setter | ||||
|     private ForgeServerHandler forgeServerHandler; | ||||
|     /*========================================================================*/ | ||||
|     private final Queue<DefinedPacket> packetQueue = new ConcurrentLinkedQueue<>(); | ||||
|     private final Unsafe unsafe = new Unsafe() | ||||
|     { | ||||
|         @Override | ||||
| @@ -177,6 +179,27 @@ public final class UserConnection implements ProxiedPlayer | ||||
|         ch.write( packet ); | ||||
|     } | ||||
|  | ||||
|     public void sendPacketQueued(DefinedPacket packet) | ||||
|     { | ||||
|         Protocol encodeProtocol = ch.getEncodeProtocol(); | ||||
|         if ( !encodeProtocol.TO_CLIENT.hasPacket( packet.getClass(), getPendingConnection().getVersion() ) ) | ||||
|         { | ||||
|             packetQueue.add( packet ); | ||||
|         } else | ||||
|         { | ||||
|             unsafe().sendPacket( packet ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void sendQueuedPackets() | ||||
|     { | ||||
|         DefinedPacket packet; | ||||
|         while ( ( packet = packetQueue.poll() ) != null ) | ||||
|         { | ||||
|             unsafe().sendPacket( packet ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Deprecated | ||||
|     public boolean isActive() | ||||
|     { | ||||
| @@ -489,10 +512,10 @@ public final class UserConnection implements ProxiedPlayer | ||||
|                 position = ChatMessageType.SYSTEM; | ||||
|             } | ||||
|  | ||||
|             unsafe().sendPacket( new SystemChat( message, position.ordinal() ) ); | ||||
|             sendPacketQueued( new SystemChat( message, position.ordinal() ) ); | ||||
|         } else | ||||
|         { | ||||
|             unsafe().sendPacket( new Chat( message, (byte) position.ordinal(), sender ) ); | ||||
|             sendPacketQueued( new Chat( message, (byte) position.ordinal(), sender ) ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -513,7 +536,7 @@ public final class UserConnection implements ProxiedPlayer | ||||
|                 net.md_5.bungee.protocol.packet.Title title = new net.md_5.bungee.protocol.packet.Title(); | ||||
|                 title.setAction( net.md_5.bungee.protocol.packet.Title.Action.ACTIONBAR ); | ||||
|                 title.setText( ComponentSerializer.toString( message ) ); | ||||
|                 unsafe.sendPacket( title ); | ||||
|                 sendPacketQueued( title ); | ||||
|             } | ||||
|         } else | ||||
|         { | ||||
| @@ -524,7 +547,7 @@ public final class UserConnection implements ProxiedPlayer | ||||
|     @Override | ||||
|     public void sendData(String channel, byte[] data) | ||||
|     { | ||||
|         unsafe().sendPacket( new PluginMessage( channel, data, forgeClientHandler.isForgeUser() ) ); | ||||
|         sendPacketQueued( new PluginMessage( channel, data, forgeClientHandler.isForgeUser() ) ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -700,7 +723,7 @@ public final class UserConnection implements ProxiedPlayer | ||||
|         header = ChatComponentTransformer.getInstance().transform( this, true, header )[0]; | ||||
|         footer = ChatComponentTransformer.getInstance().transform( this, true, footer )[0]; | ||||
|  | ||||
|         unsafe().sendPacket( new PlayerListHeaderFooter( | ||||
|         sendPacketQueued( new PlayerListHeaderFooter( | ||||
|                 ComponentSerializer.toString( header ), | ||||
|                 ComponentSerializer.toString( footer ) | ||||
|         ) ); | ||||
| @@ -712,7 +735,7 @@ public final class UserConnection implements ProxiedPlayer | ||||
|         header = ChatComponentTransformer.getInstance().transform( this, true, header ); | ||||
|         footer = ChatComponentTransformer.getInstance().transform( this, true, footer ); | ||||
|  | ||||
|         unsafe().sendPacket( new PlayerListHeaderFooter( | ||||
|         sendPacketQueued( new PlayerListHeaderFooter( | ||||
|                 ComponentSerializer.toString( header ), | ||||
|                 ComponentSerializer.toString( footer ) | ||||
|         ) ); | ||||
|   | ||||
| @@ -6,6 +6,7 @@ import com.google.common.collect.Lists; | ||||
| import com.google.common.io.ByteArrayDataOutput; | ||||
| import com.google.common.io.ByteStreams; | ||||
| import com.mojang.brigadier.arguments.StringArgumentType; | ||||
| import com.mojang.brigadier.builder.ArgumentBuilder; | ||||
| import com.mojang.brigadier.builder.LiteralArgumentBuilder; | ||||
| import com.mojang.brigadier.builder.RequiredArgumentBuilder; | ||||
| import com.mojang.brigadier.context.StringRange; | ||||
| @@ -19,9 +20,12 @@ import io.netty.channel.unix.DomainSocketAddress; | ||||
| import java.io.DataInput; | ||||
| import java.net.InetSocketAddress; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collection; | ||||
| import java.util.IdentityHashMap; | ||||
| import java.util.List; | ||||
| import java.util.Locale; | ||||
| import java.util.Map; | ||||
| import java.util.logging.Level; | ||||
| import java.util.stream.Collectors; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import net.md_5.bungee.ServerConnection; | ||||
| @@ -35,6 +39,7 @@ import net.md_5.bungee.api.chat.TextComponent; | ||||
| import net.md_5.bungee.api.config.ServerInfo; | ||||
| import net.md_5.bungee.api.connection.ProxiedPlayer; | ||||
| import net.md_5.bungee.api.connection.Server; | ||||
| import net.md_5.bungee.api.event.CommandsDeclareEvent; | ||||
| import net.md_5.bungee.api.event.PluginMessageEvent; | ||||
| import net.md_5.bungee.api.event.ServerConnectEvent; | ||||
| import net.md_5.bungee.api.event.ServerDisconnectEvent; | ||||
| @@ -299,7 +304,7 @@ public class DownstreamBridge extends PacketHandler | ||||
|             Preconditions.checkState( !serverBrand.contains( bungee.getName() ), "Cannot connect proxy to itself!" ); | ||||
|  | ||||
|             brand = ByteBufAllocator.DEFAULT.heapBuffer(); | ||||
|             DefinedPacket.writeString( bungee.getName() + " (" + bungee.getVersion() + ")" + " <- " + serverBrand, brand ); | ||||
|             DefinedPacket.writeString( bungee.getName() + " (" + bungee.getVersion() + ")" + " <- " + server.getInfo().getName() + " (" + serverBrand + ")", brand ); | ||||
|             pluginMessage.setData( DefinedPacket.toArray( brand ) ); | ||||
|             brand.release(); | ||||
|             // changes in the packet are ignored so we need to send it manually | ||||
| @@ -729,6 +734,11 @@ public class DownstreamBridge extends PacketHandler | ||||
|     { | ||||
|         boolean modified = false; | ||||
|  | ||||
|         CommandsDeclareEvent commandsDeclareEvent = new CommandsDeclareEvent( server, con, commands.getRoot() ); | ||||
|         bungee.getPluginManager().callEvent( commandsDeclareEvent ); | ||||
|  | ||||
|         modified = commandsDeclareEvent.isModified(); | ||||
|  | ||||
|         for ( Map.Entry<String, Command> command : bungee.getPluginManager().getCommands() ) | ||||
|         { | ||||
|             if ( !bungee.getDisabledCommands().contains( command.getKey() ) && commands.getRoot().getChild( command.getKey() ) == null && command.getValue().hasPermission( con ) ) | ||||
| @@ -745,11 +755,65 @@ public class DownstreamBridge extends PacketHandler | ||||
|  | ||||
|         if ( modified ) | ||||
|         { | ||||
|             commands.setRoot( (com.mojang.brigadier.tree.RootCommandNode) filterCommandNode( commands.getRoot(), new IdentityHashMap<>() ) ); | ||||
|             con.unsafe().sendPacket( commands ); | ||||
|             throw CancelSendSignal.INSTANCE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /* | ||||
|      * Create a deep copy of the provided command node but removes any node that are not accessible by the player | ||||
|      * (using {@link CommandNode#getRequirement()}) | ||||
|      */ | ||||
|     private CommandNode filterCommandNode(CommandNode source, IdentityHashMap<CommandNode, CommandNode> commandNodeMapping) | ||||
|     { | ||||
|         CommandNode dest; | ||||
|         if ( source instanceof com.mojang.brigadier.tree.RootCommandNode ) | ||||
|         { | ||||
|             dest = new com.mojang.brigadier.tree.RootCommandNode(); | ||||
|         } else | ||||
|         { | ||||
|             if ( source.getRequirement() != null ) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     if ( !source.getRequirement().test( con ) ) | ||||
|                     { | ||||
|                         commandNodeMapping.put( source, null ); | ||||
|                         return null; | ||||
|                     } | ||||
|                 } catch ( Throwable t ) | ||||
|                 { | ||||
|                     ProxyServer.getInstance().getLogger().log( Level.SEVERE, "Requirement test for command node " + source + " encountered an exception", t ); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             ArgumentBuilder destChildBuilder = source.createBuilder(); | ||||
|             destChildBuilder.requires( sender -> true ); | ||||
|             if ( destChildBuilder.getRedirect() != null ) | ||||
|             { | ||||
|                 if ( commandNodeMapping.containsKey( destChildBuilder.getRedirect() ) ) | ||||
|                     destChildBuilder.redirect( commandNodeMapping.get( destChildBuilder.getRedirect() ) ); | ||||
|                 else | ||||
|                     destChildBuilder.redirect( filterCommandNode( destChildBuilder.getRedirect(), commandNodeMapping ) ); | ||||
|             } | ||||
|  | ||||
|             dest = destChildBuilder.build(); | ||||
|         } | ||||
|  | ||||
|         commandNodeMapping.put( source, dest ); | ||||
|  | ||||
|         for ( CommandNode sourceChild : (Collection<CommandNode>) source.getChildren() ) | ||||
|         { | ||||
|             CommandNode destChild = filterCommandNode( sourceChild, commandNodeMapping ); | ||||
|             if ( destChild == null ) | ||||
|                 continue; | ||||
|             dest.addChild( destChild ); | ||||
|         } | ||||
|  | ||||
|         return dest; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void handle(ServerData serverData) throws Exception | ||||
|     { | ||||
|   | ||||
| @@ -114,6 +114,15 @@ public class InitialHandler extends PacketHandler implements PendingConnection | ||||
|     private String extraDataInHandshake = ""; | ||||
|     private UserConnection userCon; | ||||
|  | ||||
|     @Getter | ||||
|     private boolean duplication = false; | ||||
|  | ||||
|     @Getter | ||||
|     private String realName = null; | ||||
|  | ||||
|     @Getter | ||||
|     private UUID realId = null; | ||||
|  | ||||
|     @Override | ||||
|     public boolean shouldHandle(PacketWrapper packet) throws Exception | ||||
|     { | ||||
| @@ -411,6 +420,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection | ||||
|         } | ||||
|  | ||||
|         this.loginRequest = loginRequest; | ||||
|         setName( realName = loginRequest.getData() ); | ||||
|  | ||||
|         int limit = BungeeCord.getInstance().config.getPlayerLimit(); | ||||
|         if ( limit > 0 && bungee.getOnlineCount() >= limit ) | ||||
| @@ -419,14 +429,6 @@ public class InitialHandler extends PacketHandler implements PendingConnection | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // If offline mode and they are already on, don't allow connect | ||||
|         // We can just check by UUID here as names are based on UUID | ||||
|         if ( !isOnlineMode() && bungee.getPlayer( getUniqueId() ) != null ) | ||||
|         { | ||||
|             disconnect( bungee.getTranslation( "already_connected_proxy" ) ); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         Callback<PreLoginEvent> callback = new Callback<PreLoginEvent>() | ||||
|         { | ||||
|  | ||||
| @@ -443,6 +445,16 @@ public class InitialHandler extends PacketHandler implements PendingConnection | ||||
|                 { | ||||
|                     return; | ||||
|                 } | ||||
|                 if ( !realName.equals( name ) ) | ||||
|                 { | ||||
|                     // Floodgate changes the name attribute with reflexion | ||||
|                     setName( realName = name ); | ||||
|                 } | ||||
|                 if ( uniqueId != null ) | ||||
|                 { | ||||
|                     // if plugin called setUniqueId() | ||||
|                     realId = uniqueId; | ||||
|                 } | ||||
|                 if ( onlineMode ) | ||||
|                 { | ||||
|                     thisState = State.ENCRYPT; | ||||
| @@ -497,8 +509,8 @@ public class InitialHandler extends PacketHandler implements PendingConnection | ||||
|                     if ( obj != null && obj.getId() != null ) | ||||
|                     { | ||||
|                         loginProfile = obj; | ||||
|                         name = obj.getName(); | ||||
|                         uniqueId = Util.getUUID( obj.getId() ); | ||||
|                         setName( realName = obj.getName() ); | ||||
|                         uniqueId = realId = Util.getUUID( obj.getId() ); | ||||
|                         finish(); | ||||
|                         return; | ||||
|                     } | ||||
| @@ -516,10 +528,25 @@ public class InitialHandler extends PacketHandler implements PendingConnection | ||||
|  | ||||
|     private void finish() | ||||
|     { | ||||
|         offlineId = UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + getName() ).getBytes( Charsets.UTF_8 ) ); | ||||
|         if ( uniqueId == null ) | ||||
|         if ( uniqueId == null ) // offline mode and no plugin used setUniqueId() | ||||
|         { | ||||
|             uniqueId = offlineId; | ||||
|             uniqueId = realId = offlineId; | ||||
|         } | ||||
|  | ||||
|         /* | ||||
|          * At this point, player is either authenticated by Mojang (online mode), | ||||
|          * by a plugin (Floodgate ?) or the offline id is set. | ||||
|          */ | ||||
|         ProxiedPlayer existingPlayer = bungee.getPlayer( uniqueId ); | ||||
|         if ( existingPlayer != null && existingPlayer.hasPermission( "bungeecord.multiple_connect" ) ) | ||||
|         { | ||||
|             UUID newId = generateDuplicatedId( uniqueId ); | ||||
|             if ( !uniqueId.equals( newId ) ) | ||||
|             { | ||||
|                 uniqueId = newId; | ||||
|                 setName( name + "." + getDuplicationIndex( newId ) ); | ||||
|                 duplication = true; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if ( BungeeCord.getInstance().config.isEnforceSecureProfile() ) | ||||
| @@ -693,6 +720,54 @@ public class InitialHandler extends PacketHandler implements PendingConnection | ||||
|         return ( name != null ) ? name : ( loginRequest == null ) ? null : loginRequest.getData(); | ||||
|     } | ||||
|  | ||||
|     private void setName(String name) | ||||
|     { | ||||
|         this.name = name; | ||||
|         if ( loginRequest != null ) | ||||
|         { | ||||
|             loginRequest.setData( name ); // name transmitted to Spigot server | ||||
|         } | ||||
|         updateOfflineId(); | ||||
|     } | ||||
|  | ||||
|     private UUID generateDuplicatedId(UUID base) | ||||
|     { | ||||
|         // UUID version: offline = 3 ; Java online mode = 4 ; Floodgate xUID = 0 (and must be kept 0) | ||||
|         // UUID variant: offline = 0xx ; Java online mode = 10x ; Floodgate xUID = xxx | ||||
|         if ( base.version() == 0 ) | ||||
|         { | ||||
|             /* | ||||
|              * Floodgate’s xUID converted to UUID are not supported | ||||
|              * because it requires the 64 MSBs to be 0 (or Floodgate API would not | ||||
|              * recognize a Bedrock account) and we cannot modify the 64 LSBs | ||||
|              * without risking a collision with the xUID of another Bedrock account | ||||
|              */ | ||||
|             return base; | ||||
|         } | ||||
|         long MSB = base.getMostSignificantBits(); | ||||
|         long LSB = base.getLeastSignificantBits(); | ||||
|  | ||||
|         MSB &= 0xFFFFFFFF_FFFF_70FFL; // reset bits we need | ||||
|         MSB |= 0x00000000_0000_8000L; // set version to + 8 the current version | ||||
|  | ||||
|         for ( int i = 1; i <= 9; i++ ) | ||||
|         { | ||||
|             long newMSB = MSB | i << 8; | ||||
|             UUID newUUID = new UUID( newMSB, LSB ); | ||||
|             if ( bungee.getPlayer( newUUID ) != null ) | ||||
|             { | ||||
|                 continue; | ||||
|             } | ||||
|             return newUUID; | ||||
|         } | ||||
|         return base; // there are too many duplicated connections for this player | ||||
|     } | ||||
|  | ||||
|     private static int getDuplicationIndex(UUID duplicatedId) | ||||
|     { | ||||
|         return (int) ( duplicatedId.getMostSignificantBits() >> 8 ) & 0xF; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public int getVersion() | ||||
|     { | ||||
| @@ -732,6 +807,11 @@ public class InitialHandler extends PacketHandler implements PendingConnection | ||||
|         this.uniqueId = uuid; | ||||
|     } | ||||
|  | ||||
|     private void updateOfflineId() | ||||
|     { | ||||
|         offlineId = UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + getName() ).getBytes( Charsets.UTF_8 ) ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String getUUID() | ||||
|     { | ||||
|   | ||||
| @@ -6,7 +6,6 @@ import com.mojang.brigadier.suggestion.Suggestion; | ||||
| import com.mojang.brigadier.suggestion.Suggestions; | ||||
| import io.netty.channel.Channel; | ||||
| import java.util.ArrayList; | ||||
| import java.util.LinkedList; | ||||
| import java.util.List; | ||||
| import java.util.UUID; | ||||
| import net.md_5.bungee.BungeeCord; | ||||
| @@ -20,6 +19,7 @@ import net.md_5.bungee.api.event.PlayerDisconnectEvent; | ||||
| import net.md_5.bungee.api.event.PluginMessageEvent; | ||||
| import net.md_5.bungee.api.event.SettingsChangedEvent; | ||||
| import net.md_5.bungee.api.event.TabCompleteEvent; | ||||
| import net.md_5.bungee.api.event.TabCompleteRequestEvent; | ||||
| import net.md_5.bungee.entitymap.EntityMap; | ||||
| import net.md_5.bungee.forge.ForgeConstants; | ||||
| import net.md_5.bungee.netty.ChannelWrapper; | ||||
| @@ -31,6 +31,7 @@ import net.md_5.bungee.protocol.packet.Chat; | ||||
| 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.FinishConfiguration; | ||||
| import net.md_5.bungee.protocol.packet.KeepAlive; | ||||
| import net.md_5.bungee.protocol.packet.LoginAcknowledged; | ||||
| import net.md_5.bungee.protocol.packet.PlayerListItem; | ||||
| @@ -225,32 +226,42 @@ public class UpstreamBridge extends PacketHandler | ||||
|         TabCompleteEvent tabCompleteEvent = new TabCompleteEvent( con, con.getServer(), tabComplete.getCursor(), suggestions ); | ||||
|         bungee.getPluginManager().callEvent( tabCompleteEvent ); | ||||
|  | ||||
|         if ( tabCompleteEvent.isCancelled() ) | ||||
|         List<String> legacyResults = tabCompleteEvent.getSuggestions(); | ||||
|  | ||||
|         int start = tabComplete.getCursor().lastIndexOf( ' ' ) + 1; | ||||
|         int end = tabComplete.getCursor().length(); | ||||
|         StringRange lastArgumentRange = StringRange.between( start, end ); | ||||
|  | ||||
|         List<Suggestion> brigadier = new ArrayList<>( legacyResults.size() ); | ||||
|         for ( String s : legacyResults ) | ||||
|         { | ||||
|             brigadier.add( new Suggestion( lastArgumentRange, s ) ); | ||||
|         } | ||||
|  | ||||
|         TabCompleteRequestEvent tabCompleteRequestEvent = new TabCompleteRequestEvent( con, con.getServer(), tabComplete.getCursor(), lastArgumentRange, new Suggestions( lastArgumentRange, brigadier ) ); | ||||
|         tabCompleteRequestEvent.setCancelled( tabCompleteEvent.isCancelled() ); | ||||
|         bungee.getPluginManager().callEvent( tabCompleteRequestEvent ); | ||||
|  | ||||
|         if ( tabCompleteRequestEvent.isCancelled() ) | ||||
|         { | ||||
|             throw CancelSendSignal.INSTANCE; | ||||
|         } | ||||
|  | ||||
|         List<String> results = tabCompleteEvent.getSuggestions(); | ||||
|         if ( !results.isEmpty() ) | ||||
|         Suggestions brigadierResults = tabCompleteRequestEvent.getSuggestions(); | ||||
|  | ||||
|         if ( !brigadierResults.isEmpty() ) | ||||
|         { | ||||
|             // Unclear how to handle 1.13 commands at this point. Because we don't inject into the command packets we are unlikely to get this far unless | ||||
|             // Bungee plugins are adding results for commands they don't own anyway | ||||
|             if ( con.getPendingConnection().getVersion() < ProtocolConstants.MINECRAFT_1_13 ) | ||||
|             { | ||||
|                 List<String> results = new ArrayList<>( brigadierResults.getList().size() ); | ||||
|                 for ( Suggestion s : brigadierResults.getList() ) | ||||
|                 { | ||||
|                     results.add( s.getText() ); | ||||
|                 } | ||||
|                 con.unsafe().sendPacket( new TabCompleteResponse( results ) ); | ||||
|             } else | ||||
|             { | ||||
|                 int start = tabComplete.getCursor().lastIndexOf( ' ' ) + 1; | ||||
|                 int end = tabComplete.getCursor().length(); | ||||
|                 StringRange range = StringRange.between( start, end ); | ||||
|  | ||||
|                 List<Suggestion> brigadier = new LinkedList<>(); | ||||
|                 for ( String s : results ) | ||||
|                 { | ||||
|                     brigadier.add( new Suggestion( range, s ) ); | ||||
|                 } | ||||
|  | ||||
|                 con.unsafe().sendPacket( new TabCompleteResponse( tabComplete.getTransactionId(), new Suggestions( range, brigadier ) ) ); | ||||
|                 con.unsafe().sendPacket( new TabCompleteResponse( tabComplete.getTransactionId(), brigadierResults ) ); | ||||
|             } | ||||
|             throw CancelSendSignal.INSTANCE; | ||||
|         } | ||||
| @@ -330,10 +341,21 @@ public class UpstreamBridge extends PacketHandler | ||||
|             ch.setDecodeProtocol( Protocol.CONFIGURATION ); | ||||
|             ch.write( new LoginAcknowledged() ); | ||||
|             ch.setEncodeProtocol( Protocol.CONFIGURATION ); | ||||
|  | ||||
|             con.getServer().sendQueuedPackets(); | ||||
|  | ||||
|             throw CancelSendSignal.INSTANCE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void handle(FinishConfiguration finishConfiguration) throws Exception | ||||
|     { | ||||
|         con.sendQueuedPackets(); | ||||
|  | ||||
|         super.handle( finishConfiguration ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String toString() | ||||
|     { | ||||
|   | ||||
| @@ -1,34 +0,0 @@ | ||||
| package net.md_5.bungee.module; | ||||
|  | ||||
| import com.google.common.io.ByteStreams; | ||||
| import com.google.common.io.Files; | ||||
| import java.io.IOException; | ||||
| import java.net.URL; | ||||
| import java.net.URLConnection; | ||||
| import lombok.Data; | ||||
| import net.md_5.bungee.Util; | ||||
|  | ||||
| @Data | ||||
| public class JenkinsModuleSource implements ModuleSource | ||||
| { | ||||
|  | ||||
|     @Override | ||||
|     public void retrieve(ModuleSpec module, ModuleVersion version) | ||||
|     { | ||||
|         System.out.println( "Attempting to Jenkins download module " + module.getName() + " v" + version.getBuild() ); | ||||
|         try | ||||
|         { | ||||
|             URL website = new URL( "https://ci.md-5.net/job/BungeeCord/" + version.getBuild() + "/artifact/module/" + module.getName().replace( '_', '-' ) + "/target/" + module.getName() + ".jar" ); | ||||
|             URLConnection con = website.openConnection(); | ||||
|             // 15 second timeout at various stages | ||||
|             con.setConnectTimeout( 15000 ); | ||||
|             con.setReadTimeout( 15000 ); | ||||
|  | ||||
|             Files.write( ByteStreams.toByteArray( con.getInputStream() ), module.getFile() ); | ||||
|             System.out.println( "Download complete" ); | ||||
|         } catch ( IOException ex ) | ||||
|         { | ||||
|             System.out.println( "Failed to download: " + Util.exception( ex ) ); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,155 +0,0 @@ | ||||
| package net.md_5.bungee.module; | ||||
|  | ||||
| import com.google.common.base.Preconditions; | ||||
| import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; | ||||
| import java.io.File; | ||||
| import java.io.FileInputStream; | ||||
| import java.io.FileWriter; | ||||
| import java.io.InputStream; | ||||
| import java.net.URI; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collection; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.jar.JarEntry; | ||||
| import java.util.jar.JarFile; | ||||
| import java.util.logging.Level; | ||||
| import net.md_5.bungee.api.ProxyServer; | ||||
| import net.md_5.bungee.api.plugin.PluginDescription; | ||||
| import net.md_5.bungee.util.CaseInsensitiveMap; | ||||
| import org.yaml.snakeyaml.DumperOptions; | ||||
| import org.yaml.snakeyaml.Yaml; | ||||
|  | ||||
| public class ModuleManager | ||||
| { | ||||
|  | ||||
|     private final Map<String, ModuleSource> knownSources = new HashMap<>(); | ||||
|  | ||||
|     public ModuleManager() | ||||
|     { | ||||
|         knownSources.put( "jenkins", new JenkinsModuleSource() ); | ||||
|     } | ||||
|  | ||||
|     // CHECKSTYLE:OFF | ||||
|     @SuppressFBWarnings( | ||||
|             { | ||||
|                 "SF_SWITCH_FALLTHROUGH", "SF_SWITCH_NO_DEFAULT" | ||||
|             }) | ||||
|     // CHECKSTYLE:ON | ||||
|     public void load(ProxyServer proxy, File moduleDirectory) throws Exception | ||||
|     { | ||||
|         moduleDirectory.mkdir(); | ||||
|  | ||||
|         ModuleVersion bungeeVersion = ModuleVersion.parse( proxy.getVersion() ); | ||||
|         if ( bungeeVersion == null ) | ||||
|         { | ||||
|             System.out.println( "Couldn't detect bungee version. Custom build?" ); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         List<ModuleSpec> modules = new ArrayList<>(); | ||||
|         File configFile = new File( "modules.yml" ); | ||||
|         // Start Yaml | ||||
|         DumperOptions options = new DumperOptions(); | ||||
|         options.setDefaultFlowStyle( DumperOptions.FlowStyle.BLOCK ); | ||||
|         Yaml yaml = new Yaml( options ); | ||||
|  | ||||
|         Map<String, Object> config; | ||||
|  | ||||
|         configFile.createNewFile(); | ||||
|         try ( InputStream is = new FileInputStream( configFile ) ) | ||||
|         { | ||||
|             config = (Map) yaml.load( is ); | ||||
|         } | ||||
|  | ||||
|         if ( config == null ) | ||||
|         { | ||||
|             config = new CaseInsensitiveMap<>(); | ||||
|         } else | ||||
|         { | ||||
|             config = new CaseInsensitiveMap<>( config ); | ||||
|         } | ||||
|         // End yaml | ||||
|  | ||||
|         List<String> defaults = new ArrayList<>(); | ||||
|         Object readModules = config.get( "modules" ); | ||||
|         if ( readModules != null ) | ||||
|         { | ||||
|             defaults.addAll( (Collection) readModules ); | ||||
|         } | ||||
|         int version = ( config.containsKey( "version" ) ) ? (int) config.get( "version" ) : 0; | ||||
|         switch ( version ) | ||||
|         { | ||||
|             case 0: | ||||
|                 defaults.add( "jenkins://cmd_alert" ); | ||||
|                 defaults.add( "jenkins://cmd_find" ); | ||||
|                 defaults.add( "jenkins://cmd_list" ); | ||||
|                 defaults.add( "jenkins://cmd_send" ); | ||||
|                 defaults.add( "jenkins://cmd_server" ); | ||||
|             case 1: | ||||
|                 defaults.add( "jenkins://reconnect_yaml" ); | ||||
|         } | ||||
|         config.put( "modules", defaults ); | ||||
|         config.put( "version", 2 ); | ||||
|  | ||||
|         try ( FileWriter wr = new FileWriter( configFile ) ) | ||||
|         { | ||||
|             yaml.dump( config, wr ); | ||||
|         } | ||||
|  | ||||
|         for ( String s : (List<String>) config.get( "modules" ) ) | ||||
|         { | ||||
|             URI uri = new URI( s ); | ||||
|  | ||||
|             ModuleSource source = knownSources.get( uri.getScheme() ); | ||||
|             if ( source == null ) | ||||
|             { | ||||
|                 System.out.println( "Unknown module source: " + s ); | ||||
|                 continue; | ||||
|             } | ||||
|             String name = uri.getAuthority(); | ||||
|             if ( name == null ) | ||||
|             { | ||||
|                 System.out.println( "Unknown module host: " + s ); | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             ModuleSpec spec = new ModuleSpec( name, new File( moduleDirectory, name + ".jar" ), source ); | ||||
|             modules.add( spec ); | ||||
|             System.out.println( "Discovered module: " + spec ); | ||||
|         } | ||||
|  | ||||
|         for ( ModuleSpec module : modules ) | ||||
|         { | ||||
|             ModuleVersion moduleVersion = ( module.getFile().exists() ) ? getVersion( module.getFile() ) : null; | ||||
|  | ||||
|             if ( !bungeeVersion.equals( moduleVersion ) ) | ||||
|             { | ||||
|                 System.out.println( "Attempting to update plugin from " + moduleVersion + " to " + bungeeVersion ); | ||||
|                 module.getProvider().retrieve( module, bungeeVersion ); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @SuppressFBWarnings("REC_CATCH_EXCEPTION") | ||||
|     private ModuleVersion getVersion(File file) | ||||
|     { | ||||
|         try ( JarFile jar = new JarFile( file ) ) | ||||
|         { | ||||
|             JarEntry pdf = jar.getJarEntry( "plugin.yml" ); | ||||
|             Preconditions.checkNotNull( pdf, "Plugin must have a plugin.yml" ); | ||||
|  | ||||
|             try ( InputStream in = jar.getInputStream( pdf ) ) | ||||
|             { | ||||
|                 PluginDescription desc = new Yaml().loadAs( in, PluginDescription.class ); | ||||
|                 return ModuleVersion.parse( desc.getVersion() ); | ||||
|             } | ||||
|         } catch ( Exception ex ) | ||||
|         { | ||||
|             ProxyServer.getInstance().getLogger().log( Level.WARNING, "Could not check module from file " + file, ex ); | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
| @@ -1,7 +0,0 @@ | ||||
| package net.md_5.bungee.module; | ||||
|  | ||||
| interface ModuleSource | ||||
| { | ||||
|  | ||||
|     void retrieve(ModuleSpec module, ModuleVersion version); | ||||
| } | ||||
| @@ -1,13 +0,0 @@ | ||||
| package net.md_5.bungee.module; | ||||
|  | ||||
| import java.io.File; | ||||
| import lombok.Data; | ||||
|  | ||||
| @Data | ||||
| public class ModuleSpec | ||||
| { | ||||
|  | ||||
|     private final String name; | ||||
|     private final File file; | ||||
|     private final ModuleSource provider; | ||||
| } | ||||
| @@ -1,35 +0,0 @@ | ||||
| package net.md_5.bungee.module; | ||||
|  | ||||
| import lombok.AccessLevel; | ||||
| import lombok.Data; | ||||
| import lombok.RequiredArgsConstructor; | ||||
|  | ||||
| @Data | ||||
| @RequiredArgsConstructor(access = AccessLevel.PRIVATE) | ||||
| public class ModuleVersion | ||||
| { | ||||
|  | ||||
|     private final String build; | ||||
|     private final String git; | ||||
|  | ||||
|     public static ModuleVersion parse(String version) | ||||
|     { | ||||
|         int lastColon = version.lastIndexOf( ':' ); | ||||
|         int secondLastColon = version.lastIndexOf( ':', lastColon - 1 ); | ||||
|  | ||||
|         if ( lastColon == -1 || secondLastColon == -1 ) | ||||
|         { | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         String buildNumber = version.substring( lastColon + 1, version.length() ); | ||||
|         String gitCommit = version.substring( secondLastColon + 1, lastColon ).replaceAll( "\"", "" ); | ||||
|  | ||||
|         if ( "unknown".equals( buildNumber ) || "unknown".equals( gitCommit ) ) | ||||
|         { | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         return new ModuleVersion( buildNumber, gitCommit ); | ||||
|     } | ||||
| } | ||||
| @@ -69,6 +69,11 @@ public class ChannelWrapper | ||||
|         ch.pipeline().get( MinecraftEncoder.class ).setProtocolVersion( protocol ); | ||||
|     } | ||||
|  | ||||
|     public int getEncodeVersion() | ||||
|     { | ||||
|         return ch.pipeline().get( MinecraftEncoder.class ).getProtocolVersion(); | ||||
|     } | ||||
|  | ||||
|     public void write(Object packet) | ||||
|     { | ||||
|         if ( !closed ) | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| package net.md_5.bungee; | ||||
|  | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
| import com.google.common.base.Ticker; | ||||
| import java.net.InetAddress; | ||||
| import java.net.InetSocketAddress; | ||||
| import java.net.UnknownHostException; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| import org.junit.Assert; | ||||
| import org.junit.Test; | ||||
| import org.junit.jupiter.api.Test; | ||||
|  | ||||
| public class ThrottleTest | ||||
| { | ||||
| @@ -38,18 +38,18 @@ public class ThrottleTest | ||||
|             address = new InetSocketAddress( InetAddress.getByName( null ), 0 ); | ||||
|         } | ||||
|  | ||||
|         Assert.assertFalse( "Address should not be throttled", throttle.throttle( address ) ); // 1 | ||||
|         Assert.assertFalse( "Address should not be throttled", throttle.throttle( address ) ); // 2 | ||||
|         Assert.assertFalse( "Address should not be throttled", throttle.throttle( address ) ); // 3 | ||||
|         Assert.assertTrue( "Address should be throttled", throttle.throttle( address ) ); // The 3rd one must be throttled, but also increased the count to 4 | ||||
|         assertFalse( throttle.throttle( address ), "Address should not be throttled" ); // 1 | ||||
|         assertFalse( throttle.throttle( address ), "Address should not be throttled" ); // 2 | ||||
|         assertFalse( throttle.throttle( address ), "Address should not be throttled" ); // 3 | ||||
|         assertTrue( throttle.throttle( address ), "Address should be throttled" ); // The 3rd one must be throttled, but also increased the count to 4 | ||||
|  | ||||
|         throttle.unthrottle( address ); // We are back at 3, next attempt will make it 4 and throttle | ||||
|         throttle.unthrottle( address ); // Now we are at 2, will not be throttled | ||||
|         Assert.assertFalse( "Address should not be throttled", throttle.throttle( address ) ); // 3 | ||||
|         Assert.assertTrue( "Address should be throttled", throttle.throttle( address ) ); // 4 | ||||
|         assertFalse( throttle.throttle( address ), "Address should not be throttled" ); // 3 | ||||
|         assertTrue( throttle.throttle( address ), "Address should be throttled" ); // 4 | ||||
|  | ||||
|         // Now test expiration | ||||
|         ticker.value += TimeUnit.MILLISECONDS.toNanos( 50 ); | ||||
|         Assert.assertFalse( "Address should not be throttled", throttle.throttle( address ) ); | ||||
|         assertFalse( throttle.throttle( address ), "Address should not be throttled" ); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,13 +1,13 @@ | ||||
| package net.md_5.bungee.scheduler; | ||||
|  | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
| import java.util.concurrent.CountDownLatch; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| import java.util.concurrent.atomic.AtomicBoolean; | ||||
| import net.md_5.bungee.api.plugin.DummyPlugin; | ||||
| import net.md_5.bungee.api.scheduler.ScheduledTask; | ||||
| import net.md_5.bungee.api.scheduler.TaskScheduler; | ||||
| import org.junit.Assert; | ||||
| import org.junit.Test; | ||||
| import org.junit.jupiter.api.Test; | ||||
|  | ||||
| public class SchedulerTest | ||||
| { | ||||
| @@ -31,7 +31,7 @@ public class SchedulerTest | ||||
|  | ||||
|         latch.await( 5, TimeUnit.SECONDS ); | ||||
|  | ||||
|         Assert.assertEquals( 0, latch.getCount() ); | ||||
|         assertEquals( 0, latch.getCount() ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -43,17 +43,17 @@ public class SchedulerTest | ||||
|         ScheduledTask task = setup( scheduler, b ); | ||||
|         scheduler.cancel( task.getId() ); | ||||
|         Thread.sleep( 250 ); | ||||
|         Assert.assertFalse( b.get() ); | ||||
|         assertFalse( b.get() ); | ||||
|  | ||||
|         task = setup( scheduler, b ); | ||||
|         scheduler.cancel( task ); | ||||
|         Thread.sleep( 250 ); | ||||
|         Assert.assertFalse( b.get() ); | ||||
|         assertFalse( b.get() ); | ||||
|  | ||||
|         task = setup( scheduler, b ); | ||||
|         scheduler.cancel( task.getOwner() ); | ||||
|         Thread.sleep( 250 ); | ||||
|         Assert.assertFalse( b.get() ); | ||||
|         assertFalse( b.get() ); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
| @@ -64,11 +64,11 @@ public class SchedulerTest | ||||
|  | ||||
|         setup( scheduler, b ); | ||||
|         Thread.sleep( 250 ); | ||||
|         Assert.assertTrue( b.get() ); | ||||
|         assertTrue( b.get() ); | ||||
|  | ||||
|         b.set( false ); | ||||
|         Thread.sleep( 250 ); | ||||
|         Assert.assertTrue( b.get() ); | ||||
|         assertTrue( b.get() ); | ||||
|     } | ||||
|  | ||||
|     private ScheduledTask setup(TaskScheduler scheduler, final AtomicBoolean hasRun) | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| package net.md_5.bungee.util; | ||||
|  | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
| import java.net.InetSocketAddress; | ||||
| import org.junit.Assert; | ||||
| import org.junit.Test; | ||||
| import org.junit.jupiter.api.Test; | ||||
|  | ||||
| public class AddressUtilTest | ||||
| { | ||||
| @@ -11,9 +11,9 @@ public class AddressUtilTest | ||||
|     public void testScope() | ||||
|     { | ||||
|         InetSocketAddress addr = new InetSocketAddress( "0:0:0:0:0:0:0:1%0", 25577 ); | ||||
|         Assert.assertEquals( "0:0:0:0:0:0:0:1", AddressUtil.sanitizeAddress( addr ) ); | ||||
|         assertEquals( "0:0:0:0:0:0:0:1", AddressUtil.sanitizeAddress( addr ) ); | ||||
|  | ||||
|         InetSocketAddress addr2 = new InetSocketAddress( "0:0:0:0:0:0:0:1", 25577 ); | ||||
|         Assert.assertEquals( "0:0:0:0:0:0:0:1", AddressUtil.sanitizeAddress( addr2 ) ); | ||||
|         assertEquals( "0:0:0:0:0:0:0:1", AddressUtil.sanitizeAddress( addr2 ) ); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -4,13 +4,12 @@ | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|  | ||||
|     <parent> | ||||
|         <groupId>net.md-5</groupId> | ||||
|         <groupId>fr.pandacube.bungeecord</groupId> | ||||
|         <artifactId>bungeecord-parent</artifactId> | ||||
|         <version>1.20-R0.2-SNAPSHOT</version> | ||||
|         <relativePath>../pom.xml</relativePath> | ||||
|     </parent> | ||||
|  | ||||
|     <groupId>net.md-5</groupId> | ||||
|     <artifactId>bungeecord-query</artifactId> | ||||
|     <version>1.20-R0.2-SNAPSHOT</version> | ||||
|     <packaging>jar</packaging> | ||||
| @@ -25,7 +24,7 @@ | ||||
|             <scope>compile</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>net.md-5</groupId> | ||||
|             <groupId>fr.pandacube.bungeecord</groupId> | ||||
|             <artifactId>bungeecord-api</artifactId> | ||||
|             <version>${project.version}</version> | ||||
|             <scope>compile</scope> | ||||
|   | ||||
| @@ -4,13 +4,12 @@ | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|  | ||||
|     <parent> | ||||
|         <groupId>net.md-5</groupId> | ||||
|         <groupId>fr.pandacube.bungeecord</groupId> | ||||
|         <artifactId>bungeecord-parent</artifactId> | ||||
|         <version>1.20-R0.2-SNAPSHOT</version> | ||||
|         <relativePath>../pom.xml</relativePath> | ||||
|     </parent> | ||||
|  | ||||
|     <groupId>net.md-5</groupId> | ||||
|     <artifactId>bungeecord-slf4j</artifactId> | ||||
|     <version>1.20-R0.2-SNAPSHOT</version> | ||||
|     <packaging>jar</packaging> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user