diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index bf5972f2f..ce6d76461 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -28,4 +28,4 @@ jobs: if: success() with: name: Geyser - path: target/Geyser.jar + path: bootstrap/standalone/target/Geyser.jar diff --git a/.gitignore b/.gitignore index f003e0142..9b233578c 100644 --- a/.gitignore +++ b/.gitignore @@ -224,3 +224,4 @@ nbdist/ ### Geyser ### config.yml logs/ +public-key.pem diff --git a/Jenkinsfile b/Jenkinsfile index abe22b6f3..ffa4f1bdd 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -15,7 +15,7 @@ pipeline { } post { success { - archiveArtifacts artifacts: 'target/Geyser.jar', fingerprint: true + archiveArtifacts artifacts: 'bootstrap/**/target/*.jar', excludes: 'bootstrap/**/target/original-*.jar', fingerprint: true } } } @@ -28,18 +28,6 @@ pipeline { sh 'mvn javadoc:jar source:jar deploy -DskipTests' } } - - stage ('Javadoc') { - when { - branch "master" - } - steps { - sh 'mvn javadoc:javadoc -DskipTests -pl api' - step([$class: 'JavadocArchiver', - javadocDir: 'api/target/site/apidocs', - keepAll: false]) - } - } } post { diff --git a/README.md b/README.md index ed53e5fe5..1cd56040d 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t ### Currently supporting Minecraft Bedrock v1.14.X and Minecraft Java v1.15.2. ## Setting Up -Please note, Geyser is **not** (currently) a plugin. Watch the video below or take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set it up. +Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set up Geyser. [![YouTube Video](https://img.youtube.com/vi/U7dZZ8w7Gi4/0.jpg)](https://www.youtube.com/watch?v=U7dZZ8w7Gi4) @@ -35,7 +35,6 @@ Please note, Geyser is **not** (currently) a plugin. Watch the video below or ta - Block Particles - Block Entities ([`block-entities`](https://github.com/GeyserMC/Geyser/tree/block-entities)) - Some Entity Flags -- Support to be Ran as a Plugin ([`plugin`](https://github.com/GeyserMC/Geyser/tree/plugin)) ## Compiling 1. Clone the repo to your computer diff --git a/api/pom.xml b/api/pom.xml deleted file mode 100644 index 6d4e1c856..000000000 --- a/api/pom.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - 4.0.0 - - org.geysermc - geyser-parent - 1.0-SNAPSHOT - - api - - - com.google.code.gson - gson - 2.8.2 - compile - - - \ No newline at end of file diff --git a/api/src/main/java/org/geysermc/api/Connector.java b/api/src/main/java/org/geysermc/api/Connector.java deleted file mode 100644 index 708372e33..000000000 --- a/api/src/main/java/org/geysermc/api/Connector.java +++ /dev/null @@ -1,76 +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.api; - -import org.geysermc.api.command.CommandMap; -import org.geysermc.api.logger.Logger; -import org.geysermc.api.plugin.PluginManager; - -import java.util.Collection; -import java.util.concurrent.ScheduledExecutorService; - -public interface Connector { - - /** - * Returns the logger - * - * @return the logger - */ - Logger getLogger(); - - /** - * Returns the command map - * - * @return the command map - */ - CommandMap getCommandMap(); - - /** - * Returns the plugin manager - * - * @return the plugin manager - */ - PluginManager getPluginManager(); - - /** - * Returns the general thread pool - * - * @return the general thread pool - */ - ScheduledExecutorService getGeneralThreadPool(); - - /** - * Returns a collection of the connected players - * - * @return a collection of the connected players - */ - Collection getConnectedPlayers(); - - /** - * Shuts down the connector - */ - void shutdown(); -} diff --git a/api/src/main/java/org/geysermc/api/ConsoleColors.java b/api/src/main/java/org/geysermc/api/ConsoleColors.java deleted file mode 100644 index a59512275..000000000 --- a/api/src/main/java/org/geysermc/api/ConsoleColors.java +++ /dev/null @@ -1,69 +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.api; - -public class ConsoleColors { - public static final String RESET = "\u001b[0m"; - - public static final String BOLD = "\u001b[1m"; - public static final String BLINK = "\u001b[5m"; - - public static final String WHITE = "\u001b[30m"; - public static final String RED = "\u001b[31m"; - public static final String GREEN = "\u001b[32m"; - public static final String YELLOW = "\u001b[33m"; - public static final String BLUE = "\u001b[34m"; - public static final String MAGENTA = "\u001b[35m"; - public static final String CYAN = "\u001b[36m"; - public static final String LIGHT_GRAY = "\u001b[37m"; - - public static final String DARK_GRAY = "\u001b[90m"; - public static final String BRIGHT_RED = "\u001b[91m"; - public static final String BRIGHT_GREEN = "\u001b[92m"; - public static final String BRIGHT_YELLOW = "\u001b[93m"; - public static final String BRIGHT_BLUE = "\u001b[94m"; - public static final String BRIGHT_MAGENTA = "\u001b[95m"; - public static final String BRIGHT_CYAN = "\u001b[96m"; - public static final String BLACK = "\u001b[97m"; - - public static final String BLACK_BACKGROUND = "\u001b[30m"; - public static final String RED_BACKGROUND = "\u001b[31m"; - public static final String GREEN_BACKGROUND = "\u001b[32m"; - public static final String YELLOW_BACKGROUND = "\u001b[33m"; - public static final String BLUE_BACKGROUND = "\u001b[34m"; - public static final String MAGENTA_BACKGROUND = "\u001b[35m"; - public static final String CYAN_BACKGROUND = "\u001b[36m"; - public static final String WHITE_BACKGROUND = "\u001b[37m"; - - /*public static final String BLACK_BACKGROUND = "\u001b[30m"; - public static final String RED_BACKGROUND = "\u001b[31m"; - public static final String GREEN_BACKGROUND = "\u001b[32m"; - public static final String YELLOW_BACKGROUND = "\u001b[33m"; - public static final String BLUE_BACKGROUND = "\u001b[34m"; - public static final String MAGENTA_BACKGROUND = "\u001b[35m"; - public static final String CYAN_BACKGROUND = "\u001b[36m"; - public static final String WHITE_BACKGROUND = "\u001b[37m";*/ -} diff --git a/api/src/main/java/org/geysermc/api/Geyser.java b/api/src/main/java/org/geysermc/api/Geyser.java deleted file mode 100644 index 2fc9c190e..000000000 --- a/api/src/main/java/org/geysermc/api/Geyser.java +++ /dev/null @@ -1,103 +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.api; - -import org.geysermc.api.command.CommandMap; -import org.geysermc.api.logger.Logger; -import org.geysermc.api.plugin.PluginManager; - -import java.util.Collection; -import java.util.concurrent.ScheduledExecutorService; - -public class Geyser { - - private static Connector connector; - - /** - * Returns the connector instance for Geyser - * - * @return the connector instance for Geyser - */ - public static Connector getConnector() { - return connector; - } - - /** - * Sets the connector instance for Geyser - * - * @param connector the connector instance - */ - public static void setConnector(Connector connector) { - Geyser.connector = connector; - } - - /** - * Returns the logger - * - * @return the logger - */ - public static Logger getLogger() { - return connector.getLogger(); - } - - /** - * Returns the plugin manager - * - * @return the plugin manager - */ - public static PluginManager getPluginManager() { - return connector.getPluginManager(); - } - - /** - * Returns the command map - * - * @return the command map - */ - public static CommandMap getCommandMap() { - return connector.getCommandMap(); - } - - public static ScheduledExecutorService getGeneralThreadPool() { - return connector.getGeneralThreadPool(); - } - - /** - * @return the amount of online players - */ - public static int getPlayerCount() { - return connector.getConnectedPlayers().size(); - } - - /** - * Returns a collection of the connected players - * - * @return a collection of the connected players - */ - public static Collection getConnectedPlayers() { - return connector.getConnectedPlayers(); - } -} diff --git a/api/src/main/java/org/geysermc/api/Player.java b/api/src/main/java/org/geysermc/api/Player.java deleted file mode 100644 index f8107cb1d..000000000 --- a/api/src/main/java/org/geysermc/api/Player.java +++ /dev/null @@ -1,80 +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.api; - -import org.geysermc.api.command.CommandSender; -import org.geysermc.api.session.AuthData; -import org.geysermc.api.window.FormWindow; - -import java.net.InetSocketAddress; - -public interface Player extends CommandSender { - - /** - * Connects the player to the remote server - * - * @param remoteServer the remote server to connect to - */ - void connect(RemoteServer remoteServer); - - /** - * Disconnect the player for the specified reason - * - * @param reason the reason to disconnect the player for - */ - void disconnect(String reason); - - /** - * Returns the authentication data of the player. This is not the - * player's Minecraft credentials; it's simply what is given to the server - * (Name, UUID, Xbox UUID) to verify the player can/actually exists. - * - * @return the authentication data of the player - */ - AuthData getAuthenticationData(); - - /** - * Sends a form window - * - * @param window the window form to send - */ - void sendForm(FormWindow window); - - /** - * Sends a form window with the given ID - * - * @param window the window to send - * @param id the id of the window - */ - void sendForm(FormWindow window, int id); - - /** - * Returns the current hostname and port the player is connected with. - * - * @return player's socket address. - */ - InetSocketAddress getSocketAddress(); -} diff --git a/api/src/main/java/org/geysermc/api/RemoteServer.java b/api/src/main/java/org/geysermc/api/RemoteServer.java deleted file mode 100644 index 8004cbd16..000000000 --- a/api/src/main/java/org/geysermc/api/RemoteServer.java +++ /dev/null @@ -1,43 +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.api; - -public interface RemoteServer { - - /** - * Returns the IP address of the remote server - * - * @return the IP address of the remote server - */ - String getAddress(); - - /** - * Returns the port of the remote server - * - * @return the port of the remote server - */ - int getPort(); -} diff --git a/api/src/main/java/org/geysermc/api/command/Command.java b/api/src/main/java/org/geysermc/api/command/Command.java deleted file mode 100644 index ed9daf649..000000000 --- a/api/src/main/java/org/geysermc/api/command/Command.java +++ /dev/null @@ -1,67 +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.api.command; - -import java.util.List; - -public interface Command { - - /** - * Returns the name of this command - * - * @return the name of this command - */ - String getName(); - - /** - * Returns the description of this command - * - * @return the description of this command - */ - String getDescription(); - - /** - * Returns the aliases of this command - * - * @return the aliases of this command - */ - List getAliases(); - - /** - * Sets the aliases of this command - * - * @param aliases the a liases of the command - */ - void setAliases(List aliases); - - /** - * Executes the command - * - * @param sender the sender of the command - * @param args the arguments of the command - */ - void execute(CommandSender sender, String[] args); -} diff --git a/api/src/main/java/org/geysermc/api/command/CommandMap.java b/api/src/main/java/org/geysermc/api/command/CommandMap.java deleted file mode 100644 index d9dd098c6..000000000 --- a/api/src/main/java/org/geysermc/api/command/CommandMap.java +++ /dev/null @@ -1,53 +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.api.command; - -import java.util.Map; - -public interface CommandMap { - - /** - * Registers a new command - * - * @param command the command to register - */ - void registerCommand(Command command); - - /** - * Runs a command for the given command sender - * - * @param sender the sender to run the command for - * @param command the command to run - */ - void runCommand(CommandSender sender, String command); - - /** - * Returns a map of the commands - * - * @return a map of the commands - */ - Map getCommands(); -} diff --git a/api/src/main/java/org/geysermc/api/command/CommandSender.java b/api/src/main/java/org/geysermc/api/command/CommandSender.java deleted file mode 100644 index 77f397f7f..000000000 --- a/api/src/main/java/org/geysermc/api/command/CommandSender.java +++ /dev/null @@ -1,50 +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.api.command; - -public interface CommandSender { - - /** - * Returns the name of the sender - * - * @return the name of the sender - */ - String getName(); - - /** - * Sends a message to the command sender - * - * @param message the message to be sent - */ - void sendMessage(String message); - - /** - * Sends multiple messages to the command sender - * - * @param messages the messages to be sent - */ - void sendMessage(String[] messages); -} diff --git a/api/src/main/java/org/geysermc/api/command/ConsoleCommandSender.java b/api/src/main/java/org/geysermc/api/command/ConsoleCommandSender.java deleted file mode 100644 index b04f0999e..000000000 --- a/api/src/main/java/org/geysermc/api/command/ConsoleCommandSender.java +++ /dev/null @@ -1,30 +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.api.command; - -public interface ConsoleCommandSender extends CommandSender { - -} diff --git a/api/src/main/java/org/geysermc/api/events/EventHandler.java b/api/src/main/java/org/geysermc/api/events/EventHandler.java deleted file mode 100644 index d25c14ff1..000000000 --- a/api/src/main/java/org/geysermc/api/events/EventHandler.java +++ /dev/null @@ -1,56 +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.api.events; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * The annotation to put on all methods that are events. - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface EventHandler { - - /** - * @return the order to execute events. - * @see EventPriority - */ - EventPriority value() default EventPriority.NORMAL; - - /** - * When an eventHandler should be run. - * The names mostly explain. - */ - enum EventPriority { - FIRST, - NORMAL, - LAST, - READ_ONLY; - } -} diff --git a/api/src/main/java/org/geysermc/api/events/Listener.java b/api/src/main/java/org/geysermc/api/events/Listener.java deleted file mode 100644 index 3288c6821..000000000 --- a/api/src/main/java/org/geysermc/api/events/Listener.java +++ /dev/null @@ -1,33 +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.api.events; - -/** - * A marker class which says that a specific class uses events. - * @see EventHandler - */ -public interface Listener { -} diff --git a/api/src/main/java/org/geysermc/api/events/player/PlayerEvent.java b/api/src/main/java/org/geysermc/api/events/player/PlayerEvent.java deleted file mode 100644 index ab4e98a61..000000000 --- a/api/src/main/java/org/geysermc/api/events/player/PlayerEvent.java +++ /dev/null @@ -1,39 +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.api.events.player; - -import lombok.Getter; -import org.geysermc.api.Player; - -public class PlayerEvent { - - @Getter - private Player player; - - public PlayerEvent(Player player) { - this.player = player; - } -} diff --git a/api/src/main/java/org/geysermc/api/plugin/PluginManager.java b/api/src/main/java/org/geysermc/api/plugin/PluginManager.java deleted file mode 100644 index 2cc183046..000000000 --- a/api/src/main/java/org/geysermc/api/plugin/PluginManager.java +++ /dev/null @@ -1,87 +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.api.plugin; - -import org.geysermc.api.events.Listener; - -import java.util.Set; - -public interface PluginManager { - - /** - * Loads a plugin and all its class files - * - * @param plugin the plugin to load - */ - void loadPlugin(Plugin plugin); - - /** - * Enables a plugin - * - * @param plugin the plugin to enable - */ - void enablePlugin(Plugin plugin); - - /** - * Disables a plugin - * - * @param plugin the plugin to disable - */ - void disablePlugin(Plugin plugin); - - /** - * Unloads a plugin - * - * @param plugin the plugin to unload - */ - void unloadPlugin(Plugin plugin); - - /** - * Returns a set of the loaded plugins - * - * @return a set of the loaded plugins - */ - Set getPlugins(); - - /** - * @param name The name of the plugin you want to get. - * @return The plugin with the String name in the parameters. - */ - Plugin getPluginByName(String name); - - /** - * Registers a listener to be run when an event is executed - * @param plugin the plugin registering the listener - * @param listener the listener which will contain the event methods - */ - void registerEventListener(Plugin plugin, Listener listener); - - /** - * Run an event - * @param o the event object. - */ - void runEvent(Object o); -} diff --git a/bootstrap/bukkit/pom.xml b/bootstrap/bukkit/pom.xml new file mode 100644 index 000000000..0f4d32885 --- /dev/null +++ b/bootstrap/bukkit/pom.xml @@ -0,0 +1,76 @@ + + + 4.0.0 + + org.geysermc + bootstrap-parent + 1.0-SNAPSHOT + ../ + + bootstrap-bukkit + + + org.geysermc + connector + 1.0-SNAPSHOT + compile + + + org.spigotmc + spigot-api + 1.14-R0.1-SNAPSHOT + provided + + + + ${outputName}-Bukkit + + + src/main/resources/ + true + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.1 + + + package + + shade + + + + + io.netty + org.geysermc.platform.bukkit.shaded.netty + + + true + + + + + + + *:* + + META-INF/* + + + + + + com.google.code.gson:* + org.yaml:* + + + + + + + \ 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 000000000..e38a982db --- /dev/null +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitConfiguration.java @@ -0,0 +1,186 @@ +/* + * 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.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; + +public class GeyserBukkitConfiguration implements IGeyserConfiguration { + + private FileConfiguration config; + private File dataFolder; + + private BukkitBedrockConfiguration bedrockConfig; + private BukkitRemoteConfiguration remoteConfig; + private BukkitMetricsInfo metricsInfo; + + private Map userAuthInfo = new HashMap<>(); + + public GeyserBukkitConfiguration(File dataFolder, FileConfiguration config) { + this.dataFolder = dataFolder; + 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 Path getFloodgateKeyFile() { + return Paths.get(dataFolder.toString(), config.getString("floodgate-key-file", "public-key.pem")); + } + + @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 000000000..05fd2c6c8 --- /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 lombok.AllArgsConstructor; + +import org.geysermc.common.logger.IGeyserLogger; + +import java.util.logging.Level; +import java.util.logging.Logger; + +@AllArgsConstructor +public class GeyserBukkitLogger implements IGeyserLogger { + + private Logger logger; + private boolean 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/api/src/main/java/org/geysermc/api/events/player/PlayerFormResponseEvent.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java similarity index 50% rename from api/src/main/java/org/geysermc/api/events/player/PlayerFormResponseEvent.java rename to bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java index b68170b2a..21f130da3 100644 --- a/api/src/main/java/org/geysermc/api/events/player/PlayerFormResponseEvent.java +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java @@ -23,54 +23,48 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.events.player; +package org.geysermc.platform.bukkit; -import lombok.Getter; -import org.geysermc.api.Player; -import org.geysermc.api.window.FormWindow; -import org.geysermc.api.window.response.FormResponse; +import org.bukkit.plugin.java.JavaPlugin; +import org.geysermc.common.PlatformType; +import org.geysermc.connector.GeyserConnector; +import org.geysermc.common.bootstrap.IGeyserBootstrap; -/** - * Called when a player interacts with a form - */ -public class PlayerFormResponseEvent extends PlayerEvent { +import java.util.UUID; - @Getter - private int formID; +public class GeyserBukkitPlugin extends JavaPlugin implements IGeyserBootstrap { - @Getter - private FormWindow window; + private GeyserBukkitConfiguration geyserConfig; + private GeyserBukkitLogger geyserLogger; - /** - * Constructs a new PlayerFormResponseEvent instance - * - * @param player the player interacting with the form - * @param formID the id of the form - * @param window the window - */ - public PlayerFormResponseEvent(Player player, int formID, FormWindow window) { - super(player); + @Override + public void onEnable() { + saveDefaultConfig(); - this.formID = formID; - this.window = window; + geyserConfig = new GeyserBukkitConfiguration(getDataFolder(), getConfig()); + + if (geyserConfig.getMetrics().getUniqueId().equals("generateduuid")) { + getConfig().set("metrics.uuid", UUID.randomUUID().toString()); + saveConfig(); + } + + geyserLogger = new GeyserBukkitLogger(getLogger(), geyserConfig.isDebugMode()); + + GeyserConnector.start(PlatformType.BUKKIT, this); } - /** - * Returns the response of the window, can be null - * if the player closed the window - * - * @return the response of the window - */ - public FormResponse getResponse() { - return window.getResponse(); + @Override + public void onDisable() { + GeyserConnector.stop(); } - /** - * Returns if the window is closed - * - * @return if the window is closed - */ - public boolean isClosed() { - return window.isClosed(); + @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 000000000..b67547f25 --- /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/bungeecord/pom.xml b/bootstrap/bungeecord/pom.xml new file mode 100644 index 000000000..317e80cb5 --- /dev/null +++ b/bootstrap/bungeecord/pom.xml @@ -0,0 +1,80 @@ + + + 4.0.0 + + org.geysermc + bootstrap-parent + 1.0-SNAPSHOT + ../ + + bootstrap-bungeecord + + + org.geysermc + connector + 1.0-SNAPSHOT + compile + + + net.md-5 + bungeecord-api + 1.14-SNAPSHOT + provided + + + + ${outputName}-BungeeCord + + + src/main/resources/ + true + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.1 + + + package + + shade + + + + + net.md_5.bungee.jni + org.geysermc.platform.bungeecord.shaded.jni + + + io.netty + org.geysermc.platform.bungeecord.shaded.netty + + + true + + + + + + + *:* + + META-INF/* + + + + + + com.google.code.gson:* + org.yaml:* + + + + + + + \ No newline at end of file diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeConfiguration.java b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeConfiguration.java new file mode 100644 index 000000000..94580e583 --- /dev/null +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeConfiguration.java @@ -0,0 +1,187 @@ +/* + * 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.bungeecord; + +import net.md_5.bungee.config.Configuration; + +import org.geysermc.common.IGeyserConfiguration; + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; + +public class GeyserBungeeConfiguration implements IGeyserConfiguration { + + private File dataFolder; + private Configuration config; + + private BungeeBedrockConfiguration bedrockConfig; + private BungeeRemoteConfiguration remoteConfig; + private BungeeMetricsInfo metricsInfo; + + private Map userAuthInfo = new HashMap<>(); + + public GeyserBungeeConfiguration(File dataFolder, Configuration config) { + this.dataFolder = dataFolder; + this.config = config; + + bedrockConfig = new BungeeBedrockConfiguration(); + remoteConfig = new BungeeRemoteConfiguration(); + metricsInfo = new BungeeMetricsInfo(); + + if (!config.contains("userAuths")) + return; + + for (String key : config.getSection("userAuths").getKeys()) { + userAuthInfo.put(key, new BungeeUserAuthenticationInfo(key)); + } + } + + @Override + public BungeeBedrockConfiguration getBedrock() { + return bedrockConfig; + } + + @Override + public BungeeRemoteConfiguration 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 Path getFloodgateKeyFile() { + return Paths.get(dataFolder.toString(), config.getString("floodgate-key-file", "public-key.pem")); + } + + @Override + public BungeeMetricsInfo getMetrics() { + return metricsInfo; + } + + public class BungeeBedrockConfiguration 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 BungeeRemoteConfiguration 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 BungeeUserAuthenticationInfo implements IUserAuthenticationInfo { + + private String key; + + public BungeeUserAuthenticationInfo(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 BungeeMetricsInfo 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/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeLogger.java b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeLogger.java new file mode 100644 index 000000000..2ebc069b1 --- /dev/null +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeLogger.java @@ -0,0 +1,83 @@ +/* + * 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.bungeecord; + +import org.geysermc.common.logger.IGeyserLogger; + +import java.util.logging.Level; +import java.util.logging.Logger; + +public class GeyserBungeeLogger implements IGeyserLogger { + + private Logger logger; + private boolean debugMode; + + public GeyserBungeeLogger(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/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java new file mode 100644 index 000000000..b396ede5d --- /dev/null +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java @@ -0,0 +1,107 @@ +/* + * 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.bungeecord; + +import net.md_5.bungee.api.plugin.Plugin; +import net.md_5.bungee.config.Configuration; +import net.md_5.bungee.config.ConfigurationProvider; +import net.md_5.bungee.config.YamlConfiguration; + +import org.geysermc.common.PlatformType; +import org.geysermc.connector.GeyserConnector; +import org.geysermc.common.bootstrap.IGeyserBootstrap; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.util.UUID; +import java.util.logging.Level; + +public class GeyserBungeePlugin extends Plugin implements IGeyserBootstrap { + + private GeyserBungeeConfiguration geyserConfig; + private GeyserBungeeLogger geyserLogger; + + @Override + public void onEnable() { + if (!getDataFolder().exists()) + getDataFolder().mkdir(); + + File file = new File(getDataFolder(), "config.yml"); + Configuration configuration = null; + + if (!file.exists()) { + try (InputStream in = getResourceAsStream("config.yml")) { + Files.copy(in, file.toPath()); + } catch (IOException ex) { + getLogger().log(Level.SEVERE, "Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex); + return; + } + } + try { + configuration = ConfigurationProvider.getProvider(YamlConfiguration.class).load(new File(getDataFolder(), "config.yml")); + } catch(IOException e) { + e.printStackTrace(); + } + + if (configuration == null) { + getLogger().severe("Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!"); + return; + } + + geyserConfig = new GeyserBungeeConfiguration(getDataFolder(), configuration); + + if (geyserConfig.getMetrics().getUniqueId().equals("generateduuid")) { + configuration.set("metrics.uuid", UUID.randomUUID().toString()); + try { + ConfigurationProvider.getProvider(YamlConfiguration.class).save(configuration, new File(getDataFolder(), "config.yml")); + } catch (IOException ex) { + getLogger().log(Level.SEVERE, "Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex); + return; + } + } + + geyserLogger = new GeyserBungeeLogger(getLogger(), geyserConfig.isDebugMode()); + + GeyserConnector.start(PlatformType.BUNGEECORD, this); + } + + @Override + public void onDisable() { + GeyserConnector.stop(); + } + + @Override + public GeyserBungeeConfiguration getGeyserConfig() { + return geyserConfig; + } + + @Override + public GeyserBungeeLogger getGeyserLogger() { + return geyserLogger; + } +} diff --git a/bootstrap/bungeecord/src/main/resources/bungee.yml b/bootstrap/bungeecord/src/main/resources/bungee.yml new file mode 100644 index 000000000..8781ea31b --- /dev/null +++ b/bootstrap/bungeecord/src/main/resources/bungee.yml @@ -0,0 +1,5 @@ +main: org.geysermc.platform.bungeecord.GeyserBungeePlugin +name: ${outputName}-BungeeCord +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 000000000..6d12b6732 --- /dev/null +++ b/bootstrap/pom.xml @@ -0,0 +1,44 @@ + + + 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 + + + bungeecord-repo + https://oss.sonatype.org/content/repositories/snapshots + + + velocity-repo + https://repo.velocitypowered.com/snapshots/ + + + + bukkit + bungeecord + sponge + standalone + velocity + + \ No newline at end of file diff --git a/bootstrap/sponge/pom.xml b/bootstrap/sponge/pom.xml new file mode 100644 index 000000000..1b1dd8e94 --- /dev/null +++ b/bootstrap/sponge/pom.xml @@ -0,0 +1,83 @@ + + + 4.0.0 + + org.geysermc + bootstrap-parent + 1.0-SNAPSHOT + ../ + + bootstrap-sponge + + + org.geysermc + connector + 1.0-SNAPSHOT + compile + + + org.spongepowered + spongeapi + 7.1.0 + provided + + + + ${outputName}-Sponge + + + src/main/resources/ + true + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.1 + + + package + + shade + + + + + com.fasterxml.jackson + org.geysermc.platform.sponge.shaded.jackson + + + io.netty + org.geysermc.platform.sponge.shaded.netty + + + true + + + + + + + *:* + + META-INF/* + + + + + + com.google.code.gson:* + org.yaml:* + com.nukkitx:fastutil-lite:* + org.slf4j:* + org.ow2.asm:* + + + + + + + \ No newline at end of file diff --git a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeConfiguration.java b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeConfiguration.java new file mode 100644 index 000000000..dbc83fbea --- /dev/null +++ b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeConfiguration.java @@ -0,0 +1,196 @@ +/* + * 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.sponge; + +import lombok.AllArgsConstructor; + +import ninja.leaping.configurate.ConfigurationNode; + +import org.geysermc.common.IGeyserConfiguration; + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class GeyserSpongeConfiguration implements IGeyserConfiguration { + + private File dataFolder; + private ConfigurationNode node; + + private SpongeBedrockConfiguration bedrockConfig; + private SpongeRemoteConfiguration remoteConfig; + private SpongeMetricsInfo metricsInfo; + + private Map userAuthInfo = new HashMap<>(); + + public GeyserSpongeConfiguration(File dataFolder, ConfigurationNode node) { + this.dataFolder = dataFolder; + this.node = node; + + this.bedrockConfig = new SpongeBedrockConfiguration(node.getNode("bedrock")); + this.remoteConfig = new SpongeRemoteConfiguration(node.getNode("remote")); + this.metricsInfo = new SpongeMetricsInfo(); + + if (node.getNode("userAuths").getValue() == null) + return; + + for (String key : (List) node.getNode("userAuths").getValue()) { + userAuthInfo.put(key, new SpongeUserAuthenticationInfo(key)); + } + } + + @Override + public SpongeBedrockConfiguration getBedrock() { + return bedrockConfig; + } + + @Override + public SpongeRemoteConfiguration getRemote() { + return remoteConfig; + } + + @Override + public Map getUserAuths() { + return userAuthInfo; + } + + @Override + public boolean isPingPassthrough() { + return node.getNode("ping-passthrough").getBoolean(false); + } + + @Override + public int getMaxPlayers() { + return node.getNode("max-players").getInt(100); + } + + @Override + public boolean isDebugMode() { + return node.getNode("debug-mode").getBoolean(false); + } + + @Override + public int getGeneralThreadPool() { + return node.getNode("genereal-thread-pool").getInt(32); + } + + @Override + public boolean isAllowThirdPartyCapes() { + return node.getNode("allow-third-party-capes").getBoolean(true); + } + + @Override + public Path getFloodgateKeyFile() { + return Paths.get(dataFolder.toString(), node.getNode("floodgate-key-file").getString("public-key.pem")); + } + + @Override + public SpongeMetricsInfo getMetrics() { + return metricsInfo; + } + + @AllArgsConstructor + public class SpongeBedrockConfiguration implements IBedrockConfiguration { + + private ConfigurationNode node; + + @Override + public String getAddress() { + return node.getNode("address").getString("0.0.0.0"); + } + + @Override + public int getPort() { + return node.getNode("port").getInt(19132); + } + + @Override + public String getMotd1() { + return node.getNode("motd1").getString("GeyserMC"); + } + + @Override + public String getMotd2() { + return node.getNode("motd2").getString("GeyserMC"); + } + } + + @AllArgsConstructor + public class SpongeRemoteConfiguration implements IRemoteConfiguration { + + private ConfigurationNode node; + + @Override + public String getAddress() { + return node.getNode("address").getString("127.0.0.1"); + } + + @Override + public int getPort() { + return node.getNode("port").getInt(25565); + } + + @Override + public String getAuthType() { + return node.getNode("auth-type").getString("online"); + } + } + + public class SpongeUserAuthenticationInfo implements IUserAuthenticationInfo { + + private String key; + + public SpongeUserAuthenticationInfo(String key) { + this.key = key; + } + + @Override + public String getEmail() { + return node.getNode("userAuths").getNode(key).getNode("email").getString(); + } + + @Override + public String getPassword() { + return node.getNode("userAuths").getNode(key).getNode("password").getString(); + } + } + + public class SpongeMetricsInfo implements IMetricsInfo { + + @Override + public boolean isEnabled() { + return node.getNode("metrics").getNode("enabled").getBoolean(true); + } + + @Override + public String getUniqueId() { + return node.getNode("metrics").getNode("uuid").getString("generateduuid"); + } + } +} diff --git a/api/src/main/java/org/geysermc/api/events/PingEvent.java b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeLogger.java similarity index 52% rename from api/src/main/java/org/geysermc/api/events/PingEvent.java rename to bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeLogger.java index 541657d81..1df7fbf9b 100644 --- a/api/src/main/java/org/geysermc/api/events/PingEvent.java +++ b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeLogger.java @@ -23,31 +23,57 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.events; +package org.geysermc.platform.sponge; -import lombok.Getter; -import lombok.Setter; +import lombok.AllArgsConstructor; -import java.net.InetSocketAddress; +import org.geysermc.common.logger.IGeyserLogger; +import org.slf4j.Logger; -@Getter -@Setter -public class PingEvent { +@AllArgsConstructor +public class GeyserSpongeLogger implements IGeyserLogger { - public PingEvent(InetSocketAddress address) { - this.address = address; + private Logger logger; + private boolean debugMode; + + @Override + public void severe(String message) { + logger.error(message); } - private InetSocketAddress address; + @Override + public void severe(String message, Throwable error) { + logger.error(message, error); + } - private String edition; - private String motd; - private int protocolVersion; - private String version; - private int playerCount; - private int maximumPlayerCount; - private long serverId; - private String subMotd; - private String gameType; - private boolean nintendoLimited; + @Override + public void error(String message) { + logger.error(message); + } + + @Override + public void error(String message, Throwable error) { + logger.error(message, error); + } + + @Override + public void warning(String message) { + logger.warn(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 debugMode) { + this.debugMode = debugMode; + } } diff --git a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java new file mode 100644 index 000000000..15ab0d1fe --- /dev/null +++ b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java @@ -0,0 +1,112 @@ +/* + * 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.sponge; + +import com.google.inject.Inject; + +import ninja.leaping.configurate.loader.ConfigurationLoader; +import ninja.leaping.configurate.yaml.YAMLConfigurationLoader; + +import org.geysermc.common.PlatformType; +import org.geysermc.common.bootstrap.IGeyserBootstrap; +import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.utils.FileUtils; +import org.slf4j.Logger; +import org.spongepowered.api.config.ConfigDir; +import org.spongepowered.api.event.Listener; +import org.spongepowered.api.event.game.state.GameStartedServerEvent; +import org.spongepowered.api.event.game.state.GameStoppedEvent; +import org.spongepowered.api.plugin.Plugin; + +import java.io.File; +import java.io.IOException; +import java.util.UUID; + +@Plugin(id = "geyser", name = GeyserConnector.NAME + "-Sponge", version = GeyserConnector.VERSION, url = "https://geysermc.org", authors = "GeyserMC") +public class GeyserSpongePlugin implements IGeyserBootstrap { + + @Inject + private Logger logger; + + @Inject + @ConfigDir(sharedRoot = false) + private File configDir; + + private GeyserSpongeConfiguration geyserConfig; + private GeyserSpongeLogger geyserLogger; + + @Override + public void onEnable() { + if (!configDir.exists()) + configDir.mkdirs(); + + File configFile = null; + try { + configFile = FileUtils.fileOrCopiedFromResource(new File(configDir, "config.yml"), "config.yml", (file) -> file.replaceAll("generateduuid", UUID.randomUUID().toString())); + } catch (IOException ex) { + logger.warn("Failed to copy config.yml from jar path!"); + ex.printStackTrace(); + } + + ConfigurationLoader loader = YAMLConfigurationLoader.builder().setPath(configFile.toPath()).build(); + try { + this.geyserConfig = new GeyserSpongeConfiguration(configDir, loader.load()); + } catch (IOException ex) { + logger.warn("Failed to load config.yml!"); + ex.printStackTrace(); + return; + } + + this.geyserLogger = new GeyserSpongeLogger(logger, geyserConfig.isDebugMode()); + + GeyserConnector.start(PlatformType.SPONGE, this); + } + + @Override + public void onDisable() { + GeyserConnector.stop(); + } + + @Override + public GeyserSpongeConfiguration getGeyserConfig() { + return geyserConfig; + } + + @Override + public GeyserSpongeLogger getGeyserLogger() { + return geyserLogger; + } + + @Listener + public void onServerStart(GameStartedServerEvent event) { + onEnable(); + } + + @Listener + public void onServerStop(GameStoppedEvent event) { + onDisable(); + } +} diff --git a/bootstrap/standalone/pom.xml b/bootstrap/standalone/pom.xml new file mode 100644 index 000000000..7c271339a --- /dev/null +++ b/bootstrap/standalone/pom.xml @@ -0,0 +1,133 @@ + + + 4.0.0 + + org.geysermc + bootstrap-parent + 1.0-SNAPSHOT + ../ + + bootstrap-standalone + + + org.geysermc + connector + 1.0-SNAPSHOT + compile + + + net.minecrell + terminalconsoleappender + 1.1.1 + + + org.apache.logging.log4j + log4j-core + + + org.jline + jline-reader + + + org.jline + jline-terminal-jna + + + org.jline + jline-terminal + + + + + org.jline + jline-terminal + 3.9.0 + + + org.jline + jline-terminal-jna + 3.9.0 + + + org.jline + jline-reader + 3.9.0 + + + org.apache.logging.log4j + log4j-api + 2.13.1 + + + org.apache.logging.log4j + log4j-core + 2.13.1 + + + org.apache.logging.log4j + log4j-slf4j18-impl + 2.13.1 + + + + ${outputName} + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.0 + + + + org.geysermc.platform.standalone.GeyserBootstrap + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.1 + + + com.github.edwgiz + maven-shade-plugin.log4j2-cachefile-transformer + 2.8.1 + + + + + package + + shade + + + false + + + + + + + *:* + + META-INF/versions/9/module-info.class + + + + + + org.geysermc.platform.standalone.GeyserBootstrap + + + + + ${project.build.directory}/dependency-reduced-pom.xml + + + + + \ 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 000000000..199745388 --- /dev/null +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserBootstrap.java @@ -0,0 +1,78 @@ +/* + * 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.geysermc.common.PlatformType; +import org.geysermc.common.bootstrap.IGeyserBootstrap; +import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.utils.FileUtils; +import org.geysermc.platform.standalone.console.GeyserLogger; + +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() { + 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) { + geyserLogger.severe("Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex); + System.exit(0); + } + + GeyserConnector.start(PlatformType.STANDALONE, this); + geyserLogger.start(); + } + + @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 60% 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 b78fc2279..06cb711c1 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,20 +23,29 @@ * @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.nio.file.Path; +import java.nio.file.Paths; import java.util.Map; @JsonIgnoreProperties(ignoreUnknown = true) @Getter -public class GeyserConfiguration { +public class GeyserConfiguration implements IGeyserConfiguration { + private BedrockConfiguration bedrock; private RemoteConfiguration remote; + @JsonProperty("floodgate-key-file") + private String floodgateKeyFile; + private Map userAuths; @JsonProperty("ping-passthrough") @@ -54,5 +63,48 @@ public class GeyserConfiguration { @JsonProperty("allow-third-party-capes") private boolean allowThirdPartyCapes; - private MetricInfo metrics; + private MetricsInfo metrics; + + @Override + public Path getFloodgateKeyFile() { + return Paths.get(floodgateKeyFile); + } + + @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/console/GeyserLogger.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/console/GeyserLogger.java new file mode 100644 index 000000000..7df8a4efb --- /dev/null +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/console/GeyserLogger.java @@ -0,0 +1,116 @@ +/* + * 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/Geyser + */ + +package org.geysermc.platform.standalone.console; + +import lombok.extern.log4j.Log4j2; + +import net.minecrell.terminalconsole.SimpleTerminalConsole; + +import org.apache.logging.log4j.core.config.Configurator; +import org.geysermc.common.ChatColor; +import org.geysermc.common.logger.IGeyserLogger; +import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.command.CommandSender; + +@Log4j2 +public class GeyserLogger extends SimpleTerminalConsole implements IGeyserLogger, CommandSender { + + private boolean colored = true; + + @Override + protected boolean isRunning() { + return !GeyserConnector.getInstance().isShuttingDown(); + } + + @Override + protected void runCommand(String line) { + GeyserConnector.getInstance().getCommandMap().runCommand(this, line); + } + + @Override + protected void shutdown() { + GeyserConnector.getInstance().shutdown(); + } + + @Override + public void severe(String message) { + log.fatal(printConsole(ChatColor.DARK_RED + message, colored)); + } + + @Override + public void severe(String message, Throwable error) { + log.fatal(printConsole(ChatColor.DARK_RED + message, colored), error); + } + + @Override + public void error(String message) { + log.error(printConsole(ChatColor.RED + message, colored)); + } + + @Override + public void error(String message, Throwable error) { + log.error(printConsole(ChatColor.RED + message, colored), error); + } + + @Override + public void warning(String message) { + log.warn(printConsole(ChatColor.YELLOW + message, colored)); + } + + @Override + public void info(String message) { + log.info(printConsole(ChatColor.WHITE + message, colored)); + } + + @Override + public void debug(String message) { + log.debug(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) { + Configurator.setLevel(log.getName(), debug ? org.apache.logging.log4j.Level.DEBUG : log.getLevel()); + } + + @Override + public String getName() { + return "CONSOLE"; + } + + @Override + public void sendMessage(String message) { + info(message); + } + + @Override + public boolean isConsole() { + return true; + } +} diff --git a/bootstrap/standalone/src/main/resources/log4j2.xml b/bootstrap/standalone/src/main/resources/log4j2.xml new file mode 100644 index 000000000..957415405 --- /dev/null +++ b/bootstrap/standalone/src/main/resources/log4j2.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bootstrap/velocity/pom.xml b/bootstrap/velocity/pom.xml new file mode 100644 index 000000000..22fe92115 --- /dev/null +++ b/bootstrap/velocity/pom.xml @@ -0,0 +1,72 @@ + + + 4.0.0 + + org.geysermc + bootstrap-parent + 1.0-SNAPSHOT + ../ + + bootstrap-velocity + + + org.geysermc + connector + 1.0-SNAPSHOT + compile + + + com.velocitypowered + velocity-api + 1.0.0-SNAPSHOT + provided + + + + ${outputName}-Velocity + + + src/main/resources/ + true + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.1 + + + package + + shade + + + true + + + + + + + *:* + + META-INF/* + + + + + + com.google.code.gson:* + io.netty:* + org.slf4j:* + org.ow2.asm:* + + + + + + + \ No newline at end of file diff --git a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityConfiguration.java b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityConfiguration.java new file mode 100644 index 000000000..2fab448d9 --- /dev/null +++ b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityConfiguration.java @@ -0,0 +1,110 @@ +/* + * 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/Geyser + */ + +package org.geysermc.platform.velocity; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.Getter; + +import org.geysermc.common.IGeyserConfiguration; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Map; + +@JsonIgnoreProperties(ignoreUnknown = true) +@Getter +public class GeyserVelocityConfiguration implements IGeyserConfiguration { + + private BedrockConfiguration bedrock; + private RemoteConfiguration remote; + + @JsonProperty("floodgate-key-file") + private String floodgateKeyFile; + + private Map userAuths; + + @JsonProperty("ping-passthrough") + private boolean pingPassthrough; + + @JsonProperty("max-players") + private int maxPlayers; + + @JsonProperty("debug-mode") + private boolean debugMode; + + @JsonProperty("general-thread-pool") + private int generalThreadPool; + + @JsonProperty("allow-third-party-capes") + private boolean allowThirdPartyCapes; + + private MetricsInfo metrics; + + @Override + public Path getFloodgateKeyFile() { + return Paths.get(floodgateKeyFile); + } + + @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/connector/src/main/java/org/geysermc/connector/command/GeyserConsoleCommandSender.java b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityLogger.java similarity index 54% rename from connector/src/main/java/org/geysermc/connector/command/GeyserConsoleCommandSender.java rename to bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityLogger.java index 9dabe070d..623c6481e 100644 --- a/connector/src/main/java/org/geysermc/connector/command/GeyserConsoleCommandSender.java +++ b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityLogger.java @@ -23,27 +23,57 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.connector.command; +package org.geysermc.platform.velocity; -import org.geysermc.api.command.ConsoleCommandSender; -import org.geysermc.connector.console.GeyserLogger; +import lombok.AllArgsConstructor; -public class GeyserConsoleCommandSender implements ConsoleCommandSender { +import org.geysermc.common.logger.IGeyserLogger; +import org.slf4j.Logger; + +@AllArgsConstructor +public class GeyserVelocityLogger implements IGeyserLogger { + + private Logger logger; + private boolean debugMode; @Override - public String getName() { - return "CONSOLE"; + public void severe(String message) { + logger.error(message); } @Override - public void sendMessage(String message) { - System.out.println(GeyserLogger.printConsole(message, true)); + public void severe(String message, Throwable error) { + logger.error(message, error); } @Override - public void sendMessage(String[] messages) { - for (String message : messages) { - sendMessage(message); - } + public void error(String message) { + logger.error(message); } -} + + @Override + public void error(String message, Throwable error) { + logger.error(message, error); + } + + @Override + public void warning(String message) { + logger.warn(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 debugMode) { + this.debugMode = debugMode; + } +} \ No newline at end of file diff --git a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPlugin.java b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPlugin.java new file mode 100644 index 000000000..4020b81e4 --- /dev/null +++ b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPlugin.java @@ -0,0 +1,96 @@ +/* + * 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/Geyser + */ + +package org.geysermc.platform.velocity; + +import com.google.inject.Inject; + +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; +import com.velocitypowered.api.event.proxy.ProxyShutdownEvent; +import com.velocitypowered.api.plugin.Plugin; + +import org.geysermc.common.PlatformType; +import org.geysermc.common.bootstrap.IGeyserBootstrap; +import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.utils.FileUtils; +import org.slf4j.Logger; + +import java.io.File; +import java.io.IOException; +import java.util.UUID; + +@Plugin(id = "geyser", name = GeyserConnector.NAME + "-Velocity", version = GeyserConnector.VERSION, url = "https://geysermc.org", authors = "GeyserMC") +public class GeyserVelocityPlugin implements IGeyserBootstrap { + + @Inject + private Logger logger; + + private GeyserVelocityConfiguration geyserConfig; + private GeyserVelocityLogger geyserLogger; + + + @Override + public void onEnable() { + try { + File configDir = new File("plugins/" + GeyserConnector.NAME + "-Velocity/"); + if (!configDir.exists()) + configDir.mkdir(); + File configFile = FileUtils.fileOrCopiedFromResource(new File(configDir, "config.yml"), "config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString())); + geyserConfig = FileUtils.loadConfig(configFile, GeyserVelocityConfiguration.class); + } catch (IOException ex) { + logger.warn("Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex); + ex.printStackTrace(); + } + + this.geyserLogger = new GeyserVelocityLogger(logger, geyserConfig.isDebugMode()); + GeyserConnector.start(PlatformType.VELOCITY, this); + } + + @Override + public void onDisable() { + GeyserConnector.stop(); + } + + @Override + public GeyserVelocityConfiguration getGeyserConfig() { + return geyserConfig; + } + + @Override + public GeyserVelocityLogger getGeyserLogger() { + return geyserLogger; + } + + @Subscribe + public void onInit(ProxyInitializeEvent event) { + onEnable(); + } + + @Subscribe + public void onShutdown(ProxyShutdownEvent event) { + onDisable(); + } +} diff --git a/common/pom.xml b/common/pom.xml index cd96ad23a..1f6c20b7e 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -6,7 +6,17 @@ org.geysermc geyser-parent - 1.0-SNAPSHOT + parent + ../ common + 1.0-SNAPSHOT + + + com.google.code.gson + gson + 2.8.2 + compile + + \ No newline at end of file diff --git a/common/src/main/java/org/geysermc/common/AuthType.java b/common/src/main/java/org/geysermc/common/AuthType.java new file mode 100644 index 000000000..bec515600 --- /dev/null +++ b/common/src/main/java/org/geysermc/common/AuthType.java @@ -0,0 +1,26 @@ +package org.geysermc.common; + +import lombok.Getter; + +@Getter +public enum AuthType { + OFFLINE, + ONLINE, + FLOODGATE; + + public static final AuthType[] VALUES = values(); + + public static AuthType getById(int id) { + return id < VALUES.length ? VALUES[id] : OFFLINE; + } + + public static AuthType getByName(String name) { + String upperCase = name.toUpperCase(); + for (AuthType type : VALUES) { + if (type.name().equals(upperCase)) { + return type; + } + } + return OFFLINE; + } +} \ No newline at end of file diff --git a/api/src/main/java/org/geysermc/api/ChatColor.java b/common/src/main/java/org/geysermc/common/ChatColor.java similarity index 99% rename from api/src/main/java/org/geysermc/api/ChatColor.java rename to common/src/main/java/org/geysermc/common/ChatColor.java index abf82167e..20632770c 100644 --- a/api/src/main/java/org/geysermc/api/ChatColor.java +++ b/common/src/main/java/org/geysermc/common/ChatColor.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api; +package org.geysermc.common; public class ChatColor { @@ -84,4 +84,4 @@ public class ChatColor { public static String stripColors(String message) { return message = message.replaceAll("(&([a-fk-or0-9]))","").replaceAll("(§([a-fk-or0-9]))","").replaceAll("s/\\x1b\\[[0-9;]*[a-zA-Z]//g",""); } -} +} \ No newline at end of file diff --git a/api/src/main/java/org/geysermc/api/plugin/Plugin.java b/common/src/main/java/org/geysermc/common/IGeyserConfiguration.java similarity index 56% rename from api/src/main/java/org/geysermc/api/plugin/Plugin.java rename to common/src/main/java/org/geysermc/common/IGeyserConfiguration.java index 8209cade0..db5d831b1 100644 --- a/api/src/main/java/org/geysermc/api/plugin/Plugin.java +++ b/common/src/main/java/org/geysermc/common/IGeyserConfiguration.java @@ -23,62 +23,63 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.plugin; +package org.geysermc.common; -import lombok.Getter; -import lombok.Setter; +import java.nio.file.Path; +import java.util.Map; -/** - * The class that any main plugin class should extend. - * The first init point is the constructor, followed by onLoad, and finally onEnable. - */ -public class Plugin { - protected String name; - protected String version; +public interface IGeyserConfiguration { - /** - * Returns if the plugin is enabled - * - * @return if the plugin is enabled - */ - @Getter - @Setter - private boolean enabled = true; + IBedrockConfiguration getBedrock(); - /** - * Called when a plugin is enabled - */ - public void onEnable() { + IRemoteConfiguration getRemote(); + Map getUserAuths(); + + boolean isPingPassthrough(); + + int getMaxPlayers(); + + boolean isDebugMode(); + + int getGeneralThreadPool(); + + boolean isAllowThirdPartyCapes(); + + Path getFloodgateKeyFile(); + + IMetricsInfo getMetrics(); + + interface IBedrockConfiguration { + + String getAddress(); + + int getPort(); + + String getMotd1(); + + String getMotd2(); } - /** - * Called when a plugin is disabled - */ - public void onDisable() { + interface IRemoteConfiguration { + String getAddress(); + + int getPort(); + + String getAuthType(); } - /** - * Called when a plugin is loaded - */ - public void onLoad() { + interface IUserAuthenticationInfo { + String getEmail(); + String getPassword(); } - /** - * Called when the server is reloaded - */ - public void onReload() { + interface IMetricsInfo { - } + boolean isEnabled(); - public final String getName() { - return name; - } - - @Override - public final String toString() { - return getName(); + String getUniqueId(); } } diff --git a/common/src/main/java/org/geysermc/common/PlatformType.java b/common/src/main/java/org/geysermc/common/PlatformType.java new file mode 100644 index 000000000..fa6f57fda --- /dev/null +++ b/common/src/main/java/org/geysermc/common/PlatformType.java @@ -0,0 +1,17 @@ +package org.geysermc.common; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum PlatformType { + + BUKKIT("Bukkit"), + BUNGEECORD("BungeeCord"), + SPONGE("Sponge"), + STANDALONE("Standalone"), + VELOCITY("Velocity"); + + private String platformName; +} diff --git a/api/src/main/java/org/geysermc/api/session/AuthData.java b/common/src/main/java/org/geysermc/common/bootstrap/IGeyserBootstrap.java similarity index 80% rename from api/src/main/java/org/geysermc/api/session/AuthData.java rename to common/src/main/java/org/geysermc/common/bootstrap/IGeyserBootstrap.java index a095886e5..cf4b3991e 100644 --- a/api/src/main/java/org/geysermc/api/session/AuthData.java +++ b/common/src/main/java/org/geysermc/common/bootstrap/IGeyserBootstrap.java @@ -23,15 +23,18 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.session; +package org.geysermc.common.bootstrap; -import java.util.UUID; +import org.geysermc.common.IGeyserConfiguration; +import org.geysermc.common.logger.IGeyserLogger; -public interface AuthData { +public interface IGeyserBootstrap { - String getName(); + void onEnable(); - UUID getUUID(); + void onDisable(); - String getXboxUUID(); + IGeyserConfiguration getGeyserConfig(); + + IGeyserLogger getGeyserLogger(); } diff --git a/api/src/main/java/org/geysermc/api/logger/Logger.java b/common/src/main/java/org/geysermc/common/logger/IGeyserLogger.java similarity index 97% rename from api/src/main/java/org/geysermc/api/logger/Logger.java rename to common/src/main/java/org/geysermc/common/logger/IGeyserLogger.java index d6227c817..b4d143e43 100644 --- a/api/src/main/java/org/geysermc/api/logger/Logger.java +++ b/common/src/main/java/org/geysermc/common/logger/IGeyserLogger.java @@ -23,9 +23,9 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.logger; +package org.geysermc.common.logger; -public interface Logger { +public interface IGeyserLogger { /** * Logs a severe message to console diff --git a/api/src/main/java/org/geysermc/api/window/CustomFormBuilder.java b/common/src/main/java/org/geysermc/common/window/CustomFormBuilder.java similarity index 88% rename from api/src/main/java/org/geysermc/api/window/CustomFormBuilder.java rename to common/src/main/java/org/geysermc/common/window/CustomFormBuilder.java index 094ed5f44..fb6794120 100644 --- a/api/src/main/java/org/geysermc/api/window/CustomFormBuilder.java +++ b/common/src/main/java/org/geysermc/common/window/CustomFormBuilder.java @@ -23,12 +23,13 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.window; +package org.geysermc.common.window; import lombok.Getter; -import org.geysermc.api.window.button.FormImage; -import org.geysermc.api.window.component.FormComponent; -import org.geysermc.api.window.response.CustomFormResponse; +import org.geysermc.common.window.CustomFormWindow; +import org.geysermc.common.window.button.FormImage; +import org.geysermc.common.window.component.FormComponent; +import org.geysermc.common.window.response.CustomFormResponse; public class CustomFormBuilder { diff --git a/api/src/main/java/org/geysermc/api/window/CustomFormWindow.java b/common/src/main/java/org/geysermc/common/window/CustomFormWindow.java similarity index 90% rename from api/src/main/java/org/geysermc/api/window/CustomFormWindow.java rename to common/src/main/java/org/geysermc/common/window/CustomFormWindow.java index 66efd850e..a6bc72781 100644 --- a/api/src/main/java/org/geysermc/api/window/CustomFormWindow.java +++ b/common/src/main/java/org/geysermc/common/window/CustomFormWindow.java @@ -23,22 +23,16 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.window; +package org.geysermc.common.window; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import lombok.Getter; import lombok.Setter; -import org.geysermc.api.window.button.FormImage; -import org.geysermc.api.window.component.DropdownComponent; -import org.geysermc.api.window.component.FormComponent; -import org.geysermc.api.window.component.InputComponent; -import org.geysermc.api.window.component.LabelComponent; -import org.geysermc.api.window.component.SliderComponent; -import org.geysermc.api.window.component.StepSliderComponent; -import org.geysermc.api.window.component.ToggleComponent; -import org.geysermc.api.window.response.CustomFormResponse; -import org.geysermc.api.window.response.FormResponseData; +import org.geysermc.common.window.button.FormImage; +import org.geysermc.common.window.component.*; +import org.geysermc.common.window.response.CustomFormResponse; +import org.geysermc.common.window.response.FormResponseData; import java.util.ArrayList; import java.util.HashMap; diff --git a/api/src/main/java/org/geysermc/api/window/FormWindow.java b/common/src/main/java/org/geysermc/common/window/FormWindow.java similarity index 94% rename from api/src/main/java/org/geysermc/api/window/FormWindow.java rename to common/src/main/java/org/geysermc/common/window/FormWindow.java index d193950ca..968d9349d 100644 --- a/api/src/main/java/org/geysermc/api/window/FormWindow.java +++ b/common/src/main/java/org/geysermc/common/window/FormWindow.java @@ -23,11 +23,11 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.window; +package org.geysermc.common.window; import lombok.Getter; import lombok.Setter; -import org.geysermc.api.window.response.FormResponse; +import org.geysermc.common.window.response.FormResponse; public abstract class FormWindow { diff --git a/api/src/main/java/org/geysermc/api/window/ModalFormWindow.java b/common/src/main/java/org/geysermc/common/window/ModalFormWindow.java similarity index 95% rename from api/src/main/java/org/geysermc/api/window/ModalFormWindow.java rename to common/src/main/java/org/geysermc/common/window/ModalFormWindow.java index 6a419775c..934660395 100644 --- a/api/src/main/java/org/geysermc/api/window/ModalFormWindow.java +++ b/common/src/main/java/org/geysermc/common/window/ModalFormWindow.java @@ -23,12 +23,12 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.window; +package org.geysermc.common.window; import com.google.gson.Gson; import lombok.Getter; import lombok.Setter; -import org.geysermc.api.window.response.ModalFormResponse; +import org.geysermc.common.window.response.ModalFormResponse; public class ModalFormWindow extends FormWindow { diff --git a/api/src/main/java/org/geysermc/api/window/SimpleFormWindow.java b/common/src/main/java/org/geysermc/common/window/SimpleFormWindow.java similarity index 94% rename from api/src/main/java/org/geysermc/api/window/SimpleFormWindow.java rename to common/src/main/java/org/geysermc/common/window/SimpleFormWindow.java index 4a46aaf43..cc31f061a 100644 --- a/api/src/main/java/org/geysermc/api/window/SimpleFormWindow.java +++ b/common/src/main/java/org/geysermc/common/window/SimpleFormWindow.java @@ -23,13 +23,13 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.window; +package org.geysermc.common.window; import com.google.gson.Gson; import lombok.Getter; import lombok.Setter; -import org.geysermc.api.window.button.FormButton; -import org.geysermc.api.window.response.SimpleFormResponse; +import org.geysermc.common.window.button.FormButton; +import org.geysermc.common.window.response.SimpleFormResponse; import java.util.ArrayList; import java.util.List; diff --git a/api/src/main/java/org/geysermc/api/window/button/FormButton.java b/common/src/main/java/org/geysermc/common/window/button/FormButton.java similarity index 97% rename from api/src/main/java/org/geysermc/api/window/button/FormButton.java rename to common/src/main/java/org/geysermc/common/window/button/FormButton.java index 859bf9382..4f710d483 100644 --- a/api/src/main/java/org/geysermc/api/window/button/FormButton.java +++ b/common/src/main/java/org/geysermc/common/window/button/FormButton.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.window.button; +package org.geysermc.common.window.button; import lombok.Getter; import lombok.Setter; diff --git a/api/src/main/java/org/geysermc/api/window/button/FormImage.java b/common/src/main/java/org/geysermc/common/window/button/FormImage.java similarity index 97% rename from api/src/main/java/org/geysermc/api/window/button/FormImage.java rename to common/src/main/java/org/geysermc/common/window/button/FormImage.java index 17c472306..a3f83a0c5 100644 --- a/api/src/main/java/org/geysermc/api/window/button/FormImage.java +++ b/common/src/main/java/org/geysermc/common/window/button/FormImage.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.window.button; +package org.geysermc.common.window.button; import lombok.Getter; import lombok.Setter; diff --git a/api/src/main/java/org/geysermc/api/window/component/DropdownComponent.java b/common/src/main/java/org/geysermc/common/window/component/DropdownComponent.java similarity index 97% rename from api/src/main/java/org/geysermc/api/window/component/DropdownComponent.java rename to common/src/main/java/org/geysermc/common/window/component/DropdownComponent.java index 99e1bca62..8abe72ff8 100644 --- a/api/src/main/java/org/geysermc/api/window/component/DropdownComponent.java +++ b/common/src/main/java/org/geysermc/common/window/component/DropdownComponent.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.window.component; +package org.geysermc.common.window.component; import lombok.Getter; import lombok.Setter; diff --git a/api/src/main/java/org/geysermc/api/window/component/FormComponent.java b/common/src/main/java/org/geysermc/common/window/component/FormComponent.java similarity index 96% rename from api/src/main/java/org/geysermc/api/window/component/FormComponent.java rename to common/src/main/java/org/geysermc/common/window/component/FormComponent.java index 506cae687..fb5b9d18c 100644 --- a/api/src/main/java/org/geysermc/api/window/component/FormComponent.java +++ b/common/src/main/java/org/geysermc/common/window/component/FormComponent.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.window.component; +package org.geysermc.common.window.component; import lombok.Getter; diff --git a/api/src/main/java/org/geysermc/api/window/component/InputComponent.java b/common/src/main/java/org/geysermc/common/window/component/InputComponent.java similarity index 97% rename from api/src/main/java/org/geysermc/api/window/component/InputComponent.java rename to common/src/main/java/org/geysermc/common/window/component/InputComponent.java index 12af18268..53ec2b5eb 100644 --- a/api/src/main/java/org/geysermc/api/window/component/InputComponent.java +++ b/common/src/main/java/org/geysermc/common/window/component/InputComponent.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.window.component; +package org.geysermc.common.window.component; import lombok.Getter; import lombok.Setter; diff --git a/api/src/main/java/org/geysermc/api/window/component/LabelComponent.java b/common/src/main/java/org/geysermc/common/window/component/LabelComponent.java similarity index 96% rename from api/src/main/java/org/geysermc/api/window/component/LabelComponent.java rename to common/src/main/java/org/geysermc/common/window/component/LabelComponent.java index 9ba68ee4a..7d2aaa420 100644 --- a/api/src/main/java/org/geysermc/api/window/component/LabelComponent.java +++ b/common/src/main/java/org/geysermc/common/window/component/LabelComponent.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.window.component; +package org.geysermc.common.window.component; import lombok.Getter; import lombok.Setter; diff --git a/api/src/main/java/org/geysermc/api/window/component/SliderComponent.java b/common/src/main/java/org/geysermc/common/window/component/SliderComponent.java similarity index 95% rename from api/src/main/java/org/geysermc/api/window/component/SliderComponent.java rename to common/src/main/java/org/geysermc/common/window/component/SliderComponent.java index 468b700ec..fd82b3e26 100644 --- a/api/src/main/java/org/geysermc/api/window/component/SliderComponent.java +++ b/common/src/main/java/org/geysermc/common/window/component/SliderComponent.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.window.component; +package org.geysermc.common.window.component; import lombok.Getter; import lombok.Setter; @@ -54,7 +54,7 @@ public class SliderComponent extends FormComponent { super("slider"); this.text = text; - this.min = min < 0f ? 0f : min; + this.min = Math.max(min, 0f); this.max = max > this.min ? max : this.min; if (step != -1f && step > 0) this.step = step; diff --git a/api/src/main/java/org/geysermc/api/window/component/StepSliderComponent.java b/common/src/main/java/org/geysermc/common/window/component/StepSliderComponent.java similarity index 97% rename from api/src/main/java/org/geysermc/api/window/component/StepSliderComponent.java rename to common/src/main/java/org/geysermc/common/window/component/StepSliderComponent.java index aa934f062..b61e416d0 100644 --- a/api/src/main/java/org/geysermc/api/window/component/StepSliderComponent.java +++ b/common/src/main/java/org/geysermc/common/window/component/StepSliderComponent.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.window.component; +package org.geysermc.common.window.component; import lombok.Getter; import lombok.Setter; diff --git a/api/src/main/java/org/geysermc/api/window/component/ToggleComponent.java b/common/src/main/java/org/geysermc/common/window/component/ToggleComponent.java similarity index 97% rename from api/src/main/java/org/geysermc/api/window/component/ToggleComponent.java rename to common/src/main/java/org/geysermc/common/window/component/ToggleComponent.java index 41b292a61..614ecf8fb 100644 --- a/api/src/main/java/org/geysermc/api/window/component/ToggleComponent.java +++ b/common/src/main/java/org/geysermc/common/window/component/ToggleComponent.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.window.component; +package org.geysermc.common.window.component; public class ToggleComponent extends FormComponent { diff --git a/api/src/main/java/org/geysermc/api/window/response/CustomFormResponse.java b/common/src/main/java/org/geysermc/common/window/response/CustomFormResponse.java similarity index 91% rename from api/src/main/java/org/geysermc/api/window/response/CustomFormResponse.java rename to common/src/main/java/org/geysermc/common/window/response/CustomFormResponse.java index f32c43462..36b2922f9 100644 --- a/api/src/main/java/org/geysermc/api/window/response/CustomFormResponse.java +++ b/common/src/main/java/org/geysermc/common/window/response/CustomFormResponse.java @@ -23,10 +23,12 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.window.response; +package org.geysermc.common.window.response; import lombok.AllArgsConstructor; import lombok.Getter; +import org.geysermc.common.window.response.FormResponse; +import org.geysermc.common.window.response.FormResponseData; import java.util.Map; diff --git a/api/src/main/java/org/geysermc/api/window/response/FormResponse.java b/common/src/main/java/org/geysermc/common/window/response/FormResponse.java similarity index 96% rename from api/src/main/java/org/geysermc/api/window/response/FormResponse.java rename to common/src/main/java/org/geysermc/common/window/response/FormResponse.java index 0286bef1a..58c8c8e87 100644 --- a/api/src/main/java/org/geysermc/api/window/response/FormResponse.java +++ b/common/src/main/java/org/geysermc/common/window/response/FormResponse.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.window.response; +package org.geysermc.common.window.response; public interface FormResponse { } diff --git a/api/src/main/java/org/geysermc/api/window/response/FormResponseData.java b/common/src/main/java/org/geysermc/common/window/response/FormResponseData.java similarity index 96% rename from api/src/main/java/org/geysermc/api/window/response/FormResponseData.java rename to common/src/main/java/org/geysermc/common/window/response/FormResponseData.java index b97fb0521..826aba208 100644 --- a/api/src/main/java/org/geysermc/api/window/response/FormResponseData.java +++ b/common/src/main/java/org/geysermc/common/window/response/FormResponseData.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.window.response; +package org.geysermc.common.window.response; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/api/src/main/java/org/geysermc/api/window/response/ModalFormResponse.java b/common/src/main/java/org/geysermc/common/window/response/ModalFormResponse.java similarity index 93% rename from api/src/main/java/org/geysermc/api/window/response/ModalFormResponse.java rename to common/src/main/java/org/geysermc/common/window/response/ModalFormResponse.java index a62953b0d..844c9a5b8 100644 --- a/api/src/main/java/org/geysermc/api/window/response/ModalFormResponse.java +++ b/common/src/main/java/org/geysermc/common/window/response/ModalFormResponse.java @@ -23,10 +23,11 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.window.response; +package org.geysermc.common.window.response; import lombok.AllArgsConstructor; import lombok.Getter; +import org.geysermc.common.window.response.FormResponse; @Getter @AllArgsConstructor diff --git a/api/src/main/java/org/geysermc/api/window/response/SimpleFormResponse.java b/common/src/main/java/org/geysermc/common/window/response/SimpleFormResponse.java similarity index 90% rename from api/src/main/java/org/geysermc/api/window/response/SimpleFormResponse.java rename to common/src/main/java/org/geysermc/common/window/response/SimpleFormResponse.java index 4271d7546..5a53d0423 100644 --- a/api/src/main/java/org/geysermc/api/window/response/SimpleFormResponse.java +++ b/common/src/main/java/org/geysermc/common/window/response/SimpleFormResponse.java @@ -23,11 +23,12 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.api.window.response; +package org.geysermc.common.window.response; import lombok.AllArgsConstructor; import lombok.Getter; -import org.geysermc.api.window.button.FormButton; +import org.geysermc.common.window.button.FormButton; +import org.geysermc.common.window.response.FormResponse; @Getter @AllArgsConstructor 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 000000000..8beeb9987 --- /dev/null +++ b/common/src/main/java/org/geysermc/floodgate/util/BedrockData.java @@ -0,0 +1,44 @@ +package org.geysermc.floodgate.util; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class BedrockData { + public static final int EXPECTED_LENGTH = 7; + public static final String FLOODGATE_IDENTIFIER = "Geyser-Floodgate"; + + private String version; + private String username; + private String xuid; + private int deviceId; + private String languageCode; + private int inputMode; + private String ip; + private int dataLength; + + public BedrockData(String version, String username, String xuid, int deviceId, String languageCode, int inputMode, String ip) { + this(version, username, xuid, deviceId, languageCode, inputMode, ip, EXPECTED_LENGTH); + } + + public static BedrockData fromString(String data) { + String[] split = data.split("\0"); + if (split.length != EXPECTED_LENGTH) return null; + + return new BedrockData( + split[0], split[1], split[2], Integer.parseInt(split[3]), + split[4], Integer.parseInt(split[5]), split[6], split.length + ); + } + + public static BedrockData fromRawData(byte[] data) { + return fromString(new String(data)); + } + + @Override + public String toString() { + return version +'\0'+ username +'\0'+ xuid +'\0'+ deviceId +'\0'+ languageCode +'\0'+ + inputMode +'\0'+ ip; + } +} 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 000000000..881d01ba9 --- /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 encryptBedrockData(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 decryptBedrockData(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/connector/pom.xml b/connector/pom.xml index 1f6bef51f..6d56fbcad 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -6,16 +6,12 @@ org.geysermc geyser-parent - 1.0-SNAPSHOT + parent + ../ connector + 1.0-SNAPSHOT - - org.geysermc - api - 1.0-SNAPSHOT - compile - org.geysermc common @@ -40,30 +36,6 @@ 1.7.0 compile - - net.minecrell - terminalconsoleappender - 1.0.0 - compile - - - org.slf4j - slf4j-api - 1.7.5 - compile - - - org.slf4j - slf4j-simple - 1.6.4 - compile - - - org.fusesource.jansi - jansi - 1.18 - compile - com.nukkitx.protocol bedrock-v389 @@ -121,45 +93,4 @@ - - ${project.parent.name}-noshade - ../target - - - org.apache.maven.plugins - maven-jar-plugin - - - - org.geysermc.connector.GeyserConnector - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - - ${project.parent.name} - - - - org.apache.maven.plugins - maven-shade-plugin - - - package - - shade - - - - - ${project.parent.name} - 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 982afd164..12c09e162 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -30,42 +30,31 @@ import com.nukkitx.protocol.bedrock.BedrockServer; import com.nukkitx.protocol.bedrock.v389.Bedrock_v389; 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.AuthType; +import org.geysermc.common.PlatformType; +import org.geysermc.common.bootstrap.IGeyserBootstrap; +import org.geysermc.common.logger.IGeyserLogger; 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; import org.geysermc.connector.network.ConnectorServerEventHandler; -import org.geysermc.connector.network.remote.RemoteJavaServer; +import org.geysermc.connector.network.remote.RemoteServer; import org.geysermc.connector.network.session.GeyserSession; 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; @Getter -public class GeyserConnector implements Connector { +public class GeyserConnector { public static final BedrockPacketCodec BEDROCK_PACKET_CODEC = Bedrock_v389.V389_CODEC; @@ -76,37 +65,31 @@ public class GeyserConnector implements Connector { private static GeyserConnector instance; - private RemoteJavaServer remoteServer; + private RemoteServer remoteServer; + private AuthType authType; - private Logger logger; + private IGeyserLogger logger; + private IGeyserConfiguration config; - private CommandMap commandMap; - - private GeyserConfiguration config; - private GeyserPluginManager pluginManager; + private GeyserCommandMap commandMap; private boolean shuttingDown = false; private final ScheduledExecutorService generalThreadPool; private PingPassthroughThread passthroughThread; + private BedrockServer bedrockServer; + private PlatformType platformType; + private Metrics metrics; - public static void main(String[] args) { - instance = new GeyserConnector(); - } - - private GeyserConnector() { + private GeyserConnector(PlatformType platformType, IGeyserConfiguration config, IGeyserLogger logger) { 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; + this.platformType = platformType; logger.info("******************************************"); logger.info(""); @@ -114,17 +97,8 @@ 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); - consoleReader.startConsole(); logger.setDebug(config.isDebugMode()); @@ -132,18 +106,14 @@ public class GeyserConnector implements Connector { TranslatorsInit.start(); commandMap = new GeyserCommandMap(this); - remoteServer = new RemoteJavaServer(config.getRemote().getAddress(), config.getRemote().getPort()); - - Geyser.setConnector(this); - - pluginManager = new GeyserPluginManager(new GeyserPluginLoader(this)); - pluginManager.getLoader().loadPlugins(); + remoteServer = new RemoteServer(config.getRemote().getAddress(), config.getRemote().getPort()); + authType = AuthType.getByName(config.getRemote().getAuthType()); passthroughThread = new PingPassthroughThread(this); if (config.isPingPassthrough()) generalThreadPool.scheduleAtFixedRate(passthroughThread, 1, 1, TimeUnit.SECONDS); - BedrockServer bedrockServer = new BedrockServer(new InetSocketAddress(config.getBedrock().getAddress(), config.getBedrock().getPort())); + bedrockServer = new BedrockServer(new InetSocketAddress(config.getBedrock().getAddress(), config.getBedrock().getPort())); bedrockServer.setHandler(new ConnectorServerEventHandler(this)); bedrockServer.bind().whenComplete((avoid, throwable) -> { if (throwable == null) { @@ -155,43 +125,46 @@ 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(this, "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)); + metrics.addCustomChart(new Metrics.SingleLineChart("players", players::size)); + metrics.addCustomChart(new Metrics.SimplePie("authMode", authType.name()::toLowerCase)); + metrics.addCustomChart(new Metrics.SimplePie("platform", platformType::getPlatformName)); } double completeTime = (System.currentTimeMillis() - startupTime) / 1000D; - logger.info(String.format("Done (%ss)! Run /help for help!", new DecimalFormat("#.###").format(completeTime))); - } - - @Override - public Collection getConnectedPlayers() { - return players.values(); + logger.info(String.format("Done (%ss)! Run /geyser help for help!", new DecimalFormat("#.###").format(completeTime))); } public void shutdown() { - logger.info("Shutting down connector."); - for (Plugin plugin : pluginManager.getPlugins()) { - pluginManager.disablePlugin(plugin); - pluginManager.unloadPlugin(plugin); - } - + logger.info("Shutting down Geyser."); shuttingDown = true; generalThreadPool.shutdown(); - System.exit(0); + bedrockServer.close(); } public void addPlayer(GeyserSession player) { - players.put(player.getAuthenticationData().getName(), player); - players.put(player.getAuthenticationData().getUUID(), player); + players.put(player.getAuthData().getName(), player); + players.put(player.getAuthData().getUUID(), player); players.put(player.getSocketAddress(), player); } public void removePlayer(GeyserSession player) { - players.remove(player.getAuthenticationData().getName()); - players.remove(player.getAuthenticationData().getUUID()); + players.remove(player.getAuthData().getName()); + players.remove(player.getAuthData().getUUID()); players.remove(player.getSocketAddress()); } + + public static GeyserConnector start(PlatformType platformType, IGeyserBootstrap bootstrap) { + return new GeyserConnector(platformType, bootstrap.getGeyserConfig(), bootstrap.getGeyserLogger()); + } + + public static void stop() { + instance.shutdown(); + } + + public static GeyserConnector getInstance() { + return instance; + } } diff --git a/connector/src/main/java/org/geysermc/connector/command/CommandSender.java b/connector/src/main/java/org/geysermc/connector/command/CommandSender.java new file mode 100644 index 000000000..9e4f020bd --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/command/CommandSender.java @@ -0,0 +1,16 @@ +package org.geysermc.connector.command; + +public interface CommandSender { + + String getName(); + + default void sendMessage(String[] messages) { + for (String message : messages) { + sendMessage(message); + } + } + + void sendMessage(String message); + + boolean isConsole(); +} diff --git a/connector/src/main/java/org/geysermc/connector/command/GeyserCommand.java b/connector/src/main/java/org/geysermc/connector/command/GeyserCommand.java index 8f357775b..ea8ed874a 100644 --- a/connector/src/main/java/org/geysermc/connector/command/GeyserCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/GeyserCommand.java @@ -25,18 +25,24 @@ package org.geysermc.connector.command; -import org.geysermc.api.command.Command; -import org.geysermc.api.command.CommandSender; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; +import java.util.ArrayList; import java.util.List; -public abstract class GeyserCommand implements Command { +@Getter +@Setter +public abstract class GeyserCommand { private String name; private String description; + + @Setter(AccessLevel.NONE) private GeyserCommandMap commandMap; - private List aliases; + private List aliases = new ArrayList<>(); public GeyserCommand(String name) { this(name, "A geyser command."); @@ -47,38 +53,5 @@ public abstract class GeyserCommand implements Command { this.description = description; } - @Override - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @Override - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - @Override - public List getAliases() { - return aliases; - } - - @Override - public void setAliases(List aliases) { - this.aliases = aliases; - } - - @Override public abstract void execute(CommandSender sender, String[] args); - - public GeyserCommandMap getCommandMap() { - return commandMap; - } } diff --git a/connector/src/main/java/org/geysermc/connector/command/GeyserCommandMap.java b/connector/src/main/java/org/geysermc/connector/command/GeyserCommandMap.java index 47f023733..7172622c3 100644 --- a/connector/src/main/java/org/geysermc/connector/command/GeyserCommandMap.java +++ b/connector/src/main/java/org/geysermc/connector/command/GeyserCommandMap.java @@ -25,9 +25,6 @@ package org.geysermc.connector.command; -import org.geysermc.api.command.Command; -import org.geysermc.api.command.CommandMap; -import org.geysermc.api.command.CommandSender; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.defaults.HelpCommand; import org.geysermc.connector.command.defaults.StopCommand; @@ -36,9 +33,9 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; -public class GeyserCommandMap implements CommandMap { +public class GeyserCommandMap { - private final Map commandMap = Collections.synchronizedMap(new HashMap()); + private final Map commandMap = Collections.synchronizedMap(new HashMap<>()); private GeyserConnector connector; public GeyserCommandMap(GeyserConnector connector) { @@ -52,11 +49,11 @@ public class GeyserCommandMap implements CommandMap { registerCommand(new StopCommand(connector, "stop", "Shut down Geyser.")); } - public void registerCommand(Command command) { + public void registerCommand(GeyserCommand command) { commandMap.put(command.getName(), command); connector.getLogger().debug("Registered command " + command.getName()); - if (command.getAliases() == null || command.getAliases().isEmpty()) + if (command.getAliases().isEmpty()) return; for (String alias : command.getAliases()) @@ -64,34 +61,33 @@ public class GeyserCommandMap implements CommandMap { } public void runCommand(CommandSender sender, String command) { - String trim = command.trim(); - String label = null; - String[] args = null; + if (!command.startsWith("geyser ")) + return; - if (!trim.contains(" ")) { - label = trim.toLowerCase(); + command = command.trim(); + command = command.replace("geyser ", ""); + String label; + String[] args; + + if (!command.contains(" ")) { + label = command.toLowerCase(); args = new String[0]; } else { - label = trim.substring(0, trim.indexOf(" ")).toLowerCase(); - String argLine = trim.substring(trim.indexOf(" " + 1)); + label = command.substring(0, command.indexOf(" ")).toLowerCase(); + String argLine = command.substring(command.indexOf(" " + 1)); args = argLine.contains(" ") ? argLine.split(" ") : new String[] { argLine }; } - if (label == null) { - connector.getLogger().warning("Invalid Command! Try /help for a list of commands."); - return; - } - - Command cmd = commandMap.get(label); + GeyserCommand cmd = commandMap.get(label); if (cmd == null) { - connector.getLogger().warning("Invalid Command! Try /help for a list of commands."); + connector.getLogger().error("Invalid Command! Try /geyser help for a list of commands."); return; } cmd.execute(sender, args); } - public Map getCommands() { + public Map getCommands() { return commandMap; } } diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/HelpCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/HelpCommand.java index b38bcb07e..4fa0068ae 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/HelpCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/HelpCommand.java @@ -25,17 +25,12 @@ package org.geysermc.connector.command.defaults; -import org.geysermc.api.ChatColor; -import org.geysermc.api.command.Command; -import org.geysermc.api.command.CommandSender; +import org.geysermc.common.ChatColor; import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.command.CommandSender; import org.geysermc.connector.command.GeyserCommand; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import java.util.*; public class HelpCommand extends GeyserCommand { @@ -45,19 +40,19 @@ public class HelpCommand extends GeyserCommand { super(name, description); this.connector = connector; - this.setAliases(Arrays.asList("?")); + this.setAliases(Collections.singletonList("?")); } @Override public void execute(CommandSender sender, String[] args) { sender.sendMessage("---- Showing Help For: Geyser (Page 1/1) ----"); - Map cmds = connector.getCommandMap().getCommands(); + Map cmds = connector.getCommandMap().getCommands(); - List commands = new ArrayList(cmds.keySet()); + List commands = new ArrayList<>(cmds.keySet()); Collections.sort(commands); for (String cmd : commands) { - sender.sendMessage(ChatColor.YELLOW + "/" + cmd + ChatColor.WHITE + ": " + cmds.get(cmd).getDescription()); + sender.sendMessage(ChatColor.YELLOW + "/geyser " + cmd + ChatColor.WHITE + ": " + cmds.get(cmd).getDescription()); } } } diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java index a0011c97d..25034f1ad 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java @@ -25,11 +25,11 @@ package org.geysermc.connector.command.defaults; -import org.geysermc.api.command.CommandSender; import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.command.CommandSender; import org.geysermc.connector.command.GeyserCommand; -import java.util.Arrays; +import java.util.Collections; public class StopCommand extends GeyserCommand { @@ -39,11 +39,14 @@ public class StopCommand extends GeyserCommand { super(name, description); this.connector = connector; - this.setAliases(Arrays.asList("shutdown")); + this.setAliases(Collections.singletonList("shutdown")); } @Override public void execute(CommandSender sender, String[] args) { + if (!sender.isConsole()) + return; + connector.shutdown(); } } diff --git a/connector/src/main/java/org/geysermc/connector/configuration/BedrockConfiguration.java b/connector/src/main/java/org/geysermc/connector/configuration/BedrockConfiguration.java deleted file mode 100644 index 2010214ef..000000000 --- a/connector/src/main/java/org/geysermc/connector/configuration/BedrockConfiguration.java +++ /dev/null @@ -1,38 +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; - -import lombok.Getter; - -@Getter -public class BedrockConfiguration { - - private String address; - private int port; - - private String motd1; - private String motd2; -} \ No newline at end of file diff --git a/connector/src/main/java/org/geysermc/connector/configuration/MetricInfo.java b/connector/src/main/java/org/geysermc/connector/configuration/MetricInfo.java deleted file mode 100644 index d108d4b4c..000000000 --- a/connector/src/main/java/org/geysermc/connector/configuration/MetricInfo.java +++ /dev/null @@ -1,38 +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; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Getter; - -@Getter -public class MetricInfo { - - private boolean enabled; - - @JsonProperty("uuid") - private String UUID; -} diff --git a/connector/src/main/java/org/geysermc/connector/configuration/RemoteConfiguration.java b/connector/src/main/java/org/geysermc/connector/configuration/RemoteConfiguration.java deleted file mode 100644 index 7fcf8a2bb..000000000 --- a/connector/src/main/java/org/geysermc/connector/configuration/RemoteConfiguration.java +++ /dev/null @@ -1,42 +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; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Getter; - -@Getter -public class RemoteConfiguration { - - private String address; - private int port; - - private String motd1; - private String motd2; - - @JsonProperty("auth-type") - private String authType; -} \ No newline at end of file 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 e8ce14243..000000000 --- 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/ConsoleCommandReader.java b/connector/src/main/java/org/geysermc/connector/console/ConsoleCommandReader.java deleted file mode 100644 index de8a0aaba..000000000 --- a/connector/src/main/java/org/geysermc/connector/console/ConsoleCommandReader.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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/Geyser - */ - -package org.geysermc.connector.console; - -import org.geysermc.api.command.ConsoleCommandSender; -import org.geysermc.connector.GeyserConnector; -import org.geysermc.connector.command.GeyserConsoleCommandSender; -import net.minecrell.terminalconsole.TerminalConsoleAppender; -import org.jline.reader.EndOfFileException; -import org.jline.reader.LineReader; -import org.jline.reader.LineReaderBuilder; -import org.jline.reader.UserInterruptException; -import org.jline.terminal.Terminal; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class ConsoleCommandReader { - - private GeyserConnector connector; - private Terminal terminal; - private Thread thread; - - public ConsoleCommandReader(GeyserConnector connector) { - this.connector = connector; - this.terminal = TerminalConsoleAppender.getTerminal(); - } - - public void startConsole() { - thread = new Thread(() -> { - if (terminal != null) { - LineReader lineReader = LineReaderBuilder.builder() - .appName("Geyser") - .terminal(terminal) - .build(); - TerminalConsoleAppender.setReader(lineReader); - - try { - String line; - - while (true) { - try { - line = lineReader.readLine("> "); - } catch (EndOfFileException ignored) { - continue; - } - - if (line == null) - break; - } - } catch (UserInterruptException e /* do nothing */) { - // - } finally { - TerminalConsoleAppender.setReader(null); - } - } else { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) { - String line; - while ((line = reader.readLine()) != null) { - ConsoleCommandSender sender = new GeyserConsoleCommandSender(); - connector.getCommandMap().runCommand(sender, line); - } - } catch (IOException ex) { - Logger.getLogger("Geyser").log(Level.SEVERE, null, ex); - } - } - }); - - thread.setName("ConsoleCommandThread"); - connector.getGeneralThreadPool().execute(thread); - } -} diff --git a/connector/src/main/java/org/geysermc/connector/console/GeyserLogger.java b/connector/src/main/java/org/geysermc/connector/console/GeyserLogger.java deleted file mode 100644 index 8154c2a57..000000000 --- a/connector/src/main/java/org/geysermc/connector/console/GeyserLogger.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * 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/Geyser - */ - -package org.geysermc.connector.console; - -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 static final GeyserLogger DEFAULT = new GeyserLogger(); - - private 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/connector/src/main/java/org/geysermc/connector/entity/Entity.java b/connector/src/main/java/org/geysermc/connector/entity/Entity.java index 6907f489b..177d0d7a9 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/Entity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/Entity.java @@ -34,11 +34,13 @@ import com.nukkitx.protocol.bedrock.data.EntityDataMap; import com.nukkitx.protocol.bedrock.data.EntityFlag; import com.nukkitx.protocol.bedrock.data.EntityFlags; import com.nukkitx.protocol.bedrock.packet.*; + import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import it.unimi.dsi.fastutil.longs.LongSet; + import lombok.Getter; import lombok.Setter; -import org.geysermc.connector.console.GeyserLogger; + import org.geysermc.connector.entity.attribute.Attribute; import org.geysermc.connector.entity.attribute.AttributeType; import org.geysermc.connector.entity.type.EntityType; @@ -114,7 +116,7 @@ public class Entity { valid = true; session.getUpstream().sendPacket(addEntityPacket); - GeyserLogger.DEFAULT.debug("Spawned entity " + entityType + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")"); + session.getConnector().getLogger().debug("Spawned entity " + entityType + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")"); } /** diff --git a/connector/src/main/java/org/geysermc/connector/entity/PaintingEntity.java b/connector/src/main/java/org/geysermc/connector/entity/PaintingEntity.java index c8fa7a90e..87ff9a357 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/PaintingEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/PaintingEntity.java @@ -27,10 +27,11 @@ package org.geysermc.connector.entity; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.packet.AddPaintingPacket; + import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; -import org.geysermc.connector.console.GeyserLogger; + import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.utils.PaintingType; @@ -58,7 +59,7 @@ public class PaintingEntity extends Entity { valid = true; - GeyserLogger.DEFAULT.debug("Spawned painting on " + position); + session.getConnector().getLogger().debug("Spawned painting on " + position); } public Vector3f fixOffset(boolean toBedrock) { diff --git a/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java b/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java index 49af65546..56d59ec3d 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java @@ -32,9 +32,11 @@ import com.nukkitx.protocol.bedrock.data.PlayerPermission; import com.nukkitx.protocol.bedrock.packet.AddPlayerPacket; import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket; import com.nukkitx.protocol.bedrock.packet.PlayerListPacket; + import lombok.Getter; import lombok.Setter; -import org.geysermc.api.Geyser; + +import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.utils.SkinUtils; @@ -108,7 +110,7 @@ public class PlayerEntity extends LivingEntity { if (!playerList) { // remove from playerlist if player isn't on playerlist - Geyser.getGeneralThreadPool().execute(() -> { + GeyserConnector.getInstance().getGeneralThreadPool().execute(() -> { PlayerListPacket playerList = new PlayerListPacket(); playerList.setAction(PlayerListPacket.Action.REMOVE); playerList.getEntries().add(new PlayerListPacket.Entry(uuid)); diff --git a/connector/src/main/java/org/geysermc/connector/metrics/Metrics.java b/connector/src/main/java/org/geysermc/connector/metrics/Metrics.java index 2decb23be..ff2cd097c 100644 --- a/connector/src/main/java/org/geysermc/connector/metrics/Metrics.java +++ b/connector/src/main/java/org/geysermc/connector/metrics/Metrics.java @@ -27,7 +27,6 @@ package org.geysermc.connector.metrics; import com.google.gson.JsonArray; import com.google.gson.JsonObject; -import org.geysermc.api.Geyser; import org.geysermc.connector.GeyserConnector; import javax.net.ssl.HttpsURLConnection; @@ -72,15 +71,19 @@ public class Metrics { // A list with all custom charts private final List charts = new ArrayList<>(); + private GeyserConnector connector; + /** * Class constructor. * + * @param connector The GeyserConnector instance * @param name The name of the server software. * @param serverUUID The uuid of the server. * @param logFailedRequests Whether failed requests should be logged or not. * @param logger The logger for the failed requests. */ - public Metrics(String name, String serverUUID, boolean logFailedRequests, Logger logger) { + public Metrics(GeyserConnector connector, String name, String serverUUID, boolean logFailedRequests, Logger logger) { + this.connector = connector; this.name = name; this.serverUUID = serverUUID; Metrics.logFailedRequests = logFailedRequests; @@ -106,7 +109,7 @@ public class Metrics { * Starts the Scheduler which submits our data every 30 minutes. */ private void startSubmitting() { - Geyser.getGeneralThreadPool().scheduleAtFixedRate(this::submitData, 1, 30, TimeUnit.MINUTES); + connector.getGeneralThreadPool().scheduleAtFixedRate(this::submitData, 1, 30, TimeUnit.MINUTES); // Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start // WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted! // WARNING: Just don't do it! @@ -144,7 +147,7 @@ public class Metrics { */ private JsonObject getServerData() { // OS specific data - int playerAmount = Geyser.getPlayerCount(); + int playerAmount = connector.getPlayers().size(); String osName = System.getProperty("os.name"); String osArch = System.getProperty("os.arch"); 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 3234f9402..a7b28a23d 100644 --- a/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java @@ -29,11 +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; @@ -49,50 +47,35 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler { @Override public boolean onConnectionRequest(InetSocketAddress inetSocketAddress) { - GeyserLogger.DEFAULT.info(inetSocketAddress + " tried to connect!"); + connector.getLogger().info(inetSocketAddress + " tried to connect!"); return true; } @Override public BedrockPong onQuery(InetSocketAddress inetSocketAddress) { - GeyserLogger.DEFAULT.debug(inetSocketAddress + " has pinged you!"); - GeyserConfiguration config = connector.getConfig(); - PingEvent pongEvent = new PingEvent(inetSocketAddress); - pongEvent.setEdition("MCPE"); - pongEvent.setGameType("Default"); - pongEvent.setNintendoLimited(false); - pongEvent.setProtocolVersion(GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion()); - pongEvent.setVersion(GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion()); + connector.getLogger().debug(inetSocketAddress + " has pinged you!"); - connector.getPluginManager().runEvent(pongEvent); - if (connector.getConfig().isPingPassthrough()) { - ServerStatusInfo serverInfo = connector.getPassthroughThread().getInfo(); - - if (serverInfo != null) { - pongEvent.setMotd(MessageUtils.getBedrockMessage(serverInfo.getDescription())); - pongEvent.setSubMotd(config.getBedrock().getMotd2()); - pongEvent.setPlayerCount(serverInfo.getPlayerInfo().getOnlinePlayers()); - pongEvent.setMaximumPlayerCount(serverInfo.getPlayerInfo().getMaxPlayers()); - } - } else { - pongEvent.setPlayerCount(1); - pongEvent.setMaximumPlayerCount(config.getMaxPlayers()); - pongEvent.setMotd(config.getBedrock().getMotd1()); - pongEvent.setSubMotd(config.getBedrock().getMotd2()); - } + IGeyserConfiguration config = connector.getConfig(); + ServerStatusInfo serverInfo = connector.getPassthroughThread().getInfo(); BedrockPong pong = new BedrockPong(); - pong.setEdition(pongEvent.getEdition()); - pong.setGameType(pongEvent.getGameType()); - pong.setNintendoLimited(pongEvent.isNintendoLimited()); - pong.setProtocolVersion(pongEvent.getProtocolVersion()); - pong.setVersion(pongEvent.getVersion()); - pong.setMotd(pongEvent.getMotd()); - pong.setSubMotd(pongEvent.getSubMotd()); - pong.setPlayerCount(pongEvent.getPlayerCount()); - pong.setMaximumPlayerCount(pongEvent.getMaximumPlayerCount()); + pong.setEdition("MCPE"); + pong.setGameType("Default"); + pong.setNintendoLimited(false); + pong.setProtocolVersion(GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion()); + pong.setVersion(GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion()); pong.setIpv4Port(config.getBedrock().getPort()); - + if (connector.getConfig().isPingPassthrough() && serverInfo != null) { + pong.setMotd(MessageUtils.getBedrockMessage(serverInfo.getDescription())); + pong.setSubMotd(config.getBedrock().getMotd2()); + pong.setPlayerCount(serverInfo.getPlayerInfo().getOnlinePlayers()); + pong.setMaximumPlayerCount(serverInfo.getPlayerInfo().getMaxPlayers()); + } else { + pong.setPlayerCount(connector.getPlayers().size()); + pong.setMaximumPlayerCount(config.getMaxPlayers()); + pong.setMotd(config.getBedrock().getMotd1()); + pong.setMotd(config.getBedrock().getMotd2()); + } return pong; } @@ -101,7 +84,7 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler { bedrockServerSession.setLogging(true); bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(connector, new GeyserSession(connector, bedrockServerSession))); bedrockServerSession.addDisconnectHandler(disconnectReason -> { - GeyserLogger.DEFAULT.info("Bedrock user with ip: " + bedrockServerSession.getAddress().getAddress() + " has disconnected for reason " + disconnectReason); + connector.getLogger().info("Bedrock user with ip: " + bedrockServerSession.getAddress().getAddress() + " has disconnected for reason " + disconnectReason); GeyserSession player = connector.getPlayers().get(bedrockServerSession.getAddress()); if (player != null) { 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 f5edad166..6fffcda84 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; @@ -66,7 +66,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { switch (packet.getStatus()) { case COMPLETED: session.connect(connector.getRemoteServer()); - connector.getLogger().info("Player connected with username " + session.getAuthenticationData().getName()); + connector.getLogger().info("Player connected with username " + session.getAuthData().getName()); break; case HAVE_ALL_PACKS: ResourcePackStackPacket stack = new ResourcePackStackPacket(); @@ -90,11 +90,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); + connector.getLogger().info("using stored credentials for bedrock user " + session.getAuthData().getName()); + 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) @@ -109,7 +109,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { public boolean handle(MovePlayerPacket packet) { if (!session.isLoggedIn() && !session.isLoggingIn()) { // TODO it is safer to key authentication on something that won't change (UUID, not username) - if (!couldLoginUserByName(session.getAuthenticationData().getName())) { + if (!couldLoginUserByName(session.getAuthData().getName())) { LoginEncryptionUtils.showLoginWindow(session); } // else we were able to log the user in @@ -126,9 +126,4 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { boolean defaultHandler(BedrockPacket packet) { return translateAndDefault(packet); } - - @Override - public boolean handle(InventoryTransactionPacket packet) { - return translateAndDefault(packet); - } } diff --git a/connector/src/main/java/org/geysermc/connector/network/remote/RemoteJavaServer.java b/connector/src/main/java/org/geysermc/connector/network/remote/RemoteServer.java similarity index 93% rename from connector/src/main/java/org/geysermc/connector/network/remote/RemoteJavaServer.java rename to connector/src/main/java/org/geysermc/connector/network/remote/RemoteServer.java index 2aab50df6..c65301d0c 100644 --- a/connector/src/main/java/org/geysermc/connector/network/remote/RemoteJavaServer.java +++ b/connector/src/main/java/org/geysermc/connector/network/remote/RemoteServer.java @@ -27,11 +27,10 @@ package org.geysermc.connector.network.remote; import lombok.AllArgsConstructor; import lombok.Getter; -import org.geysermc.api.RemoteServer; @Getter @AllArgsConstructor -public class RemoteJavaServer implements RemoteServer { +public class RemoteServer { private String address; private int port; diff --git a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java index 439676707..5972d7152 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java @@ -30,11 +30,9 @@ import com.github.steveice10.mc.auth.exception.request.RequestException; import com.github.steveice10.mc.protocol.MinecraftProtocol; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerRespawnPacket; +import com.github.steveice10.mc.protocol.packet.handshake.client.HandshakePacket; import com.github.steveice10.packetlib.Client; -import com.github.steveice10.packetlib.event.session.ConnectedEvent; -import com.github.steveice10.packetlib.event.session.DisconnectedEvent; -import com.github.steveice10.packetlib.event.session.PacketReceivedEvent; -import com.github.steveice10.packetlib.event.session.SessionAdapter; +import com.github.steveice10.packetlib.event.session.*; import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.tcp.TcpSessionFactory; import com.nukkitx.math.GenericMath; @@ -49,33 +47,44 @@ import com.nukkitx.protocol.bedrock.data.GamePublishSetting; import com.nukkitx.protocol.bedrock.data.GameRuleData; import com.nukkitx.protocol.bedrock.data.PlayerPermission; import com.nukkitx.protocol.bedrock.packet.*; + import lombok.Getter; import lombok.Setter; -import org.geysermc.api.Player; -import org.geysermc.api.RemoteServer; -import org.geysermc.api.session.AuthData; -import org.geysermc.api.window.FormWindow; + +import org.geysermc.common.AuthType; +import org.geysermc.common.window.FormWindow; import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.command.CommandSender; import org.geysermc.connector.entity.PlayerEntity; import org.geysermc.connector.inventory.PlayerInventory; +import org.geysermc.connector.network.remote.RemoteServer; +import org.geysermc.connector.network.session.auth.AuthData; +import org.geysermc.connector.network.session.auth.BedrockClientData; import org.geysermc.connector.network.session.cache.*; import org.geysermc.connector.network.translators.Registry; import org.geysermc.connector.network.translators.block.BlockTranslator; import org.geysermc.connector.utils.ChunkUtils; import org.geysermc.connector.utils.Toolbox; +import org.geysermc.floodgate.util.BedrockData; +import org.geysermc.floodgate.util.EncryptionUtil; +import java.io.IOException; import java.net.InetSocketAddress; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; @Getter -public class GeyserSession implements Player { +public class GeyserSession implements CommandSender { private final GeyserConnector connector; private final UpstreamSession upstream; private RemoteServer remoteServer; private Client downstream; - private AuthData authenticationData; + @Setter private AuthData authData; + @Setter private BedrockClientData clientData; private PlayerEntity playerEntity; private PlayerInventory inventory; @@ -139,9 +148,14 @@ public class GeyserSession implements Player { public void connect(RemoteServer remoteServer) { startGame(); this.remoteServer = remoteServer; - if (!(connector.getConfig().getRemote().getAuthType().hashCode() == "online".hashCode())) { - connector.getLogger().info("Attempting to login using offline mode... authentication is disabled."); - authenticate(authenticationData.getName()); + if (connector.getAuthType() != AuthType.ONLINE) { + connector.getLogger().info( + "Attempting to login using " + connector.getAuthType().name().toLowerCase() + " mode... " + + (connector.getAuthType() == AuthType.OFFLINE ? + "authentication is disabled." : "authentication will be encrypted" + ) + ); + authenticate(authData.getName()); } ChunkUtils.sendEmptyChunks(this, playerEntity.getPosition().toInt(), 0, false); @@ -185,14 +199,62 @@ public class GeyserSession implements Player { protocol = new MinecraftProtocol(username); } + boolean floodgate = connector.getAuthType() == AuthType.FLOODGATE; + final PublicKey publicKey; + + if (floodgate) { + PublicKey key = null; + try { + key = EncryptionUtil.getKeyFromFile( + connector.getConfig().getFloodgateKeyFile(), + PublicKey.class + ); + } catch (IOException | InvalidKeySpecException | NoSuchAlgorithmException e) { + connector.getLogger().error("Error while reading Floodgate key file", e); + } + publicKey = key; + } else publicKey = null; + + if (publicKey != null) { + connector.getLogger().info("Loaded Floodgate key!"); + } + downstream = new Client(remoteServer.getAddress(), remoteServer.getPort(), protocol, new TcpSessionFactory()); downstream.getSession().addListener(new SessionAdapter() { + @Override + public void packetSending(PacketSendingEvent event) { + //todo move this somewhere else + if (event.getPacket() instanceof HandshakePacket && floodgate) { + String encrypted = ""; + try { + encrypted = EncryptionUtil.encryptBedrockData(publicKey, new BedrockData( + clientData.getGameVersion(), + authData.getName(), + authData.getXboxUUID(), + clientData.getDeviceOS().ordinal(), + clientData.getLanguageCode(), + clientData.getCurrentInputMode().ordinal(), + upstream.getSession().getAddress().getAddress().getHostAddress() + )); + } catch (Exception e) { + connector.getLogger().error("Failed to encrypt message", e); + } + + HandshakePacket handshakePacket = event.getPacket(); + event.setPacket(new HandshakePacket( + handshakePacket.getProtocolVersion(), + handshakePacket.getHostname() + '\0' + BedrockData.FLOODGATE_IDENTIFIER + '\0' + encrypted, + handshakePacket.getPort(), + handshakePacket.getIntent() + )); + } + } @Override public void connected(ConnectedEvent event) { loggingIn = false; loggedIn = true; - connector.getLogger().info(authenticationData.getName() + " (logged in as: " + protocol.getProfile().getName() + ")" + " has connected to remote java server on address " + remoteServer.getAddress()); + connector.getLogger().info(authData.getName() + " (logged in as: " + protocol.getProfile().getName() + ")" + " has connected to remote java server on address " + remoteServer.getAddress()); playerEntity.setUuid(protocol.getProfile().getId()); playerEntity.setUsername(protocol.getProfile().getName()); } @@ -201,7 +263,7 @@ public class GeyserSession implements Player { public void disconnected(DisconnectedEvent event) { loggingIn = false; loggedIn = false; - connector.getLogger().info(authenticationData.getName() + " has disconnected from remote java server on address " + remoteServer.getAddress() + " because of " + event.getReason()); + connector.getLogger().info(authData.getName() + " has disconnected from remote java server on address " + remoteServer.getAddress() + " because of " + event.getReason()); upstream.disconnect(event.getReason()); } @@ -245,21 +307,17 @@ public class GeyserSession implements Player { closed = true; } - public boolean isClosed() { - return closed; - } - public void close() { disconnect("Server closed."); } public void setAuthenticationData(AuthData authData) { - authenticationData = authData; + this.authData = authData; } @Override public String getName() { - return authenticationData.getName(); + return authData.getName(); } @Override @@ -276,10 +334,8 @@ public class GeyserSession implements Player { } @Override - public void sendMessage(String[] messages) { - for (String message : messages) { - sendMessage(message); - } + public boolean isConsole() { + return false; } public void sendForm(FormWindow window, int id) { @@ -296,7 +352,6 @@ public class GeyserSession implements Player { upstream.sendPacket(chunkRadiusUpdatedPacket); } - @Override public InetSocketAddress getSocketAddress() { return this.upstream.getAddress(); } diff --git a/connector/src/main/java/org/geysermc/connector/network/session/auth/BedrockAuthData.java b/connector/src/main/java/org/geysermc/connector/network/session/auth/AuthData.java similarity index 72% rename from connector/src/main/java/org/geysermc/connector/network/session/auth/BedrockAuthData.java rename to connector/src/main/java/org/geysermc/connector/network/session/auth/AuthData.java index 47d79ed85..9674f8db2 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/auth/BedrockAuthData.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/auth/AuthData.java @@ -2,13 +2,12 @@ package org.geysermc.connector.network.session.auth; import lombok.AllArgsConstructor; import lombok.Getter; -import org.geysermc.api.session.AuthData; import java.util.UUID; @Getter @AllArgsConstructor -public class BedrockAuthData implements AuthData { +public class AuthData { private String name; private UUID UUID; diff --git a/connector/src/main/java/org/geysermc/connector/network/session/auth/BedrockClientData.java b/connector/src/main/java/org/geysermc/connector/network/session/auth/BedrockClientData.java new file mode 100644 index 000000000..3793e5227 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/session/auth/BedrockClientData.java @@ -0,0 +1,92 @@ +package org.geysermc.connector.network.session.auth; + +import com.fasterxml.jackson.annotation.JsonEnumDefaultValue; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; + +import java.util.UUID; + +@JsonIgnoreProperties(ignoreUnknown = true) +@Getter +public class BedrockClientData { + @JsonProperty(value = "GameVersion") + private String gameVersion; + @JsonProperty(value = "ServerAddress") + private String serverAddress; + @JsonProperty(value = "ThirdPartyName") + private String username; + @JsonProperty(value = "LanguageCode") + private String languageCode; + + @JsonProperty(value = "SkinId") + private String skinId; + @JsonProperty(value = "SkinData") + private String skinData; + @JsonProperty(value = "CapeId") + private String capeId; + @JsonProperty(value = "CapeData") + private byte[] capeData; + @JsonProperty(value = "CapeOnClassicSkin") + private boolean capeOnClassicSkin; + @JsonProperty(value = "SkinResourcePatch") + private String geometryName; + @JsonProperty(value = "SkinGeometryData") + private String geometryData; + @JsonProperty(value = "PremiumSkin") + private boolean premiumSkin; + + @JsonProperty(value = "DeviceId") + private String deviceId; + @JsonProperty(value = "DeviceModel") + private String deviceModel; + @JsonProperty(value = "DeviceOS") + private DeviceOS deviceOS; + @JsonProperty(value = "UIProfile") + private UIProfile uiProfile; + @JsonProperty(value = "GuiScale") + private int guiScale; + @JsonProperty(value = "CurrentInputMode") + private InputMode currentInputMode; + @JsonProperty(value = "DefaultInputMode") + private InputMode defaultInputMode; + @JsonProperty("PlatformOnlineId") + private String platformOnlineId; + @JsonProperty(value = "PlatformOfflineId") + private String platformOfflineId; + @JsonProperty(value = "SelfSignedId") + private UUID selfSignedId; + @JsonProperty(value = "ClientRandomId") + private long clientRandomId; + + public enum UIProfile { + @JsonEnumDefaultValue + CLASSIC, + POCKET + } + + public enum DeviceOS { + @JsonEnumDefaultValue + UNKOWN, + ANDROID, + IOS, + OSX, + FIREOS, + GEARVR, + HOLOLENS, + WIN10, + WIN32, + DEDICATED, + ORBIS, + NX, + SWITCH + } + + public enum InputMode { + @JsonEnumDefaultValue + UNKNOWN, + KEYBOARD_MOUSE, + TOUCH, // I guess Touch? + CONTROLLER + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/session/cache/WindowCache.java b/connector/src/main/java/org/geysermc/connector/network/session/cache/WindowCache.java index 58843a0e8..1d10e4db9 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/cache/WindowCache.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/cache/WindowCache.java @@ -26,14 +26,14 @@ package org.geysermc.connector.network.session.cache; import com.nukkitx.protocol.bedrock.packet.ModalFormRequestPacket; + import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import lombok.Getter; -import org.geysermc.connector.network.session.GeyserSession; -import org.geysermc.api.window.FormWindow; -import java.util.HashMap; -import java.util.Map; +import lombok.Getter; + +import org.geysermc.common.window.FormWindow; +import org.geysermc.connector.network.session.GeyserSession; public class WindowCache { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/Registry.java b/connector/src/main/java/org/geysermc/connector/network/translators/Registry.java index 96f94212b..f32fe4b6d 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/Registry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/Registry.java @@ -27,7 +27,7 @@ package org.geysermc.connector.network.translators; import com.github.steveice10.packetlib.packet.Packet; import com.nukkitx.protocol.bedrock.BedrockPacket; -import org.geysermc.connector.console.GeyserLogger; +import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; import java.util.HashMap; @@ -55,7 +55,7 @@ public class Registry { return true; } } catch (Throwable ex) { - GeyserLogger.DEFAULT.error("Could not translate packet " + packet.getClass().getSimpleName(), ex); + GeyserConnector.getInstance().getLogger().error("Could not translate packet " + packet.getClass().getSimpleName(), ex); ex.printStackTrace(); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java index 93d07891e..292eb7958 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java @@ -36,6 +36,7 @@ import com.github.steveice10.mc.protocol.packet.ingame.server.scoreboard.ServerT import com.github.steveice10.mc.protocol.packet.ingame.server.scoreboard.ServerUpdateScorePacket; import com.github.steveice10.mc.protocol.packet.ingame.server.window.*; import com.github.steveice10.mc.protocol.packet.ingame.server.world.*; +import com.github.steveice10.mc.protocol.packet.login.server.LoginPluginRequestPacket; import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.NbtUtils; import com.nukkitx.nbt.stream.NBTOutputStream; @@ -91,6 +92,8 @@ public class TranslatorsInit { } public static void start() { + Registry.registerJava(LoginPluginRequestPacket.class, new JavaLoginPluginMessageTranslator()); + Registry.registerJava(ServerJoinGamePacket.class, new JavaJoinGameTranslator()); Registry.registerJava(ServerPluginMessagePacket.class, new JavaPluginMessageTranslator()); Registry.registerJava(ServerChatPacket.class, new JavaChatTranslator()); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockCommandRequestTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockCommandRequestTranslator.java index df0058474..19d1a55f6 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockCommandRequestTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockCommandRequestTranslator.java @@ -27,7 +27,8 @@ package org.geysermc.connector.network.translators.bedrock; import com.github.steveice10.mc.protocol.packet.ingame.client.ClientChatPacket; import com.nukkitx.protocol.bedrock.packet.CommandRequestPacket; -import org.geysermc.api.Geyser; + +import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; @@ -36,8 +37,8 @@ public class BedrockCommandRequestTranslator extends PacketTranslator { TextPacket textPacket = new TextPacket(); textPacket.setPlatformChatId(""); textPacket.setSourceName(""); - textPacket.setXuid(session.getAuthenticationData().getXboxUUID()); + textPacket.setXuid(session.getAuthData().getXboxUUID()); switch (packet.getType()) { case CHAT: textPacket.setType(TextPacket.Type.CHAT); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaLoginPluginMessageTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaLoginPluginMessageTranslator.java new file mode 100644 index 000000000..f92fca9f9 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaLoginPluginMessageTranslator.java @@ -0,0 +1,16 @@ +package org.geysermc.connector.network.translators.java; + +import com.github.steveice10.mc.protocol.packet.login.client.LoginPluginResponsePacket; +import com.github.steveice10.mc.protocol.packet.login.server.LoginPluginRequestPacket; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.PacketTranslator; + +public class JavaLoginPluginMessageTranslator extends PacketTranslator { + @Override + public void translate(LoginPluginRequestPacket packet, GeyserSession session) { + // A vanilla client doesn't know any PluginMessage in the Login state, so we don't know any either. + session.getDownstream().getSession().send( + new LoginPluginResponsePacket(packet.getMessageId(), null) + ); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerPositionRotationTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerPositionRotationTranslator.java index 5db813eb5..0c6b9258a 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerPositionRotationTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerPositionRotationTranslator.java @@ -31,7 +31,9 @@ import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.data.EntityEventType; import com.nukkitx.protocol.bedrock.packet.*; -import org.geysermc.connector.console.GeyserLogger; +import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket; +import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket; + import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; @@ -82,7 +84,7 @@ public class JavaPlayerPositionRotationTranslator extends PacketTranslator { // #slowdownbrother, just don't execute it directly + GeyserConnector.getInstance().getGeneralThreadPool().execute(() -> { // #slowdownbrother, just don't execute it directly PaintingEntity entity = new PaintingEntity( packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(), diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnPlayerTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnPlayerTranslator.java index 1e1518685..f737a13c3 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnPlayerTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnPlayerTranslator.java @@ -27,7 +27,8 @@ package org.geysermc.connector.network.translators.java.entity.spawn; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnPlayerPacket; import com.nukkitx.math.vector.Vector3f; -import org.geysermc.api.Geyser; + +import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.entity.PlayerEntity; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; @@ -43,7 +44,7 @@ public class JavaSpawnPlayerTranslator extends PacketTranslator { @Override public void translate(ServerTeamPacket packet, GeyserSession session) { - Geyser.getLogger().debug("Team packet " + packet.getTeamName() + " " + packet.getAction()+" "+ Arrays.toString(packet.getPlayers())); + GeyserConnector.getInstance().getLogger().debug("Team packet " + packet.getTeamName() + " " + packet.getAction()+" "+ Arrays.toString(packet.getPlayers())); Scoreboard scoreboard = session.getScoreboardCache().getScoreboard(); switch (packet.getAction()) { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/scoreboard/JavaUpdateScoreTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/scoreboard/JavaUpdateScoreTranslator.java index 47e99794b..5232823d0 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/scoreboard/JavaUpdateScoreTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/scoreboard/JavaUpdateScoreTranslator.java @@ -27,7 +27,8 @@ package org.geysermc.connector.network.translators.java.scoreboard; import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardAction; import com.github.steveice10.mc.protocol.packet.ingame.server.scoreboard.ServerUpdateScorePacket; -import org.geysermc.api.Geyser; + +import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.scoreboard.Objective; @@ -42,7 +43,7 @@ public class JavaUpdateScoreTranslator extends PacketTranslator InventoryUtils.openInventory(session, newInventory), 500, TimeUnit.MILLISECONDS); + GeyserConnector.getInstance().getGeneralThreadPool().schedule(() -> InventoryUtils.openInventory(session, newInventory), 500, TimeUnit.MILLISECONDS); return; } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java index e48be2d89..f570bb0b0 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java @@ -31,9 +31,11 @@ import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerChunkD import com.nukkitx.math.vector.Vector3i; import com.nukkitx.network.VarInts; import com.nukkitx.protocol.bedrock.packet.LevelChunkPacket; + import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; -import org.geysermc.api.Geyser; + +import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.BiomeTranslator; import org.geysermc.connector.network.translators.PacketTranslator; @@ -45,7 +47,7 @@ public class JavaChunkDataTranslator extends PacketTranslator { + GeyserConnector.getInstance().getGeneralThreadPool().execute(() -> { try { if (packet.getColumn().getBiomeData() != null) { //Full chunk ChunkUtils.ChunkData chunkData = ChunkUtils.translateToBedrock(packet.getColumn()); diff --git a/connector/src/main/java/org/geysermc/connector/plugin/GeyserPluginLoader.java b/connector/src/main/java/org/geysermc/connector/plugin/GeyserPluginLoader.java deleted file mode 100644 index 894b34475..000000000 --- a/connector/src/main/java/org/geysermc/connector/plugin/GeyserPluginLoader.java +++ /dev/null @@ -1,126 +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.plugin; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; -import com.nukkitx.protocol.bedrock.handler.BedrockPacketHandler; -import org.geysermc.api.Connector; -import org.geysermc.api.plugin.Plugin; -import java.io.File; -import java.io.InputStream; -import java.lang.reflect.Field; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -public class GeyserPluginLoader extends ClassLoader { - - private Connector connector; - - public GeyserPluginLoader(Connector connector) { - this.connector = connector; - } - - public void loadPlugins() { - File dir = new File("plugins"); - - if (!dir.exists()) { - dir.mkdir(); - } - - for (File f : dir.listFiles()) { - if (!f.getName().toLowerCase().endsWith(".jar")) - continue; - - try { - ZipFile file = new ZipFile(f); - ZipEntry e = file.getEntry("plugin.yml"); - - if (e == null || e.isDirectory()) { - connector.getLogger().severe("Plugin " + f.getName() + " has no valid plugin.yml!"); - continue; - } - - file.stream().forEach((x) -> { - if (x.getName().endsWith(".class")) { - try { - InputStream is = file.getInputStream(x); - byte[] b = new byte[is.available()]; - is.read(b); - this.defineClass(x.getName().replace(".class", "").replaceAll("/", "."), b, 0, b.length); - is.close(); - } catch (Exception e1) { - e1.printStackTrace(); - } - } - }); - - ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); - InputStream is = file.getInputStream(e); - - PluginYML yml = mapper.readValue(is, PluginYML.class); - is.close(); - Plugin plugin = (Plugin) Class.forName(yml.main, true, this).newInstance(); - - Class cl = Plugin.class; - - Field name = cl.getDeclaredField("name"); - name.setAccessible(true); - - Field version = cl.getDeclaredField("version"); - version.setAccessible(true); - - name.set(plugin, yml.name); - - version.set(plugin, yml.version); - - connector.getLogger().info("Loading plugin " + yml.name + " version " + yml.version); - connector.getPluginManager().loadPlugin(plugin); - } catch (Exception e) { - connector.getLogger().severe("Error loading plugin " + f.getName()); - e.printStackTrace(); - } - } - - for (Plugin plugin : connector.getPluginManager().getPlugins()) { - connector.getPluginManager().enablePlugin(plugin); - } - } - - public void loadPlugin(Plugin plugin) { - plugin.onLoad(); - } - - public void enablePlugin(Plugin plugin) { - plugin.setEnabled(true); - plugin.onEnable(); - } - - public void disablePlugin(Plugin plugin) { - plugin.setEnabled(false); - plugin.onDisable(); - } -} diff --git a/connector/src/main/java/org/geysermc/connector/plugin/GeyserPluginManager.java b/connector/src/main/java/org/geysermc/connector/plugin/GeyserPluginManager.java deleted file mode 100644 index 470dd23e0..000000000 --- a/connector/src/main/java/org/geysermc/connector/plugin/GeyserPluginManager.java +++ /dev/null @@ -1,107 +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.plugin; - -import lombok.Getter; -import org.geysermc.api.events.EventHandler; -import org.geysermc.api.events.Listener; -import org.geysermc.api.plugin.Plugin; -import org.geysermc.api.plugin.PluginManager; - -import java.awt.*; -import java.lang.reflect.Method; -import java.util.*; -import java.util.List; - -public class GeyserPluginManager implements PluginManager { - private final List EVENTS = new ArrayList<>(); - - @Getter - private GeyserPluginLoader loader; - - private Map plugins = new HashMap<>(); - - public GeyserPluginManager(GeyserPluginLoader loader) { - this.loader = loader; - } - - public void loadPlugin(Plugin plugin) { - loader.loadPlugin(plugin); - plugins.put(plugin.getName(), plugin); - } - - public void unloadPlugin(Plugin plugin) { - plugins.remove(plugin); - } - - public void enablePlugin(Plugin plugin) { - loader.enablePlugin(plugin); - } - - public void disablePlugin(Plugin plugin) { - loader.disablePlugin(plugin); - } - - public Set getPlugins() { - return new HashSet<>(plugins.values()); - } - - @Override - public void registerEventListener(Plugin p, Listener l) { - try { - Class clazz = l.getClass(); - - for(Method m : clazz.getMethods()) { - if(m.getAnnotation(EventHandler.class) != null) { - PluginListener listener = new PluginListener(); - - listener.plugin = p; - listener.listener = l; - listener.clazz = m.getParameterTypes()[0]; - listener.priority = m.getAnnotation(EventHandler.class).value(); - listener.run = m; - EVENTS.add(listener); - } - } - } catch (Exception e) { - // - } - } - - @Override - public void runEvent(Object o) { - for(EventHandler.EventPriority p : EventHandler.EventPriority.values()) { - for (PluginListener listener : EVENTS) { - listener.runIfNeeded(p, o); - } - } - } - - @Override - public Plugin getPluginByName(String name) { - return plugins.get(name); - } -} \ No newline at end of file diff --git a/connector/src/main/java/org/geysermc/connector/plugin/PluginListener.java b/connector/src/main/java/org/geysermc/connector/plugin/PluginListener.java deleted file mode 100644 index 605572f19..000000000 --- a/connector/src/main/java/org/geysermc/connector/plugin/PluginListener.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.geysermc.connector.plugin; - -import org.geysermc.api.events.EventHandler; -import org.geysermc.api.events.Listener; -import org.geysermc.api.plugin.Plugin; -import org.geysermc.connector.console.GeyserLogger; - -import java.lang.reflect.Method; - -public class PluginListener { - Method run; - Plugin plugin; - Listener listener; - Class clazz; - EventHandler.EventPriority priority; - - void runIfNeeded(EventHandler.EventPriority p, Object o) { - if(p.equals(priority) && clazz.isInstance(o)) { - try { - run.invoke(listener, o); - } catch (ReflectiveOperationException ex) { - GeyserLogger.DEFAULT.severe("Exception while trying to run event! Contact the maintainer of " + plugin.getName()); - - ex.printStackTrace(); - } - } - } -} diff --git a/connector/src/main/java/org/geysermc/connector/plugin/PluginYML.java b/connector/src/main/java/org/geysermc/connector/plugin/PluginYML.java deleted file mode 100644 index 154253692..000000000 --- a/connector/src/main/java/org/geysermc/connector/plugin/PluginYML.java +++ /dev/null @@ -1,40 +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.plugin; - -import com.fasterxml.jackson.annotation.JsonProperty; - -public class PluginYML { - - @JsonProperty("name") - String name; - - @JsonProperty("version") - String version; - - @JsonProperty("main") - String main; -} diff --git a/connector/src/main/java/org/geysermc/connector/scoreboard/Scoreboard.java b/connector/src/main/java/org/geysermc/connector/scoreboard/Scoreboard.java index a57e0247d..48fe492f4 100644 --- a/connector/src/main/java/org/geysermc/connector/scoreboard/Scoreboard.java +++ b/connector/src/main/java/org/geysermc/connector/scoreboard/Scoreboard.java @@ -31,7 +31,7 @@ import com.nukkitx.protocol.bedrock.packet.RemoveObjectivePacket; import com.nukkitx.protocol.bedrock.packet.SetDisplayObjectivePacket; import com.nukkitx.protocol.bedrock.packet.SetScorePacket; import lombok.Getter; -import org.geysermc.api.Geyser; + import org.geysermc.connector.network.session.GeyserSession; import java.util.*; @@ -77,7 +77,7 @@ public class Scoreboard { public Team registerNewTeam(String teamName, Set players) { if (teams.containsKey(teamName)) { - Geyser.getLogger().info("Ignoring team " + teamName + ". It overrides without removing old team."); + session.getConnector().getLogger().info("Ignoring team " + teamName + ". It overrides without removing old team."); return getTeam(teamName); } @@ -120,7 +120,7 @@ public class Scoreboard { for (String objectiveId : new ArrayList<>(objectives.keySet())) { Objective objective = objectives.get(objectiveId); if (objective.isTemp()) { - Geyser.getLogger().debug("Ignoring temp Scoreboard Objective '"+ objectiveId +'\''); + session.getConnector().getLogger().debug("Ignoring temp Scoreboard Objective '"+ objectiveId +'\''); continue; } diff --git a/connector/src/main/java/org/geysermc/connector/utils/FileUtils.java b/connector/src/main/java/org/geysermc/connector/utils/FileUtils.java index c6c31f01f..3070e743d 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/FileUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/FileUtils.java @@ -27,20 +27,26 @@ package org.geysermc.connector.utils; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; + import org.geysermc.connector.GeyserConnector; import java.io.*; import java.util.function.Function; public class FileUtils { + public static T loadConfig(File src, Class valueType) throws IOException { ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory()); return objectMapper.readValue(src, valueType); } public static File fileOrCopiedFromResource(String name, Function s) throws IOException { - File file = new File(name); + return fileOrCopiedFromResource(new File(name), name, s); + } + + public static File fileOrCopiedFromResource(File file, String name, Function s) throws IOException { if (!file.exists()) { + file.createNewFile(); FileOutputStream fos = new FileOutputStream(file); InputStream input = GeyserConnector.class.getResourceAsStream("/" + name); // resources need leading "/" prefix @@ -59,6 +65,4 @@ public class FileUtils { return file; } - - } diff --git a/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java b/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java index 8eb407d05..23f22fedf 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java @@ -30,7 +30,7 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.nukkitx.protocol.bedrock.data.ContainerId; import com.nukkitx.protocol.bedrock.data.ItemData; import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket; -import org.geysermc.api.Geyser; +import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.TranslatorsInit; @@ -50,7 +50,7 @@ public class InventoryUtils { translator.prepareInventory(session, inventory); //TODO: find better way to handle double chest delay if (translator instanceof DoubleChestInventoryTranslator) { - Geyser.getGeneralThreadPool().schedule(() -> { + GeyserConnector.getInstance().getGeneralThreadPool().schedule(() -> { translator.openInventory(session, inventory); translator.updateInventory(session, inventory); }, 200, TimeUnit.MILLISECONDS); diff --git a/connector/src/main/java/org/geysermc/connector/utils/LoginEncryptionUtils.java b/connector/src/main/java/org/geysermc/connector/utils/LoginEncryptionUtils.java index ec80b5254..7f6c8eda1 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/LoginEncryptionUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/LoginEncryptionUtils.java @@ -34,17 +34,19 @@ import com.nukkitx.network.util.Preconditions; import com.nukkitx.protocol.bedrock.packet.LoginPacket; import com.nukkitx.protocol.bedrock.packet.ServerToClientHandshakePacket; import com.nukkitx.protocol.bedrock.util.EncryptionUtils; + import net.minidev.json.JSONObject; -import org.geysermc.api.events.player.PlayerFormResponseEvent; -import org.geysermc.api.window.CustomFormBuilder; -import org.geysermc.api.window.CustomFormWindow; -import org.geysermc.api.window.FormWindow; -import org.geysermc.api.window.component.InputComponent; -import org.geysermc.api.window.component.LabelComponent; -import org.geysermc.api.window.response.CustomFormResponse; + +import org.geysermc.common.window.CustomFormBuilder; +import org.geysermc.common.window.CustomFormWindow; +import org.geysermc.common.window.FormWindow; +import org.geysermc.common.window.component.InputComponent; +import org.geysermc.common.window.component.LabelComponent; +import org.geysermc.common.window.response.CustomFormResponse; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; -import org.geysermc.connector.network.session.auth.BedrockAuthData; +import org.geysermc.connector.network.session.auth.AuthData; +import org.geysermc.connector.network.session.auth.BedrockClientData; import org.geysermc.connector.network.session.cache.WindowCache; import javax.crypto.SecretKey; @@ -97,7 +99,7 @@ public class LoginEncryptionUtils { encryptConnectionWithCert(connector, session, loginPacket.getSkinData().toString(), certChainData); } - private static void encryptConnectionWithCert(GeyserConnector connector, GeyserSession session, String playerSkin, JsonNode certChainData) { + private static void encryptConnectionWithCert(GeyserConnector connector, GeyserSession session, String clientData, JsonNode certChainData) { try { boolean validChain = validateChainData(certChainData); @@ -110,17 +112,23 @@ public class LoginEncryptionUtils { throw new RuntimeException("AuthData was not found!"); } - JSONObject extraData = (JSONObject) jwt.getPayload().toJSONObject().get("extraData"); - session.setAuthenticationData(new BedrockAuthData(extraData.getAsString("displayName"), UUID.fromString(extraData.getAsString("identity")), extraData.getAsString("XUID"))); + JsonNode extraData = payload.get("extraData"); + session.setAuthenticationData(new AuthData( + extraData.get("displayName").asText(), + UUID.fromString(extraData.get("identity").asText()), + extraData.get("XUID").asText() + )); if (payload.get("identityPublicKey").getNodeType() != JsonNodeType.STRING) { throw new RuntimeException("Identity Public Key was not found!"); } ECPublicKey identityPublicKey = EncryptionUtils.generateKey(payload.get("identityPublicKey").textValue()); - JWSObject clientJwt = JWSObject.parse(playerSkin); + JWSObject clientJwt = JWSObject.parse(clientData); EncryptionUtils.verifyJwt(clientJwt, identityPublicKey); + session.setClientData(JSON_MAPPER.convertValue(JSON_MAPPER.readTree(clientJwt.getPayload().toBytes()), BedrockClientData.class)); + if (EncryptionUtils.canUseEncryption()) { LoginEncryptionUtils.startEncryptionHandshake(session, identityPublicKey); } @@ -165,17 +173,13 @@ public class LoginEncryptionUtils { FormWindow window = windowCache.getWindows().remove(AUTH_FORM_ID); window.setResponse(formData.trim()); - if (session.isLoggedIn()) { - PlayerFormResponseEvent event = new PlayerFormResponseEvent(session, AUTH_FORM_ID, window); - connector.getPluginManager().runEvent(event); - } else { + if (!session.isLoggedIn()) { if (window instanceof CustomFormWindow) { CustomFormWindow customFormWindow = (CustomFormWindow) window; if (!customFormWindow.getTitle().equals("Login")) return false; CustomFormResponse response = (CustomFormResponse) customFormWindow.getResponse(); - if (response != null) { String email = response.getInputResponses().get(2); String password = response.getInputResponses().get(3); @@ -183,7 +187,6 @@ public class LoginEncryptionUtils { session.authenticate(email, password); } - // TODO should we clear the window cache in all cases or just if not already logged in? // Clear windows so authentication data isn't accidentally cached windowCache.getWindows().clear(); } diff --git a/connector/src/main/java/org/geysermc/connector/utils/SkinProvider.java b/connector/src/main/java/org/geysermc/connector/utils/SkinProvider.java index 5f1734073..c6f53ae9b 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/SkinProvider.java +++ b/connector/src/main/java/org/geysermc/connector/utils/SkinProvider.java @@ -27,16 +27,16 @@ package org.geysermc.connector.utils; import com.google.gson.Gson; import com.google.gson.GsonBuilder; + import lombok.AllArgsConstructor; import lombok.Getter; -import org.geysermc.api.Geyser; + import org.geysermc.connector.GeyserConnector; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; -import java.io.IOException; import java.net.URL; import java.util.Map; import java.util.UUID; @@ -44,7 +44,7 @@ import java.util.concurrent.*; public class SkinProvider { public static final Gson GSON = new GsonBuilder().create(); - public static final boolean ALLOW_THIRD_PARTY_CAPES = ((GeyserConnector)Geyser.getConnector()).getConfig().isAllowThirdPartyCapes(); + public static final boolean ALLOW_THIRD_PARTY_CAPES = GeyserConnector.getInstance().getConfig().isAllowThirdPartyCapes(); private static final ExecutorService EXECUTOR_SERVICE = Executors.newFixedThreadPool(ALLOW_THIRD_PARTY_CAPES ? 21 : 14); public static final byte[] STEVE_SKIN = new ProvidedSkin("bedrock/skin/skin_steve.png").getSkin(); @@ -83,7 +83,7 @@ public class SkinProvider { getOrDefault(requestCape(capeUrl, false), EMPTY_CAPE, 5) ); - Geyser.getLogger().debug("Took " + (System.currentTimeMillis() - time) + "ms for " + playerId); + GeyserConnector.getInstance().getLogger().debug("Took " + (System.currentTimeMillis() - time) + "ms for " + playerId); return skinAndCape; }, EXECUTOR_SERVICE); } @@ -187,7 +187,7 @@ public class SkinProvider { private static byte[] requestImage(String imageUrl, boolean cape) throws Exception { BufferedImage image = ImageIO.read(new URL(imageUrl)); - Geyser.getLogger().debug("Downloaded " + imageUrl); + GeyserConnector.getInstance().getLogger().debug("Downloaded " + imageUrl); if (cape) { image = image.getWidth() > 64 ? scale(image) : image; @@ -198,8 +198,7 @@ public class SkinProvider { image = newImage; } - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(image.getWidth() * 4 + image.getHeight() * 4); - try { + try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream(image.getWidth() * 4 + image.getHeight() * 4)) { for (int y = 0; y < image.getHeight(); y++) { for (int x = 0; x < image.getWidth(); x++) { int rgba = image.getRGB(x, y); @@ -211,10 +210,6 @@ public class SkinProvider { } image.flush(); return outputStream.toByteArray(); - } finally { - try { - outputStream.close(); - } catch (IOException ignored) {} } } 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 ef5bc9d9d..6e1444983 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java @@ -30,9 +30,11 @@ import com.google.gson.JsonObject; import com.nukkitx.protocol.bedrock.data.ImageData; import com.nukkitx.protocol.bedrock.data.SerializedSkin; import com.nukkitx.protocol.bedrock.packet.PlayerListPacket; + import lombok.AllArgsConstructor; import lombok.Getter; -import org.geysermc.api.Geyser; + +import org.geysermc.common.AuthType; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.entity.PlayerEntity; import org.geysermc.connector.network.session.GeyserSession; @@ -44,6 +46,7 @@ import java.util.UUID; import java.util.function.Consumer; public class SkinUtils { + public static PlayerListPacket.Entry buildCachedEntry(GameProfile profile, long geyserId) { GameProfileData data = GameProfileData.from(profile); SkinProvider.Cape cape = SkinProvider.getCachedCape(data.getCapeUrl()); @@ -121,8 +124,8 @@ public class SkinUtils { return new GameProfileData(skinUrl, capeUrl, isAlex); } catch (Exception exception) { - if (!((GeyserConnector) Geyser.getConnector()).getConfig().getRemote().getAuthType().equals("offline")) { - Geyser.getLogger().debug("Got invalid texture data for " + profile.getName() + " " + exception.getMessage()); + if (GeyserConnector.getInstance().getAuthType() != AuthType.OFFLINE) { + GeyserConnector.getInstance().getLogger().debug("Got invalid texture data for " + profile.getName() + " " + exception.getMessage()); } // return default skin with default cape when texture data is invalid return new GameProfileData(SkinProvider.EMPTY_SKIN.getTextureUrl(), SkinProvider.EMPTY_CAPE.getTextureUrl(), false); @@ -132,7 +135,7 @@ public class SkinUtils { public static void requestAndHandleSkinAndCape(PlayerEntity entity, GeyserSession session, Consumer skinAndCapeConsumer) { - Geyser.getGeneralThreadPool().execute(() -> { + GeyserConnector.getInstance().getGeneralThreadPool().execute(() -> { GameProfileData data = GameProfileData.from(entity.getProfile()); SkinProvider.requestSkinAndCape(entity.getUuid(), data.getSkinUrl(), data.getCapeUrl()) @@ -176,11 +179,12 @@ public class SkinUtils { } } } catch (Exception e) { - Geyser.getLogger().error("Failed getting skin for " + entity.getUuid(), e); + GeyserConnector.getInstance().getLogger().error("Failed getting skin for " + entity.getUuid(), e); } if (skinAndCapeConsumer != null) skinAndCapeConsumer.accept(skinAndCape); }); + }); } diff --git a/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java b/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java index f9900c662..9601b5819 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java +++ b/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java @@ -34,10 +34,11 @@ import com.nukkitx.nbt.stream.NBTInputStream; import com.nukkitx.nbt.tag.CompoundTag; import com.nukkitx.protocol.bedrock.data.ItemData; import com.nukkitx.protocol.bedrock.packet.StartGamePacket; + import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; + import org.geysermc.connector.GeyserConnector; -import org.geysermc.connector.console.GeyserLogger; import org.geysermc.connector.network.translators.item.ItemEntry; import java.io.ByteArrayInputStream; @@ -68,7 +69,7 @@ public class Toolbox { biomesTag = (CompoundTag) biomenbtInputStream.readTag(); BIOMES = biomesTag; } catch (Exception ex) { - GeyserLogger.DEFAULT.warning("Failed to get biomes from biome definitions, is there something wrong with the file?"); + GeyserConnector.getInstance().getLogger().warning("Failed to get biomes from biome definitions, is there something wrong with the file?"); throw new AssertionError(ex); } diff --git a/connector/src/main/resources/config.yml b/connector/src/main/resources/config.yml index 1a77f4ed2..ba5700e27 100644 --- a/connector/src/main/resources/config.yml +++ b/connector/src/main/resources/config.yml @@ -20,10 +20,14 @@ remote: address: 127.0.0.1 # The port of the remote (Java Edition) server port: 25565 - # Authentication type. Can be offline, online, or floodgate (see https://github.com/GeyserMC/Geyser/wiki/Floodgate). auth-type: online +# Floodgate uses encryption to ensure use from authorised sources. +# This should point to the public key generated by Floodgate (Bungee or CraftBukkit) +# You can ignore this when not using Floodgate. +floodgate-key-file: public-key.pem + ## the Xbox/MCPE username is the key for the Java server auth-info ## this allows automatic configuration/login to the remote Java server ## if you are brave/stupid enough to put your Mojang account info into diff --git a/plugin/pom.xml b/plugin/pom.xml deleted file mode 100644 index 9916408b9..000000000 --- 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 98950747b..000000000 --- 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 2f394b5a9..fc1ead33b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 org.geysermc geyser-parent - 1.0-SNAPSHOT + parent pom Geyser Allows for players from Minecraft Bedrock Edition to join Minecraft Java Edition servers. @@ -31,10 +31,9 @@ - api + bootstrap common connector - plugin @@ -91,8 +90,4 @@ provided - - - clean install - diff --git a/screenshots/endcity.png b/screenshots/endcity.png new file mode 100644 index 000000000..65d73b94d Binary files /dev/null and b/screenshots/endcity.png differ diff --git a/screenshots/endportal.png b/screenshots/endportal.png new file mode 100644 index 000000000..0da630b47 Binary files /dev/null and b/screenshots/endportal.png differ diff --git a/screenshots/nether.png b/screenshots/nether.png new file mode 100644 index 000000000..537613922 Binary files /dev/null and b/screenshots/nether.png differ