Use single-threaded I/O for StopAction

This commit is contained in:
ME1312 2020-08-13 18:26:22 -04:00
parent b18f047d53
commit 26490dc140
No known key found for this signature in database
GPG Key ID: FEFFE2F698E88FA8
6 changed files with 75 additions and 198 deletions

View File

@ -183,12 +183,21 @@ public class ExternalHost extends Host implements ClientHandler {
@Override @Override
public boolean removeSubServer(UUID player, String name) throws InterruptedException { public boolean removeSubServer(UUID player, String name) throws InterruptedException {
return removeSubServer(player, name, false);
}
@Override
public boolean forceRemoveSubServer(UUID player, String name) throws InterruptedException {
return removeSubServer(player, name, true);
}
protected boolean removeSubServer(UUID player, String name, boolean forced) throws InterruptedException {
if (Util.isNull(name)) throw new NullPointerException(); if (Util.isNull(name)) throw new NullPointerException();
SubServer server = servers.get(name.toLowerCase()); SubServer server = servers.get(name.toLowerCase());
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, server); SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, server);
plugin.getPluginManager().callEvent(event); plugin.getPluginManager().callEvent(event);
if (!event.isCancelled()) { if (forced || !event.isCancelled()) {
if (server.isRunning()) { if (server.isRunning()) {
server.stop(); server.stop();
server.waitFor(); server.waitFor();
@ -203,33 +212,23 @@ public class ExternalHost extends Host implements ClientHandler {
} }
@Override @Override
public boolean forceRemoveSubServer(UUID player, String name) throws InterruptedException { public boolean recycleSubServer(UUID player, String name) throws InterruptedException {
if (Util.isNull(name)) throw new NullPointerException(); return recycleSubServer(player, name, false);
SubServer server = servers.get(name.toLowerCase());
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, server);
plugin.getPluginManager().callEvent(event);
if (server.isRunning()) {
server.stop();
server.waitFor();
}
queue(new PacketExRemoveServer(name.toLowerCase(), data -> {
if (data.getInt(0x0001) == 0 || data.getInt(0x0001) == 1) {
servers.remove(name.toLowerCase());
}
}));
return true;
} }
@Override @Override
public boolean recycleSubServer(UUID player, String name) throws InterruptedException { public boolean forceRecycleSubServer(UUID player, String name) throws InterruptedException {
return recycleSubServer(player, name, true);
}
protected boolean recycleSubServer(UUID player, String name, boolean forced) throws InterruptedException {
if (Util.isNull(name)) throw new NullPointerException(); if (Util.isNull(name)) throw new NullPointerException();
SubServer s = servers.get(name.toLowerCase()); SubServer s = servers.get(name.toLowerCase());
String server = s.getName(); String server = s.getName();
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, s); SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, s);
plugin.getPluginManager().callEvent(event); plugin.getPluginManager().callEvent(event);
if (!event.isCancelled()) { if (forced || !event.isCancelled()) {
if (s.isRunning()) { if (s.isRunning()) {
s.stop(); s.stop();
s.waitFor(); s.waitFor();
@ -262,52 +261,23 @@ public class ExternalHost extends Host implements ClientHandler {
} }
@Override @Override
public boolean forceRecycleSubServer(UUID player, String name) throws InterruptedException { public boolean deleteSubServer(UUID player, String name) throws InterruptedException {
if (Util.isNull(name)) throw new NullPointerException(); return deleteSubServer(player, name, false);
SubServer s = servers.get(name.toLowerCase());
String server = s.getName();
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, s);
plugin.getPluginManager().callEvent(event);
if (s.isRunning()) {
s.stop();
s.waitFor();
}
Logger.get("SubServers").info("Saving...");
ObjectMap<String> info = (plugin.servers.get().getMap("Servers").getKeys().contains(server))?plugin.servers.get().getMap("Servers").getMap(server).clone():new ObjectMap<String>();
info.set("Name", server);
info.set("Timestamp", Calendar.getInstance().getTime().getTime());
try {
if (plugin.servers.get().getMap("Servers").getKeys().contains(server)) {
plugin.servers.get().getMap("Servers").remove(server);
plugin.servers.save();
}
} catch (Exception e) {
e.printStackTrace();
}
Logger.get("SubServers").info("Moving Files...");
queue(new PacketExDeleteServer(server, info, true, data -> {
if (data.getInt(0x0001) == 0 || data.getInt(0x0001) == 1) {
servers.remove(server.toLowerCase());
Logger.get("SubServers").info("Deleted SubServer: " + server);
} else {
Logger.get("SubServers").info("Couldn't remove " + server + " from memory. See " + getName() + " console for more details");
}
}));
return true;
} }
@Override @Override
public boolean deleteSubServer(UUID player, String name) throws InterruptedException { public boolean forceDeleteSubServer(UUID player, String name) throws InterruptedException {
return deleteSubServer(player, name, true);
}
protected boolean deleteSubServer(UUID player, String name, boolean forced) throws InterruptedException {
if (Util.isNull(name)) throw new NullPointerException(); if (Util.isNull(name)) throw new NullPointerException();
SubServer s = servers.get(name.toLowerCase()); SubServer s = servers.get(name.toLowerCase());
String server = s.getName(); String server = s.getName();
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, getSubServer(server)); SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, getSubServer(server));
plugin.getPluginManager().callEvent(event); plugin.getPluginManager().callEvent(event);
if (!event.isCancelled()) { if (forced || !event.isCancelled()) {
if (s.isRunning()) { if (s.isRunning()) {
s.stop(); s.stop();
s.waitFor(); s.waitFor();
@ -339,44 +309,6 @@ public class ExternalHost extends Host implements ClientHandler {
} else return false; } else return false;
} }
@Override
public boolean forceDeleteSubServer(UUID player, String name) throws InterruptedException {
if (Util.isNull(name)) throw new NullPointerException();
SubServer s = servers.get(name.toLowerCase());
String server = s.getName();
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, getSubServer(server));
plugin.getPluginManager().callEvent(event);
if (s.isRunning()) {
s.stop();
s.waitFor();
}
Logger.get("SubServers").info("Saving...");
ObjectMap<String> info = (plugin.servers.get().getMap("Servers").getKeys().contains(server))?plugin.servers.get().getMap("Servers").getMap(server).clone():new ObjectMap<String>();
info.set("Name", server);
info.set("Timestamp", Calendar.getInstance().getTime().getTime());
try {
if (plugin.servers.get().getMap("Servers").getKeys().contains(server)) {
plugin.servers.get().getMap("Servers").remove(server);
plugin.servers.save();
}
} catch (Exception e) {
e.printStackTrace();
}
Logger.get("SubServers").info("Removing Files...");
queue(new PacketExDeleteServer(server, info, false, data -> {
if (data.getInt(0x0001) == 0 || data.getInt(0x0001) == 1) {
servers.remove(server.toLowerCase());
Logger.get("SubServers").info("Deleted SubServer: " + server);
} else {
Logger.get("SubServers").info("Couldn't remove " + server + " from memory. See " + getName() + " console for more details");
}
}));
return true;
}
@Override @Override
public boolean destroy() { public boolean destroy() {
if (Util.getDespiteException(() -> Util.reflect(BungeeCord.class.getDeclaredField("isRunning"), plugin), true)) { if (Util.getDespiteException(() -> Util.reflect(BungeeCord.class.getDeclaredField("isRunning"), plugin), true)) {

View File

@ -114,11 +114,20 @@ public class InternalHost extends Host {
@Override @Override
public boolean removeSubServer(UUID player, String name) throws InterruptedException { public boolean removeSubServer(UUID player, String name) throws InterruptedException {
return removeSubServer(player, name, false);
}
@Override
public boolean forceRemoveSubServer(UUID player, String name) throws InterruptedException {
return removeSubServer(player, name, true);
}
protected boolean removeSubServer(UUID player, String name, boolean forced) throws InterruptedException {
if (Util.isNull(name)) throw new NullPointerException(); if (Util.isNull(name)) throw new NullPointerException();
SubServer server = servers.get(name.toLowerCase()); SubServer server = servers.get(name.toLowerCase());
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, server); SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, server);
plugin.getPluginManager().callEvent(event); plugin.getPluginManager().callEvent(event);
if (!event.isCancelled()) { if (forced || !event.isCancelled()) {
if (server.isRunning()) { if (server.isRunning()) {
server.stop(); server.stop();
server.waitFor(); server.waitFor();
@ -130,74 +139,22 @@ public class InternalHost extends Host {
} else return false; } else return false;
} }
@Override
public boolean forceRemoveSubServer(UUID player, String name) throws InterruptedException {
if (Util.isNull(name)) throw new NullPointerException();
SubServer server = servers.get(name.toLowerCase());
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, server);
plugin.getPluginManager().callEvent(event);
if (server.isRunning()) {
server.stop();
server.waitFor();
}
if (UPnP.isUPnPAvailable() && UPnP.isMappedTCP(server.getAddress().getPort()))
UPnP.closePortTCP(server.getAddress().getPort());
servers.remove(name.toLowerCase());
return true;
}
@Override @Override
public boolean recycleSubServer(UUID player, String name) throws InterruptedException { public boolean recycleSubServer(UUID player, String name) throws InterruptedException {
if (Util.isNull(name)) throw new NullPointerException(); return recycleSubServer(player, name, false, true);
String server = servers.get(name.toLowerCase()).getName();
File from = new File(getPath(), servers.get(server.toLowerCase()).getPath());
if (removeSubServer(player, server)) {
new Thread(() -> {
UniversalFile to = new UniversalFile(plugin.dir, "SubServers:Recently Deleted:" + server.toLowerCase());
try {
if (from.exists()) {
Logger.get("SubServers").info("Moving Files...");
if (to.exists()) {
if (to.isDirectory()) Util.deleteDirectory(to);
else to.delete();
}
to.mkdirs();
Util.copyDirectory(from, to);
Util.deleteDirectory(from);
}
} catch (Exception e) {
e.printStackTrace();
}
Logger.get("SubServers").info("Saving...");
YAMLSection info = (plugin.servers.get().getMap("Servers").getKeys().contains(server))?new YAMLSection(plugin.servers.get().getMap("Servers").getMap(server).get()):new YAMLSection();
info.set("Name", server);
info.set("Timestamp", Calendar.getInstance().getTime().getTime());
try {
if (plugin.servers.get().getMap("Servers").getKeys().contains(server)) {
plugin.servers.get().getMap("Servers").remove(server);
plugin.servers.save();
}
if (!to.exists()) to.mkdirs();
FileWriter writer = new FileWriter(new File(to, "info.json"));
writer.write(info.toJSON().toString());
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
Logger.get("SubServers").info("Deleted SubServer: " + server);
}, "SubServers.Bungee::Internal_Server_Recycler(" + name + ')').start();
return true;
} else return false;
} }
@Override @Override
public boolean forceRecycleSubServer(UUID player, String name) throws InterruptedException { public boolean forceRecycleSubServer(UUID player, String name) throws InterruptedException {
return recycleSubServer(player, name, true, true);
}
protected boolean recycleSubServer(UUID player, String name, boolean forced, boolean multithreading) throws InterruptedException {
if (Util.isNull(name)) throw new NullPointerException(); if (Util.isNull(name)) throw new NullPointerException();
String server = servers.get(name.toLowerCase()).getName(); String server = servers.get(name.toLowerCase()).getName();
File from = new File(getPath(), servers.get(server.toLowerCase()).getPath()); File from = new File(getPath(), servers.get(server.toLowerCase()).getPath());
if (forceRemoveSubServer(player, server)) { if (removeSubServer(player, server, forced)) {
new Thread(() -> { Runnable method = () -> {
UniversalFile to = new UniversalFile(plugin.dir, "SubServers:Recently Deleted:" + server.toLowerCase()); UniversalFile to = new UniversalFile(plugin.dir, "SubServers:Recently Deleted:" + server.toLowerCase());
try { try {
if (from.exists()) { if (from.exists()) {
@ -231,49 +188,31 @@ public class InternalHost extends Host {
e.printStackTrace(); e.printStackTrace();
} }
Logger.get("SubServers").info("Deleted SubServer: " + server); Logger.get("SubServers").info("Deleted SubServer: " + server);
}, "SubServers.Bungee::Internal_Server_Recycler(" + name + ')').start(); };
if (multithreading) {
new Thread(method, "SubServers.Bungee::Internal_Server_Recycler(" + name + ')').start();
} else method.run();
return true; return true;
} else return false; } else return false;
} }
@Override @Override
public boolean deleteSubServer(UUID player, String name) throws InterruptedException { public boolean deleteSubServer(UUID player, String name) throws InterruptedException {
if (Util.isNull(name)) throw new NullPointerException(); return deleteSubServer(player, name, false, true);
String server = servers.get(name.toLowerCase()).getName();
File from = new File(getPath(), servers.get(server.toLowerCase()).getPath());
if (removeSubServer(player, server)) {
new Thread(() -> {
try {
if (from.exists()) {
Logger.get("SubServers").info("Removing Files...");
Util.deleteDirectory(from);
}
} catch (Exception e) {
e.printStackTrace();
}
Logger.get("SubServers").info("Saving...");
try {
if (plugin.servers.get().getMap("Servers").getKeys().contains(server)) {
plugin.servers.get().getMap("Servers").remove(server);
plugin.servers.save();
}
} catch (Exception e) {
e.printStackTrace();
}
Logger.get("SubServers").info("Deleted SubServer: " + server);
}, "SubServers.Bungee::Internal_Server_Deletion(" + name + ')').start();
return true;
} else return false;
} }
@Override @Override
public boolean forceDeleteSubServer(UUID player, String name) throws InterruptedException { public boolean forceDeleteSubServer(UUID player, String name) throws InterruptedException {
return deleteSubServer(player, name, true, true);
}
protected boolean deleteSubServer(UUID player, String name, boolean forced, boolean multithreading) throws InterruptedException {
if (Util.isNull(name)) throw new NullPointerException(); if (Util.isNull(name)) throw new NullPointerException();
String server = servers.get(name.toLowerCase()).getName(); String server = servers.get(name.toLowerCase()).getName();
File from = new File(getPath(), servers.get(server.toLowerCase()).getPath()); File from = new File(getPath(), servers.get(server.toLowerCase()).getPath());
if (forceRemoveSubServer(player, server)) { if (removeSubServer(player, server, forced)) {
new Thread(() -> { Runnable method = () -> {
try { try {
if (from.exists()) { if (from.exists()) {
Logger.get("SubServers").info("Removing Files..."); Logger.get("SubServers").info("Removing Files...");
@ -293,7 +232,11 @@ public class InternalHost extends Host {
e.printStackTrace(); e.printStackTrace();
} }
Logger.get("SubServers").info("Deleted SubServer: " + server); Logger.get("SubServers").info("Deleted SubServer: " + server);
}, "SubServers.Bungee::Internal_Server_Deletion(" + name + ')').start(); };
if (multithreading) {
new Thread(method, "SubServers.Bungee::Internal_Server_Deletion(" + name + ')').start();
} else method.run();
return true; return true;
} else return false; } else return false;
} }

View File

@ -180,9 +180,9 @@ public class InternalSubServer extends SubServerImpl {
if (stopaction == StopAction.REMOVE_SERVER || stopaction == StopAction.RECYCLE_SERVER || stopaction == StopAction.DELETE_SERVER) { if (stopaction == StopAction.REMOVE_SERVER || stopaction == StopAction.RECYCLE_SERVER || stopaction == StopAction.DELETE_SERVER) {
try { try {
if (stopaction == StopAction.RECYCLE_SERVER) { if (stopaction == StopAction.RECYCLE_SERVER) {
host.recycleSubServer(getName()); host.recycleSubServer(null, getName(), false, false);
} else if (stopaction == StopAction.DELETE_SERVER) { } else if (stopaction == StopAction.DELETE_SERVER) {
host.deleteSubServer(getName()); host.deleteSubServer(null, getName(), false, false);
} else { } else {
try { try {
if (host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) { if (host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {

View File

@ -24,18 +24,20 @@ public class Proxy implements ClientHandler, ExtraDataHandler {
private HashMap<Integer, SubDataClient> subdata = new HashMap<Integer, SubDataClient>(); private HashMap<Integer, SubDataClient> subdata = new HashMap<Integer, SubDataClient>();
private ObjectMap<String> extra = new ObjectMap<String>(); private ObjectMap<String> extra = new ObjectMap<String>();
private final String signature; private final String signature;
private boolean persistent = true; private boolean persistent;
private String nick = null; private String nick = null;
private final String name; private final String name;
@SuppressWarnings("deprecation")
public Proxy(String name) throws IllegalArgumentException { public Proxy(String name) throws IllegalArgumentException {
if (name == null) { this(name, name != null);
name = Util.getNew(SubAPI.getInstance().getInternals().proxies.keySet(), () -> UUID.randomUUID().toString()); }
persistent = false;
} @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); if (name.contains(" ")) throw new IllegalArgumentException("Proxy names cannot have spaces: " + name);
this.name = name; this.name = name;
this.persistent = persistent;
this.signature = SubAPI.getInstance().signAnonymousObject(); this.signature = SubAPI.getInstance().signAnonymousObject();
subdata.put(0, null); subdata.put(0, null);
@ -57,8 +59,8 @@ public class Proxy implements ClientHandler, ExtraDataHandler {
if (client != null || channel == 0) { if (client != null || channel == 0) {
if (!subdata.keySet().contains(channel) || (channel == 0 && (client == null || subdata.get(channel) == null))) { if (!subdata.keySet().contains(channel) || (channel == 0 && (client == null || subdata.get(channel) == null))) {
update = true; update = true;
subdata.put(channel, (SubDataClient) client); subdata.put(channel, client);
if (client != null && (client.getHandler() == null || !equals(client.getHandler()))) ((SubDataClient) client).setHandler(this); if (client != null && (client.getHandler() == null || !equals(client.getHandler()))) client.setHandler(this);
} }
} else { } else {
update = true; update = true;

View File

@ -749,7 +749,7 @@ public final class SubProxy extends BungeeCord implements Listener {
*/ */
@Override @Override
public String getName() { public String getName() {
return (isPatched)?"SubServers Platform":super.getName(); return (isPatched)?"SubServers.Bungee":super.getName();
} }
/** /**

View File

@ -241,9 +241,9 @@ public final class ExProxy extends BungeeCord implements Listener {
* *
* @return Software Name * @return Software Name
*/ */
@Override @Override // SubServers.Bungee is used here to hide the fact that this isn't the controller instance
public String getName() { public String getName() {
return (isPatched)?"SubServers Platform":super.getName(); return (isPatched)?"SubServers.Bungee":super.getName();
} }
/** /**