Skip to content

Commit

Permalink
Use waterfall enhanced add/remove server info when available, Closes G…
Browse files Browse the repository at this point in the history
  • Loading branch information
derklaro committed May 28, 2021
1 parent 148cbb8 commit a3c447e
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ public HostAndPort(InetSocketAddress socketAddress) {
this.port = socketAddress.getPort();
}

public HostAndPort(String host, int port) {
this.host = host.trim();
this.port = port;
}

public HostAndPort() {
}

/**
* Tries to cast the provided socketAddress to an InetSocketAddress and returns a new HostAndPort based on it
*
Expand All @@ -64,14 +72,6 @@ public static HostAndPort fromSocketAddress(SocketAddress socketAddress) {
throw new IllegalArgumentException("socketAddress must be instance of InetSocketAddress!");
}

public HostAndPort(String host, int port) {
this.host = host.trim();
this.port = port;
}

public HostAndPort() {
}

@Override
public String toString() {
return this.host + ":" + this.port;
Expand All @@ -85,6 +85,10 @@ public int getPort() {
return this.port;
}

public InetSocketAddress toInetSocketAddress() {
return new InetSocketAddress(this.host, this.port);
}

@Override
public void write(@NotNull ProtocolBuffer buffer) {
buffer.writeOptionalString(this.host);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.plugin.Plugin;

import java.net.InetSocketAddress;
import java.util.Collection;
import java.util.concurrent.TimeUnit;

Expand Down Expand Up @@ -63,11 +62,7 @@ private void initServers() {
}

String name = serviceInfoSnapshot.getServiceId().getName();

super.getProxy().getServers().put(name, BungeeCloudNetHelper.createServerInfo(name, new InetSocketAddress(
serviceInfoSnapshot.getConnectAddress().getHost(),
serviceInfoSnapshot.getConnectAddress().getPort()
)));
BungeeServerRegisterHelper.registerService(name, serviceInfoSnapshot.getConnectAddress().toInetSocketAddress());

BridgeProxyHelper.cacheServiceInfoSnapshot(serviceInfoSnapshot);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package de.dytanic.cloudnet.ext.bridge.bungee;

import com.google.common.base.Preconditions;
import de.dytanic.cloudnet.common.logging.LogLevel;
import de.dytanic.cloudnet.driver.network.HostAndPort;
import de.dytanic.cloudnet.driver.service.ServiceEnvironmentType;
import de.dytanic.cloudnet.driver.service.ServiceInfoSnapshot;
Expand All @@ -16,24 +15,20 @@
import net.md_5.bungee.api.connection.PendingConnection;
import net.md_5.bungee.api.connection.ProxiedPlayer;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

public final class BungeeCloudNetHelper {

private static int lastOnlineCount = -1;

/**
* @deprecated use {@link BridgeProxyHelper#getCachedServiceInfoSnapshot(String)} or {@link BridgeProxyHelper#cacheServiceInfoSnapshot(ServiceInfoSnapshot)}
*/
@Deprecated
public static final Map<String, ServiceInfoSnapshot> SERVER_TO_SERVICE_INFO_SNAPSHOT_ASSOCIATION = BridgeProxyHelper.SERVICE_CACHE;
private static int lastOnlineCount = -1;

private BungeeCloudNetHelper() {
throw new UnsupportedOperationException();
Expand Down Expand Up @@ -162,24 +157,11 @@ public static NetworkConnectionInfo createNetworkConnectionInfo(PendingConnectio
);
}

/**
* @deprecated moved to {@link BungeeServerRegisterHelper}
*/
@Deprecated
public static ServerInfo createServerInfo(String name, InetSocketAddress address) {
Preconditions.checkNotNull(name);
Preconditions.checkNotNull(address);

// with rakNet enabled to support bedrock servers on Waterdog
if (Wrapper.getInstance().getCurrentServiceInfoSnapshot().getServiceId().getEnvironment() == ServiceEnvironmentType.WATERDOG) {
try {
Class<ProxyServer> proxyServerClass = ProxyServer.class;

Method method = proxyServerClass.getMethod("constructServerInfo",
String.class, SocketAddress.class, String.class, boolean.class, boolean.class, String.class);
method.setAccessible(true);
return (ServerInfo) method.invoke(ProxyServer.getInstance(), name, address, "CloudNet provided serverInfo", false, true, "default");
} catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException exception) {
Wrapper.getInstance().getLogger().log(LogLevel.ERROR, "Unable to enable rakNet, although using Waterdog: ", exception);
}
}

return ProxyServer.getInstance().constructServerInfo(name, address, "CloudNet provided serverInfo", false);
return BungeeServerRegisterHelper.constructServerInfo(name, address);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package de.dytanic.cloudnet.ext.bridge.bungee;

import net.md_5.bungee.api.ProxyConfig;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.config.ServerInfo;
import org.jetbrains.annotations.NotNull;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.net.InetSocketAddress;
import java.net.SocketAddress;

public final class BungeeServerRegisterHelper {

private static final MethodHandle WATERFALL_ADD_SERVER;
private static final MethodHandle WATERFALL_REMOVE_SERVER;
// WaterDog needs a specific constructServerInfo method to enable raknet
private static final MethodHandle WATER_DOG_CREATE_SERVER_INFO;

static {
// check if waterfall enhanced add/remove methods are available
MethodHandle addServer = null;
MethodHandle removeServer = null;
try {
addServer = MethodHandles.publicLookup().findVirtual(ProxyConfig.class, "addServer",
MethodType.methodType(ServerInfo.class, ServerInfo.class));
removeServer = MethodHandles.publicLookup().findVirtual(ProxyConfig.class, "removeServerNamed",
MethodType.methodType(ServerInfo.class, String.class));
} catch (NoSuchMethodException | IllegalAccessException ignored) {
// waterfall support is not available
}
// check if waterdog support is needed
MethodHandle waterDogConstructServerInfo = null;
try {
waterDogConstructServerInfo = MethodHandles.publicLookup().findVirtual(ProxyServer.class,
"constructServerInfo",
MethodType.methodType(ServerInfo.class, String.class, SocketAddress.class,
String.class, boolean.class, boolean.class, String.class));
} catch (NoSuchMethodException | IllegalAccessException ignored) {
// not on water dog
}
// assign to class final members
WATERFALL_ADD_SERVER = addServer;
WATERFALL_REMOVE_SERVER = removeServer;
WATER_DOG_CREATE_SERVER_INFO = waterDogConstructServerInfo;
}

private BungeeServerRegisterHelper() {
throw new UnsupportedOperationException();
}

public static @NotNull ServerInfo constructServerInfo(@NotNull String name, @NotNull InetSocketAddress address) {
if (WATER_DOG_CREATE_SERVER_INFO != null) {
try {
return (ServerInfo) WATER_DOG_CREATE_SERVER_INFO.invoke(ProxyServer.getInstance(),
name, address, "CloudNet provided serverInfo", false, true, "default");
} catch (Throwable throwable) {
throw new IllegalStateException("Waterdog method present but unable to create server info", throwable);
}
} else {
return ProxyServer.getInstance().constructServerInfo(name, address, "CloudNet provided serverInfo", false);
}
}

public static void registerService(@NotNull String name, @NotNull InetSocketAddress address) {
registerService(constructServerInfo(name, address));
}

public static void registerService(@NotNull ServerInfo serverInfo) {
if (WATERFALL_ADD_SERVER != null) {
try {
WATERFALL_ADD_SERVER.invoke(ProxyServer.getInstance().getConfig(), serverInfo);
} catch (Throwable throwable) {
throw new IllegalStateException("WaterFall add server method present but unable to add server", throwable);
}
} else {
ProxyServer.getInstance().getServers().put(serverInfo.getName(), serverInfo);
}
}

public static void unregisterService(@NotNull String name) {
if (WATERFALL_REMOVE_SERVER != null) {
try {
WATERFALL_REMOVE_SERVER.invoke(ProxyServer.getInstance().getConfig(), name);
} catch (Throwable throwable) {
throw new IllegalStateException("WaterFall remove server method present but unable to add server", throwable);
}
} else {
ProxyServer.getInstance().getServers().remove(name);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,48 @@
import de.dytanic.cloudnet.driver.event.EventListener;
import de.dytanic.cloudnet.driver.event.events.channel.ChannelMessageReceiveEvent;
import de.dytanic.cloudnet.driver.event.events.network.NetworkChannelPacketReceiveEvent;
import de.dytanic.cloudnet.driver.event.events.service.*;
import de.dytanic.cloudnet.driver.event.events.service.CloudServiceConnectNetworkEvent;
import de.dytanic.cloudnet.driver.event.events.service.CloudServiceDisconnectNetworkEvent;
import de.dytanic.cloudnet.driver.event.events.service.CloudServiceInfoUpdateEvent;
import de.dytanic.cloudnet.driver.event.events.service.CloudServiceRegisterEvent;
import de.dytanic.cloudnet.driver.event.events.service.CloudServiceStartEvent;
import de.dytanic.cloudnet.driver.event.events.service.CloudServiceStopEvent;
import de.dytanic.cloudnet.driver.event.events.service.CloudServiceUnregisterEvent;
import de.dytanic.cloudnet.ext.bridge.bungee.BungeeCloudNetHelper;
import de.dytanic.cloudnet.ext.bridge.bungee.event.*;
import de.dytanic.cloudnet.ext.bridge.event.*;
import de.dytanic.cloudnet.ext.bridge.bungee.BungeeServerRegisterHelper;
import de.dytanic.cloudnet.ext.bridge.bungee.event.BungeeBridgeConfigurationUpdateEvent;
import de.dytanic.cloudnet.ext.bridge.bungee.event.BungeeBridgeProxyPlayerDisconnectEvent;
import de.dytanic.cloudnet.ext.bridge.bungee.event.BungeeBridgeProxyPlayerLoginRequestEvent;
import de.dytanic.cloudnet.ext.bridge.bungee.event.BungeeBridgeProxyPlayerLoginSuccessEvent;
import de.dytanic.cloudnet.ext.bridge.bungee.event.BungeeBridgeProxyPlayerServerConnectRequestEvent;
import de.dytanic.cloudnet.ext.bridge.bungee.event.BungeeBridgeProxyPlayerServerSwitchEvent;
import de.dytanic.cloudnet.ext.bridge.bungee.event.BungeeBridgeServerPlayerDisconnectEvent;
import de.dytanic.cloudnet.ext.bridge.bungee.event.BungeeBridgeServerPlayerLoginRequestEvent;
import de.dytanic.cloudnet.ext.bridge.bungee.event.BungeeBridgeServerPlayerLoginSuccessEvent;
import de.dytanic.cloudnet.ext.bridge.bungee.event.BungeeChannelMessageReceiveEvent;
import de.dytanic.cloudnet.ext.bridge.bungee.event.BungeeCloudServiceConnectNetworkEvent;
import de.dytanic.cloudnet.ext.bridge.bungee.event.BungeeCloudServiceDisconnectNetworkEvent;
import de.dytanic.cloudnet.ext.bridge.bungee.event.BungeeCloudServiceInfoUpdateEvent;
import de.dytanic.cloudnet.ext.bridge.bungee.event.BungeeCloudServiceRegisterEvent;
import de.dytanic.cloudnet.ext.bridge.bungee.event.BungeeCloudServiceStartEvent;
import de.dytanic.cloudnet.ext.bridge.bungee.event.BungeeCloudServiceStopEvent;
import de.dytanic.cloudnet.ext.bridge.bungee.event.BungeeCloudServiceUnregisterEvent;
import de.dytanic.cloudnet.ext.bridge.bungee.event.BungeeNetworkChannelPacketReceiveEvent;
import de.dytanic.cloudnet.ext.bridge.bungee.event.BungeeServiceInfoSnapshotConfigureEvent;
import de.dytanic.cloudnet.ext.bridge.event.BridgeConfigurationUpdateEvent;
import de.dytanic.cloudnet.ext.bridge.event.BridgeProxyPlayerDisconnectEvent;
import de.dytanic.cloudnet.ext.bridge.event.BridgeProxyPlayerLoginRequestEvent;
import de.dytanic.cloudnet.ext.bridge.event.BridgeProxyPlayerLoginSuccessEvent;
import de.dytanic.cloudnet.ext.bridge.event.BridgeProxyPlayerServerConnectRequestEvent;
import de.dytanic.cloudnet.ext.bridge.event.BridgeProxyPlayerServerSwitchEvent;
import de.dytanic.cloudnet.ext.bridge.event.BridgeServerPlayerDisconnectEvent;
import de.dytanic.cloudnet.ext.bridge.event.BridgeServerPlayerLoginRequestEvent;
import de.dytanic.cloudnet.ext.bridge.event.BridgeServerPlayerLoginSuccessEvent;
import de.dytanic.cloudnet.ext.bridge.proxy.BridgeProxyHelper;
import de.dytanic.cloudnet.wrapper.event.service.ServiceInfoSnapshotConfigureEvent;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.plugin.Event;

import java.net.InetSocketAddress;

public final class BungeeCloudNetListener {

@EventListener
Expand All @@ -30,11 +61,7 @@ public void handle(CloudServiceStartEvent event) {
}

String name = event.getServiceInfo().getServiceId().getName();

ProxyServer.getInstance().getServers().put(name, BungeeCloudNetHelper.createServerInfo(name, new InetSocketAddress(
event.getServiceInfo().getConnectAddress().getHost(),
event.getServiceInfo().getConnectAddress().getPort()
)));
BungeeServerRegisterHelper.registerService(name, event.getServiceInfo().getConnectAddress().toInetSocketAddress());
}

this.bungeeCall(new BungeeCloudServiceStartEvent(event.getServiceInfo()));
Expand All @@ -43,7 +70,7 @@ public void handle(CloudServiceStartEvent event) {
@EventListener
public void handle(CloudServiceStopEvent event) {
if (BungeeCloudNetHelper.isServiceEnvironmentTypeProvidedForBungeeCord(event.getServiceInfo())) {
ProxyServer.getInstance().getServers().remove(event.getServiceInfo().getName());
BungeeServerRegisterHelper.unregisterService(event.getServiceInfo().getName());
BridgeProxyHelper.cacheServiceInfoSnapshot(event.getServiceInfo());
}

Expand Down

0 comments on commit a3c447e

Please sign in to comment.