From 33af9e094c9b3b7844e57c67c25b8c5b3577c127 Mon Sep 17 00:00:00 2001 From: David Choo Date: Fri, 12 Aug 2022 22:25:07 -0400 Subject: [PATCH 01/11] Fix missing cool down indicator when attacking mobs (#3230) --- .../BedrockInventoryTransactionTranslator.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java index 24c046ef2..7c2a48137 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java @@ -54,6 +54,7 @@ import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.PlayerInventory; import org.geysermc.geyser.inventory.click.Click; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.network.MinecraftProtocol; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; @@ -62,10 +63,7 @@ import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.inventory.item.ItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; -import org.geysermc.geyser.util.BlockUtils; -import org.geysermc.geyser.util.EntityUtils; -import org.geysermc.geyser.util.InteractionResult; -import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.geyser.util.*; import java.util.List; import java.util.concurrent.TimeUnit; @@ -468,6 +466,11 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator Date: Sat, 20 Aug 2022 14:56:40 -0400 Subject: [PATCH 02/11] Remove initialized check in movement This probably isn't needed anymore. This was introduced in https://github.com/GeyserMC/Geyser/pull/41 and is probably no longer needed since we never send movement before the player is spawned, and we don't allow movement to go through until the Bedrock player matches the unconfirmed teleport we create in JavaPlayerPositionTranslator. By removing this we should fix some instances of players kicked for 'flying' as players joining in the air would never respond to gravity until Bedrock finished loading. --- .../entity/player/BedrockMovePlayerTranslator.java | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockMovePlayerTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockMovePlayerTranslator.java index ba4652726..17d424b00 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockMovePlayerTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockMovePlayerTranslator.java @@ -31,13 +31,12 @@ import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.Server import com.github.steveice10.packetlib.packet.Packet; import com.nukkitx.math.vector.Vector3d; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.packet.MoveEntityAbsolutePacket; import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.type.player.SessionPlayerEntity; +import org.geysermc.geyser.level.BedrockDimension; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; -import org.geysermc.geyser.level.BedrockDimension; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; @@ -49,17 +48,6 @@ public class BedrockMovePlayerTranslator extends PacketTranslator Date: Sat, 20 Aug 2022 16:32:24 -0400 Subject: [PATCH 03/11] Geyser end of https://github.com/GeyserMC/GeyserOptionalPack/pull/34 --- .../java/org/geysermc/geyser/entity/type/LivingEntity.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java index 2550643d3..f7e055417 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java @@ -106,6 +106,9 @@ public class LivingEntity extends Entity { // Riptide spin attack setFlag(EntityFlag.DAMAGE_NEARBY_MOBS, (xd & 0x04) == 0x04); + + // OptionalPack usage + setFlag(EntityFlag.EMERGING, isUsingItem && isUsingOffhand); } public void setHealth(FloatEntityMetadata entityMetadata) { From 67a65c45d3f5530b31fa4ca587d339a77018d4c9 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sun, 21 Aug 2022 21:22:15 -0400 Subject: [PATCH 04/11] Implement update notifications for Geyser Geyser installations will now get notified when a new Bedrock release is out and Geyser must be updated. The system works similarly to ViaVersion where OPs get a notification of an update when they join. The permission node for players to see update notifications is `geyser.update` and the backing JSON that controls this can be found at https://github.com/GeyserMC/GeyserSite/blob/gh-pages/versions.json. There is also a config option to disable update checking. This update also fixes modern Paper installations not being able to see colored text logged from Geyser in the console. --- bootstrap/bungeecord/pom.xml | 6 + .../bungeecord/GeyserBungeePlugin.java | 2 + .../GeyserBungeeUpdateListener.java | 48 ++++++ .../command/BungeeCommandSender.java | 23 ++- bootstrap/pom.xml | 4 + bootstrap/spigot/pom.xml | 11 +- .../platform/spigot/GeyserPaperLogger.java | 59 +++++++ .../platform/spigot/GeyserSpigotPlugin.java | 23 ++- .../spigot/GeyserSpigotUpdateListener.java | 48 ++++++ .../platform/spigot/PaperAdventure.java | 154 ++++++++++++++++++ .../spigot/command/SpigotCommandSender.java | 13 ++ .../manager/GeyserSpigotWorldManager.java | 8 +- .../standalone/GeyserStandaloneLogger.java | 23 +-- .../velocity/GeyserVelocityPlugin.java | 2 + .../GeyserVelocityUpdateListener.java | 47 ++++++ .../command/VelocityCommandSender.java | 7 + .../java/org/geysermc/geyser/Constants.java | 3 + .../java/org/geysermc/geyser/GeyserImpl.java | 10 +- .../org/geysermc/geyser/GeyserLogger.java | 34 +++- .../geyser/command/CommandSender.java | 6 + .../configuration/GeyserConfiguration.java | 2 + .../GeyserJacksonConfiguration.java | 3 + .../geyser/session/cache/WorldCache.java | 2 + .../geyser/util/VersionCheckUtils.java | 47 ++++++ .../org/geysermc/geyser/util/WebUtils.java | 2 + core/src/main/resources/config.yml | 5 + 26 files changed, 558 insertions(+), 34 deletions(-) create mode 100644 bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeeUpdateListener.java create mode 100644 bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserPaperLogger.java create mode 100644 bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotUpdateListener.java create mode 100644 bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/PaperAdventure.java create mode 100644 bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityUpdateListener.java diff --git a/bootstrap/bungeecord/pom.xml b/bootstrap/bungeecord/pom.xml index 5a1e8e262..d71a20f42 100644 --- a/bootstrap/bungeecord/pom.xml +++ b/bootstrap/bungeecord/pom.xml @@ -24,6 +24,12 @@ a7c6ede provided + + net.kyori + adventure-text-serializer-bungeecord + ${adventure-platform.version} + compile + ${outputName}-BungeeCord diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java index 0883c5ff0..e8d44b02f 100644 --- a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java @@ -149,6 +149,8 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap { } this.getProxy().getPluginManager().registerCommand(this, new GeyserBungeeCommandExecutor(geyser)); + + this.getProxy().getPluginManager().registerListener(this, new GeyserBungeeUpdateListener()); } @Override diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeeUpdateListener.java b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeeUpdateListener.java new file mode 100644 index 000000000..bbde8771e --- /dev/null +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeeUpdateListener.java @@ -0,0 +1,48 @@ +/* + * 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.geyser.platform.bungeecord; + +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.event.PostLoginEvent; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.event.EventHandler; +import org.geysermc.geyser.Constants; +import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.platform.bungeecord.command.BungeeCommandSender; +import org.geysermc.geyser.util.VersionCheckUtils; + +public final class GeyserBungeeUpdateListener implements Listener { + + @EventHandler + public void onPlayerJoin(final PostLoginEvent event) { + if (GeyserImpl.getInstance().getConfig().isNotifyOnNewBedrockUpdate()) { + final ProxiedPlayer player = event.getPlayer(); + if (player.hasPermission(Constants.UPDATE_PERMISSION)) { + VersionCheckUtils.checkForGeyserUpdate(() -> new BungeeCommandSender(player)); + } + } + } +} diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/BungeeCommandSender.java b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/BungeeCommandSender.java index 05df8ba97..dcf5bd689 100644 --- a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/BungeeCommandSender.java +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/BungeeCommandSender.java @@ -25,11 +25,15 @@ package org.geysermc.geyser.platform.bungeecord.command; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer; import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.connection.ProxiedPlayer; import org.geysermc.geyser.command.CommandSender; import org.geysermc.geyser.text.GeyserLocale; +import java.util.Locale; + public class BungeeCommandSender implements CommandSender { private final net.md_5.bungee.api.CommandSender handle; @@ -50,6 +54,18 @@ public class BungeeCommandSender implements CommandSender { handle.sendMessage(TextComponent.fromLegacyText(message)); } + private static final int PROTOCOL_HEX_COLOR = 713; // Added 20w17a + + @Override + public void sendMessage(Component message) { + if (handle instanceof ProxiedPlayer player && player.getPendingConnection().getVersion() >= PROTOCOL_HEX_COLOR) { + // Include hex colors + handle.sendMessage(BungeeComponentSerializer.get().serialize(message)); + return; + } + handle.sendMessage(BungeeComponentSerializer.legacy().serialize(message)); + } + @Override public boolean isConsole() { return !(handle instanceof ProxiedPlayer); @@ -58,8 +74,11 @@ public class BungeeCommandSender implements CommandSender { @Override public String getLocale() { if (handle instanceof ProxiedPlayer player) { - String locale = player.getLocale().getLanguage() + "_" + player.getLocale().getCountry(); - return GeyserLocale.formatLocale(locale); + Locale locale = player.getLocale(); + if (locale != null) { + // Locale can be null early on in the conneciton + return GeyserLocale.formatLocale(locale.getLanguage() + "_" + locale.getCountry()); + } } return GeyserLocale.getDefaultLocale(); } diff --git a/bootstrap/pom.xml b/bootstrap/pom.xml index 371ed9bca..35ec15abe 100644 --- a/bootstrap/pom.xml +++ b/bootstrap/pom.xml @@ -11,6 +11,10 @@ bootstrap-parent pom + + 4.1.2 + + spigot-public diff --git a/bootstrap/spigot/pom.xml b/bootstrap/spigot/pom.xml index 5142d2bc3..ad4b58fe2 100644 --- a/bootstrap/spigot/pom.xml +++ b/bootstrap/spigot/pom.xml @@ -59,7 +59,13 @@ me.lucko commodore - 1.13 + 2.2 + compile + + + net.kyori + adventure-text-serializer-bungeecord + ${adventure-platform.version} compile @@ -107,6 +113,9 @@ net.kyori org.geysermc.geyser.platform.spigot.shaded.kyori + + net.kyori.adventure.text.logger.slf4j.ComponentLogger + org.objectweb.asm diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserPaperLogger.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserPaperLogger.java new file mode 100644 index 000000000..930f84cec --- /dev/null +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserPaperLogger.java @@ -0,0 +1,59 @@ +/* + * 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.geyser.platform.spigot; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.logger.slf4j.ComponentLogger; +import org.bukkit.plugin.Plugin; + +import java.util.logging.Logger; + +public final class GeyserPaperLogger extends GeyserSpigotLogger { + private final ComponentLogger componentLogger; + + public GeyserPaperLogger(Plugin plugin, Logger logger, boolean debug) { + super(logger, debug); + componentLogger = plugin.getComponentLogger(); + } + + /** + * Since 1.18.2 this is required so legacy format symbols don't show up in the console for colors + */ + @Override + public void sendMessage(Component message) { + // Done like this so the native component object field isn't relocated + componentLogger.info("{}", PaperAdventure.toNativeComponent(message)); + } + + static boolean supported() { + try { + Plugin.class.getMethod("getComponentLogger"); + return true; + } catch (NoSuchMethodException e) { + return false; + } + } +} diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java index 21c54308d..a1d9245e8 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java @@ -123,6 +123,22 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { return; } + try { + Class.forName("net.md_5.bungee.chat.ComponentSerializer"); + } catch (ClassNotFoundException e) { + if (!PaperAdventure.canSendMessageUsingComponent()) { // Prepare for Paper eventually removing Bungee chat + getLogger().severe("*********************************************"); + getLogger().severe(""); + getLogger().severe(GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_server_type.header", getServer().getName())); + getLogger().severe(GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_server_type.message", "Paper")); + getLogger().severe(""); + getLogger().severe("*********************************************"); + + Bukkit.getPluginManager().disablePlugin(this); + return; + } + } + // By default this should be localhost but may need to be changed in some circumstances if (this.geyserConfig.getRemote().getAddress().equalsIgnoreCase("auto")) { geyserConfig.setAutoconfiguredRemote(true); @@ -137,7 +153,8 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { geyserConfig.getBedrock().setPort(Bukkit.getPort()); } - this.geyserLogger = new GeyserSpigotLogger(getLogger(), geyserConfig.isDebugMode()); + this.geyserLogger = GeyserPaperLogger.supported() ? new GeyserPaperLogger(this, getLogger(), geyserConfig.isDebugMode()) + : new GeyserSpigotLogger(getLogger(), geyserConfig.isDebugMode()); GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger); // Remove this in like a year @@ -266,12 +283,16 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { GeyserLocale.getLocaleStringLog(command.getDescription()), command.isSuggestedOpOnly() ? PermissionDefault.OP : PermissionDefault.TRUE)); } + Bukkit.getPluginManager().addPermission(new Permission(Constants.UPDATE_PERMISSION, + "Whether update notifications can be seen", PermissionDefault.OP)); // Events cannot be unregistered - re-registering results in duplicate firings GeyserSpigotBlockPlaceListener blockPlaceListener = new GeyserSpigotBlockPlaceListener(geyser, this.geyserWorldManager); Bukkit.getServer().getPluginManager().registerEvents(blockPlaceListener, this); Bukkit.getServer().getPluginManager().registerEvents(new GeyserPistonListener(geyser, this.geyserWorldManager), this); + + Bukkit.getServer().getPluginManager().registerEvents(new GeyserSpigotUpdateListener(), this); } boolean brigadierSupported = CommodoreProvider.isSupported(); diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotUpdateListener.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotUpdateListener.java new file mode 100644 index 000000000..02f5367b3 --- /dev/null +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotUpdateListener.java @@ -0,0 +1,48 @@ +/* + * 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.geyser.platform.spigot; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.geysermc.geyser.Constants; +import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.platform.spigot.command.SpigotCommandSender; +import org.geysermc.geyser.util.VersionCheckUtils; + +public final class GeyserSpigotUpdateListener implements Listener { + + @EventHandler + public void onPlayerJoin(final PlayerJoinEvent event) { + if (GeyserImpl.getInstance().getConfig().isNotifyOnNewBedrockUpdate()) { + final Player player = event.getPlayer(); + if (player.hasPermission(Constants.UPDATE_PERMISSION)) { + VersionCheckUtils.checkForGeyserUpdate(() -> new SpigotCommandSender(player)); + } + } + } +} diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/PaperAdventure.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/PaperAdventure.java new file mode 100644 index 000000000..5dd16da33 --- /dev/null +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/PaperAdventure.java @@ -0,0 +1,154 @@ +/* + * 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.geyser.platform.spigot; + +import com.github.steveice10.mc.protocol.data.DefaultComponentSerializer; +import net.kyori.adventure.text.Component; +import org.bukkit.command.CommandSender; +import org.geysermc.geyser.GeyserImpl; +import org.jetbrains.annotations.Nullable; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Utility class for converting our shaded Adventure into the Adventure bundled in Paper. + * + * Code mostly taken from https://github.com/KyoriPowered/adventure-platform/blob/94d5821f2e755170f42bd8a5fe1d5bf6f66d04ad/platform-bukkit/src/main/java/net/kyori/adventure/platform/bukkit/PaperFacet.java#L46 + * and the MinecraftReflection class. + */ +public final class PaperAdventure { + private static final MethodHandle NATIVE_GSON_COMPONENT_SERIALIZER_DESERIALIZE_METHOD_BOUND; + private static final Method SEND_MESSAGE_COMPONENT; + + static { + final MethodHandles.Lookup lookup = MethodHandles.lookup(); + + MethodHandle nativeGsonComponentSerializerDeserializeMethodBound = null; + + // String.join because otherwise the class name will be relocated + final Class nativeGsonComponentSerializerClass = findClass(String.join(".", + "net", "kyori", "adventure", "text", "serializer", "gson", "GsonComponentSerializer")); + final Class nativeGsonComponentSerializerImplClass = findClass(String.join(".", + "net", "kyori", "adventure", "text", "serializer", "gson", "GsonComponentSerializerImpl")); + if (nativeGsonComponentSerializerClass != null && nativeGsonComponentSerializerImplClass != null) { + MethodHandle nativeGsonComponentSerializerGsonGetter = null; + try { + nativeGsonComponentSerializerGsonGetter = lookup.findStatic(nativeGsonComponentSerializerClass, + "gson", MethodType.methodType(nativeGsonComponentSerializerClass)); + } catch (final NoSuchMethodException | IllegalAccessException ignored) { + } + + MethodHandle nativeGsonComponentSerializerDeserializeMethod = null; + try { + final Method method = nativeGsonComponentSerializerImplClass.getDeclaredMethod("deserialize", String.class); + method.setAccessible(true); + nativeGsonComponentSerializerDeserializeMethod = lookup.unreflect(method); + } catch (final NoSuchMethodException | IllegalAccessException ignored) { + } + + if (nativeGsonComponentSerializerGsonGetter != null) { + if (nativeGsonComponentSerializerDeserializeMethod != null) { + try { + nativeGsonComponentSerializerDeserializeMethodBound = nativeGsonComponentSerializerDeserializeMethod + .bindTo(nativeGsonComponentSerializerGsonGetter.invoke()); + } catch (final Throwable throwable) { + GeyserImpl.getInstance().getLogger().error("Failed to access native GsonComponentSerializer", throwable); + } + } + } + } + + NATIVE_GSON_COMPONENT_SERIALIZER_DESERIALIZE_METHOD_BOUND = nativeGsonComponentSerializerDeserializeMethodBound; + + Method playerComponentSendMessage = null; + final Class nativeComponentClass = findClass(String.join(".", + "net", "kyori", "adventure", "text", "Component")); + if (nativeComponentClass != null) { + try { + playerComponentSendMessage = CommandSender.class.getMethod("sendMessage", nativeComponentClass); + } catch (final NoSuchMethodException e) { + if (GeyserImpl.getInstance().getLogger().isDebug()) { + e.printStackTrace(); + } + } + } + SEND_MESSAGE_COMPONENT = playerComponentSendMessage; + } + + public static Object toNativeComponent(final Component component) { + if (NATIVE_GSON_COMPONENT_SERIALIZER_DESERIALIZE_METHOD_BOUND == null) { + GeyserImpl.getInstance().getLogger().error("Illegal state where Component serialization was called when it wasn't available!"); + return null; + } + + try { + return NATIVE_GSON_COMPONENT_SERIALIZER_DESERIALIZE_METHOD_BOUND.invoke(DefaultComponentSerializer.get().serialize(component)); + } catch (final Throwable throwable) { + GeyserImpl.getInstance().getLogger().error("Failed to create native Component message", throwable); + return null; + } + } + + public static void sendMessage(final CommandSender sender, final Component component) { + if (SEND_MESSAGE_COMPONENT == null) { + GeyserImpl.getInstance().getLogger().error("Illegal state where Component sendMessage was called when it wasn't available!"); + return; + } + + final Object nativeComponent = toNativeComponent(component); + if (nativeComponent != null) { + try { + SEND_MESSAGE_COMPONENT.invoke(sender, nativeComponent); + } catch (final InvocationTargetException | IllegalAccessException e) { + GeyserImpl.getInstance().getLogger().error("Failed to send native Component message", e); + } + } + } + + public static boolean canSendMessageUsingComponent() { + return SEND_MESSAGE_COMPONENT != null; + } + + /** + * Gets a class by the first name available. + * + * @return a class or {@code null} if not found + */ + private static @Nullable Class findClass(final String className) { + try { + return Class.forName(className); + } catch (final ClassNotFoundException ignored) { + } + return null; + } + + private PaperAdventure() { + } +} diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/SpigotCommandSender.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/SpigotCommandSender.java index a05a6ebe0..c6314ced5 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/SpigotCommandSender.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/SpigotCommandSender.java @@ -25,10 +25,13 @@ package org.geysermc.geyser.platform.spigot.command; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer; import org.bukkit.command.ConsoleCommandSender; import org.bukkit.entity.Player; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.command.CommandSender; +import org.geysermc.geyser.platform.spigot.PaperAdventure; import org.geysermc.geyser.text.GeyserLocale; import java.lang.reflect.InvocationTargetException; @@ -63,6 +66,16 @@ public class SpigotCommandSender implements CommandSender { handle.sendMessage(message); } + @Override + public void sendMessage(Component message) { + if (PaperAdventure.canSendMessageUsingComponent()) { + PaperAdventure.sendMessage(handle, message); + return; + } + + handle.sendMessage(BungeeComponentSerializer.get().serialize(message)); + } + @Override public boolean isConsole() { return handle instanceof ConsoleCommandSender; diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java index a03549444..0a6117b43 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java @@ -38,14 +38,14 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.BookMeta; import org.bukkit.plugin.Plugin; -import org.geysermc.geyser.network.MinecraftProtocol; -import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.inventory.LecternInventoryTranslator; +import org.geysermc.geyser.level.GameRule; import org.geysermc.geyser.level.GeyserWorldManager; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.network.MinecraftProtocol; import org.geysermc.geyser.registry.BlockRegistries; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.inventory.LecternInventoryTranslator; import org.geysermc.geyser.util.BlockEntityUtils; -import org.geysermc.geyser.level.GameRule; import java.util.ArrayList; import java.util.List; diff --git a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneLogger.java b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneLogger.java index 3bd2a3960..78e603d7c 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneLogger.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneLogger.java @@ -31,11 +31,10 @@ import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.config.Configurator; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; -import org.geysermc.geyser.command.CommandSender; import org.geysermc.geyser.text.ChatColor; @Log4j2 -public class GeyserStandaloneLogger extends SimpleTerminalConsole implements GeyserLogger, CommandSender { +public class GeyserStandaloneLogger extends SimpleTerminalConsole implements GeyserLogger { @Override protected boolean isRunning() { @@ -95,24 +94,4 @@ public class GeyserStandaloneLogger extends SimpleTerminalConsole implements Gey public boolean isDebug() { return log.isDebugEnabled(); } - - @Override - public String name() { - return "CONSOLE"; - } - - @Override - public void sendMessage(String message) { - info(message); - } - - @Override - public boolean isConsole() { - return true; - } - - @Override - public boolean hasPermission(String permission) { - return true; - } } diff --git a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPlugin.java b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPlugin.java index 4a8a50da8..13a07121e 100644 --- a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPlugin.java +++ b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPlugin.java @@ -161,6 +161,8 @@ public class GeyserVelocityPlugin implements GeyserBootstrap { } else { this.geyserPingPassthrough = new GeyserVelocityPingPassthrough(proxyServer); } + + proxyServer.getEventManager().register(this, new GeyserVelocityUpdateListener()); } @Override diff --git a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityUpdateListener.java b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityUpdateListener.java new file mode 100644 index 000000000..506dfff71 --- /dev/null +++ b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityUpdateListener.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.geyser.platform.velocity; + +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.connection.PostLoginEvent; +import com.velocitypowered.api.proxy.Player; +import org.geysermc.geyser.Constants; +import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.platform.velocity.command.VelocityCommandSender; +import org.geysermc.geyser.util.VersionCheckUtils; + +public final class GeyserVelocityUpdateListener { + + @Subscribe + public void onPlayerJoin(PostLoginEvent event) { + if (GeyserImpl.getInstance().getConfig().isNotifyOnNewBedrockUpdate()) { + final Player player = event.getPlayer(); + if (player.hasPermission(Constants.UPDATE_PERMISSION)) { + VersionCheckUtils.checkForGeyserUpdate(() -> new VelocityCommandSender(player)); + } + } + } +} diff --git a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/VelocityCommandSender.java b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/VelocityCommandSender.java index d5e4804ee..a5474c3e0 100644 --- a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/VelocityCommandSender.java +++ b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/VelocityCommandSender.java @@ -28,6 +28,7 @@ package org.geysermc.geyser.platform.velocity.command; import com.velocitypowered.api.command.CommandSource; import com.velocitypowered.api.proxy.ConsoleCommandSource; import com.velocitypowered.api.proxy.Player; +import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.geysermc.geyser.command.CommandSender; import org.geysermc.geyser.text.GeyserLocale; @@ -59,6 +60,12 @@ public class VelocityCommandSender implements CommandSender { handle.sendMessage(LegacyComponentSerializer.legacy('ยง').deserialize(message)); } + @Override + public void sendMessage(Component message) { + // Be careful that we don't shade in Adventure!! + handle.sendMessage(message); + } + @Override public boolean isConsole() { return handle instanceof ConsoleCommandSource; diff --git a/core/src/main/java/org/geysermc/geyser/Constants.java b/core/src/main/java/org/geysermc/geyser/Constants.java index 23fb76d16..6a53c37de 100644 --- a/core/src/main/java/org/geysermc/geyser/Constants.java +++ b/core/src/main/java/org/geysermc/geyser/Constants.java @@ -37,6 +37,9 @@ public final class Constants { public static final String FLOODGATE_DOWNLOAD_LOCATION = "https://ci.opencollab.dev/job/GeyserMC/job/Floodgate/job/master/"; + public static final String GEYSER_DOWNLOAD_LOCATION = "https://ci.geysermc.org"; + public static final String UPDATE_PERMISSION = "geyser.update"; + static final String SAVED_REFRESH_TOKEN_FILE = "saved-refresh-tokens.json"; static { diff --git a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java index 4322dde59..d9f4d8a15 100644 --- a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java +++ b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java @@ -41,6 +41,8 @@ import io.netty.util.internal.SystemPropertyUtil; import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.api.Geyser; @@ -66,7 +68,6 @@ import org.geysermc.geyser.session.SessionManager; import org.geysermc.geyser.session.auth.AuthType; import org.geysermc.geyser.skin.FloodgateSkinUploader; import org.geysermc.geyser.skin.SkinProvider; -import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.GeyserLocale; import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.inventory.item.ItemTranslator; @@ -303,8 +304,8 @@ public class GeyserImpl implements GeyserApi { int port = config.getBedrock().getPort(); logger.severe(GeyserLocale.getLocaleStringLog("geyser.core.fail", address, String.valueOf(port))); if (!"0.0.0.0".equals(address)) { - logger.info(ChatColor.GREEN + "Suggestion: try setting `address` under `bedrock` in the Geyser config back to 0.0.0.0"); - logger.info(ChatColor.GREEN + "Then, restart this server."); + logger.info(Component.text("Suggestion: try setting `address` under `bedrock` in the Geyser config back to 0.0.0.0", NamedTextColor.GREEN)); + logger.info(Component.text("Then, restart this server.", NamedTextColor.GREEN)); } } }).join(); @@ -454,6 +455,9 @@ public class GeyserImpl implements GeyserApi { } newsHandler.handleNews(null, NewsItemAction.ON_SERVER_STARTED); + if (config.isNotifyOnNewBedrockUpdate()) { + VersionCheckUtils.checkForGeyserUpdate(this::getLogger); + } } @Override diff --git a/core/src/main/java/org/geysermc/geyser/GeyserLogger.java b/core/src/main/java/org/geysermc/geyser/GeyserLogger.java index b47801cb5..197a031dd 100644 --- a/core/src/main/java/org/geysermc/geyser/GeyserLogger.java +++ b/core/src/main/java/org/geysermc/geyser/GeyserLogger.java @@ -25,9 +25,12 @@ package org.geysermc.geyser; +import net.kyori.adventure.text.Component; +import org.geysermc.geyser.command.CommandSender; + import javax.annotation.Nullable; -public interface GeyserLogger { +public interface GeyserLogger extends CommandSender { /** * Logs a severe message to console @@ -73,6 +76,15 @@ public interface GeyserLogger { */ void info(String message); + /** + * Logs an info component to console + * + * @param message the message to log + */ + default void info(Component message) { + sendMessage(message); + } + /** * Logs a debug message to console * @@ -100,4 +112,24 @@ public interface GeyserLogger { * If debug is enabled for this logger */ boolean isDebug(); + + @Override + default String name() { + return "CONSOLE"; + } + + @Override + default void sendMessage(String message) { + info(message); + } + + @Override + default boolean isConsole() { + return true; + } + + @Override + default boolean hasPermission(String permission) { + return true; + } } diff --git a/core/src/main/java/org/geysermc/geyser/command/CommandSender.java b/core/src/main/java/org/geysermc/geyser/command/CommandSender.java index d9d1bcfbc..61adad717 100644 --- a/core/src/main/java/org/geysermc/geyser/command/CommandSender.java +++ b/core/src/main/java/org/geysermc/geyser/command/CommandSender.java @@ -25,6 +25,8 @@ package org.geysermc.geyser.command; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.geysermc.geyser.text.GeyserLocale; /** @@ -43,6 +45,10 @@ public interface CommandSender { void sendMessage(String message); + default void sendMessage(Component message) { + sendMessage(LegacyComponentSerializer.legacySection().serialize(message)); + } + /** * @return true if the specified sender is from the console. */ diff --git a/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfiguration.java b/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfiguration.java index 1f188cf40..f605ad103 100644 --- a/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfiguration.java +++ b/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfiguration.java @@ -105,6 +105,8 @@ public interface GeyserConfiguration { int getCustomSkullRenderDistance(); + boolean isNotifyOnNewBedrockUpdate(); + IMetricsInfo getMetrics(); int getPendingAuthenticationTimeout(); diff --git a/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java b/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java index 30a947e53..80fa22ede 100644 --- a/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java +++ b/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java @@ -148,6 +148,9 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration @JsonProperty("xbox-achievements-enabled") private boolean xboxAchievementsEnabled = false; + @JsonProperty("notify-on-new-bedrock-update") + private boolean notifyOnNewBedrockUpdate = true; + private MetricsInfo metrics = new MetricsInfo(); @JsonProperty("pending-authentication-timeout") diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java index 239f5c865..7996d1188 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java @@ -31,6 +31,7 @@ import com.nukkitx.protocol.bedrock.packet.SetTitlePacket; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Getter; import lombok.Setter; +import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.scoreboard.Scoreboard; import org.geysermc.geyser.scoreboard.ScoreboardUpdater.ScoreboardSession; import org.geysermc.geyser.session.GeyserSession; @@ -172,6 +173,7 @@ public final class WorldCache { if (serverVerifiedState.sequence <= sequence) { // This block may be out of sync with the server // In 1.19.0 Java, you can verify this by trying to mine in spawn protection + System.out.println("Resetting " + entry.getKey() + " to " + BlockRegistries.JAVA_BLOCKS.get(serverVerifiedState.blockState).getJavaIdentifier()); ChunkUtils.updateBlockClientSide(session, serverVerifiedState.blockState, entry.getKey()); it.remove(); } diff --git a/core/src/main/java/org/geysermc/geyser/util/VersionCheckUtils.java b/core/src/main/java/org/geysermc/geyser/util/VersionCheckUtils.java index 934680ce1..b1f97989f 100644 --- a/core/src/main/java/org/geysermc/geyser/util/VersionCheckUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/VersionCheckUtils.java @@ -25,10 +25,22 @@ package org.geysermc.geyser.util; +import com.fasterxml.jackson.databind.JsonNode; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextReplacementConfig; +import net.kyori.adventure.text.event.ClickEvent; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; import org.geysermc.geyser.Constants; +import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; +import org.geysermc.geyser.command.CommandSender; +import org.geysermc.geyser.network.MinecraftProtocol; import org.geysermc.geyser.text.GeyserLocale; +import java.util.concurrent.CompletableFuture; +import java.util.function.Supplier; + public final class VersionCheckUtils { public static void checkForOutdatedFloodgate(GeyserLogger logger) { @@ -42,6 +54,41 @@ public final class VersionCheckUtils { } } + public static void checkForGeyserUpdate(Supplier recipient) { + CompletableFuture.runAsync(() -> { + try { + JsonNode json = WebUtils.getJson("https://api.geysermc.org/v2/versions/geyser"); + JsonNode bedrock = json.get("bedrock").get("protocol"); + int protocolVersion = bedrock.get("id").asInt(); + if (MinecraftProtocol.getBedrockCodec(protocolVersion) != null) { + // We support the latest version! No need to print a message. + return; + } + + final String newBedrockVersion = bedrock.get("name").asText(); + + // Delayed for two reasons: save unnecessary processing, and wait to load locale if this is on join. + CommandSender sender = recipient.get(); + + // Overarching component is green - geyser.version.new component cannot be green or else the link blue is overshadowed + Component message = Component.text().color(NamedTextColor.GREEN) + .append(Component.text(GeyserLocale.getPlayerLocaleString("geyser.version.new", sender.getLocale(), newBedrockVersion)) + .replaceText(TextReplacementConfig.builder() + .match("\\{1\\}") // Replace "Download here: {1}" so we can use fancy text component yesyes + .replacement(Component.text() + .content(Constants.GEYSER_DOWNLOAD_LOCATION) + .color(NamedTextColor.BLUE) + .decoration(TextDecoration.UNDERLINED, TextDecoration.State.TRUE) + .clickEvent(ClickEvent.openUrl(Constants.GEYSER_DOWNLOAD_LOCATION))) + .build())) + .build(); + sender.sendMessage(message); + } catch (Exception e) { + GeyserImpl.getInstance().getLogger().error("Error whilst checking for Geyser update!", e); + } + }); + } + private VersionCheckUtils() { } } diff --git a/core/src/main/java/org/geysermc/geyser/util/WebUtils.java b/core/src/main/java/org/geysermc/geyser/util/WebUtils.java index f9574f08b..c0889f1c5 100644 --- a/core/src/main/java/org/geysermc/geyser/util/WebUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/WebUtils.java @@ -73,6 +73,8 @@ public class WebUtils { public static JsonNode getJson(String reqURL) throws IOException { HttpURLConnection con = (HttpURLConnection) new URL(reqURL).openConnection(); con.setRequestProperty("User-Agent", "Geyser-" + GeyserImpl.getInstance().getPlatformType().toString() + "/" + GeyserImpl.VERSION); + con.setConnectTimeout(10000); + con.setReadTimeout(10000); return GeyserImpl.JSON_MAPPER.readTree(con.getInputStream()); } diff --git a/core/src/main/resources/config.yml b/core/src/main/resources/config.yml index c331a7e62..5a32a6599 100644 --- a/core/src/main/resources/config.yml +++ b/core/src/main/resources/config.yml @@ -175,6 +175,11 @@ force-resource-packs: true # THIS DISABLES ALL COMMANDS FROM SUCCESSFULLY RUNNING FOR BEDROCK IN-GAME, as otherwise Bedrock thinks you are cheating. xbox-achievements-enabled: false +# Whether to alert the console and operators that a new Geyser version is available that supports a Bedrock version +# that this Geyser version does not support. It's recommended to keep this option enabled, as many Bedrock platforms +# auto-update. +notify-on-new-bedrock-update: true + # bStats is a stat tracker that is entirely anonymous and tracks only basic information # about Geyser, such as how many people are online, how many servers are using Geyser, # what OS is being used, etc. You can learn more about bStats here: https://bstats.org/. From d499e22502208fcc974f82233f9ef24e92de6f90 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sun, 21 Aug 2022 21:25:32 -0400 Subject: [PATCH 05/11] Debugging always sneaks in... --- .../main/java/org/geysermc/geyser/session/cache/WorldCache.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java index 7996d1188..30f8c3ba8 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java @@ -173,7 +173,6 @@ public final class WorldCache { if (serverVerifiedState.sequence <= sequence) { // This block may be out of sync with the server // In 1.19.0 Java, you can verify this by trying to mine in spawn protection - System.out.println("Resetting " + entry.getKey() + " to " + BlockRegistries.JAVA_BLOCKS.get(serverVerifiedState.blockState).getJavaIdentifier()); ChunkUtils.updateBlockClientSide(session, serverVerifiedState.blockState, entry.getKey()); it.remove(); } From 82411978c859205e78b1c8c4da7c1c7b7999eb2a Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 22 Aug 2022 14:34:26 -0400 Subject: [PATCH 06/11] Update languages submodule --- core/src/main/resources/languages | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/resources/languages b/core/src/main/resources/languages index 4351fc11d..ad92d550b 160000 --- a/core/src/main/resources/languages +++ b/core/src/main/resources/languages @@ -1 +1 @@ -Subproject commit 4351fc11d5fbd9fecc8334910234cdf8a4bc730b +Subproject commit ad92d550bab49bc46f17db6aa0042035b66a1a10 From 8dde4b434790e40221cf147e47e4aa83e3263893 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 23 Aug 2022 13:20:57 -0400 Subject: [PATCH 07/11] Support Bedrock 1.19.21 --- .../java/org/geysermc/geyser/network/MinecraftProtocol.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/network/MinecraftProtocol.java b/core/src/main/java/org/geysermc/geyser/network/MinecraftProtocol.java index 3452ec7d5..98f431d15 100644 --- a/core/src/main/java/org/geysermc/geyser/network/MinecraftProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/MinecraftProtocol.java @@ -45,7 +45,10 @@ public final class MinecraftProtocol { * Default Bedrock codec that should act as a fallback. Should represent the latest available * release of the game that Geyser supports. */ - public static final BedrockPacketCodec DEFAULT_BEDROCK_CODEC = Bedrock_v544.V544_CODEC; + public static final BedrockPacketCodec DEFAULT_BEDROCK_CODEC = Bedrock_v544.V544_CODEC.toBuilder() + .minecraftVersion("1.19.21") + .protocolVersion(545) + .build(); /** * A list of all supported Bedrock versions that can join Geyser */ @@ -64,6 +67,7 @@ public final class MinecraftProtocol { SUPPORTED_BEDROCK_CODECS.add(Bedrock_v534.V534_CODEC.toBuilder() .minecraftVersion("1.19.10/1.19.11") .build()); + SUPPORTED_BEDROCK_CODECS.add(Bedrock_v544.V544_CODEC); SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC); } From e35f3785b2566b3f8ca78ff7fea271afe71ac8c2 Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Wed, 24 Aug 2022 04:53:13 +0000 Subject: [PATCH 08/11] Resolve fallout --- api/geyser/build.gradle.kts | 2 ++ bootstrap/bungeecord/build.gradle.kts | 2 ++ .../bungeecord/GeyserBungeeUpdateListener.java | 4 ++-- bootstrap/spigot/build.gradle.kts | 7 ++++++- .../platform/spigot/GeyserSpigotUpdateListener.java | 4 ++-- .../velocity/GeyserVelocityUpdateListener.java | 4 ++-- build-logic/src/main/kotlin/Versions.kt | 1 + .../main/java/org/geysermc/geyser/GeyserLogger.java | 4 ++-- .../BedrockInventoryTransactionTranslator.java | 4 ++-- .../org/geysermc/geyser/util/VersionCheckUtils.java | 12 ++++++------ 10 files changed, 27 insertions(+), 17 deletions(-) diff --git a/api/geyser/build.gradle.kts b/api/geyser/build.gradle.kts index dcde85337..60bd4a431 100644 --- a/api/geyser/build.gradle.kts +++ b/api/geyser/build.gradle.kts @@ -4,6 +4,8 @@ plugins { dependencies { api(projects.api) + + implementation("net.kyori", "adventure-text-serializer-legacy", Versions.adventureVersion) } publishing { diff --git a/bootstrap/bungeecord/build.gradle.kts b/bootstrap/bungeecord/build.gradle.kts index 873df692a..9f3b49b67 100644 --- a/bootstrap/bungeecord/build.gradle.kts +++ b/bootstrap/bungeecord/build.gradle.kts @@ -2,6 +2,8 @@ val bungeeVersion = "a7c6ede"; dependencies { api(projects.core) + + implementation("net.kyori", "adventure-text-serializer-bungeecord", Versions.adventurePlatformVersion) } platformRelocate("net.md_5.bungee.jni") diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeeUpdateListener.java b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeeUpdateListener.java index bbde8771e..c68839b20 100644 --- a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeeUpdateListener.java +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeeUpdateListener.java @@ -31,7 +31,7 @@ import net.md_5.bungee.api.plugin.Listener; import net.md_5.bungee.event.EventHandler; import org.geysermc.geyser.Constants; import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.platform.bungeecord.command.BungeeCommandSender; +import org.geysermc.geyser.platform.bungeecord.command.BungeeCommandSource; import org.geysermc.geyser.util.VersionCheckUtils; public final class GeyserBungeeUpdateListener implements Listener { @@ -41,7 +41,7 @@ public final class GeyserBungeeUpdateListener implements Listener { if (GeyserImpl.getInstance().getConfig().isNotifyOnNewBedrockUpdate()) { final ProxiedPlayer player = event.getPlayer(); if (player.hasPermission(Constants.UPDATE_PERMISSION)) { - VersionCheckUtils.checkForGeyserUpdate(() -> new BungeeCommandSender(player)); + VersionCheckUtils.checkForGeyserUpdate(() -> new BungeeCommandSource(player)); } } } diff --git a/bootstrap/spigot/build.gradle.kts b/bootstrap/spigot/build.gradle.kts index 02883999d..2fe3d6e2b 100644 --- a/bootstrap/spigot/build.gradle.kts +++ b/bootstrap/spigot/build.gradle.kts @@ -1,7 +1,7 @@ val paperVersion = "1.19-R0.1-SNAPSHOT" val viaVersion = "4.0.0" val adaptersVersion = "1.5-SNAPSHOT" -val commodoreVersion = "1.13" +val commodoreVersion = "2.2" dependencies { api(projects.core) @@ -9,6 +9,8 @@ dependencies { implementation("org.geysermc.geyser.adapters", "spigot-all", adaptersVersion) implementation("me.lucko", "commodore", commodoreVersion) + + implementation("net.kyori", "adventure-text-serializer-bungeecord", Versions.adventurePlatformVersion) // Both paper-api and paper-mojangapi only provide Java 17 versions for 1.19 compileOnly("io.papermc.paper", "paper-api", paperVersion) { @@ -61,5 +63,8 @@ tasks.withType { // Commodore includes Brigadier exclude(dependency("com.mojang:.*")) + + // Adventure slf4j + exclude(dependency("net.kyori.adventure.text.logger.slf4j:ComponentLogger")) } } \ No newline at end of file diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotUpdateListener.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotUpdateListener.java index 02f5367b3..5e3c4def8 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotUpdateListener.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotUpdateListener.java @@ -31,7 +31,7 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import org.geysermc.geyser.Constants; import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.platform.spigot.command.SpigotCommandSender; +import org.geysermc.geyser.platform.spigot.command.SpigotCommandSource; import org.geysermc.geyser.util.VersionCheckUtils; public final class GeyserSpigotUpdateListener implements Listener { @@ -41,7 +41,7 @@ public final class GeyserSpigotUpdateListener implements Listener { if (GeyserImpl.getInstance().getConfig().isNotifyOnNewBedrockUpdate()) { final Player player = event.getPlayer(); if (player.hasPermission(Constants.UPDATE_PERMISSION)) { - VersionCheckUtils.checkForGeyserUpdate(() -> new SpigotCommandSender(player)); + VersionCheckUtils.checkForGeyserUpdate(() -> new SpigotCommandSource(player)); } } } diff --git a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityUpdateListener.java b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityUpdateListener.java index 506dfff71..31e584612 100644 --- a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityUpdateListener.java +++ b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityUpdateListener.java @@ -30,7 +30,7 @@ import com.velocitypowered.api.event.connection.PostLoginEvent; import com.velocitypowered.api.proxy.Player; import org.geysermc.geyser.Constants; import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.platform.velocity.command.VelocityCommandSender; +import org.geysermc.geyser.platform.velocity.command.VelocityCommandSource; import org.geysermc.geyser.util.VersionCheckUtils; public final class GeyserVelocityUpdateListener { @@ -40,7 +40,7 @@ public final class GeyserVelocityUpdateListener { if (GeyserImpl.getInstance().getConfig().isNotifyOnNewBedrockUpdate()) { final Player player = event.getPlayer(); if (player.hasPermission(Constants.UPDATE_PERMISSION)) { - VersionCheckUtils.checkForGeyserUpdate(() -> new VelocityCommandSender(player)); + VersionCheckUtils.checkForGeyserUpdate(() -> new VelocityCommandSource(player)); } } } diff --git a/build-logic/src/main/kotlin/Versions.kt b/build-logic/src/main/kotlin/Versions.kt index f7b20cca1..d4a0a80e3 100644 --- a/build-logic/src/main/kotlin/Versions.kt +++ b/build-logic/src/main/kotlin/Versions.kt @@ -39,6 +39,7 @@ object Versions { const val mcprotocollibversion = "9f78bd5" const val packetlibVersion = "3.0" const val adventureVersion = "4.9.3" + const val adventurePlatformVersion = "4.1.2" const val junitVersion = "4.13.1" const val checkerQualVersion = "3.19.0" const val cumulusVersion = "1.1.1" diff --git a/core/src/main/java/org/geysermc/geyser/GeyserLogger.java b/core/src/main/java/org/geysermc/geyser/GeyserLogger.java index 197a031dd..88220eec9 100644 --- a/core/src/main/java/org/geysermc/geyser/GeyserLogger.java +++ b/core/src/main/java/org/geysermc/geyser/GeyserLogger.java @@ -26,11 +26,11 @@ package org.geysermc.geyser; import net.kyori.adventure.text.Component; -import org.geysermc.geyser.command.CommandSender; +import org.geysermc.geyser.command.GeyserCommandSource; import javax.annotation.Nullable; -public interface GeyserLogger extends CommandSender { +public interface GeyserLogger extends GeyserCommandSource { /** * Logs a severe message to console diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java index 02a7ddace..e72f7d786 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java @@ -54,7 +54,7 @@ import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.PlayerInventory; import org.geysermc.geyser.inventory.click.Click; import org.geysermc.geyser.level.block.BlockStateValues; -import org.geysermc.geyser.network.MinecraftProtocol; +import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; @@ -467,7 +467,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator recipient) { + public static void checkForGeyserUpdate(Supplier recipient) { CompletableFuture.runAsync(() -> { try { JsonNode json = WebUtils.getJson("https://api.geysermc.org/v2/versions/geyser"); JsonNode bedrock = json.get("bedrock").get("protocol"); int protocolVersion = bedrock.get("id").asInt(); - if (MinecraftProtocol.getBedrockCodec(protocolVersion) != null) { + if (GameProtocol.getBedrockCodec(protocolVersion) != null) { // We support the latest version! No need to print a message. return; } @@ -68,11 +68,11 @@ public final class VersionCheckUtils { final String newBedrockVersion = bedrock.get("name").asText(); // Delayed for two reasons: save unnecessary processing, and wait to load locale if this is on join. - CommandSender sender = recipient.get(); + GeyserCommandSource sender = recipient.get(); // Overarching component is green - geyser.version.new component cannot be green or else the link blue is overshadowed Component message = Component.text().color(NamedTextColor.GREEN) - .append(Component.text(GeyserLocale.getPlayerLocaleString("geyser.version.new", sender.getLocale(), newBedrockVersion)) + .append(Component.text(GeyserLocale.getPlayerLocaleString("geyser.version.new", sender.locale(), newBedrockVersion)) .replaceText(TextReplacementConfig.builder() .match("\\{1\\}") // Replace "Download here: {1}" so we can use fancy text component yesyes .replacement(Component.text() From dc29d997fd7e7ea81ca7bfe4534b6ea946ec24cd Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Wed, 24 Aug 2022 05:18:12 +0000 Subject: [PATCH 09/11] Exclude from relocation, not inclusion --- bootstrap/spigot/build.gradle.kts | 4 ++-- build-logic/src/main/kotlin/extensions.kt | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/bootstrap/spigot/build.gradle.kts b/bootstrap/spigot/build.gradle.kts index 2fe3d6e2b..1b954e1d4 100644 --- a/bootstrap/spigot/build.gradle.kts +++ b/bootstrap/spigot/build.gradle.kts @@ -27,7 +27,7 @@ dependencies { platformRelocate("it.unimi.dsi.fastutil") platformRelocate("com.fasterxml.jackson") -platformRelocate("net.kyori") +platformRelocate("net.kyori", "net.kyori.adventure.text.logger.slf4j.ComponentLogger") platformRelocate("org.objectweb.asm") platformRelocate("me.lucko.commodore") platformRelocate("io.netty.channel.kqueue") @@ -65,6 +65,6 @@ tasks.withType { exclude(dependency("com.mojang:.*")) // Adventure slf4j - exclude(dependency("net.kyori.adventure.text.logger.slf4j:ComponentLogger")) + //exclude(dependency("net.kyori.adventure.text.logger.slf4j:ComponentLogger")) } } \ No newline at end of file diff --git a/build-logic/src/main/kotlin/extensions.kt b/build-logic/src/main/kotlin/extensions.kt index 1f9793ee4..43cdafdcc 100644 --- a/build-logic/src/main/kotlin/extensions.kt +++ b/build-logic/src/main/kotlin/extensions.kt @@ -43,9 +43,11 @@ fun Project.exclude(group: String) { } } -fun Project.platformRelocate(pattern: String) { +fun Project.platformRelocate(pattern: String, exclusion: String = "") { tasks.named("shadowJar") { - relocate(pattern, "org.geysermc.geyser.platform.${project.name}.shaded.$pattern") + relocate(pattern, "org.geysermc.geyser.platform.${project.name}.shaded.$pattern") { + exclude(exclusion) + } } } From f1642d81dc2e2c03ae9bb78c300c305aa6a9dbc3 Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Wed, 24 Aug 2022 13:41:24 +0000 Subject: [PATCH 10/11] Fix comment --- bootstrap/spigot/build.gradle.kts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bootstrap/spigot/build.gradle.kts b/bootstrap/spigot/build.gradle.kts index 1b954e1d4..5a459a09b 100644 --- a/bootstrap/spigot/build.gradle.kts +++ b/bootstrap/spigot/build.gradle.kts @@ -27,6 +27,7 @@ dependencies { platformRelocate("it.unimi.dsi.fastutil") platformRelocate("com.fasterxml.jackson") +// Relocate net.kyori but exclude the component logger platformRelocate("net.kyori", "net.kyori.adventure.text.logger.slf4j.ComponentLogger") platformRelocate("org.objectweb.asm") platformRelocate("me.lucko.commodore") @@ -63,8 +64,5 @@ tasks.withType { // Commodore includes Brigadier exclude(dependency("com.mojang:.*")) - - // Adventure slf4j - //exclude(dependency("net.kyori.adventure.text.logger.slf4j:ComponentLogger")) } } \ No newline at end of file From 936fed1ded9e8c778e296433a2221c693a9462ba Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Wed, 24 Aug 2022 15:38:54 +0000 Subject: [PATCH 11/11] Move sendMessage(Component) to GeyserCommandSource --- api/geyser/build.gradle.kts | 2 -- .../org/geysermc/geyser/api/command/CommandSource.java | 7 ------- .../org/geysermc/geyser/command/GeyserCommandSource.java | 6 ++++++ 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/api/geyser/build.gradle.kts b/api/geyser/build.gradle.kts index 60bd4a431..dcde85337 100644 --- a/api/geyser/build.gradle.kts +++ b/api/geyser/build.gradle.kts @@ -4,8 +4,6 @@ plugins { dependencies { api(projects.api) - - implementation("net.kyori", "adventure-text-serializer-legacy", Versions.adventureVersion) } publishing { diff --git a/api/geyser/src/main/java/org/geysermc/geyser/api/command/CommandSource.java b/api/geyser/src/main/java/org/geysermc/geyser/api/command/CommandSource.java index 4465e79b2..aabf0c4e8 100644 --- a/api/geyser/src/main/java/org/geysermc/geyser/api/command/CommandSource.java +++ b/api/geyser/src/main/java/org/geysermc/geyser/api/command/CommandSource.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.api.command; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; - /** * Represents an instance capable of sending commands. */ @@ -58,10 +55,6 @@ public interface CommandSource { } } - default void sendMessage(Component message) { - sendMessage(LegacyComponentSerializer.legacySection().serialize(message)); - } - /** * If this source is the console. * diff --git a/core/src/main/java/org/geysermc/geyser/command/GeyserCommandSource.java b/core/src/main/java/org/geysermc/geyser/command/GeyserCommandSource.java index eabccc243..88d148b11 100644 --- a/core/src/main/java/org/geysermc/geyser/command/GeyserCommandSource.java +++ b/core/src/main/java/org/geysermc/geyser/command/GeyserCommandSource.java @@ -27,6 +27,8 @@ package org.geysermc.geyser.command; import org.geysermc.geyser.api.command.CommandSource; import org.geysermc.geyser.text.GeyserLocale; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; /** * Implemented on top of any class that can send a command. @@ -40,4 +42,8 @@ public interface GeyserCommandSource extends CommandSource { default String locale() { return GeyserLocale.getDefaultLocale(); } + + default void sendMessage(Component message) { + sendMessage(LegacyComponentSerializer.legacySection().serialize(message)); + } }