BungeeCommon API

This commit is contained in:
ME1312 2020-11-13 22:41:56 -05:00
parent 96a3cf797e
commit 34b406e3ae
No known key found for this signature in database
GPG Key ID: FEFFE2F698E88FA8
42 changed files with 441 additions and 794 deletions

View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.ME1312.SubServers</groupId>
<artifactId>SubServers.Bungee.Common</artifactId>
<version>-PLACEHOLDER</version>
<packaging>jar</packaging>
<repositories>
<repository>
<id>md_5-repo</id>
<url>http://repo.md-5.net/content/repositories/snapshots/</url>
</repository>
<repository>
<id>me1312-repo</id>
<url>https://dev.me1312.net/maven</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>net.md_5</groupId>
<artifactId>bungeecord-internal</artifactId>
<version>1.15-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.ME1312.Galaxi</groupId>
<artifactId>GalaxiUtil</artifactId>
<version>20w33a</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.ME1312.Galaxi</groupId>
<artifactId>GalaxiEngine</artifactId>
<version>20w33a</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<directory>../../out/compile/target/SubServers.Bungee.Common</directory>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,126 @@
package net.ME1312.SubServers.Bungee;
import net.ME1312.Galaxi.Library.UniversalFile;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.Galaxi.Library.Version.Version;
import net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer;
import net.md_5.bungee.api.ProxyServer;
import java.util.*;
/**
* SubAPI BungeeCord Common Class
*/
public interface BungeeAPI {
/**
* Gets the SubAPI BungeeCord Common Methods
*
* @return SubAPI BungeeCord Common
*/
static BungeeAPI getInstance() {
return ((BungeeCommon) ProxyServer.getInstance()).api.run();
}
/**
* Adds a SubAPI Listener
*
* @param enable An Event that will be called when SubAPI is ready
* @param disable An Event that will be called before SubAPI is disabled (your plugin should reset it's values in case this is a hard-reset instead of a shutdown)
*/
void addListener(Runnable enable, Runnable disable);
/**
* Get the number of players on this network across all known proxies
*
* @return Remote Player Collection
*/
default int getRemotePlayerCount() {
return getGlobalPlayers().size();
}
/**
* Get players on this network across all known proxies
*
* @return Remote Player Collection
*/
Map<UUID, ? extends RemotePlayer> getGlobalPlayers();
/**
* Get a player on this network by searching across all known proxies
*
* @param name Player name
* @return Remote Player
*/
RemotePlayer getGlobalPlayer(String name);
/**
* Get a player on this network by searching across all known proxies
*
* @param id Player UUID
* @return Remote Player
*/
RemotePlayer getGlobalPlayer(UUID id);
/**
* Gets the current SubServers Lang Channels
*
* @return SubServers Lang Channel list
*/
Collection<String> getLangChannels();
/**
* Gets values from the SubServers Lang
*
* @param channel Lang Channel
* @return Lang Value
*/
Map<String, String> getLang(String channel);
/**
* Gets a value from the SubServers Lang
*
* @param channel Lang Channel
* @param key Key
* @return Lang Values
*/
default String getLang(String channel, String key) {
if (Util.isNull(channel, key)) throw new NullPointerException();
return getLang(channel).get(key);
}
/**
* Gets the Runtime Directory
*
* @return Directory
*/
UniversalFile getRuntimeDirectory();
/**
* Gets the SubServers Version
*
* @return SubServers Version
*/
Version getWrapperVersion();
/**
* Gets the SubServers Build Signature
*
* @return SubServers Build Signature (or null if unsigned)
*/
Version getWrapperBuild();
/**
* Gets the BungeeCord Version
*
* @return BungeeCord Version
*/
Version getProxyVersion();
/**
* Get an array of compatible Minecraft Versions
*
* @return Minecraft Versions
*/
Version[] getGameVersion();
}

View File

@ -0,0 +1,33 @@
package net.ME1312.SubServers.Bungee;
import net.ME1312.Galaxi.Library.Callback.ReturnRunnable;
import net.md_5.bungee.BungeeCord;
import net.md_5.bungee.api.config.ServerInfo;
import java.io.IOException;
import java.util.Map;
/**
* BungeeCord Common Layout Class
*/
public abstract class BungeeCommon extends BungeeCord {
final ReturnRunnable<BungeeAPI> api;
protected BungeeCommon(ReturnRunnable<BungeeAPI> api) throws IOException {
this.api = api;
}
/**
* Get the name from BungeeCord's original signature (for determining which fork is being used)
*
* @return BungeeCord Software Name
*/
public abstract String getBungeeName();
/**
* Waterfall's getServersCopy()
*
* @return Server Map Copy
*/
public abstract Map<String, ServerInfo> getServersCopy();
}

View File

@ -1,7 +1,7 @@
package net.ME1312.SubServers.Bungee.Library.Compatibility;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubServers.Bungee.SubProxy;
import net.md_5.bungee.api.ProxyServer;
import java.util.HashMap;
import java.util.logging.Handler;
@ -12,7 +12,6 @@ import java.util.logging.LogRecord;
*/
public class Logger {
private static final HashMap<String, java.util.logging.Logger> existing = new HashMap<String, java.util.logging.Logger>();
private static SubProxy plugin;
/**
* Get a logger
@ -35,7 +34,7 @@ public class Logger {
@Override
public void publish(LogRecord record) {
if (open)
plugin.getLogger().log(record.getLevel(), prefix + " > " + record.getMessage(), record.getParameters());
ProxyServer.getInstance().getLogger().log(record.getLevel(), prefix + " > " + record.getMessage(), record.getParameters());
}
@Override

View File

@ -0,0 +1,45 @@
package net.ME1312.SubServers.Bungee.Library.Compatibility;
import java.net.InetSocketAddress;
import java.util.UUID;
/**
* RemotePlayer Layout Class
*/
public interface RemotePlayer {
/**
* Get the UUID of this player.
*
* @return the UUID
*/
UUID getUniqueId();
/**
* Get the unique name of this player.
*
* @return the players username
*/
String getName();
/**
* Gets the remote address of this connection.
*
* @return the remote address
*/
InetSocketAddress getAddress();
/**
* Gets the name of the proxy this player is connected to.
*
* @return the name of the proxy this player is connected to
*/
String getProxyName();
/**
* Gets the name of the server this player is connected to.
*
* @return the name of the server this player is connected to
*/
String getServerName();
}

View File

@ -2,10 +2,7 @@ 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.ME1312.SubServers.Bungee.BungeeCommon;
import net.md_5.bungee.UserConnection;
import net.md_5.bungee.api.AbstractReconnectHandler;
import net.md_5.bungee.api.ProxyServer;
@ -25,9 +22,11 @@ import java.util.concurrent.CopyOnWriteArrayList;
public class SmartFallback implements ReconnectHandler {
private static List<FallbackInspector> inspectors = new CopyOnWriteArrayList<FallbackInspector>();
private static ReconnectHandler reconnect;
public static boolean dns_forward = false;
public SmartFallback(SubProxy proxy) {
if (reconnect == null && proxy.config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>()).getBoolean("Reconnect", false))
public SmartFallback(ObjectMap<String> settings) {
dns_forward = settings.getBoolean("DNS-Forward", false);
if (reconnect == null && settings.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);
}
@ -81,12 +80,12 @@ public class SmartFallback implements ReconnectHandler {
* @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)) {
if (connection.getVirtualHost() == null || !dns_forward) {
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()) {
for (Map.Entry<String, ServerInfo> s : ((BungeeCommon) ProxyServer.getInstance()).getServersCopy().entrySet()) {
if (dns.startsWith(s.getKey().toLowerCase() + '.'))
if (server == null || server.getKey().length() < s.getKey().length())
server = s;
@ -133,22 +132,10 @@ public class SmartFallback implements ReconnectHandler {
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);
ServerInfo server = ProxyServer.getInstance().getServerInfo(name);
if (server != null) {
boolean valid = true;
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(SmartFallback.inspectors);

View File

@ -40,10 +40,17 @@
<version>20w33a</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.ME1312.SubServers</groupId>
<artifactId>SubServers.Bungee.Common</artifactId>
<version>-PLACEHOLDER</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>net.ME1312.SubData</groupId>
<artifactId>Server</artifactId>
<version>20w46a</version>
<version>20w46b</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
@ -166,6 +173,10 @@
<link>https://dev.me1312.net/jenkins/job/SubData/javadoc/Server/</link>
<link>https://ci.md-5.net/job/BungeeCord/ws/api/target/apidocs/</link>
</links>
<includeDependencySources>true</includeDependencySources>
<dependencySourceIncludes>
<dependencySourceInclude>net.ME1312.SubServers:SubServers.Bungee.Common:*</dependencySourceInclude>
</dependencySourceIncludes>
</configuration>
</execution>
</executions>

View File

@ -101,44 +101,33 @@ public class InternalSubServer extends SubServerImpl {
this.logger = new InternalSubLogger(null, this, getName(), this.log, null);
this.thread = null;
this.command = null;
final UniversalFile[] locations = new UniversalFile[] {
new UniversalFile(this.directory, "plugins:SubServers.Client.jar"),
new UniversalFile(this.directory, "mods:SubServers.Client.jar")
};
if (new UniversalFile(this.directory, "plugins:SubServers.Client.jar").exists()) {
try {
JarInputStream updated = new JarInputStream(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/client.jar"));
JarFile existing = new JarFile(new UniversalFile(this.directory, "plugins:SubServers.Client.jar"));
for (UniversalFile location : locations) {
if (location.exists()) {
try {
JarInputStream updated = new JarInputStream(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/client.jar"));
JarFile existing = new JarFile(location);
if (existing.getManifest().getMainAttributes().getValue("Implementation-Title") != null && existing.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && existing.getManifest().getMainAttributes().getValue("Specification-Title") != null &&
updated.getManifest().getMainAttributes().getValue("Implementation-Title") != null && updated.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && updated.getManifest().getMainAttributes().getValue("Specification-Title") != null) {
if (new Version(existing.getManifest().getMainAttributes().getValue("Specification-Title")).compareTo(new Version(updated.getManifest().getMainAttributes().getValue("Specification-Title"))) < 0) {
new UniversalFile(this.directory, "plugins:SubServers.Client.jar").delete();
Util.copyFromJar(SubProxy.class.getClassLoader(), "net/ME1312/SubServers/Bungee/Library/Files/client.jar", new UniversalFile(this.directory, "plugins:SubServers.Client.jar").getPath());
if (existing.getManifest().getMainAttributes().getValue("Implementation-Title") != null && existing.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && existing.getManifest().getMainAttributes().getValue("Specification-Title") != null &&
updated.getManifest().getMainAttributes().getValue("Implementation-Title") != null && updated.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && updated.getManifest().getMainAttributes().getValue("Specification-Title") != null) {
if (new Version(existing.getManifest().getMainAttributes().getValue("Specification-Title")).compareTo(new Version(updated.getManifest().getMainAttributes().getValue("Specification-Title"))) < 0) {
location.delete();
Util.copyFromJar(SubProxy.class.getClassLoader(), "net/ME1312/SubServers/Bungee/Library/Files/client.jar", location.getPath());
}
}
existing.close();
updated.close();
} catch (Throwable e) {
System.out.println("Couldn't auto-update SubServers.Client for subserver: " + name);
e.printStackTrace();
}
existing.close();
updated.close();
} catch (Throwable e) {
System.out.println("Couldn't auto-update SubServers.Client.jar for " + name);
e.printStackTrace();
}
} else if (new UniversalFile(this.directory, "mods:SubServers.Client.jar").exists()) {
try {
JarInputStream updated = new JarInputStream(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/client.jar"));
JarFile existing = new JarFile(new UniversalFile(this.directory, "mods:SubServers.Client.jar"));
if (existing.getManifest().getMainAttributes().getValue("Implementation-Title") != null && existing.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && existing.getManifest().getMainAttributes().getValue("Specification-Title") != null &&
updated.getManifest().getMainAttributes().getValue("Implementation-Title") != null && updated.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && updated.getManifest().getMainAttributes().getValue("Specification-Title") != null) {
if (new Version(existing.getManifest().getMainAttributes().getValue("Specification-Title")).compareTo(new Version(updated.getManifest().getMainAttributes().getValue("Specification-Title"))) < 0) {
new UniversalFile(this.directory, "mods:SubServers.Client.jar").delete();
Util.copyFromJar(SubProxy.class.getClassLoader(), "net/ME1312/SubServers/Bungee/Library/Files/client.jar", new UniversalFile(this.directory, "mods:SubServers.Client.jar").getPath());
}
}
existing.close();
updated.close();
} catch (Throwable e) {
System.out.println("Couldn't auto-update SubServers.Client.jar for " + name);
e.printStackTrace();
}
}
this.lock = false;
}

View File

@ -12,7 +12,7 @@ import java.util.UUID;
/**
* Remote Player Class
*/
public class RemotePlayer implements SubDataSerializable {
public class RemotePlayer implements net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer, SubDataSerializable {
private ProxiedPlayer local;
private UUID id;
private String name;
@ -103,6 +103,12 @@ public class RemotePlayer implements SubDataSerializable {
} else return proxy;
}
@Override
public String getProxyName() {
Proxy proxy = getProxy();
return (proxy == null)? null : proxy.getName();
}
/**
* Gets the server this player is connected to.
*
@ -114,6 +120,12 @@ public class RemotePlayer implements SubDataSerializable {
} else return server;
}
@Override
public String getServerName() {
Server server = getServer();
return (server == null)? null : server.getName();
}
@Override
public boolean equals(Object obj) {
return obj instanceof RemotePlayer && getUniqueId().equals(((RemotePlayer) obj).getUniqueId());

View File

@ -14,7 +14,6 @@ import net.ME1312.Galaxi.Library.UniversalFile;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.Galaxi.Library.Version.Version;
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.protocol.ProtocolConstants;
import java.lang.reflect.InvocationTargetException;
@ -25,7 +24,7 @@ import java.util.*;
/**
* SubAPI Class
*/
public final class SubAPI {
public final class SubAPI implements BungeeAPI {
LinkedList<Runnable> enableListeners = new LinkedList<Runnable>();
LinkedList<Runnable> reloadListeners = new LinkedList<Runnable>();
LinkedList<Runnable> disableListeners = new LinkedList<Runnable>();
@ -612,18 +611,6 @@ public final class SubAPI {
return new LinkedHashMap<>(plugin.exLang.get(channel.toLowerCase()));
}
/**
* Gets a value from the SubServers Lang
*
* @param channel Lang Channel
* @param key Key
* @return Lang Values
*/
public String getLang(String channel, String key) {
if (Util.isNull(channel, key)) throw new NullPointerException();
return getLang(channel).get(key);
}
/**
* Get an Object Signature without linking the Signature to any object
*

View File

@ -18,6 +18,7 @@ import net.ME1312.SubServers.Bungee.Library.*;
import net.ME1312.Galaxi.Library.Config.YAMLConfig;
import net.ME1312.Galaxi.Library.Config.YAMLSection;
import net.ME1312.SubServers.Bungee.Library.Compatibility.Galaxi.GalaxiCommand;
import net.ME1312.SubServers.Bungee.Library.Compatibility.Galaxi.GalaxiEventListener;
import net.ME1312.SubServers.Bungee.Library.Compatibility.LegacyServerMap;
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
import net.ME1312.SubServers.Bungee.Library.Compatibility.Plugin;
@ -61,7 +62,7 @@ import java.util.concurrent.TimeUnit;
/**
* Main Plugin Class
*/
public final class SubProxy extends BungeeCord implements Listener {
public final class SubProxy extends BungeeCommon implements Listener {
final LinkedHashMap<String, LinkedHashMap<String, String>> exLang = new LinkedHashMap<String, LinkedHashMap<String, String>>();
final HashMap<String, Class<? extends Host>> hostDrivers = new HashMap<String, Class<? extends Host>>();
public final HashMap<String, Proxy> proxies = new HashMap<String, Proxy>();
@ -98,13 +99,13 @@ public final class SubProxy extends BungeeCord implements Listener {
@SuppressWarnings("unchecked")
SubProxy(PrintStream out, boolean isPatched) throws Exception {
super(SubAPI::getInstance);
this.isPatched = isPatched;
this.isGalaxi = !Util.isException(() ->
Util.reflect(Class.forName("net.ME1312.Galaxi.Engine.PluginManager").getMethod("findClasses", Class.class),
Util.reflect(Class.forName("net.ME1312.Galaxi.Engine.GalaxiEngine").getMethod("getPluginManager"),
Util.reflect(Class.forName("net.ME1312.Galaxi.Engine.GalaxiEngine").getMethod("getInstance"), null)), Launch.class));
Util.reflect(Logger.class.getDeclaredField("plugin"), null, this);
Logger.get("SubServers").info("Loading SubServers.Bungee v" + version.toString() + " Libraries (for Minecraft " + api.getGameVersion()[api.getGameVersion().length - 1] + ")");
this.out = out;
@ -252,8 +253,24 @@ public final class SubProxy extends BungeeCord implements Listener {
}
}
SmartFallback.addInspector((player, server) -> {
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()) return null;
}
return confidence;
});
if (config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>()).getBoolean("Enabled", true))
setReconnectHandler(new SmartFallback(this));
setReconnectHandler(new SmartFallback(config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>())));
subprotocol = SubProtocol.get();
subprotocol.registerCipher("DHE", DHE.get(128));
@ -261,7 +278,7 @@ public final class SubProxy extends BungeeCord implements Listener {
subprotocol.registerCipher("DHE-192", DHE.get(192));
subprotocol.registerCipher("DHE-256", DHE.get(256));
Logger.get("SubServers").info("Loading BungeeCord Libraries...");
if (isGalaxi) Util.reflect(net.ME1312.SubServers.Bungee.Library.Compatibility.Galaxi.GalaxiEventListener.class.getConstructor(SubProxy.class), this);
if (isGalaxi) Util.reflect(GalaxiEventListener.class.getConstructor(SubProxy.class), this);
}
/**
@ -325,6 +342,8 @@ public final class SubProxy extends BungeeCord implements Listener {
subdata = null;
}
SmartFallback.dns_forward = config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>()).getBoolean("DNS-Forward", false);
int hosts = 0;
Logger.get("SubServers").info(((status)?"Rel":"L")+"oading Hosts...");
for (String name : config.get().getMap("Hosts").getKeys()) {
@ -648,7 +667,7 @@ public final class SubProxy extends BungeeCord implements Listener {
GalaxiCommand.group(SubCommand.class);
if (getReconnectHandler() != null && getReconnectHandler().getClass().equals(SmartFallback.class))
setReconnectHandler(new SmartFallback(this)); // Re-initialize Smart Fallback
setReconnectHandler(new SmartFallback(config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>()))); // Re-initialize Smart Fallback
new Metrics(this);
new Timer("SubServers.Bungee::Routine_Update_Check").schedule(new TimerTask() {
@ -803,6 +822,7 @@ public final class SubProxy extends BungeeCord implements Listener {
*
* @return BungeeCord Software Name
*/
@Override
public String getBungeeName() {
return super.getName();
}
@ -822,6 +842,7 @@ public final class SubProxy extends BungeeCord implements Listener {
*
* @return Server Map Copy
*/
@Override
public Map<String, ServerInfo> getServersCopy() {
HashMap<String, ServerInfo> servers = new HashMap<String, ServerInfo>();
if (!api.ready) {

View File

@ -55,7 +55,7 @@
<dependency>
<groupId>net.ME1312.SubData</groupId>
<artifactId>Client</artifactId>
<version>20w46a</version>
<version>20w46b</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>

View File

@ -37,7 +37,7 @@
<dependency>
<groupId>net.ME1312.SubData</groupId>
<artifactId>Client</artifactId>
<version>20w46a</version>
<version>20w46b</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>

View File

@ -27,7 +27,7 @@
<dependency>
<groupId>net.ME1312.SubData</groupId>
<artifactId>Client</artifactId>
<version>20w46a</version>
<version>20w46b</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>

View File

@ -64,42 +64,30 @@ public class SubServerImpl {
this.command = null;
this.queue = new LinkedList<String>();
this.stopcmd = stopcmd;
final UniversalFile[] locations = new UniversalFile[] {
new UniversalFile(this.directory, "plugins:SubServers.Client.jar"),
new UniversalFile(this.directory, "mods:SubServers.Client.jar")
};
if (new UniversalFile(this.directory, "plugins:SubServers.Client.jar").exists()) {
try {
JarInputStream updated = new JarInputStream(ExHost.class.getResourceAsStream("/net/ME1312/SubServers/Host/Library/Files/client.jar"));
JarFile existing = new JarFile(new UniversalFile(this.directory, "plugins:SubServers.Client.jar"));
for (UniversalFile location : locations) {
if (location.exists()) {
try {
JarInputStream updated = new JarInputStream(ExHost.class.getResourceAsStream("/net/ME1312/SubServers/Host/Library/Files/client.jar"));
JarFile existing = new JarFile(location);
if (existing.getManifest().getMainAttributes().getValue("Implementation-Title") != null && existing.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && existing.getManifest().getMainAttributes().getValue("Specification-Title") != null &&
updated.getManifest().getMainAttributes().getValue("Implementation-Title") != null && updated.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && updated.getManifest().getMainAttributes().getValue("Specification-Title") != null) {
if (new Version(existing.getManifest().getMainAttributes().getValue("Specification-Title")).compareTo(new Version(updated.getManifest().getMainAttributes().getValue("Specification-Title"))) < 0) {
new UniversalFile(this.directory, "plugins:SubServers.Client.jar").delete();
Util.copyFromJar(ExHost.class.getClassLoader(), "net/ME1312/SubServers/Host/Library/Files/client.jar", new UniversalFile(this.directory, "plugins:SubServers.Client.jar").getPath());
if (existing.getManifest().getMainAttributes().getValue("Implementation-Title") != null && existing.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && existing.getManifest().getMainAttributes().getValue("Specification-Title") != null &&
updated.getManifest().getMainAttributes().getValue("Implementation-Title") != null && updated.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && updated.getManifest().getMainAttributes().getValue("Specification-Title") != null) {
if (new Version(existing.getManifest().getMainAttributes().getValue("Specification-Title")).compareTo(new Version(updated.getManifest().getMainAttributes().getValue("Specification-Title"))) < 0) {
location.delete();
Util.copyFromJar(ExHost.class.getClassLoader(), "net/ME1312/SubServers/Host/Library/Files/client.jar", location.getPath());
}
}
existing.close();
updated.close();
} catch (Throwable e) {
host.log.info.println("Couldn't auto-update SubServers.Client for subserver: " + name);
host.log.error.println(e);
}
existing.close();
updated.close();
} catch (Throwable e) {
host.log.info.println("Couldn't auto-update SubServers.Client.jar for " + name);
host.log.error.println(e);
}
} else if (new UniversalFile(this.directory, "mods:SubServers.Client.jar").exists()) {
try {
JarInputStream updated = new JarInputStream(ExHost.class.getResourceAsStream("/net/ME1312/SubServers/Host/Library/Files/client.jar"));
JarFile existing = new JarFile(new UniversalFile(this.directory, "mods:SubServers.Client.jar"));
if (existing.getManifest().getMainAttributes().getValue("Implementation-Title") != null && existing.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && existing.getManifest().getMainAttributes().getValue("Specification-Title") != null &&
updated.getManifest().getMainAttributes().getValue("Implementation-Title") != null && updated.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && updated.getManifest().getMainAttributes().getValue("Specification-Title") != null) {
if (new Version(existing.getManifest().getMainAttributes().getValue("Specification-Title")).compareTo(new Version(updated.getManifest().getMainAttributes().getValue("Specification-Title"))) < 0) {
new UniversalFile(this.directory, "mods:SubServers.Client.jar").delete();
Util.copyFromJar(ExHost.class.getClassLoader(), "net/ME1312/SubServers/Host/Library/Files/client.jar", new UniversalFile(this.directory, "mods:SubServers.Client.jar").getPath());
}
}
existing.close();
updated.close();
} catch (Throwable e) {
host.log.info.println("Couldn't auto-update SubServers.Client.jar for " + name);
host.log.error.println(e);
}
}
}

View File

@ -40,10 +40,17 @@
<version>20w33a</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.ME1312.SubServers</groupId>
<artifactId>SubServers.Bungee.Common</artifactId>
<version>-PLACEHOLDER</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>net.ME1312.SubData</groupId>
<artifactId>Client</artifactId>
<version>20w46a</version>
<version>20w46b</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
@ -164,6 +171,10 @@
<link>https://dev.me1312.net/jenkins/job/SubData/javadoc/Client/</link>
<link>https://ci.md-5.net/job/BungeeCord/ws/api/target/apidocs/</link>
</links>
<includeDependencySources>true</includeDependencySources>
<dependencySourceIncludes>
<dependencySourceInclude>net.ME1312.SubServers:SubServers.Bungee.Common:*</dependencySourceInclude>
</dependencySourceIncludes>
</configuration>
</execution>
</executions>

View File

@ -9,13 +9,14 @@ import net.ME1312.SubData.Client.Encryption.DHE;
import net.ME1312.SubData.Client.Encryption.RSA;
import net.ME1312.SubData.Client.Library.DataSize;
import net.ME1312.SubData.Client.Library.DisconnectReason;
import net.ME1312.SubServers.Bungee.BungeeCommon;
import net.ME1312.SubServers.Bungee.Library.Compatibility.Galaxi.GalaxiCommand;
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
import net.ME1312.SubServers.Bungee.Library.Fallback.SmartFallback;
import net.ME1312.SubServers.Sync.Event.*;
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.Compatibility.Plugin;
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;
@ -29,7 +30,6 @@ import net.ME1312.SubServers.Sync.Network.Packet.PacketExSyncPlayer;
import net.ME1312.SubServers.Sync.Network.SubProtocol;
import net.ME1312.SubServers.Sync.Server.ServerImpl;
import net.ME1312.SubServers.Sync.Server.SubServerImpl;
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;
@ -54,7 +54,7 @@ import java.util.concurrent.TimeUnit;
/**
* Main Plugin Class
*/
public final class ExProxy extends BungeeCord implements Listener {
public final class ExProxy extends BungeeCommon implements Listener {
HashMap<Integer, SubDataClient> subdata = new HashMap<Integer, SubDataClient>();
NamedContainer<Long, Map<String, Map<String, String>>> lang = null;
public final Map<String, ServerImpl> servers = new TreeMap<String, ServerImpl>();
@ -79,13 +79,13 @@ public final class ExProxy extends BungeeCord implements Listener {
private boolean posted = false;
ExProxy(PrintStream out, boolean isPatched) throws Exception {
super(SubAPI::getInstance);
this.isPatched = isPatched;
this.isGalaxi = !Util.isException(() ->
Util.reflect(Class.forName("net.ME1312.Galaxi.Engine.PluginManager").getMethod("findClasses", Class.class),
Util.reflect(Class.forName("net.ME1312.Galaxi.Engine.GalaxiEngine").getMethod("getPluginManager"),
Util.reflect(Class.forName("net.ME1312.Galaxi.Engine.GalaxiEngine").getMethod("getInstance"), null)), Launch.class));
Util.reflect(Logger.class.getDeclaredField("plugin"), null, this);
Logger.get("SubServers").info("Loading SubServers.Sync v" + version.toString() + " Libraries (for Minecraft " + api.getGameVersion()[api.getGameVersion().length - 1] + ")");
this.out = out;
@ -102,8 +102,24 @@ public final class ExProxy extends BungeeCord implements Listener {
ConfigUpdater.updateConfig(new UniversalFile(dir, "sync.yml"));
config = new YAMLConfig(new UniversalFile(dir, "sync.yml"));
SmartFallback.addInspector((player, server) -> {
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()) return null;
}
return confidence;
});
if (config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>()).getBoolean("Enabled", true))
setReconnectHandler(new SmartFallback(this));
setReconnectHandler(new SmartFallback(config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>())));
subprotocol = SubProtocol.get();
subprotocol.registerCipher("DHE", DHE.get(128));
@ -125,6 +141,8 @@ public final class ExProxy extends BungeeCord implements Listener {
@Override
public void startListeners() {
try {
SmartFallback.dns_forward = config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>()).getBoolean("DNS-Forward", false);
resetDate = Calendar.getInstance().getTime().getTime();
ConfigUpdater.updateConfig(new UniversalFile(dir, "SubServers:sync.yml"));
config.reload();
@ -217,7 +235,7 @@ public final class ExProxy extends BungeeCord implements Listener {
GalaxiCommand.group(SubCommand.class);
if (getReconnectHandler() != null && getReconnectHandler().getClass().equals(SmartFallback.class))
setReconnectHandler(new SmartFallback(this)); // Re-initialize Smart Fallback
setReconnectHandler(new SmartFallback(config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>()))); // Re-initialize Smart Fallback
new Metrics(this);
new Timer("SubServers.Sync::Routine_Update_Check").schedule(new TimerTask() {
@ -308,6 +326,7 @@ public final class ExProxy extends BungeeCord implements Listener {
*
* @return BungeeCord Software Name
*/
@Override
public String getBungeeName() {
return super.getName();
}

View File

@ -3,7 +3,7 @@ package net.ME1312.SubServers.Sync;
import net.ME1312.Galaxi.Library.Platform;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.Galaxi.Library.Version.Version;
import net.ME1312.SubServers.Sync.Library.Compatibility.Galaxi.GalaxiInfo;
import net.ME1312.SubServers.Bungee.Library.Compatibility.Galaxi.GalaxiInfo;
import java.security.Security;
import java.text.SimpleDateFormat;

View File

@ -1,55 +0,0 @@
package net.ME1312.SubServers.Sync.Library.Compatibility;
import net.ME1312.Galaxi.Library.Container.NamedContainer;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.plugin.Command;
import net.md_5.bungee.api.plugin.TabExecutor;
import java.util.List;
/**
* Command Layout Class that implements all possible features (Base Version)
*/
public abstract class CommandX extends Command implements TabExecutor {
/**
* Create a Command
*
* @param name Command Name
*/
public CommandX(String name) {
super(name);
}
/**
* Create a Command
*
* @param name Command Name
* @param permission Command Permission
* @param aliases Command Aliases
*/
public CommandX(String name, String permission, String... aliases) {
super(name, permission, aliases);
}
/**
* Suggest Arguments
*
* @param sender Sender
* @param args Arguments (including the final unfinished one)
* @return An Error Message (if there was one, otherwise null) and a List of Suggestions
*/
public abstract NamedContainer<String, List<String>> suggestArguments(CommandSender sender, String[] args);
/**
* Override the BungeeCord Method of {@link #suggestArguments(CommandSender, String[])}
*
* @param sender Sender
* @param args Arguments (including the final unfinished one)
* @return A Collection of Suggestions
*/
@Override
public Iterable<String> onTabComplete(CommandSender sender, String[] args) {
return suggestArguments(sender, args).get();
}
}

View File

@ -1,57 +0,0 @@
package net.ME1312.SubServers.Sync.Library.Compatibility.Galaxi;
import net.ME1312.Galaxi.Library.Util;
import net.md_5.bungee.api.plugin.Command;
/**
* Galaxi Command Compatibility Class
*/
public class GalaxiCommand {
/**
* Group similar Commands
*
* @param commands Command Classes
*/
@SafeVarargs
public static void group(Class<? extends Command>... commands) {
Util.isException(() -> Util.reflect(GalaxiCommandWrapper.class.getDeclaredConstructor(Class[].class), (Object) commands));
}
/**
* Set the Description of a Command
*
* @param command Command
* @param value Value
* @return The Command
*/
public static Command description(Command command, String value) {
Util.isException(() -> Util.reflect(Class.forName("net.ME1312.Galaxi.Plugin.Command.Command").getMethod("description", String.class), command, value));
return command;
}
/**
* Set the Help Page for a Command
*
* @param command Command
* @param lines Help Page Lines
* @return The Command
*/
public static Command help(Command command, String... lines) {
Util.isException(() -> Util.reflect(Class.forName("net.ME1312.Galaxi.Plugin.Command.Command").getMethod("help", String[].class), command, (Object) lines));
return command;
}
/**
* Set the Usage of a Command
*
* @param command Command
* @param args Argument Placeholders
* @return The Command
*/
public static Command usage(Command command, String... args) {
Util.isException(() -> Util.reflect(Class.forName("net.ME1312.Galaxi.Plugin.Command.Command").getMethod("usage", String[].class), command, (Object) args));
return command;
}
}

View File

@ -1,75 +0,0 @@
package net.ME1312.SubServers.Sync.Library.Compatibility.Galaxi;
import net.ME1312.Galaxi.Galaxi;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.Galaxi.Plugin.Command.Command;
import net.ME1312.Galaxi.Plugin.Command.CommandSender;
import net.ME1312.Galaxi.Plugin.Command.CompletionHandler;
import net.ME1312.Galaxi.Plugin.PluginManager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
class GalaxiCommandWrapper extends Command implements CompletionHandler {
private HashMap<String, Command> forwards = new HashMap<String, Command>();
private Command data;
@SafeVarargs
GalaxiCommandWrapper(Class<? extends Command>... commands) {
super(Galaxi.getInstance().getAppInfo());
Map<String, Command> registered = Util.getDespiteException(() -> Util.reflect(PluginManager.class.getDeclaredField("commands"), Galaxi.getInstance().getPluginManager()), null);
ArrayList<String> tmp = new ArrayList<String>();
tmp.addAll(registered.keySet());
for (String alias : tmp) {
Command command = registered.get(alias);
for (Class<? extends Command> type : commands) {
if (type.isInstance(command)) {
forwards.put(alias, command);
if (data == null) data = command;
registered.remove(alias);
break;
}
}
}
register(forwards.keySet().toArray(new String[0]));
}
@Override
public void command(CommandSender sender, String label, String[] args) {
if (forwards.keySet().contains(label.toLowerCase())) {
forwards.get(label.toLowerCase()).command(sender, label, args);
} else {
throw new IllegalStateException("Command label not recognised in group: " + forwards.keySet());
}
}
@Override
public String[] complete(CommandSender sender, String label, String[] args) {
if (forwards.keySet().contains(label.toLowerCase())) {
Command command = forwards.get(label.toLowerCase());
if (command.autocomplete() != null) {
return command.autocomplete().complete(sender, label, args);
} else return new String[0];
} else {
throw new IllegalStateException("Command label not recognised in group: " + forwards.keySet());
}
}
@Override
public String description() {
return (data == null)?super.description():data.description();
}
@Override
public String[] help() {
return (data == null)?super.help():data.help();
}
@Override
public String[] usage() {
return (data == null)?super.usage():data.usage();
}
}

View File

@ -1,47 +0,0 @@
package net.ME1312.SubServers.Sync.Library.Compatibility.Galaxi;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.Galaxi.Library.Version.Version;
import java.lang.annotation.Annotation;
import java.util.jar.Manifest;
/**
* Galaxi Info Class
*/
public class GalaxiInfo {
private GalaxiInfo() {}
@SuppressWarnings("unchecked")
private static <A extends Annotation> Class<A> asAnnotation(Class<?> clazz) {
return (Class<A>) clazz;
}
/**
* Get the Galaxi Version
*
* @return Galaxi Version
*/
public static Version getVersion() {
return Util.getDespiteException(() -> Version.fromString((String) Class.forName("net.ME1312.Galaxi.Plugin.App").getMethod("version").invoke(
Class.forName("net.ME1312.Galaxi.Engine.GalaxiEngine").getAnnotation(asAnnotation(Class.forName("net.ME1312.Galaxi.Plugin.App"))))), null);
}
/**
* Get the Galaxi Build Signature
*
* @return Galaxi Build Signature
*/
public static Version getSignature() {
try {
Manifest manifest = new Manifest(Class.forName("net.ME1312.Galaxi.Engine.GalaxiEngine").getResourceAsStream("/META-INF/GalaxiEngine.MF"));
if (manifest.getMainAttributes().getValue("Implementation-Version") != null && manifest.getMainAttributes().getValue("Implementation-Version").length() > 0) {
return new Version(manifest.getMainAttributes().getValue("Implementation-Version"));
} else {
return null;
}
} catch (Throwable e) {
return null;
}
}
}

View File

@ -1,60 +0,0 @@
package net.ME1312.SubServers.Sync.Library.Compatibility;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubServers.Sync.ExProxy;
import net.ME1312.SubServers.Sync.SubAPI;
import java.util.HashMap;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
/**
* Logger Compatibility Class
*/
public class Logger {
private static final HashMap<String, java.util.logging.Logger> existing = new HashMap<String, java.util.logging.Logger>();
private static ExProxy plugin;
/**
* Get a logger
*
* @param prefix Prefix
* @return Logger
*/
@SuppressWarnings("deprecation")
public static java.util.logging.Logger get(String prefix) {
if (!existing.keySet().contains(prefix)) {
ExProxy plugin = SubAPI.getInstance().getInternals();
java.util.logging.Logger log;
if (plugin.isGalaxi) {
log = Util.getDespiteException(() -> Util.reflect(Class.forName("net.ME1312.Galaxi.Library.Log.Logger").getDeclaredMethod("toPrimitive"),
Util.reflect(Class.forName("net.ME1312.Galaxi.Library.Log.Logger").getConstructor(String.class), prefix)), null);
} else {
log = java.util.logging.Logger.getAnonymousLogger();
log.setUseParentHandlers(false);
log.addHandler(new Handler() {
private boolean open = true;
@Override
public void publish(LogRecord record) {
if (open)
plugin.getLogger().log(record.getLevel(), prefix + " > " + record.getMessage(), record.getParameters());
}
@Override
public void flush() {
}
@Override
public void close() throws SecurityException {
open = false;
}
});
}
existing.put(prefix, log);
}
return existing.get(prefix);
}
}

View File

@ -1,74 +0,0 @@
package net.ME1312.SubServers.Sync.Library.Compatibility.mc1_13;
import net.ME1312.Galaxi.Library.Container.NamedContainer;
import net.md_5.bungee.api.CommandSender;
import java.util.LinkedList;
import java.util.List;
/**
* Command Layout Class that implements all possible features (1.13 Version)
*/
public class CommandX extends net.ME1312.SubServers.Sync.Library.Compatibility.CommandX/* implements TabValidator */ {
public final net.ME1312.SubServers.Sync.Library.Compatibility.CommandX command;
/**
* Create a Command
*
* @param other CommandX from previous version
*/
public CommandX(net.ME1312.SubServers.Sync.Library.Compatibility.CommandX other) {
super(other.getName());
command = other;
}
/**
* Override BungeeCord Method for the previously used one
*
* @param sender Sender
* @param args Arguments
*/
@Override
public void execute(CommandSender sender, String[] args) {
command.execute(sender, args);
}
@Override
public NamedContainer<String, List<String>> suggestArguments(CommandSender sender, String[] args) {
return command.suggestArguments(sender, args);
}
/**
* Validate a Command (Override for custom)
*
* @param sender Sender
* @param command Command to validate
* @return NamedContainer with a String error message and a Integer that represents where the command was deemed invalid
*/
public NamedContainer<String, Integer> validateCommand(CommandSender sender, String command) {
List<NamedContainer<String, Integer>> split = new LinkedList<NamedContainer<String, Integer>>();
String cmd = command;
int i;
while ((i = cmd.indexOf((int) ' ')) < 0) {
i++;
String arg = cmd.substring(i);
split.add(new NamedContainer<>(arg.contains(" ")?arg.substring(0, arg.indexOf((int) ' ')):arg, i));
cmd = arg;
}
List<String> args = new LinkedList<String>();
NamedContainer<String, Integer> response = null;
i = 0;
for (NamedContainer<String, Integer> arg : split) {
if (i > 0) {
args.add(arg.name());
NamedContainer<String, List<String>> suggestions = suggestArguments(sender, args.toArray(new String[args.size() - 1]));
if (suggestions.name() != null) response = new NamedContainer<>(suggestions.name(), arg.get());
}
i++;
}
return response;
}
// TODO Override the original validator method
}

View File

@ -4,7 +4,7 @@ import net.ME1312.Galaxi.Library.Config.YAMLConfig;
import net.ME1312.Galaxi.Library.Config.YAMLSection;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.Galaxi.Library.Version.Version;
import net.ME1312.SubServers.Sync.Library.Compatibility.Logger;
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
import net.ME1312.SubServers.Sync.SubAPI;
import java.io.File;

View File

@ -1,19 +0,0 @@
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
*/
public interface FallbackInspector {
/**
* 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
*/
Double inspect(ProxiedPlayer player, ServerInfo server);
}

View File

@ -1,221 +0,0 @@
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;
import net.md_5.bungee.UserConnection;
import net.md_5.bungee.api.AbstractReconnectHandler;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.ReconnectHandler;
import net.md_5.bungee.api.config.ListenerInfo;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.PendingConnection;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* Smart Fallback Handler Class
*/
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) {
return getServer(player, player instanceof UserConnection);
}
protected ServerInfo getServer(ProxiedPlayer player, boolean queue) {
ServerInfo override;
if ((override = getForcedHost(player.getPendingConnection())) != null
|| (override = getDNS(player.getPendingConnection())) != null) {
if (queue) ((UserConnection) player).setServerJoinQueue(new LinkedList<>());
return override;
} else {
Map<String, ServerInfo> fallbacks = getFallbackServers(player.getPendingConnection().getListener(), player);
if ((override = getReconnectServer(player)) != null || !fallbacks.isEmpty()) {
if (queue) ((UserConnection) player).setServerJoinQueue(new LinkedList<>(fallbacks.keySet()));
return (override != null)? override : new LinkedList<>(fallbacks.values()).getFirst();
} else {
return null;
}
}
}
/**
* Grabs the Forced Host Server for this connection
*
* @see AbstractReconnectHandler#getForcedHost(PendingConnection) Essentially the same method, but more ambigous
* @param connection Connection to check
* @return Forced Host Server (or null if there is none)
*/
public static ServerInfo getForcedHost(PendingConnection connection) {
if (connection.getVirtualHost() == null) {
return null;
} else {
String forced = connection.getListener().getForcedHosts().get(connection.getVirtualHost().getHostString());
//if (forced == null && con.getListener().isForceDefault()) { // This is the part of the method that made it ambiguous
// forced = con.getListener().getDefaultServer(); // Aside from that, everything else was fine
//} // :(
return ProxyServer.getInstance().getServerInfo(forced);
}
}
/**
* 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
*
* @param listener Listener to grab fallback servers from
* @return Fallback Server Map (with legacy bungee case-sensitive keys)
*/
public static Map<String, ServerInfo> getFallbackServers(ListenerInfo listener) {
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;
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(SmartFallback.inspectors);
for (FallbackInspector inspector : inspectors) try {
Double response = inspector.inspect(player, server);
if (response == null) {
valid = false;
} else {
confidence += response;
}
} catch (Throwable e) {
new InvocationTargetException(e, "Exception while running inspecting fallback server: " + server.getName()).printStackTrace();
}
if (valid) {
List<ServerInfo> servers = (score.keySet().contains(confidence))?score.get(confidence):new LinkedList<ServerInfo>();
servers.add(server);
score.put(confidence, servers);
}
}
}
Random random = new Random();
LinkedHashMap<String, ServerInfo> map = new LinkedHashMap<String, ServerInfo>();
for (List<ServerInfo> servers : score.values()) {
while (!servers.isEmpty()) {
ServerInfo next = servers.get(random.nextInt(servers.size()));
map.put(next.getName(), next);
servers.remove(next);
}
}
return map;
}
/**
* Add a Fallback Server Inspector
*
* @param inspector Inspector
*/
public static void addInspector(FallbackInspector inspector) {
if (Util.isNull(inspector)) throw new NullPointerException();
inspectors.add(inspector);
}
/**
* Remove a Fallback Server Inspector
*
* @param inspector Inspector
*/
public static void removeInspector(FallbackInspector inspector) {
if (Util.isNull(inspector)) throw new NullPointerException();
Util.isException(() -> inspectors.remove(inspector));
}
@Override
public void setServer(ProxiedPlayer player) {
if (reconnect != null) reconnect.setServer(player);
}
@Override
public void save() {
if (reconnect != null) reconnect.save();
}
@Override
public void close() {
if (reconnect != null) reconnect.close();
}
}

View File

@ -1,40 +0,0 @@
ip_forward: true
network_compression_threshold: 256
stats: 'undefined'
permissions:
default:
- bungeecord.command.server
- bungeecord.command.list
admin:
- bungeecord.command.find
- bungeecord.command.alert
- bungeecord.command.send
- bungeecord.command.end
- bungeecord.command.ip
- bungeecord.command.reload
groups: {}
servers:
Lobby:
motd: '&1Just another BungeeCord - Forced Host'
address: 127.0.0.1:25566
restricted: false
timeout: 30000
listeners:
- query_port: 25564
motd: '&1Another Bungee server'
priorities:
- Lobby
bind_local_address: true
tab_list: GLOBAL_PING
query_enabled: false
host: 0.0.0.0:25565
forced_hosts: {}
max_players: 1
tab_size: 60
ping_passthrough: false
force_default_server: true
player_limit: -1
online_mode: true
log_commands: false
disabled_commands: []
connection_throttle: 4000

View File

@ -18,7 +18,7 @@ import java.util.UUID;
/**
* Simplified RemotePlayer Data Class
*/
public class RemotePlayer {
public class RemotePlayer implements net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer {
ObjectMap<String> raw;
private Proxy proxy = null;
private Server server = null;
@ -159,6 +159,11 @@ public class RemotePlayer {
}
}
@Override
public String getProxyName() {
return getProxy();
}
/**
* Gets the server this player is connected to.
*
@ -196,6 +201,11 @@ public class RemotePlayer {
}
}
@Override
public String getServerName() {
return getServer();
}
/**
* Get the Timestamp for when the data was last refreshed
*

View File

@ -6,8 +6,8 @@ import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubData.Client.Protocol.PacketObjectIn;
import net.ME1312.SubData.Client.Protocol.PacketOut;
import net.ME1312.SubData.Client.SubDataSender;
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
import net.ME1312.SubServers.Sync.ExProxy;
import net.ME1312.SubServers.Sync.Library.Compatibility.Logger;
import java.util.Calendar;

View File

@ -6,8 +6,8 @@ import net.ME1312.SubData.Client.Protocol.Initial.InitialPacket;
import net.ME1312.SubData.Client.Protocol.PacketObjectIn;
import net.ME1312.SubData.Client.Protocol.PacketObjectOut;
import net.ME1312.SubData.Client.SubDataSender;
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
import net.ME1312.SubServers.Sync.ExProxy;
import net.ME1312.SubServers.Sync.Library.Compatibility.Logger;
import net.ME1312.SubServers.Sync.SubAPI;
/**

View File

@ -113,7 +113,7 @@ public class SubProtocol extends SubDataProtocol {
}
private Logger getLogger(int channel) {
return net.ME1312.SubServers.Sync.Library.Compatibility.Logger.get("SubData" + ((channel != 0)? "/Sub-"+channel:""));
return net.ME1312.SubServers.Bungee.Library.Compatibility.Logger.get("SubData" + ((channel != 0)? "/Sub-"+channel:""));
}
@Override
@ -144,7 +144,7 @@ public class SubProtocol extends SubDataProtocol {
subdata.sendPacket(new PacketDownloadLang());
subdata.sendPacket(new PacketDownloadPlatformInfo(platform -> {
if (plugin.lastReload != platform.getMap("subservers").getLong("last-reload")) {
net.ME1312.SubServers.Sync.Library.Compatibility.Logger.get("SubServers").info("Resetting Server Data");
net.ME1312.SubServers.Bungee.Library.Compatibility.Logger.get("SubServers").info("Resetting Server Data");
plugin.servers.clear();
plugin.lastReload = platform.getMap("subservers").getLong("last-reload");
}
@ -159,7 +159,7 @@ public class SubProtocol extends SubDataProtocol {
if (plugin.config.get().getMap("Sync", new ObjectMap<>()).getBoolean("Disabled-Commands", false)) Util.reflect(Configuration.class.getDeclaredField("disabledCommands"), plugin.getConfig(), platform.getMap("bungee").getRawStringList("disabled-cmds"));
if (plugin.config.get().getMap("Sync", new ObjectMap<>()).getBoolean("Player-Limit", false)) Util.reflect(Configuration.class.getDeclaredField("playerLimit"), plugin.getConfig(), platform.getMap("bungee").getInt("player-limit"));
} catch (Exception e) {
net.ME1312.SubServers.Sync.Library.Compatibility.Logger.get("SubServers").info("Problem syncing BungeeCord configuration options");
net.ME1312.SubServers.Bungee.Library.Compatibility.Logger.get("SubServers").info("Problem syncing BungeeCord configuration options");
e.printStackTrace();
}
@ -199,7 +199,7 @@ public class SubProtocol extends SubDataProtocol {
plugin.getPluginManager().callEvent(event);
if (plugin.isRunning) {
net.ME1312.SubServers.Sync.Library.Compatibility.Logger.get("SubData").info("Attempting reconnect in " + plugin.config.get().getMap("Settings").getMap("SubData").getInt("Reconnect", 60) + " seconds");
net.ME1312.SubServers.Bungee.Library.Compatibility.Logger.get("SubData").info("Attempting reconnect in " + plugin.config.get().getMap("Settings").getMap("SubData").getInt("Reconnect", 60) + " seconds");
Util.isException(() -> Util.reflect(ExProxy.class.getDeclaredMethod("connect", NamedContainer.class), plugin, client));
} else map.put(0, null);
});

View File

@ -7,6 +7,7 @@ import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubData.Client.DataClient;
import net.ME1312.Galaxi.Library.Version.Version;
import net.ME1312.SubData.Client.DataProtocol;
import net.ME1312.SubServers.Bungee.BungeeAPI;
import net.ME1312.SubServers.Sync.Network.API.*;
import net.ME1312.SubServers.Sync.Network.Packet.*;
import net.ME1312.SubData.Client.SubDataClient;
@ -21,7 +22,7 @@ import static net.ME1312.SubServers.Sync.Network.API.SimplifiedData.*;
/**
* SubAPI Class
*/
public final class SubAPI {
public final class SubAPI implements BungeeAPI {
LinkedList<Runnable> enableListeners = new LinkedList<Runnable>();
LinkedList<Runnable> disableListeners = new LinkedList<Runnable>();
private final ExProxy plugin;
@ -460,18 +461,6 @@ public final class SubAPI {
return new LinkedHashMap<>(plugin.lang.get().get(channel.toLowerCase()));
}
/**
* Gets a value from the SubServers Lang
*
* @param channel Lang Channel
* @param key Key
* @return Lang Values
*/
public String getLang(String channel, String key) {
if (Util.isNull(channel, key)) throw new NullPointerException();
return getLang(channel).get(key);
}
/**
* Gets the Runtime Directory
*

View File

@ -8,13 +8,13 @@ import net.ME1312.Galaxi.Library.Container.PrimitiveContainer;
import net.ME1312.Galaxi.Library.Platform;
import net.ME1312.SubData.Client.SubDataClient;
import net.ME1312.SubData.Client.SubDataSender;
import net.ME1312.SubServers.Sync.Library.Compatibility.CommandX;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.Galaxi.Library.Container.Container;
import net.ME1312.Galaxi.Library.Container.NamedContainer;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.Galaxi.Library.Version.Version;
import net.ME1312.SubServers.Sync.Library.Compatibility.Galaxi.GalaxiInfo;
import net.ME1312.SubServers.Bungee.Library.Compatibility.CommandX;
import net.ME1312.SubServers.Bungee.Library.Compatibility.Galaxi.GalaxiInfo;
import net.ME1312.SubServers.Sync.Network.API.*;
import net.ME1312.SubServers.Sync.Network.Packet.*;
import net.ME1312.SubServers.Sync.Server.ServerImpl;
@ -38,7 +38,7 @@ import java.nio.charset.Charset;
import java.util.*;
import java.util.concurrent.TimeUnit;
import static net.ME1312.SubServers.Sync.Library.Compatibility.Galaxi.GalaxiCommand.*;
import static net.ME1312.SubServers.Bungee.Library.Compatibility.Galaxi.GalaxiCommand.*;
@SuppressWarnings("deprecation")
public final class SubCommand extends CommandX {

View File

@ -9,6 +9,7 @@
<modules>
<module>SubServers.Client</module>
<module>SuBServers.Bungee/common</module>
<module>SubServers.Bungee</module>
<module>SubServers.Console</module>
<module>SubServers.Creator</module>