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