2017-04-01 07:37:48 +02:00
|
|
|
package net.ME1312.SubServers.Bungee.Host.External;
|
|
|
|
|
2020-11-16 21:34:59 +01:00
|
|
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
|
|
|
import net.ME1312.Galaxi.Library.Util;
|
2019-05-10 04:43:34 +02:00
|
|
|
import net.ME1312.SubData.Server.ClientHandler;
|
2019-04-18 16:02:09 +02:00
|
|
|
import net.ME1312.SubData.Server.DataClient;
|
2020-02-17 04:25:15 +01:00
|
|
|
import net.ME1312.SubData.Server.Protocol.PacketOut;
|
2019-04-18 16:02:09 +02:00
|
|
|
import net.ME1312.SubData.Server.SubDataClient;
|
2017-04-01 07:37:48 +02:00
|
|
|
import net.ME1312.SubServers.Bungee.Event.SubAddServerEvent;
|
|
|
|
import net.ME1312.SubServers.Bungee.Event.SubRemoveServerEvent;
|
|
|
|
import net.ME1312.SubServers.Bungee.Host.Host;
|
|
|
|
import net.ME1312.SubServers.Bungee.Host.SubCreator;
|
|
|
|
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
2019-05-17 00:36:41 +02:00
|
|
|
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
|
2017-04-01 07:37:48 +02:00
|
|
|
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
|
|
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExAddServer;
|
2017-04-01 18:50:09 +02:00
|
|
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExDeleteServer;
|
2017-04-01 07:37:48 +02:00
|
|
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExRemoveServer;
|
2019-04-18 16:02:09 +02:00
|
|
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExReset;
|
2019-08-30 21:44:54 +02:00
|
|
|
import net.ME1312.SubServers.Bungee.SubProxy;
|
2020-11-16 21:34:59 +01:00
|
|
|
|
|
|
|
import com.google.common.collect.Range;
|
2017-04-01 07:37:48 +02:00
|
|
|
|
|
|
|
import java.net.InetAddress;
|
|
|
|
import java.util.*;
|
|
|
|
|
2017-04-16 19:02:14 +02:00
|
|
|
/**
|
|
|
|
* External Host Class
|
|
|
|
*/
|
2019-05-10 04:43:34 +02:00
|
|
|
public class ExternalHost extends Host implements ClientHandler {
|
|
|
|
private HashMap<Integer, SubDataClient> subdata = new HashMap<Integer, SubDataClient>();
|
2017-04-01 07:37:48 +02:00
|
|
|
private HashMap<String, SubServer> servers = new HashMap<String, SubServer>();
|
|
|
|
private String name;
|
2020-06-12 07:45:49 +02:00
|
|
|
boolean available;
|
2017-04-01 07:37:48 +02:00
|
|
|
private boolean enabled;
|
|
|
|
private InetAddress address;
|
|
|
|
private SubCreator creator;
|
|
|
|
private String directory;
|
2020-02-17 04:25:15 +01:00
|
|
|
private LinkedList<PacketOut> queue;
|
2017-04-01 22:31:57 +02:00
|
|
|
private boolean clean;
|
2020-06-12 07:45:49 +02:00
|
|
|
SubProxy plugin;
|
2017-04-01 07:37:48 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates an External Host
|
|
|
|
*
|
2019-01-05 22:04:45 +01:00
|
|
|
* @param plugin SubServers Internals
|
|
|
|
* @param name The Name of your Host
|
|
|
|
* @param ports The range of ports to auto-select from
|
|
|
|
* @param log Whether apps like SubCreator should log to console (does not apply to servers)
|
|
|
|
* @param enabled If your host is Enabled
|
|
|
|
* @param address The address of your Host
|
|
|
|
* @param directory The runtime directory of your Host
|
|
|
|
* @param gitBash The Git Bash directory
|
2017-04-01 07:37:48 +02:00
|
|
|
*/
|
2019-08-30 21:44:54 +02:00
|
|
|
public ExternalHost(SubProxy plugin, String name, boolean enabled, Range<Integer> ports, boolean log, InetAddress address, String directory, String gitBash) {
|
2019-01-05 22:04:45 +01:00
|
|
|
super(plugin, name, enabled, ports, log, address, directory, gitBash);
|
2017-04-01 07:37:48 +02:00
|
|
|
this.plugin = plugin;
|
|
|
|
this.name = name;
|
2019-05-10 04:43:34 +02:00
|
|
|
this.available = false;
|
2017-04-01 07:37:48 +02:00
|
|
|
this.enabled = enabled;
|
|
|
|
this.address = address;
|
2019-01-05 22:04:45 +01:00
|
|
|
this.creator = new ExternalSubCreator(this, ports, log, gitBash);
|
2017-04-01 07:37:48 +02:00
|
|
|
this.directory = directory;
|
2020-02-17 04:25:15 +01:00
|
|
|
this.queue = new LinkedList<PacketOut>();
|
2017-04-01 22:31:57 +02:00
|
|
|
this.clean = false;
|
2019-05-10 04:43:34 +02:00
|
|
|
|
2019-05-14 04:02:38 +02:00
|
|
|
subdata.put(0, null);
|
2017-04-01 07:37:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2019-05-10 04:43:34 +02:00
|
|
|
public DataClient[] getSubData() {
|
2021-04-08 15:15:35 +02:00
|
|
|
Integer[] keys = subdata.keySet().toArray(new Integer[0]);
|
|
|
|
DataClient[] channels = new DataClient[keys.length];
|
|
|
|
Arrays.sort(keys);
|
|
|
|
for (int i = 0; i < keys.length; ++i) channels[i] = subdata.get(keys[i]);
|
|
|
|
return channels;
|
2019-05-10 04:43:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void setSubData(DataClient client, int channel) {
|
|
|
|
if (channel < 0) throw new IllegalArgumentException("Subchannel ID cannot be less than zero");
|
2019-05-10 06:04:10 +02:00
|
|
|
if (client != null || channel == 0) {
|
|
|
|
if (!subdata.keySet().contains(channel) || (channel == 0 && (client == null || subdata.get(channel) == null))) {
|
2019-05-10 04:43:34 +02:00
|
|
|
subdata.put(channel, (SubDataClient) client);
|
|
|
|
if (client != null && (client.getHandler() == null || !equals(client.getHandler()))) ((SubDataClient) client).setHandler(this);
|
|
|
|
}
|
2019-05-10 06:04:10 +02:00
|
|
|
} else {
|
|
|
|
subdata.remove(channel);
|
2019-05-10 04:43:34 +02:00
|
|
|
}
|
2017-04-01 07:37:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2019-05-10 04:43:34 +02:00
|
|
|
public void removeSubData(DataClient client) {
|
|
|
|
for (Integer channel : Util.getBackwards(subdata, (SubDataClient) client)) setSubData(null, channel);
|
2017-04-01 07:37:48 +02:00
|
|
|
}
|
|
|
|
|
2020-06-12 07:45:49 +02:00
|
|
|
void queue(PacketOut... packet) {
|
2020-02-17 04:25:15 +01:00
|
|
|
for (PacketOut p : packet) if (getSubData()[0] == null || !available) {
|
2017-04-01 07:37:48 +02:00
|
|
|
queue.add(p);
|
|
|
|
} else {
|
2019-05-10 04:43:34 +02:00
|
|
|
((SubDataClient) getSubData()[0]).sendPacket(p);
|
2017-04-01 07:37:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
private void requeue() {
|
2019-05-10 04:43:34 +02:00
|
|
|
SubDataClient client = (SubDataClient) getSubData()[0];
|
2017-04-01 22:31:57 +02:00
|
|
|
if (!clean) {
|
2019-05-10 04:43:34 +02:00
|
|
|
client.sendPacket(new PacketOutExReset("Prevent Desync"));
|
2017-04-01 22:31:57 +02:00
|
|
|
clean = true;
|
|
|
|
}
|
2017-04-01 07:37:48 +02:00
|
|
|
for (SubServer server : servers.values()) {
|
2021-06-06 07:28:22 +02:00
|
|
|
client.sendPacket(new PacketExAddServer((ExternalSubServer) server, (server.isRunning())?((ExternalSubLogger) server.getLogger()).getExternalAddress():null, data -> {
|
2019-08-30 02:01:52 +02:00
|
|
|
if (data.contains(0x0002)) ((ExternalSubServer) server).started(data.getUUID(0x0002));
|
|
|
|
}));
|
2017-04-01 07:37:48 +02:00
|
|
|
}
|
|
|
|
while (queue.size() != 0) {
|
2019-05-10 04:43:34 +02:00
|
|
|
client.sendPacket(queue.get(0));
|
2017-04-01 07:37:48 +02:00
|
|
|
queue.remove(0);
|
|
|
|
}
|
2019-05-10 04:43:34 +02:00
|
|
|
available = true;
|
2017-04-01 07:37:48 +02:00
|
|
|
}
|
|
|
|
|
2018-08-30 03:55:59 +02:00
|
|
|
@Override
|
|
|
|
public boolean isAvailable() {
|
2019-05-10 04:43:34 +02:00
|
|
|
return available;
|
2018-08-30 03:55:59 +02:00
|
|
|
}
|
|
|
|
|
2017-04-01 07:37:48 +02:00
|
|
|
@Override
|
|
|
|
public boolean isEnabled() {
|
2018-08-30 03:55:59 +02:00
|
|
|
return enabled;
|
2017-04-01 07:37:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setEnabled(boolean value) {
|
|
|
|
this.enabled = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public InetAddress getAddress() {
|
|
|
|
return address;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2017-04-24 18:28:16 +02:00
|
|
|
public String getPath() {
|
2017-04-01 07:37:48 +02:00
|
|
|
return directory;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String getName() {
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public SubCreator getCreator() {
|
|
|
|
return creator;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Map<String, ? extends SubServer> getSubServers() {
|
|
|
|
return new TreeMap<String, SubServer>(servers);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public SubServer getSubServer(String name) {
|
2021-06-15 06:09:51 +02:00
|
|
|
if (Util.isNull(name)) return null;
|
|
|
|
return servers.get(name.toLowerCase());
|
2017-04-01 07:37:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2021-06-06 07:28:22 +02:00
|
|
|
public SubServer constructSubServer(String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
|
|
|
return ExternalSubServer.construct(this, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean addSubServer(UUID player, SubServer server) throws InvalidServerException {
|
|
|
|
if (server.getHost() != this) throw new IllegalArgumentException("That Server does not belong to this Host!");
|
2021-06-06 08:02:27 +02:00
|
|
|
if (plugin.api.getServers().containsKey(server.getName().toLowerCase())) throw new InvalidServerException("A Server already exists with this name!");
|
2017-04-01 07:37:48 +02:00
|
|
|
SubAddServerEvent event = new SubAddServerEvent(player, this, server);
|
|
|
|
plugin.getPluginManager().callEvent(event);
|
|
|
|
if (!event.isCancelled()) {
|
2021-06-06 07:28:22 +02:00
|
|
|
queue(new PacketExAddServer(((ExternalSubServer) server), (server.isRunning())?((ExternalSubLogger) server.getLogger()).getExternalAddress():null, data -> {
|
2021-08-03 00:33:10 +02:00
|
|
|
((ExternalSubServer) server).registered(true);
|
2021-06-06 07:28:22 +02:00
|
|
|
if (data.contains(0x0002)) ((ExternalSubServer) server).started(data.getUUID(0x0002));
|
2019-08-30 02:01:52 +02:00
|
|
|
}));
|
2021-06-06 07:28:22 +02:00
|
|
|
servers.put(server.getName().toLowerCase(), server);
|
|
|
|
return true;
|
2017-04-01 07:37:48 +02:00
|
|
|
} else {
|
2021-06-06 07:28:22 +02:00
|
|
|
return false;
|
2017-04-01 07:37:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-08-14 00:26:22 +02:00
|
|
|
protected boolean removeSubServer(UUID player, String name, boolean forced) throws InterruptedException {
|
2017-04-01 07:37:48 +02:00
|
|
|
if (Util.isNull(name)) throw new NullPointerException();
|
2021-06-06 08:59:50 +02:00
|
|
|
ExternalSubServer server = (ExternalSubServer) servers.get(name.toLowerCase());
|
2018-08-30 03:55:59 +02:00
|
|
|
|
2020-06-12 07:45:49 +02:00
|
|
|
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, server);
|
2017-04-01 07:37:48 +02:00
|
|
|
plugin.getPluginManager().callEvent(event);
|
2020-08-14 00:26:22 +02:00
|
|
|
if (forced || !event.isCancelled()) {
|
2021-06-06 08:59:50 +02:00
|
|
|
server.registered(false);
|
2020-06-12 07:45:49 +02:00
|
|
|
if (server.isRunning()) {
|
|
|
|
server.stop();
|
|
|
|
server.waitFor();
|
2017-04-01 07:37:48 +02:00
|
|
|
}
|
2021-06-06 08:59:50 +02:00
|
|
|
|
2020-08-20 03:15:55 +02:00
|
|
|
servers.remove(name.toLowerCase());
|
2020-06-12 07:45:49 +02:00
|
|
|
queue(new PacketExRemoveServer(name.toLowerCase(), data -> {
|
2020-08-20 03:15:55 +02:00
|
|
|
if (data.getInt(0x0001) != 0 && data.getInt(0x0001) != 1) {
|
2021-06-06 08:59:50 +02:00
|
|
|
server.registered(true);
|
2020-08-20 03:15:55 +02:00
|
|
|
servers.put(name.toLowerCase(), server);
|
2017-08-26 07:19:59 +02:00
|
|
|
}
|
2017-04-01 07:37:48 +02:00
|
|
|
}));
|
|
|
|
return true;
|
|
|
|
} else return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-08-14 00:26:22 +02:00
|
|
|
protected boolean recycleSubServer(UUID player, String name, boolean forced) throws InterruptedException {
|
2019-04-18 16:02:09 +02:00
|
|
|
if (Util.isNull(name)) throw new NullPointerException();
|
2021-06-06 08:59:50 +02:00
|
|
|
ExternalSubServer s = (ExternalSubServer) servers.get(name.toLowerCase());
|
2020-06-12 07:45:49 +02:00
|
|
|
String server = s.getName();
|
2019-04-18 16:02:09 +02:00
|
|
|
|
2020-06-12 07:45:49 +02:00
|
|
|
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, s);
|
2019-04-18 16:02:09 +02:00
|
|
|
plugin.getPluginManager().callEvent(event);
|
2020-08-14 00:26:22 +02:00
|
|
|
if (forced || !event.isCancelled()) {
|
2021-06-06 08:59:50 +02:00
|
|
|
s.registered(false);
|
2020-06-12 07:45:49 +02:00
|
|
|
if (s.isRunning()) {
|
|
|
|
s.stop();
|
|
|
|
s.waitFor();
|
2019-04-18 16:02:09 +02:00
|
|
|
}
|
|
|
|
|
2019-05-17 00:36:41 +02:00
|
|
|
Logger.get("SubServers").info("Saving...");
|
2019-04-29 17:05:06 +02:00
|
|
|
ObjectMap<String> info = (plugin.servers.get().getMap("Servers").getKeys().contains(server))?plugin.servers.get().getMap("Servers").getMap(server).clone():new ObjectMap<String>();
|
2019-04-18 16:02:09 +02:00
|
|
|
info.set("Name", server);
|
|
|
|
info.set("Timestamp", Calendar.getInstance().getTime().getTime());
|
|
|
|
try {
|
2019-04-29 17:05:06 +02:00
|
|
|
if (plugin.servers.get().getMap("Servers").getKeys().contains(server)) {
|
|
|
|
plugin.servers.get().getMap("Servers").remove(server);
|
|
|
|
plugin.servers.save();
|
2019-04-18 16:02:09 +02:00
|
|
|
}
|
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
|
2019-05-17 00:36:41 +02:00
|
|
|
Logger.get("SubServers").info("Moving Files...");
|
2019-04-18 16:02:09 +02:00
|
|
|
queue(new PacketExDeleteServer(server, info, true, data -> {
|
2019-05-13 05:28:27 +02:00
|
|
|
if (data.getInt(0x0001) == 0 || data.getInt(0x0001) == 1) {
|
2019-04-18 16:02:09 +02:00
|
|
|
servers.remove(server.toLowerCase());
|
2019-05-17 00:36:41 +02:00
|
|
|
Logger.get("SubServers").info("Deleted SubServer: " + server);
|
2019-04-18 16:02:09 +02:00
|
|
|
} else {
|
2021-06-06 08:59:50 +02:00
|
|
|
s.registered(true);
|
2019-05-17 00:36:41 +02:00
|
|
|
Logger.get("SubServers").info("Couldn't remove " + server + " from memory. See " + getName() + " console for more details");
|
2019-04-18 16:02:09 +02:00
|
|
|
}
|
|
|
|
}));
|
|
|
|
return true;
|
|
|
|
} else return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-08-14 00:26:22 +02:00
|
|
|
protected boolean deleteSubServer(UUID player, String name, boolean forced) throws InterruptedException {
|
2017-04-01 18:50:09 +02:00
|
|
|
if (Util.isNull(name)) throw new NullPointerException();
|
2021-06-06 08:59:50 +02:00
|
|
|
ExternalSubServer s = (ExternalSubServer) servers.get(name.toLowerCase());
|
2020-06-12 07:45:49 +02:00
|
|
|
String server = s.getName();
|
2017-04-01 18:50:09 +02:00
|
|
|
|
2017-04-14 04:39:51 +02:00
|
|
|
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, getSubServer(server));
|
2017-04-01 18:50:09 +02:00
|
|
|
plugin.getPluginManager().callEvent(event);
|
2020-08-14 00:26:22 +02:00
|
|
|
if (forced || !event.isCancelled()) {
|
2021-06-06 08:59:50 +02:00
|
|
|
s.registered(false);
|
2020-06-12 07:45:49 +02:00
|
|
|
if (s.isRunning()) {
|
|
|
|
s.stop();
|
|
|
|
s.waitFor();
|
2017-04-01 18:50:09 +02:00
|
|
|
}
|
|
|
|
|
2019-05-17 00:36:41 +02:00
|
|
|
Logger.get("SubServers").info("Saving...");
|
2019-04-29 17:05:06 +02:00
|
|
|
ObjectMap<String> info = (plugin.servers.get().getMap("Servers").getKeys().contains(server))?plugin.servers.get().getMap("Servers").getMap(server).clone():new ObjectMap<String>();
|
2018-04-15 03:53:51 +02:00
|
|
|
info.set("Name", server);
|
|
|
|
info.set("Timestamp", Calendar.getInstance().getTime().getTime());
|
2017-04-01 18:50:09 +02:00
|
|
|
try {
|
2019-04-29 17:05:06 +02:00
|
|
|
if (plugin.servers.get().getMap("Servers").getKeys().contains(server)) {
|
|
|
|
plugin.servers.get().getMap("Servers").remove(server);
|
|
|
|
plugin.servers.save();
|
2017-04-01 18:50:09 +02:00
|
|
|
}
|
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
|
2019-05-17 00:36:41 +02:00
|
|
|
Logger.get("SubServers").info("Removing Files...");
|
2019-04-18 16:02:09 +02:00
|
|
|
queue(new PacketExDeleteServer(server, info, false, data -> {
|
2019-05-13 05:28:27 +02:00
|
|
|
if (data.getInt(0x0001) == 0 || data.getInt(0x0001) == 1) {
|
2017-04-14 04:39:51 +02:00
|
|
|
servers.remove(server.toLowerCase());
|
2019-05-17 00:36:41 +02:00
|
|
|
Logger.get("SubServers").info("Deleted SubServer: " + server);
|
2017-04-01 18:50:09 +02:00
|
|
|
} else {
|
2021-06-06 08:59:50 +02:00
|
|
|
s.registered(true);
|
2019-05-17 00:36:41 +02:00
|
|
|
Logger.get("SubServers").info("Couldn't remove " + server + " from memory. See " + getName() + " console for more details");
|
2017-04-01 18:50:09 +02:00
|
|
|
}
|
|
|
|
}));
|
|
|
|
return true;
|
|
|
|
} else return false;
|
|
|
|
}
|
2017-04-24 18:28:16 +02:00
|
|
|
|
2019-08-30 02:01:52 +02:00
|
|
|
@Override
|
|
|
|
public boolean destroy() {
|
2021-04-23 06:36:54 +02:00
|
|
|
if (Util.getDespiteException(() -> Util.reflect(SubProxy.class.getDeclaredField("running"), plugin), true)) {
|
2019-08-30 02:01:52 +02:00
|
|
|
return super.destroy();
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-05-14 04:02:38 +02:00
|
|
|
@Override
|
|
|
|
public ObjectMap<String> forSubData() {
|
|
|
|
ObjectMap<String> hinfo = super.forSubData();
|
|
|
|
ObjectMap<Integer> subdata = new ObjectMap<Integer>();
|
|
|
|
for (int channel : this.subdata.keySet()) subdata.set(channel, (this.subdata.get(channel) == null)?null:this.subdata.get(channel).getID());
|
|
|
|
hinfo.set("subdata", subdata);
|
|
|
|
return hinfo;
|
|
|
|
}
|
2017-04-01 07:37:48 +02:00
|
|
|
}
|