diff --git a/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/SubServer.java b/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/SubServer.java
index bcea5410..efb8c5e5 100644
--- a/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/SubServer.java
+++ b/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/SubServer.java
@@ -219,6 +219,14 @@ public interface SubServer extends Server {
*/
boolean isRunning();
+ /**
+ * If the Server is Online
+ * This method can only be true when a SubData connection is made!
+ *
+ * @return Online Status
+ */
+ boolean isOnline();
+
/**
* Grabs the Host of the Server
*
diff --git a/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/SubServerImpl.java b/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/SubServerImpl.java
index 430579a8..039a01a4 100644
--- a/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/SubServerImpl.java
+++ b/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/SubServerImpl.java
@@ -85,6 +85,11 @@ public abstract class SubServerImpl extends ServerImpl implements SubServer {
return !updating && getHost().isAvailable();
}
+ @Override
+ public boolean isOnline() {
+ return isRunning() && started;
+ }
+
@Override
public void setTemplate(String template) {
SubAPI.getInstance().getInternals().getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer("template", template), false));
@@ -176,6 +181,7 @@ public abstract class SubServerImpl extends ServerImpl implements SubServer {
sinfo.set("dir", getPath());
sinfo.set("exec", getExecutable());
sinfo.set("running", isRunning());
+ sinfo.set("online", isOnline());
sinfo.set("stop-cmd", getStopCommand());
sinfo.set("stop-action", getStopAction().toString());
sinfo.set("auto-run", SubAPI.getInstance().getInternals().servers.get().getMap("Servers").getMap(getName(), new ObjectMap()).getBoolean("Run-On-Launch", false));
diff --git a/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/SubCommand.java b/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/SubCommand.java
index e9d5d805..b64f9791 100644
--- a/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/SubCommand.java
+++ b/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/SubCommand.java
@@ -300,7 +300,7 @@ public final class SubCommand extends CommandX {
if (server.getGroups().size() > 0) sender.sendMessage(" -> Group" + ((server.getGroups().size() > 1)?"s:":": " + ChatColor.WHITE + server.getGroups().get(0)));
if (server.getGroups().size() > 1) for (String group : server.getGroups()) sender.sendMessage(" - " + ChatColor.WHITE + group);
sender.sendMessage(" -> Address: " + ChatColor.WHITE + server.getAddress().getAddress().getHostAddress()+':'+server.getAddress().getPort());
- if (server instanceof SubServer) sender.sendMessage(" -> Running: " + ((((SubServer) server).isRunning())?ChatColor.GREEN+"yes":ChatColor.RED+"no"));
+ if (server instanceof SubServer) sender.sendMessage(" -> " + ((((SubServer) server).isOnline())?"Online":"Running") + ": " + ((((SubServer) server).isRunning())?ChatColor.GREEN+"yes":ChatColor.RED+"no"));
if (!(server instanceof SubServer) || ((SubServer) server).isRunning()) {
sender.sendMessage(" -> Connected: " + ((server.getSubData()[0] != null)?ChatColor.GREEN+"yes"+((server.getSubData().length > 1)?ChatColor.AQUA+" +"+(server.getSubData().length-1)+" subchannel"+((server.getSubData().length == 2)?"":"s"):""):ChatColor.RED+"no"));
sender.sendMessage(" -> Players: " + ChatColor.AQUA + server.getGlobalPlayers().size() + " online");
diff --git a/SubServers.Client/Bukkit/pom.xml b/SubServers.Client/Bukkit/pom.xml
index ad3db9f3..a2dc993a 100644
--- a/SubServers.Client/Bukkit/pom.xml
+++ b/SubServers.Client/Bukkit/pom.xml
@@ -26,6 +26,10 @@
puharesource-repo
https://repo.puha.io/repo/
+
+ placeholderapi
+ https://repo.extendedclip.com/content/repositories/placeholderapi/
+
@@ -61,6 +65,12 @@
1.5.11
provided
+
+ me.clip
+ placeholderapi
+ 2.10.6
+ provided
+
diff --git a/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/Library/Compatibility/PlaceholderImpl.java b/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/Library/Compatibility/PlaceholderImpl.java
new file mode 100644
index 00000000..f8ce2c5d
--- /dev/null
+++ b/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/Library/Compatibility/PlaceholderImpl.java
@@ -0,0 +1,480 @@
+package net.ME1312.SubServers.Client.Bukkit.Library.Compatibility;
+
+import me.clip.placeholderapi.expansion.Cacheable;
+import me.clip.placeholderapi.expansion.PlaceholderExpansion;
+import me.clip.placeholderapi.expansion.Taskable;
+import net.ME1312.Galaxi.Library.Map.ObjectMap;
+import net.ME1312.Galaxi.Library.Util;
+import net.ME1312.SubServers.Client.Bukkit.Event.*;
+import net.ME1312.SubServers.Client.Bukkit.Network.API.*;
+import net.ME1312.SubServers.Client.Bukkit.SubAPI;
+import net.ME1312.SubServers.Client.Bukkit.SubPlugin;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.scheduler.BukkitTask;
+
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * PlaceholderAPI Implementation Class
+ */
+public class PlaceholderImpl extends PlaceholderExpansion implements Taskable, Cacheable {
+ private SubPlugin plugin;
+ private BukkitTask task;
+ private Cache cache;
+ private boolean init;
+
+ /**
+ * Create a PlaceholderAPI Implementation Instance
+ *
+ * @param plugin SubPlugin
+ */
+ public PlaceholderImpl(SubPlugin plugin) {
+ this.plugin = plugin;
+ this.cache = new Cache();
+ this.init = false;
+
+ if (plugin.config.get().getMap("Settings").getBoolean("PlaceholderAPI-Ready", false)) init();
+ }
+
+ @Override
+ public String getIdentifier() {
+ return "subservers";
+ }
+
+ @Override
+ public String getAuthor() {
+ return plugin.getDescription().getAuthors().get(0);
+ }
+
+ @Override
+ public String getVersion() {
+ return plugin.getDescription().getVersion();
+ }
+
+ @Override
+ public boolean persist() {
+ return true;
+ }
+
+ private void init() {
+ if (!init) {
+ init = true;
+ Bukkit.getPluginManager().registerEvents(cache.events, plugin);
+ Bukkit.getScheduler().runTaskLater(plugin, this::start, 120L);
+ }
+ }
+
+ @Override
+ public void start() {
+ if (task == null) {
+ int interval = plugin.config.get().getMap("Settings").getInt("PlaceholderAPI-Cache-Interval", 300);
+ int start = interval - new Random().nextInt((interval / 3) + 1); // Don't have all servers request at the same time
+ task = Bukkit.getScheduler().runTaskTimer(plugin, cache::refresh, 20L * start, 20L * interval);
+ cache.refresh();
+ }
+ }
+
+ @Override
+ public void stop() {
+ if (task != null) {
+ try {
+ task.cancel();
+ } catch (Throwable exception) {}
+ task = null;
+ }
+ }
+
+ @Override
+ public void clear() {
+ cache.reset();
+ }
+
+ @Override
+ public String onPlaceholderRequest(Player player, String request) {
+ boolean colored = request.startsWith("color_");
+ if (colored) request = request.substring(6);
+
+ String response = parse(request);
+ if (!init) init();
+
+ if (response != null && !colored) {
+ return ChatColor.stripColor(response);
+ } else {
+ return response;
+ }
+ }
+
+ private String parse(String placeholder) {
+ Matcher m = Pattern.compile("^(.+?)(?:\\((.*)\\))?$", Pattern.CASE_INSENSITIVE).matcher(placeholder);
+
+ if (m.find()) {
+ String method = m.group(1);
+ String arguments = m.group(2);
+ String[] args;
+
+ if (arguments == null || arguments.isEmpty()) {
+ args = new String[0];
+ } else if (!arguments.contains(",")) {
+ args = new String[]{ arguments };
+ } else {
+ args = arguments.split(",\\s*");
+ }
+
+ return run(method, args);
+ } else {
+ return null;
+ }
+ }
+
+ @SuppressWarnings("ConstantConditions")
+ private String run(String method, String... args) {
+ Server server = (plugin.api.getName() != null)? cache.getServer(plugin.api.getName()) : null;
+ SubServer subserver = (server instanceof SubServer)? (SubServer) server : null;
+ Host host = (subserver != null)? cache.getHost(subserver.getHost()) : null;
+ Proxy proxy = null;
+
+ String debug = Arrays.asList(args).toString();
+
+ method = method.toLowerCase();
+ if (method.startsWith("proxy.")) {
+ if (args.length > 0 && !args[0].isEmpty()) proxy = cache.getProxy(args[0]);
+ if (proxy == null) return null;
+ } else if (method.startsWith("host.")) {
+ if (args.length > 0 && !args[0].isEmpty()) host = cache.getHost(args[0]);
+ if (host == null) return null;
+ } else if (method.startsWith("server.")) {
+ if (args.length > 0 && !args[0].isEmpty()) server = cache.getServer(args[0]);
+ if (server == null) return null;
+ } else if (method.startsWith("subserver.")) {
+ if (args.length > 0 && !args[0].isEmpty()) server = subserver = cache.getSubServer(args[0]);
+ if (subserver == null) return null;
+ }
+
+
+ // --- Methods where Objects link to other Objects --
+ if (method.startsWith("subserver.host")) {
+ if (method.equals("subserver.host")) {
+ return subserver.getHost();
+ } else {
+ LinkedList arguments = new LinkedList();
+ arguments.addAll(Arrays.asList(args));
+ if (args.length > 0) arguments.removeFirst();
+ arguments.addFirst(subserver.getHost());
+ return run(method.substring(10), arguments.toArray(new String[0]));
+ }
+ } else if (method.startsWith("subserver.template")) {
+ if (method.equals("subserver.template")) {
+ return (subserver.getTemplate() != null)?subserver.getTemplate():"(custom)";
+ } else if (subserver.getTemplate() != null) {
+ LinkedList arguments = new LinkedList();
+ arguments.addAll(Arrays.asList(args));
+ if (args.length > 0) arguments.removeFirst();
+ arguments.addFirst(subserver.getTemplate());
+ arguments.addFirst(subserver.getHost());
+ return run("host.creator." + method.substring(10), arguments.toArray(new String[0]));
+ } else {
+ return null;
+ }
+ } else switch (method) { // --- Straight up Methods ---
+ case "proxy":
+ case "proxies": {
+ return ChatColor.AQUA + Integer.toString(cache.getProxies().size() + 1);
+ }
+ case "proxy.displayname": {
+ return proxy.getDisplayName();
+ }
+ case "proxy.type": {
+ return ((proxy.isMaster())?"Master ":"") + "Proxy";
+ }
+ case "proxy.redis": {
+ return (proxy.isRedis())?ChatColor.GREEN+"Available":ChatColor.RED+"Unavailable";
+ }
+ case "proxy.players": {
+ return ChatColor.AQUA + Integer.toString(proxy.getPlayers().size());
+ }
+ case "proxy.subdata": {
+ return (proxy.getSubData()[0] == null)?ChatColor.RED+"Disconnected":ChatColor.GREEN+"Connected";
+ }
+ case "proxy.subdata.channels":
+ case "proxy.subdata.subchannels": {
+ return ChatColor.AQUA + Integer.toString(proxy.getSubData().length - ((method.endsWith(".subchannels"))?1:0));
+ }
+ case "proxy.signature": {
+ return ChatColor.AQUA + proxy.getSignature();
+ }
+ case "host":
+ case "hosts": {
+ return ChatColor.AQUA + Integer.toString(cache.getHosts().size());
+ }
+ case "host.displayname": {
+ return host.getDisplayName();
+ }
+ case "host.available": {
+ return (host.isAvailable())?ChatColor.GREEN+"Available":ChatColor.RED+"Unavailable";
+ }
+ case "host.enabled": {
+ return (host.isEnabled())?ChatColor.GREEN+"Enabled":ChatColor.RED+"Disabled";
+ }
+ case "host.address": {
+ return host.getAddress().getHostAddress();
+ }
+ case "host.creator.template":
+ case "host.subcreator.template":
+ case "host.creator.templates":
+ case "host.subcreator.templates": {
+ return ChatColor.AQUA + Integer.toString(host.getCreator().getTemplates().size());
+ }
+ case "host.creator.template.displayname":
+ case "host.subcreator.template.displayname": {
+ SubCreator.ServerTemplate template = (args.length > 1 && !args[1].isEmpty())? host.getCreator().getTemplate(args[1]) : null;
+ if (template != null) return template.getDisplayName();
+ else return null;
+ }
+ case "host.creator.template.type":
+ case "host.subcreator.template.type": {
+ SubCreator.ServerTemplate template = (args.length > 1 && !args[1].isEmpty())? host.getCreator().getTemplate(args[1]) : null;
+ if (template != null) return template.getType().toString();
+ else return null;
+ }
+ case "host.creator.template.updatable":
+ case "host.subcreator.template.updatable": {
+ SubCreator.ServerTemplate template = (args.length > 1 && !args[1].isEmpty())? host.getCreator().getTemplate(args[1]) : null;
+ if (template != null) return ((template.canUpdate())?ChatColor.GREEN:ChatColor.RED+"Not ") + "Updatable";
+ else return null;
+ }
+ case "host.servers":
+ case "host.subservers": {
+ return ChatColor.AQUA + Integer.toString(host.getSubServers().size());
+ }
+ case "host.players": {
+ return ChatColor.AQUA + Integer.toString(host.getGlobalPlayers().size());
+ }
+ case "host.subdata": {
+ return (host.getSubData().length <= 0)?ChatColor.YELLOW+"Unsupported":((host.getSubData()[0] == null)?ChatColor.RED+"Disconnected":ChatColor.GREEN+"Connected");
+ }
+ case "host.subdata.channels":
+ case "host.subdata.subchannels": {
+ return ChatColor.AQUA + Integer.toString(Math.max(host.getSubData().length - ((method.endsWith(".subchannels"))?1:0), 0));
+ }
+ case "host.signature": {
+ return ChatColor.AQUA + host.getSignature();
+ }
+ case "server":
+ case "servers": {
+ return ChatColor.AQUA + Integer.toString(cache.getServers().size());
+ }
+ case "server.displayname":
+ case "subserver.displayname": {
+ return server.getDisplayName();
+ }
+ case "server.type":
+ case "subserver.type": {
+ return ((server instanceof SubServer)?"Subs":"S")+"erver";
+ }
+ case "server.groups":
+ case "subserver.groups": {
+ return ChatColor.AQUA + Integer.toString(server.getGroups().size());
+ }
+ case "server.address":
+ case "subserver.address": {
+ return server.getAddress().getAddress().getHostAddress() + ':' + server.getAddress().getPort();
+ }
+ case "server.motd":
+ case "subserver.motd": {
+ return server.getMotd();
+ }
+ case "server.restricted":
+ case "subserver.restricted": {
+ return (server.isRestricted())?ChatColor.RED+"Private":ChatColor.GREEN+"Public";
+ }
+ case "server.hidden":
+ case "subserver.hidden": {
+ return (server.isHidden())?ChatColor.RED+"Hidden":ChatColor.GREEN+"Visible";
+ }
+ case "server.players":
+ case "subserver.players": {
+ return ChatColor.AQUA + Integer.toString(server.getGlobalPlayers().size());
+ }
+ case "server.subdata":
+ case "subserver.subdata": {
+ return (server.getSubData()[0] == null)?ChatColor.RED+"Disconnected":ChatColor.GREEN+"Connected";
+ }
+ case "server.subdata.channels":
+ case "subserver.subdata.channels":
+ case "server.subdata.subchannels":
+ case "subserver.subdata.subchannels": {
+ return ChatColor.AQUA + Integer.toString(server.getSubData().length - ((method.endsWith(".subchannels"))?1:0));
+ }
+ case "server.signature":
+ case "subserver.signature": {
+ return ChatColor.AQUA + server.getSignature();
+ }
+ case "subserver":
+ case "subservers": {
+ return ChatColor.AQUA + Integer.toString(cache.getSubServers().size());
+ }
+ case "subserver.available": {
+ return (subserver.isAvailable())?ChatColor.GREEN+"Available":ChatColor.RED+"Unavailable";
+ }
+ case "subserver.enabled": {
+ return (subserver.isEnabled())?ChatColor.GREEN+"Enabled":ChatColor.RED+"Disabled";
+ }
+ case "subserver.editable": {
+ return (subserver.isEditable())?ChatColor.GREEN+"Editable":ChatColor.RED+"Locked";
+ }
+ case "subserver.running": {
+ return (subserver.isRunning())?ChatColor.GREEN+"Running":ChatColor.RED+"Offline";
+ }
+ case "subserver.online": {
+ return (subserver.isOnline())?ChatColor.GREEN+"Online":((subserver.isRunning())?ChatColor.YELLOW+"Starting":ChatColor.RED+"Offline");
+ }
+ case "subserver.logging": {
+ return (subserver.isLogging())?ChatColor.GREEN+"Logging":ChatColor.RED+"Muted";
+ }
+ case "subserver.temporary": {
+ return (subserver.getStopAction() == SubServer.StopAction.REMOVE_SERVER || subserver.getStopAction() == SubServer.StopAction.RECYCLE_SERVER || subserver.getStopAction() == SubServer.StopAction.DELETE_SERVER)?
+ ChatColor.AQUA+"Temporary":ChatColor.GREEN+"Permanent";
+ }
+ case "subserver.stopaction": {
+ return subserver.getStopAction().toString();
+ }
+ case "subserver.incompatibilities":
+ case "subserver.incompatibilities.current": {
+ List list = (method.endsWith(".current"))?subserver.getCurrentIncompatibilities():subserver.getIncompatibilities();
+ return ((list.isEmpty())?ChatColor.AQUA:ChatColor.RED) + Integer.toString(list.size());
+ }
+ default: {
+ return null;
+ }
+ }
+ }
+
+ private static final class Cache {
+ private static HashMap proxies = new HashMap();
+ private static HashMap hosts = new HashMap();
+ private static HashMap servers = new HashMap();
+ private static Proxy master = null;
+ private Listener events = new Events();
+
+ private void reset() {
+ proxies.clear();
+ hosts.clear();
+ servers.clear();
+ master = null;
+ }
+
+ private void refresh() {
+ if (SubAPI.getInstance().getSubDataNetwork()[0] != null) {
+ SubAPI.getInstance().getProxies(proxies -> {
+ Cache.proxies = new HashMap<>(proxies);
+ });
+ SubAPI.getInstance().getMasterProxy(master -> {
+ Cache.master = master;
+ });
+ SubAPI.getInstance().getHosts(hosts -> {
+ Cache.hosts = new HashMap<>(hosts);
+ });
+ SubAPI.getInstance().getServers(servers -> {
+ Cache.servers = new HashMap<>(servers);
+ });
+ }
+ }
+
+ private final class Events implements Listener {
+ @EventHandler
+ public void add(SubAddProxyEvent e) {
+ SubAPI.getInstance().getProxy(e.getProxy(), proxy -> {
+ proxies.put(proxy.getName().toLowerCase(), proxy);
+ });
+ }
+
+ @EventHandler
+ public void add(SubAddHostEvent e) {
+ SubAPI.getInstance().getHost(e.getHost(), host -> {
+ hosts.put(host.getName().toLowerCase(), host);
+ });
+ }
+
+ @EventHandler
+ public void add(SubAddServerEvent e) {
+ SubAPI.getInstance().getServer(e.getServer(), server -> {
+ servers.put(server.getName().toLowerCase(), server);
+ });
+ }
+
+ @EventHandler
+ public void start(SubStartEvent e) {
+ Server server = getServer(e.getServer());
+ if (server != null) Util.isException(() -> Util.>reflect(Server.class.getDeclaredField("raw"), server).set("running", true));
+ }
+
+ @EventHandler
+ public void started(SubStartedEvent e) {
+ Server server = getServer(e.getServer());
+ if (server != null) Util.isException(() -> Util.>reflect(Server.class.getDeclaredField("raw"), server).set("online", true));
+ }
+
+ @EventHandler
+ public void stopped(SubStoppedEvent e) {
+ Server server = getServer(e.getServer());
+ if (server != null) Util.isException(() -> {
+ ObjectMap raw = Util.reflect(Server.class.getDeclaredField("raw"), server);
+ raw.set("online", false);
+ raw.set("running", false);
+ });
+ }
+ }
+
+ public Map getProxies() {
+ return proxies;
+ }
+
+ public Proxy getProxy(String name) {
+ if (Util.isNull(name)) throw new NullPointerException();
+ Proxy proxy = getProxies().getOrDefault(name.toLowerCase(), null);
+ if (proxy == null && master != null && master.getName().equalsIgnoreCase(name)) proxy = master;
+ return proxy;
+ }
+
+ public Proxy getMasterProxy() {
+ return master;
+ }
+
+ private Map getHosts() {
+ return hosts;
+ }
+
+ private Host getHost(String name) {
+ if (Util.isNull(name)) throw new NullPointerException();
+ return getHosts().get(name.toLowerCase());
+ }
+
+ public Map getServers() {
+ return servers;
+ }
+
+ public Server getServer(String name) {
+ if (Util.isNull(name)) throw new NullPointerException();
+ return getServers().get(name.toLowerCase());
+ }
+
+ public Map getSubServers() {
+ TreeMap servers = new TreeMap();
+ for (Map.Entry server : Cache.servers.entrySet()) {
+ if (server.getValue() instanceof SubServer) servers.put(server.getKey(), (SubServer) server.getValue());
+ }
+ return servers;
+ }
+
+ public SubServer getSubServer(String name) {
+ if (Util.isNull(name)) throw new NullPointerException();
+ return getSubServers().get(name.toLowerCase());
+ }
+ }
+}
diff --git a/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/Library/ConfigUpdater.java b/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/Library/ConfigUpdater.java
index a1117280..82c73699 100644
--- a/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/Library/ConfigUpdater.java
+++ b/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/Library/ConfigUpdater.java
@@ -58,6 +58,7 @@ public class ConfigUpdater {
settings.set("API-Only-Mode", updated.getMap("Settings", new YAMLSection()).getBoolean("API-Only-Mode", 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));
+ settings.set("PlaceholderAPI-Ready", updated.getMap("Settings", new YAMLSection()).getBoolean("PlaceholderAPI-Ready", false));
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"));
diff --git a/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/Network/API/SubCreator.java b/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/Network/API/SubCreator.java
index b66a5d59..f8b36107 100644
--- a/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/Network/API/SubCreator.java
+++ b/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/Network/API/SubCreator.java
@@ -40,7 +40,7 @@ public class SubCreator {
public ServerTemplate(ObjectMap raw) {
this.raw = raw;
- this.type = (Util.isException(() -> ServerType.valueOf(raw.getRawString("type").toUpperCase())))?ServerType.valueOf(raw.getRawString("type").toUpperCase()):ServerType.CUSTOM;
+ this.type = Util.getDespiteException(() -> ServerType.valueOf(raw.getRawString("type").toUpperCase().replace('-', '_').replace(' ', '_')), ServerType.CUSTOM);
}
/**
diff --git a/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/Network/API/SubServer.java b/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/Network/API/SubServer.java
index e2704a99..19bef4be 100644
--- a/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/Network/API/SubServer.java
+++ b/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/Network/API/SubServer.java
@@ -356,6 +356,16 @@ public class SubServer extends Server {
return raw.getBoolean("running");
}
+ /**
+ * If the Server is Online
+ * This method can only be true when a SubData connection is made!
+ *
+ * @return Online Status
+ */
+ public boolean isOnline() {
+ return raw.getBoolean("online");
+ }
+
/**
* Grabs the Host of the Server
*
@@ -546,7 +556,7 @@ public class SubServer extends Server {
* @return Stop Action
*/
public StopAction getStopAction() {
- return Util.getDespiteException(() -> StopAction.valueOf(raw.getRawString("stop-action").toUpperCase().replace('-', '_').replace(' ', '_')), null);
+ return Util.getDespiteException(() -> StopAction.valueOf(raw.getRawString("stop-action").toUpperCase().replace('-', '_').replace(' ', '_')), StopAction.NONE);
}
/**
diff --git a/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/SubCommand.java b/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/SubCommand.java
index 2bce0e84..909008bd 100644
--- a/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/SubCommand.java
+++ b/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/SubCommand.java
@@ -226,7 +226,7 @@ public final class SubCommand extends BukkitCommand {
if (server.getGroups().size() > 1) for (String group : server.getGroups()) sender.sendMessage(" " + plugin.api.getLang("SubServers", "Command.Info.List") + ChatColor.WHITE + group);
if (plugin.config.get().getMap("Settings").getBoolean("Show-Addresses", false)) sender.sendMessage(plugin.api.getLang("SubServers", "Command.Info.Format").replace("$str$", "Address") + ChatColor.WHITE + server.getAddress().getAddress().getHostAddress()+':'+server.getAddress().getPort());
else sender.sendMessage(plugin.api.getLang("SubServers", "Command.Info.Format").replace("$str$", "Port") + ChatColor.AQUA.toString() + server.getAddress().getPort());
- if (server instanceof SubServer) sender.sendMessage(plugin.api.getLang("SubServers", "Command.Info.Format").replace("$str$", "Running") + ((((SubServer) server).isRunning())?ChatColor.GREEN+"yes":ChatColor.RED+"no"));
+ if (server instanceof SubServer) sender.sendMessage(plugin.api.getLang("SubServers", "Command.Info.Format").replace("$str$", ((((SubServer) server).isOnline())?"Online":"Running")) + ((((SubServer) server).isRunning())?ChatColor.GREEN+"yes":ChatColor.RED+"no"));
if (!(server instanceof SubServer) || ((SubServer) server).isRunning()) {
sender.sendMessage(plugin.api.getLang("SubServers", "Command.Info.Format").replace("$str$", "Connected") + ((server.getSubData()[0] != null)?ChatColor.GREEN+"yes"+((server.getSubData().length > 1)?ChatColor.AQUA+" +"+(server.getSubData().length-1)+" subchannel"+((server.getSubData().length == 2)?"":"s"):""):ChatColor.RED+"no"));
sender.sendMessage(plugin.api.getLang("SubServers", "Command.Info.Format").replace("$str$", "Players") + ChatColor.AQUA + server.getGlobalPlayers().size() + " online");
diff --git a/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/SubPlugin.java b/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/SubPlugin.java
index d9a563b4..55c2b72a 100644
--- a/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/SubPlugin.java
+++ b/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/SubPlugin.java
@@ -100,6 +100,10 @@ public final class SubPlugin extends JavaPlugin {
cmd.register("subservers", new SubCommand(this, "sub"));
}
+ if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
+ new net.ME1312.SubServers.Client.Bukkit.Library.Compatibility.PlaceholderImpl(this).register();
+ }
+
new Metrics(this);
Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> {
try {
diff --git a/SubServers.Client/Bukkit/src/plugin.yml b/SubServers.Client/Bukkit/src/plugin.yml
index 14256c92..2866cc48 100644
--- a/SubServers.Client/Bukkit/src/plugin.yml
+++ b/SubServers.Client/Bukkit/src/plugin.yml
@@ -2,7 +2,7 @@ name: SubServers-Client-Bukkit
main: net.ME1312.SubServers.Client.Bukkit.SubPlugin
version: "2.16.1a"
authors: ["ME1312"]
-softdepend: [TitleManager]
+softdepend: [TitleManager, PlaceholderAPI]
website: "https://github.com/ME1312/SubServers-2"
#commands:
# subservers:
diff --git a/SubServers.Client/Sponge/src/net/ME1312/SubServers/Client/Sponge/Network/API/SubCreator.java b/SubServers.Client/Sponge/src/net/ME1312/SubServers/Client/Sponge/Network/API/SubCreator.java
index 91b0c7e8..263e81e6 100644
--- a/SubServers.Client/Sponge/src/net/ME1312/SubServers/Client/Sponge/Network/API/SubCreator.java
+++ b/SubServers.Client/Sponge/src/net/ME1312/SubServers/Client/Sponge/Network/API/SubCreator.java
@@ -40,7 +40,7 @@ public class SubCreator {
public ServerTemplate(ObjectMap raw) {
this.raw = raw;
- this.type = (Util.isException(() -> ServerType.valueOf(raw.getRawString("type").toUpperCase())))? ServerType.valueOf(raw.getRawString("type").toUpperCase()): ServerType.CUSTOM;
+ this.type = Util.getDespiteException(() -> ServerType.valueOf(raw.getRawString("type").toUpperCase().replace('-', '_').replace(' ', '_')), ServerType.CUSTOM);
}
/**
diff --git a/SubServers.Client/Sponge/src/net/ME1312/SubServers/Client/Sponge/Network/API/SubServer.java b/SubServers.Client/Sponge/src/net/ME1312/SubServers/Client/Sponge/Network/API/SubServer.java
index 19b3dc81..ee39cfd9 100644
--- a/SubServers.Client/Sponge/src/net/ME1312/SubServers/Client/Sponge/Network/API/SubServer.java
+++ b/SubServers.Client/Sponge/src/net/ME1312/SubServers/Client/Sponge/Network/API/SubServer.java
@@ -359,6 +359,16 @@ public class SubServer extends Server {
return raw.getBoolean("running");
}
+ /**
+ * If the Server is Online
+ * This method can only be true when a SubData connection is made!
+ *
+ * @return Online Status
+ */
+ public boolean isOnline() {
+ return raw.getBoolean("online");
+ }
+
/**
* Grabs the Host of the Server
*
@@ -549,7 +559,7 @@ public class SubServer extends Server {
* @return Stop Action
*/
public StopAction getStopAction() {
- return Util.getDespiteException(() -> StopAction.valueOf(raw.getRawString("stop-action").toUpperCase().replace('-', '_').replace(' ', '_')), null);
+ return Util.getDespiteException(() -> StopAction.valueOf(raw.getRawString("stop-action").toUpperCase().replace('-', '_').replace(' ', '_')), StopAction.NONE);
}
/**
diff --git a/SubServers.Client/Sponge/src/net/ME1312/SubServers/Client/Sponge/SubCommand.java b/SubServers.Client/Sponge/src/net/ME1312/SubServers/Client/Sponge/SubCommand.java
index ce4b934f..09f6616f 100644
--- a/SubServers.Client/Sponge/src/net/ME1312/SubServers/Client/Sponge/SubCommand.java
+++ b/SubServers.Client/Sponge/src/net/ME1312/SubServers/Client/Sponge/SubCommand.java
@@ -532,7 +532,7 @@ public final class SubCommand implements CommandExecutor {
if (server.getGroups().size() > 1) for (String group : server.getGroups()) sender.sendMessage(ChatColor.convertColor(" " + plugin.api.getLang("SubServers", "Command.Info.List")).toBuilder().append(Text.builder(group).color(TextColors.WHITE).build()).build());
if (plugin.config.get().getMap("Settings").getBoolean("Show-Addresses", false)) sender.sendMessage(ChatColor.convertColor(plugin.api.getLang("SubServers", "Command.Info.Format").replace("$str$", "Address")).toBuilder().append(Text.builder(server.getAddress().getAddress().getHostAddress()+':'+server.getAddress().getPort()).color(TextColors.WHITE).build()).build());
else sender.sendMessage(ChatColor.convertColor(plugin.api.getLang("SubServers", "Command.Info.Format").replace("$str$", "Port")).toBuilder().append(Text.builder(Integer.toString(server.getAddress().getPort())).color(TextColors.AQUA).build()).build());
- if (server instanceof SubServer) sender.sendMessage(ChatColor.convertColor(plugin.api.getLang("SubServers", "Command.Info.Format").replace("$str$", "Running")).toBuilder().append(Text.builder((((SubServer) server).isRunning())?"yes":"no").color((((SubServer) server).isRunning())?TextColors.GREEN:TextColors.RED).build()).build());
+ if (server instanceof SubServer) sender.sendMessage(ChatColor.convertColor(plugin.api.getLang("SubServers", "Command.Info.Format").replace("$str$", ((((SubServer) server).isOnline())?"Online":"Running"))).toBuilder().append(Text.builder((((SubServer) server).isRunning())?"yes":"no").color((((SubServer) server).isRunning())?TextColors.GREEN:TextColors.RED).build()).build());
if (!(server instanceof SubServer) || ((SubServer) server).isRunning()) {
sender.sendMessage(ChatColor.convertColor(plugin.api.getLang("SubServers", "Command.Info.Format").replace("$str$", "Connected")).toBuilder().append(Text.builder((server.getSubData()[0] != null)?"yes":"no").color((server.getSubData()[0] != null)?TextColors.GREEN:TextColors.RED).build(), Text.builder((server.getSubData().length > 1)?" +"+(server.getSubData().length-1)+" subchannel"+((server.getSubData().length == 2)?"":"s"):"").color(TextColors.AQUA).build()).build());
sender.sendMessage(ChatColor.convertColor(plugin.api.getLang("SubServers", "Command.Info.Format").replace("$str$", "Players")).toBuilder().append(Text.builder(server.getGlobalPlayers().size() + " online").color(TextColors.AQUA).build()).build());
diff --git a/SubServers.Host/src/net/ME1312/SubServers/Host/Network/API/SubCreator.java b/SubServers.Host/src/net/ME1312/SubServers/Host/Network/API/SubCreator.java
index 735dc42c..664990cf 100644
--- a/SubServers.Host/src/net/ME1312/SubServers/Host/Network/API/SubCreator.java
+++ b/SubServers.Host/src/net/ME1312/SubServers/Host/Network/API/SubCreator.java
@@ -40,7 +40,7 @@ public class SubCreator {
public ServerTemplate(ObjectMap raw) {
this.raw = raw;
- this.type = (Util.isException(() -> ServerType.valueOf(raw.getRawString("type").toUpperCase())))? ServerType.valueOf(raw.getRawString("type").toUpperCase()): ServerType.CUSTOM;
+ this.type = Util.getDespiteException(() -> ServerType.valueOf(raw.getRawString("type").toUpperCase().replace('-', '_').replace(' ', '_')), ServerType.CUSTOM);
}
/**
diff --git a/SubServers.Host/src/net/ME1312/SubServers/Host/Network/API/SubServer.java b/SubServers.Host/src/net/ME1312/SubServers/Host/Network/API/SubServer.java
index 929e6a3f..dc3bb0f5 100644
--- a/SubServers.Host/src/net/ME1312/SubServers/Host/Network/API/SubServer.java
+++ b/SubServers.Host/src/net/ME1312/SubServers/Host/Network/API/SubServer.java
@@ -359,6 +359,16 @@ public class SubServer extends Server {
return raw.getBoolean("running");
}
+ /**
+ * If the Server is Online
+ * This method can only be true when a SubData connection is made!
+ *
+ * @return Online Status
+ */
+ public boolean isOnline() {
+ return raw.getBoolean("online");
+ }
+
/**
* Grabs the Host of the Server
*
@@ -549,7 +559,7 @@ public class SubServer extends Server {
* @return Stop Action
*/
public StopAction getStopAction() {
- return Util.getDespiteException(() -> StopAction.valueOf(raw.getRawString("stop-action").toUpperCase().replace('-', '_').replace(' ', '_')), null);
+ return Util.getDespiteException(() -> StopAction.valueOf(raw.getRawString("stop-action").toUpperCase().replace('-', '_').replace(' ', '_')), StopAction.NONE);
}
/**
diff --git a/SubServers.Host/src/net/ME1312/SubServers/Host/SubCommand.java b/SubServers.Host/src/net/ME1312/SubServers/Host/SubCommand.java
index c1577d79..08786724 100644
--- a/SubServers.Host/src/net/ME1312/SubServers/Host/SubCommand.java
+++ b/SubServers.Host/src/net/ME1312/SubServers/Host/SubCommand.java
@@ -219,7 +219,7 @@ public class SubCommand {
if (server.getGroups().size() > 0) sender.sendMessage(" -> Group" + ((server.getGroups().size() > 1)?"s:":": " + TextColor.WHITE + server.getGroups().get(0)));
if (server.getGroups().size() > 1) for (String group : server.getGroups()) sender.sendMessage(" - " + TextColor.WHITE + group);
sender.sendMessage(" -> Address: " + TextColor.WHITE + server.getAddress().getAddress().getHostAddress()+':'+server.getAddress().getPort());
- if (server instanceof SubServer) sender.sendMessage(" -> Running: " + ((((SubServer) server).isRunning())?TextColor.GREEN+"yes":TextColor.RED+"no"));
+ if (server instanceof SubServer) sender.sendMessage(" -> " + ((((SubServer) server).isOnline())?"Online":"Running") + ": " + ((((SubServer) server).isRunning())?TextColor.GREEN+"yes":TextColor.RED+"no"));
if (!(server instanceof SubServer) || ((SubServer) server).isRunning()) {
sender.sendMessage(" -> Connected: " + ((server.getSubData()[0] != null)?TextColor.GREEN+"yes"+((server.getSubData().length > 1)?TextColor.AQUA+" +"+(server.getSubData().length-1)+" subchannel"+((server.getSubData().length == 2)?"":"s"):""):TextColor.RED+"no"));
sender.sendMessage(" -> Players: " + TextColor.AQUA + server.getGlobalPlayers().size() + " online");
diff --git a/SubServers.Sync/src/net/ME1312/SubServers/Sync/Network/API/SubCreator.java b/SubServers.Sync/src/net/ME1312/SubServers/Sync/Network/API/SubCreator.java
index 3ad74bea..8b856815 100644
--- a/SubServers.Sync/src/net/ME1312/SubServers/Sync/Network/API/SubCreator.java
+++ b/SubServers.Sync/src/net/ME1312/SubServers/Sync/Network/API/SubCreator.java
@@ -40,7 +40,7 @@ public class SubCreator {
public ServerTemplate(ObjectMap raw) {
this.raw = raw;
- this.type = (Util.isException(() -> ServerType.valueOf(raw.getRawString("type").toUpperCase())))? ServerType.valueOf(raw.getRawString("type").toUpperCase()): ServerType.CUSTOM;
+ this.type = Util.getDespiteException(() -> ServerType.valueOf(raw.getRawString("type").toUpperCase().replace('-', '_').replace(' ', '_')), ServerType.CUSTOM);
}
/**
diff --git a/SubServers.Sync/src/net/ME1312/SubServers/Sync/Network/API/SubServer.java b/SubServers.Sync/src/net/ME1312/SubServers/Sync/Network/API/SubServer.java
index d1875aec..da40fd9e 100644
--- a/SubServers.Sync/src/net/ME1312/SubServers/Sync/Network/API/SubServer.java
+++ b/SubServers.Sync/src/net/ME1312/SubServers/Sync/Network/API/SubServer.java
@@ -359,6 +359,16 @@ public class SubServer extends Server {
return raw.getBoolean("running");
}
+ /**
+ * If the Server is Online
+ * This method can only be true when a SubData connection is made!
+ *
+ * @return Online Status
+ */
+ public boolean isOnline() {
+ return raw.getBoolean("online");
+ }
+
/**
* Grabs the Host of the Server
*
@@ -549,7 +559,7 @@ public class SubServer extends Server {
* @return Stop Action
*/
public StopAction getStopAction() {
- return Util.getDespiteException(() -> StopAction.valueOf(raw.getRawString("stop-action").toUpperCase().replace('-', '_').replace(' ', '_')), null);
+ return Util.getDespiteException(() -> StopAction.valueOf(raw.getRawString("stop-action").toUpperCase().replace('-', '_').replace(' ', '_')), StopAction.NONE);
}
/**
diff --git a/SubServers.Sync/src/net/ME1312/SubServers/Sync/SubCommand.java b/SubServers.Sync/src/net/ME1312/SubServers/Sync/SubCommand.java
index 118bf196..6acd7f0e 100644
--- a/SubServers.Sync/src/net/ME1312/SubServers/Sync/SubCommand.java
+++ b/SubServers.Sync/src/net/ME1312/SubServers/Sync/SubCommand.java
@@ -252,7 +252,7 @@ public final class SubCommand extends CommandX {
if (server.getGroups().size() > 0) sender.sendMessage(" -> Group" + ((server.getGroups().size() > 1)?"s:":": " + ChatColor.WHITE + server.getGroups().get(0)));
if (server.getGroups().size() > 1) for (String group : server.getGroups()) sender.sendMessage(" - " + ChatColor.WHITE + group);
sender.sendMessage(" -> Address: " + ChatColor.WHITE + server.getAddress().getAddress().getHostAddress()+':'+server.getAddress().getPort());
- if (server instanceof SubServer) sender.sendMessage(" -> Running: " + ((((SubServer) server).isRunning())?ChatColor.GREEN+"yes":ChatColor.RED+"no"));
+ if (server instanceof SubServer) sender.sendMessage(" -> " + ((((SubServer) server).isOnline())?"Online":"Running") + ": " + ((((SubServer) server).isRunning())?ChatColor.GREEN+"yes":ChatColor.RED+"no"));
if (!(server instanceof SubServer) || ((SubServer) server).isRunning()) {
sender.sendMessage(" -> Connected: " + ((server.getSubData()[0] != null)?ChatColor.GREEN+"yes"+((server.getSubData().length > 1)?ChatColor.AQUA+" +"+(server.getSubData().length-1)+" subchannel"+((server.getSubData().length == 2)?"":"s"):""):ChatColor.RED+"no"));
sender.sendMessage(" -> Players: " + ChatColor.AQUA + server.getGlobalPlayers().size() + " online");