From 45ca08b0f1b7886d720447064865c865bdad150f Mon Sep 17 00:00:00 2001 From: Tim203 Date: Sat, 30 Nov 2019 13:44:07 +0100 Subject: [PATCH] First commit --- .gitignore | 221 ++++++++++++++++++ bungee/pom.xml | 63 +++++ .../floodgate/BungeeFloodgateAPI.java | 9 + .../org/geysermc/floodgate/BungeePlugin.java | 95 ++++++++ bungee/src/main/resources/plugin.yml | 4 + common/pom.xml | 28 +++ .../org/geysermc/floodgate/FloodgateAPI.java | 41 ++++ .../geysermc/floodgate/FloodgateConfig.java | 91 ++++++++ .../geysermc/floodgate/FloodgatePlayer.java | 48 ++++ .../geysermc/floodgate/util/BedrockData.java | 35 +++ .../floodgate/util/EncryptionUtil.java | 76 ++++++ .../floodgate/util/ReflectionUtil.java | 37 +++ common/src/main/resources/config.yml | 4 + pom.xml | 96 ++++++++ 14 files changed, 848 insertions(+) create mode 100644 .gitignore create mode 100644 bungee/pom.xml create mode 100644 bungee/src/main/java/org/geysermc/floodgate/BungeeFloodgateAPI.java create mode 100644 bungee/src/main/java/org/geysermc/floodgate/BungeePlugin.java create mode 100644 bungee/src/main/resources/plugin.yml create mode 100644 common/pom.xml create mode 100644 common/src/main/java/org/geysermc/floodgate/FloodgateAPI.java create mode 100644 common/src/main/java/org/geysermc/floodgate/FloodgateConfig.java create mode 100644 common/src/main/java/org/geysermc/floodgate/FloodgatePlayer.java create mode 100644 common/src/main/java/org/geysermc/floodgate/util/BedrockData.java create mode 100644 common/src/main/java/org/geysermc/floodgate/util/EncryptionUtil.java create mode 100644 common/src/main/java/org/geysermc/floodgate/util/ReflectionUtil.java create mode 100644 common/src/main/resources/config.yml create mode 100644 pom.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..a3546808 --- /dev/null +++ b/.gitignore @@ -0,0 +1,221 @@ +# Created by https://www.gitignore.io/api/git,java,maven,eclipse,netbeans,jetbrains+all +# Edit at https://www.gitignore.io/?templates=git,java,maven,eclipse,netbeans,jetbrains+all + +### Eclipse ### +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# CDT- autotools +.autotools + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +# Annotation Processing +.apt_generated/ + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet + +### Eclipse Patch ### +# Eclipse Core +.project + +# JDT-specific (Eclipse Java Development Tools) +.classpath + +# Annotation Processing +.apt_generated + +.sts4-cache/ + +### Git ### +# Created by git for backups. To disable backups in Git: +# $ git config --global mergetool.keepBackup false +*.orig + +# Created by git when using merge tools for conflicts +*.BACKUP.* +*.BASE.* +*.LOCAL.* +*.REMOTE.* +*_BACKUP_*.txt +*_BASE_*.txt +*_LOCAL_*.txt +*_REMOTE_*.txt + +### Java ### +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +### JetBrains+all ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### JetBrains+all Patch ### +# Ignores the whole .idea folder and all .iml files +# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 + +.idea/ + +# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 + +*.iml +modules.xml +.idea/misc.xml +*.ipr + +# Sonarlint plugin +.idea/sonarlint + +### Maven ### +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar + +### NetBeans ### +**/nbproject/private/ +**/nbproject/Makefile-*.mk +**/nbproject/Package-*.bash +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +# End of https://www.gitignore.io/api/git,java,maven,eclipse,netbeans,jetbrains+all diff --git a/bungee/pom.xml b/bungee/pom.xml new file mode 100644 index 00000000..a6988275 --- /dev/null +++ b/bungee/pom.xml @@ -0,0 +1,63 @@ + + + + floodgate-parent + org.geysermc + 1.0-SNAPSHOT + + 4.0.0 + + floodgate-bungee + + + + net.md-5 + bungeecord-api + 1.14-SNAPSHOT + provided + + + net.md-5 + bungeecord-api + 1.14-SNAPSHOT + javadoc + provided + + + net.md-5 + bungeecord-proxy + 1.12-SNAPSHOT + provided + + + org.geysermc + floodgate-common + ${project.version} + compile + + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + + + ${outputName} + true + true + + + + + \ No newline at end of file diff --git a/bungee/src/main/java/org/geysermc/floodgate/BungeeFloodgateAPI.java b/bungee/src/main/java/org/geysermc/floodgate/BungeeFloodgateAPI.java new file mode 100644 index 00000000..cee504dd --- /dev/null +++ b/bungee/src/main/java/org/geysermc/floodgate/BungeeFloodgateAPI.java @@ -0,0 +1,9 @@ +package org.geysermc.floodgate; + +import net.md_5.bungee.api.connection.PendingConnection; + +public class BungeeFloodgateAPI extends FloodgateAPI { + public static FloodgatePlayer getPlayerByConnection(PendingConnection connection) { + return getPlayer(connection.getUniqueId()); + } +} diff --git a/bungee/src/main/java/org/geysermc/floodgate/BungeePlugin.java b/bungee/src/main/java/org/geysermc/floodgate/BungeePlugin.java new file mode 100644 index 00000000..e14bef25 --- /dev/null +++ b/bungee/src/main/java/org/geysermc/floodgate/BungeePlugin.java @@ -0,0 +1,95 @@ +package org.geysermc.floodgate; + +import lombok.Getter; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.event.PlayerDisconnectEvent; +import net.md_5.bungee.api.event.PreLoginEvent; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.api.plugin.Plugin; +import net.md_5.bungee.connection.InitialHandler; +import net.md_5.bungee.event.EventHandler; +import net.md_5.bungee.event.EventPriority; +import org.geysermc.floodgate.util.BedrockData; +import org.geysermc.floodgate.util.EncryptionUtil; +import org.geysermc.floodgate.util.ReflectionUtil; + +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +public class BungeePlugin extends Plugin implements Listener { + @Getter private static BungeePlugin instance; + @Getter private FloodgateConfig config = null; + + @Override + public void onLoad() { + instance = this; + if (!getDataFolder().exists()) { + getDataFolder().mkdir(); + } + + config = FloodgateConfig.load(getLogger(), getDataFolder().toPath().resolve("config.yml")); + } + + @Override + public void onEnable() { + getProxy().getPluginManager().registerListener(this, this); + } + + @EventHandler(priority = EventPriority.LOW) + public void onPreLogin(PreLoginEvent event) { + // only need to check when server is in online mode :D + if (ProxyServer.getInstance().getConfig().isOnlineMode()) { + event.registerIntent(this); + + getProxy().getScheduler().runAsync(this, () -> { + String[] data = ((InitialHandler) event.getConnection()).getExtraDataInHandshake().split("\0"); + System.out.println(data.length); + + if (data.length == 4 && data[1].equals("Geyser-Floodgate")) { + try { + BedrockData bedrockData = EncryptionUtil.decryptToInstance( + config.getPrivateKey(), + data[2] + '\0' + data[3] + ); + + if (bedrockData.getDataLength() != BedrockData.EXPECTED_LENGTH) { + event.setCancelReason(String.format( + config.getMessages().getInvalidArgumentsLength(), + BedrockData.EXPECTED_LENGTH, bedrockData.getDataLength() + )); + event.setCancelled(true); + return; + } + + FloodgatePlayer player = new FloodgatePlayer(bedrockData); + FloodgateAPI.players.put(player.getJavaUniqueId(), player); + + event.getConnection().setOnlineMode(false); + event.getConnection().setUniqueId(player.getJavaUniqueId()); + ReflectionUtil.setValue(event.getConnection(), "name", player.getJavaUsername()); + + System.out.println("Added " + player.getUsername() + " " + player.getJavaUniqueId()); + } catch (NullPointerException | NoSuchPaddingException | NoSuchAlgorithmException | + InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + event.setCancelReason(config.getMessages().getInvalidKey()); + event.setCancelled(true); + e.printStackTrace(); + } + } + event.completeIntent(this); + }); + } + } + + @EventHandler + public void onDisconnect(PlayerDisconnectEvent event) { + FloodgatePlayer player = BungeeFloodgateAPI.getPlayerByConnection(event.getPlayer().getPendingConnection()); + if (player != null) { + FloodgateAPI.players.remove(player.getJavaUniqueId()); + System.out.println("Removed " + player.getUsername() + " " + event.getPlayer().getUniqueId()); + } + } +} diff --git a/bungee/src/main/resources/plugin.yml b/bungee/src/main/resources/plugin.yml new file mode 100644 index 00000000..269dca83 --- /dev/null +++ b/bungee/src/main/resources/plugin.yml @@ -0,0 +1,4 @@ +name: ${project.name} +version: ${project.version} +author: ${project.organization.name} +main: org.geysermc.flootgate.BungeePlugin \ No newline at end of file diff --git a/common/pom.xml b/common/pom.xml new file mode 100644 index 00000000..2ff01ebf --- /dev/null +++ b/common/pom.xml @@ -0,0 +1,28 @@ + + + + floodgate-parent + org.geysermc + 1.0-SNAPSHOT + + 4.0.0 + + floodgate-common + + + + com.fasterxml.jackson.core + jackson-databind + 2.9.9.3 + compile + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + 2.9.9 + compile + + + \ No newline at end of file diff --git a/common/src/main/java/org/geysermc/floodgate/FloodgateAPI.java b/common/src/main/java/org/geysermc/floodgate/FloodgateAPI.java new file mode 100644 index 00000000..a8c045dc --- /dev/null +++ b/common/src/main/java/org/geysermc/floodgate/FloodgateAPI.java @@ -0,0 +1,41 @@ +package org.geysermc.floodgate; + +import com.fasterxml.jackson.annotation.JsonEnumDefaultValue; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +class FloodgateAPI { + static final Map players = new HashMap<>(); + + public static FloodgatePlayer getPlayer(UUID uuid) { + return players.get(uuid); + } + + public static UUID createJavaPlayerId(long xuid) { + return new UUID(0, xuid); + } + + public enum DeviceOS { + @JsonEnumDefaultValue + UNKOWN, + ANDROID, + IOS, + OSX, + FIREOS, + GEARVR, + HOLOLENS, + WIN10, + WIN32, + DEDICATED, + ORBIS, + NX; + + private static final DeviceOS[] VALUES = values(); + + public static DeviceOS getById(int id) { + return id < VALUES.length ? VALUES[id] : VALUES[0]; + } + } +} diff --git a/common/src/main/java/org/geysermc/floodgate/FloodgateConfig.java b/common/src/main/java/org/geysermc/floodgate/FloodgateConfig.java new file mode 100644 index 00000000..ae7e3b81 --- /dev/null +++ b/common/src/main/java/org/geysermc/floodgate/FloodgateConfig.java @@ -0,0 +1,91 @@ +package org.geysermc.floodgate; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import lombok.Getter; +import org.geysermc.floodgate.util.EncryptionUtil; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.spec.InvalidKeySpecException; +import java.util.Base64; +import java.util.logging.Level; +import java.util.logging.Logger; + +@Getter +public class FloodgateConfig { + @JsonProperty(value = "key-file-name") + private String keyFileName; + @JsonProperty(value = "disconnect") + private DisconnectMessages messages; + + @JsonIgnore + private PrivateKey privateKey = null; + + @Getter + public static class DisconnectMessages { + @JsonProperty("invalid-key") + private String invalidKey; + @JsonProperty("invalid-arguments-length") + private String invalidArgumentsLength; + } + + public static FloodgateConfig load(Logger logger, Path path) { + FloodgateConfig config = null; + try { + try { + if (!path.toFile().exists()) { + Files.copy(FloodgateConfig.class.getClassLoader().getResourceAsStream("config.yml"), path); + + KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); + generator.initialize(2048); + KeyPair keyPair = generator.generateKeyPair(); + + String test = "abcdefghijklmnopqrstuvwxyz1234567890"; + + String encrypted = EncryptionUtil.encrypt(keyPair.getPublic(), test); + String decrypted = new String(EncryptionUtil.decrypt(keyPair.getPrivate(), encrypted)); + + if (!test.equals(decrypted)) { + System.out.println(test +" "+ decrypted +" "+ encrypted +" " + new String(Base64.getDecoder().decode(encrypted.split("\0")[1]))); + throw new RuntimeException( + "Testing the private and public key failed," + + "the original message isn't the same as the decrypted!" + ); + } + + Files.write(path.getParent().resolve("encrypted.txt"), encrypted.getBytes()); + + Files.write(path.getParent().resolve("public-key.pem"), keyPair.getPublic().getEncoded()); + Files.write(path.getParent().resolve("key.pem"), keyPair.getPrivate().getEncoded()); + } + } catch (Exception e) { + logger.log(Level.SEVERE, "Error while creating config", e); + } + + config = new ObjectMapper(new YAMLFactory()).readValue( + Files.readAllBytes(path), FloodgateConfig.class + ); + } catch (Exception e) { + logger.log(Level.SEVERE, "Error while loading config", e); + } + if (config == null) return null; + + try { + config.privateKey = EncryptionUtil.getKeyFromFile( + path.getParent().resolve(config.getKeyFileName()), + PrivateKey.class + ); + } catch (IOException | InvalidKeySpecException | NoSuchAlgorithmException e) { + logger.log(Level.SEVERE, "Error while reading private key", e); + } + return config; + } +} diff --git a/common/src/main/java/org/geysermc/floodgate/FloodgatePlayer.java b/common/src/main/java/org/geysermc/floodgate/FloodgatePlayer.java new file mode 100644 index 00000000..0fe92c92 --- /dev/null +++ b/common/src/main/java/org/geysermc/floodgate/FloodgatePlayer.java @@ -0,0 +1,48 @@ +package org.geysermc.floodgate; + +import lombok.Getter; +import org.geysermc.floodgate.util.BedrockData; + +import java.util.UUID; + +@Getter +public class FloodgatePlayer { + /** + * Bedrock version of the client + */ + private String version; + /** + * Bedrock username (full version) + */ + private String username; + /** + * Bedrock username with > identifier + */ + private String javaUsername; + /** + * The Xbox Unique Identifier + */ + private String xuid; + /** + * The operation system of the bedrock client + */ + private FloodgateAPI.DeviceOS deviceOS; + /** + * The language code of the bedrock client + */ + private String languageCode; + /** + * The Java UUID used to identify the bedrock client + */ + private UUID javaUniqueId; + + FloodgatePlayer(BedrockData data) { + version = data.getVersion(); + username = data.getUsername(); + javaUsername = "*" + data.getUsername().substring(0, Math.min(data.getUsername().length(), 15)); + xuid = data.getXuid(); + deviceOS = FloodgateAPI.DeviceOS.getById(data.getDeviceId()); + languageCode = data.getLanguageCode(); + javaUniqueId = FloodgateAPI.createJavaPlayerId(Long.parseLong(data.getXuid())); + } +} diff --git a/common/src/main/java/org/geysermc/floodgate/util/BedrockData.java b/common/src/main/java/org/geysermc/floodgate/util/BedrockData.java new file mode 100644 index 00000000..cc41eeab --- /dev/null +++ b/common/src/main/java/org/geysermc/floodgate/util/BedrockData.java @@ -0,0 +1,35 @@ +package org.geysermc.floodgate.util; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class BedrockData { + public static final int EXPECTED_LENGTH = 6; + private String version; + private String username; + private String xuid; + private int deviceId; + private String languageCode; + private int inputMode; + private int dataLength; + + public BedrockData(String version, String username, String xuid, int deviceId, String languageCode, int inputMode) { + this(version, username, xuid, deviceId, languageCode, inputMode, 6); + } + + public static BedrockData fromString(String data) { + String[] split = data.split("\0"); + if (split.length != 5) return null; + return new BedrockData(split[0], split[1], split[2], Integer.parseInt(split[3]), split[4], split.length); + } + + public static BedrockData fromRawData(byte[] data) { + return fromString(new String(data)); + } + + public String toString() { + return version +"\0"+ username +"\0"+ xuid +"\0"+ deviceId +"\0"+ languageCode +"\0"+ inputMode; + } +} diff --git a/common/src/main/java/org/geysermc/floodgate/util/EncryptionUtil.java b/common/src/main/java/org/geysermc/floodgate/util/EncryptionUtil.java new file mode 100644 index 00000000..5ae6dcd4 --- /dev/null +++ b/common/src/main/java/org/geysermc/floodgate/util/EncryptionUtil.java @@ -0,0 +1,76 @@ +package org.geysermc.floodgate.util; + +import javax.crypto.*; +import javax.crypto.spec.SecretKeySpec; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.*; +import java.security.spec.EncodedKeySpec; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; + +public class EncryptionUtil { + public static String encrypt(Key key, String data) throws IllegalBlockSizeException, + InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException { + KeyGenerator generator = KeyGenerator.getInstance("AES"); + generator.init(128); + SecretKey secretKey = generator.generateKey(); + + Cipher cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.ENCRYPT_MODE, secretKey); + byte[] encryptedText = cipher.doFinal(data.getBytes()); + + cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); + cipher.init(key instanceof PublicKey ? Cipher.PUBLIC_KEY : Cipher.PRIVATE_KEY, key); + return Base64.getEncoder().encodeToString(cipher.doFinal(secretKey.getEncoded())) + '\0' + + Base64.getEncoder().encodeToString(encryptedText); + } + + public static String encryptFromInstance(Key key, BedrockData data) throws IllegalBlockSizeException, + InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException { + return encrypt(key, data.toString()); + } + + public static byte[] decrypt(Key key, String encryptedData) throws IllegalBlockSizeException, + InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException { + String[] split = encryptedData.split("\0"); + if (split.length != 2) { + throw new IllegalArgumentException("Expected two arguments, got " + split.length); + } + + Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); + cipher.init(key instanceof PublicKey ? Cipher.PUBLIC_KEY : Cipher.PRIVATE_KEY, key); + byte[] decryptedKey = cipher.doFinal(Base64.getDecoder().decode(split[0])); + + SecretKey secretKey = new SecretKeySpec(decryptedKey, 0, decryptedKey.length, "AES"); + cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.DECRYPT_MODE, secretKey); + return cipher.doFinal(Base64.getDecoder().decode(split[1])); + } + + public static BedrockData decryptToInstance(Key key, String encryptedData) throws IllegalBlockSizeException, + InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException { + return BedrockData.fromRawData(decrypt(key, encryptedData)); + } + + @SuppressWarnings("unchecked") + public static T getKeyFromFile(Path fileLocation, Class keyType) throws + IOException, InvalidKeySpecException, NoSuchAlgorithmException { + boolean isPublicKey = keyType == PublicKey.class; + if (!isPublicKey && keyType != PrivateKey.class) { + throw new RuntimeException("I can only read public and private keys!"); + } + + byte[] key = Files.readAllBytes(fileLocation); + + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + EncodedKeySpec keySpec = isPublicKey ? new X509EncodedKeySpec(key) : new PKCS8EncodedKeySpec(key); + return (T) (isPublicKey ? + keyFactory.generatePublic(keySpec) : + keyFactory.generatePrivate(keySpec) + ); + } +} diff --git a/common/src/main/java/org/geysermc/floodgate/util/ReflectionUtil.java b/common/src/main/java/org/geysermc/floodgate/util/ReflectionUtil.java new file mode 100644 index 00000000..a21b9184 --- /dev/null +++ b/common/src/main/java/org/geysermc/floodgate/util/ReflectionUtil.java @@ -0,0 +1,37 @@ +package org.geysermc.floodgate.util; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class ReflectionUtil { + public static Field getField(Class clazz, String fieldName, boolean isPublic) { + try { + return isPublic ? clazz.getField(fieldName) : clazz.getDeclaredField(fieldName); + } catch (NoSuchFieldException e) { + return null; + } + } + + public static Field getField(Class clazz, String fieldName) { + Field field = getField(clazz, fieldName, false); + return field != null ? field : getField(clazz, fieldName, true); + } + + public static boolean setValue(Object instance, String fieldName, Object value) { + Field field = getField(instance.getClass(), fieldName); + if (field != null) { + setValue(instance, field, value); + } + return field != null; + } + + public static void setValue(Object instance, Field field, Object value) { + if (!field.isAccessible()) field.setAccessible(true); + try { + field.set(instance, value); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } +} diff --git a/common/src/main/resources/config.yml b/common/src/main/resources/config.yml new file mode 100644 index 00000000..02a23bfe --- /dev/null +++ b/common/src/main/resources/config.yml @@ -0,0 +1,4 @@ +key-file-name: key.pem +disconnect: + invalid-key: Please connect through the official Geyser + invalid-arguments-length: Expected {0} arguments, got {1}. Is Geyser up-to-date? diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..6c922642 --- /dev/null +++ b/pom.xml @@ -0,0 +1,96 @@ + + + 4.0.0 + + org.geysermc + floodgate-parent + 1.0-SNAPSHOT + + bungee + common + + pom + floodgate + Allows Bedrock players to join Java edition servers while keeping online mode + https://geysermc.org + + + ${project.name} + UTF-8 + UTF-8 + 1.8 + 1.8 + + + + GeyserMC + https://github.com/GeyserMC/Floodgate/blob/master/pom.xml + + + + scm:git:https://github.com/GeyserMC/Floodgate.git + scm:git:git@github.com:GeyserMC/Floodgate.git + https://github.com/GeyserMC/Floodgate + + + + + BungeeCord + https://oss.sonatype.org/content/repositories/snapshots/ + + + + + + releases + nukkitx-releases + https://repo.nukkitx.com/maven-releases + + + snapshots + nukkitx-snapshots + https://repo.nukkitx.com/maven-snapshots + + + + + + org.projectlombok + lombok + 1.18.0 + provided + + + + + clean install + + + src/main/resources/ + true + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-shade-plugin + 3.1.0 + + false + true + + + + + \ No newline at end of file