From 1c2ef99a546efd1d1d4ae287a8b1845f01032668 Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Sun, 1 Dec 2019 15:16:52 -0600 Subject: [PATCH] Separate bootstrap and allow for Geyser to run on Bukkit (Addresses #54) --- api/pom.xml | 2 +- bootstrap/bukkit/pom.xml | 63 +++++++ .../bukkit/GeyserBukkitConfiguration.java | 176 ++++++++++++++++++ .../platform/bukkit/GeyserBukkitLogger.java | 81 ++++++++ .../platform/bukkit/GeyserBukkitPlugin.java | 49 ++++- .../bukkit/src/main/resources/plugin.yml | 5 + bootstrap/pom.xml | 36 ++++ bootstrap/standalone/pom.xml | 63 +++++++ .../platform/standalone/GeyserBootstrap.java | 81 ++++++++ .../standalone}/GeyserConfiguration.java | 46 ++++- .../platform/standalone/GeyserLogger.java | 133 +++++++++++++ common/pom.xml | 48 +---- .../geysermc/common/IGeyserConfiguration.java | 64 +++++-- .../common/bootstrap/IGeyserBootstrap.java | 18 +- connector/pom.xml | 27 +-- .../geysermc/connector/GeyserConnector.java | 46 ++--- .../configuration/UserAuthenticationInfo.java | 31 --- .../connector/console/GeyserLogger.java | 18 +- .../network/ConnectorServerEventHandler.java | 5 +- .../network/UpstreamPacketHandler.java | 6 +- .../geysermc/connector/utils/SkinUtils.java | 4 +- plugin/pom.xml | 39 ---- .../org/geysermc/plugin/GeyserPlugin.java | 47 ----- pom.xml | 4 +- 24 files changed, 837 insertions(+), 255 deletions(-) create mode 100644 bootstrap/bukkit/pom.xml create mode 100644 bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitConfiguration.java create mode 100644 bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitLogger.java rename connector/src/main/java/org/geysermc/connector/configuration/BedrockConfiguration.java => bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java (51%) create mode 100644 bootstrap/bukkit/src/main/resources/plugin.yml create mode 100644 bootstrap/pom.xml create mode 100644 bootstrap/standalone/pom.xml create mode 100644 bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserBootstrap.java rename {connector/src/main/java/org/geysermc/connector/configuration => bootstrap/standalone/src/main/java/org/geysermc/platform/standalone}/GeyserConfiguration.java (64%) create mode 100644 bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserLogger.java rename connector/src/main/java/org/geysermc/connector/configuration/RemoteConfiguration.java => common/src/main/java/org/geysermc/common/IGeyserConfiguration.java (56%) rename connector/src/main/java/org/geysermc/connector/configuration/MetricInfo.java => common/src/main/java/org/geysermc/common/bootstrap/IGeyserBootstrap.java (81%) delete mode 100644 connector/src/main/java/org/geysermc/connector/configuration/UserAuthenticationInfo.java delete mode 100644 plugin/pom.xml delete mode 100644 plugin/src/main/java/org/geysermc/plugin/GeyserPlugin.java diff --git a/api/pom.xml b/api/pom.xml index a0cbdf87..2bb85be2 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -6,7 +6,7 @@ org.geysermc geyser-parent - 1.0-SNAPSHOT + parent api diff --git a/bootstrap/bukkit/pom.xml b/bootstrap/bukkit/pom.xml new file mode 100644 index 00000000..02b7d9a2 --- /dev/null +++ b/bootstrap/bukkit/pom.xml @@ -0,0 +1,63 @@ + + + 4.0.0 + + org.geysermc + bootstrap-parent + 1.0-SNAPSHOT + ../ + + bootstrap-bukkit + + + org.geysermc + common + 1.0-SNAPSHOT + compile + + + org.geysermc + connector + 1.0-SNAPSHOT + compile + + + org.spigotmc + spigot-api + 1.14-R0.1-SNAPSHOT + provided + + + + ${outputName}-Bukkit-noshade + clean install + + + src/main/resources/ + true + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.1.0 + + + package + + shade + + + + + ${outputName}-Bukkit + false + true + + + + + \ No newline at end of file diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitConfiguration.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitConfiguration.java new file mode 100644 index 00000000..e928b9c8 --- /dev/null +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitConfiguration.java @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2019 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/Geyser + */ + +package org.geysermc.platform.bukkit; + +import org.bukkit.configuration.file.FileConfiguration; +import org.geysermc.common.IGeyserConfiguration; + +import java.util.HashMap; +import java.util.Map; + +public class GeyserBukkitConfiguration implements IGeyserConfiguration { + + private FileConfiguration config; + + private BukkitBedrockConfiguration bedrockConfig; + private BukkitRemoteConfiguration remoteConfig; + private BukkitMetricsInfo metricsInfo; + + private Map userAuthInfo = new HashMap<>(); + + public GeyserBukkitConfiguration(FileConfiguration config) { + this.config = config; + + bedrockConfig = new BukkitBedrockConfiguration(); + remoteConfig = new BukkitRemoteConfiguration(); + metricsInfo = new BukkitMetricsInfo(); + + if (!config.contains("userAuths")) + return; + + for (String key : config.getConfigurationSection("userAuths").getKeys(false)) { + userAuthInfo.put(key, new BukkitUserAuthenticationInfo(key)); + } + } + + @Override + public IBedrockConfiguration getBedrock() { + return bedrockConfig; + } + + @Override + public IRemoteConfiguration getRemote() { + return remoteConfig; + } + + @Override + public Map getUserAuths() { + return userAuthInfo; + } + + @Override + public boolean isPingPassthrough() { + return config.getBoolean("ping-passthrough", false); + } + + @Override + public int getMaxPlayers() { + return config.getInt("max-players", 10); + } + + @Override + public boolean isDebugMode() { + return config.getBoolean("debug-mode", false); + } + + @Override + public int getGeneralThreadPool() { + return config.getInt("general-thread-pool", 32); + } + + @Override + public boolean isAllowThirdPartyCapes() { + return config.getBoolean("allow-third-party-capes", true); + } + + @Override + public IMetricsInfo getMetrics() { + return metricsInfo; + } + + public class BukkitBedrockConfiguration implements IBedrockConfiguration { + + @Override + public String getAddress() { + return config.getString("bedrock.address", "0.0.0.0"); + } + + @Override + public int getPort() { + return config.getInt("bedrock.port", 25565); + } + + @Override + public String getMotd1() { + return config.getString("bedrock.motd1", "GeyserMC"); + } + + @Override + public String getMotd2() { + return config.getString("bedrock.motd2", "GeyserMC"); + } + } + + public class BukkitRemoteConfiguration implements IRemoteConfiguration { + + @Override + public String getAddress() { + return config.getString("remote.address", "127.0.0.1"); + } + + @Override + public int getPort() { + return config.getInt("remote.port", 25565); + } + + @Override + public String getAuthType() { + return config.getString("remote.auth-type", "online"); + } + } + + public class BukkitUserAuthenticationInfo implements IUserAuthenticationInfo { + + private String key; + + public BukkitUserAuthenticationInfo(String key) { + this.key = key; + } + + @Override + public String getEmail() { + return config.getString("userAuths." + key + ".email"); + } + + @Override + public String getPassword() { + return config.getString("userAuths." + key + ".password"); + } + } + + public class BukkitMetricsInfo implements IMetricsInfo { + + @Override + public boolean isEnabled() { + return config.getBoolean("metrics.enabled", true); + } + + @Override + public String getUniqueId() { + return config.getString("metrics.uuid", "generateduuid"); + } + } +} diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitLogger.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitLogger.java new file mode 100644 index 00000000..12fadc6c --- /dev/null +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitLogger.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2019 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/Geyser + */ + +package org.geysermc.platform.bukkit; + +import java.util.logging.Level; +import java.util.logging.Logger; + +public class GeyserBukkitLogger implements org.geysermc.api.logger.Logger { + + private Logger logger; + private boolean debugMode; + + public GeyserBukkitLogger(Logger logger, boolean debugMode) { + this.logger = logger; + this.debugMode = debugMode; + } + + @Override + public void severe(String message) { + logger.severe(message); + } + + @Override + public void severe(String message, Throwable error) { + logger.log(Level.SEVERE, message, error); + } + + @Override + public void error(String message) { + logger.warning(message); + } + + @Override + public void error(String message, Throwable error) { + logger.log(Level.WARNING, message, error); + } + + @Override + public void warning(String message) { + error(message); + } + + @Override + public void info(String message) { + logger.info(message); + } + + @Override + public void debug(String message) { + if (debugMode) + info(message); + } + + @Override + public void setDebug(boolean debug) { + debugMode = debug; + } +} diff --git a/connector/src/main/java/org/geysermc/connector/configuration/BedrockConfiguration.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java similarity index 51% rename from connector/src/main/java/org/geysermc/connector/configuration/BedrockConfiguration.java rename to bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java index 2010214e..86dfadbb 100644 --- a/connector/src/main/java/org/geysermc/connector/configuration/BedrockConfiguration.java +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java @@ -23,16 +23,47 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.connector.configuration; +package org.geysermc.platform.bukkit; -import lombok.Getter; +import org.bukkit.plugin.java.JavaPlugin; +import org.geysermc.connector.GeyserConnector; +import org.geysermc.common.bootstrap.IGeyserBootstrap; -@Getter -public class BedrockConfiguration { +import java.util.UUID; - private String address; - private int port; +public class GeyserBukkitPlugin extends JavaPlugin implements IGeyserBootstrap { - private String motd1; - private String motd2; -} \ No newline at end of file + private GeyserBukkitConfiguration geyserConfig; + private GeyserBukkitLogger geyserLogger; + + @Override + public void onEnable() { + saveDefaultConfig(); + + geyserConfig = new GeyserBukkitConfiguration(getConfig()); + + if (geyserConfig.getMetrics().getUniqueId().equals("generateduuid")) { + getConfig().set("metrics.uuid", UUID.randomUUID().toString()); + saveConfig(); + } + + geyserLogger = new GeyserBukkitLogger(getLogger(), geyserConfig.isDebugMode()); + + GeyserConnector.start(this, false); + } + + @Override + public void onDisable() { + GeyserConnector.stop(); + } + + @Override + public GeyserBukkitConfiguration getGeyserConfig() { + return geyserConfig; + } + + @Override + public GeyserBukkitLogger getGeyserLogger() { + return geyserLogger; + } +} diff --git a/bootstrap/bukkit/src/main/resources/plugin.yml b/bootstrap/bukkit/src/main/resources/plugin.yml new file mode 100644 index 00000000..b67547f2 --- /dev/null +++ b/bootstrap/bukkit/src/main/resources/plugin.yml @@ -0,0 +1,5 @@ +main: org.geysermc.platform.bukkit.GeyserBukkitPlugin +name: ${outputName}-Bukkit +author: ${project.organization.name} +website: ${project.organization.url} +version: ${project.version} \ No newline at end of file diff --git a/bootstrap/pom.xml b/bootstrap/pom.xml new file mode 100644 index 00000000..5c91b817 --- /dev/null +++ b/bootstrap/pom.xml @@ -0,0 +1,36 @@ + + + 4.0.0 + + org.geysermc + geyser-parent + parent + ../ + + bootstrap-parent + 1.0-SNAPSHOT + pom + + + spigot-public + https://hub.spigotmc.org/nexus/content/repositories/public/ + + + bukkit-public + https://repo.md-5.net/content/repositories/public/ + + + sponge-repo + https://repo.spongepowered.org/maven + + + + bukkit + + standalone + + + \ No newline at end of file diff --git a/bootstrap/standalone/pom.xml b/bootstrap/standalone/pom.xml new file mode 100644 index 00000000..3c38a6c0 --- /dev/null +++ b/bootstrap/standalone/pom.xml @@ -0,0 +1,63 @@ + + + 4.0.0 + + org.geysermc + bootstrap-parent + 1.0-SNAPSHOT + ../ + + bootstrap-standalone + + + org.geysermc + common + 1.0-SNAPSHOT + compile + + + org.geysermc + connector + 1.0-SNAPSHOT + compile + + + + ${outputName}-noshade + clean install + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.0 + + + + org.geysermc.platform.standalone.GeyserBootstrap + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.1.0 + + + package + + shade + + + + + ${outputName} + false + true + + + + + \ No newline at end of file diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserBootstrap.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserBootstrap.java new file mode 100644 index 00000000..014cf83e --- /dev/null +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserBootstrap.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2019 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/Geyser + */ + +package org.geysermc.platform.standalone; + +import org.fusesource.jansi.AnsiConsole; +import org.geysermc.common.bootstrap.IGeyserBootstrap; +import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.utils.FileUtils; + +import java.io.File; +import java.io.IOException; +import java.util.UUID; + +public class GeyserBootstrap implements IGeyserBootstrap { + + private GeyserConfiguration geyserConfig; + private GeyserLogger geyserLogger; + + public static void main(String[] args) { + new GeyserBootstrap().onEnable(); + } + + @Override + public void onEnable() { + // Metric + if (!(System.console() == null) && System.getProperty("os.name", "Windows 10").toLowerCase().contains("windows")) { + AnsiConsole.systemInstall(); + } + + geyserLogger = new GeyserLogger(); + + try { + File configFile = FileUtils.fileOrCopiedFromResource("config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString())); + geyserConfig = FileUtils.loadConfig(configFile, GeyserConfiguration.class); + } catch (IOException ex) { + getGeyserLogger().severe("Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex); + System.exit(0); + } + + GeyserConnector.start(this, false); + } + + @Override + public void onDisable() { + GeyserConnector.stop(); + System.exit(0); + } + + @Override + public GeyserConfiguration getGeyserConfig() { + return geyserConfig; + } + + @Override + public GeyserLogger getGeyserLogger() { + return geyserLogger; + } +} diff --git a/connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserConfiguration.java similarity index 64% rename from connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java rename to bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserConfiguration.java index b78fc227..e1a442d7 100644 --- a/connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserConfiguration.java @@ -23,17 +23,19 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.connector.configuration; +package org.geysermc.platform.standalone; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; +import org.geysermc.common.IGeyserConfiguration; import java.util.Map; @JsonIgnoreProperties(ignoreUnknown = true) @Getter -public class GeyserConfiguration { +public class GeyserConfiguration implements IGeyserConfiguration { + private BedrockConfiguration bedrock; private RemoteConfiguration remote; @@ -54,5 +56,43 @@ public class GeyserConfiguration { @JsonProperty("allow-third-party-capes") private boolean allowThirdPartyCapes; - private MetricInfo metrics; + private MetricsInfo metrics; + + @Getter + public static class BedrockConfiguration implements IBedrockConfiguration { + + private String address; + private int port; + + private String motd1; + private String motd2; + } + + @Getter + public static class RemoteConfiguration implements IRemoteConfiguration { + + private String address; + private int port; + + private String motd1; + private String motd2; + + @JsonProperty("auth-type") + private String authType; + } + + @Getter + public static class UserAuthenticationInfo implements IUserAuthenticationInfo { + private String email; + private String password; + } + + @Getter + public static class MetricsInfo implements IMetricsInfo { + + private boolean enabled; + + @JsonProperty("uuid") + private String uniqueId; + } } diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserLogger.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserLogger.java new file mode 100644 index 00000000..0df4f1f1 --- /dev/null +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserLogger.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2019 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/Geyser + */ + +package org.geysermc.platform.standalone; + +import io.sentry.Sentry; +import org.geysermc.api.ChatColor; + +import java.io.File; +import java.io.IOException; +import java.util.Date; +import java.util.logging.*; + +public class GeyserLogger implements org.geysermc.api.logger.Logger { + + private boolean colored = true; + private boolean debug = false; + + public GeyserLogger() { + ConsoleHandler consoleHandler = new ConsoleHandler(); + consoleHandler.setLevel(Level.INFO); + consoleHandler.setFormatter(new SimpleFormatter() { + private static final String format = "[%1$tT][%2$-5s] %3$s %n"; + + @Override + public synchronized String format(LogRecord lr) { + return String.format(format, + new Date(lr.getMillis()), + lr.getLevel().getLocalizedName(), + lr.getMessage() + ); + } + }); + + try { + File logDir = new File("logs"); + logDir.mkdir(); + File logFile = new File(logDir, "latest.log"); + int maxLogFileSize = 20;//Mo + if (logFile.exists() && (logFile.length()) > maxLogFileSize * 1024L * 1024L) + this.warning("Your log file is larger than " + maxLogFileSize + "Mo, you should backup and clean it !"); + FileHandler fileHandler = new FileHandler(logFile.getCanonicalPath(), true); + fileHandler.setLevel(Level.INFO); + fileHandler.setFormatter(new SimpleFormatter() { + private static final String format = "[%1$tF %1$tT][%2$-5s] %3$s %n"; + + @Override + public synchronized String format(LogRecord lr) { + return String.format(format, + new Date(lr.getMillis()), + lr.getLevel().getLocalizedName(), + lr.getMessage() + ); + } + }); + } catch (IOException | SecurityException ex) { + Logger.getLogger(GeyserLogger.class.getName()).log(Level.SEVERE, null, ex); + } + + if (System.getenv().containsKey("DP_SENTRY_CLIENT_KEY")) { + Handler sentryHandler = new io.sentry.jul.SentryHandler(); + sentryHandler.setLevel(Level.SEVERE); + Sentry.init(System.getenv().get("DP_SENTRY_CLIENT_KEY")); + } + } + + @Override + public void severe(String message) { + System.out.println(printConsole(ChatColor.DARK_RED + message, colored)); + } + + @Override + public void severe(String message, Throwable error) { + System.out.println(printConsole(ChatColor.DARK_RED + message + "\n" + error.getMessage(), colored)); + } + + @Override + public void error(String message) { + System.out.println(printConsole(ChatColor.RED + message, colored)); + } + + @Override + public void error(String message, Throwable error) { + System.out.println(printConsole(ChatColor.RED + message + "\n" + error, colored)); + } + + @Override + public void warning(String message) { + System.out.println(printConsole(ChatColor.YELLOW + message, colored)); + } + + @Override + public void info(String message) { + System.out.println(printConsole(ChatColor.WHITE + message, colored)); + } + + @Override + public void debug(String message) { + if (debug) + System.out.println(printConsole(ChatColor.GRAY + message, colored)); + } + + public static String printConsole(String message, boolean colors) { + return colors ? ChatColor.toANSI(message + ChatColor.RESET) : ChatColor.stripColors(message + ChatColor.RESET); + } + + @Override + public void setDebug(boolean debug) { + this.debug = debug; + } +} diff --git a/common/pom.xml b/common/pom.xml index 6a0a6ff0..a7f0f258 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -6,52 +6,16 @@ org.geysermc geyser-parent - 1.0-SNAPSHOT + parent + ../ common + 1.0-SNAPSHOT - com.github.steveice10 - opennbt - 1.3-SNAPSHOT - compile - - - com.github.steveice10 - packetlib - 1.4-SNAPSHOT - compile - - - com.github.steveice10 - mcauthlib - 1.1-SNAPSHOT - compile - - - com.github.steveice10 - mcprotocollib - 1.14.4-SNAPSHOT - compile - - - com.github.steveice10 - opennbt - - - com.github.steveice10 - packetlib - - - com.github.steveice10 - mcauthlib - - - - - com.auth0 - java-jwt - 3.3.0 + org.geysermc + api + 1.0-SNAPSHOT compile diff --git a/connector/src/main/java/org/geysermc/connector/configuration/RemoteConfiguration.java b/common/src/main/java/org/geysermc/common/IGeyserConfiguration.java similarity index 56% rename from connector/src/main/java/org/geysermc/connector/configuration/RemoteConfiguration.java rename to common/src/main/java/org/geysermc/common/IGeyserConfiguration.java index 7fcf8a2b..0ea120c5 100644 --- a/connector/src/main/java/org/geysermc/connector/configuration/RemoteConfiguration.java +++ b/common/src/main/java/org/geysermc/common/IGeyserConfiguration.java @@ -23,20 +23,60 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.connector.configuration; +package org.geysermc.common; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Getter; +import java.util.Map; -@Getter -public class RemoteConfiguration { +public interface IGeyserConfiguration { - private String address; - private int port; + IBedrockConfiguration getBedrock(); - private String motd1; - private String motd2; + IRemoteConfiguration getRemote(); - @JsonProperty("auth-type") - private String authType; -} \ No newline at end of file + Map getUserAuths(); + + boolean isPingPassthrough(); + + int getMaxPlayers(); + + boolean isDebugMode(); + + int getGeneralThreadPool(); + + boolean isAllowThirdPartyCapes(); + + IMetricsInfo getMetrics(); + + interface IBedrockConfiguration { + + String getAddress(); + + int getPort(); + + String getMotd1(); + + String getMotd2(); + } + + interface IRemoteConfiguration { + + String getAddress(); + + int getPort(); + + String getAuthType(); + } + + interface IUserAuthenticationInfo { + String getEmail(); + + String getPassword(); + } + + interface IMetricsInfo { + + boolean isEnabled(); + + String getUniqueId(); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/configuration/MetricInfo.java b/common/src/main/java/org/geysermc/common/bootstrap/IGeyserBootstrap.java similarity index 81% rename from connector/src/main/java/org/geysermc/connector/configuration/MetricInfo.java rename to common/src/main/java/org/geysermc/common/bootstrap/IGeyserBootstrap.java index d108d4b4..f41d0a1d 100644 --- a/connector/src/main/java/org/geysermc/connector/configuration/MetricInfo.java +++ b/common/src/main/java/org/geysermc/common/bootstrap/IGeyserBootstrap.java @@ -23,16 +23,18 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.connector.configuration; +package org.geysermc.common.bootstrap; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Getter; +import org.geysermc.api.logger.Logger; +import org.geysermc.common.IGeyserConfiguration; -@Getter -public class MetricInfo { +public interface IGeyserBootstrap { - private boolean enabled; + void onEnable(); - @JsonProperty("uuid") - private String UUID; + void onDisable(); + + IGeyserConfiguration getGeyserConfig(); + + Logger getGeyserLogger(); } diff --git a/connector/pom.xml b/connector/pom.xml index 60ecfc55..c0008f35 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -6,9 +6,11 @@ org.geysermc geyser-parent - 1.0-SNAPSHOT + parent + ../ connector + 1.0-SNAPSHOT org.geysermc @@ -129,30 +131,12 @@ - ${outputName}-noshade - ../target + ${project.artifactId}-${project.version}-noshade - - org.apache.maven.plugins - maven-jar-plugin - - - - org.geysermc.connector.GeyserConnector - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - - ${outputName} - - org.apache.maven.plugins maven-shade-plugin + 3.1.0 package @@ -162,7 +146,6 @@ - ${outputName} true true diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index 4abe763f..215769a2 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -30,15 +30,14 @@ import com.nukkitx.protocol.bedrock.BedrockServer; import com.nukkitx.protocol.bedrock.v388.Bedrock_v388; import lombok.Getter; -import org.fusesource.jansi.AnsiConsole; import org.geysermc.api.Connector; import org.geysermc.api.Geyser; import org.geysermc.api.Player; import org.geysermc.api.command.CommandMap; import org.geysermc.api.logger.Logger; import org.geysermc.api.plugin.Plugin; +import org.geysermc.common.bootstrap.IGeyserBootstrap; import org.geysermc.connector.command.GeyserCommandMap; -import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.console.ConsoleCommandReader; import org.geysermc.connector.console.GeyserLogger; import org.geysermc.connector.metrics.Metrics; @@ -49,17 +48,14 @@ import org.geysermc.connector.network.translators.TranslatorsInit; import org.geysermc.connector.plugin.GeyserPluginLoader; import org.geysermc.connector.plugin.GeyserPluginManager; import org.geysermc.connector.thread.PingPassthroughThread; -import org.geysermc.connector.utils.FileUtils; import org.geysermc.connector.utils.Toolbox; +import org.geysermc.common.IGeyserConfiguration; -import java.io.File; -import java.io.IOException; import java.net.InetSocketAddress; import java.text.DecimalFormat; import java.util.Collection; import java.util.HashMap; import java.util.Map; -import java.util.UUID; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -82,7 +78,7 @@ public class GeyserConnector implements Connector { private CommandMap commandMap; - private GeyserConfiguration config; + private IGeyserConfiguration config; private GeyserPluginManager pluginManager; private boolean shuttingDown = false; @@ -92,21 +88,13 @@ public class GeyserConnector implements Connector { private Metrics metrics; - public static void main(String[] args) { - instance = new GeyserConnector(); - } - - private GeyserConnector() { + private GeyserConnector(IGeyserConfiguration config, Logger logger, boolean loadPlugins) { long startupTime = System.currentTimeMillis(); - // Metric - if (!(System.console() == null) && System.getProperty("os.name", "Windows 10").toLowerCase().contains("windows")) { - AnsiConsole.systemInstall(); - } - instance = this; - this.logger = GeyserLogger.DEFAULT; + this.logger = logger; + GeyserLogger.setLogger(logger); logger.info("******************************************"); logger.info(""); @@ -114,13 +102,7 @@ public class GeyserConnector implements Connector { logger.info(""); logger.info("******************************************"); - try { - File configFile = FileUtils.fileOrCopiedFromResource("config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString())); - config = FileUtils.loadConfig(configFile, GeyserConfiguration.class); - } catch (IOException ex) { - logger.severe("Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex); - shutdown(); - } + this.config = config; this.generalThreadPool = Executors.newScheduledThreadPool(config.getGeneralThreadPool()); ConsoleCommandReader consoleReader = new ConsoleCommandReader(this); @@ -137,7 +119,8 @@ public class GeyserConnector implements Connector { Geyser.setConnector(this); pluginManager = new GeyserPluginManager(new GeyserPluginLoader(this)); - pluginManager.getLoader().loadPlugins(); + if (loadPlugins) + pluginManager.getLoader().loadPlugins(); passthroughThread = new PingPassthroughThread(this); if (config.isPingPassthrough()) @@ -155,7 +138,7 @@ public class GeyserConnector implements Connector { }).join(); if (config.getMetrics().isEnabled()) { - metrics = new Metrics("GeyserMC", config.getMetrics().getUUID(), false, java.util.logging.Logger.getLogger("")); + metrics = new Metrics("GeyserMC", config.getMetrics().getUniqueId(), false, java.util.logging.Logger.getLogger("")); metrics.addCustomChart(new Metrics.SingleLineChart("servers", () -> 1)); metrics.addCustomChart(new Metrics.SingleLineChart("players", Geyser::getPlayerCount)); metrics.addCustomChart(new Metrics.SimplePie("authMode", config.getRemote()::getAuthType)); @@ -180,7 +163,6 @@ public class GeyserConnector implements Connector { shuttingDown = true; generalThreadPool.shutdown(); - System.exit(0); } public void addPlayer(GeyserSession player) { @@ -194,4 +176,12 @@ public class GeyserConnector implements Connector { players.remove(player.getAuthenticationData().getUUID()); players.remove(player.getSocketAddress()); } + + public static void start(IGeyserBootstrap bootstrap, boolean loadPlugins) { + instance = new GeyserConnector(bootstrap.getGeyserConfig(), bootstrap.getGeyserLogger(), loadPlugins); + } + + public static void stop() { + instance.shutdown(); + } } diff --git a/connector/src/main/java/org/geysermc/connector/configuration/UserAuthenticationInfo.java b/connector/src/main/java/org/geysermc/connector/configuration/UserAuthenticationInfo.java deleted file mode 100644 index e8ce1424..00000000 --- a/connector/src/main/java/org/geysermc/connector/configuration/UserAuthenticationInfo.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2019 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/Geyser - */ - -package org.geysermc.connector.configuration; - -public class UserAuthenticationInfo { - public String email; - public String password; -} \ No newline at end of file diff --git a/connector/src/main/java/org/geysermc/connector/console/GeyserLogger.java b/connector/src/main/java/org/geysermc/connector/console/GeyserLogger.java index 7634debc..719667c7 100644 --- a/connector/src/main/java/org/geysermc/connector/console/GeyserLogger.java +++ b/connector/src/main/java/org/geysermc/connector/console/GeyserLogger.java @@ -27,19 +27,21 @@ package org.geysermc.connector.console; import io.sentry.Sentry; import org.geysermc.api.ChatColor; +import org.geysermc.api.logger.Logger; import java.io.File; import java.io.IOException; import java.util.Date; import java.util.logging.*; -public class GeyserLogger implements org.geysermc.api.logger.Logger { +public class GeyserLogger { + public static Logger DEFAULT; + + /* private boolean colored = true; private boolean debug = false; - public static final GeyserLogger DEFAULT = new GeyserLogger(); - private GeyserLogger() { ConsoleHandler consoleHandler = new ConsoleHandler(); consoleHandler.setLevel(Level.INFO); @@ -132,4 +134,14 @@ public class GeyserLogger implements org.geysermc.api.logger.Logger { public void setDebug(boolean debug) { this.debug = debug; } + + */ + + public static String printConsole(String message, boolean colors) { + return colors ? ChatColor.toANSI(message + ChatColor.RESET) : ChatColor.stripColors(message + ChatColor.RESET); + } + + public static void setLogger(Logger logger) { + DEFAULT = logger; + } } diff --git a/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java b/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java index da8c8581..34d36a21 100644 --- a/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java @@ -29,10 +29,9 @@ import com.github.steveice10.mc.protocol.data.status.ServerStatusInfo; import com.nukkitx.protocol.bedrock.BedrockPong; import com.nukkitx.protocol.bedrock.BedrockServerEventHandler; import com.nukkitx.protocol.bedrock.BedrockServerSession; -import org.geysermc.api.Player; import org.geysermc.api.events.PingEvent; +import org.geysermc.common.IGeyserConfiguration; import org.geysermc.connector.GeyserConnector; -import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.console.GeyserLogger; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.utils.MessageUtils; @@ -56,7 +55,7 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler { @Override public BedrockPong onQuery(InetSocketAddress inetSocketAddress) { GeyserLogger.DEFAULT.debug(inetSocketAddress + " has pinged you!"); - GeyserConfiguration config = connector.getConfig(); + IGeyserConfiguration config = connector.getConfig(); PingEvent pongEvent = new PingEvent(inetSocketAddress); pongEvent.setEdition("MCPE"); pongEvent.setGameType("Default"); diff --git a/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java b/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java index 4990280b..d24e0b33 100644 --- a/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java @@ -27,8 +27,8 @@ package org.geysermc.connector.network; import com.nukkitx.protocol.bedrock.BedrockPacket; import com.nukkitx.protocol.bedrock.packet.*; +import org.geysermc.common.IGeyserConfiguration; import org.geysermc.connector.GeyserConnector; -import org.geysermc.connector.configuration.UserAuthenticationInfo; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.Registry; import org.geysermc.connector.utils.LoginEncryptionUtils; @@ -91,11 +91,11 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { private boolean couldLoginUserByName(String bedrockUsername) { if (connector.getConfig().getUserAuths() != null) { - UserAuthenticationInfo info = connector.getConfig().getUserAuths().get(bedrockUsername); + IGeyserConfiguration.IUserAuthenticationInfo info = connector.getConfig().getUserAuths().get(bedrockUsername); if (info != null) { connector.getLogger().info("using stored credentials for bedrock user " + session.getAuthenticationData().getName()); - session.authenticate(info.email, info.password); + session.authenticate(info.getEmail(), info.getPassword()); // TODO send a message to bedrock user telling them they are connected (if nothing like a motd // somes from the Java server w/in a few seconds) diff --git a/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java b/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java index b4c9d7f6..91910c96 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java @@ -7,12 +7,12 @@ import com.nukkitx.protocol.bedrock.data.SerializedSkin; import com.nukkitx.protocol.bedrock.packet.PlayerListPacket; import lombok.AllArgsConstructor; import lombok.Getter; -import org.apache.commons.codec.Charsets; import org.geysermc.api.Geyser; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.entity.PlayerEntity; import org.geysermc.connector.network.session.GeyserSession; +import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.Collections; import java.util.UUID; @@ -80,7 +80,7 @@ public class SkinUtils { try { GameProfile.Property skinProperty = profile.getProperty("textures"); - JsonObject skinObject = SkinProvider.GSON.fromJson(new String(Base64.getDecoder().decode(skinProperty.getValue()), Charsets.UTF_8), JsonObject.class); + JsonObject skinObject = SkinProvider.GSON.fromJson(new String(Base64.getDecoder().decode(skinProperty.getValue()), StandardCharsets.UTF_8), JsonObject.class); JsonObject textures = skinObject.getAsJsonObject("textures"); JsonObject skinTexture = textures.getAsJsonObject("SKIN"); diff --git a/plugin/pom.xml b/plugin/pom.xml deleted file mode 100644 index 9916408b..00000000 --- a/plugin/pom.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - 4.0.0 - - org.geysermc - geyser-parent - 1.0-SNAPSHOT - - plugin - - - - bungeecord-repo - https://oss.sonatype.org/content/repositories/snapshots - - - dosse-repo - https://raw.github.com/JRakNet/WaifUPnP/master/ - - - - - - net.md-5 - bungeecord-api - 1.14-SNAPSHOT - jar - compile - - - com.whirvis - jraknet - 2.11.8 - compile - - - diff --git a/plugin/src/main/java/org/geysermc/plugin/GeyserPlugin.java b/plugin/src/main/java/org/geysermc/plugin/GeyserPlugin.java deleted file mode 100644 index 98950747..00000000 --- a/plugin/src/main/java/org/geysermc/plugin/GeyserPlugin.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.geysermc.plugin; - -import com.whirvis.jraknet.RakNetPacket; -import com.whirvis.jraknet.peer.RakNetClientPeer; -import com.whirvis.jraknet.server.RakNetServer; -import com.whirvis.jraknet.server.RakNetServerListener; -import net.md_5.bungee.api.ProxyServer; -import net.md_5.bungee.api.connection.ConnectedPlayer; -import net.md_5.bungee.api.plugin.Plugin; - -import java.lang.reflect.Field; -import java.net.InetSocketAddress; -import java.util.List; -import java.util.UUID; - -public class GeyserPlugin extends Plugin { - - private List players; - - @SuppressWarnings("unchecked") - @Override - public void onEnable() { - try { - Class clazz = getProxy().getClass(); - Field field = clazz.getDeclaredField("connections"); - field.setAccessible(true); - players = (List) field.get(getProxy()); - } catch (Exception e) { - throw new RuntimeException(e); - } - RakNetServer server = new RakNetServer(new InetSocketAddress("0.0.0.0", 65500), 1000000); - server.addListener(new RakNetServerListener() { - @Override - public void handleMessage(RakNetServer server, RakNetClientPeer peer, RakNetPacket packet, int channel) { - if(packet.getId() == 0) { - } - } - }); - } - private UUID fromXUID(String XUID) { - String one = XUID.substring(0, XUID.length()/2); - String two = XUID.substring(XUID.length()/2, XUID.length()); - long L1 = Long.parseLong(one); - long L2 = Long.parseLong(two); - return new UUID(L1, L2); - } -} diff --git a/pom.xml b/pom.xml index 79b7b5a1..f02c509a 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 org.geysermc geyser-parent - 1.0-SNAPSHOT + parent pom GeyserMC Allows for players from Minecraft Bedrock Edition to join Minecraft Java Edition servers. @@ -32,9 +32,9 @@ api + bootstrap common connector - plugin