SubServers.Sync.Velocity #64 (Preview)

And automatic external server definitions
This commit is contained in:
ME1312 2021-07-09 01:46:10 -04:00
parent 394c4b238b
commit ef1c593607
No known key found for this signature in database
GPG Key ID: FEFFE2F698E88FA8
80 changed files with 6950 additions and 343 deletions

View File

@ -22,6 +22,7 @@ These are some quick links for common resources of SubServers 2.
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Bungee.Common](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Bungee.Common)<br>
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Host](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Host)<br>
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Sync](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Sync)<br>
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Sync.Velocity](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Sync.Velocity)<br>
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Client.Bukkit](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Client.Bukkit)<br>
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Client.Common](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Client.Common)<br>
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Client.Sponge](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Client.Sponge)
@ -30,6 +31,7 @@ These are some quick links for common resources of SubServers 2.
> [https://bstats.org/plugin/bungeecord/SubServers_Bungee](https://bstats.org/plugin/bungeecord/SubServers%202)<br>
> [https://bstats.org/plugin/other/SubServers_Host](https://bstats.org/plugin/other/SubServers%20Host)<br>
> [https://bstats.org/plugin/bungeecord/SubServers_Sync](https://bstats.org/plugin/bungeecord/SubServers%20Sync)<br>
> [https://bstats.org/plugin/velocity/SubServers_Sync](https://bstats.org/plugin/velocity/SubServers%20Sync)<br>
> [https://bstats.org/plugin/bungeecord/SubServers_Console](https://bstats.org/plugin/bungeecord/SubServers%20Console)<br>
> [https://bstats.org/plugin/bukkit/SubServers_Client](https://bstats.org/plugin/bukkit/SubServers%20Client)<br>
> [https://bstats.org/plugin/sponge/SubServers_Client](https://bstats.org/plugin/sponge/SubServers%20Client)

View File

@ -7,13 +7,17 @@ import net.ME1312.Galaxi.Library.Container.Value;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.Galaxi.Library.Map.ObjectMapValue;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubData.Server.SubDataClient;
import net.ME1312.SubServers.Bungee.Event.*;
import net.ME1312.SubServers.Bungee.Host.*;
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExEditServer;
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExControlServer;
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExControlServer.Action;
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExEditServer;
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExEditServer.Edit;
import net.ME1312.SubServers.Bungee.SubAPI;
import net.md_5.bungee.BungeeServerInfo;
import net.md_5.bungee.api.ChatColor;
import java.io.IOException;
@ -111,7 +115,7 @@ public class ExternalSubServer extends SubServerImpl {
if (!event.isCancelled()) {
Logger.get("SubServers").info("Now starting " + getName());
started(null);
host.queue(new PacketExEditServer(this, PacketExEditServer.UpdateType.START, logger.getExternalAddress().toString()));
host.queue(new PacketExControlServer(this, Action.START, logger.getExternalAddress().toString()));
return true;
} else {
lock = false;
@ -126,7 +130,7 @@ public class ExternalSubServer extends SubServerImpl {
lock = false;
logger.start();
if (address != null) {
if (address != logger.getExternalAddress()) host.queue(new PacketExEditServer(this, PacketExEditServer.UpdateType.SET_LOGGING_ADDRESS, logger.getExternalAddress().toString()));
if (address != logger.getExternalAddress()) host.queue(new PacketExControlServer(this, Action.SET_LOGGING_ADDRESS, logger.getExternalAddress().toString()));
host.plugin.getPluginManager().callEvent(new SubStartEvent(null, this));
}
}
@ -144,7 +148,7 @@ public class ExternalSubServer extends SubServerImpl {
host.plugin.getPluginManager().callEvent(event);
if (!event.isCancelled()) {
history.add(new LoggedCommand(player, stopcmd));
host.queue(new PacketExEditServer(this, PacketExEditServer.UpdateType.STOP));
host.queue(new PacketExControlServer(this, Action.STOP));
return true;
} else return false;
} else return false;
@ -197,7 +201,7 @@ public class ExternalSubServer extends SubServerImpl {
SubStopEvent event = new SubStopEvent(player, this, true);
host.plugin.getPluginManager().callEvent(event);
if (!event.isCancelled()) {
host.queue(new PacketExEditServer(this, PacketExEditServer.UpdateType.TERMINATE));
host.queue(new PacketExControlServer(this, Action.TERMINATE));
return true;
} else return false;
} else return false;
@ -212,9 +216,9 @@ public class ExternalSubServer extends SubServerImpl {
if (!event.isCancelled() && (player == null || !DISALLOWED_COMMANDS.matcher(command).find())) {
history.add(new LoggedCommand(player, event.getCommand()));
if (event.getCommand().equalsIgnoreCase(stopcmd)) {
host.queue(new PacketExEditServer(this, PacketExEditServer.UpdateType.STOP));
host.queue(new PacketExControlServer(this, Action.STOP));
} else {
host.queue(new PacketExEditServer(this, PacketExEditServer.UpdateType.COMMAND, event.getCommand()));
host.queue(new PacketExControlServer(this, Action.COMMAND, event.getCommand()));
}
return true;
} else return false;
@ -258,14 +262,7 @@ public class ExternalSubServer extends SubServerImpl {
break;
case "display":
if (value.isString()) {
Field f = ServerImpl.class.getDeclaredField("nick");
f.setAccessible(true);
if (value.isNull() || value.asString().length() == 0 || getName().equals(value.asString())) {
f.set(this, null);
} else {
f.set(this, value.asString());
}
f.setAccessible(false);
setDisplayName(value.asRawString());
logger.name = getDisplayName();
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
if (getName().equals(getDisplayName())) {
@ -280,7 +277,7 @@ public class ExternalSubServer extends SubServerImpl {
break;
case "enabled":
if (value.isBoolean()) {
if (enabled != value.asBoolean()) host.queue(new PacketExEditServer(this, PacketExEditServer.UpdateType.SET_ENABLED, (Boolean) value.asBoolean()));
if (enabled != value.asBoolean()) host.queue(new PacketExControlServer(this, Action.SET_ENABLED, (Boolean) value.asBoolean()));
enabled = value.asBoolean();
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Enabled", isEnabled());
@ -349,7 +346,7 @@ public class ExternalSubServer extends SubServerImpl {
break;
case "log":
if (value.isBoolean()) {
if (log.value() != value.asBoolean()) host.queue(new PacketExEditServer(this, PacketExEditServer.UpdateType.SET_LOGGING, (Boolean) value.asBoolean()));
if (log.value() != value.asBoolean()) host.queue(new PacketExControlServer(this, Action.SET_LOGGING, (Boolean) value.asBoolean()));
log.value(value.asBoolean());
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Log", isLogging());
@ -396,7 +393,7 @@ public class ExternalSubServer extends SubServerImpl {
case "stop-cmd":
case "stop-command":
if (value.isString()) {
if (!stopcmd.equals(value)) host.queue(new PacketExEditServer(this, PacketExEditServer.UpdateType.SET_STOP_COMMAND, value.asRawString()));
if (!stopcmd.equals(value)) host.queue(new PacketExControlServer(this, Action.SET_STOP_COMMAND, value.asRawString()));
stopcmd = value.asRawString();
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Stop-Command", getStopCommand());
@ -465,6 +462,9 @@ public class ExternalSubServer extends SubServerImpl {
case "whitelist":
if (value.isList()) {
Util.reflect(ServerImpl.class.getDeclaredField("whitelist"), this, value.asUUIDList());
if (isRegistered()) for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.WHITELIST_SET, value.asUUIDList()));
}
c++;
}
break;
@ -534,7 +534,7 @@ public class ExternalSubServer extends SubServerImpl {
@Override
public void setEnabled(boolean value) {
if (Util.isNull(value)) throw new NullPointerException();
if (enabled != value) host.queue(new PacketExEditServer(this, PacketExEditServer.UpdateType.SET_ENABLED, (Boolean) value));
if (enabled != value) host.queue(new PacketExControlServer(this, Action.SET_ENABLED, (Boolean) value));
enabled = value;
}
@ -546,7 +546,7 @@ public class ExternalSubServer extends SubServerImpl {
@Override
public void setLogging(boolean value) {
if (Util.isNull(value)) throw new NullPointerException();
if (log.value() != value) host.queue(new PacketExEditServer(this, PacketExEditServer.UpdateType.SET_LOGGING, (Boolean) value));
if (log.value() != value) host.queue(new PacketExControlServer(this, Action.SET_LOGGING, (Boolean) value));
log.value(value);
}
@ -578,7 +578,7 @@ public class ExternalSubServer extends SubServerImpl {
@Override
public void setStopCommand(String value) {
if (Util.isNull(value)) throw new NullPointerException();
if (!stopcmd.equals(value)) host.queue(new PacketExEditServer(this, PacketExEditServer.UpdateType.SET_STOP_COMMAND, value));
if (!stopcmd.equals(value)) host.queue(new PacketExControlServer(this, Action.SET_STOP_COMMAND, value));
stopcmd = value;
}

View File

@ -602,7 +602,6 @@ public class InternalSubCreator extends SubCreator {
if (installed) {
YAMLSection config = new YAMLSection();
FileWriter writer = new FileWriter(new UniversalFile(dir, "subdata.json"), false);
config.set("Name", name);
config.setAll(getSubData());
writer.write(config.toJSON().toString());
writer.close();

View File

@ -8,10 +8,14 @@ import net.ME1312.Galaxi.Library.Map.ObjectMapValue;
import net.ME1312.Galaxi.Library.UniversalFile;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.Galaxi.Library.Version.Version;
import net.ME1312.SubData.Server.SubDataClient;
import net.ME1312.SubServers.Bungee.Event.*;
import net.ME1312.SubServers.Bungee.Host.*;
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExEditServer;
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExEditServer.Edit;
import net.ME1312.SubServers.Bungee.SubAPI;
import net.ME1312.SubServers.Bungee.SubProxy;
import net.md_5.bungee.BungeeServerInfo;
@ -330,14 +334,7 @@ public class InternalSubServer extends SubServerImpl {
break;
case "display":
if (value.isString()) {
Field f = ServerImpl.class.getDeclaredField("nick");
f.setAccessible(true);
if (value.isNull() || value.asString().length() == 0 || getName().equals(value.asString())) {
f.set(this, null);
} else {
f.set(this, value.asString());
}
f.setAccessible(false);
setDisplayName(value.asRawString());
logger.name = getDisplayName();
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
if (getName().equals(getDisplayName())) {
@ -533,6 +530,9 @@ public class InternalSubServer extends SubServerImpl {
case "whitelist":
if (value.isList()) {
Util.reflect(ServerImpl.class.getDeclaredField("whitelist"), this, value.asUUIDList());
if (isRegistered()) for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.WHITELIST_SET, value.asUUIDList()));
}
c++;
}
break;

View File

@ -23,20 +23,14 @@ public class Proxy implements ClientHandler, ExtraDataHandler {
private HashMap<Integer, SubDataClient> subdata = new HashMap<Integer, SubDataClient>();
private ObjectMap<String> extra = new ObjectMap<String>();
private final String signature;
private boolean persistent;
private boolean persistent = false;
private String nick = null;
private final String name;
public Proxy(String name) throws IllegalArgumentException {
this(name, name != null);
}
@SuppressWarnings("deprecation")
public Proxy(String name, boolean persistent) throws IllegalArgumentException {
if (name == null) name = Util.getNew(SubAPI.getInstance().getInternals().proxies.keySet(), () -> UUID.randomUUID().toString());
if (name.contains(" ")) throw new IllegalArgumentException("Proxy names cannot have spaces: " + name);
this.name = name;
this.persistent = persistent;
this.signature = SubAPI.getInstance().signAnonymousObject();
subdata.put(0, null);
@ -146,6 +140,13 @@ public class Proxy implements ClientHandler, ExtraDataHandler {
return players;
}
/**
* Makes it so the proxy object will still exist within the server manager even if it is disconnected
*/
public final void persist() {
persistent = true;
}
/**
* Get the Signature of this Object
*

View File

@ -136,6 +136,11 @@ public interface Server extends ServerInfo, ClientHandler, ExtraDataHandler {
*/
void unwhitelist(UUID player);
/**
* Makes it so the server object will still exist within the server manager even if it is disconnected
*/
void persist();
/**
* Get the Signature of this Object
*

View File

@ -1,21 +1,19 @@
package net.ME1312.SubServers.Bungee.Host;
import net.ME1312.Galaxi.Library.Container.ContainedPair;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.Galaxi.Library.Map.ObjectMapValue;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubData.Server.DataClient;
import net.ME1312.SubData.Server.SubDataClient;
import net.ME1312.SubServers.Bungee.Event.SubEditServerEvent;
import net.ME1312.SubServers.Bungee.Event.SubNetworkConnectEvent;
import net.ME1312.SubServers.Bungee.Event.SubNetworkDisconnectEvent;
import net.ME1312.SubServers.Bungee.Event.SubRemoveProxyEvent;
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExRunEvent;
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExUpdateWhitelist;
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExEditServer;
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExEditServer.Edit;
import net.ME1312.SubServers.Bungee.SubAPI;
import net.md_5.bungee.BungeeServerInfo;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.net.InetSocketAddress;
@ -33,6 +31,7 @@ public class ServerImpl extends BungeeServerInfo implements Server {
private List<UUID> whitelist = new ArrayList<UUID>();
private boolean hidden;
private final String signature = SubAPI.getInstance().signAnonymousObject();
private volatile boolean persistent = true;
/**
* Construct a new Server data type
@ -80,6 +79,16 @@ public class ServerImpl extends BungeeServerInfo implements Server {
subdata.put(0, null);
}
/**
* Get if this server has been registered
*
* @return Registered status
*/
@SuppressWarnings("deprecation")
protected boolean isRegistered() {
return SubAPI.getInstance().getInternals().exServers.containsKey(getName().toLowerCase());
}
@Override
public DataClient[] getSubData() {
Integer[] keys = subdata.keySet().toArray(new Integer[0]);
@ -103,12 +112,20 @@ public class ServerImpl extends BungeeServerInfo implements Server {
subdata.remove(channel);
}
if (update) for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
ObjectMap<String> args = new ObjectMap<String>();
args.set("server", getName());
args.set("channel", channel);
if (client != null) args.set("id", client.getID());
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExRunEvent((client != null)?SubNetworkConnectEvent.class:SubNetworkDisconnectEvent.class, args));
if (update) {
for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
if (client != null) {
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.CONNECTED, channel, client.getID()));
} else {
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.DISCONNECTED, channel));
}
}
if (!persistent) {
DataClient[] subdata = getSubData();
if (subdata[0] == null && subdata.length <= 1) {
SubAPI.getInstance().removeServer(getName());
}
}
}
}
@ -130,6 +147,9 @@ public class ServerImpl extends BungeeServerInfo implements Server {
} else {
this.nick = value;
}
for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.DISPLAY_NAME, getDisplayName()));
}
}
@Override
@ -167,14 +187,19 @@ public class ServerImpl extends BungeeServerInfo implements Server {
@Override
public void setHidden(boolean value) {
if (Util.isNull(value)) throw new NullPointerException();
this.hidden = value;
if (isRegistered()) for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.HIDDEN, isHidden()));
}
}
public void setMotd(String value) {
if (Util.isNull(value)) throw new NullPointerException();
try {
Util.reflect(BungeeServerInfo.class.getDeclaredField("motd"), this, value);
for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.MOTD, getMotd()));
}
} catch (Exception e) {
e.printStackTrace();
}
@ -184,6 +209,10 @@ public class ServerImpl extends BungeeServerInfo implements Server {
if (Util.isNull(value)) throw new NullPointerException();
try {
Util.reflect(BungeeServerInfo.class.getDeclaredField("restricted"), this, value);
if (isRegistered()) for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.RESTRICTED, isRestricted()));
}
} catch (Exception e) {
e.printStackTrace();
}
@ -197,7 +226,7 @@ public class ServerImpl extends BungeeServerInfo implements Server {
*/
@Override
public boolean canAccess(CommandSender player) {
return (player instanceof ProxiedPlayer && whitelist.contains(((ProxiedPlayer) player).getUniqueId())) || super.canAccess(player);
return super.canAccess(player) || (player instanceof ProxiedPlayer && whitelist.contains(((ProxiedPlayer) player).getUniqueId()));
}
@Override
@ -214,14 +243,23 @@ public class ServerImpl extends BungeeServerInfo implements Server {
public void whitelist(UUID player) {
if (Util.isNull(player)) throw new NullPointerException();
if (!whitelist.contains(player)) whitelist.add(player);
for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) ((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExUpdateWhitelist(getName(), true, player));
if (isRegistered()) for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.WHITELIST_ADD, player));
}
}
@Override
public void unwhitelist(UUID player) {
if (Util.isNull(player)) throw new NullPointerException();
whitelist.remove(player);
for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) ((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExUpdateWhitelist(getName(), false, player));
if (isRegistered()) for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.WHITELIST_REMOVE, player));
}
}
@Override
public final void persist() {
persistent = true;
}
@Override

View File

@ -98,6 +98,11 @@ public abstract class SubServerImpl extends ServerImpl implements SubServer {
return -1;
}
@Override
protected final boolean isRegistered() {
return registered;
}
@Override
public boolean isAvailable() {
return registered && !updating && getHost().isAvailable();

View File

@ -138,6 +138,11 @@ public class ConfigUpdater {
existing = updated.clone();
i++;
} else if (was.compareTo(new Version("21w27b")) <= 0) {
//existing = updated.clone();
i++;
}// if (was.compareTo(new Version("99w99a")) <= 0) {
// // do something
// existing = updated.clone();
@ -151,6 +156,7 @@ public class ConfigUpdater {
YAMLSection settings = new YAMLSection();
settings.set("Version", ((now.compareTo(was) <= 0)?was:now).toString());
if (updated.getMap("Settings", new YAMLSection()).contains("RPEC-Check-Interval")) settings.set("RPEC-Check-Interval", updated.getMap("Settings").getRawString("RPEC-Check-Interval"));
settings.set("Strict-Server-Linking", updated.getMap("Settings", new YAMLSection()).getBoolean("Strict-Server-Linking", true));
settings.set("Disabled-Overrides", updated.getMap("Settings", new YAMLSection()).getRawStringList("Disabled-Overrides", Collections.emptyList()));
YAMLSection smart_fallback = new YAMLSection();
@ -318,7 +324,7 @@ public class ConfigUpdater {
existing = updated.clone();
i++;
} if (was.compareTo(new Version("21w27a")) <= 0) {
} if (was.compareTo(new Version("21w27b")) <= 0) {
//existing = updated.clone();
i++;
@ -339,6 +345,7 @@ public class ConfigUpdater {
LinkedHashMap<String, String> def = new LinkedHashMap<String, String>();
def.put("Bungee.Feature.Smart-Fallback", "&6Returning from $str$: &r$msg$");
def.put("Bungee.Feature.Smart-Fallback.Result", "&6You are now on $str$.");
def.put("Bungee.Restricted", "&cYou don't have permission to access this server.");
def.put("Bungee.Ping.Offline", "&6&l[&e&lWarning&6&l] &7Backend server(s) are not running");
def.put("Bungee.Server.Current", "&6You are currently connected to $str$");
def.put("Bungee.Server.Available", "&6You may connect to the following servers at this time:");

View File

@ -12,15 +12,15 @@ import net.ME1312.SubServers.Bungee.SubProxy;
import java.util.Arrays;
/**
* Edit External Server Packet
* Control External Server Packet
*/
public class PacketExEditServer implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
public class PacketExControlServer implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
private SubProxy plugin;
private SubServer server;
private UpdateType type;
private Action type;
private Object[] args;
public enum UpdateType {
public enum Action {
// Actions
START(1, String.class),
COMMAND(2, String.class),
@ -35,7 +35,7 @@ public class PacketExEditServer implements PacketObjectIn<Integer>, PacketObject
private short value;
private Class<?>[] args;
UpdateType(int value, Class<?>... args) {
Action(int value, Class<?>... args) {
this.value = (short) value;
this.args = args;
}
@ -50,30 +50,31 @@ public class PacketExEditServer implements PacketObjectIn<Integer>, PacketObject
}
/**
* New PacketExEditServer (In)
* New PacketExControlServer (In)
* @param plugin SubPlugin
*/
public PacketExEditServer(SubProxy plugin) {
public PacketExControlServer(SubProxy plugin) {
this.plugin = plugin;
}
/**
* New PacketExEditServer (Out)
* New PacketExControlServer (Out)
*
* @param server SubServer
* @param type Update Type
* @param arguments Arguments
*/
public PacketExEditServer(SubServer server, UpdateType type, Object... arguments) {
if (arguments.length != type.getArguments().length) throw new IllegalArgumentException(((arguments.length > type.getArguments().length)?"Too many":"Not enough") + " arguments for type: " + type.toString());
int i = 0;
while (i < arguments.length) {
if (!type.getArguments()[i].isInstance(arguments[i])) throw new IllegalArgumentException("Argument " + (i+1) + " is not " + type.getArguments()[i].getCanonicalName());
i++;
}
public PacketExControlServer(SubServer server, Action type, Object... arguments) {
if (arguments.length < type.getArguments().length) throw new IllegalArgumentException("Not enough arguments for type: " + type);
this.server = server;
this.type = type;
this.args = arguments;
this.args = new Object[type.getArguments().length];
for (int i = 0; i < type.getArguments().length; ++i) {
if (!type.getArguments()[i].isInstance(arguments[i])) throw new IllegalArgumentException("Argument " + (i+1) + " is not " + type.getArguments()[i].getCanonicalName());
args[i] = arguments[i];
}
}
@Override

View File

@ -13,6 +13,7 @@ import net.ME1312.SubServers.Bungee.Host.ServerImpl;
import net.ME1312.SubServers.Bungee.Host.SubServer;
import net.ME1312.SubServers.Bungee.Host.SubServerImpl;
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
import net.ME1312.SubServers.Bungee.SubAPI;
import net.ME1312.SubServers.Bungee.SubProxy;
import net.md_5.bungee.api.ProxyServer;
@ -25,6 +26,7 @@ import java.util.concurrent.TimeUnit;
* Link Server Packet
*/
public class PacketLinkServer implements InitialPacket, PacketObjectIn<Integer>, PacketObjectOut<Integer> {
public static boolean strict = true;
private SubProxy plugin;
private int response;
private String message;
@ -72,19 +74,28 @@ public class PacketLinkServer implements InitialPacket, PacketObjectIn<Integer>,
@Override
public void receive(SubDataClient client, ObjectMap<Integer> data) {
String name = (data.contains(0x0000))?data.getRawString(0x0000):null;
Integer port = (data.contains(0x0001))?data.getInt(0x0001):null;
Integer channel = data.getInt(0x0002);
InetSocketAddress address;
try {
if (!data.contains(0x0001)) {
address = null;
} else if (data.isNumber(0x0001)) {
address = new InetSocketAddress(client.getAddress().getAddress(), data.getInt(0x0001));
} else {
String[] sa = data.getRawString(0x0001).split(":");
address = new InetSocketAddress(sa[0], Integer.parseInt(sa[1]));
}
Map<String, Server> servers = plugin.api.getServers();
Server server;
if (name != null && servers.keySet().contains(name.toLowerCase())) {
link(client, servers.get(name.toLowerCase()), channel);
} else if (port != null) {
if ((server = search(new InetSocketAddress(client.getAddress().getAddress(), port))) != null) {
link(client, server, channel);
link(client, name, address, servers.get(name.toLowerCase()), channel);
} else if (address != null) {
if ((server = search(address)) != null || !strict) {
link(client, name, address, server, channel);
} else {
throw new ServerLinkException("There is no server with address: " + client.getAddress().getAddress().getHostAddress() + ':' + port);
throw new ServerLinkException("There is no server with address: " + address.getAddress().getHostAddress() + ':' + address.getPort());
}
} else {
throw new ServerLinkException("Not enough arguments");
@ -101,9 +112,18 @@ public class PacketLinkServer implements InitialPacket, PacketObjectIn<Integer>,
}
}
static int req = 1;
static long req = 1;
static long last = Calendar.getInstance().getTime().getTime();
private void link(SubDataClient client, Server server, int channel) throws Throwable {
private void link(SubDataClient client, String name, InetSocketAddress address, Server resolved, int channel) throws Throwable {
final Server server;
if (resolved == null) {
String id = (name == null)? Util.getNew(SubAPI.getInstance().getServers().keySet(), () -> UUID.randomUUID().toString()) : name;
server = SubAPI.getInstance().addServer(id, address.getAddress(), address.getPort(), "Some Dynamic Server", name == null, false);
Util.reflect(ServerImpl.class.getDeclaredField("persistent"), server, false);
} else {
server = resolved;
}
HashMap<Integer, SubDataClient> subdata = Util.getDespiteException(() -> Util.reflect(ServerImpl.class.getDeclaredField("subdata"), server), null);
if (!subdata.keySet().contains(channel) || (channel == 0 && subdata.get(0) == null)) {
server.setSubData(client, channel);

View File

@ -0,0 +1,95 @@
package net.ME1312.SubServers.Bungee.Network.Packet;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
import net.ME1312.SubData.Server.SubDataClient;
import net.ME1312.SubServers.Bungee.Host.Server;
import net.ME1312.SubServers.Bungee.SubProxy;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
/**
* External Server Edit Notification Packet
*/
public class PacketOutExEditServer implements PacketObjectOut<Integer> {
private SubProxy plugin;
private Server server;
private Edit type;
private Object[] args;
public enum Edit {
// Generic
DISPLAY_NAME(0, String.class),
MOTD(1, String.class),
RESTRICTED(2, Boolean.class),
HIDDEN(3, Boolean.class),
// SubData
CONNECTED(4, Integer.class, UUID.class),
DISCONNECTED(5, Integer.class),
// Whitelist
WHITELIST_SET(6, List.class),
WHITELIST_ADD(7, UUID.class),
WHITELIST_REMOVE(8, UUID.class);
private short value;
private Class<?>[] args;
Edit(int value, Class<?>... args) {
this.value = (short) value;
this.args = args;
}
public Class<?>[] getArguments() {
return args;
}
public short getValue() {
return value;
}
}
/**
* New PacketExEditServer (In)
* @param plugin SubPlugin
*/
public PacketOutExEditServer(SubProxy plugin) {
this.plugin = plugin;
}
/**
* New PacketExEditServer (Out)
*
* @param server SubServer
* @param type Update Type
* @param arguments Arguments
*/
public PacketOutExEditServer(Server server, Edit type, Object... arguments) {
if (arguments.length < type.getArguments().length) throw new IllegalArgumentException("Not enough arguments for type: " + type);
this.server = server;
this.type = type;
this.args = new Object[type.getArguments().length];
for (int i = 0; i < type.getArguments().length; ++i) {
if (!type.getArguments()[i].isInstance(arguments[i])) throw new IllegalArgumentException("Argument " + (i+1) + " is not " + type.getArguments()[i].getCanonicalName());
args[i] = arguments[i];
}
}
@Override
public ObjectMap<Integer> send(SubDataClient client) {
ObjectMap<Integer> data = new ObjectMap<Integer>();
data.set(0x0000, server.getName());
data.set(0x0001, type.getValue());
data.set(0x0002, Arrays.asList(args));
return data;
}
@Override
public int version() {
return 0x0002;
}
}

View File

@ -1,45 +0,0 @@
package net.ME1312.SubServers.Bungee.Network.Packet;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
import net.ME1312.SubData.Server.SubDataClient;
import java.util.UUID;
/**
* Update External Whitelist Packet
*/
public class PacketOutExUpdateWhitelist implements PacketObjectOut<Integer> {
private String name;
private boolean mode;
private UUID value;
/**
* New PacketOutExUpdateWhitelist
*
* @param name Server Name
* @param mode Update Mode (true for add, false for remove)
* @param value Whitelist Value
*/
public PacketOutExUpdateWhitelist(String name, boolean mode, UUID value) {
if (Util.isNull(name, mode, value)) throw new NullPointerException();
this.name = name;
this.mode = mode;
this.value = value;
}
@Override
public ObjectMap<Integer> send(SubDataClient client) {
ObjectMap<Integer> data = new ObjectMap<Integer>();
data.set(0x0000, name);
data.set(0x0001, mode);
data.set(0x0002, value);
return data;
}
@Override
public int version() {
return 0x0001;
}
}

View File

@ -101,7 +101,7 @@ public class SubProtocol extends SubDataProtocol {
//registerPacket(0x0053, PacketInExRequestQueue.class);
registerPacket(0x0054, PacketExCreateServer.class);
registerPacket(0x0055, PacketExAddServer.class);
registerPacket(0x0056, PacketExEditServer.class);
registerPacket(0x0056, PacketExControlServer.class);
//registerPacket(0x0057, PacketInExLogMessage.class);
registerPacket(0x0058, PacketExRemoveServer.class);
registerPacket(0x0059, PacketExDeleteServer.class);
@ -113,7 +113,7 @@ public class SubProtocol extends SubDataProtocol {
registerPacket(0x0053, new PacketInExRequestQueue(plugin));
registerPacket(0x0054, new PacketExCreateServer(null));
registerPacket(0x0055, new PacketExAddServer());
registerPacket(0x0056, new PacketExEditServer(plugin));
registerPacket(0x0056, new PacketExControlServer(plugin));
registerPacket(0x0057, new PacketInExLogMessage());
registerPacket(0x0058, new PacketExRemoveServer());
registerPacket(0x0059, new PacketExDeleteServer());
@ -124,7 +124,7 @@ public class SubProtocol extends SubDataProtocol {
registerPacket(0x0070, PacketOutExRunEvent.class);
registerPacket(0x0071, PacketOutExReset.class);
registerPacket(0x0072, PacketOutExReload.class);
registerPacket(0x0073, PacketOutExUpdateWhitelist.class);
registerPacket(0x0073, PacketOutExEditServer.class);
registerPacket(0x0074, PacketExSyncPlayer.class);
registerPacket(0x0075, PacketExTransferPlayer.class);
registerPacket(0x0076, PacketExDisconnectPlayer.class);

View File

@ -266,7 +266,7 @@ public final class SubAPI implements BungeeAPI {
if (Util.isNull(name, getHost(name))) throw new NullPointerException();
SubRemoveHostEvent event = new SubRemoveHostEvent(player, getHost(name));
plugin.getPluginManager().callEvent(event);
if (event.isCancelled()) {
if (!event.isCancelled()) {
if (getHost(name).destroy()) {
plugin.hosts.remove(name.toLowerCase());
return true;
@ -466,7 +466,7 @@ public final class SubAPI implements BungeeAPI {
if (Util.isNull(name, getServer(name))) throw new NullPointerException();
SubRemoveServerEvent event = new SubRemoveServerEvent(player, null, getServer(name));
plugin.getPluginManager().callEvent(event);
if (event.isCancelled()) {
if (!event.isCancelled()) {
plugin.exServers.remove(name.toLowerCase());
return true;
} else return false;

View File

@ -26,6 +26,7 @@ import net.ME1312.SubServers.Bungee.Library.Fallback.SmartFallback;
import net.ME1312.SubServers.Bungee.Library.Metrics;
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExDisconnectPlayer;
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExSyncPlayer;
import net.ME1312.SubServers.Bungee.Network.Packet.PacketLinkServer;
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExReload;
import net.ME1312.SubServers.Bungee.Network.SubProtocol;
@ -365,6 +366,7 @@ public final class SubProxy extends BungeeCommon implements Listener {
Util.isException(subdata::waitFor);
}
PacketLinkServer.strict = config.get().getMap("Settings").getBoolean("Strict-Server-Linking", true);
SmartFallback.dns_forward = config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>()).getBoolean("DNS-Forward", false);
int hosts = 0;
@ -937,14 +939,14 @@ public final class SubProxy extends BungeeCommon implements Listener {
if ((dynamic = SmartFallback.getForcedHost(e.getConnection()) == null) && getReconnectHandler() instanceof SmartFallback && (override = SmartFallback.getDNS(e.getConnection())) != null) {
if (!(override instanceof SubServer) || ((SubServer) override).isRunning()) {
if (!e.getConnection().getListener().isPingPassthrough()) {
e.setResponse(new ServerPing(e.getResponse().getVersion(), e.getResponse().getPlayers(), new TextComponent(override.getMotd()), null));
e.setResponse(new ServerPing(e.getResponse().getVersion(), e.getResponse().getPlayers(), new TextComponent(override.getMotd()), e.getResponse().getFaviconObject()));
} else {
Container<Boolean> lock = new Container<>(true);
boolean mode = plugin != null;
if (mode) e.registerIntent(plugin);
((BungeeServerInfo) override).ping((ping, error) -> {
if (error != null) {
e.setResponse(new ServerPing(e.getResponse().getVersion(), e.getResponse().getPlayers(), new TextComponent(getTranslation("ping_cannot_connect")), null));
e.setResponse(new ServerPing(e.getResponse().getVersion(), e.getResponse().getPlayers(), new TextComponent(getTranslation("ping_cannot_connect")), e.getResponse().getFaviconObject()));
} else e.setResponse(ping);
lock.value = false;
if (mode) e.completeIntent(plugin);
@ -962,7 +964,7 @@ public final class SubProxy extends BungeeCommon implements Listener {
ServerInfo override;
if ((override = SmartFallback.getForcedHost(e.getConnection())) != null || (override = SmartFallback.getDNS(e.getConnection())) != null) {
if (override instanceof SubServer && !((SubServer) override).isRunning()) {
e.setResponse(new ServerPing(e.getResponse().getVersion(), e.getResponse().getPlayers(), new TextComponent(api.getLang("SubServers", "Bungee.Ping.Offline")), null));
e.setResponse(new ServerPing(e.getResponse().getVersion(), e.getResponse().getPlayers(), new TextComponent(api.getLang("SubServers", "Bungee.Ping.Offline")), e.getResponse().getFaviconObject()));
}
} else {
int offline = 0;
@ -973,7 +975,7 @@ public final class SubProxy extends BungeeCommon implements Listener {
}
if (offline >= e.getConnection().getListener().getServerPriority().size()) {
e.setResponse(new ServerPing(e.getResponse().getVersion(), e.getResponse().getPlayers(), new TextComponent(api.getLang("SubServers", "Bungee.Ping.Offline")), null));
e.setResponse(new ServerPing(e.getResponse().getVersion(), e.getResponse().getPlayers(), new TextComponent(api.getLang("SubServers", "Bungee.Ping.Offline")), e.getResponse().getFaviconObject()));
}
}
}
@ -1010,14 +1012,14 @@ public final class SubProxy extends BungeeCommon implements Listener {
if (e.getPlayer().getServer() == null || fallback.containsKey(e.getPlayer().getUniqueId())) {
if (!fallback.containsKey(e.getPlayer().getUniqueId()) || fallback.get(e.getPlayer().getUniqueId()).names.contains(e.getTarget().getName())) {
ServerKickEvent kick = new ServerKickEvent(e.getPlayer(), e.getTarget(), new BaseComponent[]{
new TextComponent(getTranslation("no_server_permission"))
new TextComponent(api.getLang("SubServers", "Bungee.Restricted"))
}, null, ServerKickEvent.State.CONNECTING);
fallback(kick);
if (!kick.isCancelled()) e.getPlayer().disconnect(kick.getKickReasonComponent());
if (e.getPlayer().getServer() != null) e.setCancelled(true);
}
} else {
e.getPlayer().sendMessage(getTranslation("no_server_permission"));
e.getPlayer().sendMessage(api.getLang("SubServers", "Bungee.Restricted"));
e.setCancelled(true);
}
} else if (e.getPlayer().getServer() != null && !fallback.containsKey(e.getPlayer().getUniqueId()) && e.getTarget() instanceof SubServer && !((SubServer) e.getTarget()).isRunning()) {
@ -1088,9 +1090,6 @@ public final class SubProxy extends BungeeCommon implements Listener {
if (init) fallback.put(e.getPlayer().getUniqueId(), state);
e.setCancelServer(state.servers.getFirst());
if (Util.isException(() -> ServerKickEvent.class.getMethod("setCancelServers", ServerInfo[].class).invoke(e, (Object) state.servers.toArray(new ServerInfo[0])))) {
((UserConnection) e.getPlayer()).setServerJoinQueue(new LinkedList<>(state.names));
}
}
}
}

View File

@ -53,7 +53,7 @@ public class DefaultUIHandler implements UIHandler, Listener {
}
public DefaultUIRenderer getRenderer(Player player) {
if (!gui.keySet().contains(player.getUniqueId())) gui.put(player.getUniqueId(), new DefaultUIRenderer(plugin, player.getUniqueId()));
if (!gui.containsKey(player.getUniqueId())) gui.put(player.getUniqueId(), new DefaultUIRenderer(plugin, player.getUniqueId()));
return gui.get(player.getUniqueId());
}
@ -64,7 +64,7 @@ public class DefaultUIHandler implements UIHandler, Listener {
@EventHandler(priority = EventPriority.HIGHEST)
public void click(InventoryClickEvent event) {
Player player = (Player) event.getWhoClicked();
if (!event.isCancelled() && enabled && gui.keySet().contains(player.getUniqueId())) {
if (!event.isCancelled() && enabled && gui.containsKey(player.getUniqueId())) {
DefaultUIRenderer gui = this.gui.get(player.getUniqueId());
String title = event.getView().getTitle();
@ -463,7 +463,7 @@ public class DefaultUIHandler implements UIHandler, Listener {
@SuppressWarnings("deprecation")
@EventHandler(priority = EventPriority.LOWEST)
public void input(org.bukkit.event.player.PlayerChatEvent event) {
if (!event.isCancelled() && enabled && input.keySet().contains(event.getPlayer().getUniqueId())) {
if (!event.isCancelled() && enabled && input.containsKey(event.getPlayer().getUniqueId())) {
YAMLSection data = new YAMLSection();
data.set("message", event.getMessage());
input.get(event.getPlayer().getUniqueId()).run(data);
@ -479,7 +479,7 @@ public class DefaultUIHandler implements UIHandler, Listener {
*/
@EventHandler(priority = EventPriority.LOWEST)
public void input(PlayerCommandPreprocessEvent event) {
if (!event.isCancelled() && enabled && input.keySet().contains(event.getPlayer().getUniqueId())) {
if (!event.isCancelled() && enabled && input.containsKey(event.getPlayer().getUniqueId())) {
YAMLSection data = new YAMLSection();
data.set("message", (event.getMessage().startsWith("/"))?event.getMessage().substring(1):event.getMessage());
input.get(event.getPlayer().getUniqueId()).run(data);

View File

@ -227,42 +227,43 @@ public abstract class UIRenderer {
* @param subtitle Subtitle to display (or null to hide)
*/
public void setDownloading(String subtitle) {
final String text = subtitle;
if (subtitle != null) {
if (!canSendTitle()) {
final String text = subtitle;
if (download != -1) Bukkit.getScheduler().cancelTask(download);
download = Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, () -> {
if (tdownload != null) Bukkit.getPlayer(player).sendMessage(plugin.api.getLang("SubServers", "Interface.Generic.Downloading").replace("$str$", text));
download = -1;
}, 50L);
return;
}
if (text != null && !canSendTitle()) {
if (download != -1) Bukkit.getScheduler().cancelTask(download);
download = Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, () -> {
if (tdownload != null) Bukkit.getPlayer(player).sendMessage(plugin.api.getLang("SubServers", "Interface.Generic.Downloading").replace("$str$", text));
download = -1;
}, 50L);
return;
}
if (!subtitle.startsWith(Character.toString(ChatColor.COLOR_CHAR))) {
subtitle = plugin.api.getLang("SubServers", "Interface.Generic.Downloading.Title-Color-Alt") + subtitle;
}
if (tdownload == null) {
tdownload = new ContainedPair<String, Integer>(subtitle, 0);
if (subtitle != null && !subtitle.startsWith(Character.toString(ChatColor.COLOR_CHAR))) {
subtitle = plugin.api.getLang("SubServers", "Interface.Generic.Downloading.Title-Color-Alt") + subtitle;
}
if (subtitle != null && tdownload == null) {
tdownload = new ContainedPair<String, Integer>(subtitle, 0);
new BukkitRunnable() {
@Override
public void run() {
if (tdownload != null) {
if (++tdownload.value >= adownload.length) {
tdownload.value = 0;
}
new BukkitRunnable() {
@Override
public void run() {
if (tdownload != null) {
if (++tdownload.value >= adownload.length) {
tdownload.value = 0;
}
if (!sendTitle(adownload[tdownload.value], tdownload.key, 0, 10, 5)) {
if (!sendTitle(adownload[tdownload.value], tdownload.key, 0, 10, 5)) {
cancel();
}
} else {
sendTitle(null);
cancel();
}
} else {
sendTitle(null);
cancel();
}
}
}.runTaskTimer(plugin, 0, 1);
} else if (subtitle != null) {
tdownload.key = subtitle;
}.runTaskTimer(plugin, 0, 1);
} else {
tdownload.key = subtitle;
}
} else {
if (tdownload != null) {
tdownload = null;

View File

@ -60,7 +60,8 @@ public class ConfigUpdater {
settings.set("Show-Addresses", updated.getMap("Settings", new YAMLSection()).getBoolean("Show-Addresses", false));
settings.set("Use-Title-Messages", updated.getMap("Settings", new YAMLSection()).getBoolean("Use-Title-Messages", true));
settings.set("PlaceholderAPI-Ready", updated.getMap("Settings", new YAMLSection()).getBoolean("PlaceholderAPI-Ready", false));
if (updated.getMap("Settings", new YAMLSection()).contains("PlaceholderAPI-Cache-Interval")) settings.set("PlaceholderAPI-Cache-Interval", updated.getMap("Settings").getRawString("PlaceholderAPI-Cache-Interval"));
if (updated.getMap("Settings", new YAMLSection()).contains("PlaceholderAPI-Cache-Interval")) settings.set("PlaceholderAPI-Cache-Interval", updated.getMap("Settings").getInt("PlaceholderAPI-Cache-Interval"));
if (updated.getMap("Settings", new YAMLSection()).contains("Connect-Address")) settings.set("Connect-Address", updated.getMap("Settings").getRawString("Connect-Address"));
YAMLSection subdata = new YAMLSection();
if (updated.getMap("Settings", new YAMLSection()).getMap("SubData", new YAMLSection()).contains("Name")) subdata.set("Name", updated.getMap("Settings").getMap("SubData").getRawString("Name"));

View File

@ -43,7 +43,15 @@ public class PacketLinkServer implements InitialPacket, PacketObjectIn<Integer>,
public ObjectMap<Integer> send(SubDataSender client) {
ObjectMap<Integer> json = new ObjectMap<Integer>();
if (plugin.api.getName() != null) json.set(0x0000, plugin.api.getName());
json.set(0x0001, Bukkit.getServer().getPort());
String address = plugin.server_address;
if (address != null) {
if (address.indexOf(':') == -1) address += ":" + Bukkit.getServer().getPort();
json.set(0x0001, address);
} else {
json.set(0x0001, Bukkit.getServer().getPort());
}
json.set(0x0002, channel);
return json;
}

View File

@ -49,6 +49,7 @@ public final class SubPlugin extends JavaPlugin {
public UIHandler gui = null;
public final Version version;
public final SubAPI api = new SubAPI(this);
public String server_address;
private long resetDate = 0;
private boolean reconnect = false;
@ -94,6 +95,7 @@ public final class SubPlugin extends JavaPlugin {
subprotocol.registerCipher("DHE-192", DHE.get(192));
subprotocol.registerCipher("DHE-256", DHE.get(256));
api.name = config.get().getMap("Settings").getMap("SubData").getString("Name", System.getenv("name"));
server_address = config.get().getMap("Settings").getRawString("Connect-Address", System.getenv("address"));
if (config.get().getMap("Settings").getMap("SubData").getRawString("Password", "").length() > 0) {
subprotocol.registerCipher("AES", new AES(128, config.get().getMap("Settings").getMap("SubData").getRawString("Password")));

View File

@ -59,6 +59,7 @@ public class ConfigUpdater {
settings.set("Allow-Deletion", updated.getMap("Settings", new YAMLSection()).getBoolean("Allow-Deletion", false));
settings.set("Show-Addresses", updated.getMap("Settings", new YAMLSection()).getBoolean("Show-Addresses", false));
settings.set("Use-Title-Messages", updated.getMap("Settings", new YAMLSection()).getBoolean("Use-Title-Messages", true));
if (updated.getMap("Settings", new YAMLSection()).contains("Connect-Address")) settings.set("Connect-Address", updated.getMap("Settings").getRawString("Connect-Address"));
YAMLSection subdata = new YAMLSection();
if (updated.getMap("Settings", new YAMLSection()).getMap("SubData", new YAMLSection()).contains("Name")) subdata.set("Name", updated.getMap("Settings").getMap("SubData").getRawString("Name"));

View File

@ -44,7 +44,16 @@ public class PacketLinkServer implements InitialPacket, PacketObjectIn<Integer>,
public ObjectMap<Integer> send(SubDataSender client) {
ObjectMap<Integer> json = new ObjectMap<Integer>();
if (plugin.api.getName() != null) json.set(0x0000, plugin.api.getName());
if (plugin.game.getServer().getBoundAddress().isPresent()) json.set(0x0001, plugin.game.getServer().getBoundAddress().get().getPort());
if (plugin.game.getServer().getBoundAddress().isPresent()) {
String address = plugin.server_address;
if (address != null) {
if (address.indexOf(':') == -1) address += ":" + plugin.game.getServer().getBoundAddress().get().getPort();
json.set(0x0001, address);
} else {
json.set(0x0001, plugin.game.getServer().getBoundAddress().get().getPort());
}
}
json.set(0x0002, channel);
return json;
}

View File

@ -62,7 +62,7 @@ public final class SubCommand implements CommandExecutor {
*/
public CommandSpec spec() {
SubCommand root = new SubCommand(plugin);
return CommandSpec.builder()
CommandSpec.Builder spec = CommandSpec.builder()
.description(Text.of("The SubServers Command"))
.executor(root)
.arguments(GenericArguments.optional(GenericArguments.string(Text.of("Command"))), GenericArguments.optional(GenericArguments.remainingJoinedStrings(Text.of("..."))))
@ -121,11 +121,6 @@ public final class SubCommand implements CommandExecutor {
.executor(new UPDATE())
.arguments(GenericArguments.optional(new ListArgument(Text.of("Subservers"))), GenericArguments.optional(GenericArguments.string(Text.of("Template"))), GenericArguments.optional(GenericArguments.string(Text.of("Version"))), GenericArguments.optional(GenericArguments.remainingJoinedStrings(Text.of("..."))))
.build(), "update", "upgrade")
.child(CommandSpec.builder()
.description(Text.of("The SubServers Command - Delete"))
.executor(new DELETE())
.arguments(GenericArguments.optional(new ListArgument(Text.of("Subservers"))), GenericArguments.optional(GenericArguments.remainingJoinedStrings(Text.of("..."))))
.build(), "remove", "del", "delete")
.child(CommandSpec.builder()
.description(Text.of("The SubServers Command - Teleport"))
.executor(new TELEPORT())
@ -135,8 +130,16 @@ public final class SubCommand implements CommandExecutor {
.description(Text.of("The SubServers Command - Open Menu"))
.executor(new OPEN())
.arguments(GenericArguments.optional(GenericArguments.string(Text.of("Menu"))), GenericArguments.optional(GenericArguments.allOf(GenericArguments.string(Text.of("Args")))))
.build(), "open", "view")
.build();
.build(), "open", "view");
if (plugin.config.get().getMap("Settings").getBoolean("Allow-Deletion", false)) spec
.child(CommandSpec.builder()
.description(Text.of("The SubServers Command - Delete"))
.executor(new DELETE())
.arguments(GenericArguments.optional(new ListArgument(Text.of("Subservers"))), GenericArguments.optional(GenericArguments.remainingJoinedStrings(Text.of("..."))))
.build(), "remove", "del", "delete");
return spec.build();
}
private boolean canRun(CommandSource sender) throws CommandException {

View File

@ -63,6 +63,7 @@ public final class SubPlugin {
public UIHandler gui = null;
public Version version;
public SubAPI api;
public String server_address;
@Inject public PluginContainer plugin;
@Inject public Game game;
@ -114,6 +115,7 @@ public final class SubPlugin {
subprotocol.registerCipher("DHE-192", DHE.get(192));
subprotocol.registerCipher("DHE-256", DHE.get(256));
api.name = config.get().getMap("Settings").getMap("SubData").getString("Name", System.getenv("name"));
server_address = config.get().getMap("Settings").getRawString("Connect-Address", System.getenv("address"));
Logger log = LoggerFactory.getLogger("SubData");
if (config.get().getMap("Settings").getMap("SubData").getRawString("Password", "").length() > 0) {

View File

@ -580,7 +580,6 @@ public class SubCreatorImpl {
if (installed) {
YAMLSection config = new YAMLSection();
FileWriter writer = new FileWriter(new UniversalFile(dir, "subdata.json"), false);
config.set("Name", name);
config.setAll(getSubData());
writer.write(config.toJSON().toString());
writer.close();

View File

@ -8,7 +8,8 @@ import net.ME1312.Galaxi.Library.Version.Version;
import net.ME1312.SubData.Client.SubDataClient;
import net.ME1312.SubServers.Host.ExHost;
import net.ME1312.SubServers.Host.Library.Exception.InvalidServerException;
import net.ME1312.SubServers.Host.Network.Packet.PacketExEditServer;
import net.ME1312.SubServers.Host.Network.Packet.PacketExControlServer;
import net.ME1312.SubServers.Host.Network.Packet.PacketExControlServer.Response;
import net.ME1312.SubServers.Host.SubAPI;
import java.io.BufferedWriter;
@ -124,12 +125,12 @@ public class SubServerImpl {
} catch (IOException | InterruptedException e) {
host.log.error.println(e);
allowrestart = false;
if (falsestart) ((SubDataClient) SubAPI.getInstance().getSubDataNetwork()[0]).sendPacket(new PacketExEditServer(this, PacketExEditServer.UpdateType.LAUNCH_EXCEPTION));
if (falsestart) ((SubDataClient) SubAPI.getInstance().getSubDataNetwork()[0]).sendPacket(new PacketExControlServer(this, Response.LAUNCH_EXCEPTION));
}
logger.destroy();
if (SubAPI.getInstance().getSubDataNetwork()[0] != null) {
((SubDataClient) SubAPI.getInstance().getSubDataNetwork()[0]).sendPacket(new PacketExEditServer(this, PacketExEditServer.UpdateType.STOPPED, (Integer) process.exitValue(), (Boolean) allowrestart));
((SubDataClient) SubAPI.getInstance().getSubDataNetwork()[0]).sendPacket(new PacketExControlServer(this, Response.STOPPED, (Integer) process.exitValue(), (Boolean) allowrestart));
}
host.log.info.println(name + " has stopped");
process = null;

View File

@ -12,15 +12,15 @@ import net.ME1312.SubServers.Host.Executable.SubServerImpl;
import java.util.Arrays;
/**
* Edit Server Packet
* Control Server Packet
*/
public class PacketExEditServer implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
public class PacketExControlServer implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
private ExHost host;
private SubServerImpl server;
private UpdateType type;
private Response type;
private Object[] args;
public enum UpdateType {
public enum Response {
// Status
LAUNCH_EXCEPTION(1),
STOPPED(2, Integer.class, Boolean.class);
@ -28,7 +28,7 @@ public class PacketExEditServer implements PacketObjectIn<Integer>, PacketObject
private short value;
private Class<?>[] args;
UpdateType(int value, Class<?>... args) {
Response(int value, Class<?>... args) {
this.value = (short) value;
this.args = args;
}
@ -43,29 +43,30 @@ public class PacketExEditServer implements PacketObjectIn<Integer>, PacketObject
}
/**
* New PacketExEditServer (In)
* New PacketExControlServer (In)
* @param host ExHost
*/
public PacketExEditServer(ExHost host) {
public PacketExControlServer(ExHost host) {
this.host = host;
}
/**
* New PacketExEditServer (Out)
* New PacketExControlServer (Out)
*
* @param type Update Type
* @param arguments Arguments
*/
public PacketExEditServer(SubServerImpl server, UpdateType type, Object... arguments) {
if (arguments.length != type.getArguments().length) throw new IllegalArgumentException(((arguments.length > type.getArguments().length)?"Too many":"Not enough") + " arguments for type: " + type.toString());
int i = 0;
while (i < arguments.length) {
if (!type.getArguments()[i].isInstance(arguments[i])) throw new IllegalArgumentException("Argument " + (i+1) + " is not " + type.getArguments()[i].getCanonicalName());
i++;
}
public PacketExControlServer(SubServerImpl server, Response type, Object... arguments) {
if (arguments.length < type.getArguments().length) throw new IllegalArgumentException("Not enough arguments for type: " + type);
this.server = server;
this.type = type;
this.args = arguments;
this.args = new Object[type.getArguments().length];
for (int i = 0; i < type.getArguments().length; ++i) {
if (!type.getArguments()[i].isInstance(arguments[i])) throw new IllegalArgumentException("Argument " + (i+1) + " is not " + type.getArguments()[i].getCanonicalName());
args[i] = arguments[i];
}
}
@Override
@ -80,7 +81,7 @@ public class PacketExEditServer implements PacketObjectIn<Integer>, PacketObject
@Override
public void receive(SubDataSender client, ObjectMap<Integer> data) {
try {
SubServerImpl server = host.servers.get(data.getString(0x0000).toLowerCase());
SubServerImpl server = host.servers.get(data.getRawString(0x0000).toLowerCase());
switch (data.getInt(0x0001)) {
case 0:
server.setEnabled(data.getList(0x0002).get(0).asBoolean());

View File

@ -1,12 +1,10 @@
package net.ME1312.SubServers.Host.Network;
import net.ME1312.Galaxi.Library.Callback.Callback;
import net.ME1312.Galaxi.Library.Config.YAMLSection;
import net.ME1312.Galaxi.Library.Container.Pair;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.Galaxi.Library.Version.Version;
import net.ME1312.SubData.Client.Library.DataSize;
import net.ME1312.SubData.Client.SubDataClient;
import net.ME1312.SubData.Client.SubDataProtocol;
import net.ME1312.SubServers.Client.Common.Network.Packet.*;
@ -101,7 +99,7 @@ public class SubProtocol extends SubDataProtocol {
registerPacket(0x0053, PacketOutExRequestQueue.class);
registerPacket(0x0054, PacketExCreateServer.class);
registerPacket(0x0055, PacketExAddServer.class);
registerPacket(0x0056, PacketExEditServer.class);
registerPacket(0x0056, PacketExControlServer.class);
registerPacket(0x0057, PacketOutExLogMessage.class);
registerPacket(0x0058, PacketExRemoveServer.class);
registerPacket(0x0059, PacketExDeleteServer.class);
@ -112,7 +110,7 @@ public class SubProtocol extends SubDataProtocol {
//registerPacket(0x0053, new PacketOutExRequestQueue(host));
registerPacket(0x0054, new PacketExCreateServer(host));
registerPacket(0x0055, new PacketExAddServer(host));
registerPacket(0x0056, new PacketExEditServer(host));
registerPacket(0x0056, new PacketExControlServer(host));
//registerPacket(0x0057, new PacketOutExLogMessage());
registerPacket(0x0058, new PacketExRemoveServer(host));
registerPacket(0x0059, new PacketExDeleteServer(host));

View File

@ -83,20 +83,6 @@
</tasks>
</configuration>
</execution>
<execution>
<id>verify</id>
<phase>verify</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks> <!-- Dependency Stripped Jar for Testing -->
<jar destfile="${basedir}/../Artifacts/Modulized/SubServers.Sync.jar" manifest="src/META-INF/MANIFEST.MOD.MF">
<zipfileset src="${basedir}/../Artifacts/SubServers.Sync.jar" excludes="net/ME1312/Galaxi/** net/ME1312/SubData/**" />
</jar>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
@ -108,31 +94,6 @@
<outputDirectory>../Artifacts/Maven</outputDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
<configuration>
<finalName>SubServers.Sync</finalName>
<outputDirectory>../Artifacts</outputDirectory>
<archive>
<manifestFile>src/META-INF/MANIFEST.MF</manifestFile>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>

View File

@ -429,14 +429,14 @@ public final class ExProxy extends BungeeCommon implements Listener {
if ((dynamic = SmartFallback.getForcedHost(e.getConnection()) == null) && getReconnectHandler() instanceof SmartFallback && (override = SmartFallback.getDNS(e.getConnection())) != null) {
if (!(override instanceof SubServerImpl) || ((SubServerImpl) override).isRunning()) {
if (!e.getConnection().getListener().isPingPassthrough()) {
e.setResponse(new ServerPing(e.getResponse().getVersion(), e.getResponse().getPlayers(), new TextComponent(override.getMotd()), null));
e.setResponse(new ServerPing(e.getResponse().getVersion(), e.getResponse().getPlayers(), new TextComponent(override.getMotd()), e.getResponse().getFaviconObject()));
} else {
Container<Boolean> lock = new Container<>(true);
boolean mode = plugin != null;
if (mode) e.registerIntent(plugin);
((BungeeServerInfo) override).ping((ping, error) -> {
if (error != null) {
e.setResponse(new ServerPing(e.getResponse().getVersion(), e.getResponse().getPlayers(), new TextComponent(getTranslation("ping_cannot_connect")), null));
e.setResponse(new ServerPing(e.getResponse().getVersion(), e.getResponse().getPlayers(), new TextComponent(getTranslation("ping_cannot_connect")), e.getResponse().getFaviconObject()));
} else e.setResponse(ping);
lock.value = false;
if (mode) e.completeIntent(plugin);
@ -454,17 +454,17 @@ public final class ExProxy extends BungeeCommon implements Listener {
ServerInfo override;
if ((override = SmartFallback.getForcedHost(e.getConnection())) != null || (override = SmartFallback.getDNS(e.getConnection())) != null) {
if (override instanceof SubServerImpl && !((SubServerImpl) override).isRunning()) {
e.setResponse(new ServerPing(e.getResponse().getVersion(), e.getResponse().getPlayers(), new TextComponent(api.getLang("SubServers", "Bungee.Ping.Offline")), null));
e.setResponse(new ServerPing(e.getResponse().getVersion(), e.getResponse().getPlayers(), new TextComponent(api.getLang("SubServers", "Bungee.Ping.Offline")), e.getResponse().getFaviconObject()));
}
} else {
int offline = 0;
for (String name : e.getConnection().getListener().getServerPriority()) {
ServerInfo server = getServerInfo(name);
if (server == null || (server instanceof SubServerImpl && !((SubServerImpl) server).isRunning())) offline++;
if (server instanceof SubServerImpl && !((SubServerImpl) server).isRunning()) offline++;
}
if (offline >= e.getConnection().getListener().getServerPriority().size()) {
e.setResponse(new ServerPing(e.getResponse().getVersion(), e.getResponse().getPlayers(), new TextComponent(api.getLang("SubServers", "Bungee.Ping.Offline")), null));
e.setResponse(new ServerPing(e.getResponse().getVersion(), e.getResponse().getPlayers(), new TextComponent(api.getLang("SubServers", "Bungee.Ping.Offline")), e.getResponse().getFaviconObject()));
}
}
}
@ -501,14 +501,14 @@ public final class ExProxy extends BungeeCommon implements Listener {
if (e.getPlayer().getServer() == null || fallback.containsKey(e.getPlayer().getUniqueId())) {
if (!fallback.containsKey(e.getPlayer().getUniqueId()) || fallback.get(e.getPlayer().getUniqueId()).names.contains(e.getTarget().getName())) {
ServerKickEvent kick = new ServerKickEvent(e.getPlayer(), e.getTarget(), new BaseComponent[]{
new TextComponent(getTranslation("no_server_permission"))
new TextComponent(api.getLang("SubServers", "Bungee.Restricted"))
}, null, ServerKickEvent.State.CONNECTING);
fallback(kick);
if (!kick.isCancelled()) e.getPlayer().disconnect(kick.getKickReasonComponent());
if (e.getPlayer().getServer() != null) e.setCancelled(true);
}
} else {
e.getPlayer().sendMessage(getTranslation("no_server_permission"));
e.getPlayer().sendMessage(api.getLang("SubServers", "Bungee.Restricted"));
e.setCancelled(true);
}
} else if (e.getPlayer().getServer() != null && !fallback.containsKey(e.getPlayer().getUniqueId()) && e.getTarget() instanceof SubServerImpl && !((SubServerImpl) e.getTarget()).isRunning()) {
@ -560,7 +560,7 @@ public final class ExProxy extends BungeeCommon implements Listener {
@SuppressWarnings("deprecation")
@EventHandler(priority = Byte.MAX_VALUE)
public void fallback(ServerKickEvent e) {
if (e.getPlayer().isConnected() && e.getPlayer() instanceof UserConnection && config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>()).getBoolean("Fallback", true)) {
if (e.getPlayer().isConnected() && config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>()).getBoolean("Fallback", true)) {
FallbackState state;
boolean init = !fallback.containsKey(e.getPlayer().getUniqueId());
if (init) {
@ -581,9 +581,6 @@ public final class ExProxy extends BungeeCommon implements Listener {
if (init) fallback.put(e.getPlayer().getUniqueId(), state);
e.setCancelServer(state.servers.getFirst());
if (Util.isException(() -> ServerKickEvent.class.getMethod("setCancelServers", ServerInfo[].class).invoke(e, (Object) state.servers.toArray(new ServerInfo[0])))) {
((UserConnection) e.getPlayer()).setServerJoinQueue(new LinkedList<>(state.names));
}
}
}
}
@ -635,7 +632,7 @@ public final class ExProxy extends BungeeCommon implements Listener {
public Boolean merge(net.ME1312.SubServers.Client.Common.Network.API.Server server) {
ServerImpl current = servers.get(server.getName().toLowerCase());
if (current == null || server instanceof net.ME1312.SubServers.Client.Common.Network.API.SubServer || !(current instanceof SubServerImpl)) {
if (server instanceof net.ME1312.SubServers.Client.Common.Network.API.SubServer || !(current instanceof SubServerImpl)) {
if (current == null || !current.getSignature().equals(server.getSignature())) {
if (server instanceof net.ME1312.SubServers.Client.Common.Network.API.SubServer) {
servers.put(server.getName().toLowerCase(), SubServerImpl.construct(server.getSignature(), server.getName(), server.getDisplayName(), server.getAddress(),
@ -668,45 +665,12 @@ public final class ExProxy extends BungeeCommon implements Listener {
return null;
}
@EventHandler(priority = Byte.MIN_VALUE)
public void edit(SubEditServerEvent e) {
if (servers.keySet().contains(e.getServer().toLowerCase())) {
ServerImpl server = servers.get(e.getServer().toLowerCase());
switch (e.getEdit().key().toLowerCase()) {
case "display":
server.setDisplayName(e.getEdit().value().asString());
break;
case "motd":
server.setMotd(ChatColor.translateAlternateColorCodes('&', e.getEdit().value().asString()));
break;
case "restricted":
server.setRestricted(e.getEdit().value().asBoolean());
break;
case "hidden":
server.setHidden(e.getEdit().value().asBoolean());
break;
}
}
}
@EventHandler(priority = Byte.MIN_VALUE)
public void start(SubStartEvent e) {
if (servers.keySet().contains(e.getServer().toLowerCase()) && servers.get(e.getServer().toLowerCase()) instanceof SubServerImpl)
((SubServerImpl) servers.get(e.getServer().toLowerCase())).setRunning(true);
}
public void connect(ServerImpl server, int channel, UUID address) {
if (server != null) {
server.setSubData(address, channel);
}
}
public void disconnect(ServerImpl server, int channel) {
if (server != null) {
server.setSubData(null, channel);
}
}
@EventHandler(priority = Byte.MIN_VALUE)
public void stop(SubStoppedEvent e) {
if (servers.keySet().contains(e.getServer().toLowerCase()) && servers.get(e.getServer().toLowerCase()) instanceof SubServerImpl)

View File

@ -0,0 +1,65 @@
package net.ME1312.SubServers.Sync.Network.Packet;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubData.Client.Protocol.PacketObjectIn;
import net.ME1312.SubData.Client.SubDataSender;
import net.ME1312.SubServers.Sync.ExProxy;
import net.ME1312.SubServers.Sync.Server.ServerImpl;
import java.util.ArrayList;
/**
* Server Edit Notification Packet
*/
public class PacketInExEditServer implements PacketObjectIn<Integer> {
private ExProxy plugin;
/**
* New PacketExControlServer (In)
*/
public PacketInExEditServer(ExProxy plugin) {
this.plugin = plugin;
}
@Override
public void receive(SubDataSender client, ObjectMap<Integer> data) {
if (plugin.servers.containsKey(data.getRawString(0x0000).toLowerCase())) {
ServerImpl server = plugin.servers.get(data.getRawString(0x0000).toLowerCase());
switch (data.getInt(0x0001)) {
case 0:
server.setDisplayName(data.getList(0x0002).get(0).asRawString());
break;
case 1:
server.setMotd(data.getList(0x0002).get(0).asRawString());
break;
case 2:
server.setRestricted(data.getList(0x0002).get(0).asBoolean());
break;
case 3:
server.setHidden(data.getList(0x0002).get(0).asBoolean());
break;
case 4:
server.setSubData(data.getList(0x0002).get(1).asUUID(), data.getList(0x0002).get(0).asInt());
break;
case 5:
server.setSubData(null, data.getList(0x0002).get(0).asInt());
break;
case 6:
server.whitelist = data.getList(0x0002).get(0).asUUIDList();
break;
case 7:
server.whitelist(data.getList(0x0002).get(0).asUUID());
break;
case 8:
server.unwhitelist(data.getList(0x0002).get(0).asUUID());
break;
}
}
}
@Override
public int version() {
return 0x0002;
}
}

View File

@ -90,20 +90,6 @@ public class PacketInExRunEvent implements PacketObjectIn<Integer> {
callback("SubStartedEvent", this);
}
});
callback("SubNetworkConnectEvent", new Callback<ObjectMap<String>>() {
@Override
public void run(ObjectMap<String> data) {
plugin.connect(plugin.servers.get(data.getRawString("server").toLowerCase()), data.getInt("channel"), data.getUUID("id"));
callback("SubNetworkConnectEvent", this);
}
});
callback("SubNetworkDisconnectEvent", new Callback<ObjectMap<String>>() {
@Override
public void run(ObjectMap<String> data) {
plugin.disconnect(plugin.servers.get(data.getRawString("server").toLowerCase()), data.getInt("channel"));
callback("SubNetworkDisconnectEvent", this);
}
});
callback("SubStopEvent", new Callback<ObjectMap<String>>() {
@Override
public void run(ObjectMap<String> data) {

View File

@ -1,34 +0,0 @@
package net.ME1312.SubServers.Sync.Network.Packet;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.SubData.Client.Protocol.PacketObjectIn;
import net.ME1312.SubData.Client.SubDataSender;
import net.ME1312.SubServers.Sync.ExProxy;
/**
* Update External Whitelist Packet
*/
public class PacketInExUpdateWhitelist implements PacketObjectIn<Integer> {
private ExProxy plugin;
/**
* New PacketInExUpdateWhitelist
*/
public PacketInExUpdateWhitelist(ExProxy plugin) {
this.plugin = plugin;
}
@Override
public void receive(SubDataSender client, ObjectMap<Integer> data) {
if (data.getBoolean(0x0001)) {
plugin.servers.get(data.getRawString(0x0000)).whitelist(data.getUUID(0x0002));
} else {
plugin.servers.get(data.getRawString(0x0000)).unwhitelist(data.getUUID(0x0002));
}
}
@Override
public int version() {
return 0x0001;
}
}

View File

@ -114,7 +114,7 @@ public class SubProtocol extends SubDataProtocol {
registerPacket(0x0070, new PacketInExRunEvent(plugin));
registerPacket(0x0071, new PacketInExReset());
registerPacket(0x0073, new PacketInExUpdateWhitelist(plugin));
registerPacket(0x0073, new PacketInExEditServer(plugin));
registerPacket(0x0074, new PacketExSyncPlayer(plugin));
registerPacket(0x0075, new PacketExTransferPlayer(plugin));
registerPacket(0x0076, new PacketExDisconnectPlayer(plugin));

View File

@ -20,7 +20,7 @@ import java.util.*;
*/
public class ServerImpl extends BungeeServerInfo {
private HashMap<Integer, UUID> subdata = new HashMap<Integer, UUID>();
private List<UUID> whitelist = new ArrayList<UUID>();
public List<UUID> whitelist = new ArrayList<UUID>();
private String nick = null;
private boolean hidden;
private final String signature;
@ -176,7 +176,7 @@ public class ServerImpl extends BungeeServerInfo {
* @return Whitelisted Status
*/
public boolean canAccess(CommandSender player) {
return (player instanceof ProxiedPlayer && whitelist.contains(((ProxiedPlayer) player).getUniqueId())) || super.canAccess(player);
return super.canAccess(player) || (player instanceof ProxiedPlayer && whitelist.contains(((ProxiedPlayer) player).getUniqueId()));
}
/**

View File

@ -0,0 +1,175 @@
<?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.Sync.Velocity</artifactId>
<version>-PLACEHOLDER</version>
<packaging>jar</packaging>
<repositories>
<repository>
<id>velocity-repo</id>
<url>https://nexus.velocitypowered.com/repository/maven-public/</url>
</repository>
<repository>
<id>me1312-repo</id>
<url>https://dev.me1312.net/maven</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.velocitypowered</groupId>
<artifactId>velocity-api</artifactId>
<version>3.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.ME1312.SubServers</groupId>
<artifactId>SubServers.Sync</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>net.ME1312.SubServers</groupId>
<artifactId>SubServers.Client.Common</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.dosse.upnp</groupId>
<artifactId>WaifUPnP</artifactId>
<version>1.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<directory>../../out/compile/target/SubServers.Sync.Velocity</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>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>process</id>
<phase>process-resources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<mkdir dir="${project.build.directory}" />
<copy file="${basedir}/../../LICENSE" todir="${project.build.directory}/classes" />
</tasks>
</configuration>
</execution>
<execution>
<id>verify</id>
<phase>verify</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks> <!-- Dependency Stripped Jar for Testing -->
<jar destfile="${basedir}/../../Artifacts/Modulized/SubServers.Sync.jar" manifest="../src/META-INF/MANIFEST.MOD.MF">
<zipfileset src="${basedir}/../../Artifacts/SubServers.Sync.jar" excludes="net/ME1312/Galaxi/** net/ME1312/SubData/**" />
</jar>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<finalName>SubServers.Sync.Velocity</finalName>
<outputDirectory>../../Artifacts/Maven</outputDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
<configuration>
<finalName>SubServers.Sync</finalName>
<outputDirectory>../../Artifacts</outputDirectory>
<archive>
<manifestFile>../src/META-INF/MANIFEST.MF</manifestFile>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>javadoc</goal>
</goals>
<configuration>
<windowtitle>SubServers.Sync.Velocity</windowtitle>
<doctitle>SubServers.Sync.Velocity ${project.version}</doctitle>
<show>protected</show>
<destDir>./</destDir>
<outputDirectory>${basedir}/../../Javadoc/SubServers.Sync.Velocity</outputDirectory>
<reportOutputDirectory>${basedir}/../../Javadoc/SubServers.Sync.Velocity</reportOutputDirectory>
<additionalOptions>-Xdoclint:none</additionalOptions>
<links>
<link>https://dev.me1312.net/jenkins/job/GalaxiEngine/javadoc/GalaxiUtil/</link>
<link>https://dev.me1312.net/jenkins/job/SubData/javadoc/Client/</link>
<link>https://jd.velocitypowered.com/3.0.0/</link>
</links>
<includeDependencySources>true</includeDependencySources>
<dependencySourceIncludes>
<dependencySourceInclude>net.ME1312.SubServers:SubServers.Client.Common:*</dependencySourceInclude>
</dependencySourceIncludes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,40 @@
package net.ME1312.SubServers.Velocity.Event;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubServers.Velocity.Library.SubEvent;
import java.util.UUID;
/**
* Add Server Event
*/
public class SubAddHostEvent implements SubEvent {
private UUID player;
private String host;
/**
* Server Add Event
*
* @param player Player Adding Server
* @param host Host to be added
*/
public SubAddHostEvent(UUID player, String host) {
if (Util.isNull(host)) throw new NullPointerException();
this.player = player;
this.host = host;
}
/**
* Gets the Host to be Added
*
* @return The Host to be Added
*/
public String getHost() { return host; }
/**
* Gets the player that triggered the Event
*
* @return The Player that triggered this Event or null if Console
*/
public UUID getPlayer() { return player; }
}

View File

@ -0,0 +1,28 @@
package net.ME1312.SubServers.Velocity.Event;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubServers.Velocity.Library.SubEvent;
/**
* Proxy Add Event
*/
public class SubAddProxyEvent implements SubEvent {
private String proxy;
/**
* Proxy Add Event
*
* @param proxy Host Being Added
*/
public SubAddProxyEvent(String proxy) {
if (Util.isNull(proxy)) throw new NullPointerException();
this.proxy = proxy;
}
/**
* Gets the Proxy to be Added
*
* @return The Proxy to be Added
*/
public String getProxy() { return proxy; }
}

View File

@ -0,0 +1,51 @@
package net.ME1312.SubServers.Velocity.Event;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubServers.Velocity.Library.SubEvent;
import java.util.UUID;
/**
* Add Server Event
*/
public class SubAddServerEvent implements SubEvent {
private UUID player;
private String host;
private String server;
/**
* Server Add Event
*
* @param player Player Adding Server
* @param server Server Starting
*/
public SubAddServerEvent(UUID player, String host, String server) {
if (Util.isNull(server)) throw new NullPointerException();
this.player = player;
this.host = host;
this.server = server;
}
/**
* Gets the Server to be Added
*
* @return The Server to be Added
*/
public String getServer() { return server; }
/**
* Gets the Host of the Server
*
* @return The Host of the Server or null if isn't a SubServer
*/
public String getHost() {
return host;
}
/**
* Gets the player that triggered the Event
*
* @return The Player that triggered this Event or null if Console
*/
public UUID getPlayer() { return player; }
}

View File

@ -0,0 +1,124 @@
package net.ME1312.SubServers.Velocity.Event;
import net.ME1312.Galaxi.Library.Callback.Callback;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.Galaxi.Library.Version.Version;
import net.ME1312.SubServers.Client.Common.Network.API.SubServer;
import net.ME1312.SubServers.Velocity.Library.SubEvent;
import net.ME1312.SubServers.Velocity.SubAPI;
import java.lang.reflect.InvocationTargetException;
import java.util.UUID;
/**
* Server Create Event
*/
public class SubCreateEvent implements SubEvent {
private UUID player;
private boolean update;
private String host;
private String name;
private String template;
private Version version;
private int port;
/**
* Server Create Event
*
* @param player Player Creating
* @param host Potential Host
* @param name Server Name
* @param template Server Type
* @param version Server Version
* @param port Server Port Number
*/
public SubCreateEvent(UUID player, String host, String name, String template, Version version, int port, boolean update) {
if (Util.isNull(host, name, template, version, port)) throw new NullPointerException();
this.player = player;
this.update = update;
this.host = host;
this.name = name;
this.template = template;
this.version = version;
this.port = port;
}
/**
* Get the Host the SubServer will run on
*
* @return Potential Host
*/
public String getHost() {
return host;
}
/**
* Get if SubCreator is being run in update mode
*
* @return Update Mode Status
*/
public boolean isUpdate() {
return update;
}
/**
* Get the Server that's being updated
*
* @param callback Updating Server
*/
public void getUpdatingServer(Callback<SubServer> callback) {
if (!update) {
try {
callback.run(null);
} catch (Throwable e) {
Throwable ew = new InvocationTargetException(e);
ew.printStackTrace();
}
} else {
SubAPI.getInstance().getSubServer(name, callback);
}
}
/**
* Get the name the SubServer will use
*
* @return SubServer Name
*/
public String getName() {
return name;
}
/**
* Get the Template to Use
*
* @return Server Template
*/
public String getTemplate() {
return template;
}
/**
* Get the Version the Server will use
*
* @return Server Version
*/
public Version getVersion() {
return version;
}
/**
* Get the Port the Server will use
*
* @return Port Number
*/
public int getPort() {
return port;
}
/**
* Gets the player that triggered the Event
*
* @return The Player that triggered this Event or null if Console
*/
public UUID getPlayer() { return player; }
}

View File

@ -0,0 +1,135 @@
package net.ME1312.SubServers.Velocity.Event;
import net.ME1312.Galaxi.Library.Callback.Callback;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.Galaxi.Library.Version.Version;
import net.ME1312.SubServers.Client.Common.Network.API.SubServer;
import net.ME1312.SubServers.Velocity.Library.SubEvent;
import net.ME1312.SubServers.Velocity.SubAPI;
import java.lang.reflect.InvocationTargetException;
import java.util.UUID;
/**
* Server Created Event
*/
public class SubCreatedEvent implements SubEvent {
private UUID player;
private boolean success;
private boolean update;
private String host;
private String name;
private String template;
private Version version;
private int port;
/**
* Server Created Event
*
* @param player Player Creating
* @param host Potential Host
* @param name Server Name
* @param template Server Type
* @param version Server Version
* @param port Server Port Number
*/
public SubCreatedEvent(UUID player, String host, String name, String template, Version version, int port, boolean update, boolean success) {
if (Util.isNull(host, name, template, port)) throw new NullPointerException();
this.player = player;
this.success = success;
this.update = update;
this.host = host;
this.name = name;
this.template = template;
this.version = version;
this.port = port;
}
/**
* Get the Host the SubServer runs on
*
* @return Host
*/
public String getHost() {
return host;
}
/**
* Get if SubCreator was being run in update mode
*
* @return Update Mode Status
*/
public boolean wasUpdate() {
return update;
}
/**
* Get if the operation was a success
*
* @return Success Status
*/
public boolean wasSuccessful() {
return success;
}
/**
* Get the Server that's being updated
*
* @param callback Updating Server
*/
public void getServer(Callback<SubServer> callback) {
if (!update && !success) {
try {
callback.run(null);
} catch (Throwable e) {
Throwable ew = new InvocationTargetException(e);
ew.printStackTrace();
}
} else {
SubAPI.getInstance().getSubServer(name, callback);
}
}
/**
* Get the name the SubServer used
*
* @return SubServer Name
*/
public String getName() {
return name;
}
/**
* Get the Template that was used
*
* @return Server Template
*/
public String getTemplate() {
return template;
}
/**
* Get the Version the Server used
*
* @return Server Version
*/
public Version getVersion() {
return version;
}
/**
* Get the Port the Server used
*
* @return Port Number
*/
public int getPort() {
return port;
}
/**
* Gets the player that triggered the Event
*
* @return The Player that triggered this Event or null if Console
*/
public UUID getPlayer() { return player; }
}

View File

@ -0,0 +1,58 @@
package net.ME1312.SubServers.Velocity.Event;
import net.ME1312.Galaxi.Library.Container.ContainedPair;
import net.ME1312.Galaxi.Library.Container.Pair;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.Galaxi.Library.Map.ObjectMapValue;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubServers.Velocity.Library.SubEvent;
import java.util.UUID;
/**
* Server Edit Event
*/
public class SubEditServerEvent implements SubEvent {
private UUID player;
private String server;
private Pair<String, ObjectMapValue<String>> edit;
/**
* Server Edit Event
*
* @param player Player Adding Server
* @param server Server to be Edited
* @param edit Edit to make
*/
public SubEditServerEvent(UUID player, String server, Pair<String, ?> edit) {
if (Util.isNull(server, edit)) throw new NullPointerException();
ObjectMap<String> section = new ObjectMap<String>();
section.set(".", edit.value());
this.player = player;
this.server = server;
this.edit = new ContainedPair<String, ObjectMapValue<String>>(edit.key(), section.get("."));
}
/**
* Gets the Server to be Edited
*
* @return The Server to be Edited
*/
public String getServer() { return server; }
/**
* Gets the player that triggered the Event
*
* @return The Player that triggered this Event or null if Console
*/
public UUID getPlayer() { return player; }
/**
* Gets the edit to be made
*
* @return Edit to be made
*/
public Pair<String, ObjectMapValue<String>> getEdit() {
return edit;
}
}

View File

@ -0,0 +1,29 @@
package net.ME1312.SubServers.Velocity.Event;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubData.Client.DataClient;
import net.ME1312.SubServers.Velocity.Library.SubEvent;
/**
* SubData Network Connect Event
*/
public class SubNetworkConnectEvent implements SubEvent {
private DataClient network;
/**
* SubData Network Connect Event
*/
public SubNetworkConnectEvent(DataClient network) {
if (Util.isNull(network)) throw new NullPointerException();
this.network = network;
}
/**
* Get the SubData network
*
* @return SubData Network
*/
public DataClient getNetwork() {
return network;
}
}

View File

@ -0,0 +1,41 @@
package net.ME1312.SubServers.Velocity.Event;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubData.Client.DataClient;
import net.ME1312.SubData.Client.Library.DisconnectReason;
import net.ME1312.SubServers.Velocity.Library.SubEvent;
/**
* SubData Network Disconnect Event
*/
public class SubNetworkDisconnectEvent implements SubEvent {
private DataClient network;
private DisconnectReason reason;
/**
* SubData Network Disconnect Event
*/
public SubNetworkDisconnectEvent(DataClient network, DisconnectReason reason) {
if (Util.isNull(network, reason)) throw new NullPointerException();
this.network = network;
this.reason = reason;
}
/**
* Get the SubData network
*
* @return SubData Network
*/
public DataClient getNetwork() {
return network;
}
/**
* Get the reason the client disconnected
*
* @return Disconnect Reason
*/
public DisconnectReason getReason() {
return reason;
}
}

View File

@ -0,0 +1,40 @@
package net.ME1312.SubServers.Velocity.Event;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubServers.Velocity.Library.SubEvent;
import java.util.UUID;
/**
* Remove Host Event
*/
public class SubRemoveHostEvent implements SubEvent {
private UUID player;
private String host;
/**
* Host Remove Event
*
* @param player Player Adding Host
* @param host Server Starting
*/
public SubRemoveHostEvent(UUID player, String host) {
if (Util.isNull(host)) throw new NullPointerException();
this.player = player;
this.host = host;
}
/**
* Gets the Host to be Removed
*
* @return The Host to be Removed
*/
public String getHost() { return host; }
/**
* Gets the player that triggered the Event
*
* @return The Player that triggered this Event or null if Console
*/
public UUID getPlayer() { return player; }
}

View File

@ -0,0 +1,28 @@
package net.ME1312.SubServers.Velocity.Event;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubServers.Velocity.Library.SubEvent;
/**
* Proxy Remove Event
*/
public class SubRemoveProxyEvent implements SubEvent {
private String proxy;
/**
* Proxy Remove Event
*
* @param proxy Host Being Added
*/
public SubRemoveProxyEvent(String proxy) {
if (Util.isNull(proxy)) throw new NullPointerException();
this.proxy = proxy;
}
/**
* Gets the Proxy to be Removed
*
* @return The Proxy to be Removed
*/
public String getProxy() { return proxy; }
}

View File

@ -0,0 +1,51 @@
package net.ME1312.SubServers.Velocity.Event;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubServers.Velocity.Library.SubEvent;
import java.util.UUID;
/**
* Remove Server Event
*/
public class SubRemoveServerEvent implements SubEvent {
private UUID player;
private String host;
private String server;
/**
* Server Remove Event
*
* @param player Player Adding Server
* @param server Server Starting
*/
public SubRemoveServerEvent(UUID player, String host, String server) {
if (Util.isNull(server)) throw new NullPointerException();
this.player = player;
this.host = host;
this.server = server;
}
/**
* Gets the Server to be Removed
*
* @return The Server to be Removed
*/
public String getServer() { return server; }
/**
* Gets the Host of the Server
*
* @return The Host of the Server or null if isn't a SubServer
*/
public String getHost() {
return host;
}
/**
* Gets the player that triggered the Event
*
* @return The Player that triggered this Event or null if Console
*/
public UUID getPlayer() { return player; }
}

View File

@ -0,0 +1,51 @@
package net.ME1312.SubServers.Velocity.Event;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubServers.Velocity.Library.SubEvent;
import java.util.UUID;
/**
* Send Command Event
*/
public class SubSendCommandEvent implements SubEvent {
private UUID player;
private String server;
private String command;
/**
* Server Command Event
*
* @param player Player Commanding Server
* @param server Server being Commanded
*/
public SubSendCommandEvent(UUID player, String server, String command) {
if (Util.isNull(server, command)) throw new NullPointerException();
this.player = player;
this.server = server;
this.command = command;
}
/**
* Gets the Server Effected
*
* @return The Server Effected
*/
public String getServer() { return server; }
/**
* Gets the player that triggered the Event
*
* @return The Player that triggered this Event or null if Console
*/
public UUID getPlayer() { return player; }
/**
* Gets the Command to Send
*
* @return Command to Send
*/
public String getCommand() {
return command;
}
}

View File

@ -0,0 +1,41 @@
package net.ME1312.SubServers.Velocity.Event;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubServers.Velocity.Library.SubEvent;
import java.util.UUID;
/**
* Start Server Event
*/
public class SubStartEvent implements SubEvent {
private boolean cancelled = false;
private UUID player;
private String server;
/**
* Server Start Event
*
* @param player Player Starting Server
* @param server Server Starting
*/
public SubStartEvent(UUID player, String server) {
if (Util.isNull(server)) throw new NullPointerException();
this.player = player;
this.server = server;
}
/**
* Gets the Server Effected
*
* @return The Server Effected
*/
public String getServer() { return server; }
/**
* Gets the player that triggered the Event
*
* @return The Player that triggered this Event or null if Console
*/
public UUID getPlayer() { return player; }
}

View File

@ -0,0 +1,31 @@
package net.ME1312.SubServers.Velocity.Event;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubServers.Velocity.Library.SubEvent;
/**
* Server Started Event
*/
public class SubStartedEvent implements SubEvent {
private String server;
/**
* Server Started Event<br>
* <b>This event can only be called when a SubData connection is made!</b>
*
* @param server Server that Started
*/
public SubStartedEvent(String server) {
if (Util.isNull(server)) throw new NullPointerException();
this.server = server;
}
/**
* Gets the Server Effected
*
* @return The Server Effected
*/
public String getServer() {
return server;
}
}

View File

@ -0,0 +1,56 @@
package net.ME1312.SubServers.Velocity.Event;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubServers.Velocity.Library.SubEvent;
import java.util.UUID;
/**
* Server Stop Event
*/
public class SubStopEvent implements SubEvent {
private UUID player;
private String server;
private boolean force;
/**
* Server Stop Event
*
* @param player Player Stopping Server
* @param server Server Stopping
* @param force If it was a Forced Shutdown
*/
public SubStopEvent(UUID player, String server, boolean force) {
if (Util.isNull(server, force)) throw new NullPointerException();
this.player = player;
this.server = server;
this.force = force;
}
/**
* Gets the Server Effected
*
* @return The Server Effected
*/
public String getServer() {
return server;
}
/**
* Gets the player that triggered the Event
*
* @return The Player that triggered this Event or null if Console
*/
public UUID getPlayer() {
return player;
}
/**
* Gets if it was a forced shutdown
*
* @return Forced Shutdown Status
*/
public boolean isForced() {
return force;
}
}

View File

@ -0,0 +1,28 @@
package net.ME1312.SubServers.Velocity.Event;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubServers.Velocity.Library.SubEvent;
/**
* Server Shell Exit Event
*/
public class SubStoppedEvent implements SubEvent {
private String server;
/**
* Server Shell Exit Event
*
* @param server Server that Stopped
*/
public SubStoppedEvent(String server) {
if (Util.isNull(server)) throw new NullPointerException();
this.server = server;
}
/**
* Gets the Server Effected
*
* @return The Server Effected
*/
public String getServer() { return server; }
}

View File

@ -0,0 +1,640 @@
package net.ME1312.SubServers.Velocity;
import net.ME1312.Galaxi.Library.Config.YAMLConfig;
import net.ME1312.Galaxi.Library.Container.Container;
import net.ME1312.Galaxi.Library.Container.Pair;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.Galaxi.Library.UniversalFile;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.Galaxi.Library.Version.Version;
import net.ME1312.SubData.Client.DataClient;
import net.ME1312.SubData.Client.Encryption.AES;
import net.ME1312.SubData.Client.Encryption.DHE;
import net.ME1312.SubData.Client.Encryption.RSA;
import net.ME1312.SubData.Client.Library.DisconnectReason;
import net.ME1312.SubData.Client.SubDataClient;
import net.ME1312.SubServers.Client.Common.Network.Packet.PacketDisconnectPlayer;
import net.ME1312.SubServers.Velocity.Event.*;
import net.ME1312.SubServers.Velocity.Library.Compatibility.ChatColor;
import net.ME1312.SubServers.Velocity.Library.Compatibility.Logger;
import net.ME1312.SubServers.Velocity.Library.ConfigUpdater;
import net.ME1312.SubServers.Velocity.Library.Fallback.FallbackState;
import net.ME1312.SubServers.Velocity.Library.Fallback.SmartFallback;
import net.ME1312.SubServers.Velocity.Library.Metrics;
import net.ME1312.SubServers.Velocity.Network.Packet.PacketExSyncPlayer;
import net.ME1312.SubServers.Velocity.Network.SubProtocol;
import net.ME1312.SubServers.Velocity.Server.CachedPlayer;
import net.ME1312.SubServers.Velocity.Server.ServerData;
import net.ME1312.SubServers.Velocity.Server.SubServerData;
import com.dosse.upnp.UPnP;
import com.google.gson.Gson;
import com.google.inject.Inject;
import com.velocitypowered.api.command.CommandMeta;
import com.velocitypowered.api.event.PostOrder;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.connection.DisconnectEvent;
import com.velocitypowered.api.event.connection.LoginEvent;
import com.velocitypowered.api.event.player.KickedFromServerEvent;
import com.velocitypowered.api.event.player.ServerPostConnectEvent;
import com.velocitypowered.api.event.player.ServerPreConnectEvent;
import com.velocitypowered.api.event.proxy.*;
import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.plugin.PluginContainer;
import com.velocitypowered.api.plugin.PluginDescription;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ProxyServer;
import com.velocitypowered.api.proxy.ServerConnection;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.proxy.server.ServerInfo;
import com.velocitypowered.api.proxy.server.ServerPing;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentLike;
import net.kyori.adventure.text.TextReplacementConfig;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.jetbrains.annotations.NotNull;
import java.io.*;
import java.net.InetAddress;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.*;
import java.util.concurrent.TimeUnit;
@Plugin(id = "subservers-sync", name = "SubServers-Sync", authors = "ME1312", version = "2.17.1a/pr1", url = "https://github.com/ME1312/SubServers-2", description = "Dynamically sync player and server connection info over multiple proxy instances")
public class ExProxy {
HashMap<Integer, SubDataClient> subdata = new HashMap<Integer, SubDataClient>();
Pair<Long, Map<String, Map<String, String>>> lang = null;
public final Map<ServerInfo, ServerData> servers = new TreeMap<ServerInfo, ServerData>();
public final HashMap<UUID, ServerData> rPlayerLinkS = new HashMap<UUID, ServerData>();
public final HashMap<UUID, String> rPlayerLinkP = new HashMap<UUID, String>();
public final HashMap<UUID, CachedPlayer> rPlayers = new HashMap<UUID, CachedPlayer>();
private final HashMap<UUID, FallbackState> fallback = new HashMap<UUID, FallbackState>();
public final org.apache.logging.log4j.Logger out;
public final UniversalFile dir = new UniversalFile(new File(System.getProperty("user.dir")));
public YAMLConfig config;
public final PluginDescription plugin;
private final ProxyServer proxy;
private final Metrics.Factory metrics;
public final SubAPI api = new SubAPI(this);
public SubProtocol subprotocol;
public final Version version;
public boolean running = false;
public long lastReload = -1;
private long resetDate = 0;
private boolean reconnect = false;
private boolean posted = false;
@Inject
private ExProxy(ProxyServer proxy, PluginContainer plugin, Metrics.Factory metrics) throws Exception {
this.proxy = proxy;
this.metrics = metrics;
this.version = Version.fromString((this.plugin = plugin.getDescription()).getVersion().get());
Util.reflect(Logger.class.getDeclaredField("parent"), null, (this.out = Util.reflect(proxy.getClass().getDeclaredField("logger"), proxy)));
Logger.get("SubServers").info("Loading SubServers.Sync v" + version.toString() + " Libraries (for Minecraft " + api.getGameVersion()[api.getGameVersion().length - 1] + ")");
Util.isException(() -> new CachedPlayer((Player) null)); // runs <clinit>
UniversalFile dir = new UniversalFile(this.dir, "SubServers");
dir.mkdir();
ConfigUpdater.updateConfig(new UniversalFile(dir, "sync.yml"));
config = new YAMLConfig(new UniversalFile(dir, "sync.yml"));
SmartFallback.addInspector((player, info) -> {
ServerData server = getData(info.getServerInfo());
double confidence = 0;
if (server != null) {
if (!server.isHidden()) confidence++;
if (!server.isRestricted()) confidence++;
if (server.getSubData()[0] != null) confidence++;
if (player != null) {
if (server.canAccess(player)) confidence++;
}
} if (server instanceof SubServerData) {
if (!((SubServerData) server).isRunning()) return null;
}
return confidence;
});
subprotocol = SubProtocol.get();
subprotocol.registerCipher("DHE", DHE.get(128));
subprotocol.registerCipher("DHE-128", DHE.get(128));
subprotocol.registerCipher("DHE-192", DHE.get(192));
subprotocol.registerCipher("DHE-256", DHE.get(256));
}
/**
* Load Hosts, Servers, SubServers, and SubData Direct
*/
@Subscribe
public void initialize(ProxyInitializeEvent e) {
try {
running = true;
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();
subprotocol.unregisterCipher("AES");
subprotocol.unregisterCipher("AES-128");
subprotocol.unregisterCipher("AES-192");
subprotocol.unregisterCipher("AES-256");
subprotocol.unregisterCipher("RSA");
api.name = config.get().getMap("Settings").getMap("SubData").getString("Name", null);
if (config.get().getMap("Settings").getMap("SubData").getRawString("Password", "").length() > 0) {
subprotocol.registerCipher("AES", new AES(128, config.get().getMap("Settings").getMap("SubData").getRawString("Password")));
subprotocol.registerCipher("AES-128", new AES(128, config.get().getMap("Settings").getMap("SubData").getRawString("Password")));
subprotocol.registerCipher("AES-192", new AES(192, config.get().getMap("Settings").getMap("SubData").getRawString("Password")));
subprotocol.registerCipher("AES-256", new AES(256, config.get().getMap("Settings").getMap("SubData").getRawString("Password")));
Logger.get("SubData").info("AES Encryption Available");
}
if (new UniversalFile(dir, "SubServers:subdata.rsa.key").exists()) {
try {
subprotocol.registerCipher("RSA", new RSA(new UniversalFile(dir, "SubServers:subdata.rsa.key")));
Logger.get("SubData").info("RSA Encryption Available");
} catch (Exception x) {
x.printStackTrace();
}
}
reconnect = true;
Logger.get("SubData").info("");
Logger.get("SubData").info("Connecting to /" + config.get().getMap("Settings").getMap("SubData").getRawString("Address", "127.0.0.1:4391"));
connect(Logger.get("SubData"), null);
if (!posted) {
posted = true;
post();
}
} catch (IOException x) {
x.printStackTrace();
}
}
private void connect(java.util.logging.Logger log, Pair<DisconnectReason, DataClient> disconnect) throws IOException {
int reconnect = config.get().getMap("Settings").getMap("SubData").getInt("Reconnect", 60);
if (disconnect == null || (this.reconnect && reconnect > 0 && disconnect.key() != DisconnectReason.PROTOCOL_MISMATCH && disconnect.key() != DisconnectReason.ENCRYPTION_MISMATCH)) {
long reset = resetDate;
Timer timer = new Timer("SubServers.Sync::SubData_Reconnect_Handler");
if (disconnect != null) log.info("Attempting reconnect in " + reconnect + " seconds");
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
try {
if (reset == resetDate && (subdata.getOrDefault(0, null) == null || subdata.get(0).isClosed())) {
SubDataClient open = subprotocol.open(InetAddress.getByName(config.get().getMap("Settings").getMap("SubData").getRawString("Address", "127.0.0.1:4391").split(":")[0]),
Integer.parseInt(config.get().getMap("Settings").getMap("SubData").getRawString("Address", "127.0.0.1:4391").split(":")[1]));
if (subdata.getOrDefault(0, null) != null) subdata.get(0).reconnect(open);
subdata.put(0, open);
}
timer.cancel();
} catch (IOException e) {
Logger.get("SubData").info("Connection was unsuccessful, retrying in " + reconnect + " seconds");
}
}
}, (disconnect == null)?0:TimeUnit.SECONDS.toMillis(reconnect), TimeUnit.SECONDS.toMillis(reconnect));
}
}
private void post() {
if (!config.get().getMap("Settings").getRawStringList("Disabled-Overrides", Collections.emptyList()).contains("/server"))
proxy.getCommandManager().register("server", new SubCommand.BungeeServer(this));
if (!config.get().getMap("Settings").getRawStringList("Disabled-Overrides", Collections.emptyList()).contains("/glist"))
proxy.getCommandManager().register("glist", new SubCommand.BungeeList(this));
proxy.getCommandManager().register("subservers", new SubCommand(this), "subserver", "sub");
if (config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>()).getBoolean("Enabled", true))
proxy.getEventManager().register(this, new SmartFallback(config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>())));
metrics.make(this, 11953);
new Timer("SubServers.Sync::Routine_Update_Check").schedule(new TimerTask() {
@SuppressWarnings("unchecked")
@Override
public void run() {
try {
ObjectMap<String> tags = new ObjectMap<String>(new Gson().fromJson("{\"tags\":" + Util.readAll(new BufferedReader(new InputStreamReader(new URL("https://api.github.com/repos/ME1312/SubServers-2/git/refs/tags").openStream(), Charset.forName("UTF-8")))) + '}', Map.class));
List<Version> versions = new LinkedList<Version>();
Version updversion = version;
int updcount = 0;
for (ObjectMap<String> tag : tags.getMapList("tags")) versions.add(Version.fromString(tag.getString("ref").substring(10)));
Collections.sort(versions);
for (Version version : versions) {
if (version.compareTo(updversion) > 0) {
updversion = version;
updcount++;
}
}
if (updcount > 0) Logger.get("SubServers").info("SubServers.Sync v" + updversion + " is available. You are " + updcount + " version" + ((updcount == 1)?"":"s") + " behind.");
} catch (Exception e) {}
}
}, 0, TimeUnit.DAYS.toMillis(2));
int rpec_i = config.get().getMap("Settings").getInt("RPEC-Check-Interval", 300);
int rpec_s = rpec_i - new Random().nextInt((rpec_i / 3) + 1);
new Timer("SubServers.Sync::RemotePlayer_Error_Checking").schedule(new TimerTask() {
@Override
public void run() {
if (api.getName() != null && api.getSubDataNetwork()[0] != null && !api.getSubDataNetwork()[0].isClosed()) {
api.getProxy(api.getName(), proxy -> {
synchronized (rPlayers) {
ArrayList<CachedPlayer> add = new ArrayList<CachedPlayer>();
for (Player player : ExProxy.this.proxy.getAllPlayers()) {
if (!rPlayers.containsKey(player.getUniqueId())) { // Add players that don't exist
CachedPlayer p = new CachedPlayer(player);
rPlayerLinkP.put(player.getUniqueId(), p.getProxyName().toLowerCase());
rPlayers.put(player.getUniqueId(), p);
ServerInfo server = player.getCurrentServer().map(ServerConnection::getServerInfo).orElse(null);
if (servers.containsKey(server)) rPlayerLinkS.put(player.getUniqueId(), servers.get(server));
add.add(p);
}
}
ArrayList<CachedPlayer> remove = new ArrayList<CachedPlayer>();
for (Pair<String, UUID> player : proxy.getPlayers()) { // Remove players that shouldn't exist
if (!ExProxy.this.proxy.getPlayer(player.value()).isPresent()) {
remove.add(rPlayers.get(player.value()));
rPlayerLinkS.remove(player.value());
rPlayerLinkP.remove(player.value());
rPlayers.remove(player.value());
}
}
for (UUID player : Util.getBackwards(rPlayerLinkP, api.getName().toLowerCase())) { // Remove players that shouldn't exist (internally)
if (!ExProxy.this.proxy.getPlayer(player).isPresent()) {
rPlayerLinkS.remove(player);
rPlayerLinkP.remove(player);
rPlayers.remove(player);
}
}
LinkedList<PacketExSyncPlayer> packets = new LinkedList<PacketExSyncPlayer>(); // Compile change data for external proxies
if (add.size() > 0) packets.add(new PacketExSyncPlayer(true, add.toArray(new CachedPlayer[0])));
if (remove.size() > 0) packets.add(new PacketExSyncPlayer(false, remove.toArray(new CachedPlayer[0])));
if (packets.size() > 0) {
PacketExSyncPlayer[] packet = packets.toArray(new PacketExSyncPlayer[0]);
if (api.getSubDataNetwork()[0] != null) {
((SubDataClient) api.getSubDataNetwork()[0]).sendPacket(packet);
}
}
}
});
}
}
}, TimeUnit.SECONDS.toMillis(rpec_s), TimeUnit.SECONDS.toMillis(rpec_i));
}
/**
* Port-forward Listeners
*/
@Subscribe
public void registerListener(ListenerBoundEvent e) {
if (UPnP.isUPnPAvailable()) {
if (config.get().getMap("Settings").getMap("UPnP", new ObjectMap<String>()).getBoolean("Forward-Proxy", true)) {
UPnP.openPortTCP(e.getAddress().getPort());
}
} else {
out.warn("UPnP is currently unavailable. Ports may not be automatically forwarded on this device.");
}
}
/**
* Get the Proxy Instance
*
* @return Proxy Instance
*/
@SuppressWarnings("deprecation")
public static ProxyServer getInstance() {
return SubAPI.getInstance().getInternals().proxy;
}
/**
* Get Internal Server Data
*
* @param server ServerInfo
* @return ServerData
*/
public ServerData getData(ServerInfo server) {
return (server == null)? null : servers.getOrDefault(server, null);
}
/**
* Simulate Proxy Reload
*/
@Subscribe
public void reload(ProxyReloadEvent e) {
shutdown(null);
initialize(null);
}
/**
* Un-port-forward Listeners
*/
@Subscribe
public void unregisterListener(ListenerCloseEvent e) {
if (UPnP.isUPnPAvailable()) {
if (UPnP.isMappedTCP(e.getAddress().getPort())) UPnP.closePortTCP(e.getAddress().getPort());
}
}
/**
* Reset all changes made by initialize()
*
* @see ExProxy#initialize(ProxyInitializeEvent)
*/
@Subscribe
public void shutdown(ProxyShutdownEvent e) {
try {
running = false;
Logger.get("SubServers").info("Removing synced data");
servers.clear();
reconnect = false;
ArrayList<SubDataClient> tmp = new ArrayList<SubDataClient>();
tmp.addAll(subdata.values());
for (SubDataClient client : tmp) if (client != null) {
client.close();
Util.isException(client::waitFor);
}
subdata.clear();
subdata.put(0, null);
rPlayerLinkS.clear();
rPlayerLinkP.clear();
rPlayers.clear();
} catch (Exception x) {
x.printStackTrace();
}
}
@Subscribe(order = PostOrder.LAST)
public void ping(ProxyPingEvent e) {
int offline = 0;
RegisteredServer[] overrides;
if ((overrides = SmartFallback.getForcedHosts(e.getConnection())) != null || (overrides = SmartFallback.getDNS(e.getConnection())) != null) {
for (RegisteredServer server : overrides)
if (server instanceof SubServerData && !((SubServerData) server).isRunning()) offline++;
if (offline >= overrides.length) {
e.setPing(new ServerPing(e.getPing().getVersion(), e.getPing().getPlayers().orElse(null), ChatColor.convertColor(api.getLang("SubServers", "Bungee.Ping.Offline")),
e.getPing().getFavicon().orElse(null), e.getPing().getModinfo().orElse(null)));
}
} else {
for (String name : proxy.getConfiguration().getAttemptConnectionOrder()) {
ServerData server = proxy.getServer(name).map(RegisteredServer::getServerInfo).map(this::getData).orElse(null);
if (server instanceof SubServerData && !((SubServerData) server).isRunning()) offline++;
}
if (offline >= proxy.getConfiguration().getAttemptConnectionOrder().size()) {
e.setPing(new ServerPing(e.getPing().getVersion(), e.getPing().getPlayers().orElse(null), ChatColor.convertColor(api.getLang("SubServers", "Bungee.Ping.Offline")),
e.getPing().getFavicon().orElse(null), e.getPing().getModinfo().orElse(null)));
}
}
}
@Subscribe(order = PostOrder.FIRST)
public void login(LoginEvent e) {
out.info("UUID of player " + e.getPlayer().getGameProfile().getName() + " is " + e.getPlayer().getUniqueId());
if (rPlayers.containsKey(e.getPlayer().getUniqueId())) {
Logger.get("SubServers").warning(e.getPlayer().getGameProfile().getName() + " connected, but already had a database entry");
CachedPlayer player = rPlayers.get(e.getPlayer().getUniqueId());
if (player.getProxyName() != null && player.getProxyName().equalsIgnoreCase(api.getName())) {
proxy.getPlayer(player.getUniqueId()).ifPresent(p -> p.disconnect(Component.translatable("velocity.error.already-connected-proxy", NamedTextColor.RED)));
} else {
((SubDataClient) api.getSubDataNetwork()[0]).sendPacket(new PacketDisconnectPlayer(new UUID[]{ player.getUniqueId() }, LegacyComponentSerializer.legacySection().serialize(Component.translatable("velocity.error.already-connected-proxy", NamedTextColor.RED))));
}
}
}
@Subscribe(order = PostOrder.LAST)
public void validate(ServerPreConnectEvent e) {
if (e.getPlayer().isActive()) {
ServerData server = getData(e.getOriginalServer().getServerInfo());
if (server == null || !server.canAccess(e.getPlayer())) {
if (!e.getPlayer().getCurrentServer().isPresent() || fallback.containsKey(e.getPlayer().getUniqueId())) {
if (!fallback.containsKey(e.getPlayer().getUniqueId()) || fallback.get(e.getPlayer().getUniqueId()).names.contains(e.getOriginalServer().getServerInfo().getName())) {
Component text = ChatColor.convertColor(api.getLang("SubServers", "Bungee.Restricted"));
KickedFromServerEvent kick = new KickedFromServerEvent(e.getPlayer(), e.getOriginalServer(), text, true, KickedFromServerEvent.DisconnectPlayer.create(text));
fallback(kick);
if (e.getPlayer().getCurrentServer().isPresent()) e.setResult(ServerPreConnectEvent.ServerResult.denied());
if (kick.getResult() instanceof KickedFromServerEvent.DisconnectPlayer) e.getPlayer().disconnect(text);
else if (kick.getResult() instanceof KickedFromServerEvent.RedirectPlayer) e.getPlayer().createConnectionRequest(((KickedFromServerEvent.RedirectPlayer) kick.getResult()).getServer()).fireAndForget();
}
} else {
e.getPlayer().sendMessage(ChatColor.convertColor(api.getLang("SubServers", "Bungee.Restricted")));
e.setResult(ServerPreConnectEvent.ServerResult.denied());
}
} else if (e.getPlayer().getCurrentServer().isPresent() && !fallback.containsKey(e.getPlayer().getUniqueId()) && server instanceof SubServerData && !((SubServerData) server).isRunning()) {
e.getPlayer().sendMessage(ChatColor.convertColor(api.getLang("SubServers", "Bungee.Server.Offline")));
e.setResult(ServerPreConnectEvent.ServerResult.denied());
}
if (fallback.containsKey(e.getPlayer().getUniqueId())) {
FallbackState state = fallback.get(e.getPlayer().getUniqueId());
if (state.names.contains(e.getOriginalServer().getServerInfo().getName())) {
state.remove(e.getOriginalServer().getServerInfo().getName());
} else if (e.getPlayer().getCurrentServer().isPresent()) {
fallback.remove(e.getPlayer().getUniqueId());
}
}
} else {
e.setResult(ServerPreConnectEvent.ServerResult.denied());
}
}
@SuppressWarnings("UnstableApiUsage")
@Subscribe(order = PostOrder.LAST)
public void connected(ServerPostConnectEvent e) {
ServerData server = getData(e.getPlayer().getCurrentServer().get().getServerInfo());
if (server != null) {
if (e.getPlayer().isActive()) {
synchronized (rPlayers) {
ObjectMap<String> raw = CachedPlayer.translate(e.getPlayer());
raw.set("server", server.getName());
CachedPlayer player = new CachedPlayer(raw);
rPlayerLinkP.put(player.getUniqueId(), player.getProxyName().toLowerCase());
rPlayers.put(player.getUniqueId(), player);
rPlayerLinkS.put(player.getUniqueId(), server);
if (api.getSubDataNetwork()[0] != null) {
((SubDataClient) api.getSubDataNetwork()[0]).sendPacket(new PacketExSyncPlayer(true, player));
}
}
}
if (fallback.containsKey(e.getPlayer().getUniqueId())) {
fallback.get(e.getPlayer().getUniqueId()).done(() -> {
if (fallback.containsKey(e.getPlayer().getUniqueId()) && e.getPlayer().getCurrentServer().get().getServerInfo().getName().equals(server.get().getName())) {
fallback.remove(e.getPlayer().getUniqueId());
}
}, proxy.getConfiguration().getConnectTimeout() + 500);
}
}
}
@Subscribe(order = PostOrder.LAST)
public void fallback(KickedFromServerEvent e) {
if (e.getPlayer().isActive() && config.get().getMap("Settings").getMap("Smart-Fallback", new ObjectMap<>()).getBoolean("Fallback", true)) {
FallbackState state;
boolean init = !fallback.containsKey(e.getPlayer().getUniqueId());
if (init) {
Map<String, RegisteredServer> map = SmartFallback.getFallbackServers(e.getPlayer());
map.remove(e.getServer().getServerInfo().getName());
state = new FallbackState(e.getPlayer().getUniqueId(), map, e.getServerKickReason().orElse(Component.text("")));
if (e.getPlayer().getCurrentServer().isPresent())
state.remove(e.getPlayer().getCurrentServer().get().getServerInfo().getName());
} else {
state = fallback.get(e.getPlayer().getUniqueId());
LinkedList<RegisteredServer> tmp = new LinkedList<>(state.servers);
for (RegisteredServer server : tmp) if (server.getServerInfo().equals(e.getServer().getServerInfo()))
state.remove(server);
}
RegisteredServer rs = e.getServer();
ServerData server = getData(rs.getServerInfo());
e.getPlayer().sendMessage(ChatColor.convertColor(api.getLang("SubServers", "Bungee.Feature.Smart-Fallback")
.replace("$str$", (server != null)? server.getDisplayName() : rs.getServerInfo().getName()))
.replaceText(TextReplacementConfig.builder().match("\\$msg\\$").replacement(e.getServerKickReason().orElse(Component.text(""))).build())
);
if (state.servers.isEmpty()) {
if (e.getPlayer().getCurrentServer().isPresent()) {
fallback.remove(e.getPlayer().getUniqueId());
rs = e.getPlayer().getCurrentServer().get().getServer();
server = getData(rs.getServerInfo());
e.setResult(KickedFromServerEvent.Notify.create(ChatColor.convertColor(api.getLang("SubServers", "Bungee.Feature.Smart-Fallback.Result").replace("$str$", (server != null)? server.getDisplayName() : rs.getServerInfo().getName()))));
} else {
e.setResult(KickedFromServerEvent.DisconnectPlayer.create(state.reason));
}
} else {
if (init) fallback.put(e.getPlayer().getUniqueId(), state);
rs = state.servers.getFirst();
server = getData(rs.getServerInfo());
e.setResult(KickedFromServerEvent.RedirectPlayer.create(rs, ChatColor.convertColor(api.getLang("SubServers", "Bungee.Feature.Smart-Fallback.Result").replace("$str$", (server != null)? server.getDisplayName() : rs.getServerInfo().getName()))));
}
}
}
@Subscribe(order = PostOrder.LAST)
public void disconnected(DisconnectEvent e) {
UUID id = e.getPlayer().getUniqueId();
fallback.remove(id);
SubCommand.permitted.remove(id);
synchronized (rPlayers) {
if (rPlayers.containsKey(id) && (!rPlayerLinkP.containsKey(id) || rPlayerLinkP.get(id).equalsIgnoreCase(api.getName()))) {
CachedPlayer player = rPlayers.get(id);
rPlayerLinkS.remove(id);
rPlayerLinkP.remove(id);
rPlayers.remove(id);
if (api.getSubDataNetwork()[0] != null) {
((SubDataClient) api.getSubDataNetwork()[0]).sendPacket(new PacketExSyncPlayer(false, player));
}
}
}
}
@SuppressWarnings("unchecked")
private Map<Integer, UUID> getSubDataAsMap(net.ME1312.SubServers.Client.Common.Network.API.Server server) {
HashMap<Integer, UUID> map = new HashMap<Integer, UUID>();
ObjectMap<Integer> subdata = new ObjectMap<Integer>((Map<Integer, ?>) server.getRaw().getObject("subdata"));
for (Integer channel : subdata.getKeys()) map.put(channel, subdata.getUUID(channel));
return map;
}
@Subscribe(order = PostOrder.FIRST)
public void add(SubAddServerEvent e) {
api.getServer(e.getServer(), server -> {
if (server != null) {
ServerData data;
if (server instanceof net.ME1312.SubServers.Client.Common.Network.API.SubServer) {
data = new SubServerData(server.getSignature(), server.getName(), server.getDisplayName(), server.getAddress(),
getSubDataAsMap(server), server.getMotd(), server.isHidden(), server.isRestricted(), server.getWhitelist(), ((net.ME1312.SubServers.Client.Common.Network.API.SubServer) server).isRunning());
Logger.get("SubServers").info("Added SubServer: " + e.getServer());
} else {
data = new ServerData(server.getSignature(), server.getName(), server.getDisplayName(), server.getAddress(),
getSubDataAsMap(server), server.getMotd(), server.isHidden(), server.isRestricted(), server.getWhitelist());
Logger.get("SubServers").info("Added Server: " + e.getServer());
}
ServerData old = servers.put(data.get(), data);
if (old != null && proxy.getServer(data.getName()).isPresent())
proxy.unregisterServer(old.get());
proxy.registerServer(data.get());
} else System.out.println("PacketDownloadServerInfo(" + e.getServer() + ") returned with an invalid response");
});
}
public Boolean merge(net.ME1312.SubServers.Client.Common.Network.API.Server server) {
ServerData current = proxy.getServer(server.getName()).map(RegisteredServer::getServerInfo).map(this::getData).orElse(null);
if (server instanceof net.ME1312.SubServers.Client.Common.Network.API.SubServer || !(current instanceof SubServerData)) {
if (current == null || !current.getSignature().equals(server.getSignature())) {
ServerData data;
if (server instanceof net.ME1312.SubServers.Client.Common.Network.API.SubServer) {
data = new SubServerData(server.getSignature(), server.getName(), server.getDisplayName(), server.getAddress(),
getSubDataAsMap(server), server.getMotd(), server.isHidden(), server.isRestricted(), server.getWhitelist(), ((net.ME1312.SubServers.Client.Common.Network.API.SubServer) server).isRunning());
} else {
data = new ServerData(server.getSignature(), server.getName(), server.getDisplayName(), server.getAddress(),
getSubDataAsMap(server), server.getMotd(), server.isHidden(), server.isRestricted(), server.getWhitelist());
}
ServerData old = servers.put(data.get(), data);
if (old != null && proxy.getServer(data.getName()).isPresent())
proxy.unregisterServer(old.get());
proxy.registerServer(data.get());
Logger.get("SubServers").info("Added "+((server instanceof net.ME1312.SubServers.Client.Common.Network.API.SubServer)?"Sub":"")+"Server: " + server.getName());
return true;
} else {
if (server instanceof net.ME1312.SubServers.Client.Common.Network.API.SubServer) {
if (((net.ME1312.SubServers.Client.Common.Network.API.SubServer) server).isRunning() != ((SubServerData) current).isRunning())
((SubServerData) current).setRunning(((net.ME1312.SubServers.Client.Common.Network.API.SubServer) server).isRunning());
}
if (!server.getMotd().equals(current.getMotd()))
current.setMotd(server.getMotd());
if (server.isHidden() != current.isHidden())
current.setHidden(server.isHidden());
if (server.isRestricted() != current.isRestricted())
current.setRestricted(server.isRestricted());
if (!server.getDisplayName().equals(current.getDisplayName()))
current.setDisplayName(server.getDisplayName());
Logger.get("SubServers").info("Re-added "+((server instanceof net.ME1312.SubServers.Client.Common.Network.API.SubServer)?"Sub":"")+"Server: " + server.getName());
return false;
}
}
return null;
}
@Subscribe(order = PostOrder.FIRST)
public void start(SubStartEvent e) {
ServerData server = proxy.getServer(e.getServer()).map(RegisteredServer::getServerInfo).map(this::getData).orElse(null);
if (server instanceof SubServerData) ((SubServerData) server).setRunning(true);
}
@Subscribe(order = PostOrder.FIRST)
public void stop(SubStoppedEvent e) {
ServerData server = proxy.getServer(e.getServer()).map(RegisteredServer::getServerInfo).map(this::getData).orElse(null);
if (server instanceof SubServerData) ((SubServerData) server).setRunning(false);
}
@Subscribe(order = PostOrder.FIRST)
public void remove(SubRemoveServerEvent e) {
ServerData server = proxy.getServer(e.getServer()).map(RegisteredServer::getServerInfo).map(this::getData).orElse(null);
if (server != null) {
servers.remove(server.get());
proxy.unregisterServer(server.get());
Logger.get("SubServers").info("Removed Server: " + e.getServer());
}
}
}

View File

@ -0,0 +1,102 @@
package net.ME1312.SubServers.Velocity.Library.Compatibility;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import java.util.Arrays;
/**
* Color Code Converter Enum
*/
public enum ChatColor {
AQUA('b'),
BLACK('0'),
BLUE('9'),
BOLD('l'),
DARK_AQUA('3'),
DARK_BLUE('1'),
DARK_GRAY('8'),
DARK_GREEN('2'),
DARK_PURPLE('5'),
DARK_RED('4'),
GOLD('6'),
GRAY('7'),
GREEN('a'),
ITALIC('o'),
LIGHT_PURPLE('d'),
MAGIC('k'),
RED('c'),
RESET('r'),
STRIKETHROUGH('m'),
UNDERLINE('n'),
WHITE('f'),
YELLOW('e');
private final Character minecraft;
ChatColor(Character minecraft) {
this.minecraft = minecraft;
}
/**
* Get this color as a Minecraft Color Code
*
* @return Minecraft Color Code
*/
public String asMinecraftCode() {
return new String(new char[]{'\u00A7', minecraft});
}
@Override
public String toString() {
return asMinecraftCode();
}
/**
* Parse Minecraft color codes starting with character
*
* @param character Character
* @param str String to parse
* @return Minecraft colored string
*/
public static String parseColor(char character, String str) {
for (ChatColor color : Arrays.asList(ChatColor.values())) {
str = str.replace(new String(new char[]{character, color.minecraft}), color.asMinecraftCode());
}
return str;
}
/**
* Convert Minecraft color codes to Sponge Text
*
* @param str Minecraft colored string
* @return Sponge Text
*/
public static TextComponent convertColor(String str) {
return LegacyComponentSerializer.legacySection().deserialize(str);
}
/**
* Convert Minecraft color codes starting with character to Sponge Text
*
* @param character Character
* @param str String to parse
* @return Sponge Text
*/
public static TextComponent convertColor(char character, String str) {
return LegacyComponentSerializer.legacy(character).deserialize(str);
}
/**
* Removes all Minecraft color codes from a string
*
* @param str String to parse
* @return String without color
*/
public static String stripColor(String str) {
for (ChatColor color : Arrays.asList(ChatColor.values())) {
str = str.replace(color.asMinecraftCode(), "");
}
return str;
}
}

View File

@ -0,0 +1,50 @@
package net.ME1312.SubServers.Velocity.Library.Compatibility;
import java.util.HashMap;
import java.util.logging.Handler;
import java.util.logging.Level;
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 org.apache.logging.log4j.Logger parent;
/**
* Get a logger
*
* @param prefix Prefix
* @return Logger
*/
public static java.util.logging.Logger get(String prefix) {
if (!existing.keySet().contains(prefix)) {
java.util.logging.Logger log = java.util.logging.Logger.getAnonymousLogger();
log.setUseParentHandlers(false);
log.addHandler(new Handler() {
@Override
public void publish(LogRecord record) {
String message = prefix + " > " + record.getMessage();
if (record.getLevel() == Level.INFO) {
parent.info(message, record.getParameters());
} else if (record.getLevel() == Level.WARNING) {
parent.warn(message, record.getParameters());
} else if (record.getLevel() == Level.SEVERE) {
parent.error(message, record.getParameters());
} else if (record.getLevel().intValue() < Level.FINE.intValue()) {
parent.trace(message, record.getParameters());
} else if (record.getLevel().intValue() < Level.INFO.intValue()) {
parent.debug(message, record.getParameters());
}
}
@Override
public void flush() {}
public void close() {}
});
existing.put(prefix, log);
}
return existing.get(prefix);
}
}

View File

@ -0,0 +1,114 @@
package net.ME1312.SubServers.Velocity.Library;
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.Velocity.Library.Compatibility.Logger;
import net.ME1312.SubServers.Velocity.SubAPI;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
/**
* SubServers Configuration Updater
*/
public class ConfigUpdater {
private static final Version UNSIGNED = new Version(new SimpleDateFormat("yy'w'ww'zz'").format(Calendar.getInstance().getTime()));
/**
* Update SubServers' config.yml
*
* @param file File to bring up-to-date
*/
public static void updateConfig(File file) throws IOException {
YAMLConfig config = new YAMLConfig(file);
YAMLSection existing = config.get().clone();
YAMLSection updated = existing.clone();
YAMLSection rewritten = new YAMLSection();
Version was = existing.getMap("Settings", new ObjectMap<>()).getVersion("Version", new Version(0));
Version now = SubAPI.getInstance().getPluginBuild();
int i = 0;
if (now == null) now = UNSIGNED;
if (!existing.contains("Settings") || !existing.getMap("Settings").contains("Version")) {
i++;
Logger.get("SubServers").info("Created ./SubServers/sync.yml");
} else {
if (was.compareTo(new Version("19w17a")) <= 0) {
i++;
} if (was.compareTo(new Version("20w34a")) <= 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);
}
if (existing.getMap("Settings", new YAMLSection()).contains("Override-Bungee-Commands") && existing.getMap("Settings").isBoolean("Override-Bungee-Commands")) {
List<String> overrides = new LinkedList<>();
if (!existing.getMap("Settings").getBoolean("Override-Bungee-Commands")) {
overrides.add("/server");
overrides.add("/glist");
}
updated.getMap("Settings").set("Disabled-Overrides", overrides);
}
existing = updated.clone();
i++;
}// if (was.compareTo(new Version("99w99a")) <= 0) {
// // do something
// i++
//}
if (i > 0) Logger.get("SubServers").info("Updated ./SubServers/sync.yml (" + i + " pass" + ((i != 1)?"es":"") + ")");
}
if (i > 0) {
YAMLSection settings = new YAMLSection();
settings.set("Version", ((now.compareTo(was) <= 0)?was:now).toString());
if (updated.getMap("Settings", new YAMLSection()).contains("RPEC-Check-Interval")) settings.set("RPEC-Check-Interval", updated.getMap("Settings").getRawString("RPEC-Check-Interval"));
settings.set("Disabled-Overrides", updated.getMap("Settings", new YAMLSection()).getRawStringList("Disabled-Overrides", Collections.emptyList()));
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);
YAMLSection subdata = new YAMLSection();
if (updated.getMap("Settings", new YAMLSection()).getMap("SubData", new YAMLSection()).contains("Name")) subdata.set("Name", updated.getMap("Settings").getMap("SubData").getRawString("Name"));
subdata.set("Address", updated.getMap("Settings", new YAMLSection()).getMap("SubData", new YAMLSection()).getRawString("Address", "127.0.0.1:4391"));
if (updated.getMap("Settings", new YAMLSection()).getMap("SubData", new YAMLSection()).contains("Password")) subdata.set("Password", updated.getMap("Settings").getMap("SubData").getRawString("Password"));
if (updated.getMap("Settings", new YAMLSection()).getMap("SubData", new YAMLSection()).contains("Reconnect")) subdata.set("Reconnect", updated.getMap("Settings").getMap("SubData").getInt("Reconnect"));
settings.set("SubData", subdata);
rewritten.set("Settings", settings);
/*
YAMLSection sync = new YAMLSection();
sync.set("Disabled-Commands", updated.getMap("Settings", new YAMLSection()).getBoolean("Disabled-Commands", false));
sync.set("Forced-Hosts", updated.getMap("Settings", new YAMLSection()).getBoolean("Forced-Hosts", true));
sync.set("Motd", updated.getMap("Settings", new YAMLSection()).getBoolean("Motd", false));
sync.set("Player-Limit", updated.getMap("Settings", new YAMLSection()).getBoolean("Player-Limit", false));
sync.set("Server-Priorities", updated.getMap("Settings", new YAMLSection()).getBoolean("Server-Priorities", true));
rewritten.set("Sync", sync); */
config.set(rewritten);
config.save();
}
}
}

View File

@ -0,0 +1,19 @@
package net.ME1312.SubServers.Velocity.Library.Fallback;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.server.RegisteredServer;
/**
* 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(Player player, RegisteredServer server);
}

View File

@ -0,0 +1,72 @@
package net.ME1312.SubServers.Velocity.Library.Fallback;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import net.kyori.adventure.text.Component;
import java.util.*;
/**
* Fallback Player State Class
*/
public class FallbackState {
public final UUID player;
public final LinkedList<String> names;
public final LinkedList<RegisteredServer> servers;
public final Component reason;
private Map<String, RegisteredServer> map;
private Timer finish;
/**
* Smart Fallback State Container
*
* @param player Player
* @param servers Fallback Servers
* @param reason Original Disconnect Reason
*/
public FallbackState(UUID player, Map<String, RegisteredServer> servers, Component reason) {
this.player = player;
this.map = servers;
this.names = new LinkedList<>(servers.keySet());
this.servers = new LinkedList<>(servers.values());
this.reason = reason;
}
/**
* <i>Use</i> a server
*
* @param name Server name to remove
*/
public void remove(String name) {
servers.remove(map.get(name));
names.remove(name);
map.remove(name);
}
/**
* <i>Use</i> a server
*
* @param server Server to remove
*/
public void remove(RegisteredServer server) {
map.remove(server.getServerInfo().getName());
names.remove(server.getServerInfo().getName());
servers.remove(server);
}
/**
* Finish the process
*
* @param callback Finishing callback
* @param delay Delay for determining stability
*/
public void done(Runnable callback, long delay) {
if (finish != null) finish.cancel();
(finish = new Timer("SubServers.Bungee::Fallback_Limbo_Timer(" + player + ')')).schedule(new TimerTask() {
@Override
public void run() {
if (callback != null) callback.run();
finish.cancel();
}
}, delay);
}
}

View File

@ -0,0 +1,183 @@
package net.ME1312.SubServers.Velocity.Library.Fallback;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubServers.Velocity.ExProxy;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.player.PlayerChooseInitialServerEvent;
import com.velocitypowered.api.proxy.InboundConnection;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* Smart Fallback Handler Class
*/
public class SmartFallback {
private static List<FallbackInspector> inspectors = new CopyOnWriteArrayList<FallbackInspector>();
public static boolean dns_forward = false;
public SmartFallback(ObjectMap<String> settings) {
dns_forward = settings.getBoolean("DNS-Forward", false);
}
@Subscribe
public void getServer(PlayerChooseInitialServerEvent e) {
RegisteredServer[] overrides;
if ((overrides = getForcedHosts(e.getPlayer())) != null
|| (overrides = getDNS(e.getPlayer())) != null) {
e.setInitialServer(overrides[0]);
} else {
Map<String, RegisteredServer> fallbacks = getFallbackServers(e.getPlayer());
if (/*(override = getReconnectServer(player)) != null || */!fallbacks.isEmpty()) {
e.setInitialServer((overrides != null)? overrides[0] : new LinkedList<>(fallbacks.values()).getFirst());
} else {
e.setInitialServer(null);
}
}
}
/**
* Grabs the Forced Host Server for this connection
*
* @param connection Connection to check
* @return Forced Host Servers (or null if there are none)
*/
public static RegisteredServer[] getForcedHosts(InboundConnection connection) {
if (!connection.getVirtualHost().isPresent()) {
return null;
} else {
List<String> names = ExProxy.getInstance().getConfiguration().getForcedHosts().get(connection.getVirtualHost().get().getHostString());
if (names == null) {
return null;
} else {
LinkedList<RegisteredServer> forced = new LinkedList<>();
for (String name : names) {
Optional<RegisteredServer> server = ExProxy.getInstance().getServer(name);
server.ifPresent(forced::add);
}
return (forced.size() == 0)? null : forced.toArray(new RegisteredServer[0]);
}
}
}
/**
* Grabs the Server that a connection's DNS matches
*
* @param connection Connection to check
* @return DNS Forward Server
*/
public static RegisteredServer[] getDNS(InboundConnection connection) {
if (!connection.getVirtualHost().isPresent() || !dns_forward) {
return null;
} else {
RegisteredServer server = null;
String dns = connection.getVirtualHost().get().getHostString().toLowerCase();
for (RegisteredServer s : ExProxy.getInstance().getAllServers()) {
if (dns.startsWith(s.getServerInfo().getName().toLowerCase() + '.'))
if (server == null || server.getServerInfo().getName().length() < s.getServerInfo().getName().length())
server = s;
}
return (server == null)? null : new RegisteredServer[]{ server };
}
}
/**
* Grabs the Server that a player was last connected to
*
* @param player Player
* @return Reconnect Server
*//*
public static ServerInfo getReconnectServer(Player 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
*
* @return Fallback Server Map (with legacy bungee case-sensitive keys)
*/
public static Map<String, RegisteredServer> getFallbackServers() {
return getFallbackServers(null);
}
/**
* Generates a <i>smart</i> sorted map of fallback servers using a generated confidence score
*
* @param player Player that is requesting fallback servers
* @return Fallback Server Map (with legacy bungee case-sensitive keys)
*/
public static Map<String, RegisteredServer> getFallbackServers(Player player) {
TreeMap<Double, List<RegisteredServer>> score = new TreeMap<Double, List<RegisteredServer>>(Collections.reverseOrder());
for (String name : ExProxy.getInstance().getConfiguration().getAttemptConnectionOrder()) {
RegisteredServer server = ExProxy.getInstance().getServer(name).orElse(null);
if (server != null) {
boolean valid = true;
double confidence = 0;
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.getServerInfo().getName()).printStackTrace();
}
if (valid) {
List<RegisteredServer> servers = (score.keySet().contains(confidence))?score.get(confidence):new LinkedList<RegisteredServer>();
servers.add(server);
score.put(confidence, servers);
}
}
}
Random random = new Random();
LinkedHashMap<String, RegisteredServer> map = new LinkedHashMap<String, RegisteredServer>();
for (List<RegisteredServer> servers : score.values()) {
while (!servers.isEmpty()) {
RegisteredServer next = servers.get(random.nextInt(servers.size()));
map.put(next.getServerInfo().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));
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
package net.ME1312.SubServers.Velocity.Library;
/**
* SubEvent Layout Class
*/
public interface SubEvent {
}

View File

@ -0,0 +1,61 @@
package net.ME1312.SubServers.Velocity.Network.Packet;
import net.ME1312.Galaxi.Library.Callback.Callback;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubData.Client.Protocol.Forwardable;
import net.ME1312.SubData.Client.Protocol.PacketObjectIn;
import net.ME1312.SubData.Client.Protocol.PacketObjectOut;
import net.ME1312.SubData.Client.SubDataSender;
import java.util.HashMap;
import java.util.UUID;
/**
* Check Permission Packet
*/
public class PacketCheckPermission implements Forwardable, PacketObjectIn<Integer>, PacketObjectOut<Integer> {
static HashMap<UUID, Callback<Boolean>[]> callbacks = new HashMap<UUID, Callback<Boolean>[]>();
private UUID player;
private String permission;
private UUID tracker;
/**
* New PacketCheckPermission (In)
*/
public PacketCheckPermission() {}
/**
* New PacketCheckPermission (Out)
*
* @param player Player to check on
* @param permission Permission to check
* @param callback Callbacks
*/
@SafeVarargs
public PacketCheckPermission(UUID player, String permission, Callback<Boolean>... callback) {
this.player = player;
this.permission = permission;
this.tracker = Util.getNew(callbacks.keySet(), UUID::randomUUID);
callbacks.put(tracker, callback);
}
@Override
public ObjectMap<Integer> send(SubDataSender client) throws Throwable {
ObjectMap<Integer> data = new ObjectMap<Integer>();
data.set(0x0000, tracker);
data.set(0x0001, player);
data.set(0x0002, permission);
return data;
}
@Override
public void receive(SubDataSender client, ObjectMap<Integer> data) throws Throwable {
client.sendPacket(new PacketCheckPermissionResponse(data.getUUID(0x0001), data.getRawString(0x0002), (data.contains(0x0000))?data.getUUID(0x0000):null));
}
@Override
public int version() {
return 0x0001;
}
}

View File

@ -0,0 +1,59 @@
package net.ME1312.SubServers.Velocity.Network.Packet;
import net.ME1312.Galaxi.Library.Callback.Callback;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubData.Client.Protocol.Forwardable;
import net.ME1312.SubData.Client.Protocol.PacketObjectIn;
import net.ME1312.SubData.Client.Protocol.PacketObjectOut;
import net.ME1312.SubData.Client.SubDataSender;
import net.ME1312.SubServers.Velocity.ExProxy;
import java.util.UUID;
import static net.ME1312.SubServers.Velocity.Network.Packet.PacketCheckPermission.callbacks;
/**
* Check Permission Response Packet
*/
public class PacketCheckPermissionResponse implements Forwardable, PacketObjectIn<Integer>, PacketObjectOut<Integer> {
private boolean result;
private UUID tracker;
/**
* New PacketCheckPermissionResponse (In)
*/
public PacketCheckPermissionResponse() {}
/**
* New PacketCheckPermissionResponse (Out)
*
* @param player Player to check on
* @param permission Permission to check
* @param tracker Receiver ID
*/
public PacketCheckPermissionResponse(UUID player, String permission, UUID tracker) {
this.result = Util.getDespiteException(() -> ExProxy.getInstance().getPlayer(player).get().hasPermission(permission), false);
this.tracker = tracker;
}
@Override
public ObjectMap<Integer> send(SubDataSender client) throws Throwable {
ObjectMap<Integer> data = new ObjectMap<Integer>();
data.set(0x0000, tracker);
data.set(0x0001, result);
return data;
}
@Override
public void receive(SubDataSender client, ObjectMap<Integer> data) throws Throwable {
for (Callback<Boolean> callback : callbacks.get(data.getUUID(0x0000))) callback.run(data.getBoolean(0x0001));
callbacks.remove(data.getUUID(0x0000));
}
@Override
public int version() {
return 0x0001;
}
}

View File

@ -0,0 +1,49 @@
package net.ME1312.SubServers.Velocity.Network.Packet;
import net.ME1312.Galaxi.Library.Container.ContainedPair;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
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.Velocity.ExProxy;
import net.ME1312.SubServers.Velocity.Library.Compatibility.Logger;
import java.util.Calendar;
/**
* Download Lang Packet
*/
public class PacketDownloadLang implements PacketObjectIn<Integer>, PacketOut {
private ExProxy plugin;
/**
* New PacketDownloadLang (In)
*
* @param plugin SubServers.Client
*/
public PacketDownloadLang(ExProxy plugin) {
if (Util.isNull(plugin)) throw new NullPointerException();
this.plugin = plugin;
}
/**
* New PacketDownloadLang (Out)
*/
public PacketDownloadLang() {}
@Override
public void receive(SubDataSender client, ObjectMap<Integer> data) {
try {
Util.reflect(ExProxy.class.getDeclaredField("lang"), plugin, new ContainedPair<>(Calendar.getInstance().getTime().getTime(), data.getObject(0x0001)));
Logger.get("SubData").info("Lang Settings Downloaded");
} catch (IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();
}
}
@Override
public int version() {
return 0x0001;
}
}

View File

@ -0,0 +1,79 @@
package net.ME1312.SubServers.Velocity.Network.Packet;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.SubData.Client.Protocol.PacketObjectIn;
import net.ME1312.SubData.Client.Protocol.PacketObjectOut;
import net.ME1312.SubData.Client.SubDataSender;
import net.ME1312.SubServers.Velocity.ExProxy;
import net.ME1312.SubServers.Velocity.Library.Compatibility.ChatColor;
import com.velocitypowered.api.proxy.Player;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
/**
* Disconnect External Player Packet
*/
public class PacketExDisconnectPlayer implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
private ExProxy plugin;
private int response;
private UUID tracker;
/**
* New PacketExDisconnectPlayer (In)
*/
public PacketExDisconnectPlayer(ExProxy plugin) {
this.plugin = plugin;
}
/**
* New PacketExDisconnectPlayer (Out)
*
* @param response Response ID
* @param tracker Receiver ID
*/
public PacketExDisconnectPlayer(int response, UUID tracker) {
this.response = response;
this.tracker = tracker;
}
@Override
public ObjectMap<Integer> send(SubDataSender client) {
ObjectMap<Integer> json = new ObjectMap<Integer>();
if (tracker != null) json.set(0x0000, tracker);
json.set(0x0001, response);
return json;
}
@SuppressWarnings("deprecation")
@Override
public void receive(SubDataSender client, ObjectMap<Integer> data) {
UUID tracker = (data.contains(0x0000)?data.getUUID(0x0000):null);
List<UUID> ids = data.getUUIDList(0x0001);
try {
Component message = (data.contains(0x0002))? ChatColor.convertColor(data.getRawString(0x0002)) : Component.text().build();
int failures = 0;
for (UUID id : ids) {
Optional<Player> local = ExProxy.getInstance().getPlayer(id);
if (local.isPresent()) {
local.get().disconnect(message);
} else {
++failures;
}
}
client.sendPacket(new PacketExDisconnectPlayer(failures, tracker));
} catch (Throwable e) {
client.sendPacket(new PacketExDisconnectPlayer(ids.size(), tracker));
e.printStackTrace();
}
}
@Override
public int version() {
return 0x0001;
}
}

View File

@ -0,0 +1,103 @@
package net.ME1312.SubServers.Velocity.Network.Packet;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.SubData.Client.Protocol.PacketObjectIn;
import net.ME1312.SubData.Client.Protocol.PacketObjectOut;
import net.ME1312.SubData.Client.SubDataSender;
import net.ME1312.SubServers.Velocity.ExProxy;
import net.ME1312.SubServers.Velocity.Library.Compatibility.ChatColor;
import com.velocitypowered.api.proxy.Player;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
/**
* Message External Player Packet
*/
public class PacketExMessagePlayer implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
private ExProxy plugin;
private int response;
private UUID tracker;
/**
* New PacketExMessagePlayer (In)
*/
public PacketExMessagePlayer(ExProxy plugin) {
this.plugin = plugin;
}
/**
* New PacketExMessagePlayer (Out)
*
* @param response Response ID
* @param tracker Receiver ID
*/
public PacketExMessagePlayer(int response, UUID tracker) {
this.response = response;
this.tracker = tracker;
}
@Override
public ObjectMap<Integer> send(SubDataSender client) {
ObjectMap<Integer> json = new ObjectMap<Integer>();
if (tracker != null) json.set(0x0000, tracker);
json.set(0x0001, response);
return json;
}
@SuppressWarnings("deprecation")
@Override
public void receive(SubDataSender client, ObjectMap<Integer> data) {
UUID tracker = (data.contains(0x0000)?data.getUUID(0x0000):null);
List<UUID> ids = (data.contains(0x0001)?data.getUUIDList(0x0001):null);
try {
Component[] legacy = null;
Component[] components = null;
if (data.contains(0x0002)) {
List<String> messages = data.getRawStringList(0x0002);
legacy = new Component[messages.size()];
for (int i = 0; i < legacy.length; ++i) legacy[i] = ChatColor.convertColor(messages.get(i));
}
if (data.contains(0x0003)) {
List<String> messages = data.getRawStringList(0x0003);
components = new Component[messages.size()];
for (int i = 0; i < components.length; ++i) components[i] = GsonComponentSerializer.gson().deserialize(messages.get(i));
}
int failures = 0;
if (ids == null || ids.size() == 0) {
if (legacy != null) for (Component c : legacy)
ExProxy.getInstance().sendMessage(c);
if (components != null) for (Component c : components)
ExProxy.getInstance().sendMessage(c);
} else {
for (UUID id : ids) {
Optional<Player> local = ExProxy.getInstance().getPlayer(id);
if (local.isPresent()) {
if (legacy != null) for (Component c : legacy)
local.get().sendMessage(c);
if (components != null) for (Component c : components)
local.get().sendMessage(c);
} else {
++failures;
}
}
}
client.sendPacket(new PacketExMessagePlayer(failures, tracker));
} catch (Throwable e) {
client.sendPacket(new PacketExMessagePlayer((ids == null || ids.size() == 0)? 1 : ids.size(), tracker));
e.printStackTrace();
}
}
@Override
public int version() {
return 0x0001;
}
}

View File

@ -0,0 +1,100 @@
package net.ME1312.SubServers.Velocity.Network.Packet;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubData.Client.Protocol.PacketObjectIn;
import net.ME1312.SubData.Client.Protocol.PacketObjectOut;
import net.ME1312.SubData.Client.SubDataSender;
import net.ME1312.SubServers.Velocity.ExProxy;
import net.ME1312.SubServers.Velocity.Server.CachedPlayer;
import net.ME1312.SubServers.Velocity.Server.ServerData;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/**
* External Player Sync Packet
*/
public class PacketExSyncPlayer implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
private ExProxy plugin;
private Boolean mode;
private CachedPlayer[] values;
/**
* New PacketExSyncPlayer (In)
*
* @param plugin SubPlugin
*/
public PacketExSyncPlayer(ExProxy plugin) {
if (Util.isNull(plugin)) throw new NullPointerException();
this.plugin = plugin;
}
/**
* New PacketExSyncPlayer (Out)
*
* @param mode Update Mode (true for add, false for remove, null for reset)
* @param values RemotePlayers
*/
public PacketExSyncPlayer(Boolean mode, CachedPlayer... values) {
this.mode = mode;
this.values = values;
}
@Override
public ObjectMap<Integer> send(SubDataSender client) {
ObjectMap<Integer> data = new ObjectMap<Integer>();
data.set(0x0001, mode);
if (values != null) {
ArrayList<ObjectMap<String>> list = new ArrayList<ObjectMap<String>>();
for (CachedPlayer value : values) list.add(value.getRaw());
data.set(0x0002, list);
}
return data;
}
@SuppressWarnings("unchecked")
@Override
public void receive(SubDataSender client, ObjectMap<Integer> data) {
String proxy = (data.contains(0x0000)?data.getRawString(0x0000).toLowerCase():null);
synchronized (plugin.rPlayers) {
if (data.getBoolean(0x0001) == null) {
for (UUID id : Util.getBackwards(plugin.rPlayerLinkP, proxy)) {
plugin.rPlayerLinkS.remove(id);
plugin.rPlayerLinkP.remove(id);
plugin.rPlayers.remove(id);
}
}
if (data.getBoolean(0x0001) != Boolean.FALSE) {
if (data.contains(0x0002)) for (Map<String, Object> object : (List<Map<String, Object>>) data.getObjectList(0x0002)) {
ServerData server = (object.getOrDefault("server", null) != null)?ExProxy.getInstance().getServer(object.get("server").toString()).map(RegisteredServer::getServerInfo).map(plugin::getData).orElse(null):null;
CachedPlayer player = new CachedPlayer(new ObjectMap<>(object));
plugin.rPlayerLinkP.put(player.getUniqueId(), proxy);
plugin.rPlayers.put(player.getUniqueId(), player);
if (server != null) plugin.rPlayerLinkS.put(player.getUniqueId(), server);
}
} else {
if (data.contains(0x0002)) for (Map<String, Object> object : (List<Map<String, Object>>) data.getObjectList(0x0002)) {
UUID id = UUID.fromString(object.get("id").toString());
// Don't accept removal requests when we're managing players
if ((!plugin.rPlayerLinkP.containsKey(id) || !plugin.rPlayerLinkP.get(id).equalsIgnoreCase(plugin.api.getName().toLowerCase()))) {
plugin.rPlayerLinkS.remove(id);
plugin.rPlayerLinkP.remove(id);
plugin.rPlayers.remove(id);
}
}
}
}
}
@Override
public int version() {
return 0x0001;
}
}

View File

@ -0,0 +1,80 @@
package net.ME1312.SubServers.Velocity.Network.Packet;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.SubData.Client.Protocol.PacketObjectIn;
import net.ME1312.SubData.Client.Protocol.PacketObjectOut;
import net.ME1312.SubData.Client.SubDataSender;
import net.ME1312.SubServers.Velocity.ExProxy;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
/**
* Transfer External Player Packet
*/
public class PacketExTransferPlayer implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
private ExProxy plugin;
private int response;
private UUID tracker;
/**
* New PacketExTransferPlayer (In)
*/
public PacketExTransferPlayer(ExProxy plugin) {
this.plugin = plugin;
}
/**
* New PacketExTransferPlayer (Out)
*
* @param response Response ID
* @param tracker Receiver ID
*/
public PacketExTransferPlayer(int response, UUID tracker) {
this.response = response;
this.tracker = tracker;
}
@Override
public ObjectMap<Integer> send(SubDataSender client) {
ObjectMap<Integer> json = new ObjectMap<Integer>();
if (tracker != null) json.set(0x0000, tracker);
json.set(0x0001, response);
return json;
}
@Override
public void receive(SubDataSender client, ObjectMap<Integer> data) {
UUID tracker = (data.contains(0x0000)?data.getUUID(0x0000):null);
List<UUID> ids = data.getUUIDList(0x0001);
try {
Optional<RegisteredServer> server = ExProxy.getInstance().getServer(data.getRawString(0x0002).toLowerCase());
if (server.isPresent()) {
int failures = 0;
for (UUID id : ids) {
Optional<Player> local = ExProxy.getInstance().getPlayer(id);
if (local.isPresent()) {
local.get().createConnectionRequest(server.get()).fireAndForget();
} else {
++failures;
}
}
client.sendPacket(new PacketExTransferPlayer(failures, tracker));
} else {
client.sendPacket(new PacketExTransferPlayer(ids.size(), tracker));
}
} catch (Throwable e) {
client.sendPacket(new PacketExTransferPlayer(ids.size(), tracker));
e.printStackTrace();
}
}
@Override
public int version() {
return 0x0001;
}
}

View File

@ -0,0 +1,65 @@
package net.ME1312.SubServers.Velocity.Network.Packet;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.SubData.Client.Protocol.PacketObjectIn;
import net.ME1312.SubData.Client.SubDataSender;
import net.ME1312.SubServers.Velocity.ExProxy;
import net.ME1312.SubServers.Velocity.Library.Compatibility.ChatColor;
import net.ME1312.SubServers.Velocity.Server.ServerData;
import com.velocitypowered.api.proxy.server.RegisteredServer;
/**
* Server Edit Notification Packet
*/
public class PacketInExEditServer implements PacketObjectIn<Integer> {
private ExProxy plugin;
/**
* New PacketExControlServer (In)
*/
public PacketInExEditServer(ExProxy plugin) {
this.plugin = plugin;
}
@Override
public void receive(SubDataSender client, ObjectMap<Integer> data) {
ServerData server = ExProxy.getInstance().getServer(data.getRawString(0x0000)).map(RegisteredServer::getServerInfo).map(plugin::getData).orElse(null);
if (server != null) {
switch (data.getInt(0x0001)) {
case 0:
server.setDisplayName(data.getList(0x0002).get(0).asRawString());
break;
case 1:
server.setMotd(ChatColor.parseColor('&', data.getList(0x0002).get(0).asRawString()));
break;
case 2:
server.setRestricted(data.getList(0x0002).get(0).asBoolean());
break;
case 3:
server.setHidden(data.getList(0x0002).get(0).asBoolean());
break;
case 4:
server.setSubData(data.getList(0x0002).get(1).asUUID(), data.getList(0x0002).get(0).asInt());
break;
case 5:
server.setSubData(null, data.getList(0x0002).get(0).asInt());
break;
case 6:
server.whitelist = data.getList(0x0002).get(0).asUUIDList();
break;
case 7:
server.whitelist(data.getList(0x0002).get(0).asUUID());
break;
case 8:
server.unwhitelist(data.getList(0x0002).get(0).asUUID());
break;
}
}
}
@Override
public int version() {
return 0x0002;
}
}

View File

@ -0,0 +1,21 @@
package net.ME1312.SubServers.Velocity.Network.Packet;
import net.ME1312.SubData.Client.Protocol.PacketIn;
import net.ME1312.SubData.Client.SubDataSender;
import net.ME1312.SubServers.Velocity.SubAPI;
/**
* Reset Packet
*/
public class PacketInExReset implements PacketIn {
@Override
public void receive(SubDataSender client) {
SubAPI.getInstance().getInternals().servers.clear();
}
@Override
public int version() {
return 0x0001;
}
}

View File

@ -0,0 +1,150 @@
package net.ME1312.SubServers.Velocity.Network.Packet;
import net.ME1312.Galaxi.Library.Callback.Callback;
import net.ME1312.Galaxi.Library.Container.ContainedPair;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.SubData.Client.Protocol.PacketObjectIn;
import net.ME1312.SubData.Client.SubDataSender;
import net.ME1312.SubServers.Velocity.Event.*;
import net.ME1312.SubServers.Velocity.ExProxy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Run Event Packet
*/
public class PacketInExRunEvent implements PacketObjectIn<Integer> {
private static HashMap<String, List<Callback<ObjectMap<String>>>> callbacks = new HashMap<String, List<Callback<ObjectMap<String>>>>();
/**
* New PacketInExRunEvent
*/
public PacketInExRunEvent(ExProxy plugin) {
callback("SubAddHostEvent", new Callback<ObjectMap<String>>() {
@Override
public void run(ObjectMap<String> data) {
ExProxy.getInstance().getEventManager().fire(new SubAddHostEvent((data.contains("player"))?data.getUUID("player"):null, data.getRawString("host")));
callback("SubAddHostEvent", this);
}
});
callback("SubAddProxyEvent", new Callback<ObjectMap<String>>() {
@Override
public void run(ObjectMap<String> data) {
ExProxy.getInstance().getEventManager().fire(new SubAddProxyEvent(data.getRawString("proxy")));
callback("SubAddProxyEvent", this);
}
});
callback("SubAddServerEvent", new Callback<ObjectMap<String>>() {
@Override
public void run(ObjectMap<String> data) {
ExProxy.getInstance().getEventManager().fire(new SubAddServerEvent((data.contains("player"))?data.getUUID("player"):null, (data.contains("host"))?data.getRawString("host"):null, data.getRawString("server")));
callback("SubAddServerEvent", this);
}
});
callback("SubCreateEvent", new Callback<ObjectMap<String>>() {
@Override
public void run(ObjectMap<String> data) {
ExProxy.getInstance().getEventManager().fire(new SubCreateEvent((data.contains("player"))?data.getUUID("player"):null, data.getRawString("host"), data.getRawString("name"),
data.getRawString("template"), data.getVersion("version"), data.getInt("port"), data.getBoolean("update")));
callback("SubCreateEvent", this);
}
});
callback("SubCreatedEvent", new Callback<ObjectMap<String>>() {
@Override
public void run(ObjectMap<String> data) {
ExProxy.getInstance().getEventManager().fire(new SubCreatedEvent((data.contains("player"))?data.getUUID("player"):null, data.getRawString("host"), data.getRawString("name"),
data.getRawString("template"), data.getVersion("version"), data.getInt("port"), data.getBoolean("update"), data.getBoolean("success")));
callback("SubCreatedEvent", this);
}
});
callback("SubSendCommandEvent", new Callback<ObjectMap<String>>() {
@Override
public void run(ObjectMap<String> data) {
ExProxy.getInstance().getEventManager().fire(new SubSendCommandEvent((data.contains("player"))?data.getUUID("player"):null, data.getRawString("server"), data.getRawString("command")));
callback("SubSendCommandEvent", this);
}
});
callback("SubEditServerEvent", new Callback<ObjectMap<String>>() {
@Override
public void run(ObjectMap<String> data) {
ExProxy.getInstance().getEventManager().fire(new SubEditServerEvent((data.contains("player"))?data.getUUID("player"):null, data.getRawString("server"), new ContainedPair<String, Object>(data.getRawString("edit"), data.get("value"))));
callback("SubEditServerEvent", this);
}
});
callback("SubStartEvent", new Callback<ObjectMap<String>>() {
@Override
public void run(ObjectMap<String> data) {
ExProxy.getInstance().getEventManager().fire(new SubStartEvent((data.contains("player"))?data.getUUID("player"):null, data.getRawString("server")));
callback("SubStartEvent", this);
}
});
callback("SubStartedEvent", new Callback<ObjectMap<String>>() {
@Override
public void run(ObjectMap<String> data) {
ExProxy.getInstance().getEventManager().fire(new SubStartedEvent(data.getRawString("server")));
callback("SubStartedEvent", this);
}
});
callback("SubStopEvent", new Callback<ObjectMap<String>>() {
@Override
public void run(ObjectMap<String> data) {
ExProxy.getInstance().getEventManager().fire(new SubStopEvent((data.contains("player"))?data.getUUID("player"):null, data.getRawString("server"), data.getBoolean("force")));
callback("SubStopEvent", this);
}
});
callback("SubStoppedEvent", new Callback<ObjectMap<String>>() {
@Override
public void run(ObjectMap<String> data) {
ExProxy.getInstance().getEventManager().fire(new SubStoppedEvent(data.getRawString("server")));
callback("SubStoppedEvent", this);
}
});
callback("SubRemoveServerEvent", new Callback<ObjectMap<String>>() {
@Override
public void run(ObjectMap<String> data) {
ExProxy.getInstance().getEventManager().fire(new SubRemoveServerEvent((data.contains("player"))?data.getUUID("player"):null, (data.contains("host"))?data.getRawString("host"):null, data.getRawString("server")));
callback("SubRemoveServerEvent", this);
}
});
callback("SubRemoveProxyEvent", new Callback<ObjectMap<String>>() {
@Override
public void run(ObjectMap<String> data) {
ExProxy.getInstance().getEventManager().fire(new SubAddProxyEvent(data.getRawString("proxy")));
callback("SubRemoveProxyEvent", this);
}
});
callback("SubRemoveHostEvent", new Callback<ObjectMap<String>>() {
@Override
public void run(ObjectMap<String> data) {
ExProxy.getInstance().getEventManager().fire(new SubRemoveHostEvent((data.contains("player"))?data.getUUID("player"):null, data.getRawString("host")));
callback("SubRemoveHostEvent", this);
}
});
}
@SuppressWarnings("unchecked")
@Override
public void receive(SubDataSender client, ObjectMap<Integer> data) {
if (callbacks.keySet().contains(data.getString(0x0000))) {
List<Callback<ObjectMap<String>>> callbacks = PacketInExRunEvent.callbacks.get(data.getString(0x0000));
PacketInExRunEvent.callbacks.remove(data.getString(0x0000));
for (Callback<ObjectMap<String>> callback : callbacks) {
callback.run(new ObjectMap<>((Map<String, ?>) data.getObject(0x0001)));
}
}
}
@Override
public int version() {
return 0x0001;
}
public static void callback(String event, Callback<ObjectMap<String>> callback) {
List<Callback<ObjectMap<String>>> callbacks = (PacketInExRunEvent.callbacks.keySet().contains(event))? PacketInExRunEvent.callbacks.get(event):new ArrayList<Callback<ObjectMap<String>>>();
callbacks.add(callback);
PacketInExRunEvent.callbacks.put(event, callbacks);
}
}

View File

@ -0,0 +1,78 @@
package net.ME1312.SubServers.Velocity.Network.Packet;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.Galaxi.Library.Util;
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.Velocity.ExProxy;
import net.ME1312.SubServers.Velocity.Library.Compatibility.Logger;
import net.ME1312.SubServers.Velocity.SubAPI;
/**
* Link Proxy Packet
*/
public class PacketLinkProxy implements InitialPacket, PacketObjectIn<Integer>, PacketObjectOut<Integer> {
private ExProxy plugin;
private int channel;
/**
* New PacketLinkProxy (In)
*
* @param plugin SubServers.Client
*/
public PacketLinkProxy(ExProxy plugin) {
if (Util.isNull(plugin)) throw new NullPointerException();
this.plugin = plugin;
}
/**
* New PacketLinkProxy (Out)
*
* @param plugin SubServers.Client
* @param channel Channel ID
*/
public PacketLinkProxy(ExProxy plugin, int channel) {
if (Util.isNull(plugin)) throw new NullPointerException();
this.plugin = plugin;
this.channel = channel;
}
@Override
public ObjectMap<Integer> send(SubDataSender client) {
ObjectMap<Integer> json = new ObjectMap<Integer>();
json.set(0x0000, plugin.api.getName());
json.set(0x0001, channel);
return json;
}
@Override
public void receive(SubDataSender client, ObjectMap<Integer> data) {
if (data.getInt(0x0001) == 0) {
try {
if (data.contains(0x0000)) Util.reflect(SubAPI.class.getDeclaredField("name"), plugin.api, data.getRawString(0x0000));
setReady(client.getConnection());
} catch (Throwable e) {
e.printStackTrace();
}
} else {
Logger.get("SubData").info("Could not link name with proxy" + ((data.contains(0x0002))?": "+data.getRawString(0x0002):'.'));
try {
if (data.getInt(0x0001) == 2) {
if (!plugin.config.get().getMap("Settings").getMap("SubData").contains("Name")) {
plugin.config.get().getMap("Settings").getMap("SubData").set("Name", "");
plugin.config.save();
}
if (plugin.config.get().getMap("Settings").getMap("SubData").getRawString("Name").length() <= 0)
Logger.get("SubData").info("Use the proxy \"Name\" option to override auto-linking");
}
} catch (Exception e) {}
new IllegalStateException().printStackTrace();
}
}
@Override
public int version() {
return 0x0001;
}
}

View File

@ -0,0 +1,225 @@
package net.ME1312.SubServers.Velocity.Network;
import net.ME1312.Galaxi.Library.Callback.Callback;
import net.ME1312.Galaxi.Library.Container.Pair;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.Galaxi.Library.Version.Version;
import net.ME1312.SubData.Client.SubDataClient;
import net.ME1312.SubData.Client.SubDataProtocol;
import net.ME1312.SubServers.Client.Common.Network.API.RemotePlayer;
import net.ME1312.SubServers.Client.Common.Network.API.Server;
import net.ME1312.SubServers.Client.Common.Network.Packet.*;
import net.ME1312.SubServers.Velocity.Event.SubNetworkConnectEvent;
import net.ME1312.SubServers.Velocity.Event.SubNetworkDisconnectEvent;
import net.ME1312.SubServers.Velocity.ExProxy;
import net.ME1312.SubServers.Velocity.Network.Packet.*;
import net.ME1312.SubServers.Velocity.Server.CachedPlayer;
import net.ME1312.SubServers.Velocity.Server.ServerData;
import net.ME1312.SubServers.Velocity.SubAPI;
import com.velocitypowered.api.proxy.config.ProxyConfig;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.UUID;
import java.util.logging.Logger;
/**
* SubServers Protocol Class
*/
public class SubProtocol extends SubDataProtocol {
private static SubProtocol instance;
@SuppressWarnings("deprecation")
protected SubProtocol() {
ExProxy plugin = SubAPI.getInstance().getInternals();
setName("SubServers 2");
addVersion(new Version("2.16a+"));
// 00-0F: Object Link Packets
registerPacket(0x0000, PacketLinkProxy.class);
registerPacket(0x0000, new PacketLinkProxy(plugin));
// 10-2F: Download Packets
registerPacket(0x0010, PacketDownloadLang.class);
registerPacket(0x0011, PacketDownloadPlatformInfo.class);
registerPacket(0x0012, PacketDownloadProxyInfo.class);
registerPacket(0x0013, PacketDownloadHostInfo.class);
registerPacket(0x0014, PacketDownloadGroupInfo.class);
registerPacket(0x0015, PacketDownloadServerInfo.class);
registerPacket(0x0016, PacketDownloadPlayerInfo.class);
registerPacket(0x0017, PacketCheckPermission.class);
registerPacket(0x0018, PacketCheckPermissionResponse.class);
registerPacket(0x0010, new PacketDownloadLang(plugin));
registerPacket(0x0011, new PacketDownloadPlatformInfo());
registerPacket(0x0012, new PacketDownloadProxyInfo());
registerPacket(0x0013, new PacketDownloadHostInfo());
registerPacket(0x0014, new PacketDownloadGroupInfo());
registerPacket(0x0015, new PacketDownloadServerInfo());
registerPacket(0x0016, new PacketDownloadPlayerInfo());
registerPacket(0x0017, new PacketCheckPermission());
registerPacket(0x0018, new PacketCheckPermissionResponse());
// 30-4F: Control Packets
registerPacket(0x0030, PacketCreateServer.class);
registerPacket(0x0031, PacketAddServer.class);
registerPacket(0x0032, PacketStartServer.class);
registerPacket(0x0033, PacketUpdateServer.class);
registerPacket(0x0034, PacketEditServer.class);
registerPacket(0x0035, PacketRestartServer.class);
registerPacket(0x0036, PacketCommandServer.class);
registerPacket(0x0037, PacketStopServer.class);
registerPacket(0x0038, PacketRemoveServer.class);
registerPacket(0x0039, PacketDeleteServer.class);
registerPacket(0x003B, PacketTransferPlayer.class);
registerPacket(0x003C, PacketDisconnectPlayer.class);
registerPacket(0x003D, PacketMessagePlayer.class);
registerPacket(0x0030, new PacketCreateServer());
registerPacket(0x0031, new PacketAddServer());
registerPacket(0x0032, new PacketStartServer());
registerPacket(0x0033, new PacketUpdateServer());
registerPacket(0x0034, new PacketEditServer());
registerPacket(0x0035, new PacketRestartServer());
registerPacket(0x0036, new PacketCommandServer());
registerPacket(0x0037, new PacketStopServer());
registerPacket(0x0038, new PacketRemoveServer());
registerPacket(0x0039, new PacketDeleteServer());
registerPacket(0x003B, new PacketTransferPlayer());
registerPacket(0x003C, new PacketDisconnectPlayer());
registerPacket(0x003D, new PacketMessagePlayer());
// 70-7F: External Sync Packets
//registerPacket(0x0070, PacketInExRunEvent.class);
//registerPacket(0x0071, PacketInExReset.class);
//registerPacket(0x0073, PacketInExReload.class);
registerPacket(0x0074, PacketExSyncPlayer.class);
registerPacket(0x0075, PacketExTransferPlayer.class);
registerPacket(0x0076, PacketExDisconnectPlayer.class);
registerPacket(0x0077, PacketExMessagePlayer.class);
registerPacket(0x0070, new PacketInExRunEvent(plugin));
registerPacket(0x0071, new PacketInExReset());
registerPacket(0x0073, new PacketInExEditServer(plugin));
registerPacket(0x0074, new PacketExSyncPlayer(plugin));
registerPacket(0x0075, new PacketExTransferPlayer(plugin));
registerPacket(0x0076, new PacketExDisconnectPlayer(plugin));
registerPacket(0x0077, new PacketExMessagePlayer(plugin));
}
public static SubProtocol get() {
if (instance == null)
instance = new SubProtocol();
return instance;
}
private Logger getLogger(int channel) {
return net.ME1312.SubServers.Velocity.Library.Compatibility.Logger.get("SubData" + ((channel != 0)?File.separator+"+"+channel:""));
}
@Override
protected SubDataClient sub(Callback<Runnable> scheduler, Logger logger, InetAddress address, int port, ObjectMap<?> login) throws IOException {
ExProxy plugin = SubAPI.getInstance().getInternals();
HashMap<Integer, SubDataClient> map = Util.getDespiteException(() -> Util.reflect(ExProxy.class.getDeclaredField("subdata"), plugin), null);
int channel = 1;
while (map.keySet().contains(channel)) channel++;
final int fc = channel;
SubDataClient subdata = super.open(scheduler, getLogger(fc), address, port, login);
map.put(fc, subdata);
subdata.sendPacket(new PacketLinkProxy(plugin, fc));
subdata.on.closed(client -> map.remove(fc));
return subdata;
}
@SuppressWarnings("deprecation")
@Override
public SubDataClient open(Callback<Runnable> scheduler, Logger logger, InetAddress address, int port) throws IOException {
ExProxy plugin = SubAPI.getInstance().getInternals();
SubDataClient subdata = super.open(scheduler, logger, address, port);
HashMap<Integer, SubDataClient> map = Util.getDespiteException(() -> Util.reflect(ExProxy.class.getDeclaredField("subdata"), plugin), null);
subdata.sendPacket(new PacketLinkProxy(plugin, 0));
subdata.sendPacket(new PacketDownloadLang());
subdata.sendPacket(new PacketDownloadPlatformInfo(platform -> {
if (plugin.lastReload != platform.getMap("subservers").getLong("last-reload")) {
net.ME1312.SubServers.Velocity.Library.Compatibility.Logger.get("SubServers").info("Resetting Server Data");
for (RegisteredServer server : ExProxy.getInstance().getAllServers()) ExProxy.getInstance().unregisterServer(server.getServerInfo());
plugin.servers.clear();
plugin.lastReload = platform.getMap("subservers").getLong("last-reload");
} /*
try {
ProxyConfig config = ExProxy.getInstance().getConfiguration(); // TODO maybe?
if (plugin.config.get().getMap("Sync", new ObjectMap<>()).getBoolean("Forced-Hosts", true)) Util.reflect(ListenerInfo.class.getDeclaredField("forcedHosts"), listeners.get(i), platform.getMap("bungee").getMapList("listeners").get(i).getMap("forced-hosts").get());
if (plugin.config.get().getMap("Sync", new ObjectMap<>()).getBoolean("Motd", false)) Util.reflect(ListenerInfo.class.getDeclaredField("motd"), listeners.get(i), platform.getMap("bungee").getMapList("listeners").get(i).getRawString("motd"));
if (plugin.config.get().getMap("Sync", new ObjectMap<>()).getBoolean("Player-Limit", false)) Util.reflect(ListenerInfo.class.getDeclaredField("maxPlayers"), listeners.get(i), platform.getMap("bungee").getMapList("listeners").get(i).getInt("player-limit"));
if (plugin.config.get().getMap("Sync", new ObjectMap<>()).getBoolean("Server-Priorities", true)) Util.reflect(ListenerInfo.class.getDeclaredField("serverPriority"), listeners.get(i), platform.getMap("bungee").getMapList("listeners").get(i).getRawStringList("priorities"));
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.Velocity.Library.Compatibility.Logger.get("SubServers").info("Problem converting synced BungeeCord configuration options");
e.printStackTrace();
} */
ArrayList<CachedPlayer> localPlayers = new ArrayList<CachedPlayer>();
for (UUID id : new ArrayList<UUID>(plugin.rPlayers.keySet())) {
if (ExProxy.getInstance().getPlayer(id).isPresent()) {
localPlayers.add(plugin.rPlayers.get(id));
} else {
plugin.rPlayerLinkS.remove(id);
plugin.rPlayerLinkP.remove(id);
plugin.rPlayers.remove(id);
}
}
subdata.sendPacket(new PacketExSyncPlayer(null, localPlayers.toArray(new CachedPlayer[0])));
plugin.api.getServers(servers -> {
for (Server server : servers.values()) {
plugin.merge(server);
}
plugin.api.getRemotePlayers(players -> {
for (RemotePlayer player : players.values()) {
plugin.rPlayerLinkP.put(player.getUniqueId(), player.getProxyName().toLowerCase());
plugin.rPlayers.put(player.getUniqueId(), (CachedPlayer) player);
ExProxy.getInstance().getServer(player.getServerName()).map(RegisteredServer::getServerInfo).map(plugin::getData).ifPresent(server ->
plugin.rPlayerLinkS.put(player.getUniqueId(), server)
);
}
});
});
}));
subdata.on.ready(client -> ExProxy.getInstance().getEventManager().fire(new SubNetworkConnectEvent((SubDataClient) client)));
subdata.on.closed(client -> {
SubNetworkDisconnectEvent event = new SubNetworkDisconnectEvent(client.value(), client.key());
ExProxy.getInstance().getEventManager().fire(event);
if (plugin.running) {
Logger log = net.ME1312.SubServers.Velocity.Library.Compatibility.Logger.get("SubData");
Util.isException(() -> Util.reflect(ExProxy.class.getDeclaredMethod("connect", Logger.class, Pair.class), plugin, log, client));
} else map.put(0, null);
});
return subdata;
}
public SubDataClient open(InetAddress address, int port) throws IOException {
return open(getLogger(0), address, port);
}
}

View File

@ -0,0 +1,209 @@
package net.ME1312.SubServers.Velocity.Server;
import net.ME1312.Galaxi.Library.Callback.Callback;
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.SubData.Client.DataClient;
import net.ME1312.SubData.Client.SubDataClient;
import net.ME1312.SubServers.Client.Common.Network.API.RemotePlayer;
import net.ME1312.SubServers.Velocity.ExProxy;
import net.ME1312.SubServers.Velocity.Library.Compatibility.ChatColor;
import net.ME1312.SubServers.Velocity.SubAPI;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.proxy.server.ServerInfo;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import java.util.ArrayList;
import java.util.Optional;
import java.util.UUID;
/**
* Cached RemotePlayer Data Class
*/
public class CachedPlayer extends RemotePlayer {
/**
* Convert a Local Player to a Cached Remote Player
*
* @param player Local Player
* @return Raw representation of the Remote Player
*/
public static ObjectMap<String> translate(Player player) {
ObjectMap<String> raw = new ObjectMap<String>();
raw = new ObjectMap<String>();
raw.set("name", player.getGameProfile().getName());
raw.set("id", player.getUniqueId());
raw.set("address", player.getRemoteAddress().getAddress().getHostAddress() + ':' + player.getRemoteAddress().getPort());
if (player.getCurrentServer().isPresent()) raw.set("server", player.getCurrentServer().get().getServerInfo().getName());
if (SubAPI.getInstance().getName() != null) raw.set("proxy", SubAPI.getInstance().getName());
return raw;
}
/**
* Convert a Local Player to a Cached Remote Player
*
* @param player Local Player
*/
public CachedPlayer(Player player) {
this(translate(player));
}
/**
* Create a Cached Remote Player
*
* @param raw Raw representation of the Remote Player
*/
public CachedPlayer(ObjectMap<String> raw) {
this(null, raw);
}
/**
* Create a Cached Remote Player
*
* @param client SubData connection
* @param raw Raw representation of the Remote Player
*/
CachedPlayer(DataClient client, ObjectMap<String> raw) {
super(client, raw);
}
/**
* Get Local Player
*
* @return Local Player (or null when not local)
*/
public Player get() {
return get(getUniqueId());
}
private static Player get(UUID player) {
return ExProxy.getInstance().getPlayer(player).orElse(null);
}
/**
* Gets the server this player is connected to.
*
* @return the server this player is connected to
*/
public ServerInfo getServer() {
String name = getServerName();
if (name == null) {
return null;
} else {
Optional<RegisteredServer> server = ExProxy.getInstance().getServer(name);
return server.map(RegisteredServer::getServerInfo).orElse(null);
}
}
static {
// These overrides prevent sending unnecessary packets in ClientCommon
instance = new StaticImpl() {
@Override
protected RemotePlayer construct(DataClient client, ObjectMap<String> raw) {
return new CachedPlayer(client, raw);
}
@Override
protected void sendMessage(SubDataClient client, UUID[] players, String[] messages, Callback<Integer> response) {
if (players != null && players.length > 0) {
ArrayList<UUID> ids = new ArrayList<UUID>();
for (UUID id : players) {
Player local = get(id);
if (local != null) {
for (String s : messages) {
local.sendMessage(Component.text(s));
}
} else {
ids.add(id);
}
}
if (ids.size() == 0) {
response.run(0);
} else {
super.sendMessage(client, ids.toArray(new UUID[0]), messages, response);
}
} else {
super.sendMessage(client, players, messages, response);
}
}
@Override
protected void sendRawMessage(SubDataClient client, UUID[] players, String[] messages, Callback<Integer> response) {
if (players != null && players.length > 0) {
ArrayList<UUID> ids = new ArrayList<UUID>();
Component[] components = null;
for (UUID id : players) {
Player local = get(id);
if (local != null) {
if (components == null) {
components = new Component[messages.length];
for (int i = 0; i < components.length; ++i) components[i] = GsonComponentSerializer.gson().deserialize(messages[i]);
}
for (Component c : components) {
local.sendMessage(c);
}
} else {
ids.add(id);
}
}
if (ids.size() == 0) {
response.run(0);
} else {
super.sendRawMessage(client, ids.toArray(new UUID[0]), messages, response);
}
} else {
super.sendRawMessage(client, players, messages, response);
}
}
@Override
protected void transfer(SubDataClient client, UUID[] players, String server, Callback<Integer> response) {
ArrayList<UUID> ids = new ArrayList<UUID>();
Optional<RegisteredServer> rs = ExProxy.getInstance().getServer(server.toLowerCase());
int failures = 0;
for (UUID id : players) {
Player local = get(id);
if (local != null) {
if (rs.isPresent()) {
local.createConnectionRequest(rs.get()).fireAndForget();
} else ++failures;
} else {
ids.add(id);
}
}
if (ids.size() == 0) {
response.run(failures);
} else {
final int ff = failures;
super.transfer(client, ids.toArray(new UUID[0]), server, i -> response.run(i + ff));
}
}
@Override
protected void disconnect(SubDataClient client, UUID[] players, String reason, Callback<Integer> response) {
Component message = (reason == null)? Component.text().build() : ChatColor.convertColor(reason);
ArrayList<UUID> ids = new ArrayList<UUID>();
for (UUID id : players) {
Player local = get(id);
if (local != null) {
local.disconnect(message);
} else {
ids.add(id);
}
}
if (ids.size() == 0) {
response.run(0);
} else {
super.disconnect(client, ids.toArray(new UUID[0]), reason, response);
}
}
};
}
}

View File

@ -0,0 +1,213 @@
package net.ME1312.SubServers.Velocity.Server;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubData.Client.DataSender;
import net.ME1312.SubData.Client.Library.ForwardedDataSender;
import net.ME1312.SubData.Client.SubDataClient;
import net.ME1312.SubServers.Velocity.SubAPI;
import com.velocitypowered.api.permission.PermissionSubject;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.server.ServerInfo;
import java.net.InetSocketAddress;
import java.util.*;
/**
* Server Class
*/
public class ServerData {
private final ServerInfo info;
private String motd;
private boolean restricted;
private HashMap<Integer, UUID> subdata = new HashMap<Integer, UUID>();
public List<UUID> whitelist = new ArrayList<UUID>();
private String nick = null;
private boolean hidden;
private final String signature;
public ServerData(String signature, String name, String display, InetSocketAddress address, Map<Integer, UUID> subdata, String motd, boolean hidden, boolean restricted, Collection<UUID> whitelist) {
this.info = new ServerInfo(name, address);
this.motd = motd;
this.restricted = restricted;
this.signature = signature;
this.whitelist.addAll(whitelist);
this.hidden = hidden;
setDisplayName(display);
for (int channel : subdata.keySet())
setSubData(subdata.get(channel), channel);
}
/**
* Gets the SubData Client Channel IDs
*
* @return SubData Client Channel ID Array
*/
public DataSender[] getSubData() {
Integer[] keys = subdata.keySet().toArray(new Integer[0]);
DataSender[] channels = new DataSender[keys.length];
Arrays.sort(keys);
for (int i = 0; i < keys.length; ++i) channels[i] = (subdata.getOrDefault(keys[i], null) == null)? null : new ForwardedDataSender((SubDataClient) SubAPI.getInstance().getSubDataNetwork()[0], subdata.get(keys[i]));
return channels;
}
/**
* Link a SubData Client to this Object
*
* @param client Client to Link
* @param channel Channel ID
*/
public void setSubData(UUID client, int channel) {
if (channel < 0) throw new IllegalArgumentException("Subchannel ID cannot be less than zero");
if (client != null || channel == 0) {
if (!subdata.keySet().contains(channel) || (channel == 0 && (client == null || subdata.get(channel) == null))) {
subdata.put(channel, client);
}
} else {
subdata.remove(channel);
}
}
/**
* Get the underlying ServerInfo of this Server
*
* @return ServerInfo
*/
public ServerInfo get() {
return info;
}
/**
* Get the Address of this Server
*
* @return Server Address
*/
public InetSocketAddress getAddress() {
return info.getAddress();
}
/**
* Get the Name of this Server
*
* @return Server Name
*/
public String getName() {
return info.getName();
}
/**
* Get the Display Name of this Server
*
* @return Display Name
*/
public String getDisplayName() {
return (nick == null)?getName():nick;
}
/**
* Sets the Display Name for this Server
*
* @param value Value (or null to reset)
*/
public void setDisplayName(String value) {
if (value == null || value.length() == 0 || getName().equals(value)) {
this.nick = null;
} else {
this.nick = value;
}
}
/**
* If the server is hidden from players
*
* @return Hidden Status
*/
public boolean isHidden() {
return hidden;
}
/**
* Set if the server is hidden from players
*
* @param value Value
*/
public void setHidden(boolean value) {
if (Util.isNull(value)) throw new NullPointerException();
this.hidden = value;
}
/**
* Gets the MOTD of the Server
*
* @return Server MOTD
*/
public String getMotd() {
return motd;
}
/**
* Sets the MOTD of the Server
*
* @param value Value
*/
public void setMotd(String value) {
this.motd = value;
}
/**
* Gets if the Server is Restricted
*
* @return Restricted Status
*/
public boolean isRestricted() {
return restricted;
}
/**
* Sets if the Server is Restricted
*
* @param value Value
*/
public void setRestricted(boolean value) {
this.restricted = value;
}
/**
* See if a player is whitelisted
*
* @param player Player
* @return Whitelisted Status
*/
public boolean canAccess(PermissionSubject player) {
return !restricted || player.hasPermission("bungeecord.server." + getName()) || (player instanceof Player && whitelist.contains(((Player) player).getUniqueId()));
}
/**
* Add a player to the whitelist (for use with restricted servers)
*
* @param player Player to add
*/
public void whitelist(UUID player) {
if (Util.isNull(player)) throw new NullPointerException();
whitelist.add(player);
}
/**
* Remove a player to the whitelist
*
* @param player Player to remove
*/
public void unwhitelist(UUID player) {
whitelist.remove(player);
}
/**
* Get the Signature of this Object
*
* @return Object Signature
*/
public final String getSignature() {
return signature;
}
}

View File

@ -0,0 +1,37 @@
package net.ME1312.SubServers.Velocity.Server;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Collection;
import java.util.Map;
import java.util.UUID;
/**
* SubServer Class
*/
public class SubServerData extends ServerData {
private boolean running;
public SubServerData(String signature, String name, String display, InetSocketAddress address, Map<Integer, UUID> subdata, String motd, boolean hidden, boolean restricted, Collection<UUID> whitelist, boolean running) {
super(signature, name, display, address, subdata, motd, hidden, restricted, whitelist);
this.running = running;
}
/**
* Gets the Running Status
*
* @return Running Status
*/
public boolean isRunning() {
return running;
}
/**
* Sets the Running Status
*
* @param running Running Status
*/
public void setRunning(boolean running) {
this.running = running;
}
}

View File

@ -0,0 +1,222 @@
package net.ME1312.SubServers.Velocity;
import net.ME1312.Galaxi.Library.UniversalFile;
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.Galaxi.Library.Version.Version;
import net.ME1312.SubData.Client.DataClient;
import net.ME1312.SubData.Client.DataProtocol;
import net.ME1312.SubData.Client.SubDataClient;
import net.ME1312.SubServers.Client.Common.ClientAPI;
import net.ME1312.SubServers.Velocity.Server.CachedPlayer;
import net.ME1312.SubServers.Velocity.Server.ServerData;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.proxy.server.ServerInfo;
import java.util.*;
/**
* SubAPI Class
*/
public final class SubAPI extends ClientAPI {
private final ExProxy plugin;
private static SubAPI api;
String name;
SubAPI(ExProxy plugin) {
this.plugin = plugin;
GAME_VERSION = getGameVersion();
api = this;
}
/**
* Gets the SubAPI Methods
*
* @return SubAPI
*/
public static SubAPI getInstance() {
return api;
}
/**
* Gets the SubServers Internals
*
* @deprecated Use SubAPI Methods when available
* @return SubPlugin Internals
*/
@Deprecated
public ExProxy getInternals() {
return plugin;
}
/**
* Get the Proxy Name
*
* @return Proxy Name
*/
public String getName() {
return name;
}
/**
* Get the number of players on this network across all known proxies
*
* @return Remote Player Count
*/
public int getRemotePlayerCount() {
return plugin.rPlayers.size();
}
/**
* Get players on this server across all known proxies (Cached)
*
* @param server Server to search
* @return Remote Player Map
*/
public Map<UUID, CachedPlayer> getRemotePlayers(ServerInfo server) {
ServerData sd = plugin.getData(server);
if (sd != null) {
HashMap<UUID, CachedPlayer> players = new HashMap<UUID, CachedPlayer>();
for (UUID id : Util.getBackwards(plugin.rPlayerLinkS, sd))
players.put(id, plugin.rPlayers.get(id));
return players;
} else {
return new HashMap<>();
}
}
/**
* Gets players on this network across all known proxies (Cached)
*
* @return Remote Player Map
*/
public Map<UUID, CachedPlayer> getRemotePlayers() {
return new HashMap<UUID, CachedPlayer>(plugin.rPlayers);
}
/**
* Gets a player on this network by searching across all known proxies (Cached)
*
* @param name Player name
* @return Remote Player
*/
public CachedPlayer getRemotePlayer(String name) {
if (Util.isNull(name)) throw new NullPointerException();
for (CachedPlayer player : getRemotePlayers().values()) {
if (player.getName().equalsIgnoreCase(name)) return player;
}
return null;
}
/**
* Gets a player on this network by searching across all known proxies (Cached)
*
* @param id Player UUID
* @return Remote Player
*/
public CachedPlayer getRemotePlayer(UUID id) {
if (Util.isNull(id)) throw new NullPointerException();
return getRemotePlayers().getOrDefault(id, null);
}
/**
* Gets the SubData Network Connections
*
* @return SubData Network Connections
*/
public DataClient[] getSubDataNetwork() {
LinkedList<Integer> keys = new LinkedList<Integer>(plugin.subdata.keySet());
LinkedList<SubDataClient> channels = new LinkedList<SubDataClient>();
Collections.sort(keys);
for (Integer channel : keys) channels.add(plugin.subdata.get(channel));
return channels.toArray(new DataClient[0]);
}
/**
* Gets the SubData Network Protocol
*
* @return SubData Network Protocol
*/
public DataProtocol getSubDataProtocol() {
return plugin.subprotocol;
}
/**
* Gets the current SubServers Lang Channels
*
* @return SubServers Lang Channel list
*/
public Collection<String> getLangChannels() {
return plugin.lang.value().keySet();
}
/**
* Gets values from the SubServers Lang
*
* @param channel Lang Channel
* @return Lang Value
*/
public Map<String, String> getLang(String channel) {
if (Util.isNull(channel)) throw new NullPointerException();
return new LinkedHashMap<>(plugin.lang.value().get(channel.toLowerCase()));
}
/**
* Gets the Runtime Directory
*
* @return Directory
*/
public UniversalFile getRuntimeDirectory() {
return plugin.dir;
}
/**
* Gets the SubServers Version
*
* @return SubServers Version
*/
public Version getPluginVersion() {
return plugin.version;
}
/**
* Gets the SubServers Build Version
*
* @return SubServers Build Version (or null if unsigned)
*/
public Version getPluginBuild() {
return (ExProxy.class.getPackage().getSpecificationTitle() != null)?new Version(ExProxy.class.getPackage().getSpecificationTitle()):null;
}
/**
* Gets the BungeeCord Version
*
* @return BungeeCord Version
*/
public Version getProxyVersion() {
return new Version(ExProxy.getInstance().getVersion().getVersion());
}
/**
* Get an array of compatible Minecraft Versions
*
* @return Minecraft Versions
*/
public Version[] getGameVersion() {
if (GAME_VERSION == null) {
if (System.getProperty("subservers.minecraft.version", "").length() > 0) {
return new Version[]{new Version(System.getProperty("subservers.minecraft.version"))};
} else if (Util.getDespiteException(() -> ProtocolVersion.SUPPORTED_VERSIONS != null, false)) {
List<Version> versions = new LinkedList<Version>();
for (ProtocolVersion protocol : ProtocolVersion.SUPPORTED_VERSIONS) for (String version : protocol.getVersionsSupportedBy()) versions.add(new Version(version));
Collections.sort(versions);
return versions.toArray(new Version[versions.size()]);
} else {
plugin.out.warn("Could not determine compatible Minecraft version(s); Now using 1.x.x as a placeholder.");
plugin.out.warn("Use this launch argument to specify a compatible Minecraft version: -Dsubservers.minecraft.version=1.x.x");
return new Version[]{new Version("1.x.x")};
}
} else return GAME_VERSION;
}
private final Version[] GAME_VERSION;
}

File diff suppressed because it is too large Load Diff

View File

@ -15,5 +15,6 @@
<module>SubServers.Creator</module>
<module>SubServers.Host</module>
<module>SubServers.Sync</module>
<module>SubServers.Sync/velocity</module>
</modules>
</project>