Compare commits
32 Commits
Minecraft-
...
Minecraft-
Author | SHA1 | Date | |
---|---|---|---|
![]() |
edc5b4dc91 | ||
![]() |
220a95aece | ||
![]() |
4685099808 | ||
![]() |
6c14f40108 | ||
![]() |
b041d84063 | ||
![]() |
a9d3d9461f | ||
![]() |
3fc7064997 | ||
![]() |
80001aa1f0 | ||
![]() |
a0d94282f6 | ||
![]() |
33e11f4c44 | ||
![]() |
b541e7aa76 | ||
![]() |
dd06937a3b | ||
![]() |
891dc87b16 | ||
![]() |
8e77cb35ff | ||
![]() |
59b32a8621 | ||
![]() |
02324206e3 | ||
![]() |
73ce828e6e | ||
![]() |
79d04bec2e | ||
![]() |
cbcd874d47 | ||
![]() |
09f123ce9a | ||
![]() |
0a5f8556fe | ||
![]() |
103a509f26 | ||
![]() |
32a5271dc3 | ||
![]() |
14389eb370 | ||
![]() |
a8b6a6b4aa | ||
![]() |
8133304cce | ||
![]() |
3e8c21a485 | ||
![]() |
f12dcc72d9 | ||
![]() |
a7a32509c7 | ||
![]() |
703a393888 | ||
![]() |
3c961cd5d9 | ||
![]() |
12ee68a315 |
16
api/pom.xml
16
api/pom.xml
@@ -6,13 +6,13 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>net.md-5</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.6.2-SNAPSHOT</version>
|
<version>1.6.4-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>net.md-5</groupId>
|
||||||
<artifactId>bungeecord-api</artifactId>
|
<artifactId>bungeecord-api</artifactId>
|
||||||
<version>1.6.2-SNAPSHOT</version>
|
<version>1.6.4-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-API</name>
|
<name>BungeeCord-API</name>
|
||||||
@@ -25,6 +25,12 @@
|
|||||||
<version>14.0.1</version>
|
<version>14.0.1</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.md-5</groupId>
|
||||||
|
<artifactId>bungeecord-config</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>net.md-5</groupId>
|
||||||
<artifactId>bungeecord-event</artifactId>
|
<artifactId>bungeecord-event</artifactId>
|
||||||
@@ -37,11 +43,5 @@
|
|||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.yaml</groupId>
|
|
||||||
<artifactId>snakeyaml</artifactId>
|
|
||||||
<version>1.12</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
@@ -53,7 +53,7 @@ public abstract class ProxyServer
|
|||||||
*
|
*
|
||||||
* @return the localized string
|
* @return the localized string
|
||||||
*/
|
*/
|
||||||
public abstract String getTranslation(String name);
|
public abstract String getTranslation(String name, Object... args);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the main logger which can be used as a suitable replacement for
|
* Gets the main logger which can be used as a suitable replacement for
|
||||||
|
@@ -61,4 +61,12 @@ public class ListenerInfo
|
|||||||
* server (force default server).
|
* server (force default server).
|
||||||
*/
|
*/
|
||||||
private final boolean pingPassthrough;
|
private final boolean pingPassthrough;
|
||||||
|
/**
|
||||||
|
* What port to run udp query on.
|
||||||
|
*/
|
||||||
|
private final int queryPort;
|
||||||
|
/**
|
||||||
|
* Whether to enable udp query.
|
||||||
|
*/
|
||||||
|
private final boolean queryEnabled;
|
||||||
}
|
}
|
||||||
|
@@ -14,26 +14,26 @@ public interface PendingConnection extends Connection
|
|||||||
*
|
*
|
||||||
* @return the requested username, or null if not set
|
* @return the requested username, or null if not set
|
||||||
*/
|
*/
|
||||||
public String getName();
|
String getName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the numerical client version of the player attempting to log in.
|
* Get the numerical client version of the player attempting to log in.
|
||||||
*
|
*
|
||||||
* @return the protocol version of the remote client
|
* @return the protocol version of the remote client
|
||||||
*/
|
*/
|
||||||
public byte getVersion();
|
byte getVersion();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the requested virtual host that the client tried to connect to.
|
* Get the requested virtual host that the client tried to connect to.
|
||||||
*
|
*
|
||||||
* @return request virtual host or null if invalid / not specified.
|
* @return request virtual host or null if invalid / not specified.
|
||||||
*/
|
*/
|
||||||
public InetSocketAddress getVirtualHost();
|
InetSocketAddress getVirtualHost();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the listener that accepted this connection.
|
* Get the listener that accepted this connection.
|
||||||
*
|
*
|
||||||
* @return the accepting listener
|
* @return the accepting listener
|
||||||
*/
|
*/
|
||||||
public ListenerInfo getListener();
|
ListenerInfo getListener();
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,34 @@
|
|||||||
|
package net.md_5.bungee.api.event;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.ToString;
|
||||||
|
import net.md_5.bungee.api.connection.PendingConnection;
|
||||||
|
import net.md_5.bungee.protocol.packet.Packet2Handshake;
|
||||||
|
import net.md_5.bungee.api.plugin.Event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event called to represent a player first making their presence and username
|
||||||
|
* known.
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ToString(callSuper = false)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class PlayerHandshakeEvent extends Event
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connection attempting to login.
|
||||||
|
*/
|
||||||
|
private final PendingConnection connection;
|
||||||
|
/**
|
||||||
|
* The handshake.
|
||||||
|
*/
|
||||||
|
private final Packet2Handshake handshake;
|
||||||
|
|
||||||
|
public PlayerHandshakeEvent(PendingConnection connection, Packet2Handshake handshake)
|
||||||
|
{
|
||||||
|
this.connection = connection;
|
||||||
|
this.handshake = handshake;
|
||||||
|
}
|
||||||
|
}
|
@@ -2,6 +2,7 @@ package net.md_5.bungee.api.event;
|
|||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NonNull;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
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;
|
||||||
@@ -21,6 +22,7 @@ public class ServerConnectEvent extends Event implements Cancellable
|
|||||||
/**
|
/**
|
||||||
* Server the player will be connected to.
|
* Server the player will be connected to.
|
||||||
*/
|
*/
|
||||||
|
@NonNull
|
||||||
private ServerInfo target;
|
private ServerInfo target;
|
||||||
/**
|
/**
|
||||||
* Cancelled state.
|
* Cancelled state.
|
||||||
|
31
bootstrap/nb-configuration.xml
Normal file
31
bootstrap/nb-configuration.xml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?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>
|
97
bootstrap/pom.xml
Normal file
97
bootstrap/pom.xml
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
|
||||||
|
<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.6.4-SNAPSHOT</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>net.md-5</groupId>
|
||||||
|
<artifactId>bungeecord-bootstrap</artifactId>
|
||||||
|
<version>1.6.4-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>BungeeCord-Bootstrap</name>
|
||||||
|
<description>Java 1.6 loader for BungeeCord</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.md-5</groupId>
|
||||||
|
<artifactId>bungeecord-proxy</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.sf.jopt-simple</groupId>
|
||||||
|
<artifactId>jopt-simple</artifactId>
|
||||||
|
<version>4.5</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>BungeeCord</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>2.5.1</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.6</source>
|
||||||
|
<target>1.6</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<!-- Don't deploy proxy to maven repo, only APIs -->
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>2.4</version>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifestEntries>
|
||||||
|
<Main-Class>net.md_5.bungee.Bootstrap</Main-Class>
|
||||||
|
<Implementation-Version>${describe}</Implementation-Version>
|
||||||
|
<Specification-Version>${maven.build.timestamp}</Specification-Version>
|
||||||
|
</manifestEntries>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<version>2.1</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<filters>
|
||||||
|
<filter>
|
||||||
|
<artifact>*:*</artifact>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*.java</exclude>
|
||||||
|
<exclude>**/*.SF</exclude>
|
||||||
|
<exclude>**/*.DSA</exclude>
|
||||||
|
</excludes>
|
||||||
|
</filter>
|
||||||
|
</filters>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
81
bootstrap/src/main/java/net/md_5/bungee/Bootstrap.java
Normal file
81
bootstrap/src/main/java/net/md_5/bungee/Bootstrap.java
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
package net.md_5.bungee;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import joptsimple.OptionParser;
|
||||||
|
import joptsimple.OptionSet;
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
import net.md_5.bungee.command.ConsoleCommandSender;
|
||||||
|
|
||||||
|
public class Bootstrap
|
||||||
|
{
|
||||||
|
|
||||||
|
private static List<String> list(String... params)
|
||||||
|
{
|
||||||
|
return Arrays.asList( params );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a new instance of BungeeCord.
|
||||||
|
*
|
||||||
|
* @param args command line arguments, currently none are used
|
||||||
|
* @throws Exception when the server cannot be started
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws Exception
|
||||||
|
{
|
||||||
|
OptionParser parser = new OptionParser();
|
||||||
|
parser.allowsUnrecognizedOptions();
|
||||||
|
parser.acceptsAll( list( "v", "version" ) );
|
||||||
|
|
||||||
|
OptionSet options = parser.parse( args );
|
||||||
|
|
||||||
|
if ( options.has( "version" ) )
|
||||||
|
{
|
||||||
|
System.out.println( Bootstrap.class.getPackage().getImplementationVersion() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !System.getProperty( "java.version" ).startsWith( "1.7" ) )
|
||||||
|
{
|
||||||
|
System.err.println( "*** ERROR *** BungeeCord requires Java 7 to function!" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( BungeeCord.class.getPackage().getSpecificationVersion() != null )
|
||||||
|
{
|
||||||
|
Calendar deadline = Calendar.getInstance();
|
||||||
|
deadline.add( Calendar.WEEK_OF_YEAR, 2 );
|
||||||
|
if ( Calendar.getInstance().after( new SimpleDateFormat( "yyyyMMdd" ).parse( BungeeCord.class.getPackage().getSpecificationVersion() ) ) )
|
||||||
|
{
|
||||||
|
System.err.println( "*** Warning, this build is outdated ***" );
|
||||||
|
System.err.println( "*** Please download a new build from http://ci.md-5.net/job/BungeeCord ***" );
|
||||||
|
System.err.println( "*** You will get NO support regarding this build ***" );
|
||||||
|
System.err.println( "*** Server will start in 30 seconds ***" );
|
||||||
|
Thread.sleep( TimeUnit.SECONDS.toMillis( 30 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.setProperty( "java.net.preferIPv4Stack", "true" );
|
||||||
|
|
||||||
|
BungeeCord bungee = new BungeeCord();
|
||||||
|
ProxyServer.setInstance( bungee );
|
||||||
|
bungee.getLogger().info( "Enabled BungeeCord version " + bungee.getVersion() );
|
||||||
|
bungee.start();
|
||||||
|
|
||||||
|
while ( bungee.isRunning )
|
||||||
|
{
|
||||||
|
String line = bungee.getConsoleReader().readLine( ">" );
|
||||||
|
if ( line != null )
|
||||||
|
{
|
||||||
|
if ( !bungee.getPluginManager().dispatchCommand( ConsoleCommandSender.getInstance(), line ) )
|
||||||
|
{
|
||||||
|
bungee.getConsole().sendMessage( ChatColor.RED + "Command not found" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -6,29 +6,24 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>net.md-5</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.6.2-SNAPSHOT</version>
|
<version>1.6.4-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>net.md-5</groupId>
|
||||||
<artifactId>bungeecord-config</artifactId>
|
<artifactId>bungeecord-config</artifactId>
|
||||||
<version>1.6.2-SNAPSHOT</version>
|
<version>1.6.4-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-Config</name>
|
<name>BungeeCord-Config</name>
|
||||||
<description>Generic java configuration API intended for use with BungeeCord</description>
|
<description>Generic java configuration API intended for use with BungeeCord</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<version>4.11</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.yaml</groupId>
|
<groupId>org.yaml</groupId>
|
||||||
<artifactId>snakeyaml</artifactId>
|
<artifactId>snakeyaml</artifactId>
|
||||||
<version>1.11</version>
|
<version>1.13</version>
|
||||||
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
@@ -2,7 +2,7 @@ package net.md_5.bungee.config;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
@@ -13,36 +13,53 @@ public final class Configuration
|
|||||||
{
|
{
|
||||||
|
|
||||||
private static final char SEPARATOR = '.';
|
private static final char SEPARATOR = '.';
|
||||||
private final Map<String, Object> self;
|
final Map<String, Object> self;
|
||||||
private Map<String, Object> comments = new HashMap<>();
|
|
||||||
private final Configuration defaults;
|
private final Configuration defaults;
|
||||||
|
|
||||||
private Map<String, Object> getHolder(String path, Map<String, Object> parent, boolean create)
|
private Configuration getSectionFor(String path)
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object get(String path, Map<String, Object> holder)
|
|
||||||
{
|
{
|
||||||
int index = path.indexOf( SEPARATOR );
|
int index = path.indexOf( SEPARATOR );
|
||||||
String first, second;
|
|
||||||
if ( index == -1 )
|
if ( index == -1 )
|
||||||
{
|
{
|
||||||
second = path;
|
return this;
|
||||||
} else
|
|
||||||
{
|
|
||||||
first = path.substring( 0, index );
|
|
||||||
second = path.substring( index + 1, path.length() );
|
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
|
String root = path.substring( 0, index );
|
||||||
|
Object section = self.get( root );
|
||||||
|
if ( section == null )
|
||||||
|
{
|
||||||
|
section = new LinkedHashMap<>();
|
||||||
|
self.put( root, section );
|
||||||
|
}
|
||||||
|
if ( section instanceof Configuration )
|
||||||
|
{
|
||||||
|
return (Configuration) section;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Configuration( (Map) section, ( defaults == null ) ? null : defaults.getSectionFor( path ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getChild(String path)
|
||||||
|
{
|
||||||
|
int index = path.indexOf( SEPARATOR );
|
||||||
|
return ( index == -1 ) ? path : path.substring( index + 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> T get(String path, T def)
|
public <T> T get(String path, T def)
|
||||||
{
|
{
|
||||||
Object val = get( path, self );
|
Configuration section = getSectionFor( path );
|
||||||
return ( val != null && val.getClass().isInstance( def ) ) ? (T) val : (T) defaults.get( path );
|
Object val;
|
||||||
|
if ( section == this )
|
||||||
|
{
|
||||||
|
val = self.get( path );
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
val = section.get( getChild( path ), def );
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( val != null ) ? (T) val : def;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object get(String path)
|
public Object get(String path)
|
||||||
@@ -52,19 +69,26 @@ public final class Configuration
|
|||||||
|
|
||||||
public Object getDefault(String path)
|
public Object getDefault(String path)
|
||||||
{
|
{
|
||||||
return defaults.get( path );
|
return ( defaults == null ) ? null : defaults.get( path );
|
||||||
}
|
|
||||||
|
|
||||||
public void set(String path, Object value, String comment)
|
|
||||||
{
|
|
||||||
String child = path.substring( path.indexOf( SEPARATOR ) + 1 );
|
|
||||||
getHolder( path, self, true ).put( child, value );
|
|
||||||
getHolder( path, comments, true ).put( child, value );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(String path, Object value)
|
public void set(String path, Object value)
|
||||||
{
|
{
|
||||||
set( path, value, null );
|
Configuration section = getSectionFor( path );
|
||||||
|
if ( section == this )
|
||||||
|
{
|
||||||
|
self.put( path, value );
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
section.set( getChild( path ), value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
public Configuration getSection(String path)
|
||||||
|
{
|
||||||
|
Object def = getDefault( path );
|
||||||
|
return new Configuration( (Map) ( get( path, ( def instanceof Map ) ? def : Collections.EMPTY_MAP ) ), ( defaults == null ) ? null : defaults.getSection( path ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
@@ -1,7 +1,9 @@
|
|||||||
package net.md_5.bungee.config;
|
package net.md_5.bungee.config;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
import java.io.Writer;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -15,13 +17,17 @@ public abstract class ConfigurationProvider
|
|||||||
providers.put( YamlConfiguration.class, new YamlConfiguration() );
|
providers.put( YamlConfiguration.class, new YamlConfiguration() );
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConfigurationProvider getProvider(Class<? extends ConfigurationProvider> provider)
|
public static ConfigurationProvider getProvider(Class<? extends ConfigurationProvider> provider)
|
||||||
{
|
{
|
||||||
return providers.get( provider );
|
return providers.get( provider );
|
||||||
}
|
}
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
public abstract Configuration load(File file);
|
public abstract void save(Configuration config, File file) throws IOException;
|
||||||
|
|
||||||
|
public abstract void save(Configuration config, Writer writer);
|
||||||
|
|
||||||
|
public abstract Configuration load(File file) throws IOException;
|
||||||
|
|
||||||
public abstract Configuration load(Reader reader);
|
public abstract Configuration load(Reader reader);
|
||||||
|
|
||||||
|
@@ -1,14 +1,18 @@
|
|||||||
package net.md_5.bungee.config;
|
package net.md_5.bungee.config;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
import java.io.Writer;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
import org.yaml.snakeyaml.DumperOptions;
|
import org.yaml.snakeyaml.DumperOptions;
|
||||||
import org.yaml.snakeyaml.Yaml;
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PACKAGE)
|
||||||
public class YamlConfiguration extends ConfigurationProvider
|
public class YamlConfiguration extends ConfigurationProvider
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -24,14 +28,26 @@ public class YamlConfiguration extends ConfigurationProvider
|
|||||||
};
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Configuration load(File file)
|
public void save(Configuration config, File file) throws IOException
|
||||||
|
{
|
||||||
|
try ( FileWriter writer = new FileWriter( file ) )
|
||||||
|
{
|
||||||
|
save( config, writer );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void save(Configuration config, Writer writer)
|
||||||
|
{
|
||||||
|
yaml.get().dump( config.self, writer );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Configuration load(File file) throws IOException
|
||||||
{
|
{
|
||||||
try ( FileReader reader = new FileReader( file ) )
|
try ( FileReader reader = new FileReader( file ) )
|
||||||
{
|
{
|
||||||
return load( reader );
|
return load( reader );
|
||||||
} catch ( IOException ex )
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,61 @@
|
|||||||
|
package net.md_5.bungee.config;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class YamlConfigurationTest
|
||||||
|
{
|
||||||
|
|
||||||
|
private String docuement = ""
|
||||||
|
+ "receipt: Oz-Ware Purchase Invoice\n"
|
||||||
|
+ "date: 2012-08-06\n"
|
||||||
|
+ "customer:\n"
|
||||||
|
+ " given: Dorothy\n"
|
||||||
|
+ " family: Gale\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "items:\n"
|
||||||
|
+ " - part_no: A4786\n"
|
||||||
|
+ " descrip: Water Bucket (Filled)\n"
|
||||||
|
+ " price: 1.47\n"
|
||||||
|
+ " quantity: 4\n"
|
||||||
|
+ "\n"
|
||||||
|
+ " - part_no: E1628\n"
|
||||||
|
+ " descrip: High Heeled \"Ruby\" Slippers\n"
|
||||||
|
+ " size: 8\n"
|
||||||
|
+ " price: 100.27\n"
|
||||||
|
+ " quantity: 1\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "bill-to: &id001\n"
|
||||||
|
+ " street: |\n"
|
||||||
|
+ " 123 Tornado Alley\n"
|
||||||
|
+ " Suite 16\n"
|
||||||
|
+ " city: East Centerville\n"
|
||||||
|
+ " state: KS\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "ship-to: *id001\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "specialDelivery: >\n"
|
||||||
|
+ " Follow the Yellow Brick\n"
|
||||||
|
+ " Road to the Emerald City.\n"
|
||||||
|
+ " Pay no attention to the\n"
|
||||||
|
+ " man behind the curtain.";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRead() throws Exception
|
||||||
|
{
|
||||||
|
Configuration conf = ConfigurationProvider.getProvider( YamlConfiguration.class ).load( docuement );
|
||||||
|
|
||||||
|
Assert.assertEquals( "receipt", "Oz-Ware Purchase Invoice", conf.getString( "receipt" ) );
|
||||||
|
// Assert.assertEquals( "date", "2012-08-06", conf.get( "date" ).toString() );
|
||||||
|
|
||||||
|
Configuration customer = conf.getSection( "customer" );
|
||||||
|
Assert.assertEquals( "customer.given", "Dorothy", customer.getString( "given" ) );
|
||||||
|
Assert.assertEquals( "customer.given", "Dorothy", conf.getString( "customer.given" ) );
|
||||||
|
|
||||||
|
List items = conf.getList( "items" );
|
||||||
|
Map item = (Map) items.get( 0 );
|
||||||
|
Assert.assertEquals( "items[0].part_no", "A4786", item.get( "part_no" ) );
|
||||||
|
}
|
||||||
|
}
|
@@ -6,13 +6,13 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>net.md-5</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.6.2-SNAPSHOT</version>
|
<version>1.6.4-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>net.md-5</groupId>
|
||||||
<artifactId>bungeecord-event</artifactId>
|
<artifactId>bungeecord-event</artifactId>
|
||||||
<version>1.6.2-SNAPSHOT</version>
|
<version>1.6.4-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-Event</name>
|
<name>BungeeCord-Event</name>
|
||||||
|
5
pom.xml
5
pom.xml
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>net.md-5</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.6.2-SNAPSHOT</version>
|
<version>1.6.4-SNAPSHOT</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<name>BungeeCord</name>
|
<name>BungeeCord</name>
|
||||||
@@ -38,9 +38,12 @@
|
|||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>api</module>
|
<module>api</module>
|
||||||
|
<module>bootstrap</module>
|
||||||
|
<module>config</module>
|
||||||
<module>event</module>
|
<module>event</module>
|
||||||
<module>protocol</module>
|
<module>protocol</module>
|
||||||
<module>proxy</module>
|
<module>proxy</module>
|
||||||
|
<module>query</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<scm>
|
<scm>
|
||||||
|
@@ -6,13 +6,13 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>net.md-5</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.6.2-SNAPSHOT</version>
|
<version>1.6.4-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>net.md-5</groupId>
|
||||||
<artifactId>bungeecord-protocol</artifactId>
|
<artifactId>bungeecord-protocol</artifactId>
|
||||||
<version>1.6.2-SNAPSHOT</version>
|
<version>1.6.4-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-Protocol</name>
|
<name>BungeeCord-Protocol</name>
|
||||||
|
@@ -0,0 +1,10 @@
|
|||||||
|
package net.md_5.bungee.protocol;
|
||||||
|
|
||||||
|
public class BadPacketException extends RuntimeException
|
||||||
|
{
|
||||||
|
|
||||||
|
public BadPacketException(String message)
|
||||||
|
{
|
||||||
|
super( message );
|
||||||
|
}
|
||||||
|
}
|
@@ -30,8 +30,8 @@ import net.md_5.bungee.protocol.skip.PacketReader;
|
|||||||
public class Vanilla implements Protocol
|
public class Vanilla implements Protocol
|
||||||
{
|
{
|
||||||
|
|
||||||
public static final byte PROTOCOL_VERSION = 74;
|
public static final byte PROTOCOL_VERSION = 78;
|
||||||
public static final String GAME_VERSION = "1.6.2";
|
public static final String GAME_VERSION = "1.6.4";
|
||||||
@Getter
|
@Getter
|
||||||
private static final Vanilla instance = new Vanilla();
|
private static final Vanilla instance = new Vanilla();
|
||||||
/*========================================================================*/
|
/*========================================================================*/
|
||||||
@@ -78,7 +78,7 @@ public class Vanilla implements Protocol
|
|||||||
DefinedPacket packet = read( packetId, buf, this );
|
DefinedPacket packet = read( packetId, buf, this );
|
||||||
if ( buf.readerIndex() == start )
|
if ( buf.readerIndex() == start )
|
||||||
{
|
{
|
||||||
throw new RuntimeException( "Unknown packet id " + packetId );
|
throw new BadPacketException( "Unknown packet id " + packetId );
|
||||||
}
|
}
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
@@ -382,9 +382,5 @@ public class Vanilla implements Protocol
|
|||||||
{
|
{
|
||||||
BYTE, FLOAT, FLOAT
|
BYTE, FLOAT, FLOAT
|
||||||
};
|
};
|
||||||
opCodes[0xCB] = new OpCode[]
|
|
||||||
{
|
|
||||||
STRING
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,6 @@
|
|||||||
package net.md_5.bungee.protocol.packet;
|
package net.md_5.bungee.protocol.packet;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
@@ -3,15 +3,17 @@ package net.md_5.bungee.protocol.packet;
|
|||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
|
@Setter
|
||||||
@ToString
|
@ToString
|
||||||
@EqualsAndHashCode(callSuper = false)
|
@EqualsAndHashCode(callSuper = false)
|
||||||
public class Packet2Handshake extends DefinedPacket
|
public class Packet2Handshake extends DefinedPacket
|
||||||
{
|
{
|
||||||
|
|
||||||
private byte procolVersion;
|
private byte protocolVersion;
|
||||||
private String username;
|
private String username;
|
||||||
private String host;
|
private String host;
|
||||||
private int port;
|
private int port;
|
||||||
@@ -24,7 +26,7 @@ public class Packet2Handshake extends DefinedPacket
|
|||||||
@Override
|
@Override
|
||||||
public void read(ByteBuf buf)
|
public void read(ByteBuf buf)
|
||||||
{
|
{
|
||||||
procolVersion = buf.readByte();
|
protocolVersion = buf.readByte();
|
||||||
username = readString( buf );
|
username = readString( buf );
|
||||||
host = readString( buf );
|
host = readString( buf );
|
||||||
port = buf.readInt();
|
port = buf.readInt();
|
||||||
@@ -33,7 +35,7 @@ public class Packet2Handshake extends DefinedPacket
|
|||||||
@Override
|
@Override
|
||||||
public void write(ByteBuf buf)
|
public void write(ByteBuf buf)
|
||||||
{
|
{
|
||||||
buf.writeByte( procolVersion );
|
buf.writeByte( protocolVersion );
|
||||||
writeString( username, buf );
|
writeString( username, buf );
|
||||||
writeString( host, buf );
|
writeString( host, buf );
|
||||||
buf.writeInt( port );
|
buf.writeInt( port );
|
||||||
|
@@ -34,18 +34,13 @@ public class PacketCBTabComplete extends DefinedPacket
|
|||||||
@Override
|
@Override
|
||||||
public void write(ByteBuf buf)
|
public void write(ByteBuf buf)
|
||||||
{
|
{
|
||||||
String tab = "";
|
StringBuilder tab = new StringBuilder();
|
||||||
for ( String alternative : commands )
|
for ( String alternative : commands )
|
||||||
{
|
{
|
||||||
if ( tab.isEmpty() )
|
tab.append( alternative );
|
||||||
{
|
tab.append( "\00" );
|
||||||
tab = alternative + " ";
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
tab += "\0" + alternative + " ";
|
|
||||||
}
|
}
|
||||||
}
|
writeString( tab.substring( 0, tab.length() - 1 ), buf );
|
||||||
writeString( tab, buf );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -6,13 +6,13 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>net.md-5</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.6.2-SNAPSHOT</version>
|
<version>1.6.4-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>net.md-5</groupId>
|
||||||
<artifactId>bungeecord-proxy</artifactId>
|
<artifactId>bungeecord-proxy</artifactId>
|
||||||
<version>1.6.2-SNAPSHOT</version>
|
<version>1.6.4-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-Proxy</name>
|
<name>BungeeCord-Proxy</name>
|
||||||
@@ -41,6 +41,12 @@
|
|||||||
<version>2.11</version>
|
<version>2.11</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.md-5</groupId>
|
||||||
|
<artifactId>bungeecord-api</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>net.md-5</groupId>
|
||||||
<artifactId>bungeecord-protocol</artifactId>
|
<artifactId>bungeecord-protocol</artifactId>
|
||||||
@@ -49,7 +55,7 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>net.md-5</groupId>
|
||||||
<artifactId>bungeecord-api</artifactId>
|
<artifactId>bungeecord-query</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
@@ -74,7 +80,6 @@
|
|||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<finalName>BungeeCord</finalName>
|
|
||||||
<resources>
|
<resources>
|
||||||
<resource>
|
<resource>
|
||||||
<directory>src/main/resources</directory>
|
<directory>src/main/resources</directory>
|
||||||
@@ -90,45 +95,6 @@
|
|||||||
<skip>true</skip>
|
<skip>true</skip>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<version>2.4</version>
|
|
||||||
<configuration>
|
|
||||||
<archive>
|
|
||||||
<manifestEntries>
|
|
||||||
<Main-Class>net.md_5.bungee.BungeeCord</Main-Class>
|
|
||||||
<Implementation-Version>${describe}</Implementation-Version>
|
|
||||||
<Specification-Version>${maven.build.timestamp}</Specification-Version>
|
|
||||||
</manifestEntries>
|
|
||||||
</archive>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
|
||||||
<version>2.1</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>shade</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<filters>
|
|
||||||
<filter>
|
|
||||||
<artifact>*:*</artifact>
|
|
||||||
<excludes>
|
|
||||||
<exclude>**/*.java</exclude>
|
|
||||||
<exclude>**/*.SF</exclude>
|
|
||||||
<exclude>**/*.DSA</exclude>
|
|
||||||
</excludes>
|
|
||||||
</filter>
|
|
||||||
</filters>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@@ -20,6 +20,7 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.text.MessageFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -60,6 +61,7 @@ import net.md_5.bungee.protocol.packet.DefinedPacket;
|
|||||||
import net.md_5.bungee.protocol.packet.Packet3Chat;
|
import net.md_5.bungee.protocol.packet.Packet3Chat;
|
||||||
import net.md_5.bungee.protocol.packet.PacketFAPluginMessage;
|
import net.md_5.bungee.protocol.packet.PacketFAPluginMessage;
|
||||||
import net.md_5.bungee.protocol.Vanilla;
|
import net.md_5.bungee.protocol.Vanilla;
|
||||||
|
import net.md_5.bungee.query.RemoteQuery;
|
||||||
import net.md_5.bungee.tab.Custom;
|
import net.md_5.bungee.tab.Custom;
|
||||||
import net.md_5.bungee.util.CaseInsensitiveMap;
|
import net.md_5.bungee.util.CaseInsensitiveMap;
|
||||||
import org.fusesource.jansi.AnsiConsole;
|
import org.fusesource.jansi.AnsiConsole;
|
||||||
@@ -81,7 +83,7 @@ public class BungeeCord extends ProxyServer
|
|||||||
/**
|
/**
|
||||||
* Localization bundle.
|
* Localization bundle.
|
||||||
*/
|
*/
|
||||||
public final ResourceBundle bundle = ResourceBundle.getBundle( "messages_en" );
|
public final ResourceBundle bundle = ResourceBundle.getBundle( "messages" );
|
||||||
public final MultithreadEventLoopGroup eventLoops = new NioEventLoopGroup( 0, new ThreadFactoryBuilder().setNameFormat( "Netty IO Thread #%1$d" ).build() );
|
public final MultithreadEventLoopGroup eventLoops = new NioEventLoopGroup( 0, new ThreadFactoryBuilder().setNameFormat( "Netty IO Thread #%1$d" ).build() );
|
||||||
/**
|
/**
|
||||||
* locations.yml save thread.
|
* locations.yml save thread.
|
||||||
@@ -160,46 +162,6 @@ public class BungeeCord extends ProxyServer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts a new instance of BungeeCord.
|
|
||||||
*
|
|
||||||
* @param args command line arguments, currently none are used
|
|
||||||
* @throws Exception when the server cannot be started
|
|
||||||
*/
|
|
||||||
public static void main(String[] args) throws Exception
|
|
||||||
{
|
|
||||||
if ( BungeeCord.class.getPackage().getSpecificationVersion() != null )
|
|
||||||
{
|
|
||||||
Calendar deadline = Calendar.getInstance();
|
|
||||||
deadline.add( Calendar.WEEK_OF_YEAR, 2 );
|
|
||||||
if ( Calendar.getInstance().after( new SimpleDateFormat( "yyyyMMdd" ).parse( BungeeCord.class.getPackage().getSpecificationVersion() ) ) )
|
|
||||||
{
|
|
||||||
System.err.println( "*** Warning, this build is outdated ***" );
|
|
||||||
System.err.println( "*** Please download a new build from http://ci.md-5.net/job/BungeeCord ***" );
|
|
||||||
System.err.println( "*** You will get NO support regarding this build ***" );
|
|
||||||
System.err.println( "*** Server will start in 30 seconds ***" );
|
|
||||||
Thread.sleep( TimeUnit.SECONDS.toMillis( 30 ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BungeeCord bungee = new BungeeCord();
|
|
||||||
ProxyServer.setInstance( bungee );
|
|
||||||
bungee.getLogger().info( "Enabled BungeeCord version " + bungee.getVersion() );
|
|
||||||
bungee.start();
|
|
||||||
|
|
||||||
while ( bungee.isRunning )
|
|
||||||
{
|
|
||||||
String line = bungee.getConsoleReader().readLine( ">" );
|
|
||||||
if ( line != null )
|
|
||||||
{
|
|
||||||
if ( !bungee.getPluginManager().dispatchCommand( ConsoleCommandSender.getInstance(), line ) )
|
|
||||||
{
|
|
||||||
bungee.getConsole().sendMessage( ChatColor.RED + "Command not found" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start this proxy instance by loading the configuration, plugins and
|
* Start this proxy instance by loading the configuration, plugins and
|
||||||
* starting the connect thread.
|
* starting the connect thread.
|
||||||
@@ -269,6 +231,26 @@ public class BungeeCord extends ProxyServer
|
|||||||
.group( eventLoops )
|
.group( eventLoops )
|
||||||
.localAddress( info.getHost() )
|
.localAddress( info.getHost() )
|
||||||
.bind().addListener( listener );
|
.bind().addListener( listener );
|
||||||
|
|
||||||
|
if ( info.isQueryEnabled() )
|
||||||
|
{
|
||||||
|
ChannelFutureListener bindListener = new ChannelFutureListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void operationComplete(ChannelFuture future) throws Exception
|
||||||
|
{
|
||||||
|
if ( future.isSuccess() )
|
||||||
|
{
|
||||||
|
listeners.add( future.channel() );
|
||||||
|
getLogger().info( "Started query on " + future.channel().localAddress() );
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
getLogger().log( Level.WARNING, "Could not bind to host " + future.channel().remoteAddress(), future.cause() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
new RemoteQuery( this, info ).start( new InetSocketAddress( info.getHost().getAddress(), info.getQueryPort() ), eventLoops, bindListener );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,12 +369,12 @@ public class BungeeCord extends ProxyServer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTranslation(String name)
|
public String getTranslation(String name, Object... args)
|
||||||
{
|
{
|
||||||
String translation = "<translation '" + name + "' missing>";
|
String translation = "<translation '" + name + "' missing>";
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
translation = bundle.getString( name );
|
translation = MessageFormat.format( bundle.getString( name ), args );
|
||||||
} catch ( MissingResourceException ex )
|
} catch ( MissingResourceException ex )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@@ -89,13 +89,13 @@ public class BungeeServerInfo implements ServerInfo
|
|||||||
Preconditions.checkNotNull( channel, "channel" );
|
Preconditions.checkNotNull( channel, "channel" );
|
||||||
Preconditions.checkNotNull( data, "data" );
|
Preconditions.checkNotNull( data, "data" );
|
||||||
|
|
||||||
|
synchronized ( packetQueue )
|
||||||
|
{
|
||||||
Server server = ( players.isEmpty() ) ? null : players.iterator().next().getServer();
|
Server server = ( players.isEmpty() ) ? null : players.iterator().next().getServer();
|
||||||
if ( server != null )
|
if ( server != null )
|
||||||
{
|
{
|
||||||
server.sendData( channel, data );
|
server.sendData( channel, data );
|
||||||
} else
|
} else
|
||||||
{
|
|
||||||
synchronized ( packetQueue )
|
|
||||||
{
|
{
|
||||||
packetQueue.add( new PacketFAPluginMessage( channel, data ) );
|
packetQueue.add( new PacketFAPluginMessage( channel, data ) );
|
||||||
}
|
}
|
||||||
|
@@ -1,14 +1,15 @@
|
|||||||
package net.md_5.bungee;
|
package net.md_5.bungee;
|
||||||
|
|
||||||
import gnu.trove.map.hash.TObjectLongHashMap;
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ConnectionThrottle
|
public class ConnectionThrottle
|
||||||
{
|
{
|
||||||
|
|
||||||
private final TObjectLongHashMap<InetAddress> throttle = new TObjectLongHashMap<>();
|
private final Map<InetAddress, Long> throttle = new HashMap<>();
|
||||||
private final int throttleTime;
|
private final int throttleTime;
|
||||||
|
|
||||||
public void unthrottle(InetAddress address)
|
public void unthrottle(InetAddress address)
|
||||||
@@ -18,10 +19,10 @@ public class ConnectionThrottle
|
|||||||
|
|
||||||
public boolean throttle(InetAddress address)
|
public boolean throttle(InetAddress address)
|
||||||
{
|
{
|
||||||
long value = throttle.get( address );
|
Long value = throttle.get( address );
|
||||||
long currentTime = System.currentTimeMillis();
|
long currentTime = System.currentTimeMillis();
|
||||||
|
|
||||||
throttle.put( address, currentTime );
|
throttle.put( address, currentTime );
|
||||||
return value != 0 && currentTime - value < throttleTime;
|
return value != null && currentTime - value < throttleTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -40,9 +40,9 @@ public class EncryptionUtil
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PacketFDEncryptionRequest encryptRequest()
|
public static PacketFDEncryptionRequest encryptRequest(boolean onlinemode)
|
||||||
{
|
{
|
||||||
String hash = ( BungeeCord.getInstance().config.isOnlineMode() ) ? Long.toString( random.nextLong(), 16 ) : "-";
|
String hash = ( onlinemode ) ? Long.toString( random.nextLong(), 16 ) : "-";
|
||||||
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 );
|
||||||
|
@@ -171,6 +171,8 @@ public final class UserConnection implements ProxiedPlayer
|
|||||||
|
|
||||||
public void connect(ServerInfo info, final boolean retry)
|
public void connect(ServerInfo info, final boolean retry)
|
||||||
{
|
{
|
||||||
|
Preconditions.checkNotNull( info, "info" );
|
||||||
|
|
||||||
ServerConnectEvent event = new ServerConnectEvent( this, info );
|
ServerConnectEvent event = new ServerConnectEvent( this, info );
|
||||||
if ( bungee.getPluginManager().callEvent( event ).isCancelled() )
|
if ( bungee.getPluginManager().callEvent( event ).isCancelled() )
|
||||||
{
|
{
|
||||||
|
@@ -54,12 +54,12 @@ public class Util
|
|||||||
+ ( ( trace.length > 0 ) ? " @ " + t.getStackTrace()[0].getClassName() + ":" + t.getStackTrace()[0].getLineNumber() : "" );
|
+ ( ( trace.length > 0 ) ? " @ " + t.getStackTrace()[0].getClassName() + ":" + t.getStackTrace()[0].getLineNumber() : "" );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String csv(Collection<?> objects)
|
public static String csv(Iterable<?> objects)
|
||||||
{
|
{
|
||||||
return format( objects, ", " );
|
return format( objects, ", " );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String format(Collection<?> objects, String separators)
|
public static String format(Iterable<?> objects, String separators)
|
||||||
{
|
{
|
||||||
StringBuilder ret = new StringBuilder();
|
StringBuilder ret = new StringBuilder();
|
||||||
for ( Object o : objects )
|
for ( Object o : objects )
|
||||||
|
@@ -32,10 +32,4 @@ public class CommandFind extends PlayerCommand
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterable<String> onTabComplete(CommandSender sender, String[] args)
|
|
||||||
{
|
|
||||||
return ( args.length == 0 ) ? super.onTabComplete( sender, args ) : Collections.EMPTY_LIST;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
package net.md_5.bungee.command;
|
package net.md_5.bungee.command;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import net.md_5.bungee.Util;
|
import net.md_5.bungee.Util;
|
||||||
@@ -33,31 +32,16 @@ public class CommandList extends Command
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Collection<ProxiedPlayer> serverPlayers = server.getPlayers();
|
|
||||||
|
|
||||||
StringBuilder message = new StringBuilder();
|
|
||||||
message.append( ChatColor.GREEN );
|
|
||||||
message.append( "[" );
|
|
||||||
message.append( server.getName() );
|
|
||||||
message.append( "] " );
|
|
||||||
message.append( ChatColor.YELLOW );
|
|
||||||
message.append( "(" );
|
|
||||||
message.append( serverPlayers.size() );
|
|
||||||
message.append( "): " );
|
|
||||||
message.append( ChatColor.RESET );
|
|
||||||
|
|
||||||
List<String> players = new ArrayList<>();
|
List<String> players = new ArrayList<>();
|
||||||
for ( ProxiedPlayer player : serverPlayers )
|
for ( ProxiedPlayer player : server.getPlayers() )
|
||||||
{
|
{
|
||||||
players.add( player.getDisplayName() );
|
players.add( player.getDisplayName() );
|
||||||
}
|
}
|
||||||
Collections.sort( players, String.CASE_INSENSITIVE_ORDER );
|
Collections.sort( players, String.CASE_INSENSITIVE_ORDER );
|
||||||
|
|
||||||
message.append( Util.format( players, ChatColor.RESET + ", " ) );
|
sender.sendMessage( ProxyServer.getInstance().getTranslation( "command_list", server.getName(), server.getPlayers().size(), Util.format( players, ChatColor.RESET + ", " ) ) );
|
||||||
|
|
||||||
sender.sendMessage( message.toString() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sender.sendMessage( ProxyServer.getInstance().getTranslation( "total_players" ) + ProxyServer.getInstance().getOnlineCount() );
|
sender.sendMessage( ProxyServer.getInstance().getTranslation( "total_players", ProxyServer.getInstance().getOnlineCount() ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package net.md_5.bungee.command;
|
package net.md_5.bungee.command;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import net.md_5.bungee.api.CommandSender;
|
import net.md_5.bungee.api.CommandSender;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
@@ -24,12 +25,20 @@ public abstract class PlayerCommand extends Command implements TabExecutor
|
|||||||
@Override
|
@Override
|
||||||
public Iterable<String> onTabComplete(CommandSender sender, String[] args)
|
public Iterable<String> onTabComplete(CommandSender sender, String[] args)
|
||||||
{
|
{
|
||||||
return Iterables.transform( ProxyServer.getInstance().getPlayers(), new Function<ProxiedPlayer, String>()
|
final String lastArg = ( args.length > 0 ) ? args[args.length - 1] : "";
|
||||||
|
return Iterables.transform( Iterables.filter( ProxyServer.getInstance().getPlayers(), new Predicate<ProxiedPlayer>()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public String apply(ProxiedPlayer input)
|
public boolean apply(ProxiedPlayer player)
|
||||||
{
|
{
|
||||||
return input.getDisplayName();
|
return player.getName().startsWith( lastArg );
|
||||||
|
}
|
||||||
|
} ), new Function<ProxiedPlayer, String>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public String apply(ProxiedPlayer player)
|
||||||
|
{
|
||||||
|
return player.getName();
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
@@ -215,7 +215,10 @@ public class YamlConfig implements ConfigurationAdapter
|
|||||||
boolean setLocalAddress = get( "bind_local_address", true, val );
|
boolean setLocalAddress = get( "bind_local_address", true, val );
|
||||||
boolean pingPassthrough = get( "ping_passthrough", false, val );
|
boolean pingPassthrough = get( "ping_passthrough", false, val );
|
||||||
|
|
||||||
ListenerInfo info = new ListenerInfo( address, motd, maxPlayers, tabListSize, defaultServer, fallbackServer, forceDefault, forced, value.clazz, setLocalAddress, pingPassthrough );
|
boolean query = get( "query_enabled", false, val );
|
||||||
|
int queryPort = get( "query_port", 25577, val );
|
||||||
|
|
||||||
|
ListenerInfo info = new ListenerInfo( address, motd, maxPlayers, tabListSize, defaultServer, fallbackServer, forceDefault, forced, value.clazz, setLocalAddress, pingPassthrough, queryPort, query );
|
||||||
ret.add( info );
|
ret.add( info );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -52,6 +52,7 @@ import net.md_5.bungee.protocol.packet.PacketFDEncryptionRequest;
|
|||||||
import net.md_5.bungee.protocol.packet.PacketFEPing;
|
import net.md_5.bungee.protocol.packet.PacketFEPing;
|
||||||
import net.md_5.bungee.protocol.packet.PacketFFKick;
|
import net.md_5.bungee.protocol.packet.PacketFFKick;
|
||||||
import net.md_5.bungee.api.AbstractReconnectHandler;
|
import net.md_5.bungee.api.AbstractReconnectHandler;
|
||||||
|
import net.md_5.bungee.api.event.PlayerHandshakeEvent;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class InitialHandler extends PacketHandler implements PendingConnection
|
public class InitialHandler extends PacketHandler implements PendingConnection
|
||||||
@@ -80,6 +81,8 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
ch.write( packet );
|
ch.write( packet );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@Getter
|
||||||
|
private boolean onlineMode = BungeeCord.getInstance().config.isOnlineMode();
|
||||||
private ScheduledFuture<?> pingFuture;
|
private ScheduledFuture<?> pingFuture;
|
||||||
private InetSocketAddress vHost;
|
private InetSocketAddress vHost;
|
||||||
private byte version = -1;
|
private byte version = -1;
|
||||||
@@ -177,7 +180,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
{
|
{
|
||||||
respondToPing();
|
respondToPing();
|
||||||
}
|
}
|
||||||
}, 500, TimeUnit.MILLISECONDS );
|
}, 200, TimeUnit.MILLISECONDS );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -198,10 +201,12 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
this.vHost = new InetSocketAddress( handshake.getHost(), handshake.getPort() );
|
this.vHost = new InetSocketAddress( handshake.getHost(), handshake.getPort() );
|
||||||
bungee.getLogger().log( Level.INFO, "{0} has connected", this );
|
bungee.getLogger().log( Level.INFO, "{0} has connected", this );
|
||||||
|
|
||||||
if ( handshake.getProcolVersion() > Vanilla.PROTOCOL_VERSION )
|
bungee.getPluginManager().callEvent( new PlayerHandshakeEvent( InitialHandler.this, handshake ) );
|
||||||
|
|
||||||
|
if ( handshake.getProtocolVersion() > Vanilla.PROTOCOL_VERSION )
|
||||||
{
|
{
|
||||||
disconnect( bungee.getTranslation( "outdated_server" ) );
|
disconnect( bungee.getTranslation( "outdated_server" ) );
|
||||||
} else if ( handshake.getProcolVersion() < Vanilla.PROTOCOL_VERSION )
|
} else if ( handshake.getProtocolVersion() < Vanilla.PROTOCOL_VERSION )
|
||||||
{
|
{
|
||||||
disconnect( bungee.getTranslation( "outdated_client" ) );
|
disconnect( bungee.getTranslation( "outdated_client" ) );
|
||||||
}
|
}
|
||||||
@@ -220,7 +225,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If offline mode and they are already on, don't allow connect
|
// If offline mode and they are already on, don't allow connect
|
||||||
if ( !BungeeCord.getInstance().config.isOnlineMode() && bungee.getPlayer( handshake.getUsername() ) != null )
|
if ( !isOnlineMode() && bungee.getPlayer( handshake.getUsername() ) != null )
|
||||||
{
|
{
|
||||||
disconnect( bungee.getTranslation( "already_connected" ) );
|
disconnect( bungee.getTranslation( "already_connected" ) );
|
||||||
return;
|
return;
|
||||||
@@ -228,7 +233,8 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
|
|
||||||
unsafe().sendPacket( PacketConstants.I_AM_BUNGEE );
|
unsafe().sendPacket( PacketConstants.I_AM_BUNGEE );
|
||||||
unsafe().sendPacket( PacketConstants.FORGE_MOD_REQUEST );
|
unsafe().sendPacket( PacketConstants.FORGE_MOD_REQUEST );
|
||||||
unsafe().sendPacket( request = EncryptionUtil.encryptRequest() );
|
|
||||||
|
unsafe().sendPacket( request = EncryptionUtil.encryptRequest( this.onlineMode ) );
|
||||||
thisState = State.ENCRYPT;
|
thisState = State.ENCRYPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,7 +247,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
Cipher decrypt = EncryptionUtil.getCipher( Cipher.DECRYPT_MODE, sharedKey );
|
Cipher decrypt = EncryptionUtil.getCipher( Cipher.DECRYPT_MODE, sharedKey );
|
||||||
ch.addBefore( PipelineUtils.PACKET_DECODE_HANDLER, PipelineUtils.DECRYPT_HANDLER, new CipherDecoder( decrypt ) );
|
ch.addBefore( PipelineUtils.PACKET_DECODE_HANDLER, PipelineUtils.DECRYPT_HANDLER, new CipherDecoder( decrypt ) );
|
||||||
|
|
||||||
if ( BungeeCord.getInstance().config.isOnlineMode() )
|
if ( this.onlineMode )
|
||||||
{
|
{
|
||||||
String encName = URLEncoder.encode( InitialHandler.this.getName(), "UTF-8" );
|
String encName = URLEncoder.encode( InitialHandler.this.getName(), "UTF-8" );
|
||||||
|
|
||||||
@@ -381,7 +387,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
@Override
|
@Override
|
||||||
public byte getVersion()
|
public byte getVersion()
|
||||||
{
|
{
|
||||||
return ( handshake == null ) ? version : handshake.getProcolVersion();
|
return ( handshake == null ) ? version : handshake.getProtocolVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -402,6 +408,12 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
return unsafe;
|
return unsafe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setOnlineMode(boolean onlineMode)
|
||||||
|
{
|
||||||
|
Preconditions.checkState( thisState == State.HANDSHAKE, "Can only set online mode status whilst handshaking" );
|
||||||
|
this.onlineMode = onlineMode;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
|
@@ -20,7 +20,7 @@ public class PingHandler extends PacketHandler
|
|||||||
@Override
|
@Override
|
||||||
public void connected(ChannelWrapper channel) throws Exception
|
public void connected(ChannelWrapper channel) throws Exception
|
||||||
{
|
{
|
||||||
// TODO: Update this to 1.6.2 style!
|
// TODO: Update this to 1.6.4 style!
|
||||||
channel.write( Unpooled.wrappedBuffer( new byte[]
|
channel.write( Unpooled.wrappedBuffer( new byte[]
|
||||||
{
|
{
|
||||||
(byte) 0xFE, (byte) 0x01
|
(byte) 0xFE, (byte) 0x01
|
||||||
|
@@ -98,7 +98,7 @@ public class UpstreamBridge extends PacketHandler
|
|||||||
if ( tabComplete.getCursor().startsWith( "/" ) )
|
if ( tabComplete.getCursor().startsWith( "/" ) )
|
||||||
{
|
{
|
||||||
List<String> results = new ArrayList<>();
|
List<String> results = new ArrayList<>();
|
||||||
bungee.getPluginManager().dispatchCommand( con, tabComplete.getCursor().substring( 1, tabComplete.getCursor().length() ), results );
|
bungee.getPluginManager().dispatchCommand( con, tabComplete.getCursor().substring( 1 ), results );
|
||||||
|
|
||||||
if ( !results.isEmpty() )
|
if ( !results.isEmpty() )
|
||||||
{
|
{
|
||||||
|
@@ -10,6 +10,7 @@ import net.md_5.bungee.api.ProxyServer;
|
|||||||
import net.md_5.bungee.connection.CancelSendSignal;
|
import net.md_5.bungee.connection.CancelSendSignal;
|
||||||
import net.md_5.bungee.connection.InitialHandler;
|
import net.md_5.bungee.connection.InitialHandler;
|
||||||
import net.md_5.bungee.connection.PingHandler;
|
import net.md_5.bungee.connection.PingHandler;
|
||||||
|
import net.md_5.bungee.protocol.BadPacketException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is a primitive wrapper for {@link PacketHandler} instances tied to
|
* This class is a primitive wrapper for {@link PacketHandler} instances tied to
|
||||||
@@ -95,6 +96,9 @@ public class HandlerBoss extends ChannelInboundHandlerAdapter
|
|||||||
if ( cause instanceof ReadTimeoutException )
|
if ( cause instanceof ReadTimeoutException )
|
||||||
{
|
{
|
||||||
ProxyServer.getInstance().getLogger().log( Level.WARNING, handler + " - read timed out" );
|
ProxyServer.getInstance().getLogger().log( Level.WARNING, handler + " - read timed out" );
|
||||||
|
} else if ( cause instanceof BadPacketException )
|
||||||
|
{
|
||||||
|
ProxyServer.getInstance().getLogger().log( Level.WARNING, handler + " - bad packet ID, are mods in use!?" );
|
||||||
} else if ( cause instanceof IOException )
|
} else if ( cause instanceof IOException )
|
||||||
{
|
{
|
||||||
ProxyServer.getInstance().getLogger().log( Level.WARNING, handler + " - IOException: " + cause.getMessage() );
|
ProxyServer.getInstance().getLogger().log( Level.WARNING, handler + " - IOException: " + cause.getMessage() );
|
||||||
|
@@ -30,8 +30,9 @@ public class PipelineUtils
|
|||||||
{
|
{
|
||||||
if ( BungeeCord.getInstance().getConnectionThrottle().throttle( ( (InetSocketAddress) ch.remoteAddress() ).getAddress() ) )
|
if ( BungeeCord.getInstance().getConnectionThrottle().throttle( ( (InetSocketAddress) ch.remoteAddress() ).getAddress() ) )
|
||||||
{
|
{
|
||||||
ch.close();
|
// TODO: Better throttle - we can't throttle this way if we want to maintain 1.7 compat!
|
||||||
return;
|
// ch.close();
|
||||||
|
// return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BASE.initChannel( ch );
|
BASE.initChannel( ch );
|
||||||
|
@@ -46,7 +46,7 @@ public class Custom extends TabListAdapter implements CustomTabList
|
|||||||
|
|
||||||
if ( text != null )
|
if ( text != null )
|
||||||
{
|
{
|
||||||
Preconditions.checkArgument( text.length() <= MAX_LEN, "text must be <= %s chars", MAX_LEN );
|
Preconditions.checkArgument( text.length() <= MAX_LEN - 2, "text must be <= %s chars", MAX_LEN - 2 );
|
||||||
Preconditions.checkArgument( !ChatColor.stripColor( text ).isEmpty(), "Text cannot consist entirely of colour codes" );
|
Preconditions.checkArgument( !ChatColor.stripColor( text ).isEmpty(), "Text cannot consist entirely of colour codes" );
|
||||||
text = attempt( text );
|
text = attempt( text );
|
||||||
sentStuff.add( text );
|
sentStuff.add( text );
|
||||||
|
21
proxy/src/main/resources/messages.properties
Normal file
21
proxy/src/main/resources/messages.properties
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
alert=\u00a78[\u00a74Alert\u00a78]\u00a7r
|
||||||
|
already_connected=\u00a7cYou are already connected to this server
|
||||||
|
already_connecting=\u00a7cAlready connecting to this server!
|
||||||
|
command_list=\u00a7a[{0}] \u00a7e({1}): \u00a7r{2}
|
||||||
|
connect_kick=\u00a7cKicked whilst connecting to
|
||||||
|
current_server=\u00a76You are currently connected to
|
||||||
|
fallback_kick=\u00a7cCould not connect to default server, please try again later:
|
||||||
|
fallback_lobby=\u00a7cCould not connect to target server, you have been moved to the lobby server
|
||||||
|
lost_connection=[Proxy] Lost connection to server.
|
||||||
|
mojang_fail=Error occurred while contacting login servers, are they down?
|
||||||
|
no_permission=\u00a7cYou do not have permission to execute this command!
|
||||||
|
no_server=\u00a7cThe specified server does not exist
|
||||||
|
no_server_permission=\u00a7cYou don't have permission to access this server
|
||||||
|
outdated_client=Outdated Client!
|
||||||
|
outdated_server=Outdated Server!
|
||||||
|
proxy_full=Server is full
|
||||||
|
restart=[Proxy] Proxy restarting.
|
||||||
|
server_kick=[Kicked]
|
||||||
|
server_list=\u00a76You may connect to the following servers at this time:
|
||||||
|
server_went_down=\u00a7cThe server you were previously on went down, you have been connected to the lobby
|
||||||
|
total_players=Total players online: {0}
|
@@ -1,20 +0,0 @@
|
|||||||
alert: \u00a78[\u00a74Alert\u00a78]\u00a7r
|
|
||||||
already_connected: \u00a7cYou are already connected to this server
|
|
||||||
already_connecting: \u00a7cAlready connecting to this server!
|
|
||||||
connect_kick: \u00a7cKicked whilst connecting to
|
|
||||||
current_server: \u00a76You are currently connected to
|
|
||||||
fallback_kick: \u00a7cCould not connect to default server, please try again later:
|
|
||||||
fallback_lobby: \u00a7cCould not connect to target server, you have been moved to the lobby server
|
|
||||||
lost_connection: [Proxy] Lost connection to server.
|
|
||||||
mojang_fail: Error occurred while contacting login servers, are they down?
|
|
||||||
no_permission: \u00a7cYou do not have permission to execute this command!
|
|
||||||
no_server: \u00a7cThe specified server does not exist
|
|
||||||
no_server_permission: \u00a7cYou don't have permission to access this server
|
|
||||||
outdated_client: Outdated Client!
|
|
||||||
outdated_server: Outdated Server!
|
|
||||||
proxy_full: Server is full
|
|
||||||
restart: [Proxy] Proxy restarting.
|
|
||||||
server_kick: [Kicked]
|
|
||||||
server_list: \u00a76You may connect to the following servers at this time:
|
|
||||||
server_went_down: \u00a7cThe server you were previously on went down, you have been connected to the lobby
|
|
||||||
total_players: Total players online:
|
|
@@ -12,7 +12,13 @@ public class ThrottleTest
|
|||||||
public void testThrottle() throws InterruptedException, UnknownHostException
|
public void testThrottle() throws InterruptedException, UnknownHostException
|
||||||
{
|
{
|
||||||
ConnectionThrottle throttle = new ConnectionThrottle( 5 );
|
ConnectionThrottle throttle = new ConnectionThrottle( 5 );
|
||||||
InetAddress address = InetAddress.getLocalHost();
|
InetAddress address;
|
||||||
|
|
||||||
|
try {
|
||||||
|
address = InetAddress.getLocalHost();
|
||||||
|
} catch (UnknownHostException ex) {
|
||||||
|
address = InetAddress.getByName( null );
|
||||||
|
}
|
||||||
|
|
||||||
Assert.assertFalse( "Address should not be throttled", throttle.throttle( address ) );
|
Assert.assertFalse( "Address should not be throttled", throttle.throttle( address ) );
|
||||||
Assert.assertTrue( "Address should be throttled", throttle.throttle( address ) );
|
Assert.assertTrue( "Address should be throttled", throttle.throttle( address ) );
|
||||||
|
31
query/nb-configuration.xml
Normal file
31
query/nb-configuration.xml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?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>
|
35
query/pom.xml
Normal file
35
query/pom.xml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
<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.6.4-SNAPSHOT</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>net.md-5</groupId>
|
||||||
|
<artifactId>bungeecord-query</artifactId>
|
||||||
|
<version>1.6.4-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>BungeeCord-Query</name>
|
||||||
|
<description>Minecraft query implementation based on the BungeeCord API.</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
<artifactId>netty-transport</artifactId>
|
||||||
|
<version>${netty.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.md-5</groupId>
|
||||||
|
<artifactId>bungeecord-api</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
139
query/src/main/java/net/md_5/bungee/query/QueryHandler.java
Normal file
139
query/src/main/java/net/md_5/bungee/query/QueryHandler.java
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
package net.md_5.bungee.query;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.channel.AddressedEnvelope;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
|
import io.netty.channel.socket.DatagramPacket;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
import net.md_5.bungee.api.config.ListenerInfo;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class QueryHandler extends SimpleChannelInboundHandler<DatagramPacket>
|
||||||
|
{
|
||||||
|
|
||||||
|
private final ProxyServer bungee;
|
||||||
|
private final ListenerInfo listener;
|
||||||
|
/*========================================================================*/
|
||||||
|
private final Random random = new Random();
|
||||||
|
private final Map<Integer, Long> sessions = new HashMap<>();
|
||||||
|
|
||||||
|
private void writeShort(ByteBuf buf, int s)
|
||||||
|
{
|
||||||
|
buf.order( ByteOrder.LITTLE_ENDIAN ).writeShort( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeNumber(ByteBuf buf, int i)
|
||||||
|
{
|
||||||
|
writeString( buf, Integer.toString( i ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeString(ByteBuf buf, String s)
|
||||||
|
{
|
||||||
|
for ( char c : s.toCharArray() )
|
||||||
|
{
|
||||||
|
buf.writeChar( c );
|
||||||
|
}
|
||||||
|
buf.writeByte( 0x00 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception
|
||||||
|
{
|
||||||
|
ByteBuf in = msg.content();
|
||||||
|
if ( in.readUnsignedByte() != 0xFE && in.readUnsignedByte() != 0xFD )
|
||||||
|
{
|
||||||
|
throw new IllegalStateException( "Incorrect magic!" );
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteBuf out = ctx.alloc().buffer();
|
||||||
|
AddressedEnvelope response = new DatagramPacket( out, msg.sender() );
|
||||||
|
|
||||||
|
byte type = in.readByte();
|
||||||
|
int sessionId = in.readInt();
|
||||||
|
|
||||||
|
if ( type == 0x09 )
|
||||||
|
{
|
||||||
|
out.writeByte( 0x09 );
|
||||||
|
out.writeInt( sessionId );
|
||||||
|
|
||||||
|
int challengeToken = random.nextInt();
|
||||||
|
sessions.put( challengeToken, System.currentTimeMillis() );
|
||||||
|
|
||||||
|
writeNumber( out, challengeToken );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( type == 0x00 )
|
||||||
|
{
|
||||||
|
int challengeToken = out.readInt();
|
||||||
|
Long session = sessions.get( challengeToken );
|
||||||
|
if ( session == null || System.currentTimeMillis() - session > TimeUnit.SECONDS.toMillis( 30 ) )
|
||||||
|
{
|
||||||
|
throw new IllegalStateException( "No session!" );
|
||||||
|
}
|
||||||
|
|
||||||
|
out.writeByte( 0x00 );
|
||||||
|
out.writeInt( sessionId );
|
||||||
|
|
||||||
|
if ( in.readableBytes() == 0 )
|
||||||
|
{
|
||||||
|
// Short response
|
||||||
|
writeString( out, listener.getMotd() ); // MOTD
|
||||||
|
writeString( out, "SMP" ); // Game Type
|
||||||
|
writeString( out, "BungeeCord_Proxy" ); // World Name
|
||||||
|
writeNumber( out, bungee.getOnlineCount() ); // Online Count
|
||||||
|
writeNumber( out, listener.getMaxPlayers() ); // Max Players
|
||||||
|
writeShort( out, listener.getHost().getPort() ); // Port
|
||||||
|
writeString( out, listener.getHost().getHostString() ); // IP
|
||||||
|
} else if ( in.readableBytes() == 8 )
|
||||||
|
{
|
||||||
|
// Long Response
|
||||||
|
out.writeBytes( new byte[ 11 ] );
|
||||||
|
Map<String, String> data = new HashMap<>();
|
||||||
|
|
||||||
|
data.put( "hostname", listener.getMotd() );
|
||||||
|
data.put( "gametype", "SMP" );
|
||||||
|
// Start Extra Info
|
||||||
|
data.put( "game_id", "MINECRAFT" );
|
||||||
|
data.put( "version", bungee.getGameVersion() );
|
||||||
|
// data.put( "plugins","");
|
||||||
|
// End Extra Info
|
||||||
|
data.put( "map", "BungeeCord_Proxy" );
|
||||||
|
data.put( "numplayers", Integer.toString( bungee.getOnlineCount() ) );
|
||||||
|
data.put( "maxplayers", Integer.toString( listener.getMaxPlayers() ) );
|
||||||
|
data.put( "hostport", Integer.toString( listener.getHost().getPort() ) );
|
||||||
|
data.put( "hostip", listener.getHost().getHostString() );
|
||||||
|
|
||||||
|
for ( Map.Entry<String, String> entry : data.entrySet() )
|
||||||
|
{
|
||||||
|
writeString( out, entry.getKey() );
|
||||||
|
writeString( out, entry.getValue() );
|
||||||
|
|
||||||
|
}
|
||||||
|
out.writeByte( 0x00 ); // Null
|
||||||
|
|
||||||
|
// Padding
|
||||||
|
out.writeBytes( new byte[ 10 ] );
|
||||||
|
// Player List
|
||||||
|
for ( ProxiedPlayer p : bungee.getPlayers() )
|
||||||
|
{
|
||||||
|
writeString( out, p.getName() );
|
||||||
|
}
|
||||||
|
out.writeByte( 0x00 ); // Null
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
// Error!
|
||||||
|
throw new IllegalStateException( "Invalid data request packet" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.writeAndFlush( response );
|
||||||
|
}
|
||||||
|
}
|
28
query/src/main/java/net/md_5/bungee/query/RemoteQuery.java
Normal file
28
query/src/main/java/net/md_5/bungee/query/RemoteQuery.java
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package net.md_5.bungee.query;
|
||||||
|
|
||||||
|
import io.netty.bootstrap.Bootstrap;
|
||||||
|
import io.netty.channel.ChannelFutureListener;
|
||||||
|
import io.netty.channel.EventLoopGroup;
|
||||||
|
import io.netty.channel.socket.nio.NioDatagramChannel;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
import net.md_5.bungee.api.config.ListenerInfo;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class RemoteQuery
|
||||||
|
{
|
||||||
|
|
||||||
|
private final ProxyServer bungee;
|
||||||
|
private final ListenerInfo listener;
|
||||||
|
|
||||||
|
public void start(InetSocketAddress address, EventLoopGroup eventLoop, ChannelFutureListener future)
|
||||||
|
{
|
||||||
|
new Bootstrap()
|
||||||
|
.channel( NioDatagramChannel.class )
|
||||||
|
.group( eventLoop )
|
||||||
|
.handler( new QueryHandler( bungee, listener ) )
|
||||||
|
.localAddress( address )
|
||||||
|
.bind().addListener( future );
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user