Compare commits
34 Commits
adaebb32f5
...
6bb83c4e61
Author | SHA1 | Date | |
---|---|---|---|
6bb83c4e61 | |||
e28802d3ff | |||
754798b372 | |||
0bc21968d9 | |||
e41691bd57 | |||
c237bd3895 | |||
|
3e9a7e45c4 | ||
|
f6c5332c1a | ||
|
d0fa62d424 | ||
|
464ed0184c | ||
|
eda268b481 | ||
|
3e1007527c | ||
|
b52b14696c | ||
|
94d5b0d03c | ||
|
c3f228f626 | ||
|
02c5c1ee76 | ||
|
c69acf728c | ||
|
a1cd694363 | ||
|
3e2bc8e2d7 | ||
|
ad7163d2d6 | ||
|
19918c694f | ||
|
21c8f2815a | ||
|
737d545fb6 | ||
|
b23a51825e | ||
|
708c5b6254 | ||
|
f5af11193c | ||
|
b711e4033f | ||
|
3deaaadc3a | ||
|
51b9a6b0b8 | ||
|
1a807731a5 | ||
|
772ad9951f | ||
|
2431c40a5c | ||
|
8144ae8d7b | ||
|
0757c39a6f |
3
.github/dependabot.yml
vendored
3
.github/dependabot.yml
vendored
@ -13,10 +13,9 @@ updates:
|
|||||||
- dependency-name: "com.puppycrawl.tools:checkstyle"
|
- dependency-name: "com.puppycrawl.tools:checkstyle"
|
||||||
# Newer versions have issues, see #1909 and #2050
|
# Newer versions have issues, see #1909 and #2050
|
||||||
- dependency-name: "jline:jline"
|
- dependency-name: "jline:jline"
|
||||||
# Later versions of these Maven dependencies are incompatible and require careful management - see SPIGOT-7400
|
# Needs to be synchronised with maven-resolver-provider dependencies
|
||||||
- dependency-name: "org.apache.maven.resolver:maven-resolver-connector-basic"
|
- dependency-name: "org.apache.maven.resolver:maven-resolver-connector-basic"
|
||||||
- dependency-name: "org.apache.maven.resolver:maven-resolver-transport-http"
|
- dependency-name: "org.apache.maven.resolver:maven-resolver-transport-http"
|
||||||
- dependency-name: "org.apache.maven:maven-resolver-provider"
|
|
||||||
# Used with maven-resolver dependencies; 2.0 update breaks other providers
|
# Used with maven-resolver dependencies; 2.0 update breaks other providers
|
||||||
- dependency-name: "org.slf4j:slf4j-api"
|
- dependency-name: "org.slf4j:slf4j-api"
|
||||||
update-types: ["version-update:semver-major"]
|
update-types: ["version-update:semver-major"]
|
||||||
|
2
.github/workflows/maven.yml
vendored
2
.github/workflows/maven.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-java@v3
|
- uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: zulu
|
distribution: zulu
|
||||||
java-version: ${{ matrix.java }}
|
java-version: ${{ matrix.java }}
|
||||||
|
21
api/pom.xml
21
api/pom.xml
@ -4,15 +4,14 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-api</artifactId>
|
<artifactId>bungeecord-api</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-API</name>
|
<name>BungeeCord-API</name>
|
||||||
@ -20,25 +19,25 @@
|
|||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-chat</artifactId>
|
<artifactId>bungeecord-chat</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-config</artifactId>
|
<artifactId>bungeecord-config</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-event</artifactId>
|
<artifactId>bungeecord-event</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-protocol</artifactId>
|
<artifactId>bungeecord-protocol</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
@ -51,21 +50,21 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.maven</groupId>
|
<groupId>org.apache.maven</groupId>
|
||||||
<artifactId>maven-resolver-provider</artifactId>
|
<artifactId>maven-resolver-provider</artifactId>
|
||||||
<version>3.8.5</version>
|
<version>3.9.6</version>
|
||||||
<!-- not part of the API proper -->
|
<!-- not part of the API proper -->
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.maven.resolver</groupId>
|
<groupId>org.apache.maven.resolver</groupId>
|
||||||
<artifactId>maven-resolver-connector-basic</artifactId>
|
<artifactId>maven-resolver-connector-basic</artifactId>
|
||||||
<version>1.7.3</version>
|
<version>1.9.18</version>
|
||||||
<!-- not part of the API proper -->
|
<!-- not part of the API proper -->
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.maven.resolver</groupId>
|
<groupId>org.apache.maven.resolver</groupId>
|
||||||
<artifactId>maven-resolver-transport-http</artifactId>
|
<artifactId>maven-resolver-transport-http</artifactId>
|
||||||
<version>1.7.3</version>
|
<version>1.9.18</version>
|
||||||
<!-- not part of the API proper -->
|
<!-- not part of the API proper -->
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
@ -2,7 +2,9 @@ package net.md_5.bungee.api.connection;
|
|||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import net.md_5.bungee.api.config.ListenerInfo;
|
import net.md_5.bungee.api.config.ListenerInfo;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a user attempting to log into the proxy.
|
* Represents a user attempting to log into the proxy.
|
||||||
@ -89,4 +91,26 @@ public interface PendingConnection extends Connection
|
|||||||
* @return Whether the client is using a legacy client.
|
* @return Whether the client is using a legacy client.
|
||||||
*/
|
*/
|
||||||
boolean isLegacy();
|
boolean isLegacy();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets if this connection has been transferred from another server.
|
||||||
|
*
|
||||||
|
* @return true if the connection has been transferred
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
boolean isTransferred();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a cookie from this pending connection.
|
||||||
|
*
|
||||||
|
* @param cookie the resource location of the cookie, for example
|
||||||
|
* "bungeecord:my_cookie"
|
||||||
|
* @return a {@link CompletableFuture} that will be completed when the
|
||||||
|
* Cookie response is received. If the cookie is not set in the client, the
|
||||||
|
* {@link CompletableFuture} will complete with a null value
|
||||||
|
* @throws IllegalStateException if the player's version is not at least
|
||||||
|
* 1.20.5
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
CompletableFuture<byte[]> retrieveCookie(String cookie);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package net.md_5.bungee.api.connection;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import net.md_5.bungee.api.Callback;
|
import net.md_5.bungee.api.Callback;
|
||||||
import net.md_5.bungee.api.ChatMessageType;
|
import net.md_5.bungee.api.ChatMessageType;
|
||||||
import net.md_5.bungee.api.CommandSender;
|
import net.md_5.bungee.api.CommandSender;
|
||||||
@ -13,6 +14,7 @@ import net.md_5.bungee.api.chat.BaseComponent;
|
|||||||
import net.md_5.bungee.api.config.ServerInfo;
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
import net.md_5.bungee.api.event.ServerConnectEvent;
|
import net.md_5.bungee.api.event.ServerConnectEvent;
|
||||||
import net.md_5.bungee.api.score.Scoreboard;
|
import net.md_5.bungee.api.score.Scoreboard;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a player whose connection is being connected to somewhere else,
|
* Represents a player whose connection is being connected to somewhere else,
|
||||||
@ -339,4 +341,45 @@ public interface ProxiedPlayer extends Connection, CommandSender
|
|||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
Scoreboard getScoreboard();
|
Scoreboard getScoreboard();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a cookie from this player.
|
||||||
|
*
|
||||||
|
* @param cookie the resource location of the cookie, for example
|
||||||
|
* "bungeecord:my_cookie"
|
||||||
|
* @return a {@link CompletableFuture} that will be completed when the
|
||||||
|
* Cookie response is received. If the cookie is not set in the client, the
|
||||||
|
* {@link CompletableFuture} will complete with a null value
|
||||||
|
* @throws IllegalStateException if the player's version is not at least
|
||||||
|
* 1.20.5
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
CompletableFuture<byte[]> retrieveCookie(String cookie);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores a cookie in this player's client.
|
||||||
|
*
|
||||||
|
* @param cookie the resource location of the cookie, for example
|
||||||
|
* "bungeecord:my_cookie"
|
||||||
|
* @param data the data to store in the cookie
|
||||||
|
* @throws IllegalStateException if the player's version is not at least
|
||||||
|
* 1.20.5
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
void storeCookie(String cookie, byte[] data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests this player to connect to a different server specified by host
|
||||||
|
* and port.
|
||||||
|
*
|
||||||
|
* This is a client-side transfer - host and port should not specify a
|
||||||
|
* BungeeCord backend server.
|
||||||
|
*
|
||||||
|
* @param host the host of the server to transfer to
|
||||||
|
* @param port the port of the server to transfer to
|
||||||
|
* @throws IllegalStateException if the players version is not at least
|
||||||
|
* 1.20.5
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
void transfer(String host, int port);
|
||||||
}
|
}
|
||||||
|
@ -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.
|
* Event called when a player uses tab completion.
|
||||||
|
* @deprecated please use {@link TabCompleteRequestEvent} to support 1.13+ suggestions.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@Data
|
@Data
|
||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
@EqualsAndHashCode(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;
|
||||||
|
}
|
||||||
|
}
|
@ -4,15 +4,14 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-bootstrap</artifactId>
|
<artifactId>bungeecord-bootstrap</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-Bootstrap</name>
|
<name>BungeeCord-Bootstrap</name>
|
||||||
@ -21,14 +20,12 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<maven.deploy.skip>true</maven.deploy.skip>
|
<maven.deploy.skip>true</maven.deploy.skip>
|
||||||
<maven.javadoc.skip>true</maven.javadoc.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>
|
<maven.build.timestamp.format>yyyyMMdd</maven.build.timestamp.format>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-proxy</artifactId>
|
<artifactId>bungeecord-proxy</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
|
@ -4,15 +4,14 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-chat</artifactId>
|
<artifactId>bungeecord-chat</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-Chat</name>
|
<name>BungeeCord-Chat</name>
|
||||||
|
@ -20,38 +20,10 @@ public abstract class BaseComponent
|
|||||||
BaseComponent parent;
|
BaseComponent parent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The color of this component and any child components (unless overridden)
|
* The component's style.
|
||||||
*/
|
*/
|
||||||
private ChatColor color;
|
@Getter
|
||||||
/**
|
private ComponentStyle style = new ComponentStyle();
|
||||||
* The font of this component and any child components (unless overridden)
|
|
||||||
*/
|
|
||||||
private String font;
|
|
||||||
/**
|
|
||||||
* Whether this component and any child components (unless overridden) is
|
|
||||||
* bold
|
|
||||||
*/
|
|
||||||
private Boolean bold;
|
|
||||||
/**
|
|
||||||
* Whether this component and any child components (unless overridden) is
|
|
||||||
* italic
|
|
||||||
*/
|
|
||||||
private Boolean italic;
|
|
||||||
/**
|
|
||||||
* Whether this component and any child components (unless overridden) is
|
|
||||||
* underlined
|
|
||||||
*/
|
|
||||||
private Boolean underlined;
|
|
||||||
/**
|
|
||||||
* Whether this component and any child components (unless overridden) is
|
|
||||||
* strikethrough
|
|
||||||
*/
|
|
||||||
private Boolean strikethrough;
|
|
||||||
/**
|
|
||||||
* Whether this component and any child components (unless overridden) is
|
|
||||||
* obfuscated
|
|
||||||
*/
|
|
||||||
private Boolean obfuscated;
|
|
||||||
/**
|
/**
|
||||||
* The text to insert into the chat when this component (and child
|
* The text to insert into the chat when this component (and child
|
||||||
* components) are clicked while pressing the shift key
|
* components) are clicked while pressing the shift key
|
||||||
@ -153,31 +125,31 @@ public abstract class BaseComponent
|
|||||||
}
|
}
|
||||||
if ( retention == FormatRetention.FORMATTING || retention == FormatRetention.ALL )
|
if ( retention == FormatRetention.FORMATTING || retention == FormatRetention.ALL )
|
||||||
{
|
{
|
||||||
if ( replace || color == null )
|
if ( replace || !style.hasColor() )
|
||||||
{
|
{
|
||||||
setColor( component.getColorRaw() );
|
setColor( component.getColorRaw() );
|
||||||
}
|
}
|
||||||
if ( replace || font == null )
|
if ( replace || !style.hasFont() )
|
||||||
{
|
{
|
||||||
setFont( component.getFontRaw() );
|
setFont( component.getFontRaw() );
|
||||||
}
|
}
|
||||||
if ( replace || bold == null )
|
if ( replace || style.isBoldRaw() == null )
|
||||||
{
|
{
|
||||||
setBold( component.isBoldRaw() );
|
setBold( component.isBoldRaw() );
|
||||||
}
|
}
|
||||||
if ( replace || italic == null )
|
if ( replace || style.isItalicRaw() == null )
|
||||||
{
|
{
|
||||||
setItalic( component.isItalicRaw() );
|
setItalic( component.isItalicRaw() );
|
||||||
}
|
}
|
||||||
if ( replace || underlined == null )
|
if ( replace || style.isUnderlinedRaw() == null )
|
||||||
{
|
{
|
||||||
setUnderlined( component.isUnderlinedRaw() );
|
setUnderlined( component.isUnderlinedRaw() );
|
||||||
}
|
}
|
||||||
if ( replace || strikethrough == null )
|
if ( replace || style.isStrikethroughRaw() == null )
|
||||||
{
|
{
|
||||||
setStrikethrough( component.isStrikethroughRaw() );
|
setStrikethrough( component.isStrikethroughRaw() );
|
||||||
}
|
}
|
||||||
if ( replace || obfuscated == null )
|
if ( replace || style.isObfuscatedRaw() == null )
|
||||||
{
|
{
|
||||||
setObfuscated( component.isObfuscatedRaw() );
|
setObfuscated( component.isObfuscatedRaw() );
|
||||||
}
|
}
|
||||||
@ -266,6 +238,29 @@ public abstract class BaseComponent
|
|||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the {@link ComponentStyle} for this component.
|
||||||
|
* <p>
|
||||||
|
* Unlike {@link #applyStyle(ComponentStyle)}, this method will overwrite
|
||||||
|
* all style values on this component.
|
||||||
|
*
|
||||||
|
* @param style the style to set, or null to set all style values to default
|
||||||
|
*/
|
||||||
|
public void setStyle(ComponentStyle style)
|
||||||
|
{
|
||||||
|
this.style = ( style != null ) ? style.clone() : new ComponentStyle();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this component's color.
|
||||||
|
*
|
||||||
|
* @param color the component color, or null to use the default
|
||||||
|
*/
|
||||||
|
public void setColor(ChatColor color)
|
||||||
|
{
|
||||||
|
this.style.setColor( color );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the color of this component. This uses the parent's color if this
|
* Returns the color of this component. This uses the parent's color if this
|
||||||
* component doesn't have one. {@link net.md_5.bungee.api.ChatColor#WHITE}
|
* component doesn't have one. {@link net.md_5.bungee.api.ChatColor#WHITE}
|
||||||
@ -275,7 +270,7 @@ public abstract class BaseComponent
|
|||||||
*/
|
*/
|
||||||
public ChatColor getColor()
|
public ChatColor getColor()
|
||||||
{
|
{
|
||||||
if ( color == null )
|
if ( !style.hasColor() )
|
||||||
{
|
{
|
||||||
if ( parent == null )
|
if ( parent == null )
|
||||||
{
|
{
|
||||||
@ -283,7 +278,7 @@ public abstract class BaseComponent
|
|||||||
}
|
}
|
||||||
return parent.getColor();
|
return parent.getColor();
|
||||||
}
|
}
|
||||||
return color;
|
return style.getColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -294,7 +289,17 @@ public abstract class BaseComponent
|
|||||||
*/
|
*/
|
||||||
public ChatColor getColorRaw()
|
public ChatColor getColorRaw()
|
||||||
{
|
{
|
||||||
return color;
|
return style.getColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this component's font.
|
||||||
|
*
|
||||||
|
* @param font the font to set, or null to use the default
|
||||||
|
*/
|
||||||
|
public void setFont(String font)
|
||||||
|
{
|
||||||
|
this.style.setFont( font );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -305,7 +310,7 @@ public abstract class BaseComponent
|
|||||||
*/
|
*/
|
||||||
public String getFont()
|
public String getFont()
|
||||||
{
|
{
|
||||||
if ( font == null )
|
if ( !style.hasFont() )
|
||||||
{
|
{
|
||||||
if ( parent == null )
|
if ( parent == null )
|
||||||
{
|
{
|
||||||
@ -313,7 +318,7 @@ public abstract class BaseComponent
|
|||||||
}
|
}
|
||||||
return parent.getFont();
|
return parent.getFont();
|
||||||
}
|
}
|
||||||
return font;
|
return style.getFont();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -324,7 +329,17 @@ public abstract class BaseComponent
|
|||||||
*/
|
*/
|
||||||
public String getFontRaw()
|
public String getFontRaw()
|
||||||
{
|
{
|
||||||
return font;
|
return style.getFont();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether or not this component is bold.
|
||||||
|
*
|
||||||
|
* @param bold the new bold state, or null to use the default
|
||||||
|
*/
|
||||||
|
public void setBold(Boolean bold)
|
||||||
|
{
|
||||||
|
this.style.setBold( bold );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -336,11 +351,11 @@ public abstract class BaseComponent
|
|||||||
*/
|
*/
|
||||||
public boolean isBold()
|
public boolean isBold()
|
||||||
{
|
{
|
||||||
if ( bold == null )
|
if ( style.isBoldRaw() == null )
|
||||||
{
|
{
|
||||||
return parent != null && parent.isBold();
|
return parent != null && parent.isBold();
|
||||||
}
|
}
|
||||||
return bold;
|
return style.isBold();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -351,7 +366,17 @@ public abstract class BaseComponent
|
|||||||
*/
|
*/
|
||||||
public Boolean isBoldRaw()
|
public Boolean isBoldRaw()
|
||||||
{
|
{
|
||||||
return bold;
|
return style.isBoldRaw();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether or not this component is italic.
|
||||||
|
*
|
||||||
|
* @param italic the new italic state, or null to use the default
|
||||||
|
*/
|
||||||
|
public void setItalic(Boolean italic)
|
||||||
|
{
|
||||||
|
this.style.setItalic( italic );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -363,11 +388,11 @@ public abstract class BaseComponent
|
|||||||
*/
|
*/
|
||||||
public boolean isItalic()
|
public boolean isItalic()
|
||||||
{
|
{
|
||||||
if ( italic == null )
|
if ( style.isItalicRaw() == null )
|
||||||
{
|
{
|
||||||
return parent != null && parent.isItalic();
|
return parent != null && parent.isItalic();
|
||||||
}
|
}
|
||||||
return italic;
|
return style.isItalic();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -378,7 +403,17 @@ public abstract class BaseComponent
|
|||||||
*/
|
*/
|
||||||
public Boolean isItalicRaw()
|
public Boolean isItalicRaw()
|
||||||
{
|
{
|
||||||
return italic;
|
return style.isItalicRaw();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether or not this component is underlined.
|
||||||
|
*
|
||||||
|
* @param underlined the new underlined state, or null to use the default
|
||||||
|
*/
|
||||||
|
public void setUnderlined(Boolean underlined)
|
||||||
|
{
|
||||||
|
this.style.setUnderlined( underlined );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -390,11 +425,11 @@ public abstract class BaseComponent
|
|||||||
*/
|
*/
|
||||||
public boolean isUnderlined()
|
public boolean isUnderlined()
|
||||||
{
|
{
|
||||||
if ( underlined == null )
|
if ( style.isUnderlinedRaw() == null )
|
||||||
{
|
{
|
||||||
return parent != null && parent.isUnderlined();
|
return parent != null && parent.isUnderlined();
|
||||||
}
|
}
|
||||||
return underlined;
|
return style.isUnderlined();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -405,7 +440,18 @@ public abstract class BaseComponent
|
|||||||
*/
|
*/
|
||||||
public Boolean isUnderlinedRaw()
|
public Boolean isUnderlinedRaw()
|
||||||
{
|
{
|
||||||
return underlined;
|
return style.isUnderlinedRaw();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether or not this component is strikethrough.
|
||||||
|
*
|
||||||
|
* @param strikethrough the new strikethrough state, or null to use the
|
||||||
|
* default
|
||||||
|
*/
|
||||||
|
public void setStrikethrough(Boolean strikethrough)
|
||||||
|
{
|
||||||
|
this.style.setStrikethrough( strikethrough );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -417,11 +463,11 @@ public abstract class BaseComponent
|
|||||||
*/
|
*/
|
||||||
public boolean isStrikethrough()
|
public boolean isStrikethrough()
|
||||||
{
|
{
|
||||||
if ( strikethrough == null )
|
if ( style.isStrikethroughRaw() == null )
|
||||||
{
|
{
|
||||||
return parent != null && parent.isStrikethrough();
|
return parent != null && parent.isStrikethrough();
|
||||||
}
|
}
|
||||||
return strikethrough;
|
return style.isStrikethrough();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -432,7 +478,17 @@ public abstract class BaseComponent
|
|||||||
*/
|
*/
|
||||||
public Boolean isStrikethroughRaw()
|
public Boolean isStrikethroughRaw()
|
||||||
{
|
{
|
||||||
return strikethrough;
|
return style.isStrikethroughRaw();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether or not this component is obfuscated.
|
||||||
|
*
|
||||||
|
* @param obfuscated the new obfuscated state, or null to use the default
|
||||||
|
*/
|
||||||
|
public void setObfuscated(Boolean obfuscated)
|
||||||
|
{
|
||||||
|
this.style.setObfuscated( obfuscated );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -444,11 +500,11 @@ public abstract class BaseComponent
|
|||||||
*/
|
*/
|
||||||
public boolean isObfuscated()
|
public boolean isObfuscated()
|
||||||
{
|
{
|
||||||
if ( obfuscated == null )
|
if ( style.isObfuscatedRaw() == null )
|
||||||
{
|
{
|
||||||
return parent != null && parent.isObfuscated();
|
return parent != null && parent.isObfuscated();
|
||||||
}
|
}
|
||||||
return obfuscated;
|
return style.isObfuscated();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -459,7 +515,48 @@ public abstract class BaseComponent
|
|||||||
*/
|
*/
|
||||||
public Boolean isObfuscatedRaw()
|
public Boolean isObfuscatedRaw()
|
||||||
{
|
{
|
||||||
return obfuscated;
|
return style.isObfuscatedRaw();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the style from the given {@link ComponentStyle} to this component.
|
||||||
|
* <p>
|
||||||
|
* Any style values that have been explicitly set in the style will be
|
||||||
|
* applied to this component. If a value is not set in the style, it will
|
||||||
|
* not override the style set in this component.
|
||||||
|
*
|
||||||
|
* @param style the style to apply
|
||||||
|
*/
|
||||||
|
public void applyStyle(ComponentStyle style)
|
||||||
|
{
|
||||||
|
if ( style.hasColor() )
|
||||||
|
{
|
||||||
|
setColor( style.getColor() );
|
||||||
|
}
|
||||||
|
if ( style.hasFont() )
|
||||||
|
{
|
||||||
|
setFont( style.getFont() );
|
||||||
|
}
|
||||||
|
if ( style.isBoldRaw() != null )
|
||||||
|
{
|
||||||
|
setBold( style.isBoldRaw() );
|
||||||
|
}
|
||||||
|
if ( style.isItalicRaw() != null )
|
||||||
|
{
|
||||||
|
setItalic( style.isItalicRaw() );
|
||||||
|
}
|
||||||
|
if ( style.isUnderlinedRaw() != null )
|
||||||
|
{
|
||||||
|
setUnderlined( style.isUnderlinedRaw() );
|
||||||
|
}
|
||||||
|
if ( style.isStrikethroughRaw() != null )
|
||||||
|
{
|
||||||
|
setStrikethrough( style.isStrikethroughRaw() );
|
||||||
|
}
|
||||||
|
if ( style.isObfuscatedRaw() != null )
|
||||||
|
{
|
||||||
|
setObfuscated( style.isObfuscatedRaw() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setExtra(List<BaseComponent> components)
|
public void setExtra(List<BaseComponent> components)
|
||||||
@ -498,6 +595,16 @@ public abstract class BaseComponent
|
|||||||
extra.add( component );
|
extra.add( component );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the component has any styling applied to it.
|
||||||
|
*
|
||||||
|
* @return Whether any styling is applied
|
||||||
|
*/
|
||||||
|
public boolean hasStyle()
|
||||||
|
{
|
||||||
|
return !style.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the component has any formatting or events applied to it
|
* Returns whether the component has any formatting or events applied to it
|
||||||
*
|
*
|
||||||
@ -505,10 +612,8 @@ public abstract class BaseComponent
|
|||||||
*/
|
*/
|
||||||
public boolean hasFormatting()
|
public boolean hasFormatting()
|
||||||
{
|
{
|
||||||
return color != null || font != null || bold != null
|
return hasStyle() || insertion != null
|
||||||
|| italic != null || underlined != null
|
|| hoverEvent != null || clickEvent != null;
|
||||||
|| strikethrough != null || obfuscated != null
|
|
||||||
|| insertion != null || hoverEvent != null || clickEvent != null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -423,6 +423,18 @@ public final class ComponentBuilder
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the provided {@link ComponentStyle} to the current part.
|
||||||
|
*
|
||||||
|
* @param style the style to apply
|
||||||
|
* @return this ComponentBuilder for chaining
|
||||||
|
*/
|
||||||
|
public ComponentBuilder style(ComponentStyle style)
|
||||||
|
{
|
||||||
|
getCurrentComponent().applyStyle( style );
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the insertion text for the current part.
|
* Sets the insertion text for the current part.
|
||||||
*
|
*
|
||||||
|
234
chat/src/main/java/net/md_5/bungee/api/chat/ComponentStyle.java
Normal file
234
chat/src/main/java/net/md_5/bungee/api/chat/ComponentStyle.java
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
package net.md_5.bungee.api.chat;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a style that may be applied to a {@link BaseComponent}.
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@EqualsAndHashCode
|
||||||
|
public final class ComponentStyle implements Cloneable
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The color of this style.
|
||||||
|
*/
|
||||||
|
private ChatColor color;
|
||||||
|
/**
|
||||||
|
* The font of this style.
|
||||||
|
*/
|
||||||
|
private String font;
|
||||||
|
/**
|
||||||
|
* Whether this style is bold.
|
||||||
|
*/
|
||||||
|
private Boolean bold;
|
||||||
|
/**
|
||||||
|
* Whether this style is italic.
|
||||||
|
*/
|
||||||
|
private Boolean italic;
|
||||||
|
/**
|
||||||
|
* Whether this style is underlined.
|
||||||
|
*/
|
||||||
|
private Boolean underlined;
|
||||||
|
/**
|
||||||
|
* Whether this style is strikethrough.
|
||||||
|
*/
|
||||||
|
private Boolean strikethrough;
|
||||||
|
/**
|
||||||
|
* Whether this style is obfuscated.
|
||||||
|
*/
|
||||||
|
private Boolean obfuscated;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the color of this style. May return null.
|
||||||
|
*
|
||||||
|
* @return the color of this style, or null if default color
|
||||||
|
*/
|
||||||
|
public ChatColor getColor()
|
||||||
|
{
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not this style has a color set.
|
||||||
|
*
|
||||||
|
* @return whether a color is set
|
||||||
|
*/
|
||||||
|
public boolean hasColor()
|
||||||
|
{
|
||||||
|
return ( color != null );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the font of this style. May return null.
|
||||||
|
*
|
||||||
|
* @return the font of this style, or null if default font
|
||||||
|
*/
|
||||||
|
public String getFont()
|
||||||
|
{
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not this style has a font set.
|
||||||
|
*
|
||||||
|
* @return whether a font is set
|
||||||
|
*/
|
||||||
|
public boolean hasFont()
|
||||||
|
{
|
||||||
|
return ( font != null );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this style is bold.
|
||||||
|
*
|
||||||
|
* @return whether the style is bold
|
||||||
|
*/
|
||||||
|
public boolean isBold()
|
||||||
|
{
|
||||||
|
return ( bold != null ) && bold.booleanValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this style is bold. May return null.
|
||||||
|
*
|
||||||
|
* @return whether the style is bold, or null if not set
|
||||||
|
*/
|
||||||
|
public Boolean isBoldRaw()
|
||||||
|
{
|
||||||
|
return bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this style is italic. May return null.
|
||||||
|
*
|
||||||
|
* @return whether the style is italic
|
||||||
|
*/
|
||||||
|
public boolean isItalic()
|
||||||
|
{
|
||||||
|
return ( italic != null ) && italic.booleanValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this style is italic. May return null.
|
||||||
|
*
|
||||||
|
* @return whether the style is italic, or null if not set
|
||||||
|
*/
|
||||||
|
public Boolean isItalicRaw()
|
||||||
|
{
|
||||||
|
return italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this style is underlined.
|
||||||
|
*
|
||||||
|
* @return whether the style is underlined
|
||||||
|
*/
|
||||||
|
public boolean isUnderlined()
|
||||||
|
{
|
||||||
|
return ( underlined != null ) && underlined.booleanValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this style is underlined. May return null.
|
||||||
|
*
|
||||||
|
* @return whether the style is underlined, or null if not set
|
||||||
|
*/
|
||||||
|
public Boolean isUnderlinedRaw()
|
||||||
|
{
|
||||||
|
return underlined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this style is strikethrough
|
||||||
|
*
|
||||||
|
* @return whether the style is strikethrough
|
||||||
|
*/
|
||||||
|
public boolean isStrikethrough()
|
||||||
|
{
|
||||||
|
return ( strikethrough != null ) && strikethrough.booleanValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this style is strikethrough. May return null.
|
||||||
|
*
|
||||||
|
* @return whether the style is strikethrough, or null if not set
|
||||||
|
*/
|
||||||
|
public Boolean isStrikethroughRaw()
|
||||||
|
{
|
||||||
|
return strikethrough;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this style is obfuscated.
|
||||||
|
*
|
||||||
|
* @return whether the style is obfuscated
|
||||||
|
*/
|
||||||
|
public boolean isObfuscated()
|
||||||
|
{
|
||||||
|
return ( obfuscated != null ) && obfuscated.booleanValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this style is obfuscated. May return null.
|
||||||
|
*
|
||||||
|
* @return whether the style is obfuscated, or null if not set
|
||||||
|
*/
|
||||||
|
public Boolean isObfuscatedRaw()
|
||||||
|
{
|
||||||
|
return obfuscated;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this style has no formatting explicitly set.
|
||||||
|
*
|
||||||
|
* @return true if no value is set, false if at least one is set
|
||||||
|
*/
|
||||||
|
public boolean isEmpty()
|
||||||
|
{
|
||||||
|
return color == null && font == null && bold == null
|
||||||
|
&& italic == null && underlined == null
|
||||||
|
&& strikethrough == null && obfuscated == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ComponentStyle clone()
|
||||||
|
{
|
||||||
|
return new ComponentStyle( color, font, bold, italic, underlined, strikethrough, obfuscated );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a new {@link ComponentStyleBuilder}.
|
||||||
|
*
|
||||||
|
* @return the builder
|
||||||
|
*/
|
||||||
|
public static ComponentStyleBuilder builder()
|
||||||
|
{
|
||||||
|
return new ComponentStyleBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a new {@link ComponentStyleBuilder} with values initialized to the
|
||||||
|
* style values of the supplied {@link ComponentStyle}.
|
||||||
|
*
|
||||||
|
* @param other the component style whose values to copy into the builder
|
||||||
|
* @return the builder
|
||||||
|
*/
|
||||||
|
public static ComponentStyleBuilder builder(ComponentStyle other)
|
||||||
|
{
|
||||||
|
return new ComponentStyleBuilder()
|
||||||
|
.color( other.color )
|
||||||
|
.font( other.font )
|
||||||
|
.bold( other.bold )
|
||||||
|
.italic( other.italic )
|
||||||
|
.underlined( other.underlined )
|
||||||
|
.strikethrough( other.strikethrough )
|
||||||
|
.obfuscated( other.obfuscated );
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,126 @@
|
|||||||
|
package net.md_5.bungee.api.chat;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* ComponentStyleBuilder simplifies creating component styles by allowing the
|
||||||
|
* use of a chainable builder.
|
||||||
|
* </p>
|
||||||
|
* <pre>
|
||||||
|
* ComponentStyle style = ComponentStyle.builder()
|
||||||
|
* .color(ChatColor.RED)
|
||||||
|
* .font("custom:font")
|
||||||
|
* .bold(true).italic(true).create();
|
||||||
|
*
|
||||||
|
* BaseComponent component = new ComponentBuilder("Hello world").style(style).create();
|
||||||
|
* // Or it can be used directly on a component
|
||||||
|
* TextComponent text = new TextComponent("Hello world");
|
||||||
|
* text.applyStyle(style);
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @see ComponentStyle#builder()
|
||||||
|
* @see ComponentStyle#builder(ComponentStyle)
|
||||||
|
*/
|
||||||
|
public final class ComponentStyleBuilder
|
||||||
|
{
|
||||||
|
|
||||||
|
private ChatColor color;
|
||||||
|
private String font;
|
||||||
|
private Boolean bold, italic, underlined, strikethrough, obfuscated;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the style color.
|
||||||
|
*
|
||||||
|
* @param color the color to set, or null to use the default
|
||||||
|
* @return this ComponentStyleBuilder for chaining
|
||||||
|
*/
|
||||||
|
public ComponentStyleBuilder color(ChatColor color)
|
||||||
|
{
|
||||||
|
this.color = color;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the style font.
|
||||||
|
*
|
||||||
|
* @param font the font key to set, or null to use the default
|
||||||
|
* @return this ComponentStyleBuilder for chaining
|
||||||
|
*/
|
||||||
|
public ComponentStyleBuilder font(String font)
|
||||||
|
{
|
||||||
|
this.font = font;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the style's bold property.
|
||||||
|
*
|
||||||
|
* @param bold the bold value to set, or null to use the default
|
||||||
|
* @return this ComponentStyleBuilder for chaining
|
||||||
|
*/
|
||||||
|
public ComponentStyleBuilder bold(Boolean bold)
|
||||||
|
{
|
||||||
|
this.bold = bold;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the style's italic property.
|
||||||
|
*
|
||||||
|
* @param italic the italic value to set, or null to use the default
|
||||||
|
* @return this ComponentStyleBuilder for chaining
|
||||||
|
*/
|
||||||
|
public ComponentStyleBuilder italic(Boolean italic)
|
||||||
|
{
|
||||||
|
this.italic = italic;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the style's underlined property.
|
||||||
|
*
|
||||||
|
* @param underlined the underlined value to set, or null to use the default
|
||||||
|
* @return this ComponentStyleBuilder for chaining
|
||||||
|
*/
|
||||||
|
public ComponentStyleBuilder underlined(Boolean underlined)
|
||||||
|
{
|
||||||
|
this.underlined = underlined;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the style's strikethrough property.
|
||||||
|
*
|
||||||
|
* @param strikethrough the strikethrough value to set, or null to use the
|
||||||
|
* default
|
||||||
|
* @return this ComponentStyleBuilder for chaining
|
||||||
|
*/
|
||||||
|
public ComponentStyleBuilder strikethrough(Boolean strikethrough)
|
||||||
|
{
|
||||||
|
this.strikethrough = strikethrough;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the style's obfuscated property.
|
||||||
|
*
|
||||||
|
* @param obfuscated the obfuscated value to set, or null to use the default
|
||||||
|
* @return this ComponentStyleBuilder for chaining
|
||||||
|
*/
|
||||||
|
public ComponentStyleBuilder obfuscated(Boolean obfuscated)
|
||||||
|
{
|
||||||
|
this.obfuscated = obfuscated;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the {@link ComponentStyle} using the values set in this builder.
|
||||||
|
*
|
||||||
|
* @return the created ComponentStyle
|
||||||
|
*/
|
||||||
|
public ComponentStyle build()
|
||||||
|
{
|
||||||
|
return new ComponentStyle( color, font, bold, italic, underlined, strikethrough, obfuscated );
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@ import com.google.gson.JsonParseException;
|
|||||||
import com.google.gson.JsonSerializationContext;
|
import com.google.gson.JsonSerializationContext;
|
||||||
import com.google.gson.JsonSerializer;
|
import com.google.gson.JsonSerializer;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.UUID;
|
||||||
import net.md_5.bungee.api.chat.BaseComponent;
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
|
|
||||||
public class EntitySerializer implements JsonSerializer<Entity>, JsonDeserializer<Entity>
|
public class EntitySerializer implements JsonSerializer<Entity>, JsonDeserializer<Entity>
|
||||||
@ -18,9 +19,19 @@ public class EntitySerializer implements JsonSerializer<Entity>, JsonDeserialize
|
|||||||
{
|
{
|
||||||
JsonObject value = element.getAsJsonObject();
|
JsonObject value = element.getAsJsonObject();
|
||||||
|
|
||||||
|
String idString;
|
||||||
|
JsonElement id = value.get( "id" );
|
||||||
|
if ( id.isJsonArray() )
|
||||||
|
{
|
||||||
|
idString = parseUUID( context.deserialize( id, int[].class ) ).toString();
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
idString = id.getAsString();
|
||||||
|
}
|
||||||
|
|
||||||
return new Entity(
|
return new Entity(
|
||||||
( value.has( "type" ) ) ? value.get( "type" ).getAsString() : null,
|
( value.has( "type" ) ) ? value.get( "type" ).getAsString() : null,
|
||||||
value.get( "id" ).getAsString(),
|
idString,
|
||||||
( value.has( "name" ) ) ? context.deserialize( value.get( "name" ), BaseComponent.class ) : null
|
( value.has( "name" ) ) ? context.deserialize( value.get( "name" ), BaseComponent.class ) : null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -37,4 +48,9 @@ public class EntitySerializer implements JsonSerializer<Entity>, JsonDeserialize
|
|||||||
}
|
}
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static UUID parseUUID(int[] array)
|
||||||
|
{
|
||||||
|
return new UUID( (long) array[0] << 32 | (long) array[1] & 0XFFFFFFFFL, (long) array[2] << 32 | (long) array[3] & 0XFFFFFFFFL );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,73 +4,25 @@ import com.google.common.base.Preconditions;
|
|||||||
import com.google.gson.JsonDeserializationContext;
|
import com.google.gson.JsonDeserializationContext;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonParseException;
|
|
||||||
import com.google.gson.JsonPrimitive;
|
|
||||||
import com.google.gson.JsonSerializationContext;
|
import com.google.gson.JsonSerializationContext;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.IdentityHashMap;
|
import java.util.IdentityHashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
|
||||||
import net.md_5.bungee.api.chat.BaseComponent;
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
import net.md_5.bungee.api.chat.ClickEvent;
|
import net.md_5.bungee.api.chat.ClickEvent;
|
||||||
|
import net.md_5.bungee.api.chat.ComponentStyle;
|
||||||
import net.md_5.bungee.api.chat.HoverEvent;
|
import net.md_5.bungee.api.chat.HoverEvent;
|
||||||
import net.md_5.bungee.api.chat.hover.content.Content;
|
import net.md_5.bungee.api.chat.hover.content.Content;
|
||||||
|
|
||||||
public class BaseComponentSerializer
|
public class BaseComponentSerializer
|
||||||
{
|
{
|
||||||
|
|
||||||
private static boolean getAsBoolean(JsonElement el)
|
|
||||||
{
|
|
||||||
if ( el.isJsonPrimitive() )
|
|
||||||
{
|
|
||||||
JsonPrimitive primitive = (JsonPrimitive) el;
|
|
||||||
|
|
||||||
if ( primitive.isBoolean() )
|
|
||||||
{
|
|
||||||
return primitive.getAsBoolean();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( primitive.isNumber() )
|
|
||||||
{
|
|
||||||
Number number = primitive.getAsNumber();
|
|
||||||
if ( number instanceof Byte )
|
|
||||||
{
|
|
||||||
return number.byteValue() != 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void deserialize(JsonObject object, BaseComponent component, JsonDeserializationContext context)
|
protected void deserialize(JsonObject object, BaseComponent component, JsonDeserializationContext context)
|
||||||
{
|
{
|
||||||
if ( object.has( "bold" ) )
|
component.applyStyle( context.deserialize( object, ComponentStyle.class ) );
|
||||||
{
|
|
||||||
component.setBold( getAsBoolean( object.get( "bold" ) ) );
|
|
||||||
}
|
|
||||||
if ( object.has( "italic" ) )
|
|
||||||
{
|
|
||||||
component.setItalic( getAsBoolean( object.get( "italic" ) ) );
|
|
||||||
}
|
|
||||||
if ( object.has( "underlined" ) )
|
|
||||||
{
|
|
||||||
component.setUnderlined( getAsBoolean( object.get( "underlined" ) ) );
|
|
||||||
}
|
|
||||||
if ( object.has( "strikethrough" ) )
|
|
||||||
{
|
|
||||||
component.setStrikethrough( getAsBoolean( object.get( "strikethrough" ) ) );
|
|
||||||
}
|
|
||||||
if ( object.has( "obfuscated" ) )
|
|
||||||
{
|
|
||||||
component.setObfuscated( getAsBoolean( object.get( "obfuscated" ) ) );
|
|
||||||
}
|
|
||||||
if ( object.has( "color" ) )
|
|
||||||
{
|
|
||||||
component.setColor( ChatColor.of( object.get( "color" ).getAsString() ) );
|
|
||||||
}
|
|
||||||
if ( object.has( "insertion" ) )
|
if ( object.has( "insertion" ) )
|
||||||
{
|
{
|
||||||
component.setInsertion( object.get( "insertion" ).getAsString() );
|
component.setInsertion( object.get( "insertion" ).getAsString() );
|
||||||
@ -90,59 +42,48 @@ public class BaseComponentSerializer
|
|||||||
HoverEvent hoverEvent = null;
|
HoverEvent hoverEvent = null;
|
||||||
HoverEvent.Action action = HoverEvent.Action.valueOf( event.get( "action" ).getAsString().toUpperCase( Locale.ROOT ) );
|
HoverEvent.Action action = HoverEvent.Action.valueOf( event.get( "action" ).getAsString().toUpperCase( Locale.ROOT ) );
|
||||||
|
|
||||||
for ( String type : Arrays.asList( "value", "contents" ) )
|
if ( event.has( "value" ) )
|
||||||
{
|
{
|
||||||
if ( !event.has( type ) )
|
JsonElement contents = event.get( "value" );
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
JsonElement contents = event.get( type );
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
// Plugins previously had support to pass BaseComponent[] into any action.
|
// Plugins previously had support to pass BaseComponent[] into any action.
|
||||||
// If the GSON is possible to be parsed as BaseComponent, attempt to parse as so.
|
// If the GSON is possible to be parsed as BaseComponent, attempt to parse as so.
|
||||||
BaseComponent[] components;
|
BaseComponent[] components;
|
||||||
if ( contents.isJsonArray() )
|
if ( contents.isJsonArray() )
|
||||||
{
|
|
||||||
components = context.deserialize( contents, BaseComponent[].class );
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
components = new BaseComponent[]
|
|
||||||
{
|
|
||||||
context.deserialize( contents, BaseComponent.class )
|
|
||||||
};
|
|
||||||
}
|
|
||||||
hoverEvent = new HoverEvent( action, components );
|
|
||||||
} catch ( JsonParseException ex )
|
|
||||||
{
|
{
|
||||||
Content[] list;
|
components = context.deserialize( contents, BaseComponent[].class );
|
||||||
if ( contents.isJsonArray() )
|
} else
|
||||||
|
{
|
||||||
|
components = new BaseComponent[]
|
||||||
{
|
{
|
||||||
list = context.deserialize( contents, HoverEvent.getClass( action, true ) );
|
context.deserialize( contents, BaseComponent.class )
|
||||||
} else
|
};
|
||||||
{
|
|
||||||
list = new Content[]
|
|
||||||
{
|
|
||||||
context.deserialize( contents, HoverEvent.getClass( action, false ) )
|
|
||||||
};
|
|
||||||
}
|
|
||||||
hoverEvent = new HoverEvent( action, new ArrayList<>( Arrays.asList( list ) ) );
|
|
||||||
}
|
}
|
||||||
|
hoverEvent = new HoverEvent( action, components );
|
||||||
|
} else if ( event.has( "contents" ) )
|
||||||
|
{
|
||||||
|
JsonElement contents = event.get( "contents" );
|
||||||
|
|
||||||
// stop the loop as soon as either one is found
|
Content[] list;
|
||||||
break;
|
if ( contents.isJsonArray() )
|
||||||
|
{
|
||||||
|
list = context.deserialize( contents, HoverEvent.getClass( action, true ) );
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
list = new Content[]
|
||||||
|
{
|
||||||
|
context.deserialize( contents, HoverEvent.getClass( action, false ) )
|
||||||
|
};
|
||||||
|
}
|
||||||
|
hoverEvent = new HoverEvent( action, new ArrayList<>( Arrays.asList( list ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( hoverEvent != null )
|
if ( hoverEvent != null )
|
||||||
{
|
{
|
||||||
component.setHoverEvent( hoverEvent );
|
component.setHoverEvent( hoverEvent );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( object.has( "font" ) )
|
|
||||||
{
|
|
||||||
component.setFont( object.get( "font" ).getAsString() );
|
|
||||||
}
|
|
||||||
if ( object.has( "extra" ) )
|
if ( object.has( "extra" ) )
|
||||||
{
|
{
|
||||||
component.setExtra( Arrays.asList( context.<BaseComponent[]>deserialize( object.get( "extra" ), BaseComponent[].class ) ) );
|
component.setExtra( Arrays.asList( context.<BaseComponent[]>deserialize( object.get( "extra" ), BaseComponent[].class ) ) );
|
||||||
@ -161,30 +102,9 @@ public class BaseComponentSerializer
|
|||||||
{
|
{
|
||||||
Preconditions.checkArgument( !ComponentSerializer.serializedComponents.get().contains( component ), "Component loop" );
|
Preconditions.checkArgument( !ComponentSerializer.serializedComponents.get().contains( component ), "Component loop" );
|
||||||
ComponentSerializer.serializedComponents.get().add( component );
|
ComponentSerializer.serializedComponents.get().add( component );
|
||||||
if ( component.isBoldRaw() != null )
|
|
||||||
{
|
ComponentStyleSerializer.serializeTo( component.getStyle(), object );
|
||||||
object.addProperty( "bold", component.isBoldRaw() );
|
|
||||||
}
|
|
||||||
if ( component.isItalicRaw() != null )
|
|
||||||
{
|
|
||||||
object.addProperty( "italic", component.isItalicRaw() );
|
|
||||||
}
|
|
||||||
if ( component.isUnderlinedRaw() != null )
|
|
||||||
{
|
|
||||||
object.addProperty( "underlined", component.isUnderlinedRaw() );
|
|
||||||
}
|
|
||||||
if ( component.isStrikethroughRaw() != null )
|
|
||||||
{
|
|
||||||
object.addProperty( "strikethrough", component.isStrikethroughRaw() );
|
|
||||||
}
|
|
||||||
if ( component.isObfuscatedRaw() != null )
|
|
||||||
{
|
|
||||||
object.addProperty( "obfuscated", component.isObfuscatedRaw() );
|
|
||||||
}
|
|
||||||
if ( component.getColorRaw() != null )
|
|
||||||
{
|
|
||||||
object.addProperty( "color", component.getColorRaw().getName() );
|
|
||||||
}
|
|
||||||
if ( component.getInsertion() != null )
|
if ( component.getInsertion() != null )
|
||||||
{
|
{
|
||||||
object.addProperty( "insertion", component.getInsertion() );
|
object.addProperty( "insertion", component.getInsertion() );
|
||||||
@ -213,10 +133,6 @@ public class BaseComponentSerializer
|
|||||||
object.add( "hoverEvent", hoverEvent );
|
object.add( "hoverEvent", hoverEvent );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( component.getFontRaw() != null )
|
|
||||||
{
|
|
||||||
object.addProperty( "font", component.getFontRaw() );
|
|
||||||
}
|
|
||||||
if ( component.getExtra() != null )
|
if ( component.getExtra() != null )
|
||||||
{
|
{
|
||||||
object.add( "extra", context.serialize( component.getExtra() ) );
|
object.add( "extra", context.serialize( component.getExtra() ) );
|
||||||
|
@ -13,6 +13,7 @@ import com.google.gson.JsonPrimitive;
|
|||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import net.md_5.bungee.api.chat.BaseComponent;
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
|
import net.md_5.bungee.api.chat.ComponentStyle;
|
||||||
import net.md_5.bungee.api.chat.ItemTag;
|
import net.md_5.bungee.api.chat.ItemTag;
|
||||||
import net.md_5.bungee.api.chat.KeybindComponent;
|
import net.md_5.bungee.api.chat.KeybindComponent;
|
||||||
import net.md_5.bungee.api.chat.ScoreComponent;
|
import net.md_5.bungee.api.chat.ScoreComponent;
|
||||||
@ -36,6 +37,7 @@ public class ComponentSerializer implements JsonDeserializer<BaseComponent>
|
|||||||
registerTypeAdapter( KeybindComponent.class, new KeybindComponentSerializer() ).
|
registerTypeAdapter( KeybindComponent.class, new KeybindComponentSerializer() ).
|
||||||
registerTypeAdapter( ScoreComponent.class, new ScoreComponentSerializer() ).
|
registerTypeAdapter( ScoreComponent.class, new ScoreComponentSerializer() ).
|
||||||
registerTypeAdapter( SelectorComponent.class, new SelectorComponentSerializer() ).
|
registerTypeAdapter( SelectorComponent.class, new SelectorComponentSerializer() ).
|
||||||
|
registerTypeAdapter( ComponentStyle.class, new ComponentStyleSerializer() ).
|
||||||
registerTypeAdapter( Entity.class, new EntitySerializer() ).
|
registerTypeAdapter( Entity.class, new EntitySerializer() ).
|
||||||
registerTypeAdapter( Text.class, new TextSerializer() ).
|
registerTypeAdapter( Text.class, new TextSerializer() ).
|
||||||
registerTypeAdapter( Item.class, new ItemSerializer() ).
|
registerTypeAdapter( Item.class, new ItemSerializer() ).
|
||||||
@ -118,11 +120,44 @@ public class ComponentSerializer implements JsonDeserializer<BaseComponent>
|
|||||||
return gson.fromJson( jsonElement, BaseComponent.class );
|
return gson.fromJson( jsonElement, BaseComponent.class );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize a JSON-compliant String as a component style.
|
||||||
|
*
|
||||||
|
* @param json the component style json to parse
|
||||||
|
* @return the deserialized component style
|
||||||
|
* @throws IllegalArgumentException if anything other than a valid JSON
|
||||||
|
* component style string is passed as input
|
||||||
|
*/
|
||||||
|
public static ComponentStyle deserializeStyle(String json)
|
||||||
|
{
|
||||||
|
JsonElement jsonElement = JsonParser.parseString( json );
|
||||||
|
|
||||||
|
return deserializeStyle( jsonElement );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize a JSON element as a component style.
|
||||||
|
*
|
||||||
|
* @param jsonElement the component style json to parse
|
||||||
|
* @return the deserialized component style
|
||||||
|
* @throws IllegalArgumentException if anything other than a valid JSON
|
||||||
|
* component style is passed as input
|
||||||
|
*/
|
||||||
|
public static ComponentStyle deserializeStyle(JsonElement jsonElement)
|
||||||
|
{
|
||||||
|
return gson.fromJson( jsonElement, ComponentStyle.class );
|
||||||
|
}
|
||||||
|
|
||||||
public static JsonElement toJson(BaseComponent component)
|
public static JsonElement toJson(BaseComponent component)
|
||||||
{
|
{
|
||||||
return gson.toJsonTree( component );
|
return gson.toJsonTree( component );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static JsonElement toJson(ComponentStyle style)
|
||||||
|
{
|
||||||
|
return gson.toJsonTree( style );
|
||||||
|
}
|
||||||
|
|
||||||
public static String toString(Object object)
|
public static String toString(Object object)
|
||||||
{
|
{
|
||||||
return gson.toJson( object );
|
return gson.toJson( object );
|
||||||
@ -144,6 +179,11 @@ public class ComponentSerializer implements JsonDeserializer<BaseComponent>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String toString(ComponentStyle style)
|
||||||
|
{
|
||||||
|
return gson.toJson( style );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
|
public BaseComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,118 @@
|
|||||||
|
package net.md_5.bungee.chat;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.gson.JsonPrimitive;
|
||||||
|
import com.google.gson.JsonSerializationContext;
|
||||||
|
import com.google.gson.JsonSerializer;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import net.md_5.bungee.api.chat.ComponentStyle;
|
||||||
|
import net.md_5.bungee.api.chat.ComponentStyleBuilder;
|
||||||
|
|
||||||
|
public class ComponentStyleSerializer implements JsonSerializer<ComponentStyle>, JsonDeserializer<ComponentStyle>
|
||||||
|
{
|
||||||
|
|
||||||
|
private static boolean getAsBoolean(JsonElement el)
|
||||||
|
{
|
||||||
|
if ( el.isJsonPrimitive() )
|
||||||
|
{
|
||||||
|
JsonPrimitive primitive = (JsonPrimitive) el;
|
||||||
|
|
||||||
|
if ( primitive.isBoolean() )
|
||||||
|
{
|
||||||
|
return primitive.getAsBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( primitive.isNumber() )
|
||||||
|
{
|
||||||
|
Number number = primitive.getAsNumber();
|
||||||
|
if ( number instanceof Byte )
|
||||||
|
{
|
||||||
|
return number.byteValue() != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void serializeTo(ComponentStyle style, JsonObject object)
|
||||||
|
{
|
||||||
|
if ( style.isBoldRaw() != null )
|
||||||
|
{
|
||||||
|
object.addProperty( "bold", style.isBoldRaw() );
|
||||||
|
}
|
||||||
|
if ( style.isItalicRaw() != null )
|
||||||
|
{
|
||||||
|
object.addProperty( "italic", style.isItalicRaw() );
|
||||||
|
}
|
||||||
|
if ( style.isUnderlinedRaw() != null )
|
||||||
|
{
|
||||||
|
object.addProperty( "underlined", style.isUnderlinedRaw() );
|
||||||
|
}
|
||||||
|
if ( style.isStrikethroughRaw() != null )
|
||||||
|
{
|
||||||
|
object.addProperty( "strikethrough", style.isStrikethroughRaw() );
|
||||||
|
}
|
||||||
|
if ( style.isObfuscatedRaw() != null )
|
||||||
|
{
|
||||||
|
object.addProperty( "obfuscated", style.isObfuscatedRaw() );
|
||||||
|
}
|
||||||
|
if ( style.hasColor() )
|
||||||
|
{
|
||||||
|
object.addProperty( "color", style.getColor().getName() );
|
||||||
|
}
|
||||||
|
if ( style.hasFont() )
|
||||||
|
{
|
||||||
|
object.addProperty( "font", style.getFont() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ComponentStyle deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
|
||||||
|
{
|
||||||
|
ComponentStyleBuilder builder = ComponentStyle.builder();
|
||||||
|
JsonObject object = json.getAsJsonObject();
|
||||||
|
if ( object.has( "bold" ) )
|
||||||
|
{
|
||||||
|
builder.bold( getAsBoolean( object.get( "bold" ) ) );
|
||||||
|
}
|
||||||
|
if ( object.has( "italic" ) )
|
||||||
|
{
|
||||||
|
builder.italic( getAsBoolean( object.get( "italic" ) ) );
|
||||||
|
}
|
||||||
|
if ( object.has( "underlined" ) )
|
||||||
|
{
|
||||||
|
builder.underlined( getAsBoolean( object.get( "underlined" ) ) );
|
||||||
|
}
|
||||||
|
if ( object.has( "strikethrough" ) )
|
||||||
|
{
|
||||||
|
builder.strikethrough( getAsBoolean( object.get( "strikethrough" ) ) );
|
||||||
|
}
|
||||||
|
if ( object.has( "obfuscated" ) )
|
||||||
|
{
|
||||||
|
builder.obfuscated( getAsBoolean( object.get( "obfuscated" ) ) );
|
||||||
|
}
|
||||||
|
if ( object.has( "color" ) )
|
||||||
|
{
|
||||||
|
builder.color( ChatColor.of( object.get( "color" ).getAsString() ) );
|
||||||
|
}
|
||||||
|
if ( object.has( "font" ) )
|
||||||
|
{
|
||||||
|
builder.font( object.get( "font" ).getAsString() );
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(ComponentStyle src, Type typeOfSrc, JsonSerializationContext context)
|
||||||
|
{
|
||||||
|
JsonObject object = new JsonObject();
|
||||||
|
serializeTo( src, object );
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@ import java.util.function.Function;
|
|||||||
import java.util.function.ObjIntConsumer;
|
import java.util.function.ObjIntConsumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import net.md_5.bungee.api.chat.hover.content.Entity;
|
||||||
import net.md_5.bungee.api.chat.hover.content.Text;
|
import net.md_5.bungee.api.chat.hover.content.Text;
|
||||||
import net.md_5.bungee.chat.ComponentSerializer;
|
import net.md_5.bungee.chat.ComponentSerializer;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@ -88,6 +89,14 @@ public class ComponentsTest
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testArrayUUIDParse()
|
||||||
|
{
|
||||||
|
BaseComponent[] uuidComponent = ComponentSerializer.parse( "{\"translate\":\"multiplayer.player.joined\",\"with\":[{\"text\":\"Rexcantor64\",\"hoverEvent\":{\"contents\":{\"type\":\"minecraft:player\",\"id\":[1328556382,-2138814985,-1895806765,-1039963041],\"name\":\"Rexcantor64\"},\"action\":\"show_entity\"},\"insertion\":\"Rexcantor64\",\"clickEvent\":{\"action\":\"suggest_command\",\"value\":\"/tell Rexcantor64 \"}}],\"color\":\"yellow\"}" );
|
||||||
|
assertEquals( "4f30295e-8084-45f7-8f00-48d3c2036c5f", ( (Entity) ( (TranslatableComponent) uuidComponent[0] ).getWith().get( 0 ).getHoverEvent().getContents().get( 0 ) ).getId() );
|
||||||
|
testDissembleReassemble( uuidComponent );
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEmptyComponentBuilderCreate()
|
public void testEmptyComponentBuilderCreate()
|
||||||
{
|
{
|
||||||
@ -421,6 +430,16 @@ public class ComponentsTest
|
|||||||
assertArrayEquals( component, reparsed );
|
assertArrayEquals( component, reparsed );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStyle()
|
||||||
|
{
|
||||||
|
ComponentStyle style = ComponentSerializer.deserializeStyle( "{\"color\":\"red\",\"font\":\"minecraft:example\",\"bold\":true,\"italic\":false,\"obfuscated\":true}" );
|
||||||
|
String text = ComponentSerializer.toString( style );
|
||||||
|
ComponentStyle reparsed = ComponentSerializer.deserializeStyle( text );
|
||||||
|
|
||||||
|
assertEquals( style, reparsed );
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBuilderAppendCreate()
|
public void testBuilderAppendCreate()
|
||||||
{
|
{
|
||||||
@ -806,6 +825,28 @@ public class ComponentsTest
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHasFormatting()
|
||||||
|
{
|
||||||
|
BaseComponent component = new TextComponent();
|
||||||
|
assertFalse( component.hasFormatting() );
|
||||||
|
|
||||||
|
component.setBold( true );
|
||||||
|
assertTrue( component.hasFormatting() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStyleIsEmpty()
|
||||||
|
{
|
||||||
|
ComponentStyle style = ComponentStyle.builder().build();
|
||||||
|
assertTrue( style.isEmpty() );
|
||||||
|
|
||||||
|
style = ComponentStyle.builder()
|
||||||
|
.bold( true )
|
||||||
|
.build();
|
||||||
|
assertFalse( style.isEmpty() );
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In legacy chat, colors and reset both reset all formatting.
|
* In legacy chat, colors and reset both reset all formatting.
|
||||||
* Make sure it works in combination with ComponentBuilder.
|
* Make sure it works in combination with ComponentBuilder.
|
||||||
|
@ -4,15 +4,14 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-config</artifactId>
|
<artifactId>bungeecord-config</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-Config</name>
|
<name>BungeeCord-Config</name>
|
||||||
|
@ -4,15 +4,14 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-event</artifactId>
|
<artifactId>bungeecord-event</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-Event</name>
|
<name>BungeeCord-Event</name>
|
||||||
|
@ -4,15 +4,14 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-log</artifactId>
|
<artifactId>bungeecord-log</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-Log</name>
|
<name>BungeeCord-Log</name>
|
||||||
@ -26,7 +25,7 @@
|
|||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-chat</artifactId>
|
<artifactId>bungeecord-chat</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<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.fromLegacy( 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.fromLegacy( ProxyServer.getInstance().getTranslation( "user_not_online" ) ) );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( args.length == 1 )
|
|
||||||
{
|
|
||||||
player.disconnect( TextComponent.fromLegacy( ProxyServer.getInstance().getTranslation( "kick_message" ) ) );
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
String[] reason = new String[ args.length - 1 ];
|
|
||||||
System.arraycopy( args, 1, reason, 0, reason.length );
|
|
||||||
player.disconnect( TextComponent.fromLegacy( ChatColor.translateAlternateColorCodes( '&', Joiner.on( ' ' ).join( reason ) ) ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterable<String> onTabComplete(CommandSender sender, String[] args)
|
|
||||||
{
|
|
||||||
if ( args.length == 1 )
|
|
||||||
{
|
|
||||||
Set<String> matches = new HashSet<>();
|
|
||||||
String search = args[0].toLowerCase( Locale.ROOT );
|
|
||||||
for ( ProxiedPlayer player : ProxyServer.getInstance().getPlayers() )
|
|
||||||
{
|
|
||||||
if ( player.getName().toLowerCase( Locale.ROOT ).startsWith( search ) )
|
|
||||||
{
|
|
||||||
matches.add( player.getName() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return matches;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
return ImmutableSet.of();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
package net.md_5.bungee.module.cmd.kick;
|
|
||||||
|
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
|
||||||
|
|
||||||
public class PluginKick extends Plugin
|
|
||||||
{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnable()
|
|
||||||
{
|
|
||||||
getProxy().getPluginManager().registerCommand( this, new CommandKick() );
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
name: ${project.name}
|
|
||||||
main: net.md_5.bungee.module.cmd.kick.PluginKick
|
|
||||||
version: ${describe}
|
|
||||||
description: ${project.description}
|
|
||||||
author: ${module.author}
|
|
@ -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, Collections.synchronizedList( new ArrayList<>() ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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,15 +4,14 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-native</artifactId>
|
<artifactId>bungeecord-native</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-Native</name>
|
<name>BungeeCord-Native</name>
|
||||||
|
21
pom.xml
21
pom.xml
@ -3,9 +3,9 @@
|
|||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-Parent</name>
|
<name>BungeeCord-Parent</name>
|
||||||
@ -37,7 +37,6 @@
|
|||||||
<module>config</module>
|
<module>config</module>
|
||||||
<module>event</module>
|
<module>event</module>
|
||||||
<module>log</module>
|
<module>log</module>
|
||||||
<module>module</module>
|
|
||||||
<module>protocol</module>
|
<module>protocol</module>
|
||||||
<module>proxy</module>
|
<module>proxy</module>
|
||||||
<module>query</module>
|
<module>query</module>
|
||||||
@ -83,7 +82,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.netty</groupId>
|
<groupId>io.netty</groupId>
|
||||||
<artifactId>netty-bom</artifactId>
|
<artifactId>netty-bom</artifactId>
|
||||||
<version>4.1.100.Final</version>
|
<version>4.1.107.Final</version>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
<scope>import</scope>
|
<scope>import</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
@ -93,7 +92,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter</artifactId>
|
<artifactId>junit-jupiter</artifactId>
|
||||||
<version>5.10.1</version>
|
<version>5.10.2</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -108,6 +107,12 @@
|
|||||||
<version>3.0.1</version>
|
<version>3.0.1</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains</groupId>
|
||||||
|
<artifactId>annotations-java5</artifactId>
|
||||||
|
<version>24.1.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
@ -122,7 +127,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
<version>3.6.2</version>
|
<version>3.6.3</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</pluginManagement>
|
</pluginManagement>
|
||||||
@ -132,7 +137,7 @@
|
|||||||
<artifactId>scriptus</artifactId>
|
<artifactId>scriptus</artifactId>
|
||||||
<version>0.5.0</version>
|
<version>0.5.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<format>git:${project.name}:${project.version}:%s:${build.number}</format>
|
<format>git:${project.name}-Pandacube:${project.version}:%s:${build.number}</format>
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
@ -146,7 +151,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.11.0</version>
|
<version>3.12.1</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
@ -4,15 +4,14 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-protocol</artifactId>
|
<artifactId>bungeecord-protocol</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-Protocol</name>
|
<name>BungeeCord-Protocol</name>
|
||||||
@ -35,7 +34,7 @@
|
|||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-chat</artifactId>
|
<artifactId>bungeecord-chat</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
|
@ -8,6 +8,8 @@ import net.md_5.bungee.protocol.packet.ClientCommand;
|
|||||||
import net.md_5.bungee.protocol.packet.ClientSettings;
|
import net.md_5.bungee.protocol.packet.ClientSettings;
|
||||||
import net.md_5.bungee.protocol.packet.ClientStatus;
|
import net.md_5.bungee.protocol.packet.ClientStatus;
|
||||||
import net.md_5.bungee.protocol.packet.Commands;
|
import net.md_5.bungee.protocol.packet.Commands;
|
||||||
|
import net.md_5.bungee.protocol.packet.CookieRequest;
|
||||||
|
import net.md_5.bungee.protocol.packet.CookieResponse;
|
||||||
import net.md_5.bungee.protocol.packet.EncryptionRequest;
|
import net.md_5.bungee.protocol.packet.EncryptionRequest;
|
||||||
import net.md_5.bungee.protocol.packet.EncryptionResponse;
|
import net.md_5.bungee.protocol.packet.EncryptionResponse;
|
||||||
import net.md_5.bungee.protocol.packet.EntityStatus;
|
import net.md_5.bungee.protocol.packet.EntityStatus;
|
||||||
@ -40,6 +42,7 @@ import net.md_5.bungee.protocol.packet.SetCompression;
|
|||||||
import net.md_5.bungee.protocol.packet.StartConfiguration;
|
import net.md_5.bungee.protocol.packet.StartConfiguration;
|
||||||
import net.md_5.bungee.protocol.packet.StatusRequest;
|
import net.md_5.bungee.protocol.packet.StatusRequest;
|
||||||
import net.md_5.bungee.protocol.packet.StatusResponse;
|
import net.md_5.bungee.protocol.packet.StatusResponse;
|
||||||
|
import net.md_5.bungee.protocol.packet.StoreCookie;
|
||||||
import net.md_5.bungee.protocol.packet.Subtitle;
|
import net.md_5.bungee.protocol.packet.Subtitle;
|
||||||
import net.md_5.bungee.protocol.packet.SystemChat;
|
import net.md_5.bungee.protocol.packet.SystemChat;
|
||||||
import net.md_5.bungee.protocol.packet.TabCompleteRequest;
|
import net.md_5.bungee.protocol.packet.TabCompleteRequest;
|
||||||
@ -47,6 +50,7 @@ import net.md_5.bungee.protocol.packet.TabCompleteResponse;
|
|||||||
import net.md_5.bungee.protocol.packet.Team;
|
import net.md_5.bungee.protocol.packet.Team;
|
||||||
import net.md_5.bungee.protocol.packet.Title;
|
import net.md_5.bungee.protocol.packet.Title;
|
||||||
import net.md_5.bungee.protocol.packet.TitleTimes;
|
import net.md_5.bungee.protocol.packet.TitleTimes;
|
||||||
|
import net.md_5.bungee.protocol.packet.Transfer;
|
||||||
import net.md_5.bungee.protocol.packet.ViewDistance;
|
import net.md_5.bungee.protocol.packet.ViewDistance;
|
||||||
|
|
||||||
public abstract class AbstractPacketHandler
|
public abstract class AbstractPacketHandler
|
||||||
@ -243,4 +247,20 @@ public abstract class AbstractPacketHandler
|
|||||||
public void handle(FinishConfiguration finishConfiguration) throws Exception
|
public void handle(FinishConfiguration finishConfiguration) throws Exception
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void handle(Transfer transfer) throws Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handle(StoreCookie storeCookie) throws Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handle(CookieRequest cookieRequest) throws Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handle(CookieResponse cookieResponse) throws Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import java.util.UUID;
|
|||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import net.md_5.bungee.api.chat.BaseComponent;
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
|
import net.md_5.bungee.api.chat.ComponentStyle;
|
||||||
import net.md_5.bungee.chat.ComponentSerializer;
|
import net.md_5.bungee.chat.ComponentSerializer;
|
||||||
import se.llbit.nbt.ErrorTag;
|
import se.llbit.nbt.ErrorTag;
|
||||||
import se.llbit.nbt.NamedTag;
|
import se.llbit.nbt.NamedTag;
|
||||||
@ -118,6 +119,14 @@ public abstract class DefinedPacket
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ComponentStyle readComponentStyle(ByteBuf buf, int protocolVersion)
|
||||||
|
{
|
||||||
|
SpecificTag nbt = (SpecificTag) readTag( buf, protocolVersion );
|
||||||
|
JsonElement json = TagUtil.toJson( nbt );
|
||||||
|
|
||||||
|
return ComponentSerializer.deserializeStyle( json );
|
||||||
|
}
|
||||||
|
|
||||||
public static void writeEitherBaseComponent(Either<String, BaseComponent> message, ByteBuf buf, int protocolVersion)
|
public static void writeEitherBaseComponent(Either<String, BaseComponent> message, ByteBuf buf, int protocolVersion)
|
||||||
{
|
{
|
||||||
if ( message.isLeft() )
|
if ( message.isLeft() )
|
||||||
@ -145,6 +154,14 @@ public abstract class DefinedPacket
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void writeComponentStyle(ComponentStyle style, ByteBuf buf, int protocolVersion)
|
||||||
|
{
|
||||||
|
JsonElement json = ComponentSerializer.toJson( style );
|
||||||
|
SpecificTag nbt = TagUtil.fromJson( json );
|
||||||
|
|
||||||
|
writeTag( nbt, buf, protocolVersion );
|
||||||
|
}
|
||||||
|
|
||||||
public static void writeArray(byte[] b, ByteBuf buf)
|
public static void writeArray(byte[] b, ByteBuf buf)
|
||||||
{
|
{
|
||||||
if ( b.length > Short.MAX_VALUE )
|
if ( b.length > Short.MAX_VALUE )
|
||||||
@ -231,7 +248,7 @@ public abstract class DefinedPacket
|
|||||||
|
|
||||||
if ( bytes > maxBytes )
|
if ( bytes > maxBytes )
|
||||||
{
|
{
|
||||||
throw new RuntimeException( "VarInt too big" );
|
throw new OverflowPacketException( "VarInt too big (max " + maxBytes + ")" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ( in & 0x80 ) != 0x80 )
|
if ( ( in & 0x80 ) != 0x80 )
|
||||||
@ -378,7 +395,7 @@ public abstract class DefinedPacket
|
|||||||
case BLANK:
|
case BLANK:
|
||||||
break;
|
break;
|
||||||
case STYLED:
|
case STYLED:
|
||||||
writeBaseComponent( (BaseComponent) format.getValue(), buf, protocolVersion ); // TODO: style
|
writeComponentStyle( (ComponentStyle) format.getValue(), buf, protocolVersion );
|
||||||
break;
|
break;
|
||||||
case FIXED:
|
case FIXED:
|
||||||
writeBaseComponent( (BaseComponent) format.getValue(), buf, protocolVersion );
|
writeBaseComponent( (BaseComponent) format.getValue(), buf, protocolVersion );
|
||||||
@ -394,7 +411,7 @@ public abstract class DefinedPacket
|
|||||||
case 0:
|
case 0:
|
||||||
return new NumberFormat( NumberFormat.Type.BLANK, null );
|
return new NumberFormat( NumberFormat.Type.BLANK, null );
|
||||||
case 1:
|
case 1:
|
||||||
return new NumberFormat( NumberFormat.Type.STYLED, readBaseComponent( buf, protocolVersion ) ); // TODO: style
|
return new NumberFormat( NumberFormat.Type.STYLED, readComponentStyle( buf, protocolVersion ) );
|
||||||
case 2:
|
case 2:
|
||||||
return new NumberFormat( NumberFormat.Type.FIXED, readBaseComponent( buf, protocolVersion ) );
|
return new NumberFormat( NumberFormat.Type.FIXED, readBaseComponent( buf, protocolVersion ) );
|
||||||
default:
|
default:
|
||||||
|
@ -16,6 +16,8 @@ import net.md_5.bungee.protocol.packet.ClientChat;
|
|||||||
import net.md_5.bungee.protocol.packet.ClientCommand;
|
import net.md_5.bungee.protocol.packet.ClientCommand;
|
||||||
import net.md_5.bungee.protocol.packet.ClientSettings;
|
import net.md_5.bungee.protocol.packet.ClientSettings;
|
||||||
import net.md_5.bungee.protocol.packet.Commands;
|
import net.md_5.bungee.protocol.packet.Commands;
|
||||||
|
import net.md_5.bungee.protocol.packet.CookieRequest;
|
||||||
|
import net.md_5.bungee.protocol.packet.CookieResponse;
|
||||||
import net.md_5.bungee.protocol.packet.EncryptionRequest;
|
import net.md_5.bungee.protocol.packet.EncryptionRequest;
|
||||||
import net.md_5.bungee.protocol.packet.EncryptionResponse;
|
import net.md_5.bungee.protocol.packet.EncryptionResponse;
|
||||||
import net.md_5.bungee.protocol.packet.EntityStatus;
|
import net.md_5.bungee.protocol.packet.EntityStatus;
|
||||||
@ -46,6 +48,7 @@ import net.md_5.bungee.protocol.packet.SetCompression;
|
|||||||
import net.md_5.bungee.protocol.packet.StartConfiguration;
|
import net.md_5.bungee.protocol.packet.StartConfiguration;
|
||||||
import net.md_5.bungee.protocol.packet.StatusRequest;
|
import net.md_5.bungee.protocol.packet.StatusRequest;
|
||||||
import net.md_5.bungee.protocol.packet.StatusResponse;
|
import net.md_5.bungee.protocol.packet.StatusResponse;
|
||||||
|
import net.md_5.bungee.protocol.packet.StoreCookie;
|
||||||
import net.md_5.bungee.protocol.packet.Subtitle;
|
import net.md_5.bungee.protocol.packet.Subtitle;
|
||||||
import net.md_5.bungee.protocol.packet.SystemChat;
|
import net.md_5.bungee.protocol.packet.SystemChat;
|
||||||
import net.md_5.bungee.protocol.packet.TabCompleteRequest;
|
import net.md_5.bungee.protocol.packet.TabCompleteRequest;
|
||||||
@ -53,6 +56,7 @@ import net.md_5.bungee.protocol.packet.TabCompleteResponse;
|
|||||||
import net.md_5.bungee.protocol.packet.Team;
|
import net.md_5.bungee.protocol.packet.Team;
|
||||||
import net.md_5.bungee.protocol.packet.Title;
|
import net.md_5.bungee.protocol.packet.Title;
|
||||||
import net.md_5.bungee.protocol.packet.TitleTimes;
|
import net.md_5.bungee.protocol.packet.TitleTimes;
|
||||||
|
import net.md_5.bungee.protocol.packet.Transfer;
|
||||||
import net.md_5.bungee.protocol.packet.ViewDistance;
|
import net.md_5.bungee.protocol.packet.ViewDistance;
|
||||||
|
|
||||||
public enum Protocol
|
public enum Protocol
|
||||||
@ -90,7 +94,8 @@ public enum Protocol
|
|||||||
map( ProtocolConstants.MINECRAFT_1_19_1, 0x20 ),
|
map( ProtocolConstants.MINECRAFT_1_19_1, 0x20 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_3, 0x1F ),
|
map( ProtocolConstants.MINECRAFT_1_19_3, 0x1F ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_4, 0x23 ),
|
map( ProtocolConstants.MINECRAFT_1_19_4, 0x23 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x24 )
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x24 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x26 )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
Login.class,
|
Login.class,
|
||||||
@ -106,7 +111,8 @@ public enum Protocol
|
|||||||
map( ProtocolConstants.MINECRAFT_1_19_1, 0x25 ),
|
map( ProtocolConstants.MINECRAFT_1_19_1, 0x25 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_3, 0x24 ),
|
map( ProtocolConstants.MINECRAFT_1_19_3, 0x24 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_4, 0x28 ),
|
map( ProtocolConstants.MINECRAFT_1_19_4, 0x28 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x29 )
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x29 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x2B )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket( Chat.class,
|
TO_CLIENT.registerPacket( Chat.class,
|
||||||
Chat::new,
|
Chat::new,
|
||||||
@ -136,7 +142,8 @@ public enum Protocol
|
|||||||
map( ProtocolConstants.MINECRAFT_1_19_3, 0x3D ),
|
map( ProtocolConstants.MINECRAFT_1_19_3, 0x3D ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_4, 0x41 ),
|
map( ProtocolConstants.MINECRAFT_1_19_4, 0x41 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x43 ),
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x43 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_3, 0x45 )
|
map( ProtocolConstants.MINECRAFT_1_20_3, 0x45 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x47 )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
BossBar.class,
|
BossBar.class,
|
||||||
@ -195,7 +202,8 @@ public enum Protocol
|
|||||||
map( ProtocolConstants.MINECRAFT_1_19_3, 0x54 ),
|
map( ProtocolConstants.MINECRAFT_1_19_3, 0x54 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_4, 0x58 ),
|
map( ProtocolConstants.MINECRAFT_1_19_4, 0x58 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x5A ),
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x5A ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_3, 0x5C )
|
map( ProtocolConstants.MINECRAFT_1_20_3, 0x5C ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x5E )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
ScoreboardScore.class,
|
ScoreboardScore.class,
|
||||||
@ -212,12 +220,14 @@ public enum Protocol
|
|||||||
map( ProtocolConstants.MINECRAFT_1_19_3, 0x57 ),
|
map( ProtocolConstants.MINECRAFT_1_19_3, 0x57 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_4, 0x5B ),
|
map( ProtocolConstants.MINECRAFT_1_19_4, 0x5B ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x5D ),
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x5D ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_3, 0x5F )
|
map( ProtocolConstants.MINECRAFT_1_20_3, 0x5F ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x61 )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
ScoreboardScoreReset.class,
|
ScoreboardScoreReset.class,
|
||||||
ScoreboardScoreReset::new,
|
ScoreboardScoreReset::new,
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_3, 0x42 )
|
map( ProtocolConstants.MINECRAFT_1_20_3, 0x42 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x44 )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
ScoreboardDisplay.class,
|
ScoreboardDisplay.class,
|
||||||
@ -234,7 +244,8 @@ public enum Protocol
|
|||||||
map( ProtocolConstants.MINECRAFT_1_19_3, 0x4D ),
|
map( ProtocolConstants.MINECRAFT_1_19_3, 0x4D ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_4, 0x51 ),
|
map( ProtocolConstants.MINECRAFT_1_19_4, 0x51 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x53 ),
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x53 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_3, 0x55 )
|
map( ProtocolConstants.MINECRAFT_1_20_3, 0x55 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x57 )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
Team.class,
|
Team.class,
|
||||||
@ -251,7 +262,8 @@ public enum Protocol
|
|||||||
map( ProtocolConstants.MINECRAFT_1_19_3, 0x56 ),
|
map( ProtocolConstants.MINECRAFT_1_19_3, 0x56 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_4, 0x5A ),
|
map( ProtocolConstants.MINECRAFT_1_19_4, 0x5A ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x5C ),
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x5C ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_3, 0x5E )
|
map( ProtocolConstants.MINECRAFT_1_20_3, 0x5E ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x60 )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
PluginMessage.class,
|
PluginMessage.class,
|
||||||
@ -268,7 +280,8 @@ public enum Protocol
|
|||||||
map( ProtocolConstants.MINECRAFT_1_19_1, 0x16 ),
|
map( ProtocolConstants.MINECRAFT_1_19_1, 0x16 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_3, 0x15 ),
|
map( ProtocolConstants.MINECRAFT_1_19_3, 0x15 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_4, 0x17 ),
|
map( ProtocolConstants.MINECRAFT_1_19_4, 0x17 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x18 )
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x18 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x19 )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
Kick.class,
|
Kick.class,
|
||||||
@ -285,7 +298,8 @@ public enum Protocol
|
|||||||
map( ProtocolConstants.MINECRAFT_1_19_1, 0x19 ),
|
map( ProtocolConstants.MINECRAFT_1_19_1, 0x19 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_3, 0x17 ),
|
map( ProtocolConstants.MINECRAFT_1_19_3, 0x17 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_4, 0x1A ),
|
map( ProtocolConstants.MINECRAFT_1_19_4, 0x1A ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x1B )
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x1B ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x1D )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
Title.class,
|
Title.class,
|
||||||
@ -303,7 +317,8 @@ public enum Protocol
|
|||||||
map( ProtocolConstants.MINECRAFT_1_19_3, 0x5B ),
|
map( ProtocolConstants.MINECRAFT_1_19_3, 0x5B ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_4, 0x5F ),
|
map( ProtocolConstants.MINECRAFT_1_19_4, 0x5F ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x61 ),
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x61 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_3, 0x63 )
|
map( ProtocolConstants.MINECRAFT_1_20_3, 0x63 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x65 )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
ClearTitles.class,
|
ClearTitles.class,
|
||||||
@ -323,7 +338,8 @@ public enum Protocol
|
|||||||
map( ProtocolConstants.MINECRAFT_1_19_3, 0x59 ),
|
map( ProtocolConstants.MINECRAFT_1_19_3, 0x59 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_4, 0x5D ),
|
map( ProtocolConstants.MINECRAFT_1_19_4, 0x5D ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x5F ),
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x5F ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_3, 0x61 )
|
map( ProtocolConstants.MINECRAFT_1_20_3, 0x61 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x63 )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
TitleTimes.class,
|
TitleTimes.class,
|
||||||
@ -334,7 +350,8 @@ public enum Protocol
|
|||||||
map( ProtocolConstants.MINECRAFT_1_19_3, 0x5C ),
|
map( ProtocolConstants.MINECRAFT_1_19_3, 0x5C ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_4, 0x60 ),
|
map( ProtocolConstants.MINECRAFT_1_19_4, 0x60 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x62 ),
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x62 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_3, 0x64 )
|
map( ProtocolConstants.MINECRAFT_1_20_3, 0x64 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x66 )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
SystemChat.class,
|
SystemChat.class,
|
||||||
@ -344,7 +361,8 @@ public enum Protocol
|
|||||||
map( ProtocolConstants.MINECRAFT_1_19_3, 0x60 ),
|
map( ProtocolConstants.MINECRAFT_1_19_3, 0x60 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_4, 0x64 ),
|
map( ProtocolConstants.MINECRAFT_1_19_4, 0x64 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x67 ),
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x67 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_3, 0x69 )
|
map( ProtocolConstants.MINECRAFT_1_20_3, 0x69 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x6C )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
PlayerListHeaderFooter.class,
|
PlayerListHeaderFooter.class,
|
||||||
@ -365,7 +383,8 @@ public enum Protocol
|
|||||||
map( ProtocolConstants.MINECRAFT_1_19_3, 0x61 ),
|
map( ProtocolConstants.MINECRAFT_1_19_3, 0x61 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_4, 0x65 ),
|
map( ProtocolConstants.MINECRAFT_1_19_4, 0x65 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x68 ),
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x68 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_3, 0x6A )
|
map( ProtocolConstants.MINECRAFT_1_20_3, 0x6A ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x6D )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
EntityStatus.class,
|
EntityStatus.class,
|
||||||
@ -382,7 +401,8 @@ public enum Protocol
|
|||||||
map( ProtocolConstants.MINECRAFT_1_19_1, 0x1A ),
|
map( ProtocolConstants.MINECRAFT_1_19_1, 0x1A ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_3, 0x19 ),
|
map( ProtocolConstants.MINECRAFT_1_19_3, 0x19 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_4, 0x1C ),
|
map( ProtocolConstants.MINECRAFT_1_19_4, 0x1C ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x1D )
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x1D ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x1F )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
Commands.class,
|
Commands.class,
|
||||||
@ -408,7 +428,8 @@ public enum Protocol
|
|||||||
map( ProtocolConstants.MINECRAFT_1_19_1, 0x1D ),
|
map( ProtocolConstants.MINECRAFT_1_19_1, 0x1D ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_3, 0x1C ),
|
map( ProtocolConstants.MINECRAFT_1_19_3, 0x1C ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_4, 0x1F ),
|
map( ProtocolConstants.MINECRAFT_1_19_4, 0x1F ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x20 )
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x20 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x22 )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
ViewDistance.class,
|
ViewDistance.class,
|
||||||
@ -422,7 +443,8 @@ public enum Protocol
|
|||||||
map( ProtocolConstants.MINECRAFT_1_19_3, 0x4B ),
|
map( ProtocolConstants.MINECRAFT_1_19_3, 0x4B ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_4, 0x4F ),
|
map( ProtocolConstants.MINECRAFT_1_19_4, 0x4F ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x51 ),
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x51 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_3, 0x53 )
|
map( ProtocolConstants.MINECRAFT_1_20_3, 0x53 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x62 )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
ServerData.class,
|
ServerData.class,
|
||||||
@ -432,27 +454,46 @@ public enum Protocol
|
|||||||
map( ProtocolConstants.MINECRAFT_1_19_3, 0x41 ),
|
map( ProtocolConstants.MINECRAFT_1_19_3, 0x41 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_4, 0x45 ),
|
map( ProtocolConstants.MINECRAFT_1_19_4, 0x45 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x47 ),
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x47 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_3, 0x49 )
|
map( ProtocolConstants.MINECRAFT_1_20_3, 0x49 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x4B )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
PlayerListItemRemove.class,
|
PlayerListItemRemove.class,
|
||||||
PlayerListItemRemove::new,
|
PlayerListItemRemove::new,
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_3, 0x35 ),
|
map( ProtocolConstants.MINECRAFT_1_19_3, 0x35 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_4, 0x39 ),
|
map( ProtocolConstants.MINECRAFT_1_19_4, 0x39 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x3B )
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x3B ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x3D )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
PlayerListItemUpdate.class,
|
PlayerListItemUpdate.class,
|
||||||
PlayerListItemUpdate::new,
|
PlayerListItemUpdate::new,
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_3, 0x36 ),
|
map( ProtocolConstants.MINECRAFT_1_19_3, 0x36 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_4, 0x3A ),
|
map( ProtocolConstants.MINECRAFT_1_19_4, 0x3A ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x3C )
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x3C ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x3E )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
StartConfiguration.class,
|
StartConfiguration.class,
|
||||||
StartConfiguration::new,
|
StartConfiguration::new,
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x65 ),
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x65 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_3, 0x67 )
|
map( ProtocolConstants.MINECRAFT_1_20_3, 0x67 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x69 )
|
||||||
|
);
|
||||||
|
TO_CLIENT.registerPacket(
|
||||||
|
CookieRequest.class,
|
||||||
|
CookieRequest::new,
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x16 )
|
||||||
|
);
|
||||||
|
TO_CLIENT.registerPacket(
|
||||||
|
StoreCookie.class,
|
||||||
|
StoreCookie::new,
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x6B )
|
||||||
|
);
|
||||||
|
TO_CLIENT.registerPacket(
|
||||||
|
Transfer.class,
|
||||||
|
Transfer::new,
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x73 )
|
||||||
);
|
);
|
||||||
|
|
||||||
TO_SERVER.registerPacket(
|
TO_SERVER.registerPacket(
|
||||||
@ -471,7 +512,8 @@ public enum Protocol
|
|||||||
map( ProtocolConstants.MINECRAFT_1_19_3, 0x11 ),
|
map( ProtocolConstants.MINECRAFT_1_19_3, 0x11 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_4, 0x12 ),
|
map( ProtocolConstants.MINECRAFT_1_19_4, 0x12 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x14 ),
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x14 ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_3, 0x15 )
|
map( ProtocolConstants.MINECRAFT_1_20_3, 0x15 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x17 )
|
||||||
);
|
);
|
||||||
TO_SERVER.registerPacket( Chat.class,
|
TO_SERVER.registerPacket( Chat.class,
|
||||||
Chat::new,
|
Chat::new,
|
||||||
@ -538,13 +580,19 @@ public enum Protocol
|
|||||||
map( ProtocolConstants.MINECRAFT_1_19_3, 0x0C ),
|
map( ProtocolConstants.MINECRAFT_1_19_3, 0x0C ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_19_4, 0x0D ),
|
map( ProtocolConstants.MINECRAFT_1_19_4, 0x0D ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x0F ),
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x0F ),
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_3, 0x10 )
|
map( ProtocolConstants.MINECRAFT_1_20_3, 0x10 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x11 )
|
||||||
);
|
);
|
||||||
TO_SERVER.registerPacket(
|
TO_SERVER.registerPacket(
|
||||||
StartConfiguration.class,
|
StartConfiguration.class,
|
||||||
StartConfiguration::new,
|
StartConfiguration::new,
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x0B )
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x0B )
|
||||||
);
|
);
|
||||||
|
TO_SERVER.registerPacket(
|
||||||
|
CookieResponse.class,
|
||||||
|
CookieResponse::new,
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x10 )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 1
|
// 1
|
||||||
@ -605,6 +653,11 @@ public enum Protocol
|
|||||||
LoginPayloadRequest::new,
|
LoginPayloadRequest::new,
|
||||||
map( ProtocolConstants.MINECRAFT_1_13, 0x04 )
|
map( ProtocolConstants.MINECRAFT_1_13, 0x04 )
|
||||||
);
|
);
|
||||||
|
TO_CLIENT.registerPacket(
|
||||||
|
CookieRequest.class,
|
||||||
|
CookieRequest::new,
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x05 )
|
||||||
|
);
|
||||||
|
|
||||||
TO_SERVER.registerPacket(
|
TO_SERVER.registerPacket(
|
||||||
LoginRequest.class,
|
LoginRequest.class,
|
||||||
@ -626,6 +679,11 @@ public enum Protocol
|
|||||||
LoginAcknowledged::new,
|
LoginAcknowledged::new,
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x03 )
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x03 )
|
||||||
);
|
);
|
||||||
|
TO_SERVER.registerPacket(
|
||||||
|
CookieResponse.class,
|
||||||
|
CookieResponse::new,
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x04 )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 3
|
// 3
|
||||||
@ -633,25 +691,45 @@ public enum Protocol
|
|||||||
{
|
{
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
TO_CLIENT.registerPacket(
|
||||||
|
CookieRequest.class,
|
||||||
|
CookieRequest::new,
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x00 )
|
||||||
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
PluginMessage.class,
|
PluginMessage.class,
|
||||||
PluginMessage::new,
|
PluginMessage::new,
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x00 )
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x00 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x01 )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
Kick.class,
|
Kick.class,
|
||||||
Kick::new,
|
Kick::new,
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x01 )
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x01 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x02 )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
FinishConfiguration.class,
|
FinishConfiguration.class,
|
||||||
FinishConfiguration::new,
|
FinishConfiguration::new,
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x02 )
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x02 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x03 )
|
||||||
);
|
);
|
||||||
TO_CLIENT.registerPacket(
|
TO_CLIENT.registerPacket(
|
||||||
KeepAlive.class,
|
KeepAlive.class,
|
||||||
KeepAlive::new,
|
KeepAlive::new,
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x03 )
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x03 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x04 )
|
||||||
|
);
|
||||||
|
TO_CLIENT.registerPacket(
|
||||||
|
StoreCookie.class,
|
||||||
|
StoreCookie::new,
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x09 )
|
||||||
|
);
|
||||||
|
TO_CLIENT.registerPacket(
|
||||||
|
Transfer.class,
|
||||||
|
Transfer::new,
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x0A )
|
||||||
);
|
);
|
||||||
|
|
||||||
TO_SERVER.registerPacket(
|
TO_SERVER.registerPacket(
|
||||||
@ -662,17 +740,20 @@ public enum Protocol
|
|||||||
TO_SERVER.registerPacket(
|
TO_SERVER.registerPacket(
|
||||||
PluginMessage.class,
|
PluginMessage.class,
|
||||||
PluginMessage::new,
|
PluginMessage::new,
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x01 )
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x01 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x02 )
|
||||||
);
|
);
|
||||||
TO_SERVER.registerPacket(
|
TO_SERVER.registerPacket(
|
||||||
FinishConfiguration.class,
|
FinishConfiguration.class,
|
||||||
FinishConfiguration::new,
|
FinishConfiguration::new,
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x02 )
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x02 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x03 )
|
||||||
);
|
);
|
||||||
TO_SERVER.registerPacket(
|
TO_SERVER.registerPacket(
|
||||||
KeepAlive.class,
|
KeepAlive.class,
|
||||||
KeepAlive::new,
|
KeepAlive::new,
|
||||||
map( ProtocolConstants.MINECRAFT_1_20_2, 0x03 )
|
map( ProtocolConstants.MINECRAFT_1_20_2, 0x03 ),
|
||||||
|
map( ProtocolConstants.MINECRAFT_1_20_5, 0x04 )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -45,6 +45,7 @@ public class ProtocolConstants
|
|||||||
public static final int MINECRAFT_1_20 = 763;
|
public static final int MINECRAFT_1_20 = 763;
|
||||||
public static final int MINECRAFT_1_20_2 = 764;
|
public static final int MINECRAFT_1_20_2 = 764;
|
||||||
public static final int MINECRAFT_1_20_3 = 765;
|
public static final int MINECRAFT_1_20_3 = 765;
|
||||||
|
public static final int MINECRAFT_1_20_5 = 1073742000;
|
||||||
public static final List<String> SUPPORTED_VERSIONS;
|
public static final List<String> SUPPORTED_VERSIONS;
|
||||||
public static final List<Integer> SUPPORTED_VERSION_IDS;
|
public static final List<Integer> SUPPORTED_VERSION_IDS;
|
||||||
|
|
||||||
@ -109,7 +110,7 @@ public class ProtocolConstants
|
|||||||
if ( SNAPSHOT_SUPPORT )
|
if ( SNAPSHOT_SUPPORT )
|
||||||
{
|
{
|
||||||
// supportedVersions.add( "1.20.x" );
|
// supportedVersions.add( "1.20.x" );
|
||||||
// supportedVersionIds.add( ProtocolConstants.MINECRAFT_1_20_3 );
|
supportedVersionIds.add( ProtocolConstants.MINECRAFT_1_20_5 );
|
||||||
}
|
}
|
||||||
|
|
||||||
SUPPORTED_VERSIONS = supportedVersions.build();
|
SUPPORTED_VERSIONS = supportedVersions.build();
|
||||||
|
@ -124,9 +124,11 @@ public final class TagUtil
|
|||||||
for ( JsonElement jsonEl : jsonArray )
|
for ( JsonElement jsonEl : jsonArray )
|
||||||
{
|
{
|
||||||
SpecificTag subTag = fromJson( jsonEl );
|
SpecificTag subTag = fromJson( jsonEl );
|
||||||
if ( subTag.tagType() != listType )
|
if ( !( subTag instanceof CompoundTag ) )
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException( "Cannot convert mixed JsonArray to Tag" );
|
CompoundTag wrapper = new CompoundTag();
|
||||||
|
wrapper.add( "", subTag );
|
||||||
|
subTag = wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
tagItems.add( subTag );
|
tagItems.add( subTag );
|
||||||
@ -179,6 +181,20 @@ public final class TagUtil
|
|||||||
JsonArray jsonList = new JsonArray( items.size() );
|
JsonArray jsonList = new JsonArray( items.size() );
|
||||||
for ( SpecificTag subTag : items )
|
for ( SpecificTag subTag : items )
|
||||||
{
|
{
|
||||||
|
if ( subTag instanceof CompoundTag )
|
||||||
|
{
|
||||||
|
CompoundTag compound = (CompoundTag) subTag;
|
||||||
|
if ( compound.size() == 1 )
|
||||||
|
{
|
||||||
|
SpecificTag first = (SpecificTag) compound.get( "" );
|
||||||
|
if ( !first.isError() )
|
||||||
|
{
|
||||||
|
jsonList.add( toJson( first ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
jsonList.add( toJson( subTag ) );
|
jsonList.add( toJson( subTag ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import com.google.common.base.Preconditions;
|
|||||||
import com.mojang.brigadier.Command;
|
import com.mojang.brigadier.Command;
|
||||||
import com.mojang.brigadier.StringReader;
|
import com.mojang.brigadier.StringReader;
|
||||||
import com.mojang.brigadier.arguments.ArgumentType;
|
import com.mojang.brigadier.arguments.ArgumentType;
|
||||||
|
import com.mojang.brigadier.arguments.BoolArgumentType;
|
||||||
import com.mojang.brigadier.arguments.DoubleArgumentType;
|
import com.mojang.brigadier.arguments.DoubleArgumentType;
|
||||||
import com.mojang.brigadier.arguments.FloatArgumentType;
|
import com.mojang.brigadier.arguments.FloatArgumentType;
|
||||||
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
||||||
@ -303,7 +304,7 @@ public class Commands extends DefinedPacket
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
private static class ArgumentRegistry
|
public static class ArgumentRegistry
|
||||||
{
|
{
|
||||||
|
|
||||||
private static final Map<String, ArgumentSerializer> PROVIDERS = new HashMap<>();
|
private static final Map<String, ArgumentSerializer> PROVIDERS = new HashMap<>();
|
||||||
@ -326,18 +327,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
|
@Override
|
||||||
protected Boolean read(ByteBuf buf)
|
protected BoolArgumentType read(ByteBuf buf)
|
||||||
{
|
{
|
||||||
return buf.readBoolean();
|
return BoolArgumentType.bool();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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>()
|
private static final ArgumentSerializer<Byte> BYTE = new ArgumentSerializer<Byte>()
|
||||||
@ -354,7 +366,7 @@ public class Commands extends DefinedPacket
|
|||||||
buf.writeByte( t );
|
buf.writeByte( t );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private static final ArgumentSerializer<FloatArgumentType> FLOAT_RANGE = new ArgumentSerializer<FloatArgumentType>()
|
private static final ProperArgumentSerializer<FloatArgumentType> FLOAT_RANGE = new ProperArgumentSerializer<FloatArgumentType>()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
protected FloatArgumentType read(ByteBuf buf)
|
protected FloatArgumentType read(ByteBuf buf)
|
||||||
@ -382,8 +394,20 @@ public class Commands extends DefinedPacket
|
|||||||
buf.writeFloat( t.getMaximum() );
|
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
|
@Override
|
||||||
protected DoubleArgumentType read(ByteBuf buf)
|
protected DoubleArgumentType read(ByteBuf buf)
|
||||||
@ -411,8 +435,20 @@ public class Commands extends DefinedPacket
|
|||||||
buf.writeDouble( t.getMaximum() );
|
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
|
@Override
|
||||||
protected IntegerArgumentType read(ByteBuf buf)
|
protected IntegerArgumentType read(ByteBuf buf)
|
||||||
@ -440,6 +476,18 @@ public class Commands extends DefinedPacket
|
|||||||
buf.writeInt( t.getMaximum() );
|
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>()
|
private static final ArgumentSerializer<Integer> INTEGER = new ArgumentSerializer<Integer>()
|
||||||
{
|
{
|
||||||
@ -455,7 +503,7 @@ public class Commands extends DefinedPacket
|
|||||||
buf.writeInt( t );
|
buf.writeInt( t );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private static final ArgumentSerializer<LongArgumentType> LONG_RANGE = new ArgumentSerializer<LongArgumentType>()
|
private static final ProperArgumentSerializer<LongArgumentType> LONG_RANGE = new ProperArgumentSerializer<LongArgumentType>()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
protected LongArgumentType read(ByteBuf buf)
|
protected LongArgumentType read(ByteBuf buf)
|
||||||
@ -483,6 +531,18 @@ public class Commands extends DefinedPacket
|
|||||||
buf.writeLong( t.getMaximum() );
|
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>()
|
private static final ProperArgumentSerializer<StringArgumentType> STRING = new ProperArgumentSerializer<StringArgumentType>()
|
||||||
{
|
{
|
||||||
@ -538,11 +598,20 @@ public class Commands extends DefinedPacket
|
|||||||
|
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
register( "brigadier:bool", VOID );
|
register( "brigadier:bool", BOOLEAN );
|
||||||
|
PROPER_PROVIDERS.put( BoolArgumentType.class, BOOLEAN );
|
||||||
|
|
||||||
register( "brigadier:float", FLOAT_RANGE );
|
register( "brigadier:float", FLOAT_RANGE );
|
||||||
|
PROPER_PROVIDERS.put( FloatArgumentType.class, FLOAT_RANGE );
|
||||||
|
|
||||||
register( "brigadier:double", DOUBLE_RANGE );
|
register( "brigadier:double", DOUBLE_RANGE );
|
||||||
|
PROPER_PROVIDERS.put( DoubleArgumentType.class, DOUBLE_RANGE );
|
||||||
|
|
||||||
register( "brigadier:integer", INTEGER_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 );
|
register( "brigadier:string", STRING );
|
||||||
PROPER_PROVIDERS.put( StringArgumentType.class, STRING );
|
PROPER_PROVIDERS.put( StringArgumentType.class, STRING );
|
||||||
@ -811,6 +880,404 @@ public class Commands extends DefinedPacket
|
|||||||
return serializer;
|
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)
|
private static ArgumentType<?> read(ByteBuf buf, int protocolVersion)
|
||||||
{
|
{
|
||||||
Object key;
|
Object key;
|
||||||
@ -937,9 +1404,13 @@ public class Commands extends DefinedPacket
|
|||||||
|
|
||||||
private static String getKey(SuggestionProvider<DummyProvider> provider)
|
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
|
@Data
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
package net.md_5.bungee.protocol.packet;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import net.md_5.bungee.protocol.AbstractPacketHandler;
|
||||||
|
import net.md_5.bungee.protocol.DefinedPacket;
|
||||||
|
import net.md_5.bungee.protocol.ProtocolConstants;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class CookieRequest extends DefinedPacket
|
||||||
|
{
|
||||||
|
|
||||||
|
private String cookie;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
|
||||||
|
{
|
||||||
|
cookie = readString( buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
|
||||||
|
{
|
||||||
|
writeString( cookie, buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(AbstractPacketHandler handler) throws Exception
|
||||||
|
{
|
||||||
|
handler.handle( this );
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package net.md_5.bungee.protocol.packet;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import net.md_5.bungee.protocol.AbstractPacketHandler;
|
||||||
|
import net.md_5.bungee.protocol.DefinedPacket;
|
||||||
|
import net.md_5.bungee.protocol.ProtocolConstants;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class CookieResponse extends DefinedPacket
|
||||||
|
{
|
||||||
|
|
||||||
|
private String cookie;
|
||||||
|
private byte[] data;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
|
||||||
|
{
|
||||||
|
cookie = readString( buf );
|
||||||
|
data = readNullable( DefinedPacket::readArray, buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
|
||||||
|
{
|
||||||
|
writeString( cookie, buf );
|
||||||
|
writeNullable( data, DefinedPacket::writeArray, buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(AbstractPacketHandler handler) throws Exception
|
||||||
|
{
|
||||||
|
handler.handle( this );
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,7 @@ public class EncryptionRequest extends DefinedPacket
|
|||||||
private String serverId;
|
private String serverId;
|
||||||
private byte[] publicKey;
|
private byte[] publicKey;
|
||||||
private byte[] verifyToken;
|
private byte[] verifyToken;
|
||||||
|
private boolean shouldAuthenticate;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
|
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
|
||||||
@ -26,6 +27,10 @@ public class EncryptionRequest extends DefinedPacket
|
|||||||
serverId = readString( buf );
|
serverId = readString( buf );
|
||||||
publicKey = readArray( buf );
|
publicKey = readArray( buf );
|
||||||
verifyToken = readArray( buf );
|
verifyToken = readArray( buf );
|
||||||
|
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_20_5 )
|
||||||
|
{
|
||||||
|
shouldAuthenticate = buf.readBoolean();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -34,6 +39,10 @@ public class EncryptionRequest extends DefinedPacket
|
|||||||
writeString( serverId, buf );
|
writeString( serverId, buf );
|
||||||
writeArray( publicKey, buf );
|
writeArray( publicKey, buf );
|
||||||
writeArray( verifyToken, buf );
|
writeArray( verifyToken, buf );
|
||||||
|
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_20_5 )
|
||||||
|
{
|
||||||
|
buf.writeBoolean( shouldAuthenticate );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -41,6 +41,7 @@ public class Login extends DefinedPacket
|
|||||||
private boolean flat;
|
private boolean flat;
|
||||||
private Location deathLocation;
|
private Location deathLocation;
|
||||||
private int portalCooldown;
|
private int portalCooldown;
|
||||||
|
private boolean secureProfile;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
|
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
|
||||||
@ -154,6 +155,11 @@ public class Login extends DefinedPacket
|
|||||||
{
|
{
|
||||||
portalCooldown = readVarInt( buf );
|
portalCooldown = readVarInt( buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_20_5 )
|
||||||
|
{
|
||||||
|
secureProfile = buf.readBoolean();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -275,6 +281,11 @@ public class Login extends DefinedPacket
|
|||||||
{
|
{
|
||||||
writeVarInt( portalCooldown, buf );
|
writeVarInt( portalCooldown, buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_20_5 )
|
||||||
|
{
|
||||||
|
buf.writeBoolean( secureProfile );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -33,7 +33,7 @@ public class ServerData extends DefinedPacket
|
|||||||
{
|
{
|
||||||
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_4 )
|
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_4 )
|
||||||
{
|
{
|
||||||
icon = DefinedPacket.readArray( buf );
|
icon = readArray( buf );
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
icon = readString( buf );
|
icon = readString( buf );
|
||||||
@ -45,7 +45,7 @@ public class ServerData extends DefinedPacket
|
|||||||
preview = buf.readBoolean();
|
preview = buf.readBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 )
|
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 && protocolVersion < ProtocolConstants.MINECRAFT_1_20_5 )
|
||||||
{
|
{
|
||||||
enforceSecure = buf.readBoolean();
|
enforceSecure = buf.readBoolean();
|
||||||
}
|
}
|
||||||
@ -76,7 +76,7 @@ public class ServerData extends DefinedPacket
|
|||||||
buf.writeBoolean( true );
|
buf.writeBoolean( true );
|
||||||
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_4 )
|
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_4 )
|
||||||
{
|
{
|
||||||
DefinedPacket.writeArray( (byte[]) icon, buf );
|
writeArray( (byte[]) icon, buf );
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
writeString( (String) icon, buf );
|
writeString( (String) icon, buf );
|
||||||
@ -91,7 +91,7 @@ public class ServerData extends DefinedPacket
|
|||||||
buf.writeBoolean( preview );
|
buf.writeBoolean( preview );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 )
|
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 && protocolVersion < ProtocolConstants.MINECRAFT_1_20_5 )
|
||||||
{
|
{
|
||||||
buf.writeBoolean( enforceSecure );
|
buf.writeBoolean( enforceSecure );
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
package net.md_5.bungee.protocol.packet;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import net.md_5.bungee.protocol.AbstractPacketHandler;
|
||||||
|
import net.md_5.bungee.protocol.DefinedPacket;
|
||||||
|
import net.md_5.bungee.protocol.ProtocolConstants;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class StoreCookie extends DefinedPacket
|
||||||
|
{
|
||||||
|
|
||||||
|
private String key;
|
||||||
|
private byte[] data;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
|
||||||
|
{
|
||||||
|
key = readString( buf );
|
||||||
|
data = readArray( buf, 5120 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
|
||||||
|
{
|
||||||
|
writeString( key, buf );
|
||||||
|
writeArray( data, buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(AbstractPacketHandler handler) throws Exception
|
||||||
|
{
|
||||||
|
handler.handle( this );
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package net.md_5.bungee.protocol.packet;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import net.md_5.bungee.protocol.AbstractPacketHandler;
|
||||||
|
import net.md_5.bungee.protocol.DefinedPacket;
|
||||||
|
import net.md_5.bungee.protocol.ProtocolConstants;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class Transfer extends DefinedPacket
|
||||||
|
{
|
||||||
|
|
||||||
|
private String host;
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
|
||||||
|
{
|
||||||
|
host = readString( buf );
|
||||||
|
port = readVarInt( buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
|
||||||
|
{
|
||||||
|
writeString( host, buf );
|
||||||
|
writeVarInt( port, buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(AbstractPacketHandler handler) throws Exception
|
||||||
|
{
|
||||||
|
handler.handle( this );
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package net.md_5.bungee.protocol;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import se.llbit.nbt.SpecificTag;
|
||||||
|
|
||||||
|
public class TagUtilTest
|
||||||
|
{
|
||||||
|
|
||||||
|
private static final Gson GSON = new Gson();
|
||||||
|
|
||||||
|
private static void testDissembleReassemble(String json)
|
||||||
|
{
|
||||||
|
JsonElement parsedJson = GSON.fromJson( json, JsonElement.class );
|
||||||
|
SpecificTag nbt = TagUtil.fromJson( parsedJson );
|
||||||
|
JsonElement convertedElement = TagUtil.toJson( nbt );
|
||||||
|
|
||||||
|
String convertedJson = GSON.toJson( convertedElement );
|
||||||
|
assertEquals( json, convertedJson );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStringLiteral()
|
||||||
|
{
|
||||||
|
testDissembleReassemble( "{\"text\":\"\",\"extra\":[\"hello\",{\"text\":\"there\",\"color\":\"#ff0000\"},{\"text\":\"friend\",\"font\":\"minecraft:default\"}]}" );
|
||||||
|
}
|
||||||
|
}
|
@ -4,15 +4,14 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-proxy</artifactId>
|
<artifactId>bungeecord-proxy</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-Proxy</name>
|
<name>BungeeCord-Proxy</name>
|
||||||
@ -52,37 +51,37 @@
|
|||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-api</artifactId>
|
<artifactId>bungeecord-api</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-log</artifactId>
|
<artifactId>bungeecord-log</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-native</artifactId>
|
<artifactId>bungeecord-native</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-protocol</artifactId>
|
<artifactId>bungeecord-protocol</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-query</artifactId>
|
<artifactId>bungeecord-query</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-slf4j</artifactId>
|
<artifactId>bungeecord-slf4j</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
@ -96,26 +95,26 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.mysql</groupId>
|
<groupId>com.mysql</groupId>
|
||||||
<artifactId>mysql-connector-j</artifactId>
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
<version>8.1.0</version>
|
<version>8.2.0</version>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- add these back in as they are not exposed by the API -->
|
<!-- add these back in as they are not exposed by the API -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.maven</groupId>
|
<groupId>org.apache.maven</groupId>
|
||||||
<artifactId>maven-resolver-provider</artifactId>
|
<artifactId>maven-resolver-provider</artifactId>
|
||||||
<version>3.8.5</version>
|
<version>3.9.6</version>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.maven.resolver</groupId>
|
<groupId>org.apache.maven.resolver</groupId>
|
||||||
<artifactId>maven-resolver-connector-basic</artifactId>
|
<artifactId>maven-resolver-connector-basic</artifactId>
|
||||||
<version>1.7.3</version>
|
<version>1.9.18</version>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.maven.resolver</groupId>
|
<groupId>org.apache.maven.resolver</groupId>
|
||||||
<artifactId>maven-resolver-transport-http</artifactId>
|
<artifactId>maven-resolver-transport-http</artifactId>
|
||||||
<version>1.7.3</version>
|
<version>1.9.18</version>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@ -58,6 +58,7 @@ import net.md_5.bungee.api.ReconnectHandler;
|
|||||||
import net.md_5.bungee.api.ServerPing;
|
import net.md_5.bungee.api.ServerPing;
|
||||||
import net.md_5.bungee.api.Title;
|
import net.md_5.bungee.api.Title;
|
||||||
import net.md_5.bungee.api.chat.BaseComponent;
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
|
import net.md_5.bungee.api.chat.ComponentStyle;
|
||||||
import net.md_5.bungee.api.chat.KeybindComponent;
|
import net.md_5.bungee.api.chat.KeybindComponent;
|
||||||
import net.md_5.bungee.api.chat.ScoreComponent;
|
import net.md_5.bungee.api.chat.ScoreComponent;
|
||||||
import net.md_5.bungee.api.chat.SelectorComponent;
|
import net.md_5.bungee.api.chat.SelectorComponent;
|
||||||
@ -70,6 +71,7 @@ import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|||||||
import net.md_5.bungee.api.plugin.Plugin;
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
import net.md_5.bungee.api.plugin.PluginManager;
|
import net.md_5.bungee.api.plugin.PluginManager;
|
||||||
import net.md_5.bungee.chat.ComponentSerializer;
|
import net.md_5.bungee.chat.ComponentSerializer;
|
||||||
|
import net.md_5.bungee.chat.ComponentStyleSerializer;
|
||||||
import net.md_5.bungee.chat.KeybindComponentSerializer;
|
import net.md_5.bungee.chat.KeybindComponentSerializer;
|
||||||
import net.md_5.bungee.chat.ScoreComponentSerializer;
|
import net.md_5.bungee.chat.ScoreComponentSerializer;
|
||||||
import net.md_5.bungee.chat.SelectorComponentSerializer;
|
import net.md_5.bungee.chat.SelectorComponentSerializer;
|
||||||
@ -89,7 +91,6 @@ import net.md_5.bungee.forge.ForgeConstants;
|
|||||||
import net.md_5.bungee.log.BungeeLogger;
|
import net.md_5.bungee.log.BungeeLogger;
|
||||||
import net.md_5.bungee.log.LoggingForwardHandler;
|
import net.md_5.bungee.log.LoggingForwardHandler;
|
||||||
import net.md_5.bungee.log.LoggingOutputStream;
|
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.netty.PipelineUtils;
|
||||||
import net.md_5.bungee.protocol.DefinedPacket;
|
import net.md_5.bungee.protocol.DefinedPacket;
|
||||||
import net.md_5.bungee.protocol.ProtocolConstants;
|
import net.md_5.bungee.protocol.ProtocolConstants;
|
||||||
@ -169,11 +170,11 @@ public class BungeeCord extends ProxyServer
|
|||||||
.registerTypeAdapter( KeybindComponent.class, new KeybindComponentSerializer() )
|
.registerTypeAdapter( KeybindComponent.class, new KeybindComponentSerializer() )
|
||||||
.registerTypeAdapter( ScoreComponent.class, new ScoreComponentSerializer() )
|
.registerTypeAdapter( ScoreComponent.class, new ScoreComponentSerializer() )
|
||||||
.registerTypeAdapter( SelectorComponent.class, new SelectorComponentSerializer() )
|
.registerTypeAdapter( SelectorComponent.class, new SelectorComponentSerializer() )
|
||||||
|
.registerTypeAdapter( ComponentStyle.class, new ComponentStyleSerializer() )
|
||||||
.registerTypeAdapter( ServerPing.PlayerInfo.class, new PlayerInfoSerializer() )
|
.registerTypeAdapter( ServerPing.PlayerInfo.class, new PlayerInfoSerializer() )
|
||||||
.registerTypeAdapter( Favicon.class, Favicon.getFaviconTypeAdapter() ).create();
|
.registerTypeAdapter( Favicon.class, Favicon.getFaviconTypeAdapter() ).create();
|
||||||
@Getter
|
@Getter
|
||||||
private ConnectionThrottle connectionThrottle;
|
private ConnectionThrottle connectionThrottle;
|
||||||
private final ModuleManager moduleManager = new ModuleManager();
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// TODO: Proper fallback when we interface the manager
|
// TODO: Proper fallback when we interface the manager
|
||||||
@ -271,10 +272,6 @@ public class BungeeCord extends ProxyServer
|
|||||||
|
|
||||||
eventLoops = PipelineUtils.newEventLoopGroup( 0, new ThreadFactoryBuilder().setNameFormat( "Netty IO Thread #%1$d" ).build() );
|
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();
|
pluginsFolder.mkdir();
|
||||||
pluginManager.detectPlugins( pluginsFolder );
|
pluginManager.detectPlugins( pluginsFolder );
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ import java.text.SimpleDateFormat;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import joptsimple.OptionParser;
|
import joptsimple.OptionParser;
|
||||||
import joptsimple.OptionSet;
|
import joptsimple.OptionSet;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
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( "*** Warning, this build is outdated ***" );
|
||||||
System.err.println( "*** Please download a new build from http://ci.md-5.net/job/BungeeCord ***" );
|
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( "*** You will get NO support regarding this build ***" );
|
||||||
System.err.println( "*** Server will start in 10 seconds ***" );
|
|
||||||
Thread.sleep( TimeUnit.SECONDS.toMillis( 10 ) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,8 @@ public class EncryptionUtil
|
|||||||
byte[] pubKey = keys.getPublic().getEncoded();
|
byte[] pubKey = keys.getPublic().getEncoded();
|
||||||
byte[] verify = new byte[ 4 ];
|
byte[] verify = new byte[ 4 ];
|
||||||
random.nextBytes( verify );
|
random.nextBytes( verify );
|
||||||
return new EncryptionRequest( hash, pubKey, verify );
|
// always auth for now
|
||||||
|
return new EncryptionRequest( hash, pubKey, verify, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean check(PlayerPublicKey publicKey, UUID uuid) throws GeneralSecurityException
|
public static boolean check(PlayerPublicKey publicKey, UUID uuid) throws GeneralSecurityException
|
||||||
|
@ -10,6 +10,7 @@ import java.util.Locale;
|
|||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.logging.Level;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
import net.md_5.bungee.api.ChatColor;
|
||||||
@ -39,6 +40,8 @@ import net.md_5.bungee.protocol.Either;
|
|||||||
import net.md_5.bungee.protocol.PacketWrapper;
|
import net.md_5.bungee.protocol.PacketWrapper;
|
||||||
import net.md_5.bungee.protocol.Protocol;
|
import net.md_5.bungee.protocol.Protocol;
|
||||||
import net.md_5.bungee.protocol.ProtocolConstants;
|
import net.md_5.bungee.protocol.ProtocolConstants;
|
||||||
|
import net.md_5.bungee.protocol.packet.CookieRequest;
|
||||||
|
import net.md_5.bungee.protocol.packet.CookieResponse;
|
||||||
import net.md_5.bungee.protocol.packet.EncryptionRequest;
|
import net.md_5.bungee.protocol.packet.EncryptionRequest;
|
||||||
import net.md_5.bungee.protocol.packet.EntityStatus;
|
import net.md_5.bungee.protocol.packet.EntityStatus;
|
||||||
import net.md_5.bungee.protocol.packet.GameState;
|
import net.md_5.bungee.protocol.packet.GameState;
|
||||||
@ -187,6 +190,12 @@ public class ServerConnector extends PacketHandler
|
|||||||
ch.setCompressionThreshold( setCompression.getThreshold() );
|
ch.setCompressionThreshold( setCompression.getThreshold() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(CookieRequest cookieRequest) throws Exception
|
||||||
|
{
|
||||||
|
user.retrieveCookie( cookieRequest.getCookie() ).thenAccept( (cookie) -> ch.write( new CookieResponse( cookieRequest.getCookie(), cookie ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(Login login) throws Exception
|
public void handle(Login login) throws Exception
|
||||||
{
|
{
|
||||||
@ -243,7 +252,7 @@ public class ServerConnector extends PacketHandler
|
|||||||
// Set tab list size, TODO: what shall we do about packet mutability
|
// Set tab list size, TODO: what shall we do about packet mutability
|
||||||
Login modLogin = new Login( login.getEntityId(), login.isHardcore(), login.getGameMode(), login.getPreviousGameMode(), login.getWorldNames(), login.getDimensions(), login.getDimension(), login.getWorldName(), login.getSeed(), login.getDifficulty(),
|
Login modLogin = new Login( login.getEntityId(), login.isHardcore(), login.getGameMode(), login.getPreviousGameMode(), login.getWorldNames(), login.getDimensions(), login.getDimension(), login.getWorldName(), login.getSeed(), login.getDifficulty(),
|
||||||
(byte) user.getPendingConnection().getListener().getTabListSize(), login.getLevelType(), login.getViewDistance(), login.getSimulationDistance(), login.isReducedDebugInfo(), login.isNormalRespawn(), login.isLimitedCrafting(), login.isDebug(), login.isFlat(), login.getDeathLocation(),
|
(byte) user.getPendingConnection().getListener().getTabListSize(), login.getLevelType(), login.getViewDistance(), login.getSimulationDistance(), login.isReducedDebugInfo(), login.isNormalRespawn(), login.isLimitedCrafting(), login.isDebug(), login.isFlat(), login.getDeathLocation(),
|
||||||
login.getPortalCooldown() );
|
login.getPortalCooldown(), login.isSecureProfile() );
|
||||||
|
|
||||||
user.unsafe().sendPacket( modLogin );
|
user.unsafe().sendPacket( modLogin );
|
||||||
|
|
||||||
@ -339,6 +348,14 @@ public class ServerConnector extends PacketHandler
|
|||||||
|
|
||||||
private void cutThrough(ServerConnection server)
|
private void cutThrough(ServerConnection server)
|
||||||
{
|
{
|
||||||
|
// TODO: Fix this?
|
||||||
|
if ( !user.isActive() )
|
||||||
|
{
|
||||||
|
server.disconnect( "Quitting" );
|
||||||
|
bungee.getLogger().log( Level.WARNING, "[{0}] No client connected for pending server!", user );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ( user.getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_20_2 )
|
if ( user.getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_20_2 )
|
||||||
{
|
{
|
||||||
if ( user.getServer() != null )
|
if ( user.getServer() != null )
|
||||||
@ -360,15 +377,6 @@ public class ServerConnector extends PacketHandler
|
|||||||
user.getServer().disconnect( "Quitting" );
|
user.getServer().disconnect( "Quitting" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Fix this?
|
|
||||||
if ( !user.isActive() )
|
|
||||||
{
|
|
||||||
server.disconnect( "Quitting" );
|
|
||||||
// Silly server admins see stack trace and die
|
|
||||||
bungee.getLogger().warning( "No client connected for pending server!" );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add to new server
|
// Add to new server
|
||||||
// TODO: Move this to the connected() method of DownstreamBridge
|
// TODO: Move this to the connected() method of DownstreamBridge
|
||||||
target.addPlayer( user );
|
target.addPlayer( user );
|
||||||
|
@ -20,6 +20,7 @@ import java.util.Map;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@ -60,7 +61,9 @@ import net.md_5.bungee.protocol.packet.Kick;
|
|||||||
import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter;
|
import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter;
|
||||||
import net.md_5.bungee.protocol.packet.PluginMessage;
|
import net.md_5.bungee.protocol.packet.PluginMessage;
|
||||||
import net.md_5.bungee.protocol.packet.SetCompression;
|
import net.md_5.bungee.protocol.packet.SetCompression;
|
||||||
|
import net.md_5.bungee.protocol.packet.StoreCookie;
|
||||||
import net.md_5.bungee.protocol.packet.SystemChat;
|
import net.md_5.bungee.protocol.packet.SystemChat;
|
||||||
|
import net.md_5.bungee.protocol.packet.Transfer;
|
||||||
import net.md_5.bungee.tab.ServerUnique;
|
import net.md_5.bungee.tab.ServerUnique;
|
||||||
import net.md_5.bungee.tab.TabList;
|
import net.md_5.bungee.tab.TabList;
|
||||||
import net.md_5.bungee.util.CaseInsensitiveSet;
|
import net.md_5.bungee.util.CaseInsensitiveSet;
|
||||||
@ -771,4 +774,26 @@ public final class UserConnection implements ProxiedPlayer
|
|||||||
{
|
{
|
||||||
return serverSentScoreboard;
|
return serverSentScoreboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<byte[]> retrieveCookie(String cookie)
|
||||||
|
{
|
||||||
|
return pendingConnection.retrieveCookie( cookie );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void storeCookie(String cookie, byte[] data)
|
||||||
|
{
|
||||||
|
Preconditions.checkState( getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_20_5, "Cookies are only supported in 1.20.5 and above" );
|
||||||
|
|
||||||
|
unsafe().sendPacket( new StoreCookie( cookie, data ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void transfer(String host, int port)
|
||||||
|
{
|
||||||
|
Preconditions.checkState( getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_20_5, "Transfers are only supported in 1.20.5 and above" );
|
||||||
|
|
||||||
|
unsafe().sendPacket( new Transfer( host, port ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,7 @@ public class Configuration implements ProxyConfig
|
|||||||
private int compressionThreshold = 256;
|
private int compressionThreshold = 256;
|
||||||
private boolean preventProxyConnections;
|
private boolean preventProxyConnections;
|
||||||
private boolean forgeSupport;
|
private boolean forgeSupport;
|
||||||
|
private boolean rejectTransfers;
|
||||||
|
|
||||||
public void load()
|
public void load()
|
||||||
{
|
{
|
||||||
@ -103,6 +104,7 @@ public class Configuration implements ProxyConfig
|
|||||||
compressionThreshold = adapter.getInt( "network_compression_threshold", compressionThreshold );
|
compressionThreshold = adapter.getInt( "network_compression_threshold", compressionThreshold );
|
||||||
preventProxyConnections = adapter.getBoolean( "prevent_proxy_connections", preventProxyConnections );
|
preventProxyConnections = adapter.getBoolean( "prevent_proxy_connections", preventProxyConnections );
|
||||||
forgeSupport = adapter.getBoolean( "forge_support", forgeSupport );
|
forgeSupport = adapter.getBoolean( "forge_support", forgeSupport );
|
||||||
|
rejectTransfers = adapter.getBoolean( "reject_transfers", rejectTransfers );
|
||||||
|
|
||||||
disabledCommands = new CaseInsensitiveSet( (Collection<String>) adapter.getList( "disabled_commands", Arrays.asList( "disabledcommandhere" ) ) );
|
disabledCommands = new CaseInsensitiveSet( (Collection<String>) adapter.getList( "disabled_commands", Arrays.asList( "disabledcommandhere" ) ) );
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import com.google.common.collect.Lists;
|
|||||||
import com.google.common.io.ByteArrayDataOutput;
|
import com.google.common.io.ByteArrayDataOutput;
|
||||||
import com.google.common.io.ByteStreams;
|
import com.google.common.io.ByteStreams;
|
||||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||||
|
import com.mojang.brigadier.builder.ArgumentBuilder;
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
|
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
|
||||||
import com.mojang.brigadier.context.StringRange;
|
import com.mojang.brigadier.context.StringRange;
|
||||||
@ -19,9 +20,12 @@ import io.netty.channel.unix.DomainSocketAddress;
|
|||||||
import java.io.DataInput;
|
import java.io.DataInput;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.IdentityHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import net.md_5.bungee.ServerConnection;
|
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.config.ServerInfo;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
import net.md_5.bungee.api.connection.Server;
|
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.PluginMessageEvent;
|
||||||
import net.md_5.bungee.api.event.ServerConnectEvent;
|
import net.md_5.bungee.api.event.ServerConnectEvent;
|
||||||
import net.md_5.bungee.api.event.ServerDisconnectEvent;
|
import net.md_5.bungee.api.event.ServerDisconnectEvent;
|
||||||
@ -312,7 +317,7 @@ public class DownstreamBridge extends PacketHandler
|
|||||||
Preconditions.checkState( !serverBrand.contains( bungee.getName() ), "Cannot connect proxy to itself!" );
|
Preconditions.checkState( !serverBrand.contains( bungee.getName() ), "Cannot connect proxy to itself!" );
|
||||||
|
|
||||||
brand = ByteBufAllocator.DEFAULT.heapBuffer();
|
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 ) );
|
pluginMessage.setData( DefinedPacket.toArray( brand ) );
|
||||||
brand.release();
|
brand.release();
|
||||||
// changes in the packet are ignored so we need to send it manually
|
// changes in the packet are ignored so we need to send it manually
|
||||||
@ -745,6 +750,11 @@ public class DownstreamBridge extends PacketHandler
|
|||||||
{
|
{
|
||||||
boolean modified = false;
|
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() )
|
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 ) )
|
if ( !bungee.getDisabledCommands().contains( command.getKey() ) && commands.getRoot().getChild( command.getKey() ) == null && command.getValue().hasPermission( con ) )
|
||||||
@ -761,11 +771,65 @@ public class DownstreamBridge extends PacketHandler
|
|||||||
|
|
||||||
if ( modified )
|
if ( modified )
|
||||||
{
|
{
|
||||||
|
commands.setRoot( (com.mojang.brigadier.tree.RootCommandNode) filterCommandNode( commands.getRoot(), new IdentityHashMap<>() ) );
|
||||||
con.unsafe().sendPacket( commands );
|
con.unsafe().sendPacket( commands );
|
||||||
throw CancelSendSignal.INSTANCE;
|
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
|
@Override
|
||||||
public void handle(ServerData serverData) throws Exception
|
public void handle(ServerData serverData) throws Exception
|
||||||
{
|
{
|
||||||
|
@ -11,12 +11,19 @@ import java.security.GeneralSecurityException;
|
|||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.Queue;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.ToString;
|
||||||
import net.md_5.bungee.BungeeCord;
|
import net.md_5.bungee.BungeeCord;
|
||||||
import net.md_5.bungee.BungeeServerInfo;
|
import net.md_5.bungee.BungeeServerInfo;
|
||||||
import net.md_5.bungee.EncryptionUtil;
|
import net.md_5.bungee.EncryptionUtil;
|
||||||
@ -51,6 +58,8 @@ import net.md_5.bungee.protocol.PacketWrapper;
|
|||||||
import net.md_5.bungee.protocol.PlayerPublicKey;
|
import net.md_5.bungee.protocol.PlayerPublicKey;
|
||||||
import net.md_5.bungee.protocol.Protocol;
|
import net.md_5.bungee.protocol.Protocol;
|
||||||
import net.md_5.bungee.protocol.ProtocolConstants;
|
import net.md_5.bungee.protocol.ProtocolConstants;
|
||||||
|
import net.md_5.bungee.protocol.packet.CookieRequest;
|
||||||
|
import net.md_5.bungee.protocol.packet.CookieResponse;
|
||||||
import net.md_5.bungee.protocol.packet.EncryptionRequest;
|
import net.md_5.bungee.protocol.packet.EncryptionRequest;
|
||||||
import net.md_5.bungee.protocol.packet.EncryptionResponse;
|
import net.md_5.bungee.protocol.packet.EncryptionResponse;
|
||||||
import net.md_5.bungee.protocol.packet.Handshake;
|
import net.md_5.bungee.protocol.packet.Handshake;
|
||||||
@ -86,6 +95,19 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
@Getter
|
@Getter
|
||||||
private final Set<String> registeredChannels = new HashSet<>();
|
private final Set<String> registeredChannels = new HashSet<>();
|
||||||
private State thisState = State.HANDSHAKE;
|
private State thisState = State.HANDSHAKE;
|
||||||
|
private final Queue<CookieFuture> requestedCookies = new LinkedList<>();
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ToString
|
||||||
|
@EqualsAndHashCode
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class CookieFuture
|
||||||
|
{
|
||||||
|
|
||||||
|
private String cookie;
|
||||||
|
private CompletableFuture<byte[]> future;
|
||||||
|
}
|
||||||
|
|
||||||
private final Unsafe unsafe = new Unsafe()
|
private final Unsafe unsafe = new Unsafe()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
@ -109,8 +131,19 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
private boolean legacy;
|
private boolean legacy;
|
||||||
@Getter
|
@Getter
|
||||||
private String extraDataInHandshake = "";
|
private String extraDataInHandshake = "";
|
||||||
|
@Getter
|
||||||
|
private boolean transferred;
|
||||||
private UserConnection userCon;
|
private UserConnection userCon;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private boolean duplication = false;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private String realName = null;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private UUID realId = null;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldHandle(PacketWrapper packet) throws Exception
|
public boolean shouldHandle(PacketWrapper packet) throws Exception
|
||||||
{
|
{
|
||||||
@ -349,6 +382,8 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
ch.setProtocol( Protocol.STATUS );
|
ch.setProtocol( Protocol.STATUS );
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
|
case 3:
|
||||||
|
transferred = handshake.getRequestedProtocol() == 3;
|
||||||
// Login
|
// Login
|
||||||
bungee.getLogger().log( Level.INFO, "{0} has connected", this );
|
bungee.getLogger().log( Level.INFO, "{0} has connected", this );
|
||||||
thisState = State.USERNAME;
|
thisState = State.USERNAME;
|
||||||
@ -365,6 +400,12 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( transferred && bungee.config.isRejectTransfers() )
|
||||||
|
{
|
||||||
|
disconnect( bungee.getTranslation( "reject_transfer" ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new QuietException( "Cannot request protocol " + handshake.getRequestedProtocol() );
|
throw new QuietException( "Cannot request protocol " + handshake.getRequestedProtocol() );
|
||||||
@ -408,6 +449,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.loginRequest = loginRequest;
|
this.loginRequest = loginRequest;
|
||||||
|
setName( realName = loginRequest.getData() );
|
||||||
|
|
||||||
int limit = BungeeCord.getInstance().config.getPlayerLimit();
|
int limit = BungeeCord.getInstance().config.getPlayerLimit();
|
||||||
if ( limit > 0 && bungee.getOnlineCount() >= limit )
|
if ( limit > 0 && bungee.getOnlineCount() >= limit )
|
||||||
@ -416,14 +458,6 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
return;
|
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>()
|
Callback<PreLoginEvent> callback = new Callback<PreLoginEvent>()
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -440,6 +474,16 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
{
|
{
|
||||||
return;
|
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 )
|
if ( onlineMode )
|
||||||
{
|
{
|
||||||
thisState = State.ENCRYPT;
|
thisState = State.ENCRYPT;
|
||||||
@ -494,8 +538,8 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
if ( obj != null && obj.getId() != null )
|
if ( obj != null && obj.getId() != null )
|
||||||
{
|
{
|
||||||
loginProfile = obj;
|
loginProfile = obj;
|
||||||
name = obj.getName();
|
setName( realName = obj.getName() );
|
||||||
uniqueId = Util.getUUID( obj.getId() );
|
uniqueId = realId = Util.getUUID( obj.getId() );
|
||||||
finish();
|
finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -513,10 +557,25 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
|
|
||||||
private void finish()
|
private void finish()
|
||||||
{
|
{
|
||||||
offlineId = UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + getName() ).getBytes( StandardCharsets.UTF_8 ) );
|
if ( uniqueId == null ) // offline mode and no plugin used setUniqueId()
|
||||||
if ( uniqueId == null )
|
|
||||||
{
|
{
|
||||||
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() )
|
if ( BungeeCord.getInstance().config.isEnforceSecureProfile() )
|
||||||
@ -621,6 +680,13 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
|
|
||||||
ch.getHandle().pipeline().get( HandlerBoss.class ).setHandler( new UpstreamBridge( bungee, userCon ) );
|
ch.getHandle().pipeline().get( HandlerBoss.class ).setHandler( new UpstreamBridge( bungee, userCon ) );
|
||||||
bungee.getPluginManager().callEvent( new PostLoginEvent( userCon ) );
|
bungee.getPluginManager().callEvent( new PostLoginEvent( userCon ) );
|
||||||
|
|
||||||
|
// #3612: Don't progress further if disconnected during event
|
||||||
|
if ( ch.isClosed() )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ServerInfo server;
|
ServerInfo server;
|
||||||
if ( bungee.getReconnectHandler() != null )
|
if ( bungee.getReconnectHandler() != null )
|
||||||
{
|
{
|
||||||
@ -643,6 +709,34 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
disconnect( "Unexpected custom LoginPayloadResponse" );
|
disconnect( "Unexpected custom LoginPayloadResponse" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(CookieResponse cookieResponse)
|
||||||
|
{
|
||||||
|
// be careful, backend server could also make the client send a cookie response
|
||||||
|
CookieFuture future;
|
||||||
|
synchronized ( requestedCookies )
|
||||||
|
{
|
||||||
|
future = requestedCookies.peek();
|
||||||
|
if ( future != null )
|
||||||
|
{
|
||||||
|
if ( future.cookie.equals( cookieResponse.getCookie() ) )
|
||||||
|
{
|
||||||
|
Preconditions.checkState( future == requestedCookies.poll(), "requestedCookies queue mismatch" );
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
future = null; // leave for handling by backend
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( future != null )
|
||||||
|
{
|
||||||
|
future.getFuture().complete( cookieResponse.getData() );
|
||||||
|
|
||||||
|
throw CancelSendSignal.INSTANCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disconnect(String reason)
|
public void disconnect(String reason)
|
||||||
{
|
{
|
||||||
@ -679,6 +773,59 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
return ( name != null ) ? name : ( loginRequest == null ) ? null : loginRequest.getData();
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateOfflineId()
|
||||||
|
{
|
||||||
|
offlineId = UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + getName() ).getBytes( StandardCharsets.UTF_8 ) );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getVersion()
|
public int getVersion()
|
||||||
{
|
{
|
||||||
@ -775,4 +922,26 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
brandMessage = input;
|
brandMessage = input;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<byte[]> retrieveCookie(String cookie)
|
||||||
|
{
|
||||||
|
Preconditions.checkState( getVersion() >= ProtocolConstants.MINECRAFT_1_20_5, "Cookies are only supported in 1.20.5 and above" );
|
||||||
|
Preconditions.checkState( loginRequest != null, "Cannot retrieve cookies for status or legacy connections" );
|
||||||
|
|
||||||
|
if ( cookie.indexOf( ':' ) == -1 )
|
||||||
|
{
|
||||||
|
// if we request an invalid resource location (no prefix) the client will respond with "minecraft:" prefix
|
||||||
|
cookie = "minecraft:" + cookie;
|
||||||
|
}
|
||||||
|
|
||||||
|
CompletableFuture<byte[]> future = new CompletableFuture<>();
|
||||||
|
synchronized ( requestedCookies )
|
||||||
|
{
|
||||||
|
requestedCookies.add( new CookieFuture( cookie, future ) );
|
||||||
|
}
|
||||||
|
unsafe.sendPacket( new CookieRequest( cookie ) );
|
||||||
|
|
||||||
|
return future;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import com.mojang.brigadier.suggestion.Suggestion;
|
|||||||
import com.mojang.brigadier.suggestion.Suggestions;
|
import com.mojang.brigadier.suggestion.Suggestions;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import net.md_5.bungee.BungeeCord;
|
import net.md_5.bungee.BungeeCord;
|
||||||
@ -21,6 +20,7 @@ import net.md_5.bungee.api.event.PlayerDisconnectEvent;
|
|||||||
import net.md_5.bungee.api.event.PluginMessageEvent;
|
import net.md_5.bungee.api.event.PluginMessageEvent;
|
||||||
import net.md_5.bungee.api.event.SettingsChangedEvent;
|
import net.md_5.bungee.api.event.SettingsChangedEvent;
|
||||||
import net.md_5.bungee.api.event.TabCompleteEvent;
|
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.entitymap.EntityMap;
|
||||||
import net.md_5.bungee.forge.ForgeConstants;
|
import net.md_5.bungee.forge.ForgeConstants;
|
||||||
import net.md_5.bungee.netty.ChannelWrapper;
|
import net.md_5.bungee.netty.ChannelWrapper;
|
||||||
@ -32,6 +32,7 @@ import net.md_5.bungee.protocol.packet.Chat;
|
|||||||
import net.md_5.bungee.protocol.packet.ClientChat;
|
import net.md_5.bungee.protocol.packet.ClientChat;
|
||||||
import net.md_5.bungee.protocol.packet.ClientCommand;
|
import net.md_5.bungee.protocol.packet.ClientCommand;
|
||||||
import net.md_5.bungee.protocol.packet.ClientSettings;
|
import net.md_5.bungee.protocol.packet.ClientSettings;
|
||||||
|
import net.md_5.bungee.protocol.packet.CookieResponse;
|
||||||
import net.md_5.bungee.protocol.packet.FinishConfiguration;
|
import net.md_5.bungee.protocol.packet.FinishConfiguration;
|
||||||
import net.md_5.bungee.protocol.packet.KeepAlive;
|
import net.md_5.bungee.protocol.packet.KeepAlive;
|
||||||
import net.md_5.bungee.protocol.packet.LoginAcknowledged;
|
import net.md_5.bungee.protocol.packet.LoginAcknowledged;
|
||||||
@ -128,7 +129,7 @@ public class UpstreamBridge extends PacketHandler
|
|||||||
@Override
|
@Override
|
||||||
public boolean shouldHandle(PacketWrapper packet) throws Exception
|
public boolean shouldHandle(PacketWrapper packet) throws Exception
|
||||||
{
|
{
|
||||||
return con.getServer() != null || packet.packet instanceof PluginMessage;
|
return con.getServer() != null || packet.packet instanceof PluginMessage || packet.packet instanceof CookieResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -234,32 +235,42 @@ public class UpstreamBridge extends PacketHandler
|
|||||||
TabCompleteEvent tabCompleteEvent = new TabCompleteEvent( con, con.getServer(), tabComplete.getCursor(), suggestions );
|
TabCompleteEvent tabCompleteEvent = new TabCompleteEvent( con, con.getServer(), tabComplete.getCursor(), suggestions );
|
||||||
bungee.getPluginManager().callEvent( tabCompleteEvent );
|
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;
|
throw CancelSendSignal.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> results = tabCompleteEvent.getSuggestions();
|
Suggestions brigadierResults = tabCompleteRequestEvent.getSuggestions();
|
||||||
if ( !results.isEmpty() )
|
|
||||||
|
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 )
|
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 ) );
|
con.unsafe().sendPacket( new TabCompleteResponse( results ) );
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
int start = tabComplete.getCursor().lastIndexOf( ' ' ) + 1;
|
con.unsafe().sendPacket( new TabCompleteResponse( tabComplete.getTransactionId(), brigadierResults ) );
|
||||||
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 ) ) );
|
|
||||||
}
|
}
|
||||||
throw CancelSendSignal.INSTANCE;
|
throw CancelSendSignal.INSTANCE;
|
||||||
}
|
}
|
||||||
@ -363,6 +374,12 @@ public class UpstreamBridge extends PacketHandler
|
|||||||
con.sendQueuedPackets();
|
con.sendQueuedPackets();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(CookieResponse cookieResponse) throws Exception
|
||||||
|
{
|
||||||
|
con.getPendingConnection().handle( cookieResponse );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
|
@ -86,6 +86,8 @@ public abstract class EntityMap
|
|||||||
return EntityMap_1_16_2.INSTANCE_1_20_2;
|
return EntityMap_1_16_2.INSTANCE_1_20_2;
|
||||||
case ProtocolConstants.MINECRAFT_1_20_3:
|
case ProtocolConstants.MINECRAFT_1_20_3:
|
||||||
return EntityMap_1_16_2.INSTANCE_1_20_3;
|
return EntityMap_1_16_2.INSTANCE_1_20_3;
|
||||||
|
case ProtocolConstants.MINECRAFT_1_20_5:
|
||||||
|
return EntityMap_1_16_2.INSTANCE_1_20_5;
|
||||||
}
|
}
|
||||||
throw new RuntimeException( "Version " + version + " has no entity map" );
|
throw new RuntimeException( "Version " + version + " has no entity map" );
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ class EntityMap_1_16_2 extends EntityMap
|
|||||||
static final EntityMap_1_16_2 INSTANCE_1_19_4 = new EntityMap_1_16_2( 0x03, 0x30 );
|
static final EntityMap_1_16_2 INSTANCE_1_19_4 = new EntityMap_1_16_2( 0x03, 0x30 );
|
||||||
static final EntityMap_1_16_2 INSTANCE_1_20_2 = new EntityMap_1_16_2( -1, 0x33 );
|
static final EntityMap_1_16_2 INSTANCE_1_20_2 = new EntityMap_1_16_2( -1, 0x33 );
|
||||||
static final EntityMap_1_16_2 INSTANCE_1_20_3 = new EntityMap_1_16_2( -1, 0x34 );
|
static final EntityMap_1_16_2 INSTANCE_1_20_3 = new EntityMap_1_16_2( -1, 0x34 );
|
||||||
|
static final EntityMap_1_16_2 INSTANCE_1_20_5 = new EntityMap_1_16_2( -1, 0x36 );
|
||||||
//
|
//
|
||||||
private final int spawnPlayerId;
|
private final int spawnPlayerId;
|
||||||
private final int spectateId;
|
private final int spectateId;
|
||||||
|
@ -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 );
|
|
||||||
}
|
|
||||||
}
|
|
@ -40,3 +40,4 @@ command_perms_permission=\u00a79- {0}
|
|||||||
command_ip=\u00a79IP of {0} is {1}
|
command_ip=\u00a79IP of {0} is {1}
|
||||||
illegal_chat_characters=\u00a7cIllegal characters in chat ({0})
|
illegal_chat_characters=\u00a7cIllegal characters in chat ({0})
|
||||||
kick_message=\u00a7cYou have been kicked off the proxy.
|
kick_message=\u00a7cYou have been kicked off the proxy.
|
||||||
|
reject_transfer=\u00a7cYour transfer was rejected.
|
||||||
|
@ -4,15 +4,14 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-query</artifactId>
|
<artifactId>bungeecord-query</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-Query</name>
|
<name>BungeeCord-Query</name>
|
||||||
@ -25,7 +24,7 @@
|
|||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-api</artifactId>
|
<artifactId>bungeecord-api</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
|
@ -4,15 +4,14 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-slf4j</artifactId>
|
<artifactId>bungeecord-slf4j</artifactId>
|
||||||
<version>1.20-R0.2-SNAPSHOT</version>
|
<version>1.20-R0.3-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-SLF4J</name>
|
<name>BungeeCord-SLF4J</name>
|
||||||
|
Loading…
Reference in New Issue
Block a user