Rework the SmartFallback API

There were a couple things in Smart Fallback that seemed short-sighted when it came to use by external plugins. Now you can:
-> Make decisions using player data (when available)
-> Assign partial points to a confidence score
This commit is contained in:
ME1312 2020-06-21 17:42:10 -04:00
parent 89856a19b8
commit d8ea0cee66
No known key found for this signature in database
GPG Key ID: FEFFE2F698E88FA8
6 changed files with 58 additions and 26 deletions

View File

@ -1,6 +1,7 @@
package net.ME1312.SubServers.Bungee.Library.Fallback;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
/**
* Fallback Server Inspector Layout Class
@ -8,10 +9,11 @@ import net.md_5.bungee.api.config.ServerInfo;
public interface FallbackInspector {
/**
* Inspect a fallback server and modify it's confidence score
* Inspect a fallback server and modify its confidence score
*
* @param player Player that requested (may be null)
* @param server Server to inspect
* @return A Positive Value to add points, a Negative Value to subtract points, a Null Value to invalidate the server, or a Zero Value to do nothing
*/
Integer inspect(ServerInfo server);
Double inspect(ProxiedPlayer player, ServerInfo server);
}

View File

@ -16,12 +16,11 @@ import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.LinkedBlockingQueue;
/**
* Smart Reconnect Handler Class
* Smart Fallback Handler Class
*/
public class SmartReconnectHandler implements ReconnectHandler {
public class SmartFallback implements ReconnectHandler {
private static List<FallbackInspector> inspectors = new CopyOnWriteArrayList<FallbackInspector>();
@Override
@ -30,7 +29,7 @@ public class SmartReconnectHandler implements ReconnectHandler {
if (forced != null) {
return forced;
} else {
Map<String, ServerInfo> fallbacks = getFallbackServers(player.getPendingConnection().getListener());
Map<String, ServerInfo> fallbacks = getFallbackServers(player.getPendingConnection().getListener(), player);
if (fallbacks.isEmpty()) {
return null;
} else {
@ -67,25 +66,40 @@ public class SmartReconnectHandler implements ReconnectHandler {
* @return Fallback Server Map (with legacy bungee case-sensitive keys)
*/
public static Map<String, ServerInfo> getFallbackServers(ListenerInfo listener) {
TreeMap<Integer, List<ServerInfo>> score = new TreeMap<Integer, List<ServerInfo>>(Collections.reverseOrder());
return getFallbackServers(listener, null);
}
/**
* Generates a <i>smart</i> sorted map of fallback servers using a generated confidence score
*
* @param listener Listener to grab fallback servers from
* @param player Player that is requesting fallback servers
* @return Fallback Server Map (with legacy bungee case-sensitive keys)
*/
public static Map<String, ServerInfo> getFallbackServers(ListenerInfo listener, ProxiedPlayer player) {
TreeMap<Double, List<ServerInfo>> score = new TreeMap<Double, List<ServerInfo>>(Collections.reverseOrder());
for (String name : listener.getServerPriority()) {
ServerInfo server = SubAPI.getInstance().getServer(name.toLowerCase());
if (server == null) server = ProxyServer.getInstance().getServerInfo(name);
if (server != null) {
boolean valid = true;
int confidence = 0;
double confidence = 0;
if (server instanceof Server) {
if (!((Server) server).isHidden()) confidence++;
if (!((Server) server).isRestricted()) confidence++;
if (((Server) server).getSubData()[0] != null) confidence++;
if (player != null) {
if (((Server) server).canAccess(player)) confidence++;
}
} if (server instanceof SubServer) {
if (!((SubServer) server).isRunning()) valid = false;
}
List<FallbackInspector> inspectors = new ArrayList<FallbackInspector>();
inspectors.addAll(SmartReconnectHandler.inspectors);
inspectors.addAll(SmartFallback.inspectors);
for (FallbackInspector inspector : inspectors) try {
Integer response = inspector.inspect(server);
Double response = inspector.inspect(player, server);
if (response == null) {
valid = false;
} else {

View File

@ -20,7 +20,7 @@ import net.ME1312.Galaxi.Library.Config.YAMLSection;
import net.ME1312.SubServers.Bungee.Library.Compatibility.Galaxi.GalaxiCommand;
import net.ME1312.SubServers.Bungee.Library.Compatibility.LegacyServerMap;
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
import net.ME1312.SubServers.Bungee.Library.Fallback.SmartReconnectHandler;
import net.ME1312.SubServers.Bungee.Library.Fallback.SmartFallback;
import net.ME1312.SubServers.Bungee.Library.ConfigUpdater;
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidHostException;
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
@ -28,7 +28,6 @@ import net.ME1312.Galaxi.Library.Version.Version;
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExReload;
import net.ME1312.SubServers.Bungee.Network.SubProtocol;
import net.md_5.bungee.BungeeCord;
import net.md_5.bungee.BungeeServerInfo;
import net.md_5.bungee.UserConnection;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.ServerPing;
@ -654,7 +653,7 @@ public final class SubProxy extends BungeeCord implements Listener {
getPluginManager().registerCommand(null, new SubCommand.BungeeList(this, "glist"));
}
if (config.get().getMap("Settings").getBoolean("Smart-Fallback", true)) {
setReconnectHandler(new SmartReconnectHandler());
setReconnectHandler(new SmartFallback());
}
getPluginManager().registerCommand(null, SubCommand.newInstance(this, "subservers").get());
getPluginManager().registerCommand(null, SubCommand.newInstance(this, "subserver").get());
@ -900,7 +899,7 @@ public final class SubProxy extends BungeeCord implements Listener {
if (e.getPlayer() instanceof UserConnection && config.get().getMap("Settings").getBoolean("Smart-Fallback", true)) {
Map<String, ServerInfo> fallbacks;
if (!fallbackLimbo.keySet().contains(e.getPlayer().getUniqueId())) {
fallbacks = SmartReconnectHandler.getFallbackServers(e.getPlayer().getPendingConnection().getListener());
fallbacks = SmartFallback.getFallbackServers(e.getPlayer().getPendingConnection().getListener(), e.getPlayer());
} else {
fallbacks = new LinkedHashMap<String, ServerInfo>();
for (ServerInfo server : fallbackLimbo.get(e.getPlayer().getUniqueId())) fallbacks.put(server.getName(), server);

View File

@ -13,7 +13,7 @@ import net.ME1312.Galaxi.Library.Config.YAMLConfig;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.SubServers.Sync.Library.Compatibility.Galaxi.GalaxiCommand;
import net.ME1312.SubServers.Sync.Library.Compatibility.Logger;
import net.ME1312.SubServers.Sync.Library.Fallback.SmartReconnectHandler;
import net.ME1312.SubServers.Sync.Library.Fallback.SmartFallback;
import net.ME1312.SubServers.Sync.Library.Metrics;
import net.ME1312.Galaxi.Library.Container.NamedContainer;
import net.ME1312.Galaxi.Library.UniversalFile;
@ -393,7 +393,7 @@ public final class ExProxy extends BungeeCord implements Listener {
if (e.getPlayer() instanceof UserConnection && config.get().getMap("Settings").getBoolean("Smart-Fallback", true)) {
Map<String, ServerInfo> fallbacks;
if (!fallbackLimbo.keySet().contains(e.getPlayer().getUniqueId())) {
fallbacks = SmartReconnectHandler.getFallbackServers(e.getPlayer().getPendingConnection().getListener());
fallbacks = SmartFallback.getFallbackServers(e.getPlayer().getPendingConnection().getListener(), e.getPlayer());
} else {
fallbacks = new LinkedHashMap<String, ServerInfo>();
for (ServerInfo server : fallbackLimbo.get(e.getPlayer().getUniqueId())) fallbacks.put(server.getName(), server);

View File

@ -1,6 +1,7 @@
package net.ME1312.SubServers.Sync.Library.Fallback;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
/**
* Fallback Server Inspector Layout Class
@ -8,10 +9,11 @@ import net.md_5.bungee.api.config.ServerInfo;
public interface FallbackInspector {
/**
* Inspect a fallback server and modify it's confidence score
* Inspect a fallback server and modify its confidence score
*
* @param player Player that requested (may be null)
* @param server Server to inspect
* @return A Positive Value to add points, a Negative Value to subtract points, a Null Value to invalidate the server, or a Zero Value to do nothing
*/
Integer inspect(ServerInfo server);
Double inspect(ProxiedPlayer player, ServerInfo server);
}

View File

@ -18,9 +18,9 @@ import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* Smart Reconnect Handler Class
* Smart Fallback Handler Class
*/
public class SmartReconnectHandler implements ReconnectHandler {
public class SmartFallback implements ReconnectHandler {
private static List<FallbackInspector> inspectors = new CopyOnWriteArrayList<FallbackInspector>();
@Override
@ -29,7 +29,7 @@ public class SmartReconnectHandler implements ReconnectHandler {
if (forced != null) {
return forced;
} else {
Map<String, ServerInfo> fallbacks = getFallbackServers(player.getPendingConnection().getListener());
Map<String, ServerInfo> fallbacks = getFallbackServers(player.getPendingConnection().getListener(), player);
if (fallbacks.isEmpty()) {
return null;
} else {
@ -65,27 +65,42 @@ public class SmartReconnectHandler implements ReconnectHandler {
* @param listener Listener to grab fallback servers from
* @return Fallback Server Map (with legacy bungee case-sensitive keys)
*/
@SuppressWarnings("deprecation")
public static Map<String, ServerInfo> getFallbackServers(ListenerInfo listener) {
TreeMap<Integer, List<ServerInfo>> score = new TreeMap<Integer, List<ServerInfo>>(Collections.reverseOrder());
return getFallbackServers(listener, null);
}
/**
* Generates a <i>smart</i> sorted map of fallback servers using a generated confidence score
*
* @param listener Listener to grab fallback servers from
* @param player Player that is requesting fallback servers
* @return Fallback Server Map (with legacy bungee case-sensitive keys)
*/
@SuppressWarnings("deprecation")
public static Map<String, ServerInfo> getFallbackServers(ListenerInfo listener, ProxiedPlayer player) {
TreeMap<Double, List<ServerInfo>> score = new TreeMap<Double, List<ServerInfo>>(Collections.reverseOrder());
for (String name : listener.getServerPriority()) {
ServerInfo server = SubAPI.getInstance().getInternals().servers.getOrDefault(name.toLowerCase(), null);
if (server == null) server = ProxyServer.getInstance().getServerInfo(name);
if (server != null) {
boolean valid = true;
int confidence = 0;
double confidence = 0;
if (server instanceof ServerImpl) {
if (!((ServerImpl) server).isHidden()) confidence++;
if (!((ServerImpl) server).isRestricted()) confidence++;
if (((ServerImpl) server).getSubData()[0] != null) confidence++;
if (player != null) {
if (((ServerImpl) server).canAccess(player)) confidence++;
}
} if (server instanceof SubServerImpl) {
if (!((SubServerImpl) server).isRunning()) valid = false;
}
List<FallbackInspector> inspectors = new ArrayList<FallbackInspector>();
inspectors.addAll(SmartReconnectHandler.inspectors);
inspectors.addAll(SmartFallback.inspectors);
for (FallbackInspector inspector : inspectors) try {
Integer response = inspector.inspect(server);
Double response = inspector.inspect(player, server);
if (response == null) {
valid = false;
} else {