Turn waterfall into a patch-based fork like Spigot and Paper (WIP)

Allows us to easily see and manage the diff with upstream.
Makes fixing conflicts with upstream easier and shows a cleaner, more acurate commit history.

All credits to scripts go to @md_5 @aikar @Zbob750 @Thinkofname @Byteflux @Techcable (GPL3 Licensed)
This commit is contained in:
Techcable 2016-05-28 10:34:39 -06:00
commit 3809083007
No known key found for this signature in database
GPG Key ID: 091A03B91D7FCE68
42 changed files with 4261 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
Waterfall-Proxy

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "BungeeCord"]
path = BungeeCord
url = https://github.com/SpigotMC/BungeeCord.git

1
BungeeCord Submodule

@ -0,0 +1 @@
Subproject commit ec48077dbe2c2c4164468b874d0cb8da949b4d4e

View File

@ -0,0 +1,792 @@
From 8a67ee0be0b56fcefea96a90b54c251f5660cc5f Mon Sep 17 00:00:00 2001
From: Tux <write@imaginarycode.com>
Date: Thu, 19 May 2016 10:33:31 -0700
Subject: [PATCH] POM Changes
Require Java 8
diff --git a/api/pom.xml b/api/pom.xml
index d9363b6..c71c1b1 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -4,42 +4,42 @@
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-parent</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-parent</artifactId>
<version>1.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-api</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-api</artifactId>
<version>1.9-SNAPSHOT</version>
<packaging>jar</packaging>
- <name>BungeeCord-API</name>
+ <name>Waterfall-API</name>
<description>API implemented by the Elastic Portal Suite</description>
<dependencies>
<dependency>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-chat</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-chat</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-config</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-config</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-event</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-event</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-protocol</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-protocol</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
diff --git a/bootstrap/pom.xml b/bootstrap/pom.xml
index 0c02349..0785736 100644
--- a/bootstrap/pom.xml
+++ b/bootstrap/pom.xml
@@ -4,19 +4,19 @@
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-parent</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-parent</artifactId>
<version>1.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-bootstrap</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-bootstrap</artifactId>
<version>1.9-SNAPSHOT</version>
<packaging>jar</packaging>
- <name>BungeeCord-Bootstrap</name>
- <description>Java 1.6 loader for BungeeCord</description>
+ <name>Waterfall-Bootstrap</name>
+ <description>Java 1.6 loader for Waterfall</description>
<properties>
<maven.compiler.source>1.6</maven.compiler.source>
@@ -26,8 +26,8 @@
<dependencies>
<dependency>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-proxy</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-proxy</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
@@ -40,7 +40,7 @@
</dependencies>
<build>
- <finalName>BungeeCord</finalName>
+ <finalName>Waterfall</finalName>
<plugins>
<plugin>
<!-- Don't deploy proxy to maven repo, only APIs -->
@@ -57,7 +57,7 @@
<configuration>
<archive>
<manifestEntries>
- <Main-Class>net.md_5.bungee.Bootstrap</Main-Class>
+ <Main-Class>net.md_5.bungee.Bootstrap</Main-Class>
<Implementation-Version>${describe}</Implementation-Version>
<Specification-Version>${maven.build.timestamp}</Specification-Version>
</manifestEntries>
diff --git a/bootstrap/src/main/java/net/md_5/bungee/Bootstrap.java b/bootstrap/src/main/java/net/md_5/bungee/Bootstrap.java
index b7cb81e..a4516ed 100644
--- a/bootstrap/src/main/java/net/md_5/bungee/Bootstrap.java
+++ b/bootstrap/src/main/java/net/md_5/bungee/Bootstrap.java
@@ -5,9 +5,9 @@ public class Bootstrap
public static void main(String[] args) throws Exception
{
- if ( Float.parseFloat( System.getProperty( "java.class.version" ) ) < 51.0 )
+ if ( Float.parseFloat( System.getProperty( "java.class.version" ) ) < 52.0 )
{
- System.err.println( "*** ERROR *** BungeeCord requires Java 7 or above to function! Please download and install it!" );
+ System.err.println( "*** ERROR *** Waterfall requires Java 8 or above to function! Please download and install it!" );
System.out.println( "You can check your Java version with the command: java -version" );
return;
}
diff --git a/chat/pom.xml b/chat/pom.xml
index 0b447c1..7ff3224 100644
--- a/chat/pom.xml
+++ b/chat/pom.xml
@@ -4,23 +4,24 @@
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-parent</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-parent</artifactId>
<version>1.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-chat</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-chat</artifactId>
<version>1.9-SNAPSHOT</version>
<packaging>jar</packaging>
- <name>BungeeCord-Chat</name>
- <description>Minecraft JSON chat API intended for use with BungeeCord</description>
+ <name>Waterfall-Chat</name>
+ <description>Minecraft JSON chat API intended for use with Waterfall</description>
<properties>
- <maven.compiler.source>1.6</maven.compiler.source>
- <maven.compiler.target>1.6</maven.compiler.target>
+ <!-- Require Java 8, not Java 6 -->
+ <maven.compiler.source>1.8</maven.compiler.source>
+ <maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
diff --git a/config/pom.xml b/config/pom.xml
index 5c99e14..29e50dc 100644
--- a/config/pom.xml
+++ b/config/pom.xml
@@ -4,19 +4,19 @@
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-parent</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-parent</artifactId>
<version>1.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-config</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-config</artifactId>
<version>1.9-SNAPSHOT</version>
<packaging>jar</packaging>
- <name>BungeeCord-Config</name>
- <description>Generic java configuration API intended for use with BungeeCord</description>
+ <name>Waterfall-Config</name>
+ <description>Generic java configuration API intended for use with Waterfall</description>
<dependencies>
<dependency>
diff --git a/event/pom.xml b/event/pom.xml
index a5fee80..b6ef990 100644
--- a/event/pom.xml
+++ b/event/pom.xml
@@ -4,17 +4,17 @@
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-parent</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-parent</artifactId>
<version>1.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-event</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-event</artifactId>
<version>1.9-SNAPSHOT</version>
<packaging>jar</packaging>
- <name>BungeeCord-Event</name>
- <description>Generic java event dispatching API intended for use with BungeeCord</description>
+ <name>Waterfall-Event</name>
+ <description>Generic java event dispatching API intended for use with Waterfall.</description>
</project>
diff --git a/module/cmd-alert/pom.xml b/module/cmd-alert/pom.xml
index 1cc7fef..bc71a34 100644
--- a/module/cmd-alert/pom.xml
+++ b/module/cmd-alert/pom.xml
@@ -4,14 +4,14 @@
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-module</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-module</artifactId>
<version>1.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-module-cmd-alert</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-module-cmd-alert</artifactId>
<version>1.9-SNAPSHOT</version>
<packaging>jar</packaging>
diff --git a/module/cmd-find/pom.xml b/module/cmd-find/pom.xml
index 10b6a4f..a4e9f89 100644
--- a/module/cmd-find/pom.xml
+++ b/module/cmd-find/pom.xml
@@ -4,14 +4,14 @@
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-module</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-module</artifactId>
<version>1.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-module-cmd-find</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-module-cmd-find</artifactId>
<version>1.9-SNAPSHOT</version>
<packaging>jar</packaging>
diff --git a/module/cmd-list/pom.xml b/module/cmd-list/pom.xml
index 774b694..6f4f4a7 100644
--- a/module/cmd-list/pom.xml
+++ b/module/cmd-list/pom.xml
@@ -4,14 +4,14 @@
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-module</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-module</artifactId>
<version>1.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-module-cmd-list</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-module-cmd-list</artifactId>
<version>1.9-SNAPSHOT</version>
<packaging>jar</packaging>
diff --git a/module/cmd-send/pom.xml b/module/cmd-send/pom.xml
index 15d03fc..7481b49 100644
--- a/module/cmd-send/pom.xml
+++ b/module/cmd-send/pom.xml
@@ -4,14 +4,14 @@
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-module</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-module</artifactId>
<version>1.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-module-cmd-send</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-module-cmd-send</artifactId>
<version>1.9-SNAPSHOT</version>
<packaging>jar</packaging>
diff --git a/module/cmd-server/pom.xml b/module/cmd-server/pom.xml
index a72db68..1be3c11 100644
--- a/module/cmd-server/pom.xml
+++ b/module/cmd-server/pom.xml
@@ -4,14 +4,14 @@
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-module</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-module</artifactId>
<version>1.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-module-cmd-server</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-module-cmd-server</artifactId>
<version>1.9-SNAPSHOT</version>
<packaging>jar</packaging>
diff --git a/module/pom.xml b/module/pom.xml
index 3482d0d..100b8d7 100644
--- a/module/pom.xml
+++ b/module/pom.xml
@@ -4,19 +4,19 @@
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-parent</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-parent</artifactId>
<version>1.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-module</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-module</artifactId>
<version>1.9-SNAPSHOT</version>
<packaging>pom</packaging>
- <name>BungeeCord Modules</name>
- <description>Parent project for all BungeeCord modules.</description>
+ <name>Waterfall Modules</name>
+ <description>Parent project for all Waterfall modules.</description>
<modules>
<module>cmd-alert</module>
@@ -33,8 +33,8 @@
<dependencies>
<dependency>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-api</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-api</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
diff --git a/module/reconnect-yaml/pom.xml b/module/reconnect-yaml/pom.xml
index bf5ae48..c0f55ba 100644
--- a/module/reconnect-yaml/pom.xml
+++ b/module/reconnect-yaml/pom.xml
@@ -4,14 +4,14 @@
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-module</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-module</artifactId>
<version>1.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-module-reconnect-yaml</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-module-reconnect-yaml</artifactId>
<version>1.9-SNAPSHOT</version>
<packaging>jar</packaging>
diff --git a/native/pom.xml b/native/pom.xml
index fb12cc4..5dd2e51 100644
--- a/native/pom.xml
+++ b/native/pom.xml
@@ -4,19 +4,19 @@
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-parent</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-parent</artifactId>
<version>1.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-native</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-native</artifactId>
<version>1.9-SNAPSHOT</version>
<packaging>jar</packaging>
- <name>BungeeCord-Native</name>
- <description>Optional native code to speed up and enhance BungeeCord functionality.</description>
+ <name>Waterfall-Native</name>
+ <description>Optional native code to speed up and enhance Waterfall functionality.</description>
<dependencies>
<dependency>
diff --git a/pom.xml b/pom.xml
index d8d7c02..badd9c4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,24 +3,18 @@
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>org.sonatype.oss</groupId>
- <artifactId>oss-parent</artifactId>
- <version>9</version>
- </parent>
-
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-parent</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-parent</artifactId>
<version>1.9-SNAPSHOT</version>
<packaging>pom</packaging>
- <name>BungeeCord-Parent</name>
- <description>Parent project for all BungeeCord modules.</description>
- <url>https://github.com/SpigotMC/BungeeCord</url>
- <inceptionYear>2012</inceptionYear>
+ <name>Waterfall-Parent</name>
+ <description>Parent project for all Waterfall modules.</description>
+ <url>https://github.com/WaterfallMC/Waterfall</url>
+ <inceptionYear>2015</inceptionYear>
<organization>
- <name>SpigotMC</name>
- <url>https://github.com/SpigotMC</url>
+ <name>WaterfallMC</name>
+ <url>https://github.com/WaterfallMC</url>
</organization>
<licenses>
<license>
@@ -32,7 +26,13 @@
<developers>
<developer>
- <id>md_5</id>
+ <id>Tux</id>
+ </developer>
+ <developer>
+ <id>Techcable</id>
+ </developer>
+ <developer>
+ <id>kashike</id>
</developer>
</developers>
@@ -50,24 +50,36 @@
</modules>
<scm>
- <connection>scm:git:git@github.com:SpigotMC/BungeeCord.git</connection>
- <developerConnection>scm:git:git@github.com:SpigotMC/BungeeCord.git</developerConnection>
- <url>git@github.com:SpigotMC/BungeeCord.git</url>
+ <connection>scm:git:git@github.com:com:WaterfallMC/Waterfall.git</connection>
+ <developerConnection>scm:git:git@github.com:WaterfallMC/Waterfall.git</developerConnection>
+ <url>git@github.com:WaterfallMC/Waterfall.git</url>
</scm>
<issueManagement>
<system>GitHub</system>
- <url>https://github.com/SpigotMC/BungeeCord/issues</url>
+ <url>https://github.com/WaterfallMC/Waterfall/issues</url>
</issueManagement>
<ciManagement>
- <system>jenkins</system>
- <url>http://ci.md-5.net/job/BungeeCord</url>
+ <system>teamcity</system>
+ <url>https://getwaterfall.xyz/builds/</url>
</ciManagement>
+ <distributionManagement>
+ <repository>
+ <id>ellune-releases</id>
+ <url>https://repo.ellune.net/content/repositories/releases/</url>
+ </repository>
+ <snapshotRepository>
+ <id>ellune-snapshots</id>
+ <url>https://repo.ellune.net/content/repositories/snapshots/</url>
+ </snapshotRepository>
+ </distributionManagement>
+
<properties>
<build.number>unknown</build.number>
<netty.version>4.0.33.Final</netty.version>
- <maven.compiler.source>1.7</maven.compiler.source>
- <maven.compiler.target>1.7</maven.compiler.target>
+ <!-- Require Java 8 -->
+ <maven.compiler.source>1.8</maven.compiler.source>
+ <maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
@@ -93,12 +105,13 @@
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
- <version>1.14.8</version>
+ <version>1.16.8</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
+ <defaultGoal>clean install</defaultGoal>
<plugins>
<plugin>
<groupId>net.md-5</groupId>
@@ -116,36 +129,14 @@
</execution>
</executions>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>animal-sniffer-maven-plugin</artifactId>
- <version>1.13</version>
- <executions>
- <execution>
- <phase>process-classes</phase>
- <goals>
- <goal>check</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <ignores>
- <ignore>java.lang.ClassLoader</ignore>
- <ignore>java.lang.Throwable</ignore>
- <ignore>java.util.Locale</ignore>
- </ignores>
- <signature>
- <groupId>org.codehaus.mojo.signature</groupId>
- <artifactId>java16</artifactId>
- <version>1.1</version>
- </signature>
- </configuration>
- </plugin>
<!-- OSS Parent 9 uses 2.7, 2.10+ is broken anyway -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.7</version>
+ <configuration>
+ <additionalparam>-Xdoclint:none</additionalparam>
+ </configuration>
</plugin>
</plugins>
<pluginManagement>
@@ -180,4 +171,49 @@
</plugins>
</pluginManagement>
</build>
+
+ <profiles>
+ <profile>
+ <id>deployment</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.7</version>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <phase>package</phase>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ <configuration>
+ <additionalparam>-Xdoclint:none</additionalparam>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.4</version>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <phase>package</phase>
+ <goals>
+ <goal>jar-no-fork</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
</project>
diff --git a/protocol/pom.xml b/protocol/pom.xml
index 9e816ab..8b462f5 100644
--- a/protocol/pom.xml
+++ b/protocol/pom.xml
@@ -4,24 +4,24 @@
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-parent</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-parent</artifactId>
<version>1.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-protocol</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-protocol</artifactId>
<version>1.9-SNAPSHOT</version>
<packaging>jar</packaging>
- <name>BungeeCord-Protocol</name>
- <description>Minimal implementation of the Minecraft protocol for use in BungeeCord</description>
+ <name>Waterfall-Protocol</name>
+ <description>Minimal implementation of the Minecraft protocol for use in Waterfall</description>
<dependencies>
<dependency>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-chat</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-chat</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
diff --git a/proxy/pom.xml b/proxy/pom.xml
index 44ff3ff..3fe4937 100644
--- a/proxy/pom.xml
+++ b/proxy/pom.xml
@@ -4,18 +4,18 @@
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-parent</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-parent</artifactId>
<version>1.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-proxy</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-proxy</artifactId>
<version>1.9-SNAPSHOT</version>
<packaging>jar</packaging>
- <name>BungeeCord-Proxy</name>
+ <name>Waterfall-Proxy</name>
<description>Proxy component of the Elastic Portal Suite</description>
<dependencies>
@@ -39,26 +39,26 @@
<scope>compile</scope>
</dependency>
<dependency>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-api</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-api</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-native</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-native</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-protocol</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-protocol</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-query</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-query</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
diff --git a/query/pom.xml b/query/pom.xml
index 81bd2c7..dbb2e81 100644
--- a/query/pom.xml
+++ b/query/pom.xml
@@ -4,19 +4,19 @@
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-parent</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-parent</artifactId>
<version>1.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-query</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-query</artifactId>
<version>1.9-SNAPSHOT</version>
<packaging>jar</packaging>
- <name>BungeeCord-Query</name>
- <description>Minecraft query implementation based on the BungeeCord API.</description>
+ <name>Waterfall-Query</name>
+ <description>Minecraft query implementation based on the Waterfall API.</description>
<dependencies>
<dependency>
@@ -26,8 +26,8 @@
<scope>compile</scope>
</dependency>
<dependency>
- <groupId>net.md-5</groupId>
- <artifactId>bungeecord-api</artifactId>
+ <groupId>io.github.waterfallmc</groupId>
+ <artifactId>waterfall-api</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
--
2.8.3

View File

@ -0,0 +1,109 @@
From 8b0e4da4f4b65ace743c2124dffb55cc5e9b2ea1 Mon Sep 17 00:00:00 2001
From: Tux <write@imaginarycode.com>
Date: Thu, 19 May 2016 11:28:45 -0700
Subject: [PATCH] Rename references from BungeeCord to Waterfall
diff --git a/bootstrap/src/main/java/net/md_5/bungee/BungeeCordLauncher.java b/bootstrap/src/main/java/net/md_5/bungee/BungeeCordLauncher.java
index 3c1bbe9..2a41a50 100644
--- a/bootstrap/src/main/java/net/md_5/bungee/BungeeCordLauncher.java
+++ b/bootstrap/src/main/java/net/md_5/bungee/BungeeCordLauncher.java
@@ -51,7 +51,7 @@ public class BungeeCordLauncher
BungeeCord bungee = new BungeeCord();
ProxyServer.setInstance( bungee );
- bungee.getLogger().info( "Enabled BungeeCord version " + bungee.getVersion() );
+ bungee.getLogger().info( "Enabled Waterfall version " + bungee.getVersion() );
bungee.start();
if ( !options.has( "noconsole" ) )
diff --git a/proxy/src/main/java/Test.java b/proxy/src/main/java/Test.java
index 9d51608..446dfe2 100644
--- a/proxy/src/main/java/Test.java
+++ b/proxy/src/main/java/Test.java
@@ -19,7 +19,7 @@ public class Test
{
BungeeCord bungee = new BungeeCord();
ProxyServer.setInstance( bungee );
- bungee.getLogger().info( "Enabled BungeeCord version " + bungee.getVersion() );
+ bungee.getLogger().info( "Enabled Waterfall version " + bungee.getVersion() );
bungee.start();
while ( bungee.isRunning )
diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
index ac08d8e..8ce4ced 100644
--- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
+++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
@@ -172,7 +172,7 @@ public class BungeeCord extends ProxyServer
public BungeeCord() throws IOException
{
// Java uses ! to indicate a resource inside of a jar/zip/other container. Running Bungee from within a directory that has a ! will cause this to muck up.
- Preconditions.checkState( new File( "." ).getAbsolutePath().indexOf( '!' ) == -1, "Cannot use BungeeCord in directory with ! in path." );
+ Preconditions.checkState( new File( "." ).getAbsolutePath().indexOf( '!' ) == -1, "Cannot use Waterfall in directory with ! in path." );
System.setSecurityManager( new BungeeSecurityManager() );
@@ -457,7 +457,7 @@ public class BungeeCord extends ProxyServer
@Override
public String getName()
{
- return "BungeeCord";
+ return "Waterfall";
}
@Override
diff --git a/proxy/src/main/java/net/md_5/bungee/command/CommandBungee.java b/proxy/src/main/java/net/md_5/bungee/command/CommandBungee.java
index b079879..b26035c 100644
--- a/proxy/src/main/java/net/md_5/bungee/command/CommandBungee.java
+++ b/proxy/src/main/java/net/md_5/bungee/command/CommandBungee.java
@@ -16,6 +16,6 @@ public class CommandBungee extends Command
@Override
public void execute(CommandSender sender, String[] args)
{
- sender.sendMessage( ChatColor.BLUE + "This server is running BungeeCord version " + ProxyServer.getInstance().getVersion() + " by md_5" );
+ sender.sendMessage( ChatColor.BLUE + "This server is running Waterfall version " + ProxyServer.getInstance().getVersion() + " by md_5" );
}
}
diff --git a/proxy/src/main/java/net/md_5/bungee/command/CommandReload.java b/proxy/src/main/java/net/md_5/bungee/command/CommandReload.java
index cbbe03c..4a49241 100644
--- a/proxy/src/main/java/net/md_5/bungee/command/CommandReload.java
+++ b/proxy/src/main/java/net/md_5/bungee/command/CommandReload.java
@@ -22,7 +22,7 @@ public class CommandReload extends Command
BungeeCord.getInstance().startListeners();
BungeeCord.getInstance().getPluginManager().callEvent( new ProxyReloadEvent( sender ) );
- sender.sendMessage( ChatColor.BOLD.toString() + ChatColor.RED.toString() + "BungeeCord has been reloaded."
- + " This is NOT advisable and you will not be supported with any issues that arise! Please restart BungeeCord ASAP." );
+ sender.sendMessage( ChatColor.BOLD.toString() + ChatColor.RED.toString() + "Waterfall has been reloaded."
+ + " This is NOT advisable and you will not be supported with any issues that arise! Please restart Waterfall ASAP." );
}
}
diff --git a/proxy/src/main/java/net/md_5/bungee/conf/YamlConfig.java b/proxy/src/main/java/net/md_5/bungee/conf/YamlConfig.java
index c7547c7..82ff91a 100644
--- a/proxy/src/main/java/net/md_5/bungee/conf/YamlConfig.java
+++ b/proxy/src/main/java/net/md_5/bungee/conf/YamlConfig.java
@@ -200,7 +200,7 @@ public class YamlConfig implements ConfigurationAdapter
Map<String, Object> val = entry.getValue();
String name = entry.getKey();
String addr = get( "address", "localhost:25565", val );
- String motd = ChatColor.translateAlternateColorCodes( '&', get( "motd", "&1Just another BungeeCord - Forced Host", val ) );
+ String motd = ChatColor.translateAlternateColorCodes( '&', get( "motd", "&1Just another Waterfall - Forced Host", val ) );
boolean restricted = get( "restricted", false, val );
InetSocketAddress address = Util.getAddr( addr );
ServerInfo info = ProxyServer.getInstance().constructServerInfo( name, address, motd, restricted );
diff --git a/proxy/src/main/java/net/md_5/bungee/log/LogDispatcher.java b/proxy/src/main/java/net/md_5/bungee/log/LogDispatcher.java
index f1ccd4f..d703d6d 100644
--- a/proxy/src/main/java/net/md_5/bungee/log/LogDispatcher.java
+++ b/proxy/src/main/java/net/md_5/bungee/log/LogDispatcher.java
@@ -12,7 +12,7 @@ public class LogDispatcher extends Thread
public LogDispatcher(BungeeLogger logger)
{
- super( "BungeeCord Logger Thread" );
+ super( "Waterfall Logger Thread" );
this.logger = logger;
}
--
2.8.3

View File

@ -0,0 +1,124 @@
From b790b1d946c66a57af7550795bf63fad398bb137 Mon Sep 17 00:00:00 2001
From: Techcable <Techcable@techcable.net>
Date: Thu, 19 May 2016 10:46:46 -0700
Subject: [PATCH] Add Waterfall configuration files
diff --git a/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java b/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java
index edd82c1..b30541b 100644
--- a/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java
+++ b/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java
@@ -79,4 +79,9 @@ public interface ProxyConfig
* The favicon used for the server ping list.
*/
Favicon getFaviconObject();
+
+ //
+ // Waterfall Options
+ //
+
}
diff --git a/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java b/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java
new file mode 100644
index 0000000..03160da
--- /dev/null
+++ b/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java
@@ -0,0 +1,19 @@
+
+package io.github.waterfallmc.waterfall.conf;
+
+import lombok.*;
+
+import java.io.File;
+
+import net.md_5.bungee.conf.Configuration;
+import net.md_5.bungee.conf.YamlConfig;
+
+public class WaterfallConfiguration extends Configuration {
+
+ @Override
+ public void load() {
+ super.load();
+ YamlConfig config = new YamlConfig(new File("waterfall.yml"));
+ config.load(false); // Load, but no permissions
+ }
+}
diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
index 8ce4ced..3dceb6e 100644
--- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
+++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
@@ -23,6 +23,7 @@ import net.md_5.bungee.scheduler.BungeeScheduler;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.google.gson.Gson;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import io.github.waterfallmc.waterfall.conf.WaterfallConfiguration;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelException;
@@ -98,7 +99,7 @@ public class BungeeCord extends ProxyServer
* Configuration.
*/
@Getter
- public final Configuration config = new Configuration();
+ public final Configuration config = new WaterfallConfiguration();
/**
* Localization bundle.
*/
diff --git a/proxy/src/main/java/net/md_5/bungee/conf/Configuration.java b/proxy/src/main/java/net/md_5/bungee/conf/Configuration.java
index 25d87d9..81dd4af 100644
--- a/proxy/src/main/java/net/md_5/bungee/conf/Configuration.java
+++ b/proxy/src/main/java/net/md_5/bungee/conf/Configuration.java
@@ -24,7 +24,7 @@ import net.md_5.bungee.util.CaseInsensitiveSet;
* Core configuration for the proxy.
*/
@Getter
-public class Configuration implements ProxyConfig
+public abstract class Configuration implements ProxyConfig
{
/**
diff --git a/proxy/src/main/java/net/md_5/bungee/conf/YamlConfig.java b/proxy/src/main/java/net/md_5/bungee/conf/YamlConfig.java
index 82ff91a..4ec9782 100644
--- a/proxy/src/main/java/net/md_5/bungee/conf/YamlConfig.java
+++ b/proxy/src/main/java/net/md_5/bungee/conf/YamlConfig.java
@@ -42,10 +42,15 @@ public class YamlConfig implements ConfigurationAdapter
}
private final Yaml yaml;
private Map config;
- private final File file = new File( "config.yml" );
+ private final File file;
- public YamlConfig()
+ public YamlConfig() {
+ this(new File("config.yml"));
+ }
+
+ public YamlConfig(File file)
{
+ this.file = file;
DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle( DumperOptions.FlowStyle.BLOCK );
yaml = new Yaml( options );
@@ -54,6 +59,11 @@ public class YamlConfig implements ConfigurationAdapter
@Override
public void load()
{
+ load(true);
+ }
+
+ public void load(boolean doPermissions)
+ {
try
{
file.createNewFile();
@@ -75,6 +85,7 @@ public class YamlConfig implements ConfigurationAdapter
throw new RuntimeException( "Could not load configuration!", ex );
}
+ if (!doPermissions) return;
Map<String, Object> permissions = get( "permissions", new HashMap<String, Object>() );
if ( permissions.isEmpty() )
{
--
2.8.3

View File

@ -0,0 +1,345 @@
From 5c789d7ac0a98e7ccc5ae6bccedef59621bb9c7f Mon Sep 17 00:00:00 2001
From: Techcable <Techcable@techcable.net>
Date: Thu, 19 May 2016 10:55:20 -0700
Subject: [PATCH] Configurable Waterfall Metrics
diff --git a/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java b/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java
index b30541b..293ec4e 100644
--- a/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java
+++ b/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java
@@ -84,4 +84,8 @@ public interface ProxyConfig
// Waterfall Options
//
+ /**
+ * If metrics is enabled
+ */
+ boolean isMetrics();
}
diff --git a/proxy/src/main/java/io/github/waterfallmc/waterfall/Metrics.java b/proxy/src/main/java/io/github/waterfallmc/waterfall/Metrics.java
new file mode 100644
index 0000000..ae5a2a9
--- /dev/null
+++ b/proxy/src/main/java/io/github/waterfallmc/waterfall/Metrics.java
@@ -0,0 +1,131 @@
+package io.github.waterfallmc.waterfall;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.util.TimerTask;
+
+import net.md_5.bungee.BungeeCord;
+import net.md_5.bungee.api.ProxyServer;
+
+public class Metrics extends TimerTask
+{
+
+ /**
+ * The current revision number
+ */
+ private final static int REVISION = 5;
+ /**
+ * The base url of the metrics domain
+ */
+ private static final String BASE_URL = "http://mcstats.org";
+ /**
+ * The url used to report a server's status
+ */
+ private static final String REPORT_URL = "/report/%s";
+ /**
+ * Interval of time to ping (in minutes)
+ */
+ public final static int PING_INTERVAL = 10;
+ boolean firstPost = true;
+
+ @Override
+ public void run()
+ {
+ try
+ {
+ // We use the inverse of firstPost because if it is the first time we are posting,
+ // it is not a interval ping, so it evaluates to FALSE
+ // Each time thereafter it will evaluate to TRUE, i.e PING!
+ postPlugin( !firstPost );
+
+ // After the first post we set firstPost to false
+ // Each post thereafter will be a ping
+ firstPost = false;
+ } catch ( IOException ex )
+ {
+ // ProxyServer.getInstance().getLogger().info( "[Metrics] " + ex.getMessage() );
+ }
+ }
+
+ /**
+ * Generic method that posts a plugin to the metrics website
+ */
+ private void postPlugin(boolean isPing) throws IOException
+ {
+ // Construct the post data
+ final StringBuilder data = new StringBuilder();
+ data.append( encode( "guid" ) ).append( '=' ).append( encode( BungeeCord.getInstance().config.getUuid() ) );
+ encodeDataPair( data, "version", ProxyServer.getInstance().getVersion() );
+ encodeDataPair( data, "server", "0" );
+ encodeDataPair( data, "players", Integer.toString( ProxyServer.getInstance().getOnlineCount() ) );
+ encodeDataPair( data, "revision", String.valueOf( REVISION ) );
+
+ // If we're pinging, append it
+ if ( isPing )
+ {
+ encodeDataPair( data, "ping", "true" );
+ }
+
+ // Create the url
+ URL url = new URL( BASE_URL + String.format( REPORT_URL, encode( "Waterfall" ) ) );
+
+ // Connect to the website
+ URLConnection connection;
+
+ connection = url.openConnection();
+
+ connection.setDoOutput( true );
+ final BufferedReader reader;
+ final String response;
+ try ( OutputStreamWriter writer = new OutputStreamWriter( connection.getOutputStream() ) )
+ {
+ writer.write( data.toString() );
+ writer.flush();
+ reader = new BufferedReader( new InputStreamReader( connection.getInputStream() ) );
+ response = reader.readLine();
+ }
+ reader.close();
+
+ if ( response == null || response.startsWith( "ERR" ) )
+ {
+ throw new IOException( response ); //Throw the exception
+ }
+ }
+
+ /**
+ * <p>
+ * Encode a key/value data pair to be used in a HTTP post request. This
+ * INCLUDES a & so the first key/value pair MUST be included manually,
+ * e.g:</p>
+ * <code>
+ * StringBuffer data = new StringBuffer();
+ * data.append(encode("guid")).append('=').append(encode(guid));
+ * encodeDataPair(data, "version", description.getVersion());
+ * </code>
+ *
+ * @param buffer the StringBuilder to append the data pair onto
+ * @param key the key value
+ * @param value the value
+ */
+ private static void encodeDataPair(final StringBuilder buffer, final String key, final String value) throws UnsupportedEncodingException
+ {
+ buffer.append( '&' ).append( encode( key ) ).append( '=' ).append( encode( value ) );
+ }
+
+ /**
+ * Encode text as UTF-8
+ *
+ * @param text the text to encode
+ * @return the encoded text, as UTF-8
+ */
+ private static String encode(final String text) throws UnsupportedEncodingException
+ {
+ return URLEncoder.encode( text, "UTF-8" );
+ }
+}
diff --git a/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java b/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java
index 03160da..1fa3ecd 100644
--- a/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java
+++ b/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java
@@ -10,10 +10,23 @@ import net.md_5.bungee.conf.YamlConfig;
public class WaterfallConfiguration extends Configuration {
+ /**
+ * If metrics is enabled
+ * <p>
+ * Default is true (enabled)
+ */
+ private boolean metrics = true;
+
@Override
public void load() {
super.load();
YamlConfig config = new YamlConfig(new File("waterfall.yml"));
config.load(false); // Load, but no permissions
+ metrics = config.getBoolean("metrics", metrics);
+ }
+
+ @Override
+ public boolean isMetrics() {
+ return metrics;
}
}
diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
index 3dceb6e..3578aa4 100644
--- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
+++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
@@ -23,6 +23,7 @@ import net.md_5.bungee.scheduler.BungeeScheduler;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.google.gson.Gson;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import io.github.waterfallmc.waterfall.Metrics;
import io.github.waterfallmc.waterfall.conf.WaterfallConfiguration;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
@@ -284,7 +285,9 @@ public class BungeeCord extends ProxyServer
}
}
}, 0, TimeUnit.MINUTES.toMillis( 5 ) );
- metricsThread.scheduleAtFixedRate( new Metrics(), 0, TimeUnit.MINUTES.toMillis( Metrics.PING_INTERVAL ) );
+ if (config.isMetrics()) {
+ metricsThread.scheduleAtFixedRate( new Metrics(), 0, TimeUnit.MINUTES.toMillis( Metrics.PING_INTERVAL ) );
+ }
}
public void startListeners()
diff --git a/proxy/src/main/java/net/md_5/bungee/Metrics.java b/proxy/src/main/java/net/md_5/bungee/Metrics.java
deleted file mode 100644
index 9523987..0000000
--- a/proxy/src/main/java/net/md_5/bungee/Metrics.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package net.md_5.bungee;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.io.UnsupportedEncodingException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.net.URLEncoder;
-import java.util.TimerTask;
-import net.md_5.bungee.api.ProxyServer;
-
-public class Metrics extends TimerTask
-{
-
- /**
- * The current revision number
- */
- private final static int REVISION = 5;
- /**
- * The base url of the metrics domain
- */
- private static final String BASE_URL = "http://mcstats.org";
- /**
- * The url used to report a server's status
- */
- private static final String REPORT_URL = "/report/%s";
- /**
- * Interval of time to ping (in minutes)
- */
- final static int PING_INTERVAL = 10;
- boolean firstPost = true;
-
- @Override
- public void run()
- {
- try
- {
- // We use the inverse of firstPost because if it is the first time we are posting,
- // it is not a interval ping, so it evaluates to FALSE
- // Each time thereafter it will evaluate to TRUE, i.e PING!
- postPlugin( !firstPost );
-
- // After the first post we set firstPost to false
- // Each post thereafter will be a ping
- firstPost = false;
- } catch ( IOException ex )
- {
- // ProxyServer.getInstance().getLogger().info( "[Metrics] " + ex.getMessage() );
- }
- }
-
- /**
- * Generic method that posts a plugin to the metrics website
- */
- private void postPlugin(boolean isPing) throws IOException
- {
- // Construct the post data
- final StringBuilder data = new StringBuilder();
- data.append( encode( "guid" ) ).append( '=' ).append( encode( BungeeCord.getInstance().config.getUuid() ) );
- encodeDataPair( data, "version", ProxyServer.getInstance().getVersion() );
- encodeDataPair( data, "server", "0" );
- encodeDataPair( data, "players", Integer.toString( ProxyServer.getInstance().getOnlineCount() ) );
- encodeDataPair( data, "revision", String.valueOf( REVISION ) );
-
- // If we're pinging, append it
- if ( isPing )
- {
- encodeDataPair( data, "ping", "true" );
- }
-
- // Create the url
- URL url = new URL( BASE_URL + String.format( REPORT_URL, encode( "BungeeCord" ) ) );
-
- // Connect to the website
- URLConnection connection;
-
- connection = url.openConnection();
-
- connection.setDoOutput( true );
- final BufferedReader reader;
- final String response;
- try ( OutputStreamWriter writer = new OutputStreamWriter( connection.getOutputStream() ) )
- {
- writer.write( data.toString() );
- writer.flush();
- reader = new BufferedReader( new InputStreamReader( connection.getInputStream() ) );
- response = reader.readLine();
- }
- reader.close();
-
- if ( response == null || response.startsWith( "ERR" ) )
- {
- throw new IOException( response ); //Throw the exception
- }
- }
-
- /**
- * <p>
- * Encode a key/value data pair to be used in a HTTP post request. This
- * INCLUDES a & so the first key/value pair MUST be included manually,
- * e.g:</p>
- * <code>
- * StringBuffer data = new StringBuffer();
- * data.append(encode("guid")).append('=').append(encode(guid));
- * encodeDataPair(data, "version", description.getVersion());
- * </code>
- *
- * @param buffer the StringBuilder to append the data pair onto
- * @param key the key value
- * @param value the value
- */
- private static void encodeDataPair(final StringBuilder buffer, final String key, final String value) throws UnsupportedEncodingException
- {
- buffer.append( '&' ).append( encode( key ) ).append( '=' ).append( encode( value ) );
- }
-
- /**
- * Encode text as UTF-8
- *
- * @param text the text to encode
- * @return the encoded text, as UTF-8
- */
- private static String encode(final String text) throws UnsupportedEncodingException
- {
- return URLEncoder.encode( text, "UTF-8" );
- }
-}
--
2.8.3

View File

@ -0,0 +1,45 @@
From 248f19f83a821f87e64714766803284e73187be8 Mon Sep 17 00:00:00 2001
From: Tux <write@imaginarycode.com>
Date: Thu, 19 May 2016 11:34:52 -0700
Subject: [PATCH] Fetch modules from the Waterfall CI
Don't fetch from the BungeeCord CI, as that only has their modules
diff --git a/proxy/src/main/java/net/md_5/bungee/module/JenkinsModuleSource.java b/proxy/src/main/java/net/md_5/bungee/module/JenkinsModuleSource.java
index 9bd2dc9..97a08da 100644
--- a/proxy/src/main/java/net/md_5/bungee/module/JenkinsModuleSource.java
+++ b/proxy/src/main/java/net/md_5/bungee/module/JenkinsModuleSource.java
@@ -1,10 +1,11 @@
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 java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+
import lombok.Data;
import net.md_5.bungee.Util;
@@ -18,13 +19,14 @@ public class JenkinsModuleSource implements ModuleSource
System.out.println( "Attempting to Jenkins download module " + module.getName() + " v" + version.getBuild() );
try
{
- URL website = new URL( "http://ci.md-5.net/job/BungeeCord/" + version.getBuild() + "/artifact/module/" + module.getName().replace( '_', '-' ) + "/target/" + module.getName() + ".jar" );
+ URL website = new URL( "https://tc.demonwav.com/guestAuth/repository/download/Waterfall_Build/" + version.getBuild() + "/" + module.getName() + ".jar" );
URLConnection con = website.openConnection();
// 15 second timeout at various stages
con.setConnectTimeout( 15000 );
con.setReadTimeout( 15000 );
+ con.setRequestProperty("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36");
- Files.write( ByteStreams.toByteArray( con.getInputStream() ), module.getFile() );
+ Files.copy(con.getInputStream(), module.getFile().toPath(), StandardCopyOption.REPLACE_EXISTING);
System.out.println( "Download complete" );
} catch ( IOException ex )
{
--
2.8.3

View File

@ -0,0 +1,107 @@
From 4229c32ccf8c2f9db70fa2155bd9f46f816a4c3f Mon Sep 17 00:00:00 2001
From: Tux <write@imaginarycode.com>
Date: Mon, 25 Jan 2016 01:19:07 -0500
Subject: [PATCH] Get rid of the security manager.
There's a lot of opinions running on both sides of the debate, but we overwhelmingly feel that the security manager does not help the vast majority of BungeeCord users or plugin developers create correct code.
diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
index 3578aa4..3cef2cf 100644
--- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
+++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
@@ -176,8 +176,6 @@ public class BungeeCord extends ProxyServer
// Java uses ! to indicate a resource inside of a jar/zip/other container. Running Bungee from within a directory that has a ! will cause this to muck up.
Preconditions.checkState( new File( "." ).getAbsolutePath().indexOf( '!' ) == -1, "Cannot use Waterfall in directory with ! in path." );
- System.setSecurityManager( new BungeeSecurityManager() );
-
try
{
baseBundle = ResourceBundle.getBundle( "messages" );
diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeSecurityManager.java b/proxy/src/main/java/net/md_5/bungee/BungeeSecurityManager.java
deleted file mode 100644
index 53c8192..0000000
--- a/proxy/src/main/java/net/md_5/bungee/BungeeSecurityManager.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package net.md_5.bungee;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.security.AccessControlException;
-import java.security.Permission;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.logging.Level;
-import net.md_5.bungee.api.ProxyServer;
-import net.md_5.bungee.api.scheduler.GroupedThreadFactory;
-
-public class BungeeSecurityManager extends SecurityManager
-{
-
- private static final boolean ENFORCE = false;
- private final Set<String> seen = new HashSet<>();
-
- private void checkRestricted(String text)
- {
- Class[] context = getClassContext();
- for ( int i = 2; i < context.length; i++ )
- {
- ClassLoader loader = context[i].getClassLoader();
-
- // Bungee / system can do everything
- if ( loader == ClassLoader.getSystemClassLoader() || loader == null )
- {
- break;
- }
-
- AccessControlException ex = new AccessControlException( "Plugin violation: " + text );
- if ( ENFORCE )
- {
- throw ex;
- }
-
- StringWriter stack = new StringWriter();
- ex.printStackTrace( new PrintWriter( stack ) );
- if ( seen.add( stack.toString() ) )
- {
- ProxyServer.getInstance().getLogger().log( Level.WARNING, "Plugin performed restricted action, please inform them to use proper API methods: " + text, ex );
- }
- break;
- }
- }
-
- @Override
- public void checkExit(int status)
- {
- checkRestricted( "Exit: Cannot close VM" );
- }
-
- @Override
- public void checkAccess(ThreadGroup g)
- {
- if ( !( g instanceof GroupedThreadFactory.BungeeGroup ) )
- {
- checkRestricted( "Illegal thread group access" );
- }
- }
-
- @Override
- public void checkPermission(Permission perm, Object context)
- {
- checkPermission( perm );
- }
-
- @Override
- public void checkPermission(Permission perm)
- {
- switch ( perm.getName() )
- {
- case "setSecurityManager":
- throw new AccessControlException( "Restricted Action", perm );
- }
- }
-}
--
2.8.3

View File

@ -0,0 +1,23 @@
From 413435b7f36587ca4cc562d1ffc373fa24b6296d Mon Sep 17 00:00:00 2001
From: Tux <write@imaginarycode.com>
Date: Wed, 13 Apr 2016 15:17:05 -0400
Subject: [PATCH] Presize the HTTP response buffer
16 characters is extremely small, and all responses start around 256 bytes. 640 characters seems to be good (covering skins and capes), based on sampling profile API responses.
diff --git a/proxy/src/main/java/net/md_5/bungee/http/HttpHandler.java b/proxy/src/main/java/net/md_5/bungee/http/HttpHandler.java
index 96d0a71..bac6b1b 100644
--- a/proxy/src/main/java/net/md_5/bungee/http/HttpHandler.java
+++ b/proxy/src/main/java/net/md_5/bungee/http/HttpHandler.java
@@ -16,7 +16,7 @@ public class HttpHandler extends SimpleChannelInboundHandler<HttpObject>
{
private final Callback<String> callback;
- private final StringBuilder buffer = new StringBuilder();
+ private final StringBuilder buffer = new StringBuilder(640);
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception
--
2.8.3

View File

@ -0,0 +1,22 @@
From ca5884cd49b8a748e4efd99b72704513c8ea008f Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Fri, 11 Sep 2015 23:50:52 -0400
Subject: [PATCH] Allow configuration of the log file path/filename
diff --git a/proxy/src/main/java/net/md_5/bungee/log/BungeeLogger.java b/proxy/src/main/java/net/md_5/bungee/log/BungeeLogger.java
index 94e924b..cde3194 100644
--- a/proxy/src/main/java/net/md_5/bungee/log/BungeeLogger.java
+++ b/proxy/src/main/java/net/md_5/bungee/log/BungeeLogger.java
@@ -27,7 +27,7 @@ public class BungeeLogger extends Logger
try
{
- FileHandler fileHandler = new FileHandler( "proxy.log", 1 << 24, 8, true );
+ FileHandler fileHandler = new FileHandler( System.getProperty("bungee.log-file", "proxy.log"), 1 << 24, 8, true );
fileHandler.setFormatter( formatter );
addHandler( fileHandler );
--
2.8.3

View File

@ -0,0 +1,57 @@
From f48dd938af3f64fdaf55b7faee68eee70d20899e Mon Sep 17 00:00:00 2001
From: kamcio96 <k.nadworski@icloud.com>
Date: Sat, 21 May 2016 17:17:36 -0600
Subject: [PATCH] Fix unicode characters in configuration files
diff --git a/config/src/main/java/net/md_5/bungee/config/YamlConfiguration.java b/config/src/main/java/net/md_5/bungee/config/YamlConfiguration.java
index 0a93602..efeaa6a 100644
--- a/config/src/main/java/net/md_5/bungee/config/YamlConfiguration.java
+++ b/config/src/main/java/net/md_5/bungee/config/YamlConfiguration.java
@@ -1,16 +1,25 @@
package net.md_5.bungee.config;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.LinkedHashMap;
import java.util.Map;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
+
+import com.google.common.base.Charsets;
+
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
@@ -32,7 +41,7 @@ public class YamlConfiguration extends ConfigurationProvider
@Override
public void save(Configuration config, File file) throws IOException
{
- try ( FileWriter writer = new FileWriter( file ) )
+ try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), Charsets.UTF_8)))
{
save( config, writer );
}
@@ -53,7 +62,7 @@ public class YamlConfiguration extends ConfigurationProvider
@Override
public Configuration load(File file, Configuration defaults) throws IOException
{
- try ( FileReader reader = new FileReader( file ) )
+ try (Reader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), Charsets.UTF_8)))
{
return load( reader, defaults );
}
--
2.8.3

View File

@ -0,0 +1,80 @@
From c5c7f68d947f366fef739e0ac3a655baed507bfe Mon Sep 17 00:00:00 2001
From: Tux <write@imaginarycode.com>
Date: Thu, 19 May 2016 18:13:48 -0600
Subject: [PATCH] Clean up and unit test the UUID code.
Also optimizes conversion to mojang-style uuids (by avoiding regex).
diff --git a/api/src/main/java/net/md_5/bungee/Util.java b/api/src/main/java/net/md_5/bungee/Util.java
index 86a0055..37e12e9 100644
--- a/api/src/main/java/net/md_5/bungee/Util.java
+++ b/api/src/main/java/net/md_5/bungee/Util.java
@@ -80,4 +80,8 @@ public class Util
{
return UUID.fromString( uuid.substring( 0, 8 ) + "-" + uuid.substring( 8, 12 ) + "-" + uuid.substring( 12, 16 ) + "-" + uuid.substring( 16, 20 ) + "-" + uuid.substring( 20, 32 ) );
}
+
+ public static String getMojangUUID(UUID uuid) {
+ return uuid.toString().replace( "-", "" );
+ }
}
diff --git a/api/src/main/java/net/md_5/bungee/api/ServerPing.java b/api/src/main/java/net/md_5/bungee/api/ServerPing.java
index 314a1d2..6804ad9 100644
--- a/api/src/main/java/net/md_5/bungee/api/ServerPing.java
+++ b/api/src/main/java/net/md_5/bungee/api/ServerPing.java
@@ -73,7 +73,7 @@ public class ServerPing
public String getId()
{
- return uniqueId.toString().replaceAll( "-", "" );
+ return Util.getMojangUUID(uniqueId);
}
}
diff --git a/api/src/test/java/net/md_5/bungee/util/UtilTest.java b/api/src/test/java/net/md_5/bungee/util/UtilTest.java
new file mode 100644
index 0000000..030b5cd
--- /dev/null
+++ b/api/src/test/java/net/md_5/bungee/util/UtilTest.java
@@ -0,0 +1,25 @@
+package net.md_5.bungee.util;
+
+import net.md_5.bungee.Util;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.UUID;
+
+import static org.junit.Assert.*;
+
+public class UtilTest {
+
+ private static final String FULL_UUID = "982709b9-6fd8-4627-929d-e7d3b91166ea";
+ private static final String MOJANG_UUID = "982709b96fd84627929de7d3b91166ea";
+
+ @Test
+ public void testGetUUID() throws Exception {
+ Assert.assertEquals(FULL_UUID, Util.getUUID(MOJANG_UUID).toString());
+ }
+
+ @Test
+ public void testGetMojangUUID() throws Exception {
+ assertEquals(MOJANG_UUID, Util.getMojangUUID(UUID.fromString(FULL_UUID)));
+ }
+}
diff --git a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
index dab6ef2..ad19168 100644
--- a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
+++ b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
@@ -603,7 +603,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
@Override
public String getUUID()
{
- return uniqueId.toString().replaceAll( "-", "" );
+ return Util.getMojangUUID(uniqueId);
}
@Override
--
2.8.3

View File

@ -0,0 +1,258 @@
From 84dc97a63f6f751464fcef7853dbc375c4a10439 Mon Sep 17 00:00:00 2001
From: Techcable <Techcable@outlook.com>
Date: Mon, 14 Mar 2016 15:40:44 -0700
Subject: [PATCH] Optimize uuid conversions
Optimizes converting to and from mojang format.
Manually decode uuids to and from hex.
diff --git a/api/src/main/java/io/github/waterfallmc/waterfall/utils/Hex.java b/api/src/main/java/io/github/waterfallmc/waterfall/utils/Hex.java
new file mode 100644
index 0000000..ece5f79
--- /dev/null
+++ b/api/src/main/java/io/github/waterfallmc/waterfall/utils/Hex.java
@@ -0,0 +1,113 @@
+package io.github.waterfallmc.waterfall.utils;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+public class Hex {
+
+ public static byte[] decode(CharSequence chars) {
+ byte[] bytes = new byte[chars.length() >> 1];
+ decode(chars, 0, bytes, 0, bytes.length);
+ return bytes;
+ }
+
+ public static void decode(char[] chars, int charOffset, byte[] dest, int offset, int length) {
+ decode(new CharSequence() {
+ @Override
+ public int length() {
+ return chars.length;
+ }
+
+ @Override
+ public char charAt(int index) {
+ return chars[index];
+ }
+
+ @Override
+ public CharSequence subSequence(int start, int end) {
+ return toString().substring(start, end);
+ }
+
+ @Override
+ public String toString() {
+ return new String(chars, charOffset, chars.length);
+ }
+ });
+ }
+
+ public static void decode(CharSequence chars, int charOffset, byte[] dest, int offset, int length) {
+ Objects.requireNonNull(chars, "Null chars");
+ Objects.requireNonNull(chars, "Null destination");
+ final int numChars = chars.length();
+ if ((numChars & 0x01) != 0) {
+ throw new IllegalArgumentException("Odd number of characters: " + numChars);
+ } else if (length < (numChars - charOffset) >> 1) {
+ throw new IllegalArgumentException("Too many bytes to fill with " + numChars + " characters: " + length);
+ } else if (offset < 0 || charOffset < 0 || length < 0 || length * 2 > numChars - charOffset || length > dest.length - offset) {
+ throw new IndexOutOfBoundsException();
+ }
+ for (int i = 0, charIndex = charOffset; i < length; i++) {
+ char first = chars.charAt(charIndex++);
+ char second = chars.charAt(charIndex++);
+ dest[i + offset] = (byte) ((toDigit(first) << 4) | (toDigit(second)));
+ }
+ }
+
+ public static String encodeString(byte[] bytes) {
+ return new String(encode(bytes));
+ }
+
+ public static char[] encode(byte[] bytes) {
+ char[] chars = new char[bytes.length << 1];
+ encode(chars, 0, bytes, 0, bytes.length);
+ return chars;
+ }
+
+ public static void encode(char[] chars, int charOffset, byte[] source, int offset, int length) {
+ Objects.requireNonNull(chars, "Null chars");
+ Objects.requireNonNull(chars, "Null bytes");
+ if (offset < 0 || charOffset < 0 || length < 0 || length * 2 > chars.length - charOffset || length > source.length - offset) {
+ throw new IndexOutOfBoundsException();
+ } else if (length == 0) {
+ return;
+ }
+ for (int i = 0, charIndex = charOffset; i < length; i++) {
+ byte b = source[i + offset];
+ chars[charIndex++] = fromDigit((byte) ((b >> 4) & 0xF));
+ chars[charIndex++] = fromDigit((byte) (b & 0xF));
+ }
+ }
+ private static final char[] ENCODE_TABLE = new char[]{
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+ };
+ private static final byte[] DECODE_TABLE = new byte[128];
+
+ static {
+ Arrays.fill(DECODE_TABLE, (byte) -1);
+ for (int value = 0; value < ENCODE_TABLE.length; value++) {
+ char c = ENCODE_TABLE[value];
+ DECODE_TABLE[c] = (byte) value;
+ char upper;
+ if ((upper = Character.toUpperCase(c)) != c) {
+ DECODE_TABLE[upper] = (byte) value;
+ }
+ }
+ }
+
+ public static byte toDigit(char c) {
+ byte value;
+ if (c < DECODE_TABLE.length) {
+ value = DECODE_TABLE[c];
+ } else {
+ value = -1;
+ }
+ if (value < 0) throw new IllegalArgumentException("Invalid character " + c);
+ return value;
+ }
+
+ private static char fromDigit(byte b) {
+ assert (b & 0xF) == b : "Out of range " + b;
+ return ENCODE_TABLE[b];
+ }
+}
\ No newline at end of file
diff --git a/api/src/main/java/io/github/waterfallmc/waterfall/utils/UUIDUtils.java b/api/src/main/java/io/github/waterfallmc/waterfall/utils/UUIDUtils.java
new file mode 100644
index 0000000..7258a26
--- /dev/null
+++ b/api/src/main/java/io/github/waterfallmc/waterfall/utils/UUIDUtils.java
@@ -0,0 +1,70 @@
+package io.github.waterfallmc.waterfall.utils;
+import java.util.UUID;
+
+import com.google.common.base.Preconditions;
+import com.google.common.primitives.Longs;
+
+public class UUIDUtils {
+ private UUIDUtils() {}
+
+ public static String toMojangString(UUID id) {
+ Preconditions.checkNotNull(id, "Null id");
+ return Hex.encodeString(toBytes(id));
+ }
+
+ public static UUID fromString(String s) {
+ Preconditions.checkNotNull(s, "Null string");
+ if (s.length() == 36) { // UUID.toString() uuid
+ s = s.replaceAll("-", "");
+ } else if (s.length() != 32) {
+ throw new IllegalArgumentException("Invalid UUID: " + s);
+ }
+ return fromMojangString0(s);
+ }
+
+ public static UUID fromMojangString(String s) {
+ Preconditions.checkNotNull(s, "Null string");
+ if (s.length() != 32) {
+ throw new IllegalArgumentException("UUID not in mojang format: " + s);
+ }
+ return fromMojangString0(s);
+ }
+
+ private static UUID fromMojangString0(String s) {
+ assert s != null : "Null string";
+ assert s.length() == 32 : "invalid length: " + s;
+ try {
+ return fromBytes(Hex.decode(s));
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("Invalid UUID: " + s);
+ }
+ }
+
+ public static byte[] toBytes(UUID id) {
+ Preconditions.checkNotNull(id, "Null id");
+ byte[] result = new byte[16];
+ long lsb = id.getLeastSignificantBits();
+ for (int i = 15; i >= 8; i--) {
+ result[i] = (byte) (lsb & 0xffL);
+ lsb >>= 8;
+ }
+ long msb = id.getMostSignificantBits();
+ for (int i = 7; i >= 0; i--) {
+ result[i] = (byte) (msb & 0xffL);
+ msb >>= 8;
+ }
+ return result;
+ }
+
+ public static UUID fromBytes(byte[] bytes) {
+ Preconditions.checkNotNull(bytes, "Null bytes");
+ if (bytes.length != 16) {
+ throw new IllegalArgumentException("Invalid length: " + bytes.length);
+ }
+ long msb = Longs.fromBytes(bytes[0], bytes[1], bytes[2], bytes[3],
+ bytes[4], bytes[5], bytes[6], bytes[7]);
+ long lsb = Longs.fromBytes(bytes[8], bytes[9], bytes[10], bytes[11],
+ bytes[12], bytes[13], bytes[14], bytes[15]);
+ return new UUID(msb, lsb);
+ }
+}
\ No newline at end of file
diff --git a/api/src/main/java/net/md_5/bungee/Util.java b/api/src/main/java/net/md_5/bungee/Util.java
index 37e12e9..b268bef 100644
--- a/api/src/main/java/net/md_5/bungee/Util.java
+++ b/api/src/main/java/net/md_5/bungee/Util.java
@@ -1,11 +1,15 @@
package net.md_5.bungee;
import com.google.common.base.Joiner;
+import com.google.common.primitives.Ints;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.UUID;
+import io.github.waterfallmc.waterfall.utils.Hex;
+import io.github.waterfallmc.waterfall.utils.UUIDUtils;
+
/**
* Series of utility classes to perform various operations.
*/
@@ -42,7 +46,7 @@ public class Util
*/
public static String hex(int i)
{
- return String.format( "0x%02X", i );
+ return Hex.encodeString(Ints.toByteArray(i));
}
/**
@@ -78,10 +82,17 @@ public class Util
*/
public static UUID getUUID(String uuid)
{
- return UUID.fromString( uuid.substring( 0, 8 ) + "-" + uuid.substring( 8, 12 ) + "-" + uuid.substring( 12, 16 ) + "-" + uuid.substring( 16, 20 ) + "-" + uuid.substring( 20, 32 ) );
+ return UUIDUtils.fromString(uuid);
}
- public static String getMojangUUID(UUID uuid) {
- return uuid.toString().replace( "-", "" );
+ /**
+ * Converts a UUID to a Mojang UUID
+ *
+ * @param uuid The string to be converted
+ * @return The result
+ */
+ public static String getMojangUUID(UUID uuid)
+ {
+ return UUIDUtils.toMojangString(uuid);
}
}
--
2.8.3

View File

@ -0,0 +1,121 @@
From 181fb185d832bbea34d4744bb7e426d9ff6bc216 Mon Sep 17 00:00:00 2001
From: Daniel Naylor <git@drnaylor.co.uk>
Date: Sun, 9 Aug 2015 13:43:57 +0100
Subject: [PATCH] Add support for FML with IP Forwarding enabled
FML adds a \00FML\00 marker to the host field, so Forge can determine whether or not to start a Forge handshake, making way to allow vanilla clients to connect to Forge servers that don't need a client modification. However, Bungee also uses the field, and the two implementations collide when using Spigot.
The original fix was to not send the FML information at the same time as the IP forwarding, you could have one or the other, but not both. This was OK, as no FML servers supported IP forwarding as of time of the patch. This was implemented in commit 4809f1f80ace9ae87b91453c8887c70f5e098bd0.
However, there is now at least one Forge coremod that intends to support IP forwarding. To be able to support Forge with IP forwarding, a way to be able to support the FML token (and any other host data) is needed. This adds a property to the user Game Profile to forward on whether the user is a FML client, along with whether there is any extra data.
No breaking changes occur due to this patch.
diff --git a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
index dd00192..5ed9fe4 100644
--- a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
+++ b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
@@ -4,6 +4,7 @@ import com.google.common.base.Preconditions;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
+import java.util.Arrays;
import java.util.Queue;
import java.util.Set;
import java.util.UUID;
@@ -92,15 +93,39 @@ public class ServerConnector extends PacketHandler
String newHost = copiedHandshake.getHost() + "\00" + user.getAddress().getHostString() + "\00" + user.getUUID();
LoginResult profile = user.getPendingConnection().getLoginProfile();
+
+ // Handle properties.
+ LoginResult.Property[] properties = new LoginResult.Property[0];
+
if ( profile != null && profile.getProperties() != null && profile.getProperties().length > 0 )
{
- newHost += "\00" + BungeeCord.getInstance().gson.toJson( profile.getProperties() );
+ properties = profile.getProperties();
}
+
+ if ( user.getForgeClientHandler().isFmlTokenInHandshake() )
+ {
+ // Get the current properties and copy them into a slightly bigger array.
+ LoginResult.Property[] newp = Arrays.copyOf( properties, properties.length + 2 );
+
+ // Add a new profile property that specifies that this user is a Forge user.
+ newp[newp.length - 2] = new LoginResult.Property( ForgeConstants.FML_LOGIN_PROFILE, "true", null );
+
+ // If we do not perform the replacement, then the IP Forwarding code in Spigot et. al. will try to split on this prematurely.
+ newp[newp.length - 1] = new LoginResult.Property( ForgeConstants.EXTRA_DATA, user.getExtraDataInHandshake().replaceAll( "\0", "\1"), "" );
+
+ // All done.
+ properties = newp;
+ }
+
+ // If we touched any properties, then append them
+ if (properties.length > 0) {
+ newHost += "\00" + BungeeCord.getInstance().gson.toJson(properties);
+ }
+
copiedHandshake.setHost( newHost );
} else if ( !user.getExtraDataInHandshake().isEmpty() )
{
- // Only restore the extra data if IP forwarding is off.
- // TODO: Add support for this data with IP forwarding.
+ // Restore the extra data
copiedHandshake.setHost( copiedHandshake.getHost() + user.getExtraDataInHandshake() );
}
diff --git a/proxy/src/main/java/net/md_5/bungee/UserConnection.java b/proxy/src/main/java/net/md_5/bungee/UserConnection.java
index a5010f3..018c02e 100644
--- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java
+++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java
@@ -12,6 +12,7 @@ import io.netty.channel.ChannelOption;
import io.netty.util.internal.PlatformDependent;
import java.net.InetSocketAddress;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
@@ -40,6 +41,8 @@ import net.md_5.bungee.api.event.ServerConnectEvent;
import net.md_5.bungee.api.score.Scoreboard;
import net.md_5.bungee.chat.ComponentSerializer;
import net.md_5.bungee.connection.InitialHandler;
+import net.md_5.bungee.connection.LoginResult;
+import net.md_5.bungee.connection.LoginResult.Property;
import net.md_5.bungee.entitymap.EntityMap;
import net.md_5.bungee.forge.ForgeClientHandler;
import net.md_5.bungee.forge.ForgeConstants;
@@ -181,8 +184,12 @@ public final class UserConnection implements ProxiedPlayer
forgeClientHandler = new ForgeClientHandler( this );
+ // No-config FML handshake marker.
// Set whether the connection has a 1.8 FML marker in the handshake.
- forgeClientHandler.setFmlTokenInHandshake( this.getPendingConnection().getExtraDataInHandshake().contains( ForgeConstants.FML_HANDSHAKE_TOKEN ) );
+ if (this.getPendingConnection().getExtraDataInHandshake().contains( ForgeConstants.FML_HANDSHAKE_TOKEN ))
+ {
+ forgeClientHandler.setFmlTokenInHandshake( true );
+ }
}
public void sendPacket(PacketWrapper packet)
diff --git a/proxy/src/main/java/net/md_5/bungee/forge/ForgeConstants.java b/proxy/src/main/java/net/md_5/bungee/forge/ForgeConstants.java
index 6dca204..f5253b8 100644
--- a/proxy/src/main/java/net/md_5/bungee/forge/ForgeConstants.java
+++ b/proxy/src/main/java/net/md_5/bungee/forge/ForgeConstants.java
@@ -14,6 +14,10 @@ public class ForgeConstants
public static final String FML_HANDSHAKE_TAG = "FML|HS";
public static final String FML_REGISTER = "REGISTER";
+ // Game profile key
+ public static final String FML_LOGIN_PROFILE = "forgeClient";
+ public static final String EXTRA_DATA = "extraData";
+
/**
* The FML 1.8 handshake token.
*/
--
2.8.3

View File

@ -0,0 +1,79 @@
From 6ee13e629b72a93e352cea0d99d142a066d12bee Mon Sep 17 00:00:00 2001
From: Tux <write@imaginarycode.com>
Date: Thu, 19 May 2016 17:36:31 -0600
Subject: [PATCH] Better unit tests for Chat API
diff --git a/chat/src/test/java/net/md_5/bungee/api/chat/TranslatableComponentTest.java b/chat/src/test/java/net/md_5/bungee/api/chat/TranslatableComponentTest.java
index 453d375..1a2ffd0 100644
--- a/chat/src/test/java/net/md_5/bungee/api/chat/TranslatableComponentTest.java
+++ b/chat/src/test/java/net/md_5/bungee/api/chat/TranslatableComponentTest.java
@@ -3,6 +3,8 @@ package net.md_5.bungee.api.chat;
import net.md_5.bungee.api.chat.TranslatableComponent;
import org.junit.Test;
+import java.util.List;
+
import static org.junit.Assert.assertEquals;
public class TranslatableComponentTest
@@ -15,4 +17,25 @@ public class TranslatableComponentTest
assertEquals( "Test string with 2 placeholders: aoeu", testComponent.toPlainText() );
assertEquals( "§fTest string with §f2§f placeholders: §faoeu", testComponent.toLegacyText() );
}
+
+ @Test
+ public void testDuplicateNullWithDoesntThrowException() {
+ TranslatableComponent component = new TranslatableComponent("Test") {
+ @Override
+ public List<BaseComponent> getExtra() {
+ return null;
+ }
+ };
+
+ TranslatableComponent copy = new TranslatableComponent(component);
+ // The fact that we don't throw an exception means it's working as intended.
+ }
+
+ @Test
+ public void testEscapedPercentInPlainText()
+ {
+ TranslatableComponent testComponent = new TranslatableComponent( "Test string with %% sign" );
+ assertEquals( "Test string with % sign", testComponent.toPlainText() );
+ assertEquals( "§fTest string with §f%§f sign", testComponent.toLegacyText() );
+ }
}
diff --git a/proxy/src/test/java/net/md_5/bungee/chat/ComponentsTest.java b/proxy/src/test/java/net/md_5/bungee/chat/ComponentsTest.java
index 004a2b7..f34eb3d 100644
--- a/proxy/src/test/java/net/md_5/bungee/chat/ComponentsTest.java
+++ b/proxy/src/test/java/net/md_5/bungee/chat/ComponentsTest.java
@@ -123,6 +123,26 @@ public class ComponentsTest
Assert.assertEquals( eventRetention[1].getClickEvent(), testClickEvent );
}
+ @Test
+ public void testBuilderSpecialFormatting()
+ {
+ BaseComponent[] components = new ComponentBuilder( "Hello " )
+ .bold(true).underlined(true).italic(true).strikethrough(true).obfuscated(true)
+ .append("World").underlined(false).strikethrough(false).create();
+
+ Assert.assertTrue( components[0].isBold() );
+ Assert.assertTrue( components[0].isUnderlined() );
+ Assert.assertTrue( components[0].isItalic() );
+ Assert.assertTrue( components[0].isStrikethrough() );
+ Assert.assertTrue( components[0].isObfuscated() );
+
+ Assert.assertTrue( components[1].isBold() );
+ Assert.assertFalse( components[1].isUnderlined() );
+ Assert.assertTrue( components[1].isItalic() );
+ Assert.assertFalse( components[1].isStrikethrough() );
+ Assert.assertTrue( components[1].isObfuscated() );
+ }
+
@Test(expected = IllegalArgumentException.class)
public void testLoopSimple()
{
--
2.8.3

View File

@ -0,0 +1,22 @@
From 7937df226bd632a263f9db241fac040845cb916c Mon Sep 17 00:00:00 2001
From: Iceee <andrew@optic.tv>
Date: Mon, 6 Jul 2015 18:59:29 -0500
Subject: [PATCH] Don't allow channel buffers to grow beyond a reasonable limit
diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
index 3cef2cf..fd8d9b0 100644
--- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
+++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
@@ -310,6 +310,8 @@ public class BungeeCord extends ProxyServer
new ServerBootstrap()
.channel( PipelineUtils.getServerChannel() )
.option( ChannelOption.SO_REUSEADDR, true ) // TODO: Move this elsewhere!
+ .childOption( ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, 1024 * 1024 * 10 )
+ .childOption( ChannelOption.WRITE_BUFFER_LOW_WATER_MARK, 1024 * 1024 * 1 )
.childAttr( PipelineUtils.LISTENER, info )
.childHandler( PipelineUtils.SERVER_CHILD )
.group( eventLoops )
--
2.8.3

View File

@ -0,0 +1,76 @@
From e3161d727171388b974b829ae6ca08abeb71fa79 Mon Sep 17 00:00:00 2001
From: Techcable <Techcable@outlook.com>
Date: Thu, 28 Jan 2016 15:13:29 -0700
Subject: [PATCH] Allow removing servers or changing addresses on reload
Moves all players on the removed server to the default server.
Address changes also move the players to the default server.
Kicks players on failure to move.
Original Issue: https://github.com/WaterfallMC/Waterfall-Old/issues/17
diff --git a/proxy/src/main/java/net/md_5/bungee/conf/Configuration.java b/proxy/src/main/java/net/md_5/bungee/conf/Configuration.java
index 81dd4af..db9ebbd 100644
--- a/proxy/src/main/java/net/md_5/bungee/conf/Configuration.java
+++ b/proxy/src/main/java/net/md_5/bungee/conf/Configuration.java
@@ -11,12 +11,15 @@ import java.util.UUID;
import java.util.logging.Level;
import javax.imageio.ImageIO;
import lombok.Getter;
+
+import net.md_5.bungee.BungeeCord;
import net.md_5.bungee.api.Favicon;
import net.md_5.bungee.api.ProxyConfig;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.config.ConfigurationAdapter;
import net.md_5.bungee.api.config.ListenerInfo;
import net.md_5.bungee.api.config.ServerInfo;
+import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.util.CaseInsensitiveMap;
import net.md_5.bungee.util.CaseInsensitiveSet;
@@ -97,18 +100,31 @@ public abstract class Configuration implements ProxyConfig
servers = new CaseInsensitiveMap<>( newServers );
} else
{
- for ( ServerInfo oldServer : servers.values() )
- {
- // Don't allow servers to be removed
- Preconditions.checkArgument( newServers.containsKey( oldServer.getName() ), "Server %s removed on reload!", oldServer.getName() );
- }
+ Map<String, ServerInfo> oldServers = this.servers;
+ this.servers = new CaseInsensitiveMap<>(newServers);
- // Add new servers
- for ( Map.Entry<String, ServerInfo> newServer : newServers.entrySet() )
+ for ( ServerInfo oldServer : oldServers.values() )
{
- if ( !servers.containsValue( newServer.getValue() ) )
- {
- servers.put( newServer.getKey(), newServer.getValue() );
+ ServerInfo newServer = newServers.get(oldServer.getName());
+ if ((newServer == null || !oldServer.getAddress().equals(newServer.getAddress())) && !oldServer.getPlayers().isEmpty()) {
+ BungeeCord.getInstance().getLogger().info("Moving players off of server: " + oldServer.getName());
+ // The server is being removed, or having it's address changed
+ for (ProxiedPlayer player : oldServer.getPlayers()) {
+ ListenerInfo listener = player.getPendingConnection().getListener();
+ String destinationName = newServers.get(listener.getDefaultServer()) == null ? listener.getDefaultServer() : listener.getFallbackServer();
+ ServerInfo destination = newServers.get(destinationName);
+ if (destination == null) {
+ BungeeCord.getInstance().getLogger().severe("Couldn't find server " + listener.getDefaultServer() + " or " + listener.getFallbackServer() + " to put player " + player.getName() + " on");
+ player.disconnect(BungeeCord.getInstance().getTranslation("fallback_kick", "Not found on reload"));
+ continue;
+ }
+ player.connect(destination, (success, cause) -> {
+ if (!success) {
+ BungeeCord.getInstance().getLogger().log(Level.WARNING, "Failed to connect " + player.getName() + " to " + destination.getName(), cause);
+ player.disconnect(BungeeCord.getInstance().getTranslation("fallback_kick", cause.getCause().getClass().getName()));
+ }
+ });
+ }
}
}
}
--
2.8.3

View File

@ -0,0 +1,272 @@
From 81c24fbb9f86c8bd14cc33208504f53147235cff Mon Sep 17 00:00:00 2001
From: Techcable <Techcable@outlook.com>
Date: Sun, 28 Feb 2016 22:46:22 -0700
Subject: [PATCH] Use ASM for events, via the Event4J library
According to benchmarks, this is about 7 nanoseconds faster than reflection (34 ns -> 27 ns).
Event4J falls back to Java 8's new MethodHandle if the event method isn't public.
diff --git a/event/pom.xml b/event/pom.xml
index b6ef990..ff72600 100644
--- a/event/pom.xml
+++ b/event/pom.xml
@@ -17,4 +17,24 @@
<name>Waterfall-Event</name>
<description>Generic java event dispatching API intended for use with Waterfall.</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>net.techcable</groupId>
+ <artifactId>event4j</artifactId>
+ <version>1.1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.ow2.asm</groupId>
+ <artifactId>asm-all</artifactId>
+ <version>5.0.4</version>
+ </dependency>
+ </dependencies>
+
+ <repositories>
+ <repository>
+ <id>techcable-repo</id>
+ <url>https://repo.techcable.net/content/groups/public/</url>
+ </repository>
+ </repositories>
</project>
diff --git a/event/src/main/java/net/md_5/bungee/event/EventBus.java b/event/src/main/java/net/md_5/bungee/event/EventBus.java
index 5b5d420..c93aa16 100644
--- a/event/src/main/java/net/md_5/bungee/event/EventBus.java
+++ b/event/src/main/java/net/md_5/bungee/event/EventBus.java
@@ -1,26 +1,13 @@
package net.md_5.bungee.event;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.logging.Level;
import java.util.logging.Logger;
public class EventBus
{
- private final Map<Class<?>, Map<Byte, Map<Object, Method[]>>> byListenerAndPriority = new HashMap<>();
- private final Map<Class<?>, EventHandlerMethod[]> byEventBaked = new ConcurrentHashMap<>();
- private final Lock lock = new ReentrantLock();
+ private final net.techcable.event4j.EventBus<Object, Object> event4JBus = net.techcable.event4j.EventBus.builder()
+ .eventMarker((m) -> m.isAnnotationPresent(EventHandler.class) ? m.getAnnotation(EventHandler.class)::priority : null)
+ .build();
private final Logger logger;
public EventBus()
@@ -35,167 +22,16 @@ public class EventBus
public void post(Object event)
{
- EventHandlerMethod[] handlers = byEventBaked.get( event.getClass() );
-
- if ( handlers != null )
- {
- for ( EventHandlerMethod method : handlers )
- {
- try
- {
- method.invoke( event );
- } catch ( IllegalAccessException ex )
- {
- throw new Error( "Method became inaccessible: " + event, ex );
- } catch ( IllegalArgumentException ex )
- {
- throw new Error( "Method rejected target/argument: " + event, ex );
- } catch ( InvocationTargetException ex )
- {
- logger.log( Level.WARNING, MessageFormat.format( "Error dispatching event {0} to listener {1}", event, method.getListener() ), ex.getCause() );
- }
- }
- }
- }
-
- private Map<Class<?>, Map<Byte, Set<Method>>> findHandlers(Object listener)
- {
- Map<Class<?>, Map<Byte, Set<Method>>> handler = new HashMap<>();
- for ( Method m : listener.getClass().getDeclaredMethods() )
- {
- EventHandler annotation = m.getAnnotation( EventHandler.class );
- if ( annotation != null )
- {
- Class<?>[] params = m.getParameterTypes();
- if ( params.length != 1 )
- {
- logger.log( Level.INFO, "Method {0} in class {1} annotated with {2} does not have single argument", new Object[]
- {
- m, listener.getClass(), annotation
- } );
- continue;
- }
- Map<Byte, Set<Method>> prioritiesMap = handler.get( params[0] );
- if ( prioritiesMap == null )
- {
- prioritiesMap = new HashMap<>();
- handler.put( params[0], prioritiesMap );
- }
- Set<Method> priority = prioritiesMap.get( annotation.priority() );
- if ( priority == null )
- {
- priority = new HashSet<>();
- prioritiesMap.put( annotation.priority(), priority );
- }
- priority.add( m );
- }
- }
- return handler;
+ event4JBus.fire(event);
}
public void register(Object listener)
{
- Map<Class<?>, Map<Byte, Set<Method>>> handler = findHandlers( listener );
- lock.lock();
- try
- {
- for ( Map.Entry<Class<?>, Map<Byte, Set<Method>>> e : handler.entrySet() )
- {
- Map<Byte, Map<Object, Method[]>> prioritiesMap = byListenerAndPriority.get( e.getKey() );
- if ( prioritiesMap == null )
- {
- prioritiesMap = new HashMap<>();
- byListenerAndPriority.put( e.getKey(), prioritiesMap );
- }
- for ( Map.Entry<Byte, Set<Method>> entry : e.getValue().entrySet() )
- {
- Map<Object, Method[]> currentPriorityMap = prioritiesMap.get( entry.getKey() );
- if ( currentPriorityMap == null )
- {
- currentPriorityMap = new HashMap<>();
- prioritiesMap.put( entry.getKey(), currentPriorityMap );
- }
- Method[] baked = new Method[ entry.getValue().size() ];
- currentPriorityMap.put( listener, entry.getValue().toArray( baked ) );
- }
- bakeHandlers( e.getKey() );
- }
- } finally
- {
- lock.unlock();
- }
+ event4JBus.register(listener);
}
public void unregister(Object listener)
{
- Map<Class<?>, Map<Byte, Set<Method>>> handler = findHandlers( listener );
- lock.lock();
- try
- {
- for ( Map.Entry<Class<?>, Map<Byte, Set<Method>>> e : handler.entrySet() )
- {
- Map<Byte, Map<Object, Method[]>> prioritiesMap = byListenerAndPriority.get( e.getKey() );
- if ( prioritiesMap != null )
- {
- for ( Byte priority : e.getValue().keySet() )
- {
- Map<Object, Method[]> currentPriority = prioritiesMap.get( priority );
- if ( currentPriority != null )
- {
- currentPriority.remove( listener );
- if ( currentPriority.isEmpty() )
- {
- prioritiesMap.remove( priority );
- }
- }
- }
- if ( prioritiesMap.isEmpty() )
- {
- byListenerAndPriority.remove( e.getKey() );
- }
- }
- bakeHandlers( e.getKey() );
- }
- } finally
- {
- lock.unlock();
- }
- }
-
- /**
- * Shouldn't be called without first locking the writeLock; intended for use
- * only inside {@link #register(java.lang.Object) register(Object)} or
- * {@link #unregister(java.lang.Object) unregister(Object)}.
- */
- private void bakeHandlers(Class<?> eventClass)
- {
- Map<Byte, Map<Object, Method[]>> handlersByPriority = byListenerAndPriority.get( eventClass );
- if ( handlersByPriority != null )
- {
- List<EventHandlerMethod> handlersList = new ArrayList<>( handlersByPriority.size() * 2 );
-
- // Either I'm really tired, or the only way we can iterate between Byte.MIN_VALUE and Byte.MAX_VALUE inclusively,
- // with only a byte on the stack is by using a do {} while() format loop.
- byte value = Byte.MIN_VALUE;
- do
- {
- Map<Object, Method[]> handlersByListener = handlersByPriority.get( value );
- if ( handlersByListener != null )
- {
- for ( Map.Entry<Object, Method[]> listenerHandlers : handlersByListener.entrySet() )
- {
- for ( Method method : listenerHandlers.getValue() )
- {
- EventHandlerMethod ehm = new EventHandlerMethod( listenerHandlers.getKey(), method );
- handlersList.add( ehm );
- }
- }
- }
- } while ( value++ < Byte.MAX_VALUE );
- byEventBaked.put( eventClass, handlersList.toArray( new EventHandlerMethod[ handlersList.size() ] ) );
- } else
- {
- byEventBaked.remove( eventClass );
- }
+ event4JBus.unregister(listener);
}
}
diff --git a/event/src/main/java/net/md_5/bungee/event/EventHandlerMethod.java b/event/src/main/java/net/md_5/bungee/event/EventHandlerMethod.java
deleted file mode 100644
index ad19c02..0000000
--- a/event/src/main/java/net/md_5/bungee/event/EventHandlerMethod.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package net.md_5.bungee.event;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-@AllArgsConstructor
-public class EventHandlerMethod
-{
-
- @Getter
- private final Object listener;
- @Getter
- private final Method method;
-
- public void invoke(Object event) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
- {
- method.invoke( listener, event );
- }
-}
--
2.8.3

View File

@ -0,0 +1,22 @@
From f78252248fff2adf844a59aa117d4eabda721144 Mon Sep 17 00:00:00 2001
From: Harry <me@harry5573.uk>
Date: Wed, 24 Feb 2016 17:16:23 +0000
Subject: [PATCH] Enable TCP_NODELAY.
This is enabled by default on CraftBukkit/Spigot >= 1.8 and may help with network performance.
diff --git a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java
index 621a06c..76cce0c 100644
--- a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java
+++ b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java
@@ -121,6 +121,7 @@ public class PipelineUtils
{
// IP_TOS is not supported (Windows XP / Windows Server 2003)
}
+ ch.config().setOption( ChannelOption.TCP_NODELAY, true );
ch.config().setAllocator( PooledByteBufAllocator.DEFAULT );
ch.pipeline().addLast( TIMEOUT_HANDLER, new ReadTimeoutHandler( BungeeCord.getInstance().config.getTimeout(), TimeUnit.MILLISECONDS ) );
--
2.8.3

View File

@ -0,0 +1,45 @@
From 01c78e08ab372071eb749652dc8bcbdeace6ab23 Mon Sep 17 00:00:00 2001
From: Tux <write@imaginarycode.com>
Date: Thu, 19 May 2016 18:05:33 -0600
Subject: [PATCH] Micro-optimizations
- PluginManager.dispatchCommand() avoids regex while splitting commands. Java 7 introduced an optimized String.split() that should be used instead (affects command dispatch).
- Avoid regex in getLocale() by changing from replaceAll(String, String) to replaceAll(char, char)
diff --git a/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java b/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java
index 2426bdb..7203d04 100644
--- a/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java
+++ b/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java
@@ -42,7 +42,6 @@ import org.yaml.snakeyaml.introspector.PropertyUtils;
public class PluginManager
{
- private static final Pattern argsSplit = Pattern.compile( " " );
/*========================================================================*/
private final ProxyServer proxy;
/*========================================================================*/
@@ -126,7 +125,7 @@ public class PluginManager
*/
public boolean dispatchCommand(CommandSender sender, String commandLine, List<String> tabResults)
{
- String[] split = argsSplit.split( commandLine, -1 );
+ String[] split = commandLine.split(" ", -1);
// Check for chat that only contains " "
if ( split.length == 0 )
{
diff --git a/proxy/src/main/java/net/md_5/bungee/UserConnection.java b/proxy/src/main/java/net/md_5/bungee/UserConnection.java
index 018c02e..9881b75 100644
--- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java
+++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java
@@ -567,7 +567,7 @@ public final class UserConnection implements ProxiedPlayer
@Override
public Locale getLocale()
{
- return ( locale == null && settings != null ) ? locale = Locale.forLanguageTag( settings.getLocale().replaceAll( "_", "-" ) ) : locale;
+ return ( locale == null && settings != null ) ? locale = Locale.forLanguageTag( settings.getLocale().replace( '_', '-' ) ) : locale;
}
@Override
--
2.8.3

View File

@ -0,0 +1,122 @@
From e41f8d2465c135cede5d3065647c943c2e3e5435 Mon Sep 17 00:00:00 2001
From: Techcable <Techcable@techcable.net>
Date: Thu, 19 May 2016 17:09:22 -0600
Subject: [PATCH] Allow invalid packet ids for forge servers
Some forge mods (COFH) use negative packet ids instead of plugin channels for 'reasons'.
Vanilla servers still error on negative/invalid packets.
Original issue: https://github.com/WaterfallMC/Waterfall-Old/issues/11
diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java b/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java
index e7cb380..447eaae 100644
--- a/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java
@@ -16,6 +16,14 @@ public class MinecraftDecoder extends MessageToMessageDecoder<ByteBuf>
private final boolean server;
@Setter
private int protocolVersion;
+ @Setter
+ private boolean supportsForge = false;
+
+ public MinecraftDecoder(Protocol protocol, boolean server, int protocolVersion) {
+ this.protocol = protocol;
+ this.server = server;
+ this.protocolVersion = protocolVersion;
+ }
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception
@@ -27,7 +35,7 @@ public class MinecraftDecoder extends MessageToMessageDecoder<ByteBuf>
{
int packetId = DefinedPacket.readVarInt( in );
- DefinedPacket packet = prot.createPacket( packetId, protocolVersion );
+ DefinedPacket packet = prot.createPacket( packetId, protocolVersion, supportsForge );
if ( packet != null )
{
packet.read( in, prot.getDirection(), protocolVersion );
diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java b/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java
index 2cbe052..08621b6 100644
--- a/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java
@@ -275,14 +275,18 @@ public enum Protocol
return protocol;
}
- public final DefinedPacket createPacket(int id, int version)
+ public boolean hasPacket(int i, boolean supportsForge) {
+ return supportsForge || i >= 0 && i <= MAX_PACKET_ID;
+ }
+
+ public final DefinedPacket createPacket(int id, int version, boolean supportsForge)
{
ProtocolData protocolData = getProtocolData( version );
if (protocolData == null)
{
throw new BadPacketException( "Unsupported protocol version" );
}
- if ( id > MAX_PACKET_ID )
+ if ( !hasPacket(id, supportsForge) )
{
throw new BadPacketException( "Packet with id " + id + " outside of range " );
}
diff --git a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
index 5ed9fe4..7d14ea7 100644
--- a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
+++ b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
@@ -29,7 +29,9 @@ import net.md_5.bungee.forge.ForgeUtils;
import net.md_5.bungee.netty.ChannelWrapper;
import net.md_5.bungee.netty.HandlerBoss;
import net.md_5.bungee.netty.PacketHandler;
+import net.md_5.bungee.netty.PipelineUtils;
import net.md_5.bungee.protocol.DefinedPacket;
+import net.md_5.bungee.protocol.MinecraftDecoder;
import net.md_5.bungee.protocol.Protocol;
import net.md_5.bungee.protocol.packet.BossBar;
import net.md_5.bungee.protocol.packet.EncryptionRequest;
@@ -183,6 +185,12 @@ public class ServerConnector extends PacketHandler
ServerConnection server = new ServerConnection( ch, target );
ServerConnectedEvent event = new ServerConnectedEvent( user, server );
+
+ if (server.isForgeServer() && user.isForgeUser()) {
+ ((MinecraftDecoder) server.getCh().getHandle().pipeline().get(PipelineUtils.PACKET_DECODER)).setSupportsForge(true);
+ ((MinecraftDecoder) user.getCh().getHandle().pipeline().get(PipelineUtils.PACKET_DECODER)).setSupportsForge(true);
+ }
+
bungee.getPluginManager().callEvent( event );
ch.write( BungeeCord.getInstance().registerChannels() );
diff --git a/proxy/src/main/java/net/md_5/bungee/UserConnection.java b/proxy/src/main/java/net/md_5/bungee/UserConnection.java
index 9881b75..c88ab49 100644
--- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java
+++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java
@@ -76,6 +76,7 @@ public final class UserConnection implements ProxiedPlayer
@NonNull
private final ProxyServer bungee;
@NonNull
+ @Getter
private final ChannelWrapper ch;
@Getter
@NonNull
diff --git a/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java b/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java
index 02881ac..9ba9633 100644
--- a/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java
+++ b/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java
@@ -103,6 +103,12 @@ public abstract class EntityMap
int packetId = DefinedPacket.readVarInt( packet );
int packetIdLength = packet.readerIndex() - readerIndex;
+ if (packetId < 0 || packetId > ints.length || packetId > varints.length) { // Invalid packet id
+ // Ignore these invalid packets for compatibility reasons
+ packet.readerIndex( readerIndex );
+ return;
+ }
+
if ( ints[packetId] )
{
rewriteInt( packet, oldId, newId, readerIndex + packetIdLength );
--
2.8.3

View File

@ -0,0 +1,47 @@
From 5657f0dd4286279c4d4ff0ac8a659ca1818fa954 Mon Sep 17 00:00:00 2001
From: Tux <write@imaginarycode.com>
Date: Fri, 12 Feb 2016 23:55:53 -0500
Subject: [PATCH] Resolve sendData() deadlocks
diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java b/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java
index 1dd0aeb..bc56d4f 100644
--- a/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java
+++ b/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java
@@ -101,19 +101,22 @@ public class BungeeServerInfo implements ServerInfo
Preconditions.checkNotNull( channel, "channel" );
Preconditions.checkNotNull( data, "data" );
- synchronized ( packetQueue )
- {
- Server server = ( players.isEmpty() ) ? null : players.iterator().next().getServer();
- if ( server != null )
- {
- server.sendData( channel, data );
- return true;
- } else if ( queue )
- {
- packetQueue.add( new PluginMessage( channel, data, false ) );
+ Server server;
+
+ synchronized (players) {
+ server = players.isEmpty() ? null : players.iterator().next().getServer();
+ }
+
+ if (server != null) {
+ server.sendData(channel, data);
+ return true;
+ } else if (queue) {
+ synchronized (packetQueue) {
+ packetQueue.add(new PluginMessage(channel, data, false));
}
- return false;
}
+
+ return false;
}
@Override
--
2.8.3

View File

@ -0,0 +1,98 @@
From 4b36feac0d134f081b418653e41547fb5b243081 Mon Sep 17 00:00:00 2001
From: Johannes Donath <johannesd@torchmind.com>
Date: Sat, 4 Jul 2015 06:31:33 +0200
Subject: [PATCH] Add basic support for configurable tab-complete throttling
diff --git a/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java b/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java
index 293ec4e..66d0b8a 100644
--- a/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java
+++ b/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java
@@ -88,4 +88,13 @@ public interface ProxyConfig
* If metrics is enabled
*/
boolean isMetrics();
+
+ // Throttling options
+
+ /**
+ * How often tab-complete packets can be sent.
+ * <p/>
+ * Values in milliseconds.
+ */
+ int getTabThrottle();
}
diff --git a/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java b/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java
index 1fa3ecd..23a5c94 100644
--- a/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java
+++ b/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java
@@ -17,16 +17,36 @@ public class WaterfallConfiguration extends Configuration {
*/
private boolean metrics = true;
+ /*
+ * Throttling options
+ * Helps prevent players from overloading the servers behind us
+ */
+
+ /**
+ * How often players are allowed to send tab throttle.
+ * Value in milliseconds.
+ * <p/>
+ * Default is one packet per second.
+ */
+ private int tabThrottle = 1000;
+
@Override
public void load() {
super.load();
YamlConfig config = new YamlConfig(new File("waterfall.yml"));
config.load(false); // Load, but no permissions
metrics = config.getBoolean("metrics", metrics);
+ // Throttling options
+ tabThrottle = config.getInt("throttling.tab_complete", tabThrottle);
}
@Override
public boolean isMetrics() {
return metrics;
}
+
+ @Override
+ public int getTabThrottle() {
+ return tabThrottle;
+ }
}
diff --git a/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java b/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java
index 23d4f25..28791a6 100644
--- a/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java
+++ b/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java
@@ -31,6 +31,8 @@ public class UpstreamBridge extends PacketHandler
private final ProxyServer bungee;
private final UserConnection con;
+ private long lastTabCompletion = -1;
+
public UpstreamBridge(ProxyServer bungee, UserConnection con)
{
this.bungee = bungee;
@@ -121,6 +123,16 @@ public class UpstreamBridge extends PacketHandler
@Override
public void handle(TabCompleteRequest tabComplete) throws Exception
{
+ if ( bungee.getConfig().getTabThrottle() > 0 )
+ {
+ long now = System.currentTimeMillis();
+ if ( lastTabCompletion > 0 && (now - lastTabCompletion) <= bungee.getConfig().getTabThrottle() )
+ {
+ throw CancelSendSignal.INSTANCE;
+ }
+ lastTabCompletion = now;
+ }
+
List<String> suggestions = new ArrayList<>();
if ( tabComplete.getCursor().startsWith( "/" ) )
--
2.8.3

View File

@ -0,0 +1,46 @@
From 41ff2cd5701b5c40003385c1901df3b39045365a Mon Sep 17 00:00:00 2001
From: Harry <me@harry5573.uk>
Date: Tue, 26 Jan 2016 01:01:57 +0000
Subject: [PATCH] Don't create a new KickStringWriter for each new connection.
diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/KickStringWriter.java b/protocol/src/main/java/net/md_5/bungee/protocol/KickStringWriter.java
index eda9571..e5275c7 100644
--- a/protocol/src/main/java/net/md_5/bungee/protocol/KickStringWriter.java
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/KickStringWriter.java
@@ -1,9 +1,11 @@
package net.md_5.bungee.protocol;
import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
+@Sharable
public class KickStringWriter extends MessageToByteEncoder<String>
{
diff --git a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java
index 76cce0c..f0d0189 100644
--- a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java
+++ b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java
@@ -53,7 +53,7 @@ public class PipelineUtils
ch.pipeline().addBefore( FRAME_DECODER, LEGACY_DECODER, new LegacyDecoder() );
ch.pipeline().addAfter( FRAME_DECODER, PACKET_DECODER, new MinecraftDecoder( Protocol.HANDSHAKE, true, ProxyServer.getInstance().getProtocolVersion() ) );
ch.pipeline().addAfter( FRAME_PREPENDER, PACKET_ENCODER, new MinecraftEncoder( Protocol.HANDSHAKE, true, ProxyServer.getInstance().getProtocolVersion() ) );
- ch.pipeline().addBefore( FRAME_PREPENDER, LEGACY_KICKER, new KickStringWriter() );
+ ch.pipeline().addBefore( FRAME_PREPENDER, LEGACY_KICKER, PipelineUtils.KICK_STRING_WRITER );
ch.pipeline().get( HandlerBoss.class ).setHandler( new InitialHandler( BungeeCord.getInstance(), ch.attr( LISTENER ).get() ) );
}
};
@@ -69,6 +69,7 @@ public class PipelineUtils
public static final String FRAME_PREPENDER = "frame-prepender";
public static final String LEGACY_DECODER = "legacy-decoder";
public static final String LEGACY_KICKER = "legacy-kick";
+ private static final KickStringWriter KICK_STRING_WRITER = new KickStringWriter();
private static boolean epoll;
--
2.8.3

View File

@ -0,0 +1,138 @@
From 538e4649bc72a9a167768f0fb1bef46c4040e863 Mon Sep 17 00:00:00 2001
From: Janmm14 <computerjanimaus@yahoo.de>
Date: Sat, 12 Dec 2015 23:43:30 +0100
Subject: [PATCH] Optional server list ping logging.
Add IPs to the log where user names are shown.
This avoids spamming the logs with connection notices.
Server list pings are only logged if the log_server_list_pings config.yml option is true, defaults to false
diff --git a/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java b/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java
index 66d0b8a..5a49050 100644
--- a/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java
+++ b/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java
@@ -89,6 +89,11 @@ public interface ProxyConfig
*/
boolean isMetrics();
+ /**
+ * Whether we log server list pings
+ */
+ boolean isLogServerListPing();
+
// Throttling options
/**
diff --git a/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java b/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java
index 23a5c94..114961d 100644
--- a/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java
+++ b/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java
@@ -17,6 +17,13 @@ public class WaterfallConfiguration extends Configuration {
*/
private boolean metrics = true;
+ /**
+ * Whether we log server list pings
+ * <p>
+ * Default is false (don't log)
+ */
+ private boolean logServerListPing = false;
+
/*
* Throttling options
* Helps prevent players from overloading the servers behind us
@@ -36,6 +43,7 @@ public class WaterfallConfiguration extends Configuration {
YamlConfig config = new YamlConfig(new File("waterfall.yml"));
config.load(false); // Load, but no permissions
metrics = config.getBoolean("metrics", metrics);
+ logServerListPing = config.getBoolean( "log_server_list_ping", logServerListPing );
// Throttling options
tabThrottle = config.getInt("throttling.tab_complete", tabThrottle);
}
@@ -49,4 +57,9 @@ public class WaterfallConfiguration extends Configuration {
public int getTabThrottle() {
return tabThrottle;
}
+
+ @Override
+ public boolean isLogServerListPing() {
+ return logServerListPing;
+ }
}
diff --git a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
index 7d14ea7..44f0b61 100644
--- a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
+++ b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
@@ -377,6 +377,6 @@ public class ServerConnector extends PacketHandler
@Override
public String toString()
{
- return "[" + user.getName() + "] <-> ServerConnector [" + target.getName() + "]";
+ return "[" + user.getName() + "|" + user.getAddress() + "] <-> ServerConnector [" + target.getName() + "]";
}
}
diff --git a/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java b/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java
index cb9dbaf..7ba0bcb 100644
--- a/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java
+++ b/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java
@@ -503,6 +503,6 @@ public class DownstreamBridge extends PacketHandler
@Override
public String toString()
{
- return "[" + con.getName() + "] <-> DownstreamBridge <-> [" + server.getInfo().getName() + "]";
+ return "[" + con.getAddress() + "|" + con.getName() + "] <-> DownstreamBridge <-> [" + server.getInfo().getName() + "]";
}
}
diff --git a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
index ad19168..2056907 100644
--- a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
+++ b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
@@ -277,19 +277,22 @@ public class InitialHandler extends PacketHandler implements PendingConnection
}
this.virtualHost = InetSocketAddress.createUnresolved( handshake.getHost(), handshake.getPort() );
- bungee.getLogger().log( Level.INFO, "{0} has connected", this );
bungee.getPluginManager().callEvent( new PlayerHandshakeEvent( InitialHandler.this, handshake ) );
switch ( handshake.getRequestedProtocol() )
{
case 1:
+ if (BungeeCord.getInstance().getConfig().isLogServerListPing()) {
+ bungee.getLogger().log( Level.INFO, "{0} is pinging", this );
+ }
// Ping
thisState = State.STATUS;
ch.setProtocol( Protocol.STATUS );
break;
case 2:
// Login
+ bungee.getLogger().log( Level.INFO, "{0} has connected", this );
thisState = State.USERNAME;
ch.setProtocol( Protocol.LOGIN );
@@ -609,7 +612,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
@Override
public String toString()
{
- return "[" + ( ( getName() != null ) ? getName() : getAddress() ) + "] <-> InitialHandler";
+ return "[" + getAddress() + ( getName() != null ? "|" + getName() : "" ) + "] <-> InitialHandler";
}
@Override
diff --git a/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java b/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java
index 28791a6..a96e793 100644
--- a/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java
+++ b/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java
@@ -206,6 +206,6 @@ public class UpstreamBridge extends PacketHandler
@Override
public String toString()
{
- return "[" + con.getName() + "] -> UpstreamBridge";
+ return "[" + con.getAddress() + "|" + con.getName() + "] -> UpstreamBridge";
}
}
--
2.8.3

View File

@ -0,0 +1,30 @@
From 6d0fcbace0fb04518462a064d3f08de8e85ade3b Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 5 Oct 2015 23:20:54 -0400
Subject: [PATCH] Set a more reasonable Recycler Capacity
Default Netty Recycler capacity is 262k~, resulting in major memory
consumption over long runtimes that will never free.
This lowers it by 80%, which should only even be hit on the largest of servers.
diff --git a/bootstrap/src/main/java/net/md_5/bungee/BungeeCordLauncher.java b/bootstrap/src/main/java/net/md_5/bungee/BungeeCordLauncher.java
index 2a41a50..29e2294 100644
--- a/bootstrap/src/main/java/net/md_5/bungee/BungeeCordLauncher.java
+++ b/bootstrap/src/main/java/net/md_5/bungee/BungeeCordLauncher.java
@@ -20,6 +20,12 @@ public class BungeeCordLauncher
Security.setProperty( "networkaddress.cache.ttl", "30" );
Security.setProperty( "networkaddress.cache.negative.ttl", "10" );
+ // TODO: remove .default for netty 5!
+ if ( System.getProperty( "io.netty.recycler.maxCapacity.default" ) == null )
+ {
+ System.setProperty( "io.netty.recycler.maxCapacity.default", "50000" );
+ }
+
OptionParser parser = new OptionParser();
parser.allowsUnrecognizedOptions();
parser.acceptsAll( Arrays.asList( "v", "version" ) );
--
2.8.3

View File

@ -0,0 +1,23 @@
From be14a36864738f608de88028912627a57eb20515 Mon Sep 17 00:00:00 2001
From: Tux <write@imaginarycode.com>
Date: Sun, 14 Feb 2016 01:03:27 -0500
Subject: [PATCH] Reduce max log size to 8MB and don't append to existing log
files
diff --git a/proxy/src/main/java/net/md_5/bungee/log/BungeeLogger.java b/proxy/src/main/java/net/md_5/bungee/log/BungeeLogger.java
index cde3194..54275f6 100644
--- a/proxy/src/main/java/net/md_5/bungee/log/BungeeLogger.java
+++ b/proxy/src/main/java/net/md_5/bungee/log/BungeeLogger.java
@@ -27,7 +27,7 @@ public class BungeeLogger extends Logger
try
{
- FileHandler fileHandler = new FileHandler( System.getProperty("bungee.log-file", "proxy.log"), 1 << 24, 8, true );
+ FileHandler fileHandler = new FileHandler( System.getProperty("bungee.log-file", "proxy.log"), 1 << 23, 8, false );
fileHandler.setFormatter( formatter );
addHandler( fileHandler );
--
2.8.3

View File

@ -0,0 +1,33 @@
From c45b17cb631a5cf8ff869199b2b6e1331a548474 Mon Sep 17 00:00:00 2001
From: Techcable <Techcable@outlook.com>
Date: Sun, 7 Feb 2016 00:01:19 -0700
Subject: [PATCH] Add a property to accept invalid ping packets
This is disabled by default, as I don't wanna accept invalid packets
You can enable it by setting '-Dwaterfall.acceptInvalidPackets=true' at the command line
Fixes #23
diff --git a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
index 2056907..53d7ef8 100644
--- a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
+++ b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
@@ -243,10 +243,14 @@ public class InitialHandler extends PacketHandler implements PendingConnection
thisState = State.PING;
}
+ private static final boolean ACCEPT_INVALID_PACKETS = Boolean.parseBoolean(System.getProperty("waterfall.acceptInvalidPackets", "false"));
+
@Override
public void handle(PingPacket ping) throws Exception
{
- Preconditions.checkState( thisState == State.PING, "Not expecting PING" );
+ if (!ACCEPT_INVALID_PACKETS) {
+ Preconditions.checkState(thisState == State.PING, "Not expecting PING");
+ }
unsafe.sendPacket( ping );
disconnect( "" );
}
--
2.8.3

View File

@ -0,0 +1,47 @@
From 48727687f5d0091dc4a79106630aee820d464a6d Mon Sep 17 00:00:00 2001
From: Jonas Konrad <me@yawk.at>
Date: Tue, 23 Jun 2015 21:56:13 +0200
Subject: [PATCH] Ignore incoming chat messages before connecting to the
backend
Merges SpigotMC/BungeeCord#1515
diff --git a/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java b/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java
index a96e793..50f0308 100644
--- a/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java
+++ b/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java
@@ -2,6 +2,7 @@ package net.md_5.bungee.connection;
import com.google.common.base.Preconditions;
import net.md_5.bungee.BungeeCord;
+import net.md_5.bungee.ServerConnection;
import net.md_5.bungee.UserConnection;
import net.md_5.bungee.Util;
import net.md_5.bungee.api.ProxyServer;
@@ -108,13 +109,21 @@ public class UpstreamBridge extends PacketHandler
{
Preconditions.checkArgument( chat.getMessage().length() <= 100, "Chat message too long" ); // Mojang limit, check on updates
- ChatEvent chatEvent = new ChatEvent( con, con.getServer(), chat.getMessage() );
+ ServerConnection server = con.getServer();
+
+ // if we're still connecting just ignore this packet
+ if ( server == null )
+ {
+ throw CancelSendSignal.INSTANCE;
+ }
+
+ ChatEvent chatEvent = new ChatEvent( con, server, chat.getMessage() );
if ( !bungee.getPluginManager().callEvent( chatEvent ).isCancelled() )
{
chat.setMessage( chatEvent.getMessage() );
if ( !chatEvent.isCommand() || !bungee.getPluginManager().dispatchCommand( con, chat.getMessage().substring( 1 ) ) )
{
- con.getServer().unsafe().sendPacket( chat );
+ server.unsafe().sendPacket( chat );
}
}
throw CancelSendSignal.INSTANCE;
--
2.8.3

View File

@ -0,0 +1,200 @@
From cd50f5e9403ffc31c760f29aa6fce77490ae5ac3 Mon Sep 17 00:00:00 2001
From: kamcio96 <k.nadworski@icloud.com>
Date: Mon, 14 Mar 2016 15:59:52 -0700
Subject: [PATCH] Improve connection closing, fixing the kick delay.
Merges some of https://github.com/SpigotMC/BungeeCord/pull/1706 by @kamcio96
@kamcio96 claims that these channel closing changes are removing the need of delayed kick packets
@Janmm14 can confirm this (at login state) on a no-latency and low-latency connection (<1ms; ~16ms), high-latency connection was not tested, but it should work on these too.
diff --git a/proxy/src/main/java/net/md_5/bungee/ServerConnection.java b/proxy/src/main/java/net/md_5/bungee/ServerConnection.java
index 8c1260a..a7dfd1f 100644
--- a/proxy/src/main/java/net/md_5/bungee/ServerConnection.java
+++ b/proxy/src/main/java/net/md_5/bungee/ServerConnection.java
@@ -59,7 +59,7 @@ public class ServerConnection implements Server
@Override
public void run()
{
- ch.getHandle().close();
+ ch.close();
}
}, 100, TimeUnit.MILLISECONDS );
}
diff --git a/proxy/src/main/java/net/md_5/bungee/UserConnection.java b/proxy/src/main/java/net/md_5/bungee/UserConnection.java
index c88ab49..9a13f5c 100644
--- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java
+++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java
@@ -379,21 +379,7 @@ public final class UserConnection implements ProxiedPlayer
getName(), BaseComponent.toLegacyText( reason )
} );
- // Why do we have to delay this you might ask? Well the simple reason is MOJANG.
- // Despite many a bug report posted, ever since the 1.7 protocol rewrite, the client STILL has a race condition upon switching protocols.
- // As such, despite the protocol switch packets already having been sent, there is the possibility of a client side exception
- // To help combat this we will wait half a second before actually sending the disconnected packet so that whoever is on the other
- // end has a somewhat better chance of receiving the proper packet.
- ch.getHandle().eventLoop().schedule( new Runnable()
- {
-
- @Override
- public void run()
- {
- unsafe().sendPacket( new Kick( ComponentSerializer.toString( reason ) ) );
- ch.close();
- }
- }, 500, TimeUnit.MILLISECONDS );
+ ch.close(new Kick(ComponentSerializer.toString( reason )));
if ( server != null )
{
diff --git a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
index 53d7ef8..0b1be45 100644
--- a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
+++ b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
@@ -136,8 +136,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
public void handle(LegacyHandshake legacyHandshake) throws Exception
{
this.legacy = true;
- ch.getHandle().writeAndFlush( bungee.getTranslation( "outdated_client" ) );
- ch.close();
+ ch.close( bungee.getTranslation( "outdated_client" ) );
}
@Override
@@ -179,8 +178,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
+ '\u00a7' + legacy.getPlayers().getMax();
}
- ch.getHandle().writeAndFlush( kickMessage );
- ch.close();
+ ch.close( kickMessage );
}
};
@@ -251,8 +249,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
if (!ACCEPT_INVALID_PACKETS) {
Preconditions.checkState(thisState == State.PING, "Not expecting PING");
}
- unsafe.sendPacket( ping );
- disconnect( "" );
+ ch.close( ping );
}
@Override
@@ -538,24 +535,11 @@ public class InitialHandler extends PacketHandler implements PendingConnection
if ( !disconnecting || !ch.isClosed() )
{
disconnecting = true;
- // Why do we have to delay this you might ask? Well the simple reason is MOJANG.
- // Despite many a bug report posted, ever since the 1.7 protocol rewrite, the client STILL has a race condition upon switching protocols.
- // As such, despite the protocol switch packets already having been sent, there is the possibility of a client side exception
- // To help combat this we will wait half a second before actually sending the disconnected packet so that whoever is on the other
- // end has a somewhat better chance of receiving the proper packet.
- ch.getHandle().eventLoop().schedule( new Runnable()
- {
-
- @Override
- public void run()
- {
- if ( thisState != State.STATUS && thisState != State.PING )
- {
- unsafe().sendPacket( new Kick( ComponentSerializer.toString( reason ) ) );
- }
- ch.close();
- }
- }, 500, TimeUnit.MILLISECONDS );
+ if ( thisState != State.STATUS && thisState != State.PING ) {
+ ch.close( new Kick( ComponentSerializer.toString( reason ) ) );
+ } else {
+ ch.close();
+ }
}
}
diff --git a/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java b/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java
index 50f0308..7565ff9 100644
--- a/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java
+++ b/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java
@@ -79,6 +79,7 @@ public class UpstreamBridge extends PacketHandler
{
player.unsafe().sendPacket( packet );
}
+ con.getServer().setObsolete(true);
con.getServer().disconnect( "Quitting" );
}
}
diff --git a/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java b/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java
index 06d19c3..76bdff2 100644
--- a/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java
+++ b/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java
@@ -5,6 +5,7 @@ import net.md_5.bungee.compress.PacketDecompressor;
import net.md_5.bungee.protocol.PacketWrapper;
import com.google.common.base.Preconditions;
import io.netty.channel.Channel;
+import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import lombok.Getter;
@@ -16,7 +17,6 @@ public class ChannelWrapper
{
private final Channel ch;
- @Getter
private volatile boolean closed;
public ChannelWrapper(ChannelHandlerContext ctx)
@@ -38,23 +38,22 @@ public class ChannelWrapper
public void write(Object packet)
{
- if ( !closed )
+ if ( !isClosed() )
{
if ( packet instanceof PacketWrapper )
{
( (PacketWrapper) packet ).setReleased( true );
- ch.write( ( (PacketWrapper) packet ).buf, ch.voidPromise() );
+ ch.writeAndFlush( ( (PacketWrapper) packet ).buf, ch.voidPromise() );
} else
{
- ch.write( packet, ch.voidPromise() );
+ ch.writeAndFlush( packet, ch.voidPromise() );
}
- ch.flush();
}
}
public void close()
{
- if ( !closed )
+ if ( !isClosed() )
{
closed = true;
ch.flush();
@@ -62,6 +61,22 @@ public class ChannelWrapper
}
}
+ /**
+ * Send the given packet, then close the connection
+ *
+ * @param packet the packet to send before closing
+ */
+ public void close(Object packet) {
+ if (!isClosed()) {
+ closed = true;
+ ch.writeAndFlush(packet).addListeners(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE, ChannelFutureListener.CLOSE);
+ }
+ }
+
+ public boolean isClosed() {
+ return closed || !ch.isActive();
+ }
+
public void addBefore(String baseName, String name, ChannelHandler handler)
{
Preconditions.checkState( ch.eventLoop().inEventLoop(), "cannot add handler outside of event loop" );
--
2.8.3

View File

@ -0,0 +1,87 @@
From 465cc07d8909d48ac81e5a71916a8bc0b7e3a193 Mon Sep 17 00:00:00 2001
From: kamcio96 <k.nadworski@icloud.com>
Date: Mon, 14 Mar 2016 16:07:20 -0700
Subject: [PATCH] Use a worker and a boss event loop group.
Merges the rest of https://github.com/SpigotMC/BungeeCord/pull/1706 by @kamcio96 along with b8845c4edbae46bb66f6adda338330a1d4032057
This is proper practice for netty.
diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
index fd8d9b0..d0739c1 100644
--- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
+++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
@@ -106,7 +106,7 @@ public class BungeeCord extends ProxyServer
*/
private ResourceBundle baseBundle;
private ResourceBundle customBundle;
- public EventLoopGroup eventLoops;
+ public EventLoopGroup bossEventLoopGroup, workerEventLoopGroup;
/**
* locations.yml save thread.
*/
@@ -246,7 +246,8 @@ public class BungeeCord extends ProxyServer
ResourceLeakDetector.setLevel( ResourceLeakDetector.Level.DISABLED ); // Eats performance
}
- eventLoops = PipelineUtils.newEventLoopGroup( 0, new ThreadFactoryBuilder().setNameFormat( "Netty IO Thread #%1$d" ).build() );
+ bossEventLoopGroup = PipelineUtils.newEventLoopGroup( 0, new ThreadFactoryBuilder().setNameFormat( "Netty Boss IO Thread #%1$d" ).build() );
+ workerEventLoopGroup = PipelineUtils.newEventLoopGroup( 0, new ThreadFactoryBuilder().setNameFormat( "Netty Worker IO Thread #%1$d" ).build() );
File moduleDirectory = new File( "modules" );
moduleManager.load( this, moduleDirectory );
@@ -314,7 +315,7 @@ public class BungeeCord extends ProxyServer
.childOption( ChannelOption.WRITE_BUFFER_LOW_WATER_MARK, 1024 * 1024 * 1 )
.childAttr( PipelineUtils.LISTENER, info )
.childHandler( PipelineUtils.SERVER_CHILD )
- .group( eventLoops )
+ .group( bossEventLoopGroup, workerEventLoopGroup )
.localAddress( info.getHost() )
.bind().addListener( listener );
@@ -335,7 +336,7 @@ public class BungeeCord extends ProxyServer
}
}
};
- new RemoteQuery( this, info ).start( PipelineUtils.getDatagramChannel(), new InetSocketAddress( info.getHost().getAddress(), info.getQueryPort() ), eventLoops, bindListener );
+ new RemoteQuery( this, info ).start( PipelineUtils.getDatagramChannel(), new InetSocketAddress( info.getHost().getAddress(), info.getQueryPort() ), workerEventLoopGroup, bindListener );
}
}
}
@@ -391,12 +392,14 @@ public class BungeeCord extends ProxyServer
}
getLogger().info( "Closing IO threads" );
- eventLoops.shutdownGracefully();
- try
- {
- eventLoops.awaitTermination( Long.MAX_VALUE, TimeUnit.NANOSECONDS );
- } catch ( InterruptedException ex )
- {
+ bossEventLoopGroup.shutdownGracefully();
+ workerEventLoopGroup.shutdownGracefully();
+ while (true) {
+ try {
+ bossEventLoopGroup.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
+ workerEventLoopGroup.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
+ break;
+ } catch (InterruptedException ignored) {}
}
if ( reconnectHandler != null )
diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java b/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java
index bc56d4f..efcba31 100644
--- a/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java
+++ b/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java
@@ -145,7 +145,7 @@ public class BungeeServerInfo implements ServerInfo
};
new Bootstrap()
.channel( PipelineUtils.getChannel() )
- .group( BungeeCord.getInstance().eventLoops )
+ .group( BungeeCord.getInstance().workerEventLoopGroup )
.handler( PipelineUtils.BASE )
.option( ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000 ) // TODO: Configurable
.remoteAddress( getAddress() )
--
2.8.3

View File

@ -0,0 +1,62 @@
From 18a1e9fa9a98f93e8877616607b37cc92eaa07fb Mon Sep 17 00:00:00 2001
From: Techcable <Techcable@techcable.net>
Date: Fri, 18 Mar 2016 10:53:24 -0700
Subject: [PATCH] Better Decompression Sanity
Fixes #40
diff --git a/proxy/src/main/java/net/md_5/bungee/compress/PacketDecompressor.java b/proxy/src/main/java/net/md_5/bungee/compress/PacketDecompressor.java
index 21b3ea2..37fe6ac 100644
--- a/proxy/src/main/java/net/md_5/bungee/compress/PacketDecompressor.java
+++ b/proxy/src/main/java/net/md_5/bungee/compress/PacketDecompressor.java
@@ -1,5 +1,7 @@
package net.md_5.bungee.compress;
+import lombok.*;
+
import com.google.common.base.Preconditions;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
@@ -8,9 +10,11 @@ import java.util.List;
import net.md_5.bungee.jni.zlib.BungeeZlib;
import net.md_5.bungee.protocol.DefinedPacket;
+@RequiredArgsConstructor
public class PacketDecompressor extends MessageToMessageDecoder<ByteBuf>
{
+ private final int compressionThreshold;
private final BungeeZlib zlib = CompressFactory.zlib.newInstance();
@Override
@@ -35,12 +39,13 @@ public class PacketDecompressor extends MessageToMessageDecoder<ByteBuf>
in.skipBytes( in.readableBytes() );
} else
{
+ Preconditions.checkArgument( size >= compressionThreshold, "Decompressed size %s less than compression threshold %s", size, compressionThreshold);
ByteBuf decompressed = ctx.alloc().directBuffer();
try
{
zlib.process( in, decompressed );
- Preconditions.checkState( decompressed.readableBytes() == size, "Decompressed packet size mismatch" );
+ Preconditions.checkArgument( decompressed.readableBytes() == size, "Decompressed size %s is not equal to actual decompressed bytes", size, decompressed.readableBytes());
out.add( decompressed );
decompressed = null;
diff --git a/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java b/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java
index 76bdff2..f5c8f0a 100644
--- a/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java
+++ b/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java
@@ -105,7 +105,7 @@ public class ChannelWrapper
if ( ch.pipeline().get( PacketDecompressor.class ) == null && compressionThreshold != -1 )
{
- addBefore( PipelineUtils.PACKET_DECODER, "decompress", new PacketDecompressor() );
+ addBefore( PipelineUtils.PACKET_DECODER, "decompress", new PacketDecompressor(compressionThreshold) );
}
if ( compressionThreshold == -1 )
{
--
2.8.3

View File

@ -0,0 +1,47 @@
From 851c2b19e31527f7b758f9c924290ad0c950849d Mon Sep 17 00:00:00 2001
From: Tux <write@imaginarycode.com>
Date: Sun, 20 Mar 2016 01:36:23 -0400
Subject: [PATCH] Better race condition check for disconnect()
diff --git a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
index 0b1be45..9ced50c 100644
--- a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
+++ b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
@@ -8,6 +8,7 @@ import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.List;
import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import javax.crypto.SecretKey;
import com.google.gson.Gson;
@@ -96,12 +97,11 @@ public class InitialHandler extends PacketHandler implements PendingConnection
private boolean legacy;
@Getter
private String extraDataInHandshake = "";
- private boolean disconnecting;
+ private final AtomicBoolean disconnecting = new AtomicBoolean(false);
- @Override
public boolean shouldHandle(PacketWrapper packet) throws Exception
{
- return !disconnecting;
+ return !disconnecting.get();
}
private enum State
@@ -532,9 +532,8 @@ public class InitialHandler extends PacketHandler implements PendingConnection
@Override
public void disconnect(final BaseComponent... reason)
{
- if ( !disconnecting || !ch.isClosed() )
+ if ( disconnecting.compareAndSet(false, true) || !ch.isClosed() )
{
- disconnecting = true;
if ( thisState != State.STATUS && thisState != State.PING ) {
ch.close( new Kick( ComponentSerializer.toString( reason ) ) );
} else {
--
2.8.3

View File

@ -0,0 +1,120 @@
From da4c0a77fa856feae15b346aa2428714270afccf Mon Sep 17 00:00:00 2001
From: Techcable <Techcable@techcable.net>
Date: Tue, 3 May 2016 20:31:52 -0700
Subject: [PATCH] Upgrade to netty 4.1
Don't access a ByteBuf's underlying array with ByteBuf.array()
- ByteBuf.array() returns the underlying array storage, and does *not* return a view of the buffer as an array
diff --git a/pom.xml b/pom.xml
index fda3278..d2f458a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -76,7 +76,7 @@
<properties>
<build.number>unknown</build.number>
- <netty.version>4.0.33.Final</netty.version>
+ <netty.version>4.1.0.CR7</netty.version>
<!-- Require Java 8 -->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
diff --git a/protocol/pom.xml b/protocol/pom.xml
index 8b462f5..ccee47e 100644
--- a/protocol/pom.xml
+++ b/protocol/pom.xml
@@ -32,6 +32,12 @@
<scope>compile</scope>
</dependency>
<dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-handler</artifactId>
+ <version>${netty.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
<groupId>net.sf.trove4j</groupId>
<artifactId>trove4j</artifactId>
<version>3.0.3</version>
diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/PluginMessage.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/PluginMessage.java
index bbaef39..e094932 100644
--- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/PluginMessage.java
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/PluginMessage.java
@@ -9,6 +9,8 @@ import java.io.DataInputStream;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
+import io.netty.buffer.ByteBufInputStream;
+import io.netty.buffer.ByteBufUtil;
import lombok.NoArgsConstructor;
import net.md_5.bungee.protocol.AbstractPacketHandler;
import net.md_5.bungee.protocol.ProtocolConstants;
@@ -20,9 +22,22 @@ import net.md_5.bungee.protocol.ProtocolConstants;
public class PluginMessage extends DefinedPacket
{
+ public PluginMessage(String tag, ByteBuf data, boolean allowExtendedPacket) {
+ this(tag, ByteBufUtil.getBytes(data), allowExtendedPacket);
+ }
+
private String tag;
private byte[] data;
+ public void setData(byte[] data) {
+ this.data = Preconditions.checkNotNull(data, "Null data");
+ }
+
+ public void setData(ByteBuf buf) {
+ Preconditions.checkNotNull(buf, "Null buffer");
+ setData(ByteBufUtil.getBytes(buf));
+ }
+
/**
* Allow this packet to be sent as an "extended" packet.
*/
diff --git a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
index 44f0b61..e327325 100644
--- a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
+++ b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
@@ -232,7 +232,7 @@ public class ServerConnector extends PacketHandler
ByteBuf brand = ByteBufAllocator.DEFAULT.heapBuffer();
DefinedPacket.writeString( bungee.getName() + " (" + bungee.getVersion() + ")", brand );
- user.unsafe().sendPacket( new PluginMessage( "MC|Brand", brand.array().clone(), handshakeHandler.isServerForge() ) );
+ user.unsafe().sendPacket( new PluginMessage( "MC|Brand", brand, handshakeHandler.isServerForge() ) );
brand.release();
} else
{
diff --git a/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java b/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java
index 7ba0bcb..fa57f28 100644
--- a/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java
+++ b/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java
@@ -235,7 +235,7 @@ public class DownstreamBridge extends PacketHandler
brand.release();
brand = ByteBufAllocator.DEFAULT.heapBuffer();
DefinedPacket.writeString( bungee.getName() + " (" + bungee.getVersion() + ")" + " <- " + serverBrand, brand );
- pluginMessage.setData( brand.array().clone() );
+ pluginMessage.setData( brand );
brand.release();
// changes in the packet are ignored so we need to send it manually
con.unsafe().sendPacket( pluginMessage );
diff --git a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java
index f0d0189..aec8251 100644
--- a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java
+++ b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java
@@ -41,9 +41,9 @@ import net.md_5.bungee.protocol.Varint21LengthFieldPrepender;
public class PipelineUtils
{
- public static final AttributeKey<ListenerInfo> LISTENER = new AttributeKey<>( "ListerInfo" );
- public static final AttributeKey<UserConnection> USER = new AttributeKey<>( "User" );
- public static final AttributeKey<BungeeServerInfo> TARGET = new AttributeKey<>( "Target" );
+ public static final AttributeKey<ListenerInfo> LISTENER = AttributeKey.newInstance("ListerInfo");
+ public static final AttributeKey<UserConnection> USER = AttributeKey.newInstance("User");
+ public static final AttributeKey<BungeeServerInfo> TARGET = AttributeKey.newInstance("Target");
public static final ChannelInitializer<Channel> SERVER_CHILD = new ChannelInitializer<Channel>()
{
@Override
--
2.8.3

View File

@ -0,0 +1,23 @@
From ced5b9324cc6270083caa16674d09e78e8ae72cd Mon Sep 17 00:00:00 2001
From: Techcable <Techcable@techcable.net>
Date: Tue, 5 Apr 2016 11:00:16 -0700
Subject: [PATCH] Print stack trace when the ByteBuf is not direct.
The issue with ByteBufs not being direct should be fixed as of netty 4.1, and stacktraces provide valuable information.
diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/Varint21FrameDecoder.java b/protocol/src/main/java/net/md_5/bungee/protocol/Varint21FrameDecoder.java
index 29e54db..6da27fc 100644
--- a/protocol/src/main/java/net/md_5/bungee/protocol/Varint21FrameDecoder.java
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/Varint21FrameDecoder.java
@@ -51,7 +51,7 @@ public class Varint21FrameDecoder extends ByteToMessageDecoder
if ( !DIRECT_WARNING )
{
DIRECT_WARNING = true;
- System.out.println( "Netty is not using direct IO buffers." );
+ new Throwable("Using a " + in.getClass().getTypeName() + ", not a direct byte buf!").printStackTrace();
}
// See https://github.com/SpigotMC/BungeeCord/issues/1717
--
2.8.3

View File

@ -0,0 +1,57 @@
From bc91805c7d00866d7c320cf01ee5bc79e450cc72 Mon Sep 17 00:00:00 2001
From: Tux <write@imaginarycode.com>
Date: Wed, 13 Apr 2016 14:00:40 -0400
Subject: [PATCH] Validate that chat messages are non-blank
diff --git a/proxy/src/main/java/io/github/waterfallmc/waterfall/StringUtil.java b/proxy/src/main/java/io/github/waterfallmc/waterfall/StringUtil.java
new file mode 100644
index 0000000..940ad80
--- /dev/null
+++ b/proxy/src/main/java/io/github/waterfallmc/waterfall/StringUtil.java
@@ -0,0 +1,22 @@
+package io.github.waterfallmc.waterfall;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class StringUtil {
+ public static boolean isBlank(String str) {
+ if (str.isEmpty()) {
+ return true;
+ }
+
+ int l = str.length();
+ for (int i = 0; i < l; i++) {
+ if (!Character.isWhitespace(str.charAt(i))) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java b/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java
index 7565ff9..42bb2fb 100644
--- a/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java
+++ b/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java
@@ -1,6 +1,7 @@
package net.md_5.bungee.connection;
import com.google.common.base.Preconditions;
+import io.github.waterfallmc.waterfall.StringUtil;
import net.md_5.bungee.BungeeCord;
import net.md_5.bungee.ServerConnection;
import net.md_5.bungee.UserConnection;
@@ -109,6 +110,7 @@ public class UpstreamBridge extends PacketHandler
public void handle(Chat chat) throws Exception
{
Preconditions.checkArgument( chat.getMessage().length() <= 100, "Chat message too long" ); // Mojang limit, check on updates
+ Preconditions.checkArgument(!StringUtil.isBlank(chat.getMessage()), "Chat message is empty");
ServerConnection server = con.getServer();
--
2.8.3

View File

@ -0,0 +1,297 @@
From be2a4b8a6d0f1d6e2e4ceea0bf35a8c3209af118 Mon Sep 17 00:00:00 2001
From: Techcable <Techcable@techcable.net>
Date: Mon, 25 Apr 2016 23:46:00 -0700
Subject: [PATCH] Reduce the overhead of lots and lots of teams with the same
names
Featherboard (and other bad plugins) use persistent scoreboards (scoreboard.dat), causing every team ever to be sent to waterfall. This is bad, and takes tons of memory.
Uses String.intern() to avoid duplicating strings
Uses a sorted array to avoid the overhead of the hashset in a team.
diff --git a/api/src/main/java/io/github/waterfallmc/waterfall/utils/LowMemorySet.java b/api/src/main/java/io/github/waterfallmc/waterfall/utils/LowMemorySet.java
new file mode 100644
index 0000000..3a062b6
--- /dev/null
+++ b/api/src/main/java/io/github/waterfallmc/waterfall/utils/LowMemorySet.java
@@ -0,0 +1,177 @@
+package io.github.waterfallmc.waterfall.utils;
+
+import lombok.*;
+
+import java.util.AbstractSet;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * A set that uses a <a href=>binary search</a> to find objects in a <a href=https://en.wikipedia.org/wiki/Sorted_array>sorted array</a>.
+ * Avoids the memory cost of {@link java.util.HashSet}, while maintaining reasonable {@link Set#contains}
+ * <b>Insertions ma O(N)!</b>
+ */
+public class LowMemorySet<T extends Comparable<T>> extends AbstractSet<T> implements Set<T> {
+ private final List<T> backing;
+ @Setter
+ private boolean trimAggressively;
+
+ protected LowMemorySet(List<T> list) {
+ this.backing = checkNotNull(list, "Null list");
+ this.sort(); // We have to sort any initial elements
+ this.trim(true);
+ }
+
+ public static <T extends Comparable<T>> LowMemorySet<T> create() {
+ return new LowMemorySet<>(new ArrayList<T>());
+ }
+
+ public static <T extends Comparable<T>> LowMemorySet<T> copyOf(Collection<T> c) {
+ return new LowMemorySet<>(new ArrayList<>(c));
+ }
+
+ @SuppressWarnings("unchecked") // nope
+ private int indexOf(Object o) {
+ return Collections.binarySearch((List) backing, o);
+ }
+
+ private void sort() {
+ backing.sort(null);
+ this.trim();
+ }
+
+ private void trim() {
+ trim(false);
+ }
+
+ private void trim(boolean force) {
+ if (backing instanceof ArrayList && force || trimAggressively) ((ArrayList) backing).trimToSize();
+ }
+
+ @Override
+ public int size() {
+ return backing.size();
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return indexOf(o) >= 0;
+ }
+
+ @Override
+ public Iterator<T> iterator() {
+ Iterator<T> backing = this.backing.iterator();
+ return new Iterator<T>() {
+ private T last;
+
+ @Override
+ public boolean hasNext() {
+ return backing.hasNext();
+ }
+
+ @Override
+ public T next() {
+ return (last = backing.next());
+ }
+
+ @Override
+ public void remove() {
+ LowMemorySet.this.remove(last);
+ }
+
+ @Override
+ public void forEachRemaining(Consumer<? super T> action) {
+ backing.forEachRemaining(action);
+ }
+ };
+ }
+
+ @Override
+ public Object[] toArray() {
+ return backing.toArray();
+ }
+
+ @Override
+ public <T1> T1[] toArray(T1[] a) {
+ return backing.toArray(a);
+ }
+
+ @Override
+ public boolean add(T t) {
+ if (contains(t)) return false;
+ backing.add(t);
+ this.sort();
+ return true;
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ T old = backing.remove(indexOf(o));
+ this.trim();
+ assert old == o;
+ return old != null;
+ }
+
+ @Override
+ public boolean removeAll(Collection<?> c) {
+ int oldSize = this.size();
+ boolean result = backing.removeIf(c::contains);
+ this.trim(oldSize - this.size() > 10);
+ return result;
+ }
+
+ @Override
+ public boolean retainAll(Collection<?> c) {
+ int oldSize = this.size();
+ boolean result = backing.removeIf((o) -> !c.contains(o));
+ this.trim(oldSize - this.size() > 10);
+ return result;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public boolean addAll(Collection<? extends T> c) {
+ if (containsAll(c)) return false;
+ backing.addAll(c);
+ this.sort();
+ return true;
+ }
+
+ @Override
+ public void clear() {
+ backing.clear();
+ this.trim(true);
+ }
+
+ @Override
+ public void forEach(Consumer<? super T> action) {
+ backing.forEach(action);
+ }
+
+ @Override
+ public Stream<T> stream() {
+ return backing.stream();
+ }
+
+ @Override
+ public Stream<T> parallelStream() {
+ return backing.parallelStream();
+ }
+
+ @Override
+ public boolean removeIf(Predicate<? super T> filter) {
+ int oldSize = this.size();
+ boolean worked = backing.removeIf(filter);
+ this.trim(this.size() - oldSize > 10);
+ return worked;
+ }
+}
diff --git a/api/src/main/java/net/md_5/bungee/api/score/Team.java b/api/src/main/java/net/md_5/bungee/api/score/Team.java
index 4166037..f0f019b 100644
--- a/api/src/main/java/net/md_5/bungee/api/score/Team.java
+++ b/api/src/main/java/net/md_5/bungee/api/score/Team.java
@@ -1,11 +1,12 @@
package net.md_5.bungee.api.score;
+import lombok.*;
+
import java.util.Collection;
import java.util.Collections;
-import java.util.HashSet;
import java.util.Set;
-import lombok.Data;
-import lombok.NonNull;
+
+import io.github.waterfallmc.waterfall.utils.LowMemorySet;
@Data
public class Team
@@ -20,7 +21,7 @@ public class Team
private String nameTagVisibility;
private String collisionRule;
private byte color;
- private Set<String> players = new HashSet<>();
+ private Set<String> players = LowMemorySet.create();
public Collection<String> getPlayers()
{
@@ -29,7 +30,7 @@ public class Team
public void addPlayer(String name)
{
- players.add( name );
+ players.add(name.intern());
}
public void removePlayer(String name)
diff --git a/api/src/test/java/io/github/waterfallmc/waterfall/utils/LowMemorySetTest.java b/api/src/test/java/io/github/waterfallmc/waterfall/utils/LowMemorySetTest.java
new file mode 100644
index 0000000..5aa306a
--- /dev/null
+++ b/api/src/test/java/io/github/waterfallmc/waterfall/utils/LowMemorySetTest.java
@@ -0,0 +1,56 @@
+package io.github.waterfallmc.waterfall.utils;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class LowMemorySetTest {
+
+ private static final ImmutableList<String> ELEMENTS = ImmutableList.of("test", "bob", "road", "food", "sleep", "sore-thought", "pain");
+
+ @Test
+ public void testContains() {
+ LowMemorySet<String> set = LowMemorySet.copyOf(ELEMENTS);
+ assertTrue(set.contains("test"));
+ assertTrue(set.contains("bob"));
+ assertFalse(set.contains("stupid"));
+ assertFalse(set.contains("head"));
+ }
+
+ @Test
+ public void testRemove() {
+ LowMemorySet<String> set = LowMemorySet.copyOf(ELEMENTS);
+ assertTrue(set.contains("test"));
+ set.remove("test");
+ assertFalse(set.contains("test"));
+ assertTrue(set.contains("bob"));
+ set.remove("bob");
+ assertFalse(set.contains("bob"));
+ assertTrue(ELEMENTS.size() - set.size() == 2);
+ assertTrue(set.contains("road"));
+ assertTrue(set.contains("food"));
+ assertTrue(set.contains("pain"));
+ set.removeAll(ImmutableList.of("road", "food", "pain"));
+ assertFalse(set.contains("road"));
+ assertFalse(set.contains("food"));
+ assertFalse(set.contains("pain"));
+ assertTrue(ELEMENTS.size() - set.size() == 5);
+ }
+
+ @Test
+ public void testAdd() {
+ LowMemorySet<String> set = LowMemorySet.copyOf(ELEMENTS);
+ assertFalse(set.contains("Techcable"));
+ set.add("Techcable");
+ assertTrue(set.contains("Techcable"));
+ set.addAll(ImmutableList.of("Techcable", "PhanaticD", "Dragonslayer293", "Aikar"));
+ assertTrue(set.contains("Techcable"));
+ assertTrue(set.contains("PhanaticD"));
+ assertTrue(set.contains("Aikar"));
+ assertFalse(set.contains("md_5"));
+ }
+
+}
--
2.8.3

21
LICENSE.txt Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2015-2016 Waterfall Team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

30
README.md Normal file
View File

@ -0,0 +1,30 @@
# Waterfall <a href="https://ci.getwaterfall.xyz/project.html?projectId=Waterfall"><img src="https://ci.getwaterfall.xyz/app/rest/builds/buildType:Waterfall_Build,branch:master/statusIcon"/></a>
Waterfall is a fork of the well-known [BungeeCord](https://github.com/SpigotMC/BungeeCord) server teleportation suite.
Waterfall focuses on three main areas:
* **Stability**: Waterfall aims to be stable. We will achieve this through making the code base testable and discouraging practices that lead to proxy lag.
* **Features**: Waterfall aims to include more features than canonical BungeeCord.
* **Scalability**: Waterfall should be able to handle a large number of concurrent players, given a reasonably modern CPU, memory, and good network connection.
## Why fork BungeeCord?
Think of Waterfall as a principles fork.
Waterfall was forked because of the fact that upstream does not accept many contributions that are intended to better the ecosystem. Simply put, Waterfall aims to better
the ecosystem by allowing changes to be exposed to a wider audience more quickly.
Waterfall will still track upstream BungeeCord and merge changes as needed.
## Join us
* Feel free to open a PR! We accept contributions.
* Join us on IRC (irc.esper.net #waterfall, [webchat](http://webchat.esper.net/?nick=&channels=waterfall)).
* Visit our forums on [Aquifer](https://aquifermc.org).
Special Thanks To
-----------------
![YourKit-Logo](https://yourkit.com/images/yklogo.png)
[YourKit](https://yourkit.com/), makers of the outstanding Java profiler, supports open source projects of all kinds with their full-featured [Java](https://yourkit.com/features/) and [.NET](https://yourkit.com/dotnet/features/) application profilers. We thank them for granting Waterfall an OSS license so that we can make our software the best it can be.

68
applyPatches.sh Executable file
View File

@ -0,0 +1,68 @@
#!/usr/bin/env bash
(
PS1="$"
basedir="$(cd "$1" && pwd -P)"
workdir="$basedir/work"
gpgsign="$(git config commit.gpgsign || echo "false")"
echo "Rebuilding Forked projects.... "
function applyPatch {
what=$1
what_name=$(basename "$what")
target=$2
branch=$3
cd "$basedir/$what"
git fetch
git branch -f upstream "$branch" >/dev/null
cd "$basedir"
if [ ! -d "$basedir/$target" ]; then
git clone "$what" "$target"
fi
cd "$basedir/$target"
# Disable GPG signing before AM, slows things down and doesn't play nicely.
# There is also zero rational or logical reason to do so for these sub-repo AMs.
# Calm down kids, it's re-enabled (if needed) immediately after, pass or fail.
git config commit.gpgsign false
echo "Resetting $target to $what_name..."
git remote rm upstream > /dev/null 2>&1
git remote add upstream "$basedir/$what" >/dev/null 2>&1
git checkout master 2>/dev/null || git checkout -b master
git fetch upstream >/dev/null 2>&1
git reset --hard upstream/upstream
echo " Applying patches to $target..."
git am --abort >/dev/null 2>&1
git am --3way --ignore-whitespace "$basedir/${what_name}-Patches/"*.patch
if [ "$?" != "0" ]; then
echo " Something did not apply cleanly to $target."
echo " Please review above details and finish the apply then"
echo " save the changes with rebuildPatches.sh"
exit 1
else
echo " Patches applied cleanly to $target"
fi
}
function enableCommitSigningIfNeeded {
if [[ "$gpgsign" == "true" ]]; then
git config commit.gpgsign true
fi
}
# Apply paper
cd "$basedir"
(
applyPatch "BungeeCord" Waterfall-Proxy HEAD
enableCommitSigningIfNeeded
) || (
echo "Failed to apply WaterfallPatches"
enableCommitSigningIfNeeded
exit 1
) || exit 1
)

61
rebuildPatches.sh Executable file
View File

@ -0,0 +1,61 @@
#!/usr/bin/env bash
(
PS1="$"
basedir="$(cd "$1" && pwd -P)"
workdir="$basedir/work"
echo "Rebuilding patch files from current fork state..."
git config core.safecrlf false
function cleanupPatches {
cd "$1"
for patch in *.patch; do
echo "$patch"
gitver=$(tail -n 2 "$patch" | grep -ve "^$" | tail -n 1)
diffs=$(git diff --staged "$patch" | grep -E "^(\+|\-)" | grep -Ev "(From [a-z0-9]{32,}|\-\-\- a|\+\+\+ b|.index)")
testver=$(echo "$diffs" | tail -n 2 | grep -ve "^$" | tail -n 1 | grep "$gitver")
if [ "x$testver" != "x" ]; then
diffs=$(echo "$diffs" | sed 'N;$!P;$!D;$d')
fi
if [ "x$diffs" == "x" ] ; then
git reset HEAD "$patch" >/dev/null
git checkout -- "$patch" >/dev/null
fi
done
}
function savePatches {
what=$1
what_name=$(basename "$what")
target=$2
echo "Formatting patches for $what..."
cd "$basedir/${what_name}-Patches/"
if [ -d "$basedir/$target/.git/rebase-apply" ]; then
# in middle of a rebase, be smarter
echo "REBASE DETECTED - PARTIAL SAVE"
last=$(cat "$basedir/$target/.git/rebase-apply/last")
next=$(cat "$basedir/$target/.git/rebase-apply/next")
for i in $(seq -f "%04g" 1 1 $last)
do
if [ $i -lt $next ]; then
rm ${i}-*.patch
fi
done
else
rm -rf *.patch
fi
cd "$basedir/$target"
git format-patch --no-stat -N -o "$basedir/${what_name}-Patches/" upstream/upstream >/dev/null
cd "$basedir"
git add -A "$basedir/${what_name}-Patches"
cleanupPatches "$basedir/${what_name}-Patches"
echo " Patches saved for $what to $what_name-Patches/"
}
savePatches "BungeeCord" "Waterfall-Proxy"
)