mirror of
https://github.com/GeyserMC/Floodgate.git
synced 2025-12-19 14:59:20 +00:00
Added a translate method to the logger and changed the code style a bit
This commit is contained in:
414
.idea/codeStyles/Project.xml
generated
414
.idea/codeStyles/Project.xml
generated
@@ -1,7 +1,64 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<option name="OTHER_INDENT_OPTIONS">
|
||||
<value>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="INSERT_INNER_CLASS_IMPORTS" value="true" />
|
||||
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
|
||||
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
|
||||
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
|
||||
<value />
|
||||
</option>
|
||||
<option name="IMPORT_LAYOUT_TABLE">
|
||||
<value>
|
||||
<package name="" withSubpackages="true" static="true" />
|
||||
<emptyLine />
|
||||
<package name="" withSubpackages="true" static="false" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RIGHT_MARGIN" value="100" />
|
||||
<option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="true" />
|
||||
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
|
||||
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
|
||||
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
||||
<option name="ALIGN_MULTILINE_FOR" value="false" />
|
||||
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true" />
|
||||
<option name="CALL_PARAMETERS_WRAP" value="1" />
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="1" />
|
||||
<option name="EXTENDS_LIST_WRAP" value="1" />
|
||||
<option name="THROWS_KEYWORD_WRAP" value="1" />
|
||||
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
|
||||
<option name="BINARY_OPERATION_WRAP" value="1" />
|
||||
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
|
||||
<option name="TERNARY_OPERATION_WRAP" value="1" />
|
||||
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
|
||||
<option name="FOR_STATEMENT_WRAP" value="1" />
|
||||
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
|
||||
<option name="WRAP_COMMENTS" value="true" />
|
||||
<option name="IF_BRACE_FORCE" value="3" />
|
||||
<option name="DOWHILE_BRACE_FORCE" value="3" />
|
||||
<option name="WHILE_BRACE_FORCE" value="3" />
|
||||
<option name="FOR_BRACE_FORCE" value="3" />
|
||||
<JavaCodeStyleSettings>
|
||||
<option name="DO_NOT_WRAP_AFTER_SINGLE_ANNOTATION" value="true" />
|
||||
<option name="INSERT_INNER_CLASS_IMPORTS" value="true" />
|
||||
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
|
||||
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
|
||||
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
|
||||
<value />
|
||||
</option>
|
||||
<option name="IMPORT_LAYOUT_TABLE">
|
||||
<value>
|
||||
<package name="" withSubpackages="true" static="true" />
|
||||
<emptyLine />
|
||||
<package name="" withSubpackages="true" static="false" />
|
||||
</value>
|
||||
</option>
|
||||
</JavaCodeStyleSettings>
|
||||
<JetCodeStyleSettings>
|
||||
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
||||
<value>
|
||||
@@ -20,8 +77,357 @@
|
||||
</value>
|
||||
</option>
|
||||
</JetCodeStyleSettings>
|
||||
<ScalaCodeStyleSettings>
|
||||
<option name="MULTILINE_STRING_CLOSING_QUOTES_ON_NEW_LINE" value="true" />
|
||||
</ScalaCodeStyleSettings>
|
||||
<XML>
|
||||
<option name="XML_ALIGN_ATTRIBUTES" value="false" />
|
||||
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
|
||||
</XML>
|
||||
<codeStyleSettings language="JAVA">
|
||||
<option name="RIGHT_MARGIN" value="100" />
|
||||
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
|
||||
<option name="CALL_PARAMETERS_WRAP" value="1" />
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="1" />
|
||||
<option name="EXTENDS_LIST_WRAP" value="1" />
|
||||
<option name="THROWS_KEYWORD_WRAP" value="1" />
|
||||
<option name="BINARY_OPERATION_WRAP" value="1" />
|
||||
<option name="TERNARY_OPERATION_WRAP" value="1" />
|
||||
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
|
||||
<option name="KEEP_SIMPLE_CLASSES_IN_ONE_LINE" value="true" />
|
||||
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
|
||||
<option name="WRAP_COMMENTS" value="true" />
|
||||
<option name="IF_BRACE_FORCE" value="3" />
|
||||
<option name="DOWHILE_BRACE_FORCE" value="3" />
|
||||
<option name="WHILE_BRACE_FORCE" value="3" />
|
||||
<option name="FOR_BRACE_FORCE" value="3" />
|
||||
<option name="WRAP_ON_TYPING" value="0" />
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="JSON">
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="XML">
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
<arrangement>
|
||||
<rules>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:android</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:id</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>style</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:.*Style</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_width</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_height</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_weight</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_margin</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_marginTop</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_marginBottom</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_marginStart</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_marginEnd</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_marginLeft</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_marginRight</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:padding</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:paddingTop</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:paddingBottom</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:paddingStart</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:paddingEnd</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:paddingLeft</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:paddingRight</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res-auto\n</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_NAMESPACE>http://schemas.android.com/tools</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
</rules>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
88
api/pom.xml
88
api/pom.xml
@@ -2,14 +2,55 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<artifactId>api</artifactId>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<finalName>${outputName}</finalName>
|
||||
<shadedArtifactAttached>true</shadedArtifactAttached>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.geysermc</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>${geyser.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-transport</artifactId>
|
||||
<version>4.1.49.Final</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jsr305</artifactId>
|
||||
<version>3.0.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>api</artifactId>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
@@ -33,45 +74,4 @@
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.geysermc</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>${geyser.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-transport</artifactId>
|
||||
<version>4.1.49.Final</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jsr305</artifactId>
|
||||
<version>3.0.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<finalName>${outputName}</finalName>
|
||||
<shadedArtifactAttached>true</shadedArtifactAttached>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -25,12 +25,18 @@
|
||||
|
||||
package org.geysermc.floodgate.api;
|
||||
|
||||
import java.util.UUID;
|
||||
import org.geysermc.floodgate.api.link.PlayerLink;
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface FloodgateApi {
|
||||
/**
|
||||
* Returns the Floodgate API instance.
|
||||
*/
|
||||
static FloodgateApi getInstance() {
|
||||
return InstanceHolder.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to determine if the given <b>online</b> player is a bedrock player
|
||||
*
|
||||
@@ -56,9 +62,9 @@ public interface FloodgateApi {
|
||||
UUID createJavaPlayerId(long xuid);
|
||||
|
||||
/**
|
||||
* Checks if the uuid of the player has the {@link #createJavaPlayerId(long)} format.
|
||||
* This method can't validate a linked player uuid, since that doesn't equal the format.
|
||||
* Use {@link #isBedrockPlayer(UUID)} if you want to include linked accounts.
|
||||
* Checks if the uuid of the player has the {@link #createJavaPlayerId(long)} format. This
|
||||
* method can't validate a linked player uuid, since that doesn't equal the format. Use {@link
|
||||
* #isBedrockPlayer(UUID)} if you want to include linked accounts.
|
||||
*
|
||||
* @param uuid the uuid to check
|
||||
* @return true if the given uuid has the correct format.
|
||||
@@ -71,11 +77,4 @@ public interface FloodgateApi {
|
||||
default PlayerLink getPlayerLink() {
|
||||
return InstanceHolder.getPlayerLink();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Floodgate API instance.
|
||||
*/
|
||||
static FloodgateApi getInstance() {
|
||||
return InstanceHolder.getInstance();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,12 +25,11 @@
|
||||
|
||||
package org.geysermc.floodgate.api;
|
||||
|
||||
import java.util.UUID;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.floodgate.api.inject.PlatformInjector;
|
||||
import org.geysermc.floodgate.api.link.PlayerLink;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public final class InstanceHolder {
|
||||
@Getter private static FloodgateApi instance;
|
||||
@Getter private static PlayerLink playerLink;
|
||||
|
||||
@@ -29,30 +29,27 @@ import io.netty.channel.Channel;
|
||||
|
||||
public interface InjectorAddon {
|
||||
/**
|
||||
* Called when injecting a specific channel
|
||||
* (every client that is connected to the server has his own channel).
|
||||
* Internally used for the Floodgate debugger and data handler but can also be used for
|
||||
* third party things.
|
||||
* Called when injecting a specific channel (every client that is connected to the server has
|
||||
* his own channel). Internally used for the Floodgate debugger and data handler but can also be
|
||||
* used for third party things.
|
||||
*
|
||||
* @param channel the channel that the injector is injecting
|
||||
* @param proxyToServer if the the connection is between the proxy and a server
|
||||
* @param toServer if the the connection is between a proxy and a server
|
||||
*/
|
||||
void onInject(Channel channel, boolean proxyToServer);
|
||||
void onInject(Channel channel, boolean toServer);
|
||||
|
||||
/**
|
||||
* Called when the player successfully logged in.
|
||||
* That is the moment that most of the addons can deregister.
|
||||
* Note that it is entirely optional to remove the addon from the channel,
|
||||
* the injector won't force the addon to remove.
|
||||
* Called when the player successfully logged in. That is the moment that most of the addons can
|
||||
* deregister. Note that it is entirely optional to remove the addon from the channel, the
|
||||
* injector won't force the addon to remove.
|
||||
*
|
||||
* @param channel the channel that the injector injected
|
||||
*/
|
||||
void onLoginDone(Channel channel);
|
||||
|
||||
/**
|
||||
* Called when Floodgate is removing the injection from the server.
|
||||
* The addon should remove his traces otherwise it is likely that an error will popup after
|
||||
* the server is injected again.
|
||||
* Called when Floodgate is removing the injection from the server. The addon should remove his
|
||||
* traces otherwise it is likely that an error will popup after the server is injected again.
|
||||
*
|
||||
* @param channel the channel that the injector injected
|
||||
*/
|
||||
|
||||
@@ -26,17 +26,16 @@
|
||||
package org.geysermc.floodgate.api.inject;
|
||||
|
||||
/**
|
||||
* The global interface of all the Platform Injectors.
|
||||
* The injector can be used for various things. It is used internally for getting Floodgate
|
||||
* data out of the handshake packet and for debug mode, but there is also an option to add your
|
||||
* own addons.
|
||||
* Note that every Floodgate platform that supports netty should implement this,
|
||||
* but the platform implementation isn't required to implement this.
|
||||
* The global interface of all the Platform Injectors. The injector can be used for various things.
|
||||
* It is used internally for getting Floodgate data out of the handshake packet and for debug mode,
|
||||
* but there is also an option to add your own addons. Note that every Floodgate platform that
|
||||
* supports netty should implement this, but the platform implementation isn't required to implement
|
||||
* this.
|
||||
*/
|
||||
public interface PlatformInjector {
|
||||
/**
|
||||
* Injects the server connection.
|
||||
* This will allow various addons (like getting the Floodgate data and debug mode) to work.
|
||||
* Injects the server connection. This will allow various addons (like getting the Floodgate
|
||||
* data and debug mode) to work.
|
||||
*
|
||||
* @return true if the connection has successfully been injected
|
||||
* @throws Exception if something went wrong while injecting the server connection
|
||||
@@ -44,9 +43,8 @@ public interface PlatformInjector {
|
||||
boolean inject() throws Exception;
|
||||
|
||||
/**
|
||||
* Removes the injection from the server.
|
||||
* Please note that this function should only be used internally (on plugin shutdown).
|
||||
* This method will also remove every added addon.
|
||||
* Removes the injection from the server. Please note that this function should only be used
|
||||
* internally (on plugin shutdown). This method will also remove every added addon.
|
||||
*
|
||||
* @return true if the injection has successfully been removed
|
||||
* @throws Exception if something went wrong while removing the injection
|
||||
@@ -61,9 +59,8 @@ public interface PlatformInjector {
|
||||
boolean isInjected();
|
||||
|
||||
/**
|
||||
* Adds an addon to the addon list of the Floodgate Injector
|
||||
* (the addon is called when Floodgate injects a channel).
|
||||
* See {@link InjectorAddon} for more info.
|
||||
* Adds an addon to the addon list of the Floodgate Injector (the addon is called when Floodgate
|
||||
* injects a channel). See {@link InjectorAddon} for more info.
|
||||
*
|
||||
* @param addon the addon to add to the addon list
|
||||
* @return true if the addon has been added, false if the addon is already present
|
||||
@@ -71,9 +68,8 @@ public interface PlatformInjector {
|
||||
boolean addAddon(InjectorAddon addon);
|
||||
|
||||
/**
|
||||
* Removes an addon from the addon list of the Floodgate Injector
|
||||
* (the addon is called when Floodgate injects a channel).
|
||||
* See {@link InjectorAddon} for more info.
|
||||
* Removes an addon from the addon list of the Floodgate Injector (the addon is called when
|
||||
* Floodgate injects a channel). See {@link InjectorAddon} for more info.
|
||||
*
|
||||
* @param addon the class of the addon to remove from the addon list
|
||||
* @param <T> the addon type
|
||||
|
||||
@@ -25,9 +25,8 @@
|
||||
|
||||
package org.geysermc.floodgate.api.link;
|
||||
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
|
||||
public interface LinkRequest {
|
||||
/**
|
||||
@@ -64,10 +63,10 @@ public interface LinkRequest {
|
||||
boolean isExpired(long linkTimeout);
|
||||
|
||||
/**
|
||||
* Checks if the given FloodgatePlayer is the player requested in this LinkRequest.
|
||||
* This method will check both the real bedrock username
|
||||
* {@link FloodgatePlayer#getUsername()} and the edited username
|
||||
* {@link FloodgatePlayer#getJavaUsername()} and returns true if one of the two matches.
|
||||
* Checks if the given FloodgatePlayer is the player requested in this LinkRequest. This method
|
||||
* will check both the real bedrock username {@link FloodgatePlayer#getUsername()} and the
|
||||
* edited username {@link FloodgatePlayer#getJavaUsername()} and returns true if one of the two
|
||||
* matches.
|
||||
*
|
||||
* @param player the player to check
|
||||
* @return true if the given player is the player requested
|
||||
|
||||
@@ -25,22 +25,20 @@
|
||||
|
||||
package org.geysermc.floodgate.api.link;
|
||||
|
||||
import org.geysermc.floodgate.util.LinkedPlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import org.geysermc.floodgate.util.LinkedPlayer;
|
||||
|
||||
/**
|
||||
* The base class of the PlayerLink database implementation.
|
||||
* The implementation is responsible for making a connection with the database
|
||||
* and keeping that connection alive so that Floodgate (or a third party plugin)
|
||||
* can check for example if a given player is linked.
|
||||
* The base class of the PlayerLink database implementation. The implementation is responsible for
|
||||
* making a connection with the database and keeping that connection alive so that Floodgate (or a
|
||||
* third party plugin) can check for example if a given player is linked.
|
||||
*/
|
||||
public interface PlayerLink {
|
||||
/**
|
||||
* Called by Floodgate after the initialization of the class.
|
||||
* In this method the implementation should start the connection with the database and
|
||||
* create the collections if they don't exist already.
|
||||
* Called by Floodgate after the initialization of the class. In this method the implementation
|
||||
* should start the connection with the database and create the collections if they don't exist
|
||||
* already.
|
||||
*/
|
||||
void load();
|
||||
|
||||
@@ -48,8 +46,8 @@ public interface PlayerLink {
|
||||
* Get a linked player by the bedrock uuid
|
||||
*
|
||||
* @param bedrockId the uuid of the bedrock player
|
||||
* @return a completable future with the {@link LinkedPlayer}.
|
||||
* The future will have a null value if that Bedrock player isn't linked
|
||||
* @return a completable future with the {@link LinkedPlayer}. The future will have a null value
|
||||
* if that Bedrock player isn't linked
|
||||
*/
|
||||
CompletableFuture<LinkedPlayer> getLinkedPlayer(UUID bedrockId);
|
||||
|
||||
@@ -80,10 +78,9 @@ public interface PlayerLink {
|
||||
CompletableFuture<Void> unlinkPlayer(UUID javaId);
|
||||
|
||||
/**
|
||||
* Return if account linking is enabled.
|
||||
* The difference between enabled and allowed is that 'enabled' still allows already linked
|
||||
* people to join with their linked account while 'allow linking' allows people to link
|
||||
* accounts using the commands.
|
||||
* Return if account linking is enabled. The difference between enabled and allowed is that
|
||||
* 'enabled' still allows already linked people to join with their linked account while 'allow
|
||||
* linking' allows people to link accounts using the commands.
|
||||
*/
|
||||
boolean isEnabled();
|
||||
|
||||
@@ -93,10 +90,9 @@ public interface PlayerLink {
|
||||
long getVerifyLinkTimeout();
|
||||
|
||||
/**
|
||||
* Return if account linking is allowed.
|
||||
* The difference between enabled and allowed is that 'enabled' still allows already linked
|
||||
* people to join with their linked account while 'allow linking' allows people to link
|
||||
* accounts using the commands.
|
||||
* Return if account linking is allowed. The difference between enabled and allowed is that
|
||||
* 'enabled' still allows already linked people to join with their linked account while 'allow
|
||||
* linking' allows people to link accounts using the commands.
|
||||
*/
|
||||
boolean isAllowLinking();
|
||||
|
||||
|
||||
@@ -61,6 +61,8 @@ public interface FloodgateLogger {
|
||||
*/
|
||||
void info(String message, Object... args);
|
||||
|
||||
void translatedInfo(String message, Object... args);
|
||||
|
||||
/**
|
||||
* Logs a debug message to the console, with 0 or more arguments.
|
||||
*
|
||||
@@ -83,9 +85,8 @@ public interface FloodgateLogger {
|
||||
void enableDebug();
|
||||
|
||||
/**
|
||||
* Disables debug mode for the Floodgate logger.
|
||||
* Debug messages can still be sent after running this method,
|
||||
* but they will be hidden from the console.
|
||||
* Disables debug mode for the Floodgate logger. Debug messages can still be sent after running
|
||||
* this method, but they will be hidden from the console.
|
||||
*/
|
||||
void disableDebug();
|
||||
}
|
||||
|
||||
@@ -25,35 +25,36 @@
|
||||
|
||||
package org.geysermc.floodgate.api.player;
|
||||
|
||||
import org.geysermc.floodgate.util.*;
|
||||
|
||||
import java.util.UUID;
|
||||
import org.geysermc.floodgate.util.DeviceOs;
|
||||
import org.geysermc.floodgate.util.InputMode;
|
||||
import org.geysermc.floodgate.util.LinkedPlayer;
|
||||
import org.geysermc.floodgate.util.RawSkin;
|
||||
import org.geysermc.floodgate.util.UiProfile;
|
||||
|
||||
public interface FloodgatePlayer {
|
||||
/**
|
||||
* Returns the Bedrock username that will be used as username on the server.
|
||||
* This includes replace spaces (if enabled), username shortened and prefix appended.<br>
|
||||
* Note that this field is not used when the player is a {@link LinkedPlayer LinkedPlayer}
|
||||
* Returns the Bedrock username that will be used as username on the server. This includes
|
||||
* replace spaces (if enabled), username shortened and prefix appended.<br> Note that this field
|
||||
* is not used when the player is a {@link LinkedPlayer LinkedPlayer}
|
||||
*/
|
||||
String getJavaUsername();
|
||||
|
||||
/**
|
||||
* Returns the uuid that will be used as UUID on the server.<br>
|
||||
* Note that this field is not used when the player is a {@link LinkedPlayer LinkedPlayer}
|
||||
* Returns the uuid that will be used as UUID on the server.<br> Note that this field is not
|
||||
* used when the player is a {@link LinkedPlayer LinkedPlayer}
|
||||
*/
|
||||
UUID getJavaUniqueId();
|
||||
|
||||
/**
|
||||
* Returns the uuid that the server will use as uuid of that player.
|
||||
* Will return {@link #getJavaUniqueId()} when not linked or
|
||||
* {@link LinkedPlayer#getJavaUniqueId()} when linked.
|
||||
* Returns the uuid that the server will use as uuid of that player. Will return {@link
|
||||
* #getJavaUniqueId()} when not linked or {@link LinkedPlayer#getJavaUniqueId()} when linked.
|
||||
*/
|
||||
UUID getCorrectUniqueId();
|
||||
|
||||
/**
|
||||
* Returns the username the server will as username for that player.
|
||||
* Will return {@link #getJavaUsername()} when not linked or
|
||||
* {@link LinkedPlayer#getJavaUsername()} when linked.
|
||||
* Returns the username the server will as username for that player. Will return {@link
|
||||
* #getJavaUsername()} when not linked or {@link LinkedPlayer#getJavaUsername()} when linked.
|
||||
*/
|
||||
String getCorrectUsername();
|
||||
|
||||
@@ -63,9 +64,8 @@ public interface FloodgatePlayer {
|
||||
String getVersion();
|
||||
|
||||
/**
|
||||
* Returns the real username of the Bedrock client.
|
||||
* This username doesn't have a prefix, spaces aren't replaced and the username hasn't been
|
||||
* shortened.
|
||||
* Returns the real username of the Bedrock client. This username doesn't have a prefix, spaces
|
||||
* aren't replaced and the username hasn't been shortened.
|
||||
*/
|
||||
String getUsername();
|
||||
|
||||
|
||||
@@ -2,47 +2,7 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>bungee</artifactId>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>bungeecord-repo</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
<version>${bungee.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-protocol</artifactId>
|
||||
<version>${bungee.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<version>3.27.0-GA</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
@@ -70,4 +30,44 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
<version>${bungee.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-protocol</artifactId>
|
||||
<version>${bungee.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<version>3.27.0-GA</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>bungeecord-repo</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
</project>
|
||||
@@ -28,7 +28,12 @@ package org.geysermc.floodgate;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
import org.geysermc.floodgate.module.*;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.module.BungeeAddonModule;
|
||||
import org.geysermc.floodgate.module.BungeeListenerModule;
|
||||
import org.geysermc.floodgate.module.BungeePlatformModule;
|
||||
import org.geysermc.floodgate.module.CommandModule;
|
||||
import org.geysermc.floodgate.module.CommonModule;
|
||||
import org.geysermc.floodgate.util.ReflectionUtils;
|
||||
|
||||
public final class BungeePlugin extends Plugin {
|
||||
@@ -49,10 +54,8 @@ public final class BungeePlugin extends Plugin {
|
||||
platform = injector.getInstance(FloodgatePlatform.class);
|
||||
|
||||
long endCtm = System.currentTimeMillis();
|
||||
getLogger().info(platform.getLanguageManager().getLogString(
|
||||
"floodgate.core.finish",
|
||||
endCtm - ctm
|
||||
));
|
||||
injector.getInstance(FloodgateLogger.class)
|
||||
.translatedInfo("floodgate.core.finish", endCtm - ctm);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
package org.geysermc.floodgate.command;
|
||||
|
||||
import java.util.Locale;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
@@ -35,8 +36,6 @@ import org.geysermc.floodgate.platform.command.CommandRegistration;
|
||||
import org.geysermc.floodgate.platform.command.CommandUtil;
|
||||
import org.geysermc.floodgate.util.LanguageManager;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class BungeeCommandRegistration implements CommandRegistration {
|
||||
private final BungeePlugin plugin;
|
||||
|
||||
@@ -25,10 +25,16 @@
|
||||
|
||||
package org.geysermc.floodgate.handler;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.geysermc.floodgate.HandshakeHandler.ResultType;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.name.Named;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.util.AttributeKey;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.event.PreLoginEvent;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
@@ -42,13 +48,6 @@ import org.geysermc.floodgate.config.ProxyFloodgateConfig;
|
||||
import org.geysermc.floodgate.util.BedrockData;
|
||||
import org.geysermc.floodgate.util.ReflectionUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.geysermc.floodgate.HandshakeHandler.ResultType;
|
||||
|
||||
public final class BungeeDataHandler {
|
||||
private static final Field EXTRA_HANDSHAKE_DATA;
|
||||
private static final Field PLAYER_NAME;
|
||||
@@ -57,31 +56,38 @@ public final class BungeeDataHandler {
|
||||
private static final Field PLAYER_REMOTE_ADDRESS;
|
||||
private static final Field CACHED_HANDSHAKE_PACKET;
|
||||
|
||||
@Inject
|
||||
private Plugin plugin;
|
||||
@Inject
|
||||
private ProxyFloodgateConfig config;
|
||||
@Inject
|
||||
private ProxyFloodgateApi api;
|
||||
@Inject
|
||||
private HandshakeHandler handler;
|
||||
static {
|
||||
Class<?> initialHandler = ReflectionUtils.getPrefixedClass("connection.InitialHandler");
|
||||
EXTRA_HANDSHAKE_DATA = ReflectionUtils.getField(initialHandler, "extraDataInHandshake");
|
||||
checkNotNull(EXTRA_HANDSHAKE_DATA, "extraDataInHandshake field cannot be null");
|
||||
|
||||
PLAYER_NAME = ReflectionUtils.getField(initialHandler, "name");
|
||||
checkNotNull(PLAYER_NAME, "Initial name field cannot be null");
|
||||
|
||||
Class<?> channelWrapper = ReflectionUtils.getPrefixedClass("netty.ChannelWrapper");
|
||||
PLAYER_CHANNEL_WRAPPER = ReflectionUtils.getFieldOfType(initialHandler, channelWrapper);
|
||||
checkNotNull(PLAYER_CHANNEL_WRAPPER, "ChannelWrapper field cannot be null");
|
||||
|
||||
PLAYER_CHANNEL = ReflectionUtils.getFieldOfType(channelWrapper, Channel.class);
|
||||
checkNotNull(PLAYER_CHANNEL, "Channel field cannot be null");
|
||||
|
||||
PLAYER_REMOTE_ADDRESS = ReflectionUtils.getFieldOfType(channelWrapper, SocketAddress.class);
|
||||
checkNotNull(PLAYER_REMOTE_ADDRESS, "Remote address field cannot be null");
|
||||
|
||||
Class<?> handshakePacket = ReflectionUtils.getPrefixedClass("protocol.packet.Handshake");
|
||||
CACHED_HANDSHAKE_PACKET = ReflectionUtils.getFieldOfType(initialHandler, handshakePacket);
|
||||
checkNotNull(CACHED_HANDSHAKE_PACKET, "Cached handshake packet field cannot be null");
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named("playerAttribute")
|
||||
private AttributeKey<FloodgatePlayer> playerAttribute;
|
||||
@Inject
|
||||
private FloodgateLogger logger;
|
||||
|
||||
public BungeeDataHandler(Plugin plugin, ProxyFloodgateConfig config,
|
||||
ProxyFloodgateApi api, HandshakeHandler handshakeHandler,
|
||||
AttributeKey<FloodgatePlayer> playerAttribute,
|
||||
FloodgateLogger logger) {
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
this.handler = handshakeHandler;
|
||||
this.api = api;
|
||||
this.playerAttribute = playerAttribute;
|
||||
this.logger = logger;
|
||||
}
|
||||
@Inject private Plugin plugin;
|
||||
@Inject private ProxyFloodgateConfig config;
|
||||
@Inject private ProxyFloodgateApi api;
|
||||
@Inject private HandshakeHandler handler;
|
||||
@Inject private FloodgateLogger logger;
|
||||
|
||||
public void handlePreLogin(PreLoginEvent event) {
|
||||
event.registerIntent(plugin);
|
||||
@@ -129,8 +135,8 @@ public final class BungeeDataHandler {
|
||||
channel.attr(playerAttribute).set(player);
|
||||
|
||||
if (!(remoteAddress instanceof InetSocketAddress)) {
|
||||
logger.info("Player {} doesn't use an InetSocketAddress. " +
|
||||
"It uses {}. Ignoring the player, I guess.",
|
||||
logger.info("Player {} doesn't use an InetSocketAddress, it uses {}. " +
|
||||
"Ignoring the player, I guess.",
|
||||
player.getUsername(), remoteAddress.getClass().getSimpleName()
|
||||
);
|
||||
} else {
|
||||
@@ -159,27 +165,4 @@ public final class BungeeDataHandler {
|
||||
// Bungeecord will add his data after our data
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
Class<?> initialHandler = ReflectionUtils.getPrefixedClass("connection.InitialHandler");
|
||||
EXTRA_HANDSHAKE_DATA = ReflectionUtils.getField(initialHandler, "extraDataInHandshake");
|
||||
checkNotNull(EXTRA_HANDSHAKE_DATA, "extraDataInHandshake field cannot be null");
|
||||
|
||||
PLAYER_NAME = ReflectionUtils.getField(initialHandler, "name");
|
||||
checkNotNull(PLAYER_NAME, "Initial name field cannot be null");
|
||||
|
||||
Class<?> channelWrapper = ReflectionUtils.getPrefixedClass("netty.ChannelWrapper");
|
||||
PLAYER_CHANNEL_WRAPPER = ReflectionUtils.getFieldOfType(initialHandler, channelWrapper);
|
||||
checkNotNull(PLAYER_CHANNEL_WRAPPER, "ChannelWrapper field cannot be null");
|
||||
|
||||
PLAYER_CHANNEL = ReflectionUtils.getFieldOfType(channelWrapper, Channel.class);
|
||||
checkNotNull(PLAYER_CHANNEL, "Channel field cannot be null");
|
||||
|
||||
PLAYER_REMOTE_ADDRESS = ReflectionUtils.getFieldOfType(channelWrapper, SocketAddress.class);
|
||||
checkNotNull(PLAYER_REMOTE_ADDRESS, "Remote address field cannot be null");
|
||||
|
||||
Class<?> handshakePacket = ReflectionUtils.getPrefixedClass("protocol.packet.Handshake");
|
||||
CACHED_HANDSHAKE_PACKET = ReflectionUtils.getFieldOfType(initialHandler, handshakePacket);
|
||||
checkNotNull(CACHED_HANDSHAKE_PACKET, "Cached handshake packet field cannot be null");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,21 +26,23 @@
|
||||
package org.geysermc.floodgate.inject.bungee;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import javassist.*;
|
||||
import java.util.function.Consumer;
|
||||
import javassist.ClassPool;
|
||||
import javassist.CtClass;
|
||||
import javassist.CtField;
|
||||
import javassist.CtMethod;
|
||||
import javassist.Modifier;
|
||||
import javax.naming.OperationNotSupportedException;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.inject.CommonPlatformInjector;
|
||||
import org.geysermc.floodgate.util.ReflectionUtils;
|
||||
|
||||
import javax.naming.OperationNotSupportedException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class BungeeInjector extends CommonPlatformInjector {
|
||||
private final FloodgateLogger logger;
|
||||
@Getter
|
||||
private boolean injected;
|
||||
@Getter private boolean injected;
|
||||
|
||||
@Override
|
||||
public boolean inject() {
|
||||
@@ -54,7 +56,8 @@ public final class BungeeInjector extends CommonPlatformInjector {
|
||||
|
||||
// create a new field that we can access
|
||||
CtField channelConsumerField = new CtField(
|
||||
classPool.get("java.util.function.Consumer"), "channelConsumer", handlerBossClass
|
||||
classPool.get("java.util.function.Consumer"), "channelConsumer",
|
||||
handlerBossClass
|
||||
);
|
||||
channelConsumerField.setModifiers(Modifier.PUBLIC | Modifier.STATIC);
|
||||
handlerBossClass.addField(channelConsumerField);
|
||||
@@ -62,7 +65,7 @@ public final class BungeeInjector extends CommonPlatformInjector {
|
||||
// edit a method to call the new field when we need it
|
||||
CtMethod channelActiveMethod = handlerBossClass.getMethod(
|
||||
"channelActive", "(Lio/netty/channel/ChannelHandlerContext;)V");
|
||||
channelActiveMethod.insertBefore("" +
|
||||
channelActiveMethod.insertBefore(
|
||||
"{if (handler != null) {channelConsumer.accept(ctx.channel());}}");
|
||||
|
||||
Class<?> clazz = handlerBossClass.toClass();
|
||||
|
||||
@@ -27,6 +27,7 @@ package org.geysermc.floodgate.listener;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import java.util.UUID;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.event.LoginEvent;
|
||||
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
|
||||
@@ -42,8 +43,6 @@ import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
import org.geysermc.floodgate.handler.BungeeDataHandler;
|
||||
import org.geysermc.floodgate.util.LanguageManager;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public final class BungeeListener implements Listener {
|
||||
private BungeeDataHandler dataHandler;
|
||||
@Inject private ProxyFloodgateApi api;
|
||||
@@ -80,8 +79,10 @@ public final class BungeeListener implements Listener {
|
||||
FloodgatePlayer player = api.getPlayer(uniqueId);
|
||||
if (player != null) {
|
||||
player.as(FloodgatePlayerImpl.class).setLogin(false);
|
||||
logger.info(languageManager.getLogString("floodgate.ingame.login_name",
|
||||
player.getCorrectUsername(), player.getCorrectUniqueId()));
|
||||
logger.translatedInfo(
|
||||
"floodgate.ingame.login_name",
|
||||
player.getCorrectUsername(), uniqueId
|
||||
);
|
||||
languageManager.loadLocale(player.getLanguageCode());
|
||||
}
|
||||
}
|
||||
@@ -98,9 +99,7 @@ public final class BungeeListener implements Listener {
|
||||
ProxiedPlayer player = event.getPlayer();
|
||||
if (api.removePlayer(player.getUniqueId()) != null) {
|
||||
api.removeEncryptedData(player.getUniqueId());
|
||||
logger.info(languageManager.getLogString(
|
||||
"floodgate.ingame.disconnect_name", player.getName())
|
||||
);
|
||||
logger.translatedInfo("floodgate.ingame.disconnect_name", player.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,8 +80,8 @@ public final class BungeePlatformModule extends AbstractModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public FloodgateLogger floodgateLogger() {
|
||||
return new JavaUtilFloodgateLogger(plugin.getLogger());
|
||||
public FloodgateLogger floodgateLogger(LanguageManager languageManager) {
|
||||
return new JavaUtilFloodgateLogger(plugin.getLogger(), languageManager);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
102
common/pom.xml
102
common/pom.xml
@@ -2,37 +2,28 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>common</artifactId>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>nukkitx-release-repo</id>
|
||||
<url>https://repo.nukkitx.com/maven-releases/</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>nukkitx-snapshot-repo</id>
|
||||
<url>https://repo.nukkitx.com/maven-snapshots/</url>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<finalName>${outputName}</finalName>
|
||||
<shadedArtifactAttached>true</shadedArtifactAttached>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
@@ -64,25 +55,34 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<finalName>${outputName}</finalName>
|
||||
<shadedArtifactAttached>true</shadedArtifactAttached>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>nukkitx-release-repo</id>
|
||||
<url>https://repo.nukkitx.com/maven-releases/</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>nukkitx-snapshot-repo</id>
|
||||
<url>https://repo.nukkitx.com/maven-snapshots/</url>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
</project>
|
||||
@@ -29,8 +29,9 @@ import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.name.Named;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.UUID;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
import org.geysermc.floodgate.api.InstanceHolder;
|
||||
import org.geysermc.floodgate.api.inject.PlatformInjector;
|
||||
@@ -43,35 +44,30 @@ import org.geysermc.floodgate.module.ConfigLoadedModule;
|
||||
import org.geysermc.floodgate.module.PostInitializeModule;
|
||||
import org.geysermc.floodgate.util.LanguageManager;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.UUID;
|
||||
|
||||
public class FloodgatePlatform {
|
||||
private static final UUID KEY = UUID.randomUUID();
|
||||
|
||||
private final FloodgateConfig config;
|
||||
private final FloodgateApi api;
|
||||
private final LanguageManager languageManager;
|
||||
private final PlatformInjector injector;
|
||||
|
||||
private final FloodgateLogger logger;
|
||||
|
||||
@Getter(AccessLevel.PROTECTED)
|
||||
private final LanguageManager languageManager;
|
||||
|
||||
private final Injector guice;
|
||||
private FloodgateConfig config;
|
||||
private Injector guice;
|
||||
|
||||
@Inject
|
||||
private PlatformInjector injector;
|
||||
|
||||
@Inject
|
||||
public FloodgatePlatform(@Named("dataDirectory") Path dataDirectory, FloodgateApi api,
|
||||
ConfigLoader configLoader, PlayerLinkLoader playerLinkLoader,
|
||||
HandshakeHandler handshakeHandler, FloodgateLogger logger,
|
||||
PlatformInjector platformInjector, LanguageManager languageManager,
|
||||
Injector injector) {
|
||||
public FloodgatePlatform(FloodgateApi api, LanguageManager languageManager,
|
||||
PlatformInjector platformInjector, FloodgateLogger logger) {
|
||||
this.api = api;
|
||||
this.logger = logger;
|
||||
this.languageManager = languageManager;
|
||||
this.injector = platformInjector;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void init(@Named("dataDirectory") Path dataDirectory, ConfigLoader configLoader,
|
||||
PlayerLinkLoader playerLinkLoader, HandshakeHandler handshakeHandler,
|
||||
Injector injector) {
|
||||
|
||||
if (!Files.isDirectory(dataDirectory)) {
|
||||
try {
|
||||
@@ -96,7 +92,7 @@ public class FloodgatePlatform {
|
||||
|
||||
PlayerLink link = playerLinkLoader.load();
|
||||
|
||||
InstanceHolder.setInstance(api, link, platformInjector, KEY);
|
||||
InstanceHolder.setInstance(api, link, this.injector, KEY);
|
||||
}
|
||||
|
||||
public boolean enable(Module... postInitializeModules) {
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
|
||||
package org.geysermc.floodgate;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
@@ -32,11 +35,12 @@ import org.geysermc.floodgate.api.InstanceHolder;
|
||||
import org.geysermc.floodgate.api.ProxyFloodgateApi;
|
||||
import org.geysermc.floodgate.api.link.PlayerLink;
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
import org.geysermc.floodgate.util.*;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import org.geysermc.floodgate.util.BedrockData;
|
||||
import org.geysermc.floodgate.util.DeviceOs;
|
||||
import org.geysermc.floodgate.util.InputMode;
|
||||
import org.geysermc.floodgate.util.LinkedPlayer;
|
||||
import org.geysermc.floodgate.util.RawSkin;
|
||||
import org.geysermc.floodgate.util.UiProfile;
|
||||
|
||||
@Getter
|
||||
public final class FloodgatePlayerImpl implements FloodgatePlayer {
|
||||
@@ -57,8 +61,7 @@ public final class FloodgatePlayerImpl implements FloodgatePlayer {
|
||||
/**
|
||||
* Returns true if the player is still logging in
|
||||
*/
|
||||
@Setter
|
||||
private boolean login = true;
|
||||
@Setter private boolean login = true;
|
||||
|
||||
FloodgatePlayerImpl(BedrockData data, RawSkin skin, String prefix, boolean replaceSpaces) {
|
||||
FloodgateApi api = FloodgateApi.getInstance();
|
||||
@@ -130,8 +133,8 @@ public final class FloodgatePlayerImpl implements FloodgatePlayer {
|
||||
/**
|
||||
* Fetch and return the LinkedPlayer object associated to the player if the player is linked.
|
||||
*
|
||||
* @return a future holding the LinkedPlayer or null if the player isn't linked or when
|
||||
* linking isn't enabled
|
||||
* @return a future holding the LinkedPlayer or null if the player isn't linked or when linking
|
||||
* isn't enabled
|
||||
* @see #fetchLinkedPlayer(PlayerLink) for the sync version
|
||||
*/
|
||||
public CompletableFuture<LinkedPlayer> fetchLinkedPlayerAsync(PlayerLink link) {
|
||||
|
||||
@@ -25,9 +25,15 @@
|
||||
|
||||
package org.geysermc.floodgate;
|
||||
|
||||
import static org.geysermc.floodgate.util.BedrockData.EXPECTED_LENGTH;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.inject.Inject;
|
||||
import lombok.*;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.api.SimpleFloodgateApi;
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||
@@ -37,8 +43,6 @@ import org.geysermc.floodgate.util.BedrockData;
|
||||
import org.geysermc.floodgate.util.InvalidFormatException;
|
||||
import org.geysermc.floodgate.util.RawSkin;
|
||||
|
||||
import static org.geysermc.floodgate.util.BedrockData.EXPECTED_LENGTH;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class HandshakeHandler {
|
||||
private final SimpleFloodgateApi api;
|
||||
@@ -122,19 +126,6 @@ public final class HandshakeHandler {
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
@Getter
|
||||
public static class HandshakeResult {
|
||||
private final ResultType resultType;
|
||||
private final String[] handshakeData;
|
||||
private final BedrockData bedrockData;
|
||||
private final FloodgatePlayer floodgatePlayer;
|
||||
|
||||
public boolean isBungeeData() {
|
||||
return handshakeData.length == 4 || handshakeData.length == 5;
|
||||
}
|
||||
}
|
||||
|
||||
public enum ResultType {
|
||||
EXCEPTION,
|
||||
NOT_FLOODGATE_DATA,
|
||||
@@ -148,4 +139,17 @@ public final class HandshakeHandler {
|
||||
cachedResult = new HandshakeResult(this, null, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
@Getter
|
||||
public static class HandshakeResult {
|
||||
private final ResultType resultType;
|
||||
private final String[] handshakeData;
|
||||
private final BedrockData bedrockData;
|
||||
private final FloodgatePlayer floodgatePlayer;
|
||||
|
||||
public boolean isBungeeData() {
|
||||
return handshakeData.length == 4 || handshakeData.length == 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ public final class AddonManagerAddon implements InjectorAddon {
|
||||
@Inject private CommonPlatformInjector injector;
|
||||
|
||||
@Override
|
||||
public void onInject(Channel channel, boolean proxyToServer) {
|
||||
public void onInject(Channel channel, boolean toServer) {
|
||||
channel.pipeline().addLast("floodgate_addon", new AddonManagerHandler(injector, channel));
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ package org.geysermc.floodgate.addon;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.name.Named;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import org.geysermc.floodgate.addon.debug.ChannelInDebugHandler;
|
||||
import org.geysermc.floodgate.addon.debug.ChannelOutDebugHandler;
|
||||
import org.geysermc.floodgate.api.inject.InjectorAddon;
|
||||
@@ -51,13 +52,13 @@ public final class DebugAddon implements InjectorAddon {
|
||||
private String packetDecoder;
|
||||
|
||||
@Override
|
||||
public void onInject(Channel channel, boolean proxyToServer) {
|
||||
public void onInject(Channel channel, boolean toServer) {
|
||||
channel.pipeline().addBefore(
|
||||
packetEncoder, "floodgate_debug_out",
|
||||
new ChannelOutDebugHandler(implementationName, !proxyToServer, logger)
|
||||
new ChannelOutDebugHandler(implementationName, toServer, logger)
|
||||
).addBefore(
|
||||
packetDecoder, "floodgate_debug_in",
|
||||
new ChannelInDebugHandler(logger, implementationName, !proxyToServer)
|
||||
new ChannelInDebugHandler(implementationName, toServer, logger)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -68,8 +69,10 @@ public final class DebugAddon implements InjectorAddon {
|
||||
|
||||
@Override
|
||||
public void onRemoveInject(Channel channel) {
|
||||
channel.pipeline().remove("floodgate_debug_out");
|
||||
channel.pipeline().remove("floodgate_debug_in");
|
||||
ChannelPipeline pipeline = channel.pipeline();
|
||||
|
||||
pipeline.remove("floodgate_debug_out");
|
||||
pipeline.remove("floodgate_debug_in");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -35,17 +35,21 @@ public final class ChannelInDebugHandler extends SimpleChannelInboundHandler<Byt
|
||||
private final String message;
|
||||
private final FloodgateLogger logger;
|
||||
|
||||
public ChannelInDebugHandler(FloodgateLogger logger, String implementationType,
|
||||
boolean player) {
|
||||
public ChannelInDebugHandler(String implementationType, boolean toServer,
|
||||
FloodgateLogger logger) {
|
||||
this.message = (toServer ? "Server ->" : "Player ->") + ' ' + implementationType;
|
||||
this.logger = logger;
|
||||
this.message = (player ? "Player ->" : "Server ->") + ' ' + implementationType;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) {
|
||||
int index = msg.readerIndex();
|
||||
|
||||
logger.info("{}:\n{}", message, ByteBufUtil.prettyHexDump(msg));
|
||||
|
||||
// reset index
|
||||
msg.readerIndex(index);
|
||||
|
||||
ctx.fireChannelRead(msg.retain());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,18 +35,21 @@ public final class ChannelOutDebugHandler extends MessageToByteEncoder<ByteBuf>
|
||||
private final String direction;
|
||||
private final FloodgateLogger logger;
|
||||
|
||||
public ChannelOutDebugHandler(String implementationType, boolean player,
|
||||
public ChannelOutDebugHandler(String implementationType, boolean toServer,
|
||||
FloodgateLogger logger) {
|
||||
this.direction = implementationType + (player ? " -> Player" : " -> Server");
|
||||
this.direction = implementationType + (toServer ? " -> Server" : " -> Player");
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) {
|
||||
int index = msg.readerIndex();
|
||||
|
||||
logger.info("{}:\n{}", direction, ByteBufUtil.prettyHexDump(msg));
|
||||
|
||||
// reset index
|
||||
msg.readerIndex(index);
|
||||
|
||||
out.writeBytes(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,15 +25,13 @@
|
||||
|
||||
package org.geysermc.floodgate.api;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.crypto.FloodgateCipher;
|
||||
import org.geysermc.floodgate.util.BedrockData;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.crypto.FloodgateCipher;
|
||||
import org.geysermc.floodgate.util.BedrockData;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class ProxyFloodgateApi extends SimpleFloodgateApi {
|
||||
@@ -55,9 +53,6 @@ public final class ProxyFloodgateApi extends SimpleFloodgateApi {
|
||||
public void updateEncryptedData(UUID uuid, BedrockData bedrockData) {
|
||||
try {
|
||||
byte[] encryptedData = cipher.encryptFromString(bedrockData.toString());
|
||||
encryptedData = Base64.getEncoder().encode(encryptedData);
|
||||
//todo maybe bake Base64 support into it?
|
||||
|
||||
addEncryptedData(uuid, new String(encryptedData, StandardCharsets.UTF_8));
|
||||
} catch (Exception exception) {
|
||||
throw new IllegalStateException("We failed to update the BedrockData, " +
|
||||
|
||||
@@ -25,14 +25,13 @@
|
||||
|
||||
package org.geysermc.floodgate.api;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.FloodgatePlayerImpl;
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.FloodgatePlayerImpl;
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class SimpleFloodgateApi implements FloodgateApi {
|
||||
@@ -84,29 +83,34 @@ public class SimpleFloodgateApi implements FloodgateApi {
|
||||
*/
|
||||
@Nullable
|
||||
public FloodgatePlayer removePlayer(UUID onlineId, boolean removeLogin) {
|
||||
FloodgatePlayer player = players.get(onlineId);
|
||||
FloodgatePlayer selfPlayer = players.get(onlineId);
|
||||
// the player is a non-linked player or a linked player but somehow someone tried to
|
||||
// remove the player by his xuid, we have to find out
|
||||
if (player != null) {
|
||||
if (selfPlayer != null) {
|
||||
// we don't allow them to remove a player by his xuid
|
||||
// because a linked player is never registered by his linked java uuid
|
||||
if (player.getLinkedPlayer() != null) return null;
|
||||
if (selfPlayer.getLinkedPlayer() != null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// removeLogin logic
|
||||
if (!shouldRemove(player, removeLogin)) return null;
|
||||
if (!shouldRemove(selfPlayer, removeLogin)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// passed the test
|
||||
players.remove(onlineId);
|
||||
// was the account linked?
|
||||
return player;
|
||||
return selfPlayer;
|
||||
}
|
||||
|
||||
// we still want to be able to remove a linked-player by his linked java uuid
|
||||
for (FloodgatePlayer player1 : players.values()) {
|
||||
if (!shouldRemove(player1, removeLogin)) continue;
|
||||
if (!player1.getCorrectUniqueId().equals(onlineId)) continue;
|
||||
players.remove(player1.getJavaUniqueId());
|
||||
return player1;
|
||||
for (FloodgatePlayer player : players.values()) {
|
||||
if (shouldRemove(player, removeLogin) && player.getCorrectUniqueId().equals(onlineId)) {
|
||||
continue;
|
||||
}
|
||||
players.remove(player.getJavaUniqueId());
|
||||
return player;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -125,8 +129,8 @@ public class SimpleFloodgateApi implements FloodgateApi {
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent of {@link #removePlayer(UUID, boolean)} except that it removes a
|
||||
* FloodgatePlayer instance directly.
|
||||
* Equivalent of {@link #removePlayer(UUID, boolean)} except that it removes a FloodgatePlayer
|
||||
* instance directly.
|
||||
*/
|
||||
public boolean removePlayer(FloodgatePlayer player) {
|
||||
boolean removed = players.remove(player.getJavaUniqueId(), player);
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
package org.geysermc.floodgate.command;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
@@ -36,11 +40,6 @@ import org.geysermc.floodgate.platform.command.Command;
|
||||
import org.geysermc.floodgate.platform.command.CommandMessage;
|
||||
import org.geysermc.floodgate.platform.command.CommandUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
@NoArgsConstructor
|
||||
public final class LinkAccountCommand implements Command {
|
||||
private final Map<String, LinkRequest> activeLinkRequests = new HashMap<>();
|
||||
@@ -56,7 +55,8 @@ public final class LinkAccountCommand implements Command {
|
||||
return;
|
||||
}
|
||||
|
||||
link.isLinkedPlayer(uuid).whenComplete((linked, throwable) -> {
|
||||
link.isLinkedPlayer(uuid)
|
||||
.whenComplete((linked, throwable) -> {
|
||||
if (throwable != null) {
|
||||
sendMessage(player, locale, CommonCommandMessage.IS_LINKED_ERROR);
|
||||
return;
|
||||
@@ -116,7 +116,7 @@ public final class LinkAccountCommand implements Command {
|
||||
}
|
||||
|
||||
link.linkPlayer(uuid, request.getJavaUniqueId(), request.getJavaUsername())
|
||||
.whenComplete((aVoid, error) -> {
|
||||
.whenComplete((unused, error) -> {
|
||||
if (error != null) {
|
||||
sendMessage(player, locale, Message.LINK_REQUEST_ERROR);
|
||||
return;
|
||||
@@ -161,8 +161,7 @@ public final class LinkAccountCommand implements Command {
|
||||
NO_LINK_REQUESTED("floodgate.command.link_account.no_link_requested"),
|
||||
LINK_REQUEST_DISABLED("floodgate.commands.linking_disabled");
|
||||
|
||||
@Getter
|
||||
private final String message;
|
||||
@Getter private final String message;
|
||||
|
||||
Message(String message) {
|
||||
this.message = message;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
package org.geysermc.floodgate.command;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.UUID;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
@@ -34,8 +35,6 @@ import org.geysermc.floodgate.platform.command.Command;
|
||||
import org.geysermc.floodgate.platform.command.CommandMessage;
|
||||
import org.geysermc.floodgate.platform.command.CommandUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@NoArgsConstructor
|
||||
public final class UnlinkAccountCommand implements Command {
|
||||
@Inject private FloodgateApi api;
|
||||
@@ -49,8 +48,9 @@ public final class UnlinkAccountCommand implements Command {
|
||||
return;
|
||||
}
|
||||
|
||||
link.isLinkedPlayer(uuid).whenComplete((linked, throwable) -> {
|
||||
if (throwable != null) {
|
||||
link.isLinkedPlayer(uuid)
|
||||
.whenComplete((linked, error) -> {
|
||||
if (error != null) {
|
||||
sendMessage(player, locale, CommonCommandMessage.IS_LINKED_ERROR);
|
||||
return;
|
||||
}
|
||||
@@ -60,13 +60,15 @@ public final class UnlinkAccountCommand implements Command {
|
||||
return;
|
||||
}
|
||||
|
||||
link.unlinkPlayer(uuid).whenComplete((aVoid, throwable1) ->
|
||||
sendMessage(player, locale,
|
||||
throwable1 == null ?
|
||||
Message.UNLINK_SUCCESS :
|
||||
Message.UNLINK_ERROR
|
||||
)
|
||||
);
|
||||
link.unlinkPlayer(uuid)
|
||||
.whenComplete((unused, error1) -> {
|
||||
if (error1 != null) {
|
||||
sendMessage(player, locale, Message.UNLINK_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
sendMessage(player, locale, Message.UNLINK_SUCCESS);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -96,8 +98,7 @@ public final class UnlinkAccountCommand implements Command {
|
||||
UNLINK_ERROR("floodgate.command.unlink_account.error"),
|
||||
LINKING_NOT_ENABLED("floodgate.commands.linking_disabled");
|
||||
|
||||
@Getter
|
||||
private final String message;
|
||||
@Getter private final String message;
|
||||
|
||||
Message(String message) {
|
||||
this.message = message;
|
||||
|
||||
@@ -27,14 +27,12 @@ package org.geysermc.floodgate.config;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.security.Key;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.security.Key;
|
||||
|
||||
/**
|
||||
* The global Floodgate configuration file used in every platform.
|
||||
* Some platforms have their own addition to the global configuration like
|
||||
* {@link ProxyFloodgateConfig} for the proxies.
|
||||
* The global Floodgate configuration file used in every platform. Some platforms have their own
|
||||
* addition to the global configuration like {@link ProxyFloodgateConfig} for the proxies.
|
||||
*/
|
||||
@Getter
|
||||
public class FloodgateConfig {
|
||||
@@ -63,6 +61,16 @@ public class FloodgateConfig {
|
||||
@JsonIgnore
|
||||
private Key key = null;
|
||||
|
||||
public void setKey(Key key) {
|
||||
if (this.key == null) {
|
||||
this.key = key;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isProxy() {
|
||||
return this instanceof ProxyFloodgateConfig;
|
||||
}
|
||||
|
||||
@Getter
|
||||
public static class DisconnectMessages {
|
||||
@JsonProperty("invalid-key")
|
||||
@@ -84,14 +92,4 @@ public class FloodgateConfig {
|
||||
@JsonProperty("auto-download")
|
||||
private boolean autoDownload;
|
||||
}
|
||||
|
||||
public void setKey(Key key) {
|
||||
if (this.key == null) {
|
||||
this.key = key;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isProxy() {
|
||||
return this instanceof ProxyFloodgateConfig;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import lombok.Getter;
|
||||
* The Floodgate configuration used by proxy platforms, currently Velocity and Bungeecord.
|
||||
*/
|
||||
public final class ProxyFloodgateConfig extends FloodgateConfig {
|
||||
@Getter
|
||||
@JsonProperty(value = "send-floodgate-data")
|
||||
@Getter private boolean sendFloodgateData;
|
||||
private boolean sendFloodgateData;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,12 @@ package org.geysermc.floodgate.config.loader;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.Key;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||
@@ -35,16 +41,8 @@ import org.geysermc.floodgate.config.updater.ConfigUpdater;
|
||||
import org.geysermc.floodgate.crypto.FloodgateCipher;
|
||||
import org.geysermc.floodgate.crypto.KeyProducer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.Key;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class ConfigLoader {
|
||||
public final class ConfigLoader {
|
||||
private final Path dataFolder;
|
||||
private final Class<? extends FloodgateConfig> configClass;
|
||||
private final ConfigUpdater updater;
|
||||
@@ -116,14 +114,16 @@ public class ConfigLoader {
|
||||
updater.update(defaultConfigPath);
|
||||
}
|
||||
|
||||
configInstance = (T) new ObjectMapper(new YAMLFactory())
|
||||
FloodgateConfig config =
|
||||
new ObjectMapper(new YAMLFactory())
|
||||
.readValue(Files.readAllBytes(configPath), configClass);
|
||||
} catch (ClassCastException exception) {
|
||||
logger.error("Provided class {} cannot be cast to the required return type",
|
||||
configClass.getName());
|
||||
|
||||
throw new RuntimeException("Failed to load cast the config! " +
|
||||
"Try to contact the platform developer");
|
||||
try {
|
||||
configInstance = (T) config;
|
||||
} catch (ClassCastException exception) {
|
||||
logger.error("Failed to cast config file to required class.", exception);
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
logger.error("Error while loading config", exception);
|
||||
throw new RuntimeException("Failed to load the config! Try to delete the config file");
|
||||
|
||||
@@ -26,27 +26,25 @@
|
||||
package org.geysermc.floodgate.config.updater;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
|
||||
public class ConfigFileUpdater {
|
||||
@Inject
|
||||
private FloodgateLogger logger;
|
||||
public final class ConfigFileUpdater {
|
||||
@Inject private FloodgateLogger logger;
|
||||
|
||||
/**
|
||||
* Simple config file updater.
|
||||
* Please note that all the keys should be unique and that this system wasn't made for complex
|
||||
* configurations.
|
||||
* Simple config file updater. Please note that all the keys should be unique and that this
|
||||
* system wasn't made for complex configurations.
|
||||
*
|
||||
* @param configLocation the location of the Floodgate config
|
||||
* @param currentVersion the key value map of the current config
|
||||
* @param renames name changes introduced in this version. new (key) to old (value)
|
||||
* @param renames name changes introduced in this version. new (key) to old
|
||||
* (value)
|
||||
* @param defaultConfigLocation the location of the default Floodgate config
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
@@ -59,7 +57,9 @@ public class ConfigFileUpdater {
|
||||
for (int i = 0; i < newConfig.size(); i++) {
|
||||
line = newConfig.get(i);
|
||||
// we don't have to check comments
|
||||
if (line.startsWith("#")) continue;
|
||||
if (line.startsWith("#")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int splitIndex = line.indexOf(':');
|
||||
// if the line has a 'key: value' structure
|
||||
@@ -69,11 +69,7 @@ public class ConfigFileUpdater {
|
||||
Object value;
|
||||
|
||||
logger.info(name);
|
||||
if (renames.containsKey(name)) {
|
||||
value = currentVersion.get(renames.get(name));
|
||||
} else {
|
||||
value = currentVersion.get(name);
|
||||
}
|
||||
value = currentVersion.get(renames.getOrDefault(name, name));
|
||||
|
||||
if (value == null) {
|
||||
notFound.add(name);
|
||||
@@ -102,9 +98,7 @@ public class ConfigFileUpdater {
|
||||
if (notFound.size() > 0) {
|
||||
StringBuilder messageBuilder = new StringBuilder(
|
||||
"Please note that the following keys we not found in the old config and " +
|
||||
"are now using the default Floodgate config value. " +
|
||||
"Missing/new keys: "
|
||||
);
|
||||
"are now using the default Floodgate config value. Missing/new keys: ");
|
||||
|
||||
boolean first = true;
|
||||
for (String value : notFound) {
|
||||
|
||||
@@ -25,9 +25,8 @@
|
||||
|
||||
package org.geysermc.floodgate.config.updater;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static org.geysermc.floodgate.util.MessageFormatter.format;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
@@ -35,17 +34,17 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class ConfigUpdater {
|
||||
public final class ConfigUpdater {
|
||||
private static final int CONFIG_VERSION = 1;
|
||||
private final Path dataFolder;
|
||||
private final ConfigFileUpdater fileUpdater;
|
||||
private final FloodgateLogger logger;
|
||||
|
||||
private static final int CONFIG_VERSION = 1;
|
||||
|
||||
public void update(Path defaultConfigLocation) {
|
||||
Path configLocation = dataFolder.resolve("config.yml");
|
||||
|
||||
@@ -72,8 +71,8 @@ public class ConfigUpdater {
|
||||
int version = (int) versionElement;
|
||||
checkArgument(
|
||||
version == CONFIG_VERSION,
|
||||
"Config is newer then possible on this version! Expected " + CONFIG_VERSION + ", got " + version
|
||||
);
|
||||
format("Config is newer then possible on this version! Expected {}, got {}",
|
||||
CONFIG_VERSION, version));
|
||||
|
||||
// config is already up-to-date
|
||||
if (version == CONFIG_VERSION) {
|
||||
|
||||
@@ -26,13 +26,12 @@
|
||||
package org.geysermc.floodgate.inject;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import org.geysermc.floodgate.api.inject.InjectorAddon;
|
||||
import org.geysermc.floodgate.api.inject.PlatformInjector;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.geysermc.floodgate.api.inject.InjectorAddon;
|
||||
import org.geysermc.floodgate.api.inject.PlatformInjector;
|
||||
|
||||
public abstract class CommonPlatformInjector implements PlatformInjector {
|
||||
private final Set<Channel> injectedClients = new HashSet<>();
|
||||
@@ -58,13 +57,12 @@ public abstract class CommonPlatformInjector implements PlatformInjector {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to loop through all the addons and call
|
||||
* {@link InjectorAddon#onInject(Channel, boolean)} if
|
||||
* {@link InjectorAddon#shouldInject()}.
|
||||
* Method to loop through all the addons and call {@link InjectorAddon#onInject(Channel,
|
||||
* boolean)} if {@link InjectorAddon#shouldInject()}.
|
||||
*
|
||||
* @param channel the channel to inject
|
||||
* @param proxyToServer true if the proxy is connecting to a server or false when the player
|
||||
* is connecting to the proxy or false when the platform isn't a proxy
|
||||
* @param proxyToServer true if the proxy is connecting to a server or false when the player is
|
||||
* connecting to the proxy or false when the platform isn't a proxy
|
||||
*/
|
||||
public void injectAddonsCall(Channel channel, boolean proxyToServer) {
|
||||
for (InjectorAddon addon : addons.values()) {
|
||||
@@ -75,8 +73,7 @@ public abstract class CommonPlatformInjector implements PlatformInjector {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to loop through all the addons and call
|
||||
* {@link InjectorAddon#onLoginDone(Channel)} if
|
||||
* Method to loop through all the addons and call {@link InjectorAddon#onLoginDone(Channel)} if
|
||||
* {@link InjectorAddon#shouldInject()}.
|
||||
*
|
||||
* @param channel the channel that was injected
|
||||
@@ -90,9 +87,8 @@ public abstract class CommonPlatformInjector implements PlatformInjector {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to loop through all the addons and call
|
||||
* {@link InjectorAddon#onRemoveInject(Channel)} if
|
||||
* {@link InjectorAddon#shouldInject()}.
|
||||
* Method to loop through all the addons and call {@link InjectorAddon#onRemoveInject(Channel)}
|
||||
* if {@link InjectorAddon#shouldInject()}.
|
||||
*
|
||||
* @param channel the channel that was injected
|
||||
*/
|
||||
|
||||
@@ -26,24 +26,24 @@
|
||||
package org.geysermc.floodgate.link;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.floodgate.api.link.PlayerLink;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public abstract class CommonPlayerLink implements PlayerLink {
|
||||
@Getter(AccessLevel.PROTECTED)
|
||||
private final ExecutorService executorService = Executors.newFixedThreadPool(11);
|
||||
|
||||
@Getter private boolean enabled;
|
||||
@Getter private boolean allowLinking;
|
||||
@Getter private long verifyLinkTimeout;
|
||||
|
||||
@Inject
|
||||
@Getter(AccessLevel.PROTECTED)
|
||||
private final ExecutorService executorService = Executors.newFixedThreadPool(11);
|
||||
|
||||
@Inject @Getter(AccessLevel.PROTECTED)
|
||||
private FloodgateLogger logger;
|
||||
|
||||
@Inject
|
||||
|
||||
@@ -25,17 +25,16 @@
|
||||
|
||||
package org.geysermc.floodgate.link;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
import org.geysermc.floodgate.api.link.PlayerLink;
|
||||
import org.geysermc.floodgate.util.LinkedPlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Simple class used when PlayerLinking is disabled.
|
||||
* This class has been made because Floodgate doesn't have a default PlayerLink implementation
|
||||
* anymore and {@link FloodgateApi#getPlayerLink()} returning null} is also not an option.
|
||||
* Simple class used when PlayerLinking is disabled. This class has been made because Floodgate
|
||||
* doesn't have a default PlayerLink implementation anymore and {@link FloodgateApi#getPlayerLink()}
|
||||
* returning null} is also not an option.
|
||||
*/
|
||||
final class DisabledPlayerLink implements PlayerLink {
|
||||
@Override
|
||||
|
||||
@@ -25,11 +25,10 @@
|
||||
|
||||
package org.geysermc.floodgate.link;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.geysermc.floodgate.api.link.LinkRequest;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.floodgate.api.link.LinkRequest;
|
||||
|
||||
@Getter
|
||||
public final class LinkRequestImpl implements LinkRequest {
|
||||
|
||||
@@ -25,15 +25,13 @@
|
||||
|
||||
package org.geysermc.floodgate.link;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.name.Named;
|
||||
import org.geysermc.floodgate.api.link.PlayerLink;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
@@ -43,17 +41,19 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import org.geysermc.floodgate.api.link.PlayerLink;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public class PlayerLinkLoader {
|
||||
@Named("dataDirectory")
|
||||
@Inject private Path dataDirectory;
|
||||
public final class PlayerLinkLoader {
|
||||
@Inject private Injector injector;
|
||||
@Inject private FloodgateConfig config;
|
||||
|
||||
@Inject private FloodgateLogger logger;
|
||||
|
||||
@Inject
|
||||
@Named("dataDirectory")
|
||||
private Path dataDirectory;
|
||||
|
||||
public PlayerLink load() {
|
||||
FloodgateConfig.PlayerLinkConfig linkConfig = config.getPlayerLink();
|
||||
if (!linkConfig.isEnabled()) {
|
||||
|
||||
@@ -25,17 +25,18 @@
|
||||
|
||||
package org.geysermc.floodgate.logger;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import static org.geysermc.floodgate.util.MessageFormatter.format;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.geysermc.floodgate.util.MessageFormatter.format;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.util.LanguageManager;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class JavaUtilFloodgateLogger implements FloodgateLogger {
|
||||
private final Logger logger;
|
||||
private final LanguageManager languageManager;
|
||||
private Level originLevel = null;
|
||||
|
||||
@Override
|
||||
@@ -58,6 +59,11 @@ public final class JavaUtilFloodgateLogger implements FloodgateLogger {
|
||||
logger.info(format(message, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translatedInfo(String message, Object... args) {
|
||||
logger.info(languageManager.getLogString(message, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String message, Object... args) {
|
||||
logger.fine(format(message, args));
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.google.inject.Provides;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.name.Named;
|
||||
import io.netty.util.AttributeKey;
|
||||
import java.nio.file.Path;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.HandshakeHandler;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
@@ -41,13 +42,15 @@ import org.geysermc.floodgate.config.FloodgateConfig;
|
||||
import org.geysermc.floodgate.config.loader.ConfigLoader;
|
||||
import org.geysermc.floodgate.config.updater.ConfigFileUpdater;
|
||||
import org.geysermc.floodgate.config.updater.ConfigUpdater;
|
||||
import org.geysermc.floodgate.crypto.*;
|
||||
import org.geysermc.floodgate.crypto.AesCipher;
|
||||
import org.geysermc.floodgate.crypto.AesKeyProducer;
|
||||
import org.geysermc.floodgate.crypto.Base64Topping;
|
||||
import org.geysermc.floodgate.crypto.FloodgateCipher;
|
||||
import org.geysermc.floodgate.crypto.KeyProducer;
|
||||
import org.geysermc.floodgate.inject.CommonPlatformInjector;
|
||||
import org.geysermc.floodgate.link.PlayerLinkLoader;
|
||||
import org.geysermc.floodgate.util.LanguageManager;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class CommonModule extends AbstractModule {
|
||||
private final Path dataDirectory;
|
||||
@@ -79,9 +82,11 @@ public final class CommonModule extends AbstractModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public ConfigLoader configLoader(@Named("configClass") Class<? extends FloodgateConfig> configClass,
|
||||
public ConfigLoader configLoader(
|
||||
@Named("configClass") Class<? extends FloodgateConfig> configClass,
|
||||
ConfigUpdater configUpdater, KeyProducer producer,
|
||||
FloodgateCipher cipher, FloodgateLogger logger) {
|
||||
|
||||
return new ConfigLoader(
|
||||
dataDirectory, configClass, configUpdater, producer, cipher, logger
|
||||
);
|
||||
|
||||
@@ -32,11 +32,11 @@ import java.util.UUID;
|
||||
*/
|
||||
public interface Command {
|
||||
/**
|
||||
* Should be implemented when {@link #isRequirePlayer()} is true
|
||||
* or when the source is a player.
|
||||
* Should be implemented when {@link #isRequirePlayer()} is true or when the source is a
|
||||
* player.
|
||||
*
|
||||
* @param player the player instance (used for example in combination with
|
||||
* {@link CommandUtil#kickPlayer(Object, String, CommandMessage, Object...)}
|
||||
* @param player the player instance (used for example in combination with {@link
|
||||
* CommandUtil#kickPlayer(Object, String, CommandMessage, Object...)}
|
||||
* @param uuid the uuid of the player
|
||||
* @param username the username of the player
|
||||
* @param locale the locale of the player
|
||||
@@ -69,16 +69,16 @@ public interface Command {
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* The permission that is required to execute the specific command.
|
||||
* Should return null when there is no permission required.
|
||||
* The permission that is required to execute the specific command. Should return null when
|
||||
* there is no permission required.
|
||||
*
|
||||
* @return the permission required to execute the command
|
||||
*/
|
||||
String getPermission();
|
||||
|
||||
/**
|
||||
* If the Command requires a Player to execute this command
|
||||
* or if it doesn't matter if (for example) the console executes the command.
|
||||
* If the Command requires a Player to execute this command or if it doesn't matter if (for
|
||||
* example) the console executes the command.
|
||||
*
|
||||
* @return true if this command can only be executed by a player
|
||||
*/
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
package org.geysermc.floodgate.platform.command;
|
||||
|
||||
/**
|
||||
* CommandMessage is the interface of a message that can be send to a command source after
|
||||
* executing a command. Messages are generally implemented using enums.
|
||||
* CommandMessage is the interface of a message that can be send to a command source after executing
|
||||
* a command. Messages are generally implemented using enums.
|
||||
*/
|
||||
public interface CommandMessage {
|
||||
/**
|
||||
|
||||
@@ -26,10 +26,9 @@
|
||||
package org.geysermc.floodgate.platform.command;
|
||||
|
||||
/**
|
||||
* This class is responsible for registering commands to the command register of the platform
|
||||
* that is currently in use. So that the commands only have to be written once
|
||||
* (in the common module) and can be used across all platforms without the need of adding platform
|
||||
* specific commands.
|
||||
* This class is responsible for registering commands to the command register of the platform that
|
||||
* is currently in use. So that the commands only have to be written once (in the common module) and
|
||||
* can be used across all platforms without the need of adding platform specific commands.
|
||||
*/
|
||||
public interface CommandRegistration {
|
||||
/**
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
package org.geysermc.floodgate.platform.command;
|
||||
|
||||
/**
|
||||
* An interface used across all Floodgate platforms to simple stuff in commands like kicking
|
||||
* players and sending player messages independent of the Floodgate platform implementation.
|
||||
* An interface used across all Floodgate platforms to simple stuff in commands like kicking players
|
||||
* and sending player messages independent of the Floodgate platform implementation.
|
||||
*/
|
||||
public interface CommandUtil {
|
||||
/**
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
package org.geysermc.floodgate.platform.listener;
|
||||
|
||||
/**
|
||||
* This class is responsible for registering listeners to the listener manager of the platform
|
||||
* that is currently in use. Unfortunately due to the major differences between the platforms
|
||||
* (when it comes to listeners) every Floodgate platform has to implement their own listeners.
|
||||
* This class is responsible for registering listeners to the listener manager of the platform that
|
||||
* is currently in use. Unfortunately due to the major differences between the platforms (when it
|
||||
* comes to listeners) every Floodgate platform has to implement their own listeners.
|
||||
*
|
||||
* @param <T> the platform-specific listener class
|
||||
*/
|
||||
|
||||
@@ -27,11 +27,10 @@ package org.geysermc.floodgate.register;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import java.util.Set;
|
||||
import org.geysermc.floodgate.api.inject.InjectorAddon;
|
||||
import org.geysermc.floodgate.api.inject.PlatformInjector;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public final class AddonRegister {
|
||||
@Inject private Injector guice;
|
||||
@Inject private PlatformInjector injector;
|
||||
|
||||
@@ -27,12 +27,11 @@ package org.geysermc.floodgate.register;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import java.util.Set;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.platform.command.Command;
|
||||
import org.geysermc.floodgate.platform.command.CommandRegistration;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Inject))
|
||||
public final class CommandRegister {
|
||||
private final CommandRegistration registration;
|
||||
|
||||
@@ -27,11 +27,10 @@ package org.geysermc.floodgate.register;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import java.util.Set;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.platform.listener.ListenerRegistration;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Inject))
|
||||
public final class ListenerRegister<T> {
|
||||
private final ListenerRegistration<T> registration;
|
||||
|
||||
@@ -26,25 +26,25 @@
|
||||
package org.geysermc.floodgate.util;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||
|
||||
/**
|
||||
* Manages translations for strings in Floodgate
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class LanguageManager {
|
||||
public final class LanguageManager {
|
||||
private final Map<String, Properties> LOCALE_MAPPINGS = new HashMap<>();
|
||||
|
||||
private final FloodgateLogger logger;
|
||||
@@ -52,8 +52,22 @@ public class LanguageManager {
|
||||
/**
|
||||
* The locale used in console and as a fallback
|
||||
*/
|
||||
@Getter
|
||||
private String defaultLocale;
|
||||
@Getter private String defaultLocale;
|
||||
|
||||
/**
|
||||
* Cleans up and formats a locale string
|
||||
*
|
||||
* @param locale the locale to format
|
||||
* @return the formatted locale
|
||||
*/
|
||||
private static String formatLocale(String locale) {
|
||||
try {
|
||||
String[] parts = locale.toLowerCase().split("_");
|
||||
return parts[0] + "_" + parts[1].toUpperCase();
|
||||
} catch (Exception e) {
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the log's locale file once Floodgate loads the config
|
||||
@@ -72,8 +86,7 @@ public class LanguageManager {
|
||||
}
|
||||
|
||||
String systemLocale = formatLocale(
|
||||
Locale.getDefault().getLanguage() + "_" +
|
||||
Locale.getDefault().getCountry()
|
||||
Locale.getDefault().getLanguage() + "_" + Locale.getDefault().getCountry()
|
||||
);
|
||||
|
||||
if (isValidLanguage(systemLocale)) {
|
||||
@@ -88,7 +101,7 @@ public class LanguageManager {
|
||||
/**
|
||||
* Loads a Floodgate locale from resources; if the file doesn't exist it just logs a warning
|
||||
*
|
||||
* @param locale Locale to load
|
||||
* @param locale locale to load
|
||||
*/
|
||||
public void loadLocale(String locale) {
|
||||
locale = formatLocale(locale);
|
||||
@@ -120,9 +133,9 @@ public class LanguageManager {
|
||||
/**
|
||||
* Get a formatted language string with the default locale for Floodgate
|
||||
*
|
||||
* @param key Language string to translate
|
||||
* @param values Values to put into the string
|
||||
* @return Translated string or the original message if it was not found in the given locale
|
||||
* @param key language string to translate
|
||||
* @param values values to put into the string
|
||||
* @return translated string or the original message if it was not found in the given locale
|
||||
*/
|
||||
public String getLogString(String key, Object... values) {
|
||||
return getString(key, defaultLocale, values);
|
||||
@@ -131,10 +144,10 @@ public class LanguageManager {
|
||||
/**
|
||||
* Get a formatted language string with the given locale for Floodgate
|
||||
*
|
||||
* @param key Language string to translate
|
||||
* @param locale Locale to translate to
|
||||
* @param values Values to put into the string
|
||||
* @return Translated string or the original message if it was not found in the given locale
|
||||
* @param key language string to translate
|
||||
* @param locale locale to translate to
|
||||
* @param values values to put into the string
|
||||
* @return translated string or the original message if it was not found in the given locale
|
||||
*/
|
||||
public String getString(String key, String locale, Object... values) {
|
||||
locale = formatLocale(locale);
|
||||
@@ -162,23 +175,9 @@ public class LanguageManager {
|
||||
return MessageFormat.format(formatString.replace("'", "''").replace("&", "\u00a7"), values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up and formats a locale string
|
||||
*
|
||||
* @param locale The locale to format
|
||||
* @return The formatted locale
|
||||
*/
|
||||
private static String formatLocale(String locale) {
|
||||
try {
|
||||
String[] parts = locale.toLowerCase().split("_");
|
||||
return parts[0] + "_" + parts[1].toUpperCase();
|
||||
} catch (Exception e) {
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the given locale is supported by Floodgate
|
||||
*
|
||||
* @param locale the locale to validate
|
||||
* @return true if the given locale is supported by Floodgate
|
||||
*/
|
||||
@@ -187,7 +186,10 @@ public class LanguageManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LanguageManager.class.getResource("/languages/texts/" + locale + ".properties") == null) {
|
||||
URL languageFile = LanguageManager.class
|
||||
.getResource("/languages/texts/" + locale + ".properties");
|
||||
|
||||
if (languageFile == null) {
|
||||
logger.warn(locale + " is not a supported Floodgate language.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,9 @@ public final class MessageFormatter {
|
||||
|
||||
public static String format(String message, Object... arguments) {
|
||||
// simple variant of slf4j's parameters.
|
||||
if (arguments == null || arguments.length == 0) return message;
|
||||
if (arguments == null || arguments.length == 0) {
|
||||
return message;
|
||||
}
|
||||
|
||||
String[] args = new String[arguments.length];
|
||||
for (int i = 0; i < arguments.length; i++) {
|
||||
@@ -49,30 +51,36 @@ public final class MessageFormatter {
|
||||
if (currentIndex == -1) {
|
||||
// no parameter places left in message,
|
||||
// we'll ignore the remaining parameters and return the message
|
||||
if (previousIndex == -1) return message;
|
||||
else {
|
||||
if (previousIndex == -1) {
|
||||
return message;
|
||||
} else {
|
||||
stringBuilder.append(message.substring(previousIndex));
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
if (previousIndex == -1) stringBuilder.append(message, 0, currentIndex);
|
||||
else stringBuilder.append(message, previousIndex, currentIndex);
|
||||
if (previousIndex == -1) {
|
||||
stringBuilder.append(message, 0, currentIndex);
|
||||
} else {
|
||||
stringBuilder.append(message, previousIndex, currentIndex);
|
||||
}
|
||||
stringBuilder.append(argument);
|
||||
|
||||
// we finished this argument, so we're past the current delimiter
|
||||
previousIndex = currentIndex + DELIM_LENGTH;
|
||||
}
|
||||
|
||||
if (previousIndex != message.length())
|
||||
if (previousIndex != message.length()) {
|
||||
stringBuilder.append(message, previousIndex, message.length());
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
public static int getArgsContentLength(String... args) {
|
||||
int length = 0;
|
||||
for (String arg : args)
|
||||
for (String arg : args) {
|
||||
length += arg.length();
|
||||
}
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,30 +25,69 @@
|
||||
|
||||
package org.geysermc.floodgate.util;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.reflect.*;
|
||||
|
||||
import static org.geysermc.floodgate.util.MessageFormatter.format;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.Setter;
|
||||
|
||||
public final class ReflectionUtils {
|
||||
private static final Field MODIFIERS_FIELD;
|
||||
|
||||
/**
|
||||
* The package name that is shared between all the {@link #getPrefixedClass(String)} calls so
|
||||
* that the className will be a lot shorter.
|
||||
* Example net.minecraft.server.v1_8R3.PacketHandshakingInSetProtocol will become
|
||||
* PacketHandshakingInSetProtocol if the prefix is set to net.minecraft.server.v1_8R3
|
||||
* that the className will be a lot shorter. Example net.minecraft.server.v1_8R3.PacketHandshakingInSetProtocol
|
||||
* will become PacketHandshakingInSetProtocol if the prefix is set to
|
||||
* net.minecraft.server.v1_8R3
|
||||
*/
|
||||
@Setter
|
||||
private static String prefix = null;
|
||||
@Setter private static String prefix = null;
|
||||
|
||||
static {
|
||||
Field modifiersField = null;
|
||||
try {
|
||||
modifiersField = Field.class.getDeclaredField("modifiers");
|
||||
} catch (NoSuchFieldException ignored) {
|
||||
// Java 12 compatibility, thanks to https://github.com/powermock/powermock/pull/1010
|
||||
try {
|
||||
Method declaredFields = getMethod(Class.class, "getDeclaredFields0", boolean.class);
|
||||
if (declaredFields == null) {
|
||||
throw new NoSuchMethodException();
|
||||
}
|
||||
|
||||
Field[] fields = castedInvoke(Field.class, declaredFields, false);
|
||||
if (fields == null) {
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
for (Field field : fields) {
|
||||
if ("modifiers".equals(field.getName())) {
|
||||
modifiersField = field;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
throw new RuntimeException(format(
|
||||
"Cannot find the modifiers field :/\nJava version: {}\nVendor: {} ({})",
|
||||
System.getProperty("java.version"),
|
||||
System.getProperty("java.vendor"),
|
||||
System.getProperty("java.vendor.url")
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Preconditions.checkNotNull(modifiersField, "Modifiers field cannot be null!");
|
||||
MODIFIERS_FIELD = modifiersField;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a class that is prefixed with the prefix provided in {@link #setPrefix(String)}.
|
||||
* Calling this method is equal to calling {@link #getClass(String)}
|
||||
* with <i>prefix</i>.<i>classname</i> as class name.
|
||||
* Get a class that is prefixed with the prefix provided in {@link #setPrefix(String)}. Calling
|
||||
* this method is equal to calling {@link #getClass(String)} with <i>prefix</i>.<i>classname</i>
|
||||
* as class name.
|
||||
*
|
||||
* @param className the prefix class to find
|
||||
* @return the class if found, otherwise null
|
||||
@@ -59,11 +98,10 @@ public final class ReflectionUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class from a class name.
|
||||
* Calling this method is equal to calling {@link Class#forName(String)} where String is the
|
||||
* class name.<br>
|
||||
* This method will return null when the class isn't found instead of throwing the exception,
|
||||
* but the exception will be printed to the console.
|
||||
* Get the class from a class name. Calling this method is equal to calling {@link
|
||||
* Class#forName(String)} where String is the class name.<br> This method will return null when
|
||||
* the class isn't found instead of throwing the exception, but the exception will be printed to
|
||||
* the console.
|
||||
*
|
||||
* @param className the name of the class to find
|
||||
* @return the class or null if the class wasn't found.
|
||||
@@ -79,12 +117,11 @@ public final class ReflectionUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a field of a class.
|
||||
* Calling this method is equal to calling {@link Class#getField(String)} where String is the
|
||||
* fieldName when isPublic is true and calling this method is equal to calling
|
||||
* {@link Class#getDeclaredField(String)} where String is the fieldName when isPublic is
|
||||
* false.<br>
|
||||
* Please note that this method will return null instead of throwing the exception.
|
||||
* Get a field of a class. Calling this method is equal to calling {@link
|
||||
* Class#getField(String)} where String is the fieldName when isPublic is true and calling this
|
||||
* method is equal to calling {@link Class#getDeclaredField(String)} where String is the
|
||||
* fieldName when isPublic is false.<br> Please note that this method will return null instead
|
||||
* of throwing the exception.
|
||||
*
|
||||
* @param clazz the class name to get the field from
|
||||
* @param fieldName the name of the field
|
||||
@@ -104,9 +141,8 @@ public final class ReflectionUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a field from a class, it doesn't matter if the field is public or not.
|
||||
* This method will first try to get a declared field and if that failed it'll try to get a
|
||||
* public field.
|
||||
* Get a field from a class, it doesn't matter if the field is public or not. This method will
|
||||
* first try to get a declared field and if that failed it'll try to get a public field.
|
||||
*
|
||||
* @param clazz the class to get the field from
|
||||
* @param fieldName the name of the field
|
||||
@@ -134,15 +170,17 @@ public final class ReflectionUtils {
|
||||
Field[] fields = declared ? clazz.getDeclaredFields() : clazz.getFields();
|
||||
for (Field field : fields) {
|
||||
makeAccessible(field);
|
||||
if (field.getType() == fieldType) return field;
|
||||
if (field.getType() == fieldType) {
|
||||
return field;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a declared field from a class without having to provide a field name.<br>
|
||||
* Calling this method is equal to calling {@link #getFieldOfType(Class, Class, boolean)}
|
||||
* with declared = true.
|
||||
* Get a declared field from a class without having to provide a field name.<br> Calling this
|
||||
* method is equal to calling {@link #getFieldOfType(Class, Class, boolean)} with declared =
|
||||
* true.
|
||||
*
|
||||
* @param clazz the class to search the field from
|
||||
* @param fieldType the type of the declared field
|
||||
@@ -154,10 +192,9 @@ public final class ReflectionUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of a field.
|
||||
* This method first makes the field accessible and then gets the value.<br>
|
||||
* This method will return null instead of throwing an exception,
|
||||
* but it'll log the stacktrace to the console.
|
||||
* Get the value of a field. This method first makes the field accessible and then gets the
|
||||
* value.<br> This method will return null instead of throwing an exception, but it'll log the
|
||||
* stacktrace to the console.
|
||||
*
|
||||
* @param instance the instance to get the value from
|
||||
* @param field the field to get the value from
|
||||
@@ -201,8 +238,7 @@ public final class ReflectionUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of a field.
|
||||
* This method make the field accessible and then sets the value.<br>
|
||||
* Set the value of a field. This method make the field accessible and then sets the value.<br>
|
||||
* This method doesn't throw an exception when failed, but it'll log the error to the console.
|
||||
*
|
||||
* @param instance the instance to set the value to
|
||||
@@ -219,8 +255,8 @@ public final class ReflectionUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of a field.
|
||||
* This method finds the field, and then calls {@link #setValue(Object, Field, Object)}.
|
||||
* Set the value of a field. This method finds the field, and then calls {@link
|
||||
* #setValue(Object, Field, Object)}.
|
||||
*
|
||||
* @param instance the instance to set the value to
|
||||
* @param fieldName the field to set the value to
|
||||
@@ -236,10 +272,9 @@ public final class ReflectionUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of a <b>final</b> field.
|
||||
* This method first makes the field accessible, then removes the final modifier and then
|
||||
* sets the value.<br>
|
||||
* This method will not throw exceptions when failed, but it'll log the error to the console.
|
||||
* Set the value of a <b>final</b> field. This method first makes the field accessible, then
|
||||
* removes the final modifier and then sets the value.<br> This method will not throw exceptions
|
||||
* when failed, but it'll log the error to the console.
|
||||
*
|
||||
* @param instance the instance to set the value to
|
||||
* @param field the field to set the value to
|
||||
@@ -264,11 +299,10 @@ public final class ReflectionUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a method from a class, it doesn't matter if the field is public or not.
|
||||
* This method will first try to get a declared field and if that failed it'll try to get a
|
||||
* public field.<br>
|
||||
* Instead of throwing an exception when the method wasn't found, it will return null, but
|
||||
* the exception will be printed in the console.
|
||||
* Get a method from a class, it doesn't matter if the field is public or not. This method will
|
||||
* first try to get a declared field and if that failed it'll try to get a public field.<br>
|
||||
* Instead of throwing an exception when the method wasn't found, it will return null, but the
|
||||
* exception will be printed in the console.
|
||||
*
|
||||
* @param clazz the class to get the method from
|
||||
* @param method the name of the method to find
|
||||
@@ -290,9 +324,8 @@ public final class ReflectionUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a method from a class, it doesn't matter if the method is public or not.
|
||||
* This method will first try to get a declared method and if that fails it'll try to get a
|
||||
* public method.
|
||||
* Get a method from a class, it doesn't matter if the method is public or not. This method will
|
||||
* first try to get a declared method and if that fails it'll try to get a public method.
|
||||
*
|
||||
* @param clazz the class to get the method from
|
||||
* @param methodName the name of the method to find
|
||||
@@ -309,9 +342,8 @@ public final class ReflectionUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a method from a class, it doesn't matter if the method is public or not.
|
||||
* This method will first try to get a declared method and if that fails it'll try to get a
|
||||
* public method.
|
||||
* Get a method from a class, it doesn't matter if the method is public or not. This method will
|
||||
* first try to get a declared method and if that fails it'll try to get a public method.
|
||||
*
|
||||
* @param instance the class to get the method from
|
||||
* @param methodName the name of the method to find
|
||||
@@ -402,41 +434,4 @@ public final class ReflectionUtils {
|
||||
}
|
||||
return accessibleObject;
|
||||
}
|
||||
|
||||
static {
|
||||
Field modifiersField = null;
|
||||
try {
|
||||
modifiersField = Field.class.getDeclaredField("modifiers");
|
||||
} catch (NoSuchFieldException ignored) {
|
||||
// Java 12 compatibility, thanks to https://github.com/powermock/powermock/pull/1010
|
||||
try {
|
||||
Method declaredFields = getMethod(Class.class, "getDeclaredFields0", boolean.class);
|
||||
if (declaredFields == null) {
|
||||
throw new NoSuchMethodException();
|
||||
}
|
||||
|
||||
Field[] fields = castedInvoke(Field.class, declaredFields, false);
|
||||
if (fields == null) {
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
for (Field field : fields) {
|
||||
if ("modifiers".equals(field.getName())) {
|
||||
modifiersField = field;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
throw new RuntimeException(format("Cannot find the modifiers field :/\n" +
|
||||
"Java version: {}\nVendor: {} ({})",
|
||||
System.getProperty("java.version"),
|
||||
System.getProperty("java.vendor"),
|
||||
System.getProperty("java.vendor.url")
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Preconditions.checkNotNull(modifiersField, "Modifiers field cannot be null!");
|
||||
MODIFIERS_FIELD = modifiersField;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,51 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
|
||||
~
|
||||
~ 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.
|
||||
~
|
||||
~ @author GeyserMC
|
||||
~ @link https://github.com/GeyserMC/Floodgate
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>org.geysermc.floodgate.database</groupId>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<modules>
|
||||
<module>sqlite</module>
|
||||
</modules>
|
||||
<name>database</name>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.geysermc.floodgate.database</groupId>
|
||||
<artifactId>parent</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<name>database</name>
|
||||
|
||||
<modules>
|
||||
<module>sqlite</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<outputName>floodgate-${project.name}-database</outputName>
|
||||
</properties>
|
||||
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</project>
|
||||
@@ -1,62 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
|
||||
~
|
||||
~ 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.
|
||||
~
|
||||
~ @author GeyserMC
|
||||
~ @link https://github.com/GeyserMC/Floodgate
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>org.geysermc.floodgate.database</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>sqlite</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.30.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.12</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
@@ -84,4 +30,33 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.30.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.12</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>org.geysermc.floodgate.database</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
</project>
|
||||
@@ -27,14 +27,18 @@ package org.geysermc.floodgate.database;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.name.Named;
|
||||
import org.geysermc.floodgate.link.CommonPlayerLink;
|
||||
import org.geysermc.floodgate.util.LinkedPlayer;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.sql.*;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import org.geysermc.floodgate.link.CommonPlayerLink;
|
||||
import org.geysermc.floodgate.util.LinkedPlayer;
|
||||
|
||||
public class SqliteDatabase extends CommonPlayerLink {
|
||||
private Connection connection;
|
||||
@@ -51,7 +55,9 @@ public class SqliteDatabase extends CommonPlayerLink {
|
||||
connection = DriverManager.getConnection("jdbc:sqlite:" + databasePath.toString());
|
||||
Statement statement = connection.createStatement();
|
||||
statement.setQueryTimeout(30); // set timeout to 30 sec.
|
||||
statement.executeUpdate("create table if not exists LinkedPlayers (bedrockId string, javaUniqueId string, javaUsername string)");
|
||||
statement.executeUpdate(
|
||||
"create table if not exists LinkedPlayers (bedrockId string, javaUniqueId string, javaUsername string)"
|
||||
);
|
||||
} catch (ClassNotFoundException exception) {
|
||||
getLogger().error("The required class to load the SQLite database wasn't found");
|
||||
} catch (SQLException exception) {
|
||||
@@ -73,10 +79,14 @@ public class SqliteDatabase extends CommonPlayerLink {
|
||||
public CompletableFuture<LinkedPlayer> getLinkedPlayer(UUID bedrockId) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
PreparedStatement query = connection.prepareStatement("select * from LinkedPlayers where bedrockId = ?");
|
||||
PreparedStatement query = connection.prepareStatement(
|
||||
"select * from LinkedPlayers where bedrockId = ?"
|
||||
);
|
||||
query.setString(1, bedrockId.toString());
|
||||
ResultSet result = query.executeQuery();
|
||||
if (!result.next()) return null;
|
||||
if (!result.next()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String javaUsername = result.getString("javaUsername");
|
||||
UUID javaUniqueId = UUID.fromString(result.getString("javaUniqueId"));
|
||||
@@ -92,7 +102,9 @@ public class SqliteDatabase extends CommonPlayerLink {
|
||||
public CompletableFuture<Boolean> isLinkedPlayer(UUID bedrockId) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
PreparedStatement query = connection.prepareStatement("select javaUniqueId from LinkedPlayers where bedrockId = ? or javaUniqueId = ?");
|
||||
PreparedStatement query = connection.prepareStatement(
|
||||
"select javaUniqueId from LinkedPlayers where bedrockId = ? or javaUniqueId = ?"
|
||||
);
|
||||
query.setString(1, bedrockId.toString());
|
||||
query.setString(2, bedrockId.toString());
|
||||
ResultSet result = query.executeQuery();
|
||||
@@ -110,7 +122,9 @@ public class SqliteDatabase extends CommonPlayerLink {
|
||||
public CompletableFuture<Void> linkPlayer(UUID bedrockId, UUID javaId, String username) {
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
PreparedStatement query = connection.prepareStatement("insert into LinkedPlayers values(?, ?, ?)");
|
||||
PreparedStatement query = connection.prepareStatement(
|
||||
"insert into LinkedPlayers values(?, ?, ?)"
|
||||
);
|
||||
query.setString(1, bedrockId.toString());
|
||||
query.setString(2, javaId.toString());
|
||||
query.setString(3, username);
|
||||
@@ -126,7 +140,9 @@ public class SqliteDatabase extends CommonPlayerLink {
|
||||
public CompletableFuture<Void> unlinkPlayer(UUID javaId) {
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
PreparedStatement query = connection.prepareStatement("delete from LinkedPlayers where javaUniqueId = ? or bedrockId = ?");
|
||||
PreparedStatement query = connection.prepareStatement(
|
||||
"delete from LinkedPlayers where javaUniqueId = ? or bedrockId = ?"
|
||||
);
|
||||
query.setString(1, javaId.toString());
|
||||
query.setString(2, javaId.toString());
|
||||
query.executeUpdate();
|
||||
|
||||
64
pom.xml
64
pom.xml
@@ -2,11 +2,31 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<artifactId>parent</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.10</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<description>Allows Bedrock players to join Java edition servers while keeping the server in online mode</description>
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>releases</id>
|
||||
<name>nukkitx-releases</name>
|
||||
<url>https://repo.nukkitx.com/maven-releases</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>snapshots</id>
|
||||
<name>nukkitx-snapshots</name>
|
||||
<url>https://repo.nukkitx.com/maven-snapshots</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<modules>
|
||||
<module>api</module>
|
||||
<module>common</module>
|
||||
@@ -15,10 +35,13 @@
|
||||
<module>velocity</module>
|
||||
<module>database</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
<name>floodgate</name>
|
||||
<description>Allows Bedrock players to join Java edition servers while keeping online mode</description>
|
||||
<url>https://github.com/GeyserMC/Floodgate</url>
|
||||
<organization>
|
||||
<name>GeyserMC</name>
|
||||
<url>https://geysermc.org/</url>
|
||||
</organization>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<properties>
|
||||
<geyser.version>1.1.0</geyser.version>
|
||||
@@ -33,36 +56,13 @@
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<organization>
|
||||
<name>GeyserMC</name>
|
||||
<url>https://geysermc.org/</url>
|
||||
</organization>
|
||||
|
||||
<scm>
|
||||
<connection>scm:git:https://github.com/GeyserMC/Floodgate.git</connection>
|
||||
<developerConnection>scm:git:git@github.com:GeyserMC/Floodgate.git</developerConnection>
|
||||
<url>https://github.com/GeyserMC/Floodgate/</url>
|
||||
</scm>
|
||||
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>releases</id>
|
||||
<name>nukkitx-releases</name>
|
||||
<url>https://repo.nukkitx.com/maven-releases</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>snapshots</id>
|
||||
<name>nukkitx-snapshots</name>
|
||||
<url>https://repo.nukkitx.com/maven-snapshots</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
<url>https://github.com/GeyserMC/Floodgate</url>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.10</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</project>
|
||||
|
||||
@@ -2,48 +2,7 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<artifactId>parent</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spigot</artifactId>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>${spigot.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-transport</artifactId>
|
||||
<version>4.1.43.Final</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-codec</artifactId>
|
||||
<version>4.1.43.Final</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
@@ -71,4 +30,45 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>${spigot.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-transport</artifactId>
|
||||
<version>4.1.43.Final</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-codec</artifactId>
|
||||
<version>4.1.43.Final</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<artifactId>parent</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
</project>
|
||||
|
||||
@@ -26,31 +26,21 @@
|
||||
package org.geysermc.floodgate;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.name.Named;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
import org.geysermc.floodgate.api.inject.PlatformInjector;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.config.loader.ConfigLoader;
|
||||
import org.geysermc.floodgate.link.PlayerLinkLoader;
|
||||
import org.geysermc.floodgate.util.LanguageManager;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public final class SpigotPlatform extends FloodgatePlatform {
|
||||
@Inject private JavaPlugin plugin;
|
||||
|
||||
@Inject
|
||||
public SpigotPlatform(@Named("dataDirectory") Path dataDirectory, FloodgateApi api,
|
||||
ConfigLoader configLoader, PlayerLinkLoader playerLinkLoader,
|
||||
HandshakeHandler handshakeHandler, FloodgateLogger logger,
|
||||
PlatformInjector platformInjector, LanguageManager languageManager,
|
||||
Injector injector) {
|
||||
super(dataDirectory, api, configLoader, playerLinkLoader, handshakeHandler,
|
||||
logger, platformInjector, languageManager, injector);
|
||||
public SpigotPlatform(FloodgateApi api, LanguageManager languageManager,
|
||||
PlatformInjector platformInjector, FloodgateLogger logger) {
|
||||
super(api, languageManager, platformInjector, logger);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -28,7 +28,12 @@ package org.geysermc.floodgate;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.geysermc.floodgate.module.*;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.module.CommandModule;
|
||||
import org.geysermc.floodgate.module.CommonModule;
|
||||
import org.geysermc.floodgate.module.SpigotAddonModule;
|
||||
import org.geysermc.floodgate.module.SpigotListenerModule;
|
||||
import org.geysermc.floodgate.module.SpigotPlatformModule;
|
||||
import org.geysermc.floodgate.util.ReflectionUtils;
|
||||
|
||||
public final class SpigotPlugin extends JavaPlugin {
|
||||
@@ -48,10 +53,8 @@ public final class SpigotPlugin extends JavaPlugin {
|
||||
platform = injector.getInstance(SpigotPlatform.class);
|
||||
|
||||
long endCtm = System.currentTimeMillis();
|
||||
getLogger().info(platform.getLanguageManager().getLogString(
|
||||
"floodgate.core.finish",
|
||||
endCtm - ctm
|
||||
));
|
||||
injector.getInstance(FloodgateLogger.class)
|
||||
.translatedInfo("floodgate.core.finish", endCtm - ctm);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -40,14 +40,16 @@ public final class SpigotDataAddon implements InjectorAddon {
|
||||
@Inject private FloodgateConfig config;
|
||||
@Inject private FloodgateLogger logger;
|
||||
|
||||
@Inject @Named("playerAttribute")
|
||||
@Inject
|
||||
@Named("playerAttribute")
|
||||
private AttributeKey<FloodgatePlayer> playerAttribute;
|
||||
|
||||
@Inject @Named("packetHandler")
|
||||
@Inject
|
||||
@Named("packetHandler")
|
||||
private String packetHandlerName;
|
||||
|
||||
@Override
|
||||
public void onInject(Channel channel, boolean proxyToServer) {
|
||||
public void onInject(Channel channel, boolean toServer) {
|
||||
channel.pipeline().addBefore(
|
||||
packetHandlerName, "floodgate_data_handler",
|
||||
new SpigotDataHandler(config, handshakeHandler, playerAttribute, logger)
|
||||
|
||||
@@ -25,9 +25,23 @@
|
||||
|
||||
package org.geysermc.floodgate.addon.data;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.getCastedValue;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.getFieldOfType;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.getMethod;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.getPrefixedClass;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.makeAccessible;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.setValue;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.util.AttributeKey;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.UUID;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.HandshakeHandler;
|
||||
import org.geysermc.floodgate.HandshakeHandler.HandshakeResult;
|
||||
@@ -37,16 +51,6 @@ import org.geysermc.floodgate.config.FloodgateConfig;
|
||||
import org.geysermc.floodgate.util.BedrockData;
|
||||
import org.geysermc.floodgate.util.ReflectionUtils;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.*;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class SpigotDataHandler extends SimpleChannelInboundHandler<Object> {
|
||||
private static final Field SOCKET_ADDRESS;
|
||||
@@ -69,16 +73,89 @@ public final class SpigotDataHandler extends SimpleChannelInboundHandler<Object>
|
||||
private static final Field PROTOCOL_STATE;
|
||||
private static final Object READY_TO_ACCEPT_PROTOCOL_STATE;
|
||||
|
||||
static {
|
||||
Class<?> networkManager = getPrefixedClass("NetworkManager");
|
||||
checkNotNull(networkManager, "NetworkManager class cannot be null");
|
||||
|
||||
SOCKET_ADDRESS = getFieldOfType(networkManager, SocketAddress.class, false);
|
||||
checkNotNull(SOCKET_ADDRESS, "SocketAddress field cannot be null");
|
||||
|
||||
HANDSHAKE_PACKET = getPrefixedClass("PacketHandshakingInSetProtocol");
|
||||
checkNotNull(HANDSHAKE_PACKET, "PacketHandshakingInSetProtocol cannot be null");
|
||||
HANDSHAKE_HOST = getFieldOfType(HANDSHAKE_PACKET, String.class);
|
||||
checkNotNull(HANDSHAKE_HOST, "Host field from handshake packet cannot be null");
|
||||
|
||||
LOGIN_START_PACKET = getPrefixedClass("PacketLoginInStart");
|
||||
checkNotNull(LOGIN_START_PACKET, "PacketLoginInStart cannot be null");
|
||||
|
||||
GAME_PROFILE = ReflectionUtils.getClass("com.mojang.authlib.GameProfile");
|
||||
checkNotNull(GAME_PROFILE, "GameProfile class cannot be null");
|
||||
|
||||
Constructor<?> gameProfileConstructor = null;
|
||||
try {
|
||||
gameProfileConstructor = GAME_PROFILE.getConstructor(UUID.class, String.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
GAME_PROFILE_CONSTRUCTOR = gameProfileConstructor;
|
||||
checkNotNull(GAME_PROFILE_CONSTRUCTOR, "GameProfileConstructor cannot be null");
|
||||
|
||||
LOGIN_LISTENER = getPrefixedClass("LoginListener");
|
||||
checkNotNull(LOGIN_LISTENER, "LoginListener cannot be null");
|
||||
LOGIN_PROFILE = getFieldOfType(LOGIN_LISTENER, GAME_PROFILE);
|
||||
checkNotNull(LOGIN_PROFILE, "Profile from LoginListener cannot be null");
|
||||
INIT_UUID = getMethod(LOGIN_LISTENER, "initUUID");
|
||||
checkNotNull(INIT_UUID, "initUUID from LoginListener cannot be null");
|
||||
|
||||
Field protocolStateField = null;
|
||||
for (Field field : LOGIN_LISTENER.getDeclaredFields()) {
|
||||
if (field.getType().isEnum()) {
|
||||
protocolStateField = field;
|
||||
}
|
||||
}
|
||||
PROTOCOL_STATE = protocolStateField;
|
||||
checkNotNull(PROTOCOL_STATE, "Protocol state field from LoginListener cannot be null");
|
||||
|
||||
Enum<?>[] protocolStates = (Enum<?>[]) PROTOCOL_STATE.getType().getEnumConstants();
|
||||
Object readyToAcceptState = null;
|
||||
for (Enum<?> protocolState : protocolStates) {
|
||||
if (protocolState.name().equals("READY_TO_ACCEPT")) {
|
||||
readyToAcceptState = protocolState;
|
||||
}
|
||||
}
|
||||
READY_TO_ACCEPT_PROTOCOL_STATE = readyToAcceptState;
|
||||
checkNotNull(READY_TO_ACCEPT_PROTOCOL_STATE,
|
||||
"Ready to accept state from Protocol state cannot be null");
|
||||
|
||||
Class<?> packetListenerClass = getPrefixedClass("PacketListener");
|
||||
PACKET_LISTENER = getFieldOfType(networkManager, packetListenerClass);
|
||||
checkNotNull(PACKET_LISTENER, "PacketListener cannot be null");
|
||||
|
||||
LOGIN_HANDLER = getPrefixedClass("LoginListener$LoginHandler");
|
||||
checkNotNull(LOGIN_HANDLER, "LoginHandler cannot be null");
|
||||
|
||||
Constructor<?> loginHandlerConstructor = null;
|
||||
try {
|
||||
loginHandlerConstructor = makeAccessible(
|
||||
LOGIN_HANDLER.getDeclaredConstructor(LOGIN_LISTENER));
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
LOGIN_HANDLER_CONSTRUCTOR = loginHandlerConstructor;
|
||||
checkNotNull(LOGIN_HANDLER_CONSTRUCTOR, "LoginHandler constructor cannot be null");
|
||||
|
||||
FIRE_LOGIN_EVENTS = getMethod(LOGIN_HANDLER, "fireEvents");
|
||||
checkNotNull(FIRE_LOGIN_EVENTS, "fireEvents from LoginHandler cannot be null");
|
||||
}
|
||||
|
||||
/* per player stuff */
|
||||
private final FloodgateConfig config;
|
||||
private final HandshakeHandler handshakeHandler;
|
||||
private final AttributeKey<FloodgatePlayer> playerAttribute;
|
||||
private final FloodgateLogger logger;
|
||||
|
||||
private Object networkManager;
|
||||
private FloodgatePlayer fPlayer;
|
||||
private boolean bungee;
|
||||
|
||||
private boolean done;
|
||||
|
||||
@Override
|
||||
@@ -103,8 +180,10 @@ public final class SpigotDataHandler extends SimpleChannelInboundHandler<Object>
|
||||
break;
|
||||
case INVALID_DATA_LENGTH:
|
||||
int dataLength = result.getBedrockData().getDataLength();
|
||||
logger.info(config.getMessages().getInvalidArgumentsLength(),
|
||||
BedrockData.EXPECTED_LENGTH, dataLength);
|
||||
logger.info(
|
||||
config.getMessages().getInvalidArgumentsLength(),
|
||||
BedrockData.EXPECTED_LENGTH, dataLength
|
||||
);
|
||||
ctx.close();
|
||||
return;
|
||||
default: // only continue when SUCCESS
|
||||
@@ -182,78 +261,4 @@ public final class SpigotDataHandler extends SimpleChannelInboundHandler<Object>
|
||||
super.exceptionCaught(ctx, cause);
|
||||
cause.printStackTrace();
|
||||
}
|
||||
|
||||
static {
|
||||
Class<?> networkManager = getPrefixedClass("NetworkManager");
|
||||
checkNotNull(networkManager, "NetworkManager class cannot be null");
|
||||
|
||||
SOCKET_ADDRESS = getFieldOfType(networkManager, SocketAddress.class, false);
|
||||
checkNotNull(SOCKET_ADDRESS, "SocketAddress field cannot be null");
|
||||
|
||||
HANDSHAKE_PACKET = getPrefixedClass("PacketHandshakingInSetProtocol");
|
||||
checkNotNull(HANDSHAKE_PACKET, "PacketHandshakingInSetProtocol cannot be null");
|
||||
HANDSHAKE_HOST = getFieldOfType(HANDSHAKE_PACKET, String.class);
|
||||
checkNotNull(HANDSHAKE_HOST, "Host field from handshake packet cannot be null");
|
||||
|
||||
LOGIN_START_PACKET = getPrefixedClass("PacketLoginInStart");
|
||||
checkNotNull(LOGIN_START_PACKET, "PacketLoginInStart cannot be null");
|
||||
|
||||
GAME_PROFILE = ReflectionUtils.getClass("com.mojang.authlib.GameProfile");
|
||||
checkNotNull(GAME_PROFILE, "GameProfile class cannot be null");
|
||||
|
||||
Constructor<?> gameProfileConstructor = null;
|
||||
try {
|
||||
gameProfileConstructor = GAME_PROFILE.getConstructor(UUID.class, String.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
GAME_PROFILE_CONSTRUCTOR = gameProfileConstructor;
|
||||
checkNotNull(GAME_PROFILE_CONSTRUCTOR, "GameProfileConstructor cannot be null");
|
||||
|
||||
LOGIN_LISTENER = getPrefixedClass("LoginListener");
|
||||
checkNotNull(LOGIN_LISTENER, "LoginListener cannot be null");
|
||||
LOGIN_PROFILE = getFieldOfType(LOGIN_LISTENER, GAME_PROFILE);
|
||||
checkNotNull(LOGIN_PROFILE, "Profile from LoginListener cannot be null");
|
||||
INIT_UUID = getMethod(LOGIN_LISTENER, "initUUID");
|
||||
checkNotNull(INIT_UUID, "initUUID from LoginListener cannot be null");
|
||||
|
||||
Field protocolStateField = null;
|
||||
for (Field field : LOGIN_LISTENER.getDeclaredFields()) {
|
||||
if (field.getType().isEnum()) {
|
||||
protocolStateField = field;
|
||||
}
|
||||
}
|
||||
PROTOCOL_STATE = protocolStateField;
|
||||
checkNotNull(PROTOCOL_STATE, "Protocol state field from LoginListener cannot be null");
|
||||
|
||||
Enum<?>[] protocolStates = (Enum<?>[]) PROTOCOL_STATE.getType().getEnumConstants();
|
||||
Object readyToAcceptState = null;
|
||||
for (Enum<?> protocolState : protocolStates) {
|
||||
if (protocolState.name().equals("READY_TO_ACCEPT")) {
|
||||
readyToAcceptState = protocolState;
|
||||
}
|
||||
}
|
||||
READY_TO_ACCEPT_PROTOCOL_STATE = readyToAcceptState;
|
||||
checkNotNull(READY_TO_ACCEPT_PROTOCOL_STATE,
|
||||
"Ready to accept state from Protocol state cannot be null");
|
||||
|
||||
Class<?> packetListenerClass = getPrefixedClass("PacketListener");
|
||||
PACKET_LISTENER = getFieldOfType(networkManager, packetListenerClass);
|
||||
checkNotNull(PACKET_LISTENER, "PacketListener cannot be null");
|
||||
|
||||
LOGIN_HANDLER = getPrefixedClass("LoginListener$LoginHandler");
|
||||
checkNotNull(LOGIN_HANDLER, "LoginHandler cannot be null");
|
||||
|
||||
Constructor<?> loginHandlerConstructor = null;
|
||||
try {
|
||||
loginHandlerConstructor = makeAccessible(LOGIN_HANDLER.getDeclaredConstructor(LOGIN_LISTENER));
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
LOGIN_HANDLER_CONSTRUCTOR = loginHandlerConstructor;
|
||||
checkNotNull(LOGIN_HANDLER_CONSTRUCTOR, "LoginHandler constructor cannot be null");
|
||||
|
||||
FIRE_LOGIN_EVENTS = getMethod(LOGIN_HANDLER, "fireEvents");
|
||||
checkNotNull(FIRE_LOGIN_EVENTS, "fireEvents from LoginHandler cannot be null");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,9 +45,8 @@ public final class SpigotCommandRegistration implements CommandRegistration {
|
||||
public void register(Command command) {
|
||||
String defaultLocale = languageManager.getDefaultLocale();
|
||||
|
||||
plugin.getCommand(command.getName()).setExecutor(
|
||||
new SpigotCommandWrapper(commandUtil, command, defaultLocale)
|
||||
);
|
||||
plugin.getCommand(command.getName())
|
||||
.setExecutor(new SpigotCommandWrapper(commandUtil, command, defaultLocale));
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
|
||||
@@ -25,13 +25,12 @@
|
||||
|
||||
package org.geysermc.floodgate.inject.spigot;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@AllArgsConstructor
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@@ -78,11 +77,21 @@ public abstract class CustomList implements List {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void add(int index, Object element) {
|
||||
originalList.add(index, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean remove(Object o) {
|
||||
return originalList.remove(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Object remove(int index) {
|
||||
return originalList.remove(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean containsAll(Collection c) {
|
||||
return originalList.containsAll(c);
|
||||
@@ -133,16 +142,6 @@ public abstract class CustomList implements List {
|
||||
return originalList.set(index, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void add(int index, Object element) {
|
||||
originalList.add(index, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Object remove(int index) {
|
||||
return originalList.remove(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int indexOf(Object o) {
|
||||
return originalList.indexOf(o);
|
||||
|
||||
@@ -25,23 +25,33 @@
|
||||
|
||||
package org.geysermc.floodgate.inject.spigot;
|
||||
|
||||
import io.netty.channel.*;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.inject.CommonPlatformInjector;
|
||||
import org.geysermc.floodgate.util.ReflectionUtils;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class SpigotInjector extends CommonPlatformInjector {
|
||||
private Object serverConnection;
|
||||
private final Set<Channel> injectedClients = new HashSet<>();
|
||||
|
||||
@Getter private boolean injected = false;
|
||||
private Object serverConnection;
|
||||
private String injectedFieldName;
|
||||
|
||||
@Getter private boolean injected = false;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
|
||||
public boolean inject() throws Exception {
|
||||
@@ -50,11 +60,11 @@ public final class SpigotInjector extends CommonPlatformInjector {
|
||||
}
|
||||
|
||||
if (getServerConnection() != null) {
|
||||
for (Field f : serverConnection.getClass().getDeclaredFields()) {
|
||||
if (f.getType() == List.class) {
|
||||
f.setAccessible(true);
|
||||
for (Field field : serverConnection.getClass().getDeclaredFields()) {
|
||||
if (field.getType() == List.class) {
|
||||
field.setAccessible(true);
|
||||
|
||||
ParameterizedType parameterType = ((ParameterizedType) f.getGenericType());
|
||||
ParameterizedType parameterType = ((ParameterizedType) field.getGenericType());
|
||||
Type listType = parameterType.getActualTypeArguments()[0];
|
||||
|
||||
// the list we search has ChannelFuture as type
|
||||
@@ -62,30 +72,30 @@ public final class SpigotInjector extends CommonPlatformInjector {
|
||||
continue;
|
||||
}
|
||||
|
||||
injectedFieldName = f.getName();
|
||||
List<?> newList = new CustomList((List<?>) f.get(serverConnection)) {
|
||||
injectedFieldName = field.getName();
|
||||
List<?> newList = new CustomList((List<?>) field.get(serverConnection)) {
|
||||
@Override
|
||||
public void onAdd(Object o) {
|
||||
public void onAdd(Object object) {
|
||||
try {
|
||||
injectClient((ChannelFuture) o);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
injectClient((ChannelFuture) object);
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// inject existing
|
||||
synchronized (newList) {
|
||||
for (Object o : newList) {
|
||||
for (Object object : newList) {
|
||||
try {
|
||||
injectClient((ChannelFuture) o);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
injectClient((ChannelFuture) object);
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
f.set(serverConnection, newList);
|
||||
field.set(serverConnection, newList);
|
||||
injected = true;
|
||||
return true;
|
||||
}
|
||||
@@ -129,6 +139,7 @@ public final class SpigotInjector extends CommonPlatformInjector {
|
||||
if (serverConnection != null) {
|
||||
Field field = ReflectionUtils.getField(serverConnection.getClass(), injectedFieldName);
|
||||
List<?> list = (List<?>) ReflectionUtils.getValue(serverConnection, field);
|
||||
|
||||
if (list instanceof CustomList) {
|
||||
CustomList customList = (CustomList) list;
|
||||
ReflectionUtils.setValue(serverConnection, field, customList.getOriginalList());
|
||||
@@ -143,15 +154,17 @@ public final class SpigotInjector extends CommonPlatformInjector {
|
||||
}
|
||||
|
||||
public Object getServerConnection() throws IllegalAccessException, InvocationTargetException {
|
||||
if (serverConnection != null) return serverConnection;
|
||||
if (serverConnection != null) {
|
||||
return serverConnection;
|
||||
}
|
||||
Class<?> minecraftServer = ReflectionUtils.getPrefixedClass("MinecraftServer");
|
||||
assert minecraftServer != null;
|
||||
|
||||
Object minecraftServerInstance = ReflectionUtils.invokeStatic(minecraftServer, "getServer");
|
||||
for (Method m : minecraftServer.getDeclaredMethods()) {
|
||||
if (m.getReturnType().getSimpleName().equals("ServerConnection")) {
|
||||
if (m.getParameterTypes().length == 0) {
|
||||
serverConnection = m.invoke(minecraftServerInstance);
|
||||
for (Method method : minecraftServer.getDeclaredMethods()) {
|
||||
if (method.getReturnType().getSimpleName().equals("ServerConnection")) {
|
||||
if (method.getParameterTypes().length == 0) {
|
||||
serverConnection = method.invoke(minecraftServerInstance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
package org.geysermc.floodgate.listener;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@@ -39,8 +40,6 @@ import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
import org.geysermc.floodgate.util.LanguageManager;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public final class SpigotListener implements Listener {
|
||||
@Inject private SimpleFloodgateApi api;
|
||||
@Inject private FloodgateLogger logger;
|
||||
@@ -66,8 +65,10 @@ public final class SpigotListener implements Listener {
|
||||
FloodgatePlayer player = api.getPlayer(uniqueId);
|
||||
if (player != null) {
|
||||
player.as(FloodgatePlayerImpl.class).setLogin(false);
|
||||
logger.info(languageManager.getLogString("floodgate.ingame.login_name",
|
||||
player.getCorrectUsername(), player.getCorrectUniqueId()));
|
||||
logger.translatedInfo(
|
||||
"floodgate.ingame.login_name",
|
||||
player.getCorrectUsername(), player.getCorrectUniqueId()
|
||||
);
|
||||
languageManager.loadLocale(player.getLanguageCode());
|
||||
}
|
||||
}
|
||||
@@ -76,9 +77,7 @@ public final class SpigotListener implements Listener {
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (api.removePlayer(player.getUniqueId()) != null) {
|
||||
logger.info(languageManager.getLogString(
|
||||
"floodgate.ingame.disconnect_name", player.getName())
|
||||
);
|
||||
logger.translatedInfo("floodgate.ingame.disconnect_name", player.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,9 +29,9 @@ import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.multibindings.ProvidesIntoSet;
|
||||
import org.geysermc.floodgate.addon.AddonManagerAddon;
|
||||
import org.geysermc.floodgate.addon.DebugAddon;
|
||||
import org.geysermc.floodgate.addon.data.SpigotDataAddon;
|
||||
import org.geysermc.floodgate.api.inject.InjectorAddon;
|
||||
import org.geysermc.floodgate.addon.DebugAddon;
|
||||
import org.geysermc.floodgate.register.AddonRegister;
|
||||
|
||||
public final class SpigotAddonModule extends AbstractModule {
|
||||
|
||||
@@ -72,8 +72,8 @@ public final class SpigotPlatformModule extends AbstractModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public FloodgateLogger floodgateLogger() {
|
||||
return new JavaUtilFloodgateLogger(plugin.getLogger());
|
||||
public FloodgateLogger floodgateLogger(LanguageManager languageManager) {
|
||||
return new JavaUtilFloodgateLogger(plugin.getLogger(), languageManager);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
114
velocity/pom.xml
114
velocity/pom.xml
@@ -2,64 +2,7 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<url>${parent.url}</url>
|
||||
|
||||
<artifactId>velocity</artifactId>
|
||||
|
||||
<properties>
|
||||
<log4j.version>2.11.2</log4j.version>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>velocity-repo</id>
|
||||
<url>https://repo.velocitypowered.com/snapshots/</url>
|
||||
</repository>
|
||||
<!-- Hotfix to support the newest velocity-api, because they depend on the minecraft repo
|
||||
but for whatever reason they don't have it in the velocity-api -->
|
||||
<repository>
|
||||
<id>minecraft-repo</id>
|
||||
<url>https://libraries.minecraft.net/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>sponge-repo</id>
|
||||
<url>https://repo.spongepowered.org/maven/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.velocitypowered</groupId>
|
||||
<artifactId>velocity-api</artifactId>
|
||||
<version>${velocity.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.1.45.Final</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
@@ -87,4 +30,61 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.velocitypowered</groupId>
|
||||
<artifactId>velocity-api</artifactId>
|
||||
<version>${velocity.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.1.45.Final</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<log4j.version>2.11.2</log4j.version>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>velocity-repo</id>
|
||||
<url>https://repo.velocitypowered.com/snapshots/</url>
|
||||
</repository>
|
||||
<!-- Hotfix to support the newest velocity-api, because they depend on the minecraft repo
|
||||
but for whatever reason they don't have it in the velocity-api -->
|
||||
<repository>
|
||||
<id>minecraft-repo</id>
|
||||
<url>https://libraries.minecraft.net/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>sponge-repo</id>
|
||||
<url>https://repo.spongepowered.org/maven/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<url>${parent.url}</url>
|
||||
</project>
|
||||
@@ -30,17 +30,20 @@ import com.google.inject.Injector;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
||||
import com.velocitypowered.api.plugin.annotation.DataDirectory;
|
||||
import org.geysermc.floodgate.module.*;
|
||||
import org.geysermc.floodgate.util.ReflectionUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.module.CommandModule;
|
||||
import org.geysermc.floodgate.module.CommonModule;
|
||||
import org.geysermc.floodgate.module.VelocityAddonModule;
|
||||
import org.geysermc.floodgate.module.VelocityListenerModule;
|
||||
import org.geysermc.floodgate.module.VelocityPlatformModule;
|
||||
import org.geysermc.floodgate.util.ReflectionUtils;
|
||||
|
||||
public final class VelocityPlugin {
|
||||
private final FloodgatePlatform platform;
|
||||
|
||||
@Inject
|
||||
public VelocityPlugin(@DataDirectory Path dataDirectory, Injector guice, Logger logger) {
|
||||
public VelocityPlugin(@DataDirectory Path dataDirectory, Injector guice) {
|
||||
ReflectionUtils.setPrefix("com.velocitypowered.proxy");
|
||||
|
||||
long ctm = System.currentTimeMillis();
|
||||
@@ -52,15 +55,15 @@ public final class VelocityPlugin {
|
||||
platform = injector.getInstance(FloodgatePlatform.class);
|
||||
|
||||
long endCtm = System.currentTimeMillis();
|
||||
logger.info(platform.getLanguageManager().getLogString(
|
||||
"floodgate.core.finish",
|
||||
endCtm - ctm
|
||||
));
|
||||
injector.getInstance(FloodgateLogger.class)
|
||||
.translatedInfo("floodgate.core.finish", endCtm - ctm);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onProxyInitialization(ProxyInitializeEvent event) {
|
||||
platform.enable(new CommandModule(), new VelocityListenerModule(),
|
||||
new VelocityAddonModule());
|
||||
platform.enable(
|
||||
new CommandModule(), new VelocityListenerModule(),
|
||||
new VelocityAddonModule()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ package org.geysermc.floodgate.addon.data;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.name.Named;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.util.AttributeKey;
|
||||
import org.geysermc.floodgate.HandshakeHandler;
|
||||
import org.geysermc.floodgate.api.ProxyFloodgateApi;
|
||||
@@ -37,9 +36,6 @@ import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
import org.geysermc.floodgate.config.ProxyFloodgateConfig;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class VelocityDataAddon implements InjectorAddon {
|
||||
@Inject private HandshakeHandler handshakeHandler;
|
||||
@Inject private ProxyFloodgateConfig config;
|
||||
@@ -63,8 +59,8 @@ public final class VelocityDataAddon implements InjectorAddon {
|
||||
private AttributeKey<String> kickMessageAttribute;
|
||||
|
||||
@Override
|
||||
public void onInject(Channel channel, boolean proxyToServer) {
|
||||
if (proxyToServer) {
|
||||
public void onInject(Channel channel, boolean toServer) {
|
||||
if (toServer) {
|
||||
channel.pipeline().addAfter(
|
||||
packetEncoder, "floodgate_data_handler",
|
||||
new VelocityServerDataHandler(config, api)
|
||||
|
||||
@@ -25,10 +25,16 @@
|
||||
|
||||
package org.geysermc.floodgate.addon.data;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.getCastedValue;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.getField;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.getPrefixedClass;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.util.AttributeKey;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
import java.lang.reflect.Field;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.HandshakeHandler;
|
||||
import org.geysermc.floodgate.HandshakeHandler.HandshakeResult;
|
||||
@@ -37,26 +43,32 @@ import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
import org.geysermc.floodgate.config.ProxyFloodgateConfig;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.*;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class VelocityProxyDataHandler extends SimpleChannelInboundHandler<Object> {
|
||||
private static final Field HANDSHAKE;
|
||||
private static final Class<?> HANDSHAKE_PACKET;
|
||||
private static final Field HANDSHAKE_SERVER_ADDRESS;
|
||||
|
||||
static {
|
||||
Class<?> iic = getPrefixedClass("connection.client.InitialInboundConnection");
|
||||
checkNotNull(iic, "InitialInboundConnection class cannot be null");
|
||||
|
||||
HANDSHAKE = getField(iic, "handshake");
|
||||
checkNotNull(HANDSHAKE, "Handshake field cannot be null");
|
||||
|
||||
HANDSHAKE_PACKET = getPrefixedClass("protocol.packet.Handshake");
|
||||
checkNotNull(HANDSHAKE_PACKET, "Handshake packet class cannot be null");
|
||||
|
||||
HANDSHAKE_SERVER_ADDRESS = getField(HANDSHAKE_PACKET, "serverAddress");
|
||||
checkNotNull(HANDSHAKE_SERVER_ADDRESS, "Address in the Handshake packet cannot be null");
|
||||
}
|
||||
|
||||
private final ProxyFloodgateConfig config;
|
||||
private final ProxyFloodgateApi api;
|
||||
private final HandshakeHandler handshakeHandler;
|
||||
|
||||
private final AttributeKey<FloodgatePlayer> playerAttribute;
|
||||
private final AttributeKey<String> kickMessageAttribute;
|
||||
|
||||
private final FloodgateLogger logger;
|
||||
|
||||
private boolean done;
|
||||
|
||||
@Override
|
||||
@@ -102,19 +114,4 @@ public final class VelocityProxyDataHandler extends SimpleChannelInboundHandler<
|
||||
logger.info("Floodgate player who is logged in as {} {} joined",
|
||||
player.getCorrectUsername(), player.getCorrectUniqueId());
|
||||
}
|
||||
|
||||
static {
|
||||
Class<?> initialInboundConnection =
|
||||
getPrefixedClass("connection.client.InitialInboundConnection");
|
||||
checkNotNull(initialInboundConnection, "InitialInboundConnection class cannot be null");
|
||||
|
||||
HANDSHAKE = getField(initialInboundConnection, "handshake");
|
||||
checkNotNull(HANDSHAKE, "Handshake field cannot be null");
|
||||
|
||||
HANDSHAKE_PACKET = getPrefixedClass("protocol.packet.Handshake");
|
||||
checkNotNull(HANDSHAKE_PACKET, "Handshake packet class cannot be null");
|
||||
|
||||
HANDSHAKE_SERVER_ADDRESS = getField(HANDSHAKE_PACKET, "serverAddress");
|
||||
checkNotNull(HANDSHAKE_SERVER_ADDRESS, "Address field of the Handshake packet cannot be null");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,33 +25,55 @@
|
||||
|
||||
package org.geysermc.floodgate.addon.data;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.castedInvoke;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.getCastedValue;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.getField;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.getMethod;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.getPrefixedClass;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.invoke;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.setValue;
|
||||
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageEncoder;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.api.ProxyFloodgateApi;
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
import org.geysermc.floodgate.config.ProxyFloodgateConfig;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.*;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class VelocityServerDataHandler extends MessageToMessageEncoder<Object> {
|
||||
public final class VelocityServerDataHandler extends MessageToMessageEncoder<Object> {
|
||||
private static final Class<?> HANDSHAKE_PACKET;
|
||||
private static final Field HANDSHAKE_ADDRESS;
|
||||
private static final Method GET_ASSOCIATION;
|
||||
private static final Method GET_PLAYER;
|
||||
|
||||
static {
|
||||
HANDSHAKE_PACKET = getPrefixedClass("protocol.packet.Handshake");
|
||||
checkNotNull(HANDSHAKE_PACKET, "Handshake packet class cannot be null");
|
||||
|
||||
HANDSHAKE_ADDRESS = getField(HANDSHAKE_PACKET, "serverAddress");
|
||||
checkNotNull(HANDSHAKE_ADDRESS, "Address field of the Handshake packet cannot be null");
|
||||
|
||||
Class<?> minecraftConnection = getPrefixedClass("connection.MinecraftConnection");
|
||||
|
||||
GET_ASSOCIATION = getMethod(minecraftConnection, "getAssociation");
|
||||
checkNotNull(GET_ASSOCIATION, "getAssociation in MinecraftConnection cannot be null");
|
||||
|
||||
Class<?> serverConnection = getPrefixedClass("connection.backend.VelocityServerConnection");
|
||||
|
||||
GET_PLAYER = getMethod(serverConnection, "getPlayer");
|
||||
checkNotNull(GET_PLAYER, "getPlayer in VelocityServerConnection cannot be null");
|
||||
}
|
||||
|
||||
private final ProxyFloodgateConfig config;
|
||||
private final ProxyFloodgateApi api;
|
||||
|
||||
private boolean done;
|
||||
|
||||
@Override
|
||||
@@ -63,7 +85,8 @@ public class VelocityServerDataHandler extends MessageToMessageEncoder<Object> {
|
||||
}
|
||||
|
||||
if (!HANDSHAKE_PACKET.isInstance(packet) || !config.isSendFloodgateData()) {
|
||||
System.out.println(HANDSHAKE_PACKET.isInstance(packet)+" "+config.isSendFloodgateData());
|
||||
System.out.println(
|
||||
HANDSHAKE_PACKET.isInstance(packet) + " " + config.isSendFloodgateData());
|
||||
done = true;
|
||||
out.add(packet);
|
||||
return;
|
||||
@@ -99,22 +122,4 @@ public class VelocityServerDataHandler extends MessageToMessageEncoder<Object> {
|
||||
done = true;
|
||||
out.add(packet);
|
||||
}
|
||||
|
||||
static {
|
||||
HANDSHAKE_PACKET = getPrefixedClass("protocol.packet.Handshake");
|
||||
checkNotNull(HANDSHAKE_PACKET, "Handshake packet class cannot be null");
|
||||
|
||||
HANDSHAKE_ADDRESS = getField(HANDSHAKE_PACKET, "serverAddress");
|
||||
checkNotNull(HANDSHAKE_ADDRESS, "Address field of the Handshake packet cannot be null");
|
||||
|
||||
Class<?> minecraftConnection = getPrefixedClass("connection.MinecraftConnection");
|
||||
|
||||
GET_ASSOCIATION = getMethod(minecraftConnection, "getAssociation");
|
||||
checkNotNull(GET_ASSOCIATION, "getAssociation in MinecraftConnection cannot be null");
|
||||
|
||||
Class<?> serverConnection = getPrefixedClass("connection.backend.VelocityServerConnection");
|
||||
|
||||
GET_PLAYER = getMethod(serverConnection, "getPlayer");
|
||||
checkNotNull(GET_PLAYER, "getPlayer in VelocityServerConnection cannot be null");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ package org.geysermc.floodgate.command;
|
||||
import com.velocitypowered.api.command.CommandManager;
|
||||
import com.velocitypowered.api.command.CommandSource;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import java.util.Locale;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.floodgate.platform.command.Command;
|
||||
@@ -35,8 +36,6 @@ import org.geysermc.floodgate.platform.command.CommandRegistration;
|
||||
import org.geysermc.floodgate.platform.command.CommandUtil;
|
||||
import org.geysermc.floodgate.util.LanguageManager;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class VelocityCommandRegistration implements CommandRegistration {
|
||||
private final CommandManager commandManager;
|
||||
|
||||
@@ -25,26 +25,31 @@
|
||||
|
||||
package org.geysermc.floodgate.inject.velocity;
|
||||
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.castedInvoke;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.getMethod;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.getValue;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.invoke;
|
||||
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import java.lang.reflect.Method;
|
||||
import javax.naming.OperationNotSupportedException;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.inject.CommonPlatformInjector;
|
||||
|
||||
import javax.naming.OperationNotSupportedException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.*;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class VelocityInjector extends CommonPlatformInjector {
|
||||
private final ProxyServer server;
|
||||
|
||||
@Getter private boolean injected = false;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public boolean inject() {
|
||||
if (isInjected()) return true;
|
||||
if (isInjected()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Object connectionManager = getValue(server, "cm");
|
||||
|
||||
@@ -80,6 +85,10 @@ public final class VelocityInjector extends CommonPlatformInjector {
|
||||
private static final class VelocityChannelInitializer extends ChannelInitializer<Channel> {
|
||||
private static final Method initChannel;
|
||||
|
||||
static {
|
||||
initChannel = getMethod(ChannelInitializer.class, "initChannel", Channel.class);
|
||||
}
|
||||
|
||||
private final VelocityInjector injector;
|
||||
private final ChannelInitializer original;
|
||||
private final boolean proxyToServer;
|
||||
@@ -91,9 +100,5 @@ public final class VelocityInjector extends CommonPlatformInjector {
|
||||
injector.injectAddonsCall(channel, proxyToServer);
|
||||
injector.addInjectedClient(channel);
|
||||
}
|
||||
|
||||
static {
|
||||
initChannel = getMethod(ChannelInitializer.class, "initChannel", Channel.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,11 @@
|
||||
|
||||
package org.geysermc.floodgate.listener;
|
||||
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.getCastedValue;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.getFieldOfType;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.getPrefixedClass;
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.getValue;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.inject.Inject;
|
||||
@@ -40,23 +45,36 @@ import com.velocitypowered.api.proxy.Player;
|
||||
import com.velocitypowered.api.util.GameProfile;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.util.AttributeKey;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
import org.geysermc.floodgate.api.ProxyFloodgateApi;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
import org.geysermc.floodgate.util.LanguageManager;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.geysermc.floodgate.util.ReflectionUtils.*;
|
||||
|
||||
public final class VelocityListener {
|
||||
private static final Field INITIAL_MINECRAFT_CONNECTION;
|
||||
private static final Field MINECRAFT_CONNECTION;
|
||||
private static final Field CHANNEL;
|
||||
|
||||
static {
|
||||
Class<?> initialConnection = getPrefixedClass("connection.client.InitialInboundConnection");
|
||||
|
||||
Class<?> minecraftConnection = getPrefixedClass("connection.MinecraftConnection");
|
||||
INITIAL_MINECRAFT_CONNECTION = getFieldOfType(initialConnection, minecraftConnection);
|
||||
Class<?> connectedPlayer = getPrefixedClass("connection.client.ConnectedPlayer");
|
||||
MINECRAFT_CONNECTION = getFieldOfType(connectedPlayer, minecraftConnection);
|
||||
CHANNEL = getFieldOfType(minecraftConnection, Channel.class);
|
||||
}
|
||||
|
||||
private final Cache<InboundConnection, FloodgatePlayer> playerCache =
|
||||
CacheBuilder.newBuilder()
|
||||
.maximumSize(500)
|
||||
.expireAfterAccess(20, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
@Inject private ProxyFloodgateApi api;
|
||||
@Inject private LanguageManager languageManager;
|
||||
@Inject private FloodgateLogger logger;
|
||||
@@ -69,12 +87,6 @@ public final class VelocityListener {
|
||||
@Named("kickMessageAttribute")
|
||||
private AttributeKey<String> kickMessageAttribute;
|
||||
|
||||
private final Cache<InboundConnection, FloodgatePlayer> playerCache =
|
||||
CacheBuilder.newBuilder()
|
||||
.maximumSize(500)
|
||||
.expireAfterAccess(20, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
@Subscribe(order = PostOrder.EARLY)
|
||||
public void onPreLogin(PreLoginEvent event) {
|
||||
FloodgatePlayer player = null;
|
||||
@@ -91,7 +103,9 @@ public final class VelocityListener {
|
||||
}
|
||||
|
||||
if (kickMessage != null) {
|
||||
event.setResult(PreLoginEvent.PreLoginComponentResult.denied(TextComponent.of(kickMessage)));
|
||||
event.setResult(
|
||||
PreLoginEvent.PreLoginComponentResult.denied(TextComponent.of(kickMessage))
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -111,13 +125,15 @@ public final class VelocityListener {
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@Subscribe(order = PostOrder.LAST)
|
||||
public void onLogin(LoginEvent event) {
|
||||
if (event.getResult().isAllowed()) {
|
||||
FloodgatePlayer player = api.getPlayer(event.getPlayer().getUniqueId());
|
||||
if (player != null) {
|
||||
languageManager.loadLocale(player.getLanguageCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe(order = PostOrder.LAST)
|
||||
public void onDisconnect(DisconnectEvent event) {
|
||||
@@ -129,22 +145,10 @@ public final class VelocityListener {
|
||||
|
||||
if (fPlayer != null && api.removePlayer(fPlayer)) {
|
||||
api.removeEncryptedData(event.getPlayer().getUniqueId());
|
||||
logger.info(languageManager.getLogString(
|
||||
"floodgate.ingame.disconnect_name", player.getUsername()
|
||||
));
|
||||
logger.translatedInfo("floodgate.ingame.disconnect_name", player.getUsername());
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
logger.error("Failed to remove the player", exception);
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
Class<?> initialConnection = getPrefixedClass("connection.client.InitialInboundConnection");
|
||||
|
||||
Class<?> minecraftConnection = getPrefixedClass("connection.MinecraftConnection");
|
||||
INITIAL_MINECRAFT_CONNECTION = getFieldOfType(initialConnection, minecraftConnection);
|
||||
Class<?> connectedPlayer = getPrefixedClass("connection.client.ConnectedPlayer");
|
||||
MINECRAFT_CONNECTION = getFieldOfType(connectedPlayer, minecraftConnection);
|
||||
CHANNEL = getFieldOfType(minecraftConnection, Channel.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,17 +25,19 @@
|
||||
|
||||
package org.geysermc.floodgate.logger;
|
||||
|
||||
import static org.geysermc.floodgate.util.MessageFormatter.format;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.apache.logging.log4j.core.config.Configurator;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.util.LanguageManager;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import static org.geysermc.floodgate.util.MessageFormatter.format;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class Slf4jFloodgateLogger implements FloodgateLogger {
|
||||
private final Logger logger;
|
||||
private final LanguageManager languageManager;
|
||||
|
||||
@Override
|
||||
public void error(String message, Object... args) {
|
||||
@@ -57,6 +59,11 @@ public final class Slf4jFloodgateLogger implements FloodgateLogger {
|
||||
logger.info(message, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translatedInfo(String message, Object... args) {
|
||||
logger.info(languageManager.getLogString(message, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String message, Object... args) {
|
||||
logger.debug(message, args);
|
||||
|
||||
@@ -74,8 +74,8 @@ public final class VelocityPlatformModule extends AbstractModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public FloodgateLogger floodgateLogger(Logger logger) {
|
||||
return new Slf4jFloodgateLogger(logger);
|
||||
public FloodgateLogger floodgateLogger(Logger logger, LanguageManager languageManager) {
|
||||
return new Slf4jFloodgateLogger(logger, languageManager);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -49,9 +49,7 @@ public final class VelocityCommandUtil implements CommandUtil {
|
||||
|
||||
public TextComponent translateAndTransform(String locale, CommandMessage message,
|
||||
Object... args) {
|
||||
return TextComponent.of(manager.getString(
|
||||
message.getMessage(), locale, args
|
||||
));
|
||||
return TextComponent.of(manager.getString(message.getMessage(), locale, args));
|
||||
}
|
||||
|
||||
protected Player cast(Object instance) {
|
||||
|
||||
Reference in New Issue
Block a user