Add more features to Smart Fallback

This commit is contained in:
ME1312 2020-07-03 17:14:59 -04:00
parent 928c40addc
commit d76d0347e5
No known key found for this signature in database
GPG Key ID: FEFFE2F698E88FA8
14 changed files with 174 additions and 36 deletions

View File

@ -30,14 +30,14 @@
<dependency>
<groupId>net.ME1312.Galaxi</groupId>
<artifactId>GalaxiUtil</artifactId>
<version>20w15a</version>
<version>20w27a</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>net.ME1312.Galaxi</groupId>
<artifactId>GalaxiEngine</artifactId>
<version>20w15a</version>
<version>20w27a</version>
<scope>provided</scope>
</dependency>
<dependency>

View File

@ -118,6 +118,16 @@ public class ConfigUpdater {
}
}
existing = updated.clone();
i++;
} if (was.compareTo(new Version("20w26a")) <= 0) {
if (existing.getMap("Settings", new YAMLSection()).contains("Smart-Fallback") && existing.getMap("Settings").isBoolean("Smart-Fallback")) {
YAMLSection smart_fallback = new YAMLSection();
smart_fallback.set("Enabled", existing.getMap("Settings").getBoolean("Smart-Fallback"));
smart_fallback.set("Fallback", existing.getMap("Settings").getBoolean("Smart-Fallback"));
updated.getMap("Settings").set("Smart-Fallback", smart_fallback);
}
existing = updated.clone();
i++;
}// if (was.compareTo(new Version("99w99a")) <= 0) {
@ -132,9 +142,15 @@ public class ConfigUpdater {
if (i > 0) {
YAMLSection settings = new YAMLSection();
settings.set("Version", ((now.compareTo(was) <= 0)?was:now).toString());
settings.set("Smart-Fallback", updated.getMap("Settings", new YAMLSection()).getBoolean("Smart-Fallback", true));
settings.set("Override-Bungee-Commands", updated.getMap("Settings", new YAMLSection()).getBoolean("Override-Bungee-Commands", true));
YAMLSection smart_fallback = new YAMLSection();
smart_fallback.set("Enabled", updated.getMap("Settings", new YAMLSection()).getMap("Smart-Fallback", new YAMLSection()).getBoolean("Enabled", true));
smart_fallback.set("Fallback", updated.getMap("Settings", new YAMLSection()).getMap("Smart-Fallback", new YAMLSection()).getBoolean("Fallback", true));
smart_fallback.set("Reconnect", updated.getMap("Settings", new YAMLSection()).getMap("Smart-Fallback", new YAMLSection()).getBoolean("Reconnect", false));
smart_fallback.set("DNS-Forward", updated.getMap("Settings", new YAMLSection()).getMap("Smart-Fallback", new YAMLSection()).getBoolean("DNS-Forward", false));
settings.set("Smart-Fallback", smart_fallback);
YAMLSection upnp = new YAMLSection();
upnp.set("Forward-Proxy", updated.getMap("Settings", new YAMLSection()).getMap("UPnP", new YAMLSection()).getBoolean("Forward-Proxy", true));
upnp.set("Forward-SubData", updated.getMap("Settings", new YAMLSection()).getMap("UPnP", new YAMLSection()).getBoolean("Forward-SubData", false));

View File

@ -1,9 +1,11 @@
package net.ME1312.SubServers.Bungee.Library.Fallback;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubServers.Bungee.Host.Server;
import net.ME1312.SubServers.Bungee.Host.SubServer;
import net.ME1312.SubServers.Bungee.SubAPI;
import net.ME1312.SubServers.Bungee.SubProxy;
import net.md_5.bungee.UserConnection;
import net.md_5.bungee.api.AbstractReconnectHandler;
import net.md_5.bungee.api.ProxyServer;
@ -22,12 +24,22 @@ import java.util.concurrent.CopyOnWriteArrayList;
*/
public class SmartFallback implements ReconnectHandler {
private static List<FallbackInspector> inspectors = new CopyOnWriteArrayList<FallbackInspector>();
private static ReconnectHandler reconnect;
public SmartFallback(SubProxy proxy) {
if (reconnect == null && proxy.config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>()).getBoolean("Reconnect", false))
reconnect = Util.getDespiteException(() -> Util.reflect(ProxyServer.getInstance().getPluginManager().getPlugin("reconnect_yaml").getClass().getClassLoader().loadClass("net.md_5.bungee.module.reconnect.yaml.YamlReconnectHandler").getConstructor()), null);
}
@Override
public ServerInfo getServer(ProxiedPlayer player) {
ServerInfo forced = getForcedHost(player.getPendingConnection());
if (forced != null) {
return forced;
ServerInfo override;
if ((override = getForcedHost(player.getPendingConnection())) != null) {
return override;
} else if ((override = getDNS(player.getPendingConnection())) != null) {
return override;
} else if ((override = getReconnectServer(player)) != null) {
return override;
} else {
Map<String, ServerInfo> fallbacks = getFallbackServers(player.getPendingConnection().getListener(), player);
if (fallbacks.isEmpty()) {
@ -59,6 +71,45 @@ public class SmartFallback implements ReconnectHandler {
}
}
/**
* Grabs the Server that a connection's DNS matches
*
* @param connection Connection to check
* @return DNS Forward Server
*/
public static ServerInfo getDNS(PendingConnection connection) {
if (connection.getVirtualHost() == null || !((SubProxy) ProxyServer.getInstance()).config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>()).getBoolean("DNS-Forward", false)) {
return null;
} else {
Map.Entry<String, ServerInfo> server = null;
String dns = connection.getVirtualHost().getHostString().toLowerCase();
for (Map.Entry<String, ServerInfo> s : ((SubProxy) ProxyServer.getInstance()).getServersCopy().entrySet()) {
if (dns.startsWith(s.getKey().toLowerCase() + '.'))
if (server == null || server.getKey().length() < s.getKey().length())
server = s;
}
return (server == null)?null:server.getValue();
}
}
/**
* Grabs the Server that a player was last connected to
*
* @param player Player
* @return Reconnect Server
*/
public static ServerInfo getReconnectServer(ProxiedPlayer player) {
if (reconnect == null) {
return null;
} else try {
return Util.reflect(reconnect.getClass().getDeclaredMethod("getStoredServer", ProxiedPlayer.class), reconnect, player);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
return null;
}
}
/**
* Generates a <i>smart</i> sorted map of fallback servers using a generated confidence score
*
@ -151,16 +202,16 @@ public class SmartFallback implements ReconnectHandler {
@Override
public void setServer(ProxiedPlayer player) {
// Ignore server switching
if (reconnect != null) reconnect.setServer(player);
}
@Override
public void save() {
// Nothing to save
if (reconnect != null) reconnect.save();
}
@Override
public void close() {
// Nothing to close
if (reconnect != null) reconnect.close();
}
}

View File

@ -74,7 +74,7 @@ public final class SubProxy extends BungeeCord implements Listener {
public SubProtocol subprotocol;
public SubDataServer subdata = null;
public SubServer sudo = null;
public static final Version version = Version.fromString("2.16a");
public static final Version version = Version.fromString("2.16.1a");
public Proxy redis = null;
public boolean canSudo = false;
@ -237,9 +237,8 @@ public final class SubProxy extends BungeeCord implements Listener {
}
}
if (config.get().getMap("Settings").getBoolean("Smart-Fallback", true)) {
setReconnectHandler(new SmartFallback());
}
if (config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>()).getBoolean("Enabled", true))
setReconnectHandler(new SmartFallback(this));
subprotocol = SubProtocol.get();
subprotocol.registerCipher("DHE", DHE.get(128));
@ -661,6 +660,9 @@ public final class SubProxy extends BungeeCord implements Listener {
getPluginManager().registerCommand(null, SubCommand.newInstance(this, "sub").get());
GalaxiCommand.group(SubCommand.class);
if (getReconnectHandler() != null && getReconnectHandler().getClass().equals(SmartFallback.class))
setReconnectHandler(new SmartFallback(this)); // Re-initialize Smart Fallback
new Metrics(this);
new Timer("SubServers.Bungee::Routine_Update_Check").schedule(new TimerTask() {
@SuppressWarnings("unchecked")
@ -695,7 +697,7 @@ public final class SubProxy extends BungeeCord implements Listener {
public void stopListeners() {
try {
legServers.clear();
legServers.putAll(getServers());
legServers.putAll(getServersCopy());
if (api.disableListeners.size() > 0) {
Logger.get("SubServers").info("Resetting SubAPI Plugins...");
for (Runnable listener : api.disableListeners) {
@ -860,7 +862,7 @@ public final class SubProxy extends BungeeCord implements Listener {
if (servers.keySet().contains(e.getTarget().getName().toLowerCase()) && e.getTarget() != servers.get(e.getTarget().getName().toLowerCase())) {
e.setTarget(servers.get(e.getTarget().getName().toLowerCase()));
} else {
servers = getServers();
servers = getServersCopy();
if (servers.keySet().contains(e.getTarget().getName()) && e.getTarget() != servers.get(e.getTarget().getName())) {
e.setTarget(servers.get(e.getTarget().getName()));
}
@ -897,7 +899,7 @@ public final class SubProxy extends BungeeCord implements Listener {
@SuppressWarnings("deprecation")
@EventHandler(priority = Byte.MAX_VALUE)
public void fallback(ServerKickEvent e) {
if (e.getPlayer() instanceof UserConnection && config.get().getMap("Settings").getBoolean("Smart-Fallback", true)) {
if (e.getPlayer() instanceof UserConnection && config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>()).getBoolean("Fallback", true)) {
Map<String, ServerInfo> fallbacks;
if (!fallbackLimbo.keySet().contains(e.getPlayer().getUniqueId())) {
fallbacks = SmartFallback.getFallbackServers(e.getPlayer().getPendingConnection().getListener(), e.getPlayer());

View File

@ -44,7 +44,7 @@
<dependency>
<groupId>net.ME1312.Galaxi</groupId>
<artifactId>GalaxiUtil</artifactId>
<version>20w15a</version>
<version>20w27a</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>

View File

@ -1,6 +1,6 @@
name: SubServers-Client-Bukkit
main: net.ME1312.SubServers.Client.Bukkit.SubPlugin
version: "2.16a"
version: "2.16.1a"
authors: ["ME1312"]
softdepend: [TitleManager]
website: "https://github.com/ME1312/SubServers-2"

View File

@ -30,7 +30,7 @@
<dependency>
<groupId>net.ME1312.Galaxi</groupId>
<artifactId>GalaxiUtil</artifactId>
<version>20w15a</version>
<version>20w27a</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>

View File

@ -46,7 +46,7 @@ import java.util.concurrent.TimeUnit;
/**
* SubServers Client Plugin Class
*/
@Plugin(id = "subservers-client-sponge", name = "SubServers-Client-Sponge", authors = "ME1312", version = "2.16a", url = "https://github.com/ME1312/SubServers-2", description = "Take control of the server manager — from your servers")
@Plugin(id = "subservers-client-sponge", name = "SubServers-Client-Sponge", authors = "ME1312", version = "2.16.1a", url = "https://github.com/ME1312/SubServers-2", description = "Take control of the server manager — from your servers")
public final class SubPlugin {
HashMap<Integer, SubDataClient> subdata = new HashMap<Integer, SubDataClient>();
NamedContainer<Long, Map<String, Map<String, String>>> lang = null;

View File

@ -20,7 +20,7 @@
<dependency>
<groupId>net.ME1312.Galaxi</groupId>
<artifactId>GalaxiEngine</artifactId>
<version>20w15a</version>
<version>20w27a</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>

View File

@ -42,7 +42,7 @@ import java.util.jar.Manifest;
/**
* SubServers.Host Main Class
*/
@App(name = "SubServers.Host", version = "2.16a", authors = "ME1312", website = "https://github.com/ME1312/SubServers-2", description = "Host subservers on separate machines")
@App(name = "SubServers.Host", version = "2.16.1a", authors = "ME1312", website = "https://github.com/ME1312/SubServers-2", description = "Host subservers on separate machines")
public final class ExHost {
HashMap<Integer, SubDataClient> subdata = new HashMap<Integer, SubDataClient>();
NamedContainer<Long, Map<String, Map<String, String>>> lang = null;

View File

@ -30,14 +30,14 @@
<dependency>
<groupId>net.ME1312.Galaxi</groupId>
<artifactId>GalaxiUtil</artifactId>
<version>20w15a</version>
<version>20w27a</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>net.ME1312.Galaxi</groupId>
<artifactId>GalaxiEngine</artifactId>
<version>20w15a</version>
<version>20w27a</version>
<scope>provided</scope>
</dependency>
<dependency>

View File

@ -59,7 +59,7 @@ public final class ExProxy extends BungeeCord implements Listener {
public boolean redis = false;
public final SubAPI api = new SubAPI(this);
public SubProtocol subprotocol;
public static final Version version = Version.fromString("2.16a");
public static final Version version = Version.fromString("2.16.1a");
public final boolean isPatched;
public final boolean isGalaxi;
@ -92,9 +92,8 @@ public final class ExProxy extends BungeeCord implements Listener {
ConfigUpdater.updateConfig(new UniversalFile(dir, "sync.yml"));
config = new YAMLConfig(new UniversalFile(dir, "sync.yml"));
if (config.get().getMap("Settings").getBoolean("Smart-Fallback", true)) {
setReconnectHandler(new SmartFallback());
}
if (config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>()).getBoolean("Enabled", true))
setReconnectHandler(new SmartFallback(this));
subprotocol = SubProtocol.get();
subprotocol.registerCipher("DHE", DHE.get(128));
@ -203,6 +202,9 @@ public final class ExProxy extends BungeeCord implements Listener {
getPluginManager().registerCommand(null, SubCommand.newInstance(this, "sub").get());
GalaxiCommand.group(SubCommand.class);
if (getReconnectHandler() != null && getReconnectHandler().getClass().equals(SmartFallback.class))
setReconnectHandler(new SmartFallback(this)); // Re-initialize Smart Fallback
new Metrics(this);
new Timer("SubServers.Sync::Routine_Update_Check").schedule(new TimerTask() {
@SuppressWarnings("unchecked")
@ -394,7 +396,7 @@ public final class ExProxy extends BungeeCord implements Listener {
@SuppressWarnings("deprecation")
@EventHandler(priority = Byte.MAX_VALUE)
public void fallback(ServerKickEvent e) {
if (e.getPlayer() instanceof UserConnection && config.get().getMap("Settings").getBoolean("Smart-Fallback", true)) {
if (e.getPlayer() instanceof UserConnection && config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>()).getBoolean("Fallback", true)) {
Map<String, ServerInfo> fallbacks;
if (!fallbackLimbo.keySet().contains(e.getPlayer().getUniqueId())) {
fallbacks = SmartFallback.getFallbackServers(e.getPlayer().getPendingConnection().getListener(), e.getPlayer());

View File

@ -41,6 +41,16 @@ public class ConfigUpdater {
} else {
if (was.compareTo(new Version("19w17a")) <= 0) {
i++;
} if (was.compareTo(new Version("20w26a")) <= 0) {
if (existing.getMap("Settings", new YAMLSection()).contains("Smart-Fallback") && existing.getMap("Settings").isBoolean("Smart-Fallback")) {
YAMLSection smart_fallback = new YAMLSection();
smart_fallback.set("Enabled", existing.getMap("Settings").getBoolean("Smart-Fallback"));
smart_fallback.set("Fallback", existing.getMap("Settings").getBoolean("Smart-Fallback"));
updated.getMap("Settings").set("Smart-Fallback", smart_fallback);
}
existing = updated.clone();
i++;
}// if (was.compareTo(new Version("99w99a")) <= 0) {
// // do something
@ -53,9 +63,15 @@ public class ConfigUpdater {
if (i > 0) {
YAMLSection settings = new YAMLSection();
settings.set("Version", ((now.compareTo(was) <= 0)?was:now).toString());
settings.set("Smart-Fallback", updated.getMap("Settings", new YAMLSection()).getBoolean("Smart-Fallback", true));
settings.set("Override-Bungee-Commands", updated.getMap("Settings", new YAMLSection()).getBoolean("Override-Bungee-Commands", true));
YAMLSection smart_fallback = new YAMLSection();
smart_fallback.set("Enabled", updated.getMap("Settings", new YAMLSection()).getMap("Smart-Fallback", new YAMLSection()).getBoolean("Enabled", true));
smart_fallback.set("Fallback", updated.getMap("Settings", new YAMLSection()).getMap("Smart-Fallback", new YAMLSection()).getBoolean("Fallback", true));
smart_fallback.set("Reconnect", updated.getMap("Settings", new YAMLSection()).getMap("Smart-Fallback", new YAMLSection()).getBoolean("Reconnect", false));
smart_fallback.set("DNS-Forward", updated.getMap("Settings", new YAMLSection()).getMap("Smart-Fallback", new YAMLSection()).getBoolean("DNS-Forward", false));
settings.set("Smart-Fallback", smart_fallback);
YAMLSection upnp = new YAMLSection();
upnp.set("Forward-Proxy", updated.getMap("Settings", new YAMLSection()).getMap("UPnP", new YAMLSection()).getBoolean("Forward-Proxy", true));
settings.set("UPnP", upnp);

View File

@ -1,6 +1,8 @@
package net.ME1312.SubServers.Sync.Library.Fallback;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubServers.Sync.ExProxy;
import net.ME1312.SubServers.Sync.Server.ServerImpl;
import net.ME1312.SubServers.Sync.Server.SubServerImpl;
import net.ME1312.SubServers.Sync.SubAPI;
@ -22,12 +24,22 @@ import java.util.concurrent.CopyOnWriteArrayList;
*/
public class SmartFallback implements ReconnectHandler {
private static List<FallbackInspector> inspectors = new CopyOnWriteArrayList<FallbackInspector>();
private static ReconnectHandler reconnect;
public SmartFallback(ExProxy proxy) {
if (reconnect == null && proxy.config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>()).getBoolean("Reconnect", false))
reconnect = Util.getDespiteException(() -> Util.reflect(ProxyServer.getInstance().getPluginManager().getPlugin("reconnect_yaml").getClass().getClassLoader().loadClass("net.md_5.bungee.module.reconnect.yaml.YamlReconnectHandler").getConstructor()), null);
}
@Override
public ServerInfo getServer(ProxiedPlayer player) {
ServerInfo forced = getForcedHost(player.getPendingConnection());
if (forced != null) {
return forced;
ServerInfo override;
if ((override = getForcedHost(player.getPendingConnection())) != null) {
return override;
} else if ((override = getDNS(player.getPendingConnection())) != null) {
return override;
} else if ((override = getReconnectServer(player)) != null) {
return override;
} else {
Map<String, ServerInfo> fallbacks = getFallbackServers(player.getPendingConnection().getListener(), player);
if (fallbacks.isEmpty()) {
@ -59,6 +71,45 @@ public class SmartFallback implements ReconnectHandler {
}
}
/**
* Grabs the Server that a connection's DNS matches
*
* @param connection Connection to check
* @return DNS Forward Server
*/
public static ServerInfo getDNS(PendingConnection connection) {
if (connection.getVirtualHost() == null || !((ExProxy) ProxyServer.getInstance()).config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>()).getBoolean("DNS-Forward", false)) {
return null;
} else {
Map.Entry<String, ServerInfo> server = null;
String dns = connection.getVirtualHost().getHostString().toLowerCase();
for (Map.Entry<String, ServerInfo> s : ((ExProxy) ProxyServer.getInstance()).getServersCopy().entrySet()) {
if (dns.startsWith(s.getKey().toLowerCase() + '.'))
if (server == null || server.getKey().length() < s.getKey().length())
server = s;
}
return (server == null)?null:server.getValue();
}
}
/**
* Grabs the Server that a player was last connected to
*
* @param player Player
* @return Reconnect Server
*/
public static ServerInfo getReconnectServer(ProxiedPlayer player) {
if (reconnect == null) {
return null;
} else try {
return Util.reflect(reconnect.getClass().getDeclaredMethod("getStoredServer", ProxiedPlayer.class), reconnect, player);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
return null;
}
}
/**
* Generates a <i>smart</i> sorted map of fallback servers using a generated confidence score
*
@ -152,16 +203,16 @@ public class SmartFallback implements ReconnectHandler {
@Override
public void setServer(ProxiedPlayer player) {
// Ignore server switching
if (reconnect != null) reconnect.setServer(player);
}
@Override
public void save() {
// Nothing to save
if (reconnect != null) reconnect.save();
}
@Override
public void close() {
// Nothing to close
if (reconnect != null) reconnect.close();
}
}