From ee82c80c47e7279acbde6113ee3e449c5179403a Mon Sep 17 00:00:00 2001 From: Tim203 Date: Wed, 9 Nov 2022 01:51:45 +0100 Subject: [PATCH] Moved the common Floodgate classes to Floodgate. Revert renaming api --- {legacy-api => api}/build.gradle.kts | 1 - .../geysermc/floodgate/api/FloodgateApi.java | 0 .../floodgate/api/InstanceHolder.java | 0 .../api/handshake/HandshakeData.java | 0 .../api/handshake/HandshakeHandler.java | 0 .../api/handshake/HandshakeHandlers.java | 0 .../floodgate/api/inject/InjectorAddon.java | 0 .../api/inject/PlatformInjector.java | 0 .../floodgate/api/link/LinkRequest.java | 0 .../floodgate/api/link/LinkRequestResult.java | 0 .../floodgate/api/link/PlayerLink.java | 0 .../floodgate/api/logger/FloodgateLogger.java | 0 .../floodgate/api/packet/PacketHandler.java | 0 .../floodgate/api/packet/PacketHandlers.java | 0 .../floodgate/api/player/FloodgatePlayer.java | 0 .../geysermc/floodgate/api/unsafe/Unsafe.java | 0 .../floodgate/api/util/TriFunction.java | 0 .../geysermc/floodgate/util/BedrockData.java | 0 .../org/geysermc/floodgate/util/DeviceOs.java | 70 +++++++++ .../geysermc/floodgate/util/InputMode.java | 47 ++++++ .../geysermc/floodgate/util/LinkedPlayer.java | 80 ++++++++++ .../geysermc/floodgate/util/UiProfile.java | 44 ++++++ build.gradle.kts | 2 +- core/build.gradle.kts | 3 +- .../geysermc/floodgate/FloodgatePlatform.java | 2 - .../addon/data/HandshakeDataImpl.java | 2 +- .../geysermc/floodgate/crypto/AesCipher.java | 123 +++++++++++++++ .../floodgate/crypto/AesKeyProducer.java | 73 +++++++++ .../floodgate/crypto/Base64Topping.java | 40 +++++ .../floodgate/crypto/FloodgateCipher.java | 144 ++++++++++++++++++ .../floodgate/crypto/KeyProducer.java | 40 +++++ .../geysermc/floodgate/crypto/Topping.java | 31 ++++ .../org/geysermc/floodgate/news/NewsItem.java | 126 +++++++++++++++ .../floodgate/news/NewsItemAction.java | 44 ++++++ .../floodgate/news/NewsItemMessage.java | 89 +++++++++++ .../org/geysermc/floodgate/news/NewsType.java | 62 ++++++++ .../floodgate/news/data/AnnouncementData.java | 62 ++++++++ .../news/data/BuildSpecificData.java | 62 ++++++++ .../floodgate/news/data/CheckAfterData.java | 44 ++++++ .../news/data/ConfigSpecificData.java | 64 ++++++++ .../floodgate/news/data/ItemData.java | 29 ++++ .../player/FloodgateHandshakeHandler.java | 6 +- .../util/InvalidFormatException.java | 32 ++++ .../floodgate/util/WebsocketEventType.java | 91 +++++++++++ settings.gradle.kts | 2 +- 45 files changed, 1405 insertions(+), 10 deletions(-) rename {legacy-api => api}/build.gradle.kts (79%) rename {legacy-api => api}/src/main/java/org/geysermc/floodgate/api/FloodgateApi.java (100%) rename {legacy-api => api}/src/main/java/org/geysermc/floodgate/api/InstanceHolder.java (100%) rename {legacy-api => api}/src/main/java/org/geysermc/floodgate/api/handshake/HandshakeData.java (100%) rename {legacy-api => api}/src/main/java/org/geysermc/floodgate/api/handshake/HandshakeHandler.java (100%) rename {legacy-api => api}/src/main/java/org/geysermc/floodgate/api/handshake/HandshakeHandlers.java (100%) rename {legacy-api => api}/src/main/java/org/geysermc/floodgate/api/inject/InjectorAddon.java (100%) rename {legacy-api => api}/src/main/java/org/geysermc/floodgate/api/inject/PlatformInjector.java (100%) rename {legacy-api => api}/src/main/java/org/geysermc/floodgate/api/link/LinkRequest.java (100%) rename {legacy-api => api}/src/main/java/org/geysermc/floodgate/api/link/LinkRequestResult.java (100%) rename {legacy-api => api}/src/main/java/org/geysermc/floodgate/api/link/PlayerLink.java (100%) rename {legacy-api => api}/src/main/java/org/geysermc/floodgate/api/logger/FloodgateLogger.java (100%) rename {legacy-api => api}/src/main/java/org/geysermc/floodgate/api/packet/PacketHandler.java (100%) rename {legacy-api => api}/src/main/java/org/geysermc/floodgate/api/packet/PacketHandlers.java (100%) rename {legacy-api => api}/src/main/java/org/geysermc/floodgate/api/player/FloodgatePlayer.java (100%) rename {legacy-api => api}/src/main/java/org/geysermc/floodgate/api/unsafe/Unsafe.java (100%) rename {legacy-api => api}/src/main/java/org/geysermc/floodgate/api/util/TriFunction.java (100%) rename {core => api}/src/main/java/org/geysermc/floodgate/util/BedrockData.java (100%) create mode 100644 api/src/main/java/org/geysermc/floodgate/util/DeviceOs.java create mode 100644 api/src/main/java/org/geysermc/floodgate/util/InputMode.java create mode 100644 api/src/main/java/org/geysermc/floodgate/util/LinkedPlayer.java create mode 100644 api/src/main/java/org/geysermc/floodgate/util/UiProfile.java create mode 100644 core/src/main/java/org/geysermc/floodgate/crypto/AesCipher.java create mode 100644 core/src/main/java/org/geysermc/floodgate/crypto/AesKeyProducer.java create mode 100644 core/src/main/java/org/geysermc/floodgate/crypto/Base64Topping.java create mode 100644 core/src/main/java/org/geysermc/floodgate/crypto/FloodgateCipher.java create mode 100644 core/src/main/java/org/geysermc/floodgate/crypto/KeyProducer.java create mode 100644 core/src/main/java/org/geysermc/floodgate/crypto/Topping.java create mode 100644 core/src/main/java/org/geysermc/floodgate/news/NewsItem.java create mode 100644 core/src/main/java/org/geysermc/floodgate/news/NewsItemAction.java create mode 100644 core/src/main/java/org/geysermc/floodgate/news/NewsItemMessage.java create mode 100644 core/src/main/java/org/geysermc/floodgate/news/NewsType.java create mode 100644 core/src/main/java/org/geysermc/floodgate/news/data/AnnouncementData.java create mode 100644 core/src/main/java/org/geysermc/floodgate/news/data/BuildSpecificData.java create mode 100644 core/src/main/java/org/geysermc/floodgate/news/data/CheckAfterData.java create mode 100644 core/src/main/java/org/geysermc/floodgate/news/data/ConfigSpecificData.java create mode 100644 core/src/main/java/org/geysermc/floodgate/news/data/ItemData.java create mode 100644 core/src/main/java/org/geysermc/floodgate/util/InvalidFormatException.java create mode 100644 core/src/main/java/org/geysermc/floodgate/util/WebsocketEventType.java diff --git a/legacy-api/build.gradle.kts b/api/build.gradle.kts similarity index 79% rename from legacy-api/build.gradle.kts rename to api/build.gradle.kts index 09fb2163..f0b264a2 100644 --- a/legacy-api/build.gradle.kts +++ b/api/build.gradle.kts @@ -1,5 +1,4 @@ dependencies { - api("org.geysermc", "common", Versions.geyserVersion) api("org.geysermc.cumulus", "cumulus", Versions.cumulusVersion) api("org.geysermc.event", "events", Versions.eventsVersion) diff --git a/legacy-api/src/main/java/org/geysermc/floodgate/api/FloodgateApi.java b/api/src/main/java/org/geysermc/floodgate/api/FloodgateApi.java similarity index 100% rename from legacy-api/src/main/java/org/geysermc/floodgate/api/FloodgateApi.java rename to api/src/main/java/org/geysermc/floodgate/api/FloodgateApi.java diff --git a/legacy-api/src/main/java/org/geysermc/floodgate/api/InstanceHolder.java b/api/src/main/java/org/geysermc/floodgate/api/InstanceHolder.java similarity index 100% rename from legacy-api/src/main/java/org/geysermc/floodgate/api/InstanceHolder.java rename to api/src/main/java/org/geysermc/floodgate/api/InstanceHolder.java diff --git a/legacy-api/src/main/java/org/geysermc/floodgate/api/handshake/HandshakeData.java b/api/src/main/java/org/geysermc/floodgate/api/handshake/HandshakeData.java similarity index 100% rename from legacy-api/src/main/java/org/geysermc/floodgate/api/handshake/HandshakeData.java rename to api/src/main/java/org/geysermc/floodgate/api/handshake/HandshakeData.java diff --git a/legacy-api/src/main/java/org/geysermc/floodgate/api/handshake/HandshakeHandler.java b/api/src/main/java/org/geysermc/floodgate/api/handshake/HandshakeHandler.java similarity index 100% rename from legacy-api/src/main/java/org/geysermc/floodgate/api/handshake/HandshakeHandler.java rename to api/src/main/java/org/geysermc/floodgate/api/handshake/HandshakeHandler.java diff --git a/legacy-api/src/main/java/org/geysermc/floodgate/api/handshake/HandshakeHandlers.java b/api/src/main/java/org/geysermc/floodgate/api/handshake/HandshakeHandlers.java similarity index 100% rename from legacy-api/src/main/java/org/geysermc/floodgate/api/handshake/HandshakeHandlers.java rename to api/src/main/java/org/geysermc/floodgate/api/handshake/HandshakeHandlers.java diff --git a/legacy-api/src/main/java/org/geysermc/floodgate/api/inject/InjectorAddon.java b/api/src/main/java/org/geysermc/floodgate/api/inject/InjectorAddon.java similarity index 100% rename from legacy-api/src/main/java/org/geysermc/floodgate/api/inject/InjectorAddon.java rename to api/src/main/java/org/geysermc/floodgate/api/inject/InjectorAddon.java diff --git a/legacy-api/src/main/java/org/geysermc/floodgate/api/inject/PlatformInjector.java b/api/src/main/java/org/geysermc/floodgate/api/inject/PlatformInjector.java similarity index 100% rename from legacy-api/src/main/java/org/geysermc/floodgate/api/inject/PlatformInjector.java rename to api/src/main/java/org/geysermc/floodgate/api/inject/PlatformInjector.java diff --git a/legacy-api/src/main/java/org/geysermc/floodgate/api/link/LinkRequest.java b/api/src/main/java/org/geysermc/floodgate/api/link/LinkRequest.java similarity index 100% rename from legacy-api/src/main/java/org/geysermc/floodgate/api/link/LinkRequest.java rename to api/src/main/java/org/geysermc/floodgate/api/link/LinkRequest.java diff --git a/legacy-api/src/main/java/org/geysermc/floodgate/api/link/LinkRequestResult.java b/api/src/main/java/org/geysermc/floodgate/api/link/LinkRequestResult.java similarity index 100% rename from legacy-api/src/main/java/org/geysermc/floodgate/api/link/LinkRequestResult.java rename to api/src/main/java/org/geysermc/floodgate/api/link/LinkRequestResult.java diff --git a/legacy-api/src/main/java/org/geysermc/floodgate/api/link/PlayerLink.java b/api/src/main/java/org/geysermc/floodgate/api/link/PlayerLink.java similarity index 100% rename from legacy-api/src/main/java/org/geysermc/floodgate/api/link/PlayerLink.java rename to api/src/main/java/org/geysermc/floodgate/api/link/PlayerLink.java diff --git a/legacy-api/src/main/java/org/geysermc/floodgate/api/logger/FloodgateLogger.java b/api/src/main/java/org/geysermc/floodgate/api/logger/FloodgateLogger.java similarity index 100% rename from legacy-api/src/main/java/org/geysermc/floodgate/api/logger/FloodgateLogger.java rename to api/src/main/java/org/geysermc/floodgate/api/logger/FloodgateLogger.java diff --git a/legacy-api/src/main/java/org/geysermc/floodgate/api/packet/PacketHandler.java b/api/src/main/java/org/geysermc/floodgate/api/packet/PacketHandler.java similarity index 100% rename from legacy-api/src/main/java/org/geysermc/floodgate/api/packet/PacketHandler.java rename to api/src/main/java/org/geysermc/floodgate/api/packet/PacketHandler.java diff --git a/legacy-api/src/main/java/org/geysermc/floodgate/api/packet/PacketHandlers.java b/api/src/main/java/org/geysermc/floodgate/api/packet/PacketHandlers.java similarity index 100% rename from legacy-api/src/main/java/org/geysermc/floodgate/api/packet/PacketHandlers.java rename to api/src/main/java/org/geysermc/floodgate/api/packet/PacketHandlers.java diff --git a/legacy-api/src/main/java/org/geysermc/floodgate/api/player/FloodgatePlayer.java b/api/src/main/java/org/geysermc/floodgate/api/player/FloodgatePlayer.java similarity index 100% rename from legacy-api/src/main/java/org/geysermc/floodgate/api/player/FloodgatePlayer.java rename to api/src/main/java/org/geysermc/floodgate/api/player/FloodgatePlayer.java diff --git a/legacy-api/src/main/java/org/geysermc/floodgate/api/unsafe/Unsafe.java b/api/src/main/java/org/geysermc/floodgate/api/unsafe/Unsafe.java similarity index 100% rename from legacy-api/src/main/java/org/geysermc/floodgate/api/unsafe/Unsafe.java rename to api/src/main/java/org/geysermc/floodgate/api/unsafe/Unsafe.java diff --git a/legacy-api/src/main/java/org/geysermc/floodgate/api/util/TriFunction.java b/api/src/main/java/org/geysermc/floodgate/api/util/TriFunction.java similarity index 100% rename from legacy-api/src/main/java/org/geysermc/floodgate/api/util/TriFunction.java rename to api/src/main/java/org/geysermc/floodgate/api/util/TriFunction.java diff --git a/core/src/main/java/org/geysermc/floodgate/util/BedrockData.java b/api/src/main/java/org/geysermc/floodgate/util/BedrockData.java similarity index 100% rename from core/src/main/java/org/geysermc/floodgate/util/BedrockData.java rename to api/src/main/java/org/geysermc/floodgate/util/BedrockData.java diff --git a/api/src/main/java/org/geysermc/floodgate/util/DeviceOs.java b/api/src/main/java/org/geysermc/floodgate/util/DeviceOs.java new file mode 100644 index 00000000..beed5f19 --- /dev/null +++ b/api/src/main/java/org/geysermc/floodgate/util/DeviceOs.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2019-2022 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.floodgate.util; + +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; + +@Deprecated +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) +public enum DeviceOs { + UNKNOWN("Unknown"), + GOOGLE("Android"), + IOS("iOS"), + OSX("macOS"), + AMAZON("Amazon"), + GEARVR("Gear VR"), + HOLOLENS("Hololens"), + UWP("Windows"), + WIN32("Windows x86"), + DEDICATED("Dedicated"), + TVOS("Apple TV"), + PS4("PS4"), + NX("Switch"), + XBOX("Xbox One"), + WINDOWS_PHONE("Windows Phone"); + + private final String displayName; + + /** + * Get the DeviceOs instance from the identifier. + * + * @param id the DeviceOs identifier + * @return The DeviceOs or {@link #UNKNOWN} if the DeviceOs wasn't found + */ + public static DeviceOs fromId(int id) { + DeviceOs[] VALUES = values(); + return id < VALUES.length ? VALUES[id] : VALUES[0]; + } + + /** + * @return friendly display name of platform. + */ + @Override + public String toString() { + return displayName; + } +} \ No newline at end of file diff --git a/api/src/main/java/org/geysermc/floodgate/util/InputMode.java b/api/src/main/java/org/geysermc/floodgate/util/InputMode.java new file mode 100644 index 00000000..b58c8294 --- /dev/null +++ b/api/src/main/java/org/geysermc/floodgate/util/InputMode.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019-2022 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.floodgate.util; + +@Deprecated +public enum InputMode { + UNKNOWN, + KEYBOARD_MOUSE, + TOUCH, + CONTROLLER, + VR; + + private static final InputMode[] VALUES = values(); + + /** + * Get the InputMode instance from the identifier. + * + * @param id the InputMode identifier + * @return The InputMode or {@link #UNKNOWN} if the DeviceOs wasn't found + */ + public static InputMode fromId(int id) { + return VALUES.length > id ? VALUES[id] : VALUES[0]; + } +} \ No newline at end of file diff --git a/api/src/main/java/org/geysermc/floodgate/util/LinkedPlayer.java b/api/src/main/java/org/geysermc/floodgate/util/LinkedPlayer.java new file mode 100644 index 00000000..1f2d9560 --- /dev/null +++ b/api/src/main/java/org/geysermc/floodgate/util/LinkedPlayer.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Floodgate + */ + +package org.geysermc.floodgate.util; + +import java.util.UUID; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) +public final class LinkedPlayer implements Cloneable { + /** + * The Java username of the linked player + */ + private final String javaUsername; + /** + * The Java UUID of the linked player + */ + private final UUID javaUniqueId; + /** + * The UUID of the Bedrock player + */ + private final UUID bedrockId; + /** + * If the LinkedPlayer is sent from a different platform. For example the LinkedPlayer is from + * Bungee but the data has been sent to the Bukkit server. + */ + private boolean fromDifferentPlatform = false; + + public static LinkedPlayer of(String javaUsername, UUID javaUniqueId, UUID bedrockId) { + return new LinkedPlayer(javaUsername, javaUniqueId, bedrockId); + } + + public static LinkedPlayer fromString(String data) { + String[] split = data.split(";"); + if (split.length != 3) { + return null; + } + + LinkedPlayer player = new LinkedPlayer( + split[0], UUID.fromString(split[1]), UUID.fromString(split[2]) + ); + player.fromDifferentPlatform = true; + return player; + } + + @Override + public String toString() { + return javaUsername + ';' + javaUniqueId.toString() + ';' + bedrockId.toString(); + } + + @Override + public LinkedPlayer clone() throws CloneNotSupportedException { + return (LinkedPlayer) super.clone(); + } +} diff --git a/api/src/main/java/org/geysermc/floodgate/util/UiProfile.java b/api/src/main/java/org/geysermc/floodgate/util/UiProfile.java new file mode 100644 index 00000000..8d9960ed --- /dev/null +++ b/api/src/main/java/org/geysermc/floodgate/util/UiProfile.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2019-2022 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.floodgate.util; + +@Deprecated +public enum UiProfile { + CLASSIC, + POCKET; + + private static final UiProfile[] VALUES = values(); + + /** + * Get the UiProfile instance from the identifier. + * + * @param id the UiProfile identifier + * @return The UiProfile or {@link #CLASSIC} if the UiProfile wasn't found + */ + public static UiProfile fromId(int id) { + return VALUES.length > id ? VALUES[id] : VALUES[0]; + } +} diff --git a/build.gradle.kts b/build.gradle.kts index 89e1952c..09dace78 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,7 +11,7 @@ allprojects { } val deployProjects = setOf( - projects.legacyApi, + projects.api, // for future Floodgate integration + Fabric projects.core, projects.bungee, diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 639d1b61..e87e156e 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -6,7 +6,8 @@ plugins { dependencies { api("org.geysermc", "api", "3.0.0-SNAPSHOT") - api("org.geysermc", "floodgate-legacy-api", "3.0.0-SNAPSHOT") + api(projects.api) +// api("org.geysermc", "floodgate-legacy-api", "3.0.0-SNAPSHOT") api("org.geysermc.configutils", "configutils", Versions.configUtilsVersion) compileOnly(projects.ap) diff --git a/core/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java b/core/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java index 43f21567..9add6d8f 100644 --- a/core/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java +++ b/core/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java @@ -34,9 +34,7 @@ import lombok.AccessLevel; import lombok.Getter; import org.geysermc.api.Geyser; import org.geysermc.api.GeyserApiBase; -import org.geysermc.floodgate.api.FloodgateApi; import org.geysermc.floodgate.api.InstanceHolder; -import org.geysermc.floodgate.api.handshake.HandshakeHandlers; import org.geysermc.floodgate.api.impl.FloodgateApiWrapper; import org.geysermc.floodgate.api.inject.PlatformInjector; import org.geysermc.floodgate.api.link.PlayerLink; diff --git a/core/src/main/java/org/geysermc/floodgate/addon/data/HandshakeDataImpl.java b/core/src/main/java/org/geysermc/floodgate/addon/data/HandshakeDataImpl.java index 3a6398a2..480175e9 100644 --- a/core/src/main/java/org/geysermc/floodgate/addon/data/HandshakeDataImpl.java +++ b/core/src/main/java/org/geysermc/floodgate/addon/data/HandshakeDataImpl.java @@ -36,7 +36,7 @@ import org.geysermc.floodgate.util.LinkedPlayer; import org.geysermc.floodgate.util.Utils; @Getter -public class HandshakeDataImpl { +public class HandshakeDataImpl implements HandshakeData { private final Channel channel; private final boolean floodgatePlayer; private final BedrockData bedrockData; diff --git a/core/src/main/java/org/geysermc/floodgate/crypto/AesCipher.java b/core/src/main/java/org/geysermc/floodgate/crypto/AesCipher.java new file mode 100644 index 00000000..d28b8e7e --- /dev/null +++ b/core/src/main/java/org/geysermc/floodgate/crypto/AesCipher.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Floodgate + */ + +package org.geysermc.floodgate.crypto; + +import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.security.Key; +import java.security.SecureRandom; +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.spec.GCMParameterSpec; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public final class AesCipher implements FloodgateCipher { + public static final int IV_LENGTH = 12; + private static final int TAG_BIT_LENGTH = 128; + private static final String CIPHER_NAME = "AES/GCM/NoPadding"; + + private final SecureRandom secureRandom = new SecureRandom(); + private final Topping topping; + private SecretKey secretKey; + + public void init(Key key) { + if (!"AES".equals(key.getAlgorithm())) { + throw new RuntimeException( + "Algorithm was expected to be AES, but got " + key.getAlgorithm() + ); + } + secretKey = (SecretKey) key; + } + + public byte[] encrypt(byte[] data) throws Exception { + Cipher cipher = Cipher.getInstance(CIPHER_NAME); + + byte[] iv = new byte[IV_LENGTH]; + secureRandom.nextBytes(iv); + + GCMParameterSpec spec = new GCMParameterSpec(TAG_BIT_LENGTH, iv); + cipher.init(Cipher.ENCRYPT_MODE, secretKey, spec); + byte[] cipherText = cipher.doFinal(data); + + if (topping != null) { + iv = topping.encode(iv); + cipherText = topping.encode(cipherText); + } + + return ByteBuffer.allocate(HEADER.length + iv.length + cipherText.length + 1) + .put(HEADER) + .put(iv) + .put((byte) 0x21) + .put(cipherText) + .array(); + } + + public byte[] decrypt(byte[] cipherTextWithIv) throws Exception { + checkHeader(cipherTextWithIv); + + Cipher cipher = Cipher.getInstance(CIPHER_NAME); + + int bufferLength = cipherTextWithIv.length - HEADER.length; + ByteBuffer buffer = ByteBuffer.wrap(cipherTextWithIv, HEADER.length, bufferLength); + + int ivLength = IV_LENGTH; + + if (topping != null) { + int mark = buffer.position(); + + // we need the first index, the second is for the actual data + boolean found = false; + while (buffer.hasRemaining() && !found) { + if (buffer.get() == 0x21) { + found = true; + } + } + + ivLength = buffer.position() - mark - 1; // don't include the splitter itself + // don't remove this cast, it'll cause problems if you remove it + ((Buffer) buffer).position(mark); // reset to the pre-while index + } + + byte[] iv = new byte[ivLength]; + buffer.get(iv); + + // don't remove this cast, it'll cause problems if you remove it + ((Buffer) buffer).position(buffer.position() + 1); // skip splitter + + byte[] cipherText = new byte[buffer.remaining()]; + buffer.get(cipherText); + + if (topping != null) { + iv = topping.decode(iv); + cipherText = topping.decode(cipherText); + } + + GCMParameterSpec spec = new GCMParameterSpec(TAG_BIT_LENGTH, iv); + cipher.init(Cipher.DECRYPT_MODE, secretKey, spec); + return cipher.doFinal(cipherText); + } +} diff --git a/core/src/main/java/org/geysermc/floodgate/crypto/AesKeyProducer.java b/core/src/main/java/org/geysermc/floodgate/crypto/AesKeyProducer.java new file mode 100644 index 00000000..fd5c37e9 --- /dev/null +++ b/core/src/main/java/org/geysermc/floodgate/crypto/AesKeyProducer.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Floodgate + */ + +package org.geysermc.floodgate.crypto; + +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +public final class AesKeyProducer implements KeyProducer { + public static int KEY_SIZE = 128; + + @Override + public SecretKey produce() { + try { + KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); + keyGenerator.init(KEY_SIZE, secureRandom()); + return keyGenerator.generateKey(); + } catch (Exception exception) { + throw new RuntimeException(exception); + } + } + + @Override + public SecretKey produceFrom(byte[] keyFileData) { + try { + return new SecretKeySpec(keyFileData, "AES"); + } catch (Exception exception) { + throw new RuntimeException(exception); + } + } + + private SecureRandom secureRandom() throws NoSuchAlgorithmException { + // use Windows-PRNG for windows (default impl is SHA1PRNG) + if (System.getProperty("os.name").startsWith("Windows")) { + return SecureRandom.getInstance("Windows-PRNG"); + } else { + try { + // NativePRNG (which should be the default on unix-systems) can still block your + // system. Even though it isn't as bad as NativePRNGBlocking, we still try to + // prevent that if possible + return SecureRandom.getInstance("NativePRNGNonBlocking"); + } catch (NoSuchAlgorithmException ignored) { + // at this point we just have to go with the default impl even if it blocks + return new SecureRandom(); + } + } + } +} diff --git a/core/src/main/java/org/geysermc/floodgate/crypto/Base64Topping.java b/core/src/main/java/org/geysermc/floodgate/crypto/Base64Topping.java new file mode 100644 index 00000000..002a23f3 --- /dev/null +++ b/core/src/main/java/org/geysermc/floodgate/crypto/Base64Topping.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019-2022 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.floodgate.crypto; + +import java.util.Base64; + +public final class Base64Topping implements Topping { + @Override + public byte[] encode(byte[] data) { + return Base64.getEncoder().encode(data); + } + + @Override + public byte[] decode(byte[] data) { + return Base64.getDecoder().decode(data); + } +} diff --git a/core/src/main/java/org/geysermc/floodgate/crypto/FloodgateCipher.java b/core/src/main/java/org/geysermc/floodgate/crypto/FloodgateCipher.java new file mode 100644 index 00000000..f6087a65 --- /dev/null +++ b/core/src/main/java/org/geysermc/floodgate/crypto/FloodgateCipher.java @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Floodgate + */ + +package org.geysermc.floodgate.crypto; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import java.security.Key; +import org.geysermc.floodgate.util.InvalidFormatException; + +/** + * Responsible for both encrypting and decrypting data + */ +public interface FloodgateCipher { + int VERSION = 0; + byte[] IDENTIFIER = "^Floodgate^".getBytes(UTF_8); + byte[] HEADER = (new String(IDENTIFIER, UTF_8) + (char) (VERSION + 0x3E)).getBytes(UTF_8); + + static int version(String data) { + if (data.length() <= HEADER.length) { + return -1; + } + + for (int i = 0; i < IDENTIFIER.length; i++) { + if (IDENTIFIER[i] != data.charAt(i)) { + return -1; + } + } + + return data.charAt(IDENTIFIER.length) - 0x3E; + } + + /** + * Initializes the instance by giving it the key it needs to encrypt or decrypt data + * + * @param key the key used to encrypt and decrypt data + */ + void init(Key key); + + /** + * Encrypts the given data using the Key provided in {@link #init(Key)} + * + * @param data the data to encrypt + * @return the encrypted data + * @throws Exception when the encryption failed + */ + byte[] encrypt(byte[] data) throws Exception; + + /** + * Encrypts data from a String.
This method internally calls {@link #encrypt(byte[])} + * + * @param data the data to encrypt + * @return the encrypted data + * @throws Exception when the encryption failed + */ + default byte[] encryptFromString(String data) throws Exception { + return encrypt(data.getBytes(UTF_8)); + } + + /** + * Decrypts the given data using the Key provided in {@link #init(Key)} + * + * @param data the data to decrypt + * @return the decrypted data + * @throws Exception when the decrypting failed + */ + byte[] decrypt(byte[] data) throws Exception; + + /** + * Decrypts a byte[] and turn it into a String.
This method internally calls {@link + * #decrypt(byte[])} and converts the returned byte[] into a String. + * + * @param data the data to encrypt + * @return the decrypted data in a UTF-8 String + * @throws Exception when the decrypting failed + */ + default String decryptToString(byte[] data) throws Exception { + byte[] decrypted = decrypt(data); + if (decrypted == null) { + return null; + } + return new String(decrypted, UTF_8); + } + + /** + * Decrypts a String.
This method internally calls {@link #decrypt(byte[])} by converting + * the UTF-8 String into a byte[] + * + * @param data the data to decrypt + * @return the decrypted data in a byte[] + * @throws Exception when the decrypting failed + */ + default byte[] decryptFromString(String data) throws Exception { + return decrypt(data.getBytes(UTF_8)); + } + + /** + * Checks if the header is valid. This method will throw an InvalidFormatException when the + * header is invalid. + * + * @param data the data to check + * @throws InvalidFormatException when the header is invalid + */ + default void checkHeader(byte[] data) throws InvalidFormatException { + if (data.length <= HEADER.length) { + throw new InvalidFormatException( + "Data length is smaller then header." + + "Needed " + HEADER.length + ", got " + data.length + ); + } + + for (int i = 0; i < IDENTIFIER.length; i++) { + if (IDENTIFIER[i] != data[i]) { + String identifier = new String(IDENTIFIER, UTF_8); + String received = new String(data, 0, IDENTIFIER.length, UTF_8); + throw new InvalidFormatException( + "Expected identifier " + identifier + ", got " + received + ); + } + } + } +} diff --git a/core/src/main/java/org/geysermc/floodgate/crypto/KeyProducer.java b/core/src/main/java/org/geysermc/floodgate/crypto/KeyProducer.java new file mode 100644 index 00000000..4ee00f36 --- /dev/null +++ b/core/src/main/java/org/geysermc/floodgate/crypto/KeyProducer.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019-2022 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.floodgate.crypto; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.Key; + +public interface KeyProducer { + Key produce(); + Key produceFrom(byte[] keyFileData); + + default Key produceFrom(Path keyFileLocation) throws IOException { + return produceFrom(Files.readAllBytes(keyFileLocation)); + } +} diff --git a/core/src/main/java/org/geysermc/floodgate/crypto/Topping.java b/core/src/main/java/org/geysermc/floodgate/crypto/Topping.java new file mode 100644 index 00000000..3805c0bc --- /dev/null +++ b/core/src/main/java/org/geysermc/floodgate/crypto/Topping.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2019-2022 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.floodgate.crypto; + +public interface Topping { + byte[] encode(byte[] data); + byte[] decode(byte[] data); +} diff --git a/core/src/main/java/org/geysermc/floodgate/news/NewsItem.java b/core/src/main/java/org/geysermc/floodgate/news/NewsItem.java new file mode 100644 index 00000000..9a7b20a3 --- /dev/null +++ b/core/src/main/java/org/geysermc/floodgate/news/NewsItem.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Floodgate + */ + +package org.geysermc.floodgate.news; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import org.geysermc.floodgate.news.data.ItemData; + +public final class NewsItem { + private final int id; + private final boolean active; + private final NewsType type; + private final ItemData data; + private final String message; + private final Set actions; + private final String url; + + private NewsItem( + int id, boolean active, NewsType type, ItemData data, + String message, Set actions, String url) { + + this.id = id; + this.active = active; + this.type = type; + this.data = data; + this.message = message; + this.actions = Collections.unmodifiableSet(actions); + this.url = url; + } + + public static NewsItem readItem(JsonObject newsItem) { + NewsType newsType = NewsType.getByName(newsItem.get("type").getAsString()); + if (newsType == null) { + return null; + } + + JsonObject messageObject = newsItem.getAsJsonObject("message"); + NewsItemMessage itemMessage = NewsItemMessage.getById(messageObject.get("id").getAsInt()); + + String message = "Received an unknown news message type. Please update"; + if (itemMessage != null) { + message = itemMessage.getFormattedMessage(messageObject.getAsJsonArray("args")); + } + + Set actions = new HashSet<>(); + for (JsonElement actionElement : newsItem.getAsJsonArray("actions")) { + NewsItemAction action = NewsItemAction.getByName(actionElement.getAsString()); + if (action != null) { + actions.add(action); + } + } + + return new NewsItem( + newsItem.get("id").getAsInt(), + newsItem.get("active").getAsBoolean(), + newsType, + newsType.read(newsItem.getAsJsonObject("data")), + message, + actions, + newsItem.get("url").getAsString() + ); + } + + public int getId() { + return id; + } + + public boolean isActive() { + return active; + } + + public NewsType getType() { + return type; + } + + public ItemData getData() { + return data; + } + + @SuppressWarnings("unchecked") + public T getDataAs(Class type) { + return (T) data; + } + + public String getRawMessage() { + return message; + } + + public String getMessage() { + return message + " See " + getUrl() + " for more information."; + } + + public Set getActions() { + return actions; + } + + public String getUrl() { + return url; + } +} diff --git a/core/src/main/java/org/geysermc/floodgate/news/NewsItemAction.java b/core/src/main/java/org/geysermc/floodgate/news/NewsItemAction.java new file mode 100644 index 00000000..00e34b62 --- /dev/null +++ b/core/src/main/java/org/geysermc/floodgate/news/NewsItemAction.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2019-2022 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.floodgate.news; + +public enum NewsItemAction { + ON_SERVER_STARTED, + ON_OPERATOR_JOIN, + BROADCAST_TO_CONSOLE, + BROADCAST_TO_OPERATORS; + + private static final NewsItemAction[] VALUES = values(); + + public static NewsItemAction getByName(String actionName) { + for (NewsItemAction type : VALUES) { + if (type.name().equalsIgnoreCase(actionName)) { + return type; + } + } + return null; + } +} diff --git a/core/src/main/java/org/geysermc/floodgate/news/NewsItemMessage.java b/core/src/main/java/org/geysermc/floodgate/news/NewsItemMessage.java new file mode 100644 index 00000000..9c2f3d15 --- /dev/null +++ b/core/src/main/java/org/geysermc/floodgate/news/NewsItemMessage.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2019-2022 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.floodgate.news; + +import com.google.gson.JsonArray; + +// {} is used for things that have to be filled in by the server, +// {@} is for things that have to be filled in by us +public enum NewsItemMessage { + UPDATE_AVAILABLE("There is an update available for {}. The newest version is: {}"), + UPDATE_RECOMMENDED(UPDATE_AVAILABLE + ". Your version is quite old, updating is recommend."), + UPDATE_HIGHLY_RECOMMENDED(UPDATE_AVAILABLE + ". We highly recommend updating because some important changes have been made."), + UPDATE_ANCIENT_VERSION(UPDATE_AVAILABLE + ". You are running an ancient version, updating is recommended."), + + DOWNTIME_GENERIC("The {} is temporarily going down for maintenance soon."), + DOWNTIME_WITH_START("The {} is temporarily going down for maintenance on {}."), + DOWNTIME_TIMEFRAME(DOWNTIME_WITH_START + " The maintenance is expected to last till {}."); + + private static final NewsItemMessage[] VALUES = values(); + + private final String messageFormat; + private final String[] messageSplitted; + + NewsItemMessage(String messageFormat) { + this.messageFormat = messageFormat; + this.messageSplitted = messageFormat.split(" "); + } + + public static NewsItemMessage getById(int id) { + return VALUES.length > id ? VALUES[id] : null; + } + + public String getMessageFormat() { + return messageFormat; + } + + public String getFormattedMessage(JsonArray serverArguments) { + int serverArgumentsIndex = 0; + + StringBuilder message = new StringBuilder(); + for (String split : messageSplitted) { + if (message.length() > 0) { + message.append(' '); + } + + String result = split; + + if (serverArgumentsIndex < serverArguments.size()) { + String argument = serverArguments.get(serverArgumentsIndex).getAsString(); + result = result.replace("{}", argument); + if (!result.equals(split)) { + serverArgumentsIndex++; + } + } + + message.append(result); + } + return message.toString(); + } + + + @Override + public String toString() { + return getMessageFormat(); + } +} diff --git a/core/src/main/java/org/geysermc/floodgate/news/NewsType.java b/core/src/main/java/org/geysermc/floodgate/news/NewsType.java new file mode 100644 index 00000000..95f1f1ad --- /dev/null +++ b/core/src/main/java/org/geysermc/floodgate/news/NewsType.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Floodgate + */ + +package org.geysermc.floodgate.news; + +import com.google.gson.JsonObject; +import java.util.function.Function; +import org.geysermc.floodgate.news.data.AnnouncementData; +import org.geysermc.floodgate.news.data.BuildSpecificData; +import org.geysermc.floodgate.news.data.CheckAfterData; +import org.geysermc.floodgate.news.data.ConfigSpecificData; +import org.geysermc.floodgate.news.data.ItemData; + +public enum NewsType { + BUILD_SPECIFIC(BuildSpecificData::read), + CHECK_AFTER(CheckAfterData::read), + ANNOUNCEMENT(AnnouncementData::read), + CONFIG_SPECIFIC(ConfigSpecificData::read); + + private static final NewsType[] VALUES = values(); + + private final Function readFunction; + + NewsType(Function readFunction) { + this.readFunction = readFunction; + } + + public static NewsType getByName(String newsType) { + for (NewsType type : VALUES) { + if (type.name().equalsIgnoreCase(newsType)) { + return type; + } + } + return null; + } + + public ItemData read(JsonObject data) { + return readFunction.apply(data); + } +} diff --git a/core/src/main/java/org/geysermc/floodgate/news/data/AnnouncementData.java b/core/src/main/java/org/geysermc/floodgate/news/data/AnnouncementData.java new file mode 100644 index 00000000..71aae853 --- /dev/null +++ b/core/src/main/java/org/geysermc/floodgate/news/data/AnnouncementData.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Floodgate + */ + +package org.geysermc.floodgate.news.data; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import java.util.HashSet; +import java.util.Set; + +public final class AnnouncementData implements ItemData { + private final Set including = new HashSet<>(); + private final Set excluding = new HashSet<>(); + + private AnnouncementData() {} + + public static AnnouncementData read(JsonObject data) { + AnnouncementData announcementData = new AnnouncementData(); + + if (data.has("including")) { + JsonArray including = data.getAsJsonArray("including"); + for (JsonElement element : including) { + announcementData.including.add(element.getAsString()); + } + } + + if (data.has("excluding")) { + JsonArray including = data.getAsJsonArray("excluding"); + for (JsonElement element : including) { + announcementData.excluding.add(element.getAsString()); + } + } + return announcementData; + } + + public boolean isAffected(String project) { + return !excluding.contains(project) && (including.isEmpty() || including.contains(project)); + } +} diff --git a/core/src/main/java/org/geysermc/floodgate/news/data/BuildSpecificData.java b/core/src/main/java/org/geysermc/floodgate/news/data/BuildSpecificData.java new file mode 100644 index 00000000..7f2c7360 --- /dev/null +++ b/core/src/main/java/org/geysermc/floodgate/news/data/BuildSpecificData.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2019-2022 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.floodgate.news.data; + +import com.google.gson.JsonObject; + +public final class BuildSpecificData implements ItemData { + private String branch; + + private boolean allAffected; + private int affectedGreaterThan; + private int affectedLessThan; + + private BuildSpecificData() {} + + public static BuildSpecificData read(JsonObject data) { + BuildSpecificData updateData = new BuildSpecificData(); + updateData.branch = data.get("branch").getAsString(); + + JsonObject affectedBuilds = data.getAsJsonObject("affected_builds"); + if (affectedBuilds.has("all")) { + updateData.allAffected = affectedBuilds.get("all").getAsBoolean(); + } + if (!updateData.allAffected) { + updateData.affectedGreaterThan = affectedBuilds.get("gt").getAsInt(); + updateData.affectedLessThan = affectedBuilds.get("lt").getAsInt(); + } + return updateData; + } + + public boolean isAffected(String branch, int buildId) { + return this.branch.equals(branch) && + (allAffected || buildId > affectedGreaterThan && buildId < affectedLessThan); + } + + public String getBranch() { + return branch; + } +} diff --git a/core/src/main/java/org/geysermc/floodgate/news/data/CheckAfterData.java b/core/src/main/java/org/geysermc/floodgate/news/data/CheckAfterData.java new file mode 100644 index 00000000..1e5fef4d --- /dev/null +++ b/core/src/main/java/org/geysermc/floodgate/news/data/CheckAfterData.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2019-2022 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.floodgate.news.data; + +import com.google.gson.JsonObject; + +public final class CheckAfterData implements ItemData { + private long checkAfter; + + private CheckAfterData() {} + + public static CheckAfterData read(JsonObject data) { + CheckAfterData checkAfterData = new CheckAfterData(); + checkAfterData.checkAfter = data.get("check_after").getAsLong(); + return checkAfterData; + } + + public long getCheckAfter() { + return checkAfter; + } +} diff --git a/core/src/main/java/org/geysermc/floodgate/news/data/ConfigSpecificData.java b/core/src/main/java/org/geysermc/floodgate/news/data/ConfigSpecificData.java new file mode 100644 index 00000000..88b5897a --- /dev/null +++ b/core/src/main/java/org/geysermc/floodgate/news/data/ConfigSpecificData.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Floodgate + */ + +package org.geysermc.floodgate.news.data; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Pattern; + +public final class ConfigSpecificData implements ItemData { + private final Map affectedKeys = new HashMap<>(); + + private ConfigSpecificData() {} + + public static ConfigSpecificData read(JsonObject data) { + ConfigSpecificData configSpecificData = new ConfigSpecificData(); + + JsonArray entries = data.getAsJsonArray("entries"); + for (JsonElement element : entries) { + JsonObject entry = element.getAsJsonObject(); + String key = entry.get("key").getAsString(); + String pattern = entry.get("pattern").getAsString(); + configSpecificData.affectedKeys.put(key, Pattern.compile(pattern)); + } + return configSpecificData; + } + + public boolean isAffected(Map config) { + for (Map.Entry entry : affectedKeys.entrySet()) { + if (config.containsKey(entry.getKey())) { + String value = config.get(entry.getKey()); + if (entry.getValue().matcher(value).matches()) { + return true; + } + } + } + return false; + } +} diff --git a/core/src/main/java/org/geysermc/floodgate/news/data/ItemData.java b/core/src/main/java/org/geysermc/floodgate/news/data/ItemData.java new file mode 100644 index 00000000..64a1aedf --- /dev/null +++ b/core/src/main/java/org/geysermc/floodgate/news/data/ItemData.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2019-2022 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.floodgate.news.data; + +public interface ItemData { +} diff --git a/core/src/main/java/org/geysermc/floodgate/player/FloodgateHandshakeHandler.java b/core/src/main/java/org/geysermc/floodgate/player/FloodgateHandshakeHandler.java index 4c678a96..68f56bf2 100644 --- a/core/src/main/java/org/geysermc/floodgate/player/FloodgateHandshakeHandler.java +++ b/core/src/main/java/org/geysermc/floodgate/player/FloodgateHandshakeHandler.java @@ -241,7 +241,7 @@ public final class FloodgateHandshakeHandler { BedrockData bedrockData, String hostname) { - HandshakeInjectedData handshakeData = new HandshakeDataImpl(channel, bedrockData != null, + HandshakeData handshakeData = new HandshakeDataImpl(channel, bedrockData != null, bedrockData, config, null, hostname); handshakeHandlers.callHandshakeHandlers(handshakeData); @@ -276,13 +276,13 @@ public final class FloodgateHandshakeHandler { @Getter public static class HandshakeResult extends IllegalStateException { private final ResultType resultType; - private final HandshakeInjectedData handshakeData; + private final HandshakeData handshakeData; private final BedrockData bedrockData; private final Connection floodgatePlayer; public InetSocketAddress getNewIp(Channel channel) { if (floodgatePlayer != null) { - return floodgatePlayer.socketAddress(); + return (InetSocketAddress) floodgatePlayer.socketAddress(); } if (handshakeData.getIp() != null) { int port = ((InetSocketAddress) channel.remoteAddress()).getPort(); diff --git a/core/src/main/java/org/geysermc/floodgate/util/InvalidFormatException.java b/core/src/main/java/org/geysermc/floodgate/util/InvalidFormatException.java new file mode 100644 index 00000000..e0630d48 --- /dev/null +++ b/core/src/main/java/org/geysermc/floodgate/util/InvalidFormatException.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019-2022 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.floodgate.util; + +public class InvalidFormatException extends Exception { + public InvalidFormatException(String message) { + super(message); + } +} diff --git a/core/src/main/java/org/geysermc/floodgate/util/WebsocketEventType.java b/core/src/main/java/org/geysermc/floodgate/util/WebsocketEventType.java new file mode 100644 index 00000000..61e6c63b --- /dev/null +++ b/core/src/main/java/org/geysermc/floodgate/util/WebsocketEventType.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2019-2022 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.floodgate.util; + +public enum WebsocketEventType { + /** + * Sent once we successfully connected to the server + */ + SUBSCRIBER_CREATED(0), + /** + * Sent every time a subscriber got added or disconnected + */ + SUBSCRIBER_COUNT(1), + /** + * Sent once the creator disconnected. After this packet the server will automatically close the + * connection once the queue size (sent in {@link #ADDED_TO_QUEUE} and {@link #SKIN_UPLOADED} + * reaches 0. + */ + CREATOR_DISCONNECTED(4), + + /** + * Sent every time a skin got added to the upload queue + */ + ADDED_TO_QUEUE(2), + /** + * Sent every time a skin got successfully uploaded + */ + SKIN_UPLOADED(3), + + /** + * Sent every time a news item was added + */ + NEWS_ADDED(6), + + /** + * Sent when the server wants you to know something. Currently used for violations that aren't + * bad enough to close the connection + */ + LOG_MESSAGE(5); + + private static final WebsocketEventType[] VALUES; + + static { + WebsocketEventType[] values = values(); + VALUES = new WebsocketEventType[values.length]; + for (WebsocketEventType value : values) { + VALUES[value.id] = value; + } + } + + /** + * The ID is based of the time it got added. However, to keep the enum organized as time goes on, + * it looks nicer to sort the events based of categories. + */ + private final int id; + + WebsocketEventType(int id) { + this.id = id; + } + + public static WebsocketEventType fromId(int id) { + return VALUES.length > id ? VALUES[id] : null; + } + + public int id() { + return id; + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index c6fe2d2d..8ca9799c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -62,7 +62,7 @@ pluginManagement { rootProject.name = "floodgate-parent" -include(":legacy-api") +include(":api") include(":ap") include(":core") include(":bungee")