Add throw back feature for velocity server when connection is unsuccessful

This commit is contained in:
Xingjian Xie 2024-02-17 05:45:12 +00:00
parent a0cd907242
commit 8210fdf96b
5 changed files with 82 additions and 7 deletions

View File

@ -27,6 +27,8 @@ public class AdvancedPortalsPlugin extends JavaPlugin {
protected boolean isProxyPluginEnabled = false; protected boolean isProxyPluginEnabled = false;
protected boolean isVelocitySupported = false;
protected boolean forceRegisterProxyChannels = false; protected boolean forceRegisterProxyChannels = false;
protected boolean disableProxyWarning = false; protected boolean disableProxyWarning = false;
@ -134,6 +136,10 @@ public class AdvancedPortalsPlugin extends JavaPlugin {
return isProxyPluginEnabled; return isProxyPluginEnabled;
} }
public boolean isVelocitySupported() {
return isVelocitySupported;
}
private boolean checkIfBungee() private boolean checkIfBungee()
{ {
// we check if the server is Spigot/Paper (because of the spigot.yml file) // 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) if(Objects.equals(config.get("velocity-support.enabled"),true)
|| Objects.equals(config.get("proxies.velocity.enabled"),true)) { || Objects.equals(config.get("proxies.velocity.enabled"),true)) {
getLogger().info( "Modern forwarding detected. Enabling proxy features." ); getLogger().info( "Modern forwarding detected. Enabling proxy features." );
isVelocitySupported = true;
return true; return true;
} }
} catch(NoSuchMethodError | NullPointerException e) { } catch(NoSuchMethodError | NullPointerException e) {

View File

@ -3,9 +3,11 @@ package com.sekwah.advancedportals.bukkit.listeners;
import com.google.common.io.ByteArrayDataInput; import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams; import com.google.common.io.ByteStreams;
import com.sekwah.advancedportals.bukkit.AdvancedPortalsPlugin; 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.ConfigAccessor;
import com.sekwah.advancedportals.bukkit.config.ConfigHelper; import com.sekwah.advancedportals.bukkit.config.ConfigHelper;
import com.sekwah.advancedportals.bukkit.destinations.Destination; import com.sekwah.advancedportals.bukkit.destinations.Destination;
import com.sekwah.advancedportals.bukkit.portals.Portal;
import com.sekwah.advancedportals.bungee.BungeeMessages; import com.sekwah.advancedportals.bungee.BungeeMessages;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.messaging.PluginMessageListener; 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);
}
} }
} }

View File

@ -546,16 +546,24 @@ public class Portal {
} }
ByteArrayDataOutput outForSend = ByteStreams.newDataOutput(); if (!plugin.isVelocitySupported() || !doKnockback) {
outForSend.writeUTF("Connect"); ByteArrayDataOutput outForSend = ByteStreams.newDataOutput();
outForSend.writeUTF(bungeeServer); 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()); portal.inPortal.add(player.getUniqueId());
player.sendPluginMessage(plugin, "BungeeCord", outForSend.toByteArray()); player.sendPluginMessage(plugin, BungeeMessages.CHANNEL_NAME, outForSend.toByteArray());
// Down to bungee to sort out the teleporting but yea theoretically they should }
// warp.
} else if (portal.getDestinations().length > 0) { } else if (portal.getDestinations().length > 0) {
ConfigAccessor configDesti = new ConfigAccessor(plugin, "destinations.yml"); ConfigAccessor configDesti = new ConfigAccessor(plugin, "destinations.yml");
String randomDest = portal.getDestinations()[random.nextInt(portal.getDestinations().length)]; String randomDest = portal.getDestinations()[random.nextInt(portal.getDestinations().length)];

View File

@ -17,6 +17,10 @@ public class BungeeMessages {
*/ */
public static String ENTER_PORTAL = "PortalEnter"; 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"; public static String CHANNEL_NAME = "advancedportals:warp";

View File

@ -10,12 +10,19 @@ import com.velocitypowered.api.event.connection.PluginMessageEvent;
import com.velocitypowered.api.event.player.ServerPostConnectEvent; import com.velocitypowered.api.event.player.ServerPostConnectEvent;
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import com.velocitypowered.api.plugin.Plugin; 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.ProxyServer;
import com.velocitypowered.api.proxy.ServerConnection; import com.velocitypowered.api.proxy.ServerConnection;
import com.velocitypowered.api.proxy.messages.LegacyChannelIdentifier; import com.velocitypowered.api.proxy.messages.LegacyChannelIdentifier;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import org.slf4j.Logger; import org.slf4j.Logger;
import java.util.HashMap; 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; import java.util.concurrent.TimeUnit;
/** /**
@ -51,6 +58,21 @@ public class AdvancedPortalsPlugin {
proxy.getChannelRegistrar().register(AP_CHANNEL); 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 @Subscribe
public void onPluginMessage(PluginMessageEvent event) { public void onPluginMessage(PluginMessageEvent event) {
if(event.getIdentifier().equals(AP_CHANNEL)) { if(event.getIdentifier().equals(AP_CHANNEL)) {
@ -77,6 +99,27 @@ public class AdvancedPortalsPlugin {
proxy.getCommandManager().executeAsync(connection.getPlayer(), command); proxy.getCommandManager().executeAsync(connection.getPlayer(), command);
} }
} else if (subChannel.equalsIgnoreCase(BungeeMessages.SEND_TO_SERVER_WITH_KNOCKBACK)) {
String targetServer = in.readUTF();
Optional<RegisteredServer> server = proxy.getServer(targetServer);
Player player = ((ServerConnection) event.getSource()).getPlayer();
if (!server.isPresent()) {
throwPlayerBack(player, "The server is invalid");
} else {
CompletableFuture<ConnectionRequestBuilder.Result> 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. // So that client packets don't make it through to the servers, always trigger on this channel.