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 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) {

View File

@ -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);
}
}
}

View File

@ -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)];

View File

@ -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";

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.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<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.