From 8210fdf96bdbbcaf04f928a7aad09f040fe2525d Mon Sep 17 00:00:00 2001 From: Xingjian Xie Date: Sat, 17 Feb 2024 05:45:12 +0000 Subject: [PATCH] Add throw back feature for velocity server when connection is unsuccessful --- .../bukkit/AdvancedPortalsPlugin.java | 7 +++ .../listeners/PluginMessageReceiver.java | 13 ++++++ .../bukkit/portals/Portal.java | 22 +++++++--- .../bungee/BungeeMessages.java | 4 ++ .../velocity/AdvancedPortalsPlugin.java | 43 +++++++++++++++++++ 5 files changed, 82 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/sekwah/advancedportals/bukkit/AdvancedPortalsPlugin.java b/src/main/java/com/sekwah/advancedportals/bukkit/AdvancedPortalsPlugin.java index 30051c2..b64537b 100644 --- a/src/main/java/com/sekwah/advancedportals/bukkit/AdvancedPortalsPlugin.java +++ b/src/main/java/com/sekwah/advancedportals/bukkit/AdvancedPortalsPlugin.java @@ -27,6 +27,8 @@ public class AdvancedPortalsPlugin extends JavaPlugin { protected boolean isProxyPluginEnabled = false; + protected boolean isVelocitySupported = false; + protected boolean forceRegisterProxyChannels = false; protected boolean disableProxyWarning = false; @@ -134,6 +136,10 @@ public class AdvancedPortalsPlugin extends JavaPlugin { return isProxyPluginEnabled; } + public boolean isVelocitySupported() { + return isVelocitySupported; + } + private boolean checkIfBungee() { // we check if the server is Spigot/Paper (because of the spigot.yml file) @@ -161,6 +167,7 @@ public class AdvancedPortalsPlugin extends JavaPlugin { if(Objects.equals(config.get("velocity-support.enabled"),true) || Objects.equals(config.get("proxies.velocity.enabled"),true)) { getLogger().info( "Modern forwarding detected. Enabling proxy features." ); + isVelocitySupported = true; return true; } } catch(NoSuchMethodError | NullPointerException e) { diff --git a/src/main/java/com/sekwah/advancedportals/bukkit/listeners/PluginMessageReceiver.java b/src/main/java/com/sekwah/advancedportals/bukkit/listeners/PluginMessageReceiver.java index 693462d..54f54de 100644 --- a/src/main/java/com/sekwah/advancedportals/bukkit/listeners/PluginMessageReceiver.java +++ b/src/main/java/com/sekwah/advancedportals/bukkit/listeners/PluginMessageReceiver.java @@ -3,9 +3,11 @@ package com.sekwah.advancedportals.bukkit.listeners; import com.google.common.io.ByteArrayDataInput; import com.google.common.io.ByteStreams; import com.sekwah.advancedportals.bukkit.AdvancedPortalsPlugin; +import com.sekwah.advancedportals.bukkit.PluginMessages; import com.sekwah.advancedportals.bukkit.config.ConfigAccessor; import com.sekwah.advancedportals.bukkit.config.ConfigHelper; import com.sekwah.advancedportals.bukkit.destinations.Destination; +import com.sekwah.advancedportals.bukkit.portals.Portal; import com.sekwah.advancedportals.bungee.BungeeMessages; import org.bukkit.entity.Player; import org.bukkit.plugin.messaging.PluginMessageListener; @@ -48,6 +50,17 @@ public class PluginMessageReceiver implements PluginMessageListener { ); } + } else if (subchannel.equals(BungeeMessages.KNOCKBACK)) { + String reason = in.readUTF(); + String bungeeUUID = in.readUTF(); + + Player targetPlayer = this.plugin.getServer().getPlayer(UUID.fromString(bungeeUUID)); + + if (targetPlayer != null) { + Portal.throwPlayerBack(targetPlayer); + player.sendMessage(PluginMessages.customPrefixFail + + "\u00A7c " + reason); + } } } diff --git a/src/main/java/com/sekwah/advancedportals/bukkit/portals/Portal.java b/src/main/java/com/sekwah/advancedportals/bukkit/portals/Portal.java index 9cdd76b..a65dd11 100644 --- a/src/main/java/com/sekwah/advancedportals/bukkit/portals/Portal.java +++ b/src/main/java/com/sekwah/advancedportals/bukkit/portals/Portal.java @@ -546,16 +546,24 @@ public class Portal { } - ByteArrayDataOutput outForSend = ByteStreams.newDataOutput(); - outForSend.writeUTF("Connect"); - outForSend.writeUTF(bungeeServer); + if (!plugin.isVelocitySupported() || !doKnockback) { + ByteArrayDataOutput outForSend = ByteStreams.newDataOutput(); + outForSend.writeUTF("Connect"); + outForSend.writeUTF(bungeeServer); + portal.inPortal.add(player.getUniqueId()); + player.sendPluginMessage(plugin, "BungeeCord", outForSend.toByteArray()); + // Down to bungee to sort out the teleporting but yea theoretically they should + // warp. + } else { + ByteArrayDataOutput outForSend = ByteStreams.newDataOutput(); + outForSend.writeUTF(BungeeMessages.SEND_TO_SERVER_WITH_KNOCKBACK); + outForSend.writeUTF(bungeeServer); - portal.inPortal.add(player.getUniqueId()); - player.sendPluginMessage(plugin, "BungeeCord", outForSend.toByteArray()); - // Down to bungee to sort out the teleporting but yea theoretically they should - // warp. + portal.inPortal.add(player.getUniqueId()); + player.sendPluginMessage(plugin, BungeeMessages.CHANNEL_NAME, outForSend.toByteArray()); + } } else if (portal.getDestinations().length > 0) { ConfigAccessor configDesti = new ConfigAccessor(plugin, "destinations.yml"); String randomDest = portal.getDestinations()[random.nextInt(portal.getDestinations().length)]; diff --git a/src/main/java/com/sekwah/advancedportals/bungee/BungeeMessages.java b/src/main/java/com/sekwah/advancedportals/bungee/BungeeMessages.java index 9931ddc..f766292 100644 --- a/src/main/java/com/sekwah/advancedportals/bungee/BungeeMessages.java +++ b/src/main/java/com/sekwah/advancedportals/bungee/BungeeMessages.java @@ -17,6 +17,10 @@ public class BungeeMessages { */ public static String ENTER_PORTAL = "PortalEnter"; + public static String SEND_TO_SERVER_WITH_KNOCKBACK = "SendToServerWithKnockback"; + + public static String KNOCKBACK = "Knockback"; + public static String CHANNEL_NAME = "advancedportals:warp"; diff --git a/src/main/java/com/sekwah/advancedportals/velocity/AdvancedPortalsPlugin.java b/src/main/java/com/sekwah/advancedportals/velocity/AdvancedPortalsPlugin.java index e6809de..1b890f6 100644 --- a/src/main/java/com/sekwah/advancedportals/velocity/AdvancedPortalsPlugin.java +++ b/src/main/java/com/sekwah/advancedportals/velocity/AdvancedPortalsPlugin.java @@ -10,12 +10,19 @@ import com.velocitypowered.api.event.connection.PluginMessageEvent; import com.velocitypowered.api.event.player.ServerPostConnectEvent; import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; import com.velocitypowered.api.plugin.Plugin; +import com.velocitypowered.api.proxy.ConnectionRequestBuilder; +import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.ProxyServer; import com.velocitypowered.api.proxy.ServerConnection; import com.velocitypowered.api.proxy.messages.LegacyChannelIdentifier; +import com.velocitypowered.api.proxy.server.RegisteredServer; import org.slf4j.Logger; import java.util.HashMap; +import java.util.Optional; +import java.util.concurrent.CancellationException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; /** @@ -51,6 +58,21 @@ public class AdvancedPortalsPlugin { proxy.getChannelRegistrar().register(AP_CHANNEL); } + private void throwPlayerBack(Player player, String reason) { + ByteArrayDataOutput out = ByteStreams.newDataOutput(); + + out.writeUTF(BungeeMessages.KNOCKBACK); + out.writeUTF(reason); + out.writeUTF(player.getUniqueId().toString()); + + player.getCurrentServer().ifPresent(serverConnection -> + serverConnection.sendPluginMessage(AP_CHANNEL, out.toByteArray()) + ); + } + + static class CannotConnectException extends Exception { + } + @Subscribe public void onPluginMessage(PluginMessageEvent event) { if(event.getIdentifier().equals(AP_CHANNEL)) { @@ -77,6 +99,27 @@ public class AdvancedPortalsPlugin { proxy.getCommandManager().executeAsync(connection.getPlayer(), command); } + } else if (subChannel.equalsIgnoreCase(BungeeMessages.SEND_TO_SERVER_WITH_KNOCKBACK)) { + String targetServer = in.readUTF(); + Optional server = proxy.getServer(targetServer); + Player player = ((ServerConnection) event.getSource()).getPlayer(); + if (!server.isPresent()) { + throwPlayerBack(player, "The server is invalid"); + } else { + CompletableFuture future = player.createConnectionRequest(server.get()) + .connect(); + proxy.getScheduler().buildTask(this, () -> { + try { + ConnectionRequestBuilder.Result result = future.get(); + if (!result.isSuccessful()) { + throw new CannotConnectException(); + } + } catch (CancellationException | InterruptedException | ExecutionException | + CannotConnectException e) { + throwPlayerBack(player, "Could not connect to the server"); + } + }).schedule(); + } } } // So that client packets don't make it through to the servers, always trigger on this channel.