Feature creep commit

This commit has 3 new features in it:
-> Internal Templates
-> The new Purpur Template
-> Changes to External Logging
This commit is contained in:
ME1312 2021-06-24 23:06:53 -04:00
parent ff709ba314
commit 1533987bf5
No known key found for this signature in database
GPG Key ID: FEFFE2F698E88FA8
34 changed files with 258 additions and 126 deletions

View File

@ -85,6 +85,7 @@
<mkdir dir="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates" />
<zip basedir="${basedir}/../SubServers.Creator" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/forge.zip" includes="Forge/**" />
<zip basedir="${basedir}/../SubServers.Creator" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/paper.zip" includes="Paper/**" />
<zip basedir="${basedir}/../SubServers.Creator" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/purpur.zip" includes="Purpur/**" />
<zip basedir="${basedir}/../SubServers.Creator" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/spigot.zip" includes="Spigot/**" />
<zip basedir="${basedir}/../SubServers.Creator" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/sponge.zip" includes="Sponge/**" />
<zip basedir="${basedir}/../SubServers.Creator" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/vanilla.zip" includes="Vanilla/**" />

View File

@ -71,7 +71,7 @@ public class ExternalSubCreator extends SubCreator {
try {
if (file.isDirectory() && !file.getName().endsWith(".x")) {
ObjectMap<String> config = (new UniversalFile(file, "template.yml").exists())?new YAMLConfig(new UniversalFile(file, "template.yml")).get().getMap("Template", new ObjectMap<String>()):new ObjectMap<String>();
ServerTemplate template = loadTemplate(file.getName(), config.getBoolean("Enabled", true), config.getRawString("Icon", "::NULL::"), file, config.getMap("Build", new ObjectMap<String>()), config.getMap("Settings", new ObjectMap<String>()));
ServerTemplate template = loadTemplate(file.getName(), config.getBoolean("Enabled", true), config.getBoolean("Internal", false), config.getRawString("Icon", "::NULL::"), file, config.getMap("Build", new ObjectMap<String>()), config.getMap("Settings", new ObjectMap<String>()));
templatesR.put(file.getName().toLowerCase(), template);
if (config.getKeys().contains("Display")) template.setDisplayName(config.getString("Display"));
}
@ -82,7 +82,6 @@ public class ExternalSubCreator extends SubCreator {
}
if (host.available && !Util.getDespiteException(() -> Util.reflect(SubProxy.class.getDeclaredField("reloading"), host.plugin), false)) {
host.queue(new PacketExConfigureHost(host.plugin, host));
host.queue(new PacketExUploadTemplates(host.plugin));
if (enableRT == null || enableRT) host.queue(new PacketExDownloadTemplates(host.plugin, host));
}
@ -115,7 +114,6 @@ public class ExternalSubCreator extends SubCreator {
logger.start();
host.queue(new PacketExCreateServer(player, name, template, version, port, logger.getExternalAddress(), data -> {
finish(player, null, name, template, version, fport, prefix, origin, data, callback);
logger.stop();
this.thread.remove(name.toLowerCase());
}));
return true;
@ -156,7 +154,6 @@ public class ExternalSubCreator extends SubCreator {
((ExternalSubServer) server).updating(false);
if (callback != null) callback.run(s != null);
});
logger.stop();
this.thread.remove(name.toLowerCase());
}));
return true;
@ -334,14 +331,26 @@ public class ExternalSubCreator extends SubCreator {
@Override
public Map<String, ServerTemplate> getTemplates() {
TreeMap<String, ServerTemplate> map = new TreeMap<String, ServerTemplate>();
if (enableRT != null && enableRT) map.putAll(templatesR);
map.putAll(templates);
if (enableRT != null && enableRT) for (Map.Entry<String, ServerTemplate> template : templatesR.entrySet()) {
if (!template.getValue().isInternal()) map.put(template.getKey(), template.getValue());
}
for (Map.Entry<String, ServerTemplate> template : templates.entrySet()) {
if (!template.getValue().isInternal()) map.put(template.getKey(), template.getValue());
}
return map;
}
@Override
public ServerTemplate getTemplate(String name) {
if (Util.isNull(name)) throw new NullPointerException();
return getTemplates().get(name.toLowerCase());
name = name.toLowerCase();
ServerTemplate template = templates.getOrDefault(name, null);
if (template == null && enableRT != null && enableRT) template = templatesR.getOrDefault(name, null);
if (template == null || template.isInternal()) {
return null;
} else {
return template;
}
}
}

View File

@ -13,7 +13,9 @@ import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
@ -72,29 +74,17 @@ public class ExternalSubLogger extends SubLogger {
}
@SuppressWarnings("deprecation")
private void log(String line) {
private void log(String type, String msg) {
if (started) {
String msg = line;
Level level;
// REGEX Formatting
String type = "";
Matcher matcher = Pattern.compile("^((?:\\s*\\[?([0-9]{2}:[0-9]{2}:[0-9]{2})]?)?[\\s\\/\\\\\\|]*(?:\\[|\\[.*\\/)?(MESSAGE|INFO|WARNING|WARN|ERROR|ERR|SEVERE)\\]?:?(?:\\s*>)?\\s*)").matcher(msg.replaceAll("\u001B\\[[;\\d]*m", ""));
while (matcher.find()) {
type = matcher.group(3).toUpperCase();
}
msg = msg.substring(msg.length() - msg.replaceAll("^((?:\\s*\\[?([0-9]{2}:[0-9]{2}:[0-9]{2})]?)?[\\s\\/\\\\\\|]*(?:\\[|\\[.*\\/)?(MESSAGE|INFO|WARNING|WARN|ERROR|ERR|SEVERE)\\]?:?(?:\\s*>)?\\s*)", "").length());
// Determine LOG LEVEL
switch (type) {
case "WARNING":
case "WARN":
level = Level.WARNING;
break;
case "SEVERE":
case "ERROR":
case "ERR":
level = Level.SEVERE;
break;
default:
@ -117,7 +107,7 @@ public class ExternalSubLogger extends SubLogger {
// Log to FILE
if (writer != null) {
writer.println(line);
writer.println('[' + new SimpleDateFormat("HH:mm:ss").format(Calendar.getInstance().getTime()) + "] [" + level + "] > " + msg);
writer.flush();
}
}
@ -147,7 +137,6 @@ public class ExternalSubLogger extends SubLogger {
@Override
public void stop() {
if (started) {
PacketInExLogMessage.unregister(id);
id = null;
started = false;
List<SubLogFilter> filters = new ArrayList<SubLogFilter>();

View File

@ -102,30 +102,24 @@ public class InternalSubCreator extends SubCreator {
if (templates.get(other.toLowerCase()).isEnabled()) {
if (version != null || !templates.get(other.toLowerCase()).requiresVersion()) {
if (update == null || templates.get(other.toLowerCase()).canUpdate()) {
ObjectMap<String> config = build(dir, templates.get(other.toLowerCase()), history);
if (config == null) {
throw new SubCreatorException();
} else {
server.setAll(config);
}
server.setAll(this.build(dir, templates.get(other.toLowerCase()), history));
} else {
Logger.get(prefix).info("Skipping template that cannot be run in update mode: " + other);
Logger.get(prefix).warning("Skipping template that cannot be run in update mode: " + other);
}
} else {
Logger.get(prefix).info("Skipping template that requires extra versioning information: " + other);
Logger.get(prefix).warning("Skipping template that requires extra versioning information: " + other);
}
} else {
Logger.get(prefix).info("Skipping disabled template: " + other);
Logger.get(prefix).warning("Skipping disabled template: " + other);
}
} else {
Logger.get(prefix).info("Skipping missing template: " + other);
Logger.get(prefix).warning("Skipping missing template: " + other);
}
}
server.setAll(template.getConfigOptions());
try {
Logger.get(prefix).info("Loading" + ((template.isDynamic())?" Dynamic":"") + " Template: " + template.getDisplayName());
if (template.getBuildOptions().getBoolean("Update-Files", false)) updateDirectory(template.getDirectory(), dir);
else Util.copyDirectory(template.getDirectory(), dir);
updateDirectory(template.getDirectory(), dir, template.getBuildOptions().getBoolean("Update-Files", false));
for (ObjectMapValue<String> replacement : template.getBuildOptions().getMap("Replacements", new ObjectMap<>()).getValues()) if (!replacement.isNull()) {
replacements.put(replacement.getHandle().toLowerCase().replace('-', '_').replace(' ', '_'), replacement.asRawString());
@ -235,7 +229,6 @@ public class InternalSubCreator extends SubCreator {
declaration.run();
File dir = (update != null)?new File(update.getFullPath()):new File(host.getPath(),
(template.getConfigOptions().contains("Directory"))?new ReplacementScanner(replacements).replace(template.getConfigOptions().getRawString("Directory")).toString():name);
dir.mkdirs();
ObjectMap<String> server = new ObjectMap<String>();
ObjectMap<String> config;
@ -366,7 +359,7 @@ public class InternalSubCreator extends SubCreator {
try {
if (file.isDirectory() && !file.getName().endsWith(".x")) {
ObjectMap<String> config = (new UniversalFile(file, "template.yml").exists()) ? new YAMLConfig(new UniversalFile(file, "template.yml")).get().getMap("Template", new ObjectMap<String>()) : new ObjectMap<String>();
ServerTemplate template = loadTemplate(file.getName(), config.getBoolean("Enabled", true), config.getRawString("Icon", "::NULL::"), file, config.getMap("Build", new ObjectMap<String>()), config.getMap("Settings", new ObjectMap<String>()));
ServerTemplate template = loadTemplate(file.getName(), config.getBoolean("Enabled", true), config.getBoolean("Internal", false), config.getRawString("Icon", "::NULL::"), file, config.getMap("Build", new ObjectMap<String>()), config.getMap("Settings", new ObjectMap<String>()));
templates.put(file.getName().toLowerCase(), template);
if (config.getKeys().contains("Display")) template.setDisplayName(config.getString("Display"));
}
@ -550,13 +543,23 @@ public class InternalSubCreator extends SubCreator {
@Override
public Map<String, ServerTemplate> getTemplates() {
return new TreeMap<String, ServerTemplate>(templates);
TreeMap<String, ServerTemplate> map = new TreeMap<String, ServerTemplate>();
for (Map.Entry<String, ServerTemplate> template : templates.entrySet()) {
if (!template.getValue().isInternal()) map.put(template.getKey(), template.getValue());
}
return map;
}
@Override
public ServerTemplate getTemplate(String name) {
if (Util.isNull(name)) throw new NullPointerException();
return getTemplates().get(name.toLowerCase());
ServerTemplate template = templates.getOrDefault(name.toLowerCase(), null);
if (template == null || template.isInternal()) {
return null;
} else {
return template;
}
}
private static Pair<YAMLSection, Map<String, Object>> subdata = null;
@ -598,23 +601,21 @@ public class InternalSubCreator extends SubCreator {
}
}
private void updateDirectory(File from, File to) {
if (from.isDirectory() && !Files.isSymbolicLink(from.toPath())) {
if (!to.exists()) {
to.mkdirs();
}
private void updateDirectory(File from, File to, boolean overwrite) {
if (!to.exists()) {
Util.copyDirectory(from, to);
} else if (from.isDirectory() && !Files.isSymbolicLink(from.toPath())) {
String files[] = from.list();
for (String file : files) {
File srcFile = new File(from, file);
File destFile = new File(to, file);
updateDirectory(srcFile, destFile);
updateDirectory(srcFile, destFile, overwrite);
}
} else {
try {
if (!to.exists() || from.length() != to.length() || !Arrays.equals(generateSHA256(to), generateSHA256(from))) {
if (overwrite && (from.length() != to.length() || !Arrays.equals(generateSHA256(to), generateSHA256(from)))) {
if (to.exists()) {
if (to.isDirectory()) Util.deleteDirectory(to);
else to.delete();

View File

@ -90,6 +90,7 @@ public class InternalSubLogger extends SubLogger {
}
}
private static final String PATTERN = "^((?:\\s*\\[?([0-9]{2}:[0-9]{2}:[0-9]{2})]?)?[\\s\\/\\\\\\|]*(?:\\[|\\[.*\\/)?(DEBUG|MESSAGE|MSG|" + Pattern.quote(Level.INFO.getLocalizedName()) + "|INFO|" + Pattern.quote(Level.WARNING.getLocalizedName()) + "|WARNING|WARN|ERROR|ERR|" + Pattern.quote(Level.SEVERE.getLocalizedName()) + "|SEVERE)\\]?:?(?:\\s*>)?\\s*)";
private void log(String line) {
if (!line.startsWith(">")) {
String msg = line;
@ -97,15 +98,19 @@ public class InternalSubLogger extends SubLogger {
// REGEX Formatting
String type = "";
Matcher matcher = Pattern.compile("^((?:\\s*\\[?([0-9]{2}:[0-9]{2}:[0-9]{2})]?)?[\\s\\/\\\\\\|]*(?:\\[|\\[.*\\/)?(MESSAGE|INFO|WARNING|WARN|ERROR|ERR|SEVERE)\\]?:?(?:\\s*>)?\\s*)").matcher(msg.replaceAll("\u001B\\[[;\\d]*m", ""));
Matcher matcher = Pattern.compile(PATTERN).matcher(msg.replaceAll("\u001B\\[[;\\d]*m", ""));
while (matcher.find()) {
type = matcher.group(3).toUpperCase();
}
msg = msg.replaceAll("^((?:\\s*\\[?([0-9]{2}:[0-9]{2}:[0-9]{2})]?)?[\\s\\/\\\\\\|]*(?:\\[|\\[.*\\/)?(MESSAGE|INFO|WARNING|WARN|ERROR|ERR|SEVERE)\\]?:?(?:\\s*>)?\\s*)", "");
msg = msg.replaceAll(PATTERN, "");
// Determine LOG LEVEL
switch (type) {
if (type.equalsIgnoreCase(Level.WARNING.getLocalizedName())) {
level = Level.WARNING;
} else if (type.equalsIgnoreCase(Level.SEVERE.getLocalizedName())) {
level = Level.SEVERE;
} else switch (type) {
case "WARNING":
case "WARN":
level = Level.WARNING;

View File

@ -22,6 +22,7 @@ public abstract class SubCreator {
private String name;
private String nick = null;
private boolean enabled;
private boolean internal;
private String icon;
private File directory;
private ServerType type;
@ -39,14 +40,15 @@ public abstract class SubCreator {
* @param options Configuration Options
*/
public ServerTemplate(String name, boolean enabled, String icon, File directory, ObjectMap<String> build, ObjectMap<String> options) {
this(name, enabled, icon, directory, build, options, true);
this(name, enabled, false, icon, directory, build, options, true);
}
private ServerTemplate(String name, boolean enabled, String icon, File directory, ObjectMap<String> build, ObjectMap<String> options, boolean dynamic) {
private ServerTemplate(String name, boolean enabled, boolean internal, String icon, File directory, ObjectMap<String> build, ObjectMap<String> options, boolean dynamic) {
if (Util.isNull(name, enabled, directory, build, options)) throw new NullPointerException();
if (name.contains(" ")) throw new InvalidTemplateException("Template names cannot have spaces: " + name);
this.name = name;
this.enabled = enabled;
this.internal = internal;
this.icon = icon;
this.directory = directory;
this.type = (build.contains("Server-Type"))?ServerType.valueOf(build.getRawString("Server-Type").toUpperCase()):ServerType.CUSTOM;
@ -104,6 +106,15 @@ public abstract class SubCreator {
enabled = value;
}
/**
* Get if this Template is for Internal use only
*
* @return Internal Status
*/
public boolean isInternal() {
return internal;
}
/**
* Get the Item Icon for this Template
*
@ -161,7 +172,7 @@ public abstract class SubCreator {
/**
* Get whether this Template was generated by a SubCreator instance
*
* @return Custom Status
* @return Dynamic Status
*/
public boolean isDynamic() {
return dynamic;
@ -512,13 +523,14 @@ public abstract class SubCreator {
*
* @param name Template Name
* @param enabled Template Enabled Status
* @param internal Template Internal Status
* @param icon Template Item Icon Name
* @param directory Template Directory
* @param build Build Options
* @param options Configuration Options
*/
protected ServerTemplate loadTemplate(String name, boolean enabled, String icon, File directory, ObjectMap<String> build, ObjectMap<String> options) {
return new ServerTemplate(name, enabled, icon, directory, build, options, false);
protected ServerTemplate loadTemplate(String name, boolean enabled, boolean internal, String icon, File directory, ObjectMap<String> build, ObjectMap<String> options) {
return new ServerTemplate(name, enabled, internal, icon, directory, build, options, false);
}
/**

View File

@ -40,8 +40,8 @@ public class PacketExUploadTemplates implements PacketObjectIn<Integer>, PacketO
for (String name : templates.getKeys()) {
try {
UniversalFile dir = new UniversalFile(templatedir, name);
SubCreator.ServerTemplate template = Util.reflect(SubCreator.class.getDeclaredMethod("loadTemplate", String.class, boolean.class, String.class, File.class, ObjectMap.class, ObjectMap.class),
((ExternalHost) client.getHandler()).getCreator(), name, templates.getMap(name).getBoolean("enabled"), templates.getMap(name).getRawString("icon"), dir,
SubCreator.ServerTemplate template = Util.reflect(SubCreator.class.getDeclaredMethod("loadTemplate", String.class, boolean.class, boolean.class, String.class, File.class, ObjectMap.class, ObjectMap.class),
((ExternalHost) client.getHandler()).getCreator(), name, templates.getMap(name).getBoolean("enabled"), templates.getMap(name).getBoolean("internal"), templates.getMap(name).getRawString("icon"), dir,
templates.getMap(name).getMap("build").clone(), templates.getMap(name).getMap("settings").clone());
map.put(name.toLowerCase(), template);
if (!templates.getMap(name).getRawString("display").equals(name)) template.setDisplayName(templates.getMap(name).getRawString("display"));
@ -55,6 +55,6 @@ public class PacketExUploadTemplates implements PacketObjectIn<Integer>, PacketO
@Override
public int version() {
return 0x0001;
return 0x0002;
}
}

View File

@ -23,8 +23,12 @@ public class PacketInExLogMessage implements PacketObjectIn<Integer> {
@Override
public void receive(SubDataClient client, ObjectMap<Integer> data) {
try {
if (data.contains(0x0000) && data.contains(0x0001) && loggers.keySet().contains(data.getUUID(0x0000))) {
Util.reflect(ExternalSubLogger.class.getDeclaredMethod("log", String.class), loggers.get(data.getUUID(0x0000)), data.getRawString(0x0001));
if (data.contains(0x0000) && loggers.keySet().contains(data.getUUID(0x0000))) {
if (data.contains(0x0001) && data.contains(0x0002)) {
Util.reflect(ExternalSubLogger.class.getDeclaredMethod("log", String.class, String.class), loggers.get(data.getUUID(0x0000)), data.getRawString(0x0001), data.getRawString(0x0002));
} else {
unregister(data.getUUID(0x0000));
}
}
} catch (Exception e) {
e.printStackTrace();
@ -33,7 +37,7 @@ public class PacketInExLogMessage implements PacketObjectIn<Integer> {
@Override
public int version() {
return 0x0001;
return 0x0002;
}
/**
@ -54,6 +58,6 @@ public class PacketInExLogMessage implements PacketObjectIn<Integer> {
* @param id External Address
*/
public static void unregister(UUID id) {
loggers.remove(id);
loggers.remove(id).stop();
}
}

View File

@ -65,7 +65,7 @@ public class PacketLinkExHost implements InitialPacket, PacketObjectIn<Integer>,
HashMap<Integer, SubDataClient> subdata = Util.getDespiteException(() -> Util.reflect(ExternalHost.class.getDeclaredField("subdata"), host), null);
if (!subdata.keySet().contains(channel) || (channel == 0 && subdata.get(0) == null)) {
((ExternalHost) host).setSubData(client, channel);
Logger.get("SubData").info(client.getAddress().toString() + " has been defined as Host: " + host.getName() + ((channel > 0)?" (Sub-"+channel+")":""));
Logger.get("SubData").info(client.getAddress().toString() + " has been defined as Host: " + host.getName() + ((channel > 0)?" [+"+channel+"]":""));
queue(host.getName(), () -> client.sendPacket(new PacketLinkExHost(0, null)));
setReady(client);
} else {

View File

@ -76,7 +76,7 @@ public class PacketLinkProxy implements InitialPacket, PacketObjectIn<Integer>,
if (!subdata.keySet().contains(channel) || (channel == 0 && subdata.get(0) == null)) {
proxy.setSubData(client, channel);
if (isnew) plugin.getPluginManager().callEvent(new SubAddProxyEvent(proxy));
Logger.get("SubData").info(client.getAddress().toString() + " has been defined as Proxy: " + proxy.getName() + ((channel > 0)?" (Sub-"+channel+")":""));
Logger.get("SubData").info(client.getAddress().toString() + " has been defined as Proxy: " + proxy.getName() + ((channel > 0)?" [+"+channel+"]":""));
queue(proxy.getName(), () -> client.sendPacket(new PacketLinkProxy(proxy.getName(), 0, null)));
setReady(client);
} else {

View File

@ -107,7 +107,7 @@ public class PacketLinkServer implements InitialPacket, PacketObjectIn<Integer>,
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);
Logger.get("SubData").info(client.getAddress().toString() + " has been defined as " + ((server instanceof SubServer) ? "SubServer" : "Server") + ": " + server.getName() + ((channel > 0)?" (Sub-"+channel+")":""));
Logger.get("SubData").info(client.getAddress().toString() + " has been defined as " + ((server instanceof SubServer) ? "SubServer" : "Server") + ": " + server.getName() + ((channel > 0)?" [+"+channel+"]":""));
Runnable register = () -> {
if (server instanceof SubServer && !((SubServer) server).isRunning()) {
if (((SubServer) server).getHost().isAvailable()) {

View File

@ -90,7 +90,7 @@ public final class SubProxy extends BungeeCommon implements Listener {
public SubProtocol subprotocol;
public SubDataServer subdata = null;
public SubServer sudo = null;
public static final Version version = Version.fromString("2.17b/p1");
public static final Version version = Version.fromString("2.17.1a");
public final Proxy mProxy;
public boolean canSudo = false;
@ -146,6 +146,9 @@ public final class SubProxy extends BungeeCommon implements Listener {
Util.unzip(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/Templates/paper.zip"), new UniversalFile(dir, "Templates"));
Logger.get("SubServers").info("Created ./SubServers/Templates/Paper");
Util.unzip(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/Templates/purpur.zip"), new UniversalFile(dir, "Templates"));
Logger.get("SubServers").info("Created ./SubServers/Templates/Purpur");
Util.unzip(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/Templates/forge.zip"), new UniversalFile(dir, "Templates"));
Logger.get("SubServers").info("Created ./SubServers/Templates/Forge");
@ -170,6 +173,11 @@ public final class SubProxy extends BungeeCommon implements Listener {
Util.unzip(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/Templates/paper.zip"), new UniversalFile(dir, "Templates"));
Logger.get("SubServers").info("Updated ./SubServers/Templates/Paper");
}
if (new UniversalFile(dir, "Templates:Purpur:template.yml").exists() && ((new YAMLConfig(new UniversalFile(dir, "Templates:Purpur:template.yml"))).get().getVersion("Version", version)).compareTo(version) != 0) {
Files.move(new UniversalFile(dir, "Templates:Purpur").toPath(), new UniversalFile(dir, "Templates:Purpur." + stamp + ".x").toPath());
Util.unzip(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/Templates/purpur.zip"), new UniversalFile(dir, "Templates"));
Logger.get("SubServers").info("Updated ./SubServers/Templates/Purpur");
}
if (new UniversalFile(dir, "Templates:Forge:template.yml").exists() && ((new YAMLConfig(new UniversalFile(dir, "Templates:Forge:template.yml"))).get().getVersion("Version", version)).compareTo(version) != 0) {
Files.move(new UniversalFile(dir, "Templates:Forge").toPath(), new UniversalFile(dir, "Templates:Forge." + stamp + ".x").toPath());
Util.unzip(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/Templates/forge.zip"), new UniversalFile(dir, "Templates"));

View File

@ -118,7 +118,7 @@ public class SubProtocol extends SubDataProtocol {
log.setUseParentHandlers(false);
log.addHandler(new Handler() {
private boolean open = true;
private String prefix = "SubData" + ((channel != 0)? "/Sub-"+channel:"");
private String prefix = "SubData" + ((channel != 0)?"/+"+channel:"");
@Override
public void publish(LogRecord record) {

View File

@ -52,7 +52,7 @@ public final class SubCommand extends Command {
@Override
public boolean execute(CommandSender sender, String label, String[] args) {
label = "/" + label;
if (plugin.api.getSubDataNetwork()[0] == null) {
if (plugin.api.getSubDataNetwork()[0] == null || plugin.api.getSubDataNetwork()[0].isClosed()) {
new IllegalStateException("SubData is not connected").printStackTrace();
if (!(sender instanceof ConsoleCommandSender)) sender.sendMessage(ChatColor.RED + "An exception has occurred while running this command");
} else if (plugin.lang == null) {

View File

@ -1,6 +1,6 @@
name: SubServers-Client-Bukkit
main: net.ME1312.SubServers.Client.Bukkit.SubPlugin
version: "2.17b/p1"
version: "2.17.1a"
authors: ["ME1312"]
softdepend: [TitleAPI, PlaceholderAPI]
website: "https://github.com/ME1312/SubServers-2"

View File

@ -119,7 +119,7 @@ public class SubProtocol extends SubDataProtocol {
Logger log = Logger.getAnonymousLogger();
log.setUseParentHandlers(false);
log.addHandler(new Handler() {
private org.slf4j.Logger log = LoggerFactory.getLogger("SubData" + ((channel != 0)? "/Sub-"+channel:""));
private org.slf4j.Logger log = LoggerFactory.getLogger("SubData" + ((channel != 0)? "/+"+channel:""));
private boolean open = true;
@Override

View File

@ -139,7 +139,7 @@ public final class SubCommand implements CommandExecutor {
}
private boolean canRun(CommandSource sender, boolean permitted) throws CommandException {
if (SubAPI.getInstance().getSubDataNetwork()[0] == null) {
if (SubAPI.getInstance().getSubDataNetwork()[0] == null || plugin.api.getSubDataNetwork()[0].isClosed()) {
throw new CommandException(Text.builder("An exception has occurred while running this command").color(TextColors.RED).build(), new IllegalStateException("SubData is not connected"), false);
} else if (plugin.lang == null) {
throw new CommandException(Text.builder("An exception has occurred while running this command").color(TextColors.RED).build(), new IllegalStateException("There are no lang options available at this time"), false);

View File

@ -49,7 +49,7 @@ import static net.ME1312.SubServers.Client.Sponge.Library.AccessMode.NO_COMMANDS
/**
* SubServers Client Plugin Class
*/
@Plugin(id = "subservers-client-sponge", name = "SubServers-Client-Sponge", authors = "ME1312", version = "2.17b/p1", url = "https://github.com/ME1312/SubServers-2", description = "Take control of the server manager — from your servers")
@Plugin(id = "subservers-client-sponge", name = "SubServers-Client-Sponge", authors = "ME1312", version = "2.17.1a", url = "https://github.com/ME1312/SubServers-2", description = "Take control of the server manager — from your servers")
public final class SubPlugin {
HashMap<Integer, SubDataClient> subdata = new HashMap<Integer, SubDataClient>();
Pair<Long, Map<String, Map<String, String>>> lang = null;

View File

@ -1,4 +1,4 @@
name: SubServers-Console
main: net.ME1312.SubServers.Console.ConsolePlugin
version: 2.17b/p1
version: 2.17.1a
author: ME1312

View File

@ -0,0 +1,52 @@
# SubCreator Purpur Build Script
#
#!/usr/bin/env bash
if [[ -z "$version" ]]
then
echo ERROR: No Build Version Supplied
rm -Rf "$0"
exit 1
fi
function __DL() {
if [[ -x "$(command -v wget)" ]]; then
wget -O "$1" "$2"; return $?
else
curl -o "$1" "$2"; return $?
fi
}
function __Restore() {
if [[ -f "Purpur.old.jar.x" ]]; then
if [[ -f "Purpur.jar" ]]; then
rm -Rf Purpur.jar
fi
mv Purpur.old.jar.x Purpur.jar
fi
}
echo Downloading Purpur...
if [[ -f "Purpur.jar" ]]; then
if [[ -f "Purpur.old.jar.x" ]]; then
rm -Rf Purpur.old.jar.x
fi
mv Purpur.jar Purpur.old.jar.x
fi
__DL Purpur.jar "https://purpur.pl3x.net/api/v1/purpur/$version/latest/download"; __RETURN=$?
if [[ $__RETURN -eq 0 ]]; then
if [[ $(stat -c%s "Purpur.jar") -ge 1000000 ]]; then
echo Cleaning Up...
rm -Rf "$0"
exit 0
else
echo ERROR: Received invalid jarfile when requesting Purpur version $version:
cat Purpur.jar
printf "\n"
__Restore
rm -Rf "$0"
exit 4
fi
else
echo ERROR: Failed downloading Purpur. Is Pl3x.net down?
__Restore
rm -Rf "$0"
exit 3
fi
exit 2

View File

@ -0,0 +1,2 @@
#By using SubCreator to create your server you have indicated your agreement to the Minecraft EULA (https://account.mojang.com/documents/minecraft_eula).
eula=true

View File

@ -0,0 +1,10 @@
#Minecraft server properties
server-ip=SubServers::address
server-port=SubServers::port
online-mode=false
enable-query=false
broadcast-console-to-ops=false
announce-player-achievements=false
network-compression-threshold=-1
enable-command-block=true
motd=Some SubServer

View File

@ -0,0 +1,3 @@
config-version: 4
settings:
bungeecord: true

View File

@ -0,0 +1,12 @@
Version: '2.16a+'
Template:
Enabled: true
Icon: 'purpur_block'
Build:
Server-Type: 'Spigot'
Use-Cache: false
Require-Version: true
Can-Update: true
Executable: 'bash build.sh'
Settings:
Executable: 'java -Xmx1024M -Dterminal.jline=false -jar Purpur.jar nogui'

View File

@ -43,7 +43,7 @@ import java.util.jar.Manifest;
/**
* SubServers.Host Main Class
*/
@App(name = "SubServers.Host", version = "2.17b/p1", authors = "ME1312", website = "https://github.com/ME1312/SubServers-2", description = "Host subservers on separate machines")
@App(name = "SubServers.Host", version = "2.17.1a", authors = "ME1312", website = "https://github.com/ME1312/SubServers-2", description = "Host subservers on separate machines")
public final class ExHost {
HashMap<Integer, SubDataClient> subdata = new HashMap<Integer, SubDataClient>();
Pair<Long, Map<String, Map<String, String>>> lang = null;

View File

@ -46,6 +46,7 @@ public class SubCreatorImpl {
private String name;
private String nick = null;
private boolean enabled;
private boolean internal;
private String icon;
private File directory;
private ServerType type;
@ -63,14 +64,15 @@ public class SubCreatorImpl {
* @param options Configuration Options
*/
public ServerTemplate(String name, boolean enabled, String icon, File directory, ObjectMap<String> build, ObjectMap<String> options) {
this(name, enabled, icon, directory, build, options, true);
this(name, enabled, false, icon, directory, build, options, true);
}
private ServerTemplate(String name, boolean enabled, String icon, File directory, ObjectMap<String> build, ObjectMap<String> options, boolean dynamic) {
private ServerTemplate(String name, boolean enabled, boolean internal, String icon, File directory, ObjectMap<String> build, ObjectMap<String> options, boolean dynamic) {
super(toRaw(name, enabled, icon, directory, build, options));
if (name.contains(" ")) throw new InvalidTemplateException("Template names cannot have spaces: " + name);
this.name = name;
this.enabled = enabled;
this.internal = internal;
this.icon = icon;
this.directory = directory;
this.type = (build.contains("Server-Type"))?ServerType.valueOf(build.getRawString("Server-Type").toUpperCase()):ServerType.CUSTOM;
@ -128,6 +130,15 @@ public class SubCreatorImpl {
enabled = value;
}
/**
* Get if this Template is for Internal use only
*
* @return Internal Status
*/
public boolean isInternal() {
return internal;
}
/**
* Get the Item Icon for this Template
*
@ -237,7 +248,7 @@ public class SubCreatorImpl {
try {
if (file.isDirectory() && !file.getName().endsWith(".x")) {
ObjectMap<String> config = (new UniversalFile(file, "template.yml").exists())?new YAMLConfig(new UniversalFile(file, "template.yml")).get().getMap("Template", new ObjectMap<String>()):new ObjectMap<String>();
ServerTemplate template = new ServerTemplate(file.getName(), config.getBoolean("Enabled", true), config.getRawString("Icon", "::NULL::"), file, config.getMap("Build", new ObjectMap<String>()), config.getMap("Settings", new ObjectMap<String>()), false);
ServerTemplate template = new ServerTemplate(file.getName(), config.getBoolean("Enabled", true), config.getBoolean("Internal", false), config.getRawString("Icon", "::NULL::"), file, config.getMap("Build", new ObjectMap<String>()), config.getMap("Settings", new ObjectMap<String>()), false);
templates.put(file.getName().toLowerCase(), template);
if (config.getKeys().contains("Display")) template.setDisplayName(config.getString("Display"));
}
@ -294,35 +305,24 @@ public class SubCreatorImpl {
if (templates.get(other.toLowerCase()).isEnabled()) {
if (version != null || !templates.get(other.toLowerCase()).requiresVersion()) {
if (update == null || templates.get(other.toLowerCase()).canUpdate()) {
ObjectMap<String> config = build(dir, templates.get(other.toLowerCase()), history);
if (config == null) {
throw new SubCreatorException();
} else {
server.setAll(config);
}
server.setAll(this.build(dir, templates.get(other.toLowerCase()), history));
} else {
log.logger.warn.println("Skipping template that cannot be run in update mode: " + other);
((SubDataClient) SubAPI.getInstance().getSubDataNetwork()[0]).sendPacket(new PacketOutExLogMessage(address, "Skipping template that cannot be run in update mode: " + other));
}
} else {
log.logger.warn.println("Skipping template that requires extra versioning information: " + other);
((SubDataClient) SubAPI.getInstance().getSubDataNetwork()[0]).sendPacket(new PacketOutExLogMessage(address, "Skipping template that requires extra versioning information: " + other));
}
} else {
log.logger.warn.println("Skipping disabled template: " + other);
((SubDataClient) SubAPI.getInstance().getSubDataNetwork()[0]).sendPacket(new PacketOutExLogMessage(address, "Skipping disabled template: " + other));
}
} else {
log.logger.warn.println("Skipping missing template: " + other);
((SubDataClient) SubAPI.getInstance().getSubDataNetwork()[0]).sendPacket(new PacketOutExLogMessage(address, "Skipping missing template: " + other));
}
}
server.setAll(template.getConfigOptions());
try {
log.logger.info.println("Loading" + ((template.isDynamic())?" Dynamic":"") + " Template: " + template.getDisplayName());
((SubDataClient) SubAPI.getInstance().getSubDataNetwork()[0]).sendPacket(new PacketOutExLogMessage(address, "Loading Template: " + template.getDisplayName()));
if (template.getBuildOptions().getBoolean("Update-Files", false)) updateDirectory(template.getDirectory(), dir);
else Util.copyDirectory(template.getDirectory(), dir);
updateDirectory(template.getDirectory(), dir, template.getBuildOptions().getBoolean("Update-Files", false));
for (ObjectMapValue<String> replacement : template.getBuildOptions().getMap("Replacements", new ObjectMap<>()).getValues()) if (!replacement.isNull()) {
replacements.put(replacement.getHandle().toLowerCase().replace('-', '_').replace(' ', '_'), replacement.asRawString());
@ -346,7 +346,6 @@ public class SubCreatorImpl {
case FORGE:
if (version != null) {
log.logger.info.println("Searching Versions...");
((SubDataClient) SubAPI.getInstance().getSubDataNetwork()[0]).sendPacket(new PacketOutExLogMessage(address, "Searching Versions..."));
YAMLSection spversionmanifest = new YAMLSection(new JSONObject("{\"versions\":" + Util.readAll(new BufferedReader(new InputStreamReader(new URL("https://dl-api.spongepowered.org/v1/org.spongepowered/sponge" + ((template.getType() == ServerType.FORGE)?"forge":"vanilla") + "/downloads?type=stable&minecraft=" + version).openStream(), Charset.forName("UTF-8")))) + '}'));
ObjectMap<String> spprofile = null;
@ -357,15 +356,12 @@ public class SubCreatorImpl {
spversion = new Version(profile.getRawString("version"));
}
}
if (spversion == null)
throw new InvalidServerException("Cannot find Sponge version for Minecraft " + version.toString());
if (spversion == null) throw new InvalidServerException("Cannot find Sponge version for Minecraft " + version.toString());
log.logger.info.println("Found \"sponge" + ((template.getType() == ServerType.FORGE)?"forge":"vanilla") + "-" + spversion.toString() + '"');
((SubDataClient) SubAPI.getInstance().getSubDataNetwork()[0]).sendPacket(new PacketOutExLogMessage(address, "Found \"sponge" + ((template.getType() == ServerType.FORGE)?"forge":"vanilla") + "-" + spversion.toString() + '"'));
if (template.getType() == ServerType.FORGE) {
Version mcfversion = new Version(((spprofile.getMap("dependencies").getRawString("forge").contains("-"))?"":spprofile.getMap("dependencies").getRawString("minecraft") + '-') + spprofile.getMap("dependencies").getRawString("forge"));
log.logger.info.println("Found \"forge-" + mcfversion.toString() + '"');
((SubDataClient) SubAPI.getInstance().getSubDataNetwork()[0]).sendPacket(new PacketOutExLogMessage(address, "Found \"forge-" + mcfversion.toString() + '"'));
var.put("mcf_version", mcfversion.toString());
}
@ -388,7 +384,6 @@ public class SubCreatorImpl {
try {
log.logger.info.println("Launching Build Script...");
((SubDataClient) SubAPI.getInstance().getSubDataNetwork()[0]).sendPacket(new PacketOutExLogMessage(address, "Launching Build Script..."));
ProcessBuilder pb = new ProcessBuilder().command(Executable.parse(host.host.getRawString("Git-Bash"), template.getBuildOptions().getRawString("Executable"))).directory(dir);
pb.environment().putAll(var);
process = pb.start();
@ -436,7 +431,6 @@ public class SubCreatorImpl {
declaration.run();
File dir = (update != null)?new File(update.getFullPath()):new File(host.host.getRawString("Directory"),
(template.getConfigOptions().contains("Directory"))?new ReplacementScanner(replacements).replace(template.getConfigOptions().getRawString("Directory")).toString():name);
dir.mkdirs();
ObjectMap<String> config;
try {
@ -587,23 +581,21 @@ public class SubCreatorImpl {
}
}
private void updateDirectory(File from, File to) {
if (from.isDirectory() && !Files.isSymbolicLink(from.toPath())) {
if (!to.exists()) {
to.mkdirs();
}
private void updateDirectory(File from, File to, boolean overwrite) {
if (!to.exists()) {
Util.copyDirectory(from, to);
} else if (from.isDirectory() && !Files.isSymbolicLink(from.toPath())) {
String files[] = from.list();
for (String file : files) {
File srcFile = new File(from, file);
File destFile = new File(to, file);
updateDirectory(srcFile, destFile);
updateDirectory(srcFile, destFile, overwrite);
}
} else {
try {
if (!to.exists() || from.length() != to.length() || !Arrays.equals(generateSHA256(to), generateSHA256(from))) {
if (overwrite && (from.length() != to.length() || !Arrays.equals(generateSHA256(to), generateSHA256(from)))) {
if (to.exists()) {
if (to.isDirectory()) Util.deleteDirectory(to);
else to.delete();

View File

@ -1,8 +1,10 @@
package net.ME1312.SubServers.Host.Executable;
import net.ME1312.Galaxi.Library.Callback.Callback;
import net.ME1312.Galaxi.Library.Container.ContainedPair;
import net.ME1312.Galaxi.Library.Container.Pair;
import net.ME1312.Galaxi.Library.Container.Value;
import net.ME1312.Galaxi.Log.LogFilter;
import net.ME1312.Galaxi.Log.LogStream;
import net.ME1312.Galaxi.Log.Logger;
import net.ME1312.Galaxi.Library.Util;
@ -15,10 +17,12 @@ import net.ME1312.SubServers.Host.Network.Packet.PacketOutExLogMessage;
import net.ME1312.SubServers.Host.SubAPI;
import java.io.*;
import java.util.LinkedList;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -36,6 +40,7 @@ public class SubLoggerImpl {
static boolean logc = true;
File file;
private SubDataClient channel = null;
private LinkedList<Pair<String, String>> ccache = null;
private PrintWriter writer = null;
private boolean started = false;
private Thread out = null;
@ -59,6 +64,25 @@ public class SubLoggerImpl {
this.address = address;
this.log = log;
this.file = file;
logger.addFilter((stream, message) -> {
// Log to NETWORK
if (logn) {
if (this.address != null && channel != null && !channel.isClosed()) {
if (ccache != null) {
for (Pair<String, String> val : ccache) channel.sendPacket(new PacketOutExLogMessage(this.address, val.key(), val.value()));
ccache = null;
}
channel.sendPacket(new PacketOutExLogMessage(this.address, stream.getLevel().getName(), message));
} else {
if (ccache == null) ccache = new LinkedList<Pair<String, String>>();
ccache.add(new ContainedPair<>(stream.getLevel().getName(), message));
}
}
// Log to CONSOLE
return logc || !started;
});
}
/**
@ -131,6 +155,7 @@ public class SubLoggerImpl {
}
}
private static final String PATTERN = "^((?:\\s*\\[?([0-9]{2}:[0-9]{2}:[0-9]{2})]?)?[\\s\\/\\\\\\|]*(?:\\[|\\[.*\\/)?(MESSAGE|MSG|" + Pattern.quote(Level.INFO.getLocalizedName()) + "|INFO|" + Pattern.quote(Level.WARNING.getLocalizedName()) + "|WARNING|WARN|ERROR|ERR|" + Pattern.quote(Level.SEVERE.getLocalizedName()) + "|SEVERE)\\]?:?(?:\\s*>)?\\s*)";
private void log(String line) {
if (!line.startsWith(">")) {
String msg = line;
@ -138,15 +163,19 @@ public class SubLoggerImpl {
// REGEX Formatting
String type = "";
Matcher matcher = Pattern.compile("^((?:\\s*\\[?([0-9]{2}:[0-9]{2}:[0-9]{2})]?)?[\\s\\/\\\\\\|]*(?:\\[|\\[.*\\/)?(MESSAGE|INFO|WARNING|WARN|ERROR|ERR|SEVERE)\\]?:?(?:\\s*>)?\\s*)").matcher(msg.replaceAll("\u001B\\[[;\\d]*m", ""));
Matcher matcher = Pattern.compile(PATTERN).matcher(msg.replaceAll("\u001B\\[[;\\d]*m", ""));
while (matcher.find()) {
type = matcher.group(3).toUpperCase();
}
msg = msg.replaceAll("^((?:\\s*\\[?([0-9]{2}:[0-9]{2}:[0-9]{2})]?)?[\\s\\/\\\\\\|]*(?:\\[|\\[.*\\/)?(MESSAGE|INFO|WARNING|WARN|ERROR|ERR|SEVERE)\\]?:?(?:\\s*>)?\\s*)", "");
msg = msg.replaceAll(PATTERN, "");
// Determine LOG LEVEL
switch (type) {
if (type.equalsIgnoreCase(Level.WARNING.getLocalizedName())) {
level = logger.warn;
} else if (type.equalsIgnoreCase(Level.SEVERE.getLocalizedName())) {
level = logger.severe;
} else switch (type) {
case "WARNING":
case "WARN":
level = logger.warn;
@ -158,15 +187,16 @@ public class SubLoggerImpl {
case "ERR":
level = logger.error;
break;
case "MSG":
case "MESSAGE":
level = logger.message;
break;
default:
level = logger.info;
}
// Log to NETWORK
if (log.value() && channel != null && !channel.isClosed()) channel.sendPacket(new PacketOutExLogMessage(address, line));
// Log to CONSOLE
if (log.value() && logc) level.println(TextColor.convertColor(msg));
// Log to FILTER
if (log.value()) level.println(TextColor.convertColor(msg));
// Log to FILE
if (writer != null) {
@ -202,7 +232,7 @@ public class SubLoggerImpl {
}
}
if (channel != null && !channel.isClosed()) {
channel.sendPacket(new PacketOutExLogMessage(address, true));
channel.sendPacket(new PacketOutExLogMessage(address));
}
channel = null;
}

View File

@ -36,6 +36,7 @@ public class PacketExUploadTemplates implements PacketIn, PacketObjectOut<Intege
for (SubCreatorImpl.ServerTemplate template : host.templates.values()) {
ObjectMap<String> tinfo = new ObjectMap<String>();
tinfo.set("enabled", template.isEnabled());
tinfo.set("internal", template.isInternal());
tinfo.set("display", template.getDisplayName());
tinfo.set("icon", template.getIcon());
tinfo.set("build", template.getBuildOptions().clone());
@ -54,6 +55,6 @@ public class PacketExUploadTemplates implements PacketIn, PacketObjectOut<Intege
@Override
public int version() {
return 0x0001;
return 0x0002;
}
}

View File

@ -11,14 +11,15 @@ import java.util.UUID;
*/
public class PacketOutExLogMessage implements PacketObjectOut<Integer> {
private UUID address;
private String line;
private String level, line;
private boolean terminate;
/**
* New PacketInExLogMessage (Out)
*/
public PacketOutExLogMessage(UUID address, String line) {
public PacketOutExLogMessage(UUID address, String level, String line) {
this.address = address;
this.level = level;
this.line = line;
this.terminate = false;
}
@ -26,10 +27,9 @@ public class PacketOutExLogMessage implements PacketObjectOut<Integer> {
/**
* New PacketInExLogMessage (Out)
*/
public PacketOutExLogMessage(UUID address, boolean terminate) {
public PacketOutExLogMessage(UUID address) {
this.address = address;
this.line = null;
this.terminate = terminate;
this.terminate = true;
}
@Override
@ -38,12 +38,13 @@ public class PacketOutExLogMessage implements PacketObjectOut<Integer> {
ObjectMap<Integer> data = new ObjectMap<Integer>();
data.set(0x0000, address);
if (line != null) data.set(0x0001, line);
if (level != null) data.set(0x0001, level);
if (line != null) data.set(0x0002, line);
return data;
}
@Override
public int version() {
return 0x0001;
return 0x0002;
}
}

View File

@ -136,7 +136,7 @@ public class SubProtocol extends SubDataProtocol {
}
private Logger getLogger(int channel) {
return new net.ME1312.Galaxi.Log.Logger("SubData" + ((channel != 0)?File.separator+"Sub-"+channel:"")).toPrimitive();
return new net.ME1312.Galaxi.Log.Logger("SubData" + ((channel != 0)?File.separator+"+"+channel:"")).toPrimitive();
}
@Override

View File

@ -39,7 +39,7 @@ public class SubCommand {
private final ExHost host;
private static boolean canRun() {
if (SubAPI.getInstance().getSubDataNetwork()[0] == null) {
if (SubAPI.getInstance().getSubDataNetwork()[0] == null || SubAPI.getInstance().getSubDataNetwork()[0].isClosed()) {
throw new IllegalStateException("SubData is not connected");
} else {
return true;

View File

@ -72,7 +72,7 @@ public final class ExProxy extends BungeeCommon implements Listener {
public final Plugin plugin;
public final SubAPI api = new SubAPI(this);
public SubProtocol subprotocol;
public static final Version version = Version.fromString("2.17b/p1");
public static final Version version = Version.fromString("2.17.1a");
public final boolean isPatched;
public long lastReload = -1;

View File

@ -128,7 +128,7 @@ public class SubProtocol extends SubDataProtocol {
}
private Logger getLogger(int channel) {
return net.ME1312.SubServers.Bungee.Library.Compatibility.Logger.get("SubData" + ((channel != 0)? "/Sub-"+channel:""));
return net.ME1312.SubServers.Bungee.Library.Compatibility.Logger.get("SubData" + ((channel != 0)?"/+"+channel:""));
}
@Override

View File

@ -63,7 +63,7 @@ public final class SubCommand extends Command implements TabExecutor {
@Override
public void execute(CommandSender sender, String[] args) {
if (!(sender instanceof ProxiedPlayer)) {
if (plugin.api.getSubDataNetwork()[0] == null) {
if (plugin.api.getSubDataNetwork()[0] == null || plugin.api.getSubDataNetwork()[0].isClosed()) {
new IllegalStateException("SubData is not connected").printStackTrace();
if (!(sender instanceof ConsoleCommandSender)) sender.sendMessage(ChatColor.RED + "An exception has occurred while running this command");
} else {