ajUtils
This commit is contained in:
@@ -35,8 +35,8 @@
|
|||||||
<configuration>
|
<configuration>
|
||||||
<relocations>
|
<relocations>
|
||||||
<relocation>
|
<relocation>
|
||||||
<pattern>us.ajg0702.premium</pattern>
|
<pattern>us.ajg0702.utils</pattern>
|
||||||
<shadedPattern>us.ajg0702.queue</shadedPattern>
|
<shadedPattern>us.ajg0702.queue.utils</shadedPattern>
|
||||||
</relocation>
|
</relocation>
|
||||||
</relocations>
|
</relocations>
|
||||||
</configuration>
|
</configuration>
|
||||||
@@ -134,35 +134,6 @@
|
|||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-api</artifactId>
|
|
||||||
<version>1.14-SNAPSHOT</version>
|
|
||||||
<type>javadoc</type>
|
|
||||||
<scope>provided</scope>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<artifactId>bungeecord-chat</artifactId>
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<artifactId>bungeecord-config</artifactId>
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<artifactId>bungeecord-event</artifactId>
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<artifactId>bungeecord-protocol</artifactId>
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<artifactId>guava</artifactId>
|
|
||||||
<groupId>com.google.guava</groupId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.spigotmc</groupId>
|
<groupId>org.spigotmc</groupId>
|
||||||
<artifactId>spigot-api</artifactId>
|
<artifactId>spigot-api</artifactId>
|
||||||
|
|||||||
@@ -26,17 +26,15 @@
|
|||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>us.ajg0702</groupId>
|
||||||
<artifactId>bungeecord-api</artifactId>
|
<artifactId>ajUtils</artifactId>
|
||||||
<version>1.14-SNAPSHOT</version>
|
<version>1.0.0</version>
|
||||||
<type>jar</type>
|
<scope>compile</scope>
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>net.md-5</groupId>
|
||||||
<artifactId>bungeecord-api</artifactId>
|
<artifactId>bungeecord-api</artifactId>
|
||||||
<version>1.14-SNAPSHOT</version>
|
<version>1.14-SNAPSHOT</version>
|
||||||
<type>javadoc</type>
|
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -91,8 +89,8 @@
|
|||||||
<configuration>
|
<configuration>
|
||||||
<relocations>
|
<relocations>
|
||||||
<relocation>
|
<relocation>
|
||||||
<pattern>us.ajg0702.premium</pattern>
|
<pattern>us.ajg0702.utils</pattern>
|
||||||
<shadedPattern>us.ajg0702.queue</shadedPattern>
|
<shadedPattern>us.ajg0702.queue.utils</shadedPattern>
|
||||||
</relocation>
|
</relocation>
|
||||||
</relocations>
|
</relocations>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package us.ajg0702.queue;
|
|||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
@@ -20,10 +21,10 @@ import net.md_5.bungee.event.EventHandler;
|
|||||||
import us.ajg0702.queue.commands.LeaveCommand;
|
import us.ajg0702.queue.commands.LeaveCommand;
|
||||||
import us.ajg0702.queue.commands.ManageCommand;
|
import us.ajg0702.queue.commands.ManageCommand;
|
||||||
import us.ajg0702.queue.commands.MoveCommand;
|
import us.ajg0702.queue.commands.MoveCommand;
|
||||||
import us.ajg0702.queue.utils.BungeeConfig;
|
import us.ajg0702.utils.bungee.BungeeConfig;
|
||||||
import us.ajg0702.queue.utils.BungeeMessages;
|
import us.ajg0702.utils.bungee.BungeeMessages;
|
||||||
import us.ajg0702.queue.utils.BungeeStats;
|
import us.ajg0702.utils.bungee.BungeeStats;
|
||||||
import us.ajg0702.queue.utils.BungeeUtils;
|
import us.ajg0702.utils.bungee.BungeeUtils;
|
||||||
|
|
||||||
public class Main extends Plugin implements Listener {
|
public class Main extends Plugin implements Listener {
|
||||||
|
|
||||||
@@ -47,13 +48,16 @@ public class Main extends Plugin implements Listener {
|
|||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
plugin = this;
|
plugin = this;
|
||||||
|
|
||||||
/*LinkedHashMap<String, String> d = new LinkedHashMap<>();
|
LinkedHashMap<String, String> d = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
|
||||||
d.put("status.offline.base", "&cThe server you are queued for is {STATUS}. &7You are in position &f{POS}&7 of &f{LEN}&7.");
|
d.put("status.offline.base", "&cThe server you are queued for is {STATUS}. &7You are in position &f{POS}&7 of &f{LEN}&7.");
|
||||||
|
|
||||||
d.put("status.offline.offline", "offline");
|
d.put("status.offline.offline", "offline");
|
||||||
d.put("status.offline.restarting", "restarting");
|
d.put("status.offline.restarting", "restarting");
|
||||||
d.put("status.offline.full", "full");
|
d.put("status.offline.full", "full");
|
||||||
|
d.put("status.offline.restricted", "restricted");
|
||||||
|
|
||||||
d.put("status.online.base", "&7You are in position &f{POS}&7 of &f{LEN}&7. Estimated time: {TIME}");
|
d.put("status.online.base", "&7You are in position &f{POS}&7 of &f{LEN}&7. Estimated time: {TIME}");
|
||||||
d.put("status.left-last-queue", "&aYou left the last queue you were in.");
|
d.put("status.left-last-queue", "&aYou left the last queue you were in.");
|
||||||
d.put("status.now-in-queue", "&aYou are now queued for {SERVER}! &7You are in position &f{POS}&7 of &f{LEN}&7.\n&7Type &f/leavequeue&7 to leave the queue!");
|
d.put("status.now-in-queue", "&aYou are now queued for {SERVER}! &7You are in position &f{POS}&7 of &f{LEN}&7.\n&7Type &f/leavequeue&7 to leave the queue!");
|
||||||
@@ -65,8 +69,9 @@ public class Main extends Plugin implements Listener {
|
|||||||
d.put("errors.player-only", "&cThis command can only be executed as a player!");
|
d.put("errors.player-only", "&cThis command can only be executed as a player!");
|
||||||
d.put("errors.already-connected", "&cYou are already connected to this server!");
|
d.put("errors.already-connected", "&cYou are already connected to this server!");
|
||||||
|
|
||||||
d.put("commands.leave-queue", "&aYou left the queue!");
|
d.put("commands.leave-queue", "&aYou left the queue for {SERVER}!");
|
||||||
d.put("commands.reload", "&aConfig and messages reloaded successfully!");
|
d.put("commands.reload", "&aConfig and messages reloaded successfully!");
|
||||||
|
d.put("commands.joinqueue.usage", "&cUsage: /joinqueue <server>");
|
||||||
|
|
||||||
d.put("noperm", "&cYou do not have permission to do this!");
|
d.put("noperm", "&cYou do not have permission to do this!");
|
||||||
|
|
||||||
@@ -82,12 +87,13 @@ public class Main extends Plugin implements Listener {
|
|||||||
d.put("spigot.actionbar.offline", "&7You are queued for &f{SERVER}&7. &7You are in position &f{POS}&7 of &f{LEN}&7.");
|
d.put("spigot.actionbar.offline", "&7You are queued for &f{SERVER}&7. &7You are in position &f{POS}&7 of &f{LEN}&7.");
|
||||||
|
|
||||||
d.put("send", "&aAdded &f{PLAYER}&a to the queue for &f{SERVER}");
|
d.put("send", "&aAdded &f{PLAYER}&a to the queue for &f{SERVER}");
|
||||||
|
d.put("remove", "&aRemoved &f{PLAYER} from all queues they were in.");
|
||||||
|
|
||||||
d.put("placeholders.queued.none", "None");
|
d.put("placeholders.queued.none", "None");
|
||||||
d.put("placeholders.position.none", "None");
|
d.put("placeholders.position.none", "None");
|
||||||
|
|
||||||
msgs = BungeeMessages.getInstance(this, d);*/
|
msgs = BungeeMessages.getInstance(this, d);
|
||||||
msgs = BungeeMessages.getInstance(this);
|
//msgs = BungeeMessages.getInstance(this);
|
||||||
|
|
||||||
config = new BungeeConfig(this);
|
config = new BungeeConfig(this);
|
||||||
checkConfig();
|
checkConfig();
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
import net.md_5.bungee.api.config.ServerInfo;
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
import us.ajg0702.queue.utils.BungeeMessages;
|
import us.ajg0702.utils.bungee.BungeeMessages;
|
||||||
import us.ajg0702.queue.utils.BungeeUtils;
|
import us.ajg0702.utils.bungee.BungeeUtils;
|
||||||
|
|
||||||
public class Manager {
|
public class Manager {
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import net.md_5.bungee.api.plugin.Command;
|
|||||||
import us.ajg0702.queue.Main;
|
import us.ajg0702.queue.Main;
|
||||||
import us.ajg0702.queue.Manager;
|
import us.ajg0702.queue.Manager;
|
||||||
import us.ajg0702.queue.Server;
|
import us.ajg0702.queue.Server;
|
||||||
import us.ajg0702.queue.utils.BungeeMessages;
|
import us.ajg0702.utils.bungee.BungeeMessages;
|
||||||
|
|
||||||
public class LeaveCommand extends Command {
|
public class LeaveCommand extends Command {
|
||||||
Main plugin;
|
Main plugin;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import net.md_5.bungee.api.plugin.Command;
|
|||||||
import us.ajg0702.queue.Main;
|
import us.ajg0702.queue.Main;
|
||||||
import us.ajg0702.queue.Manager;
|
import us.ajg0702.queue.Manager;
|
||||||
import us.ajg0702.queue.Server;
|
import us.ajg0702.queue.Server;
|
||||||
import us.ajg0702.queue.utils.BungeeMessages;
|
import us.ajg0702.utils.bungee.BungeeMessages;
|
||||||
|
|
||||||
public class ManageCommand extends Command {
|
public class ManageCommand extends Command {
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|||||||
import net.md_5.bungee.api.plugin.Command;
|
import net.md_5.bungee.api.plugin.Command;
|
||||||
import us.ajg0702.queue.Main;
|
import us.ajg0702.queue.Main;
|
||||||
import us.ajg0702.queue.Manager;
|
import us.ajg0702.queue.Manager;
|
||||||
import us.ajg0702.queue.utils.BungeeMessages;
|
import us.ajg0702.utils.bungee.BungeeMessages;
|
||||||
|
|
||||||
public class MoveCommand extends Command {
|
public class MoveCommand extends Command {
|
||||||
Main plugin;
|
Main plugin;
|
||||||
|
|||||||
@@ -1,208 +0,0 @@
|
|||||||
package us.ajg0702.queue.utils;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.text.DateFormat;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
|
||||||
import net.md_5.bungee.config.Configuration;
|
|
||||||
import net.md_5.bungee.config.ConfigurationProvider;
|
|
||||||
import net.md_5.bungee.config.YamlConfiguration;
|
|
||||||
|
|
||||||
public class BungeeConfig {
|
|
||||||
|
|
||||||
File f;
|
|
||||||
Configuration config;
|
|
||||||
|
|
||||||
ConfigurationProvider cv = ConfigurationProvider.getProvider(YamlConfiguration.class);
|
|
||||||
|
|
||||||
String nfm = "Could not find KEY in config! Try restarting the server or deleting the config and allowing the plugin to re-create it.";
|
|
||||||
|
|
||||||
public Object get(String key) {
|
|
||||||
Object r = config.get(key);
|
|
||||||
if(r == null) {
|
|
||||||
pl.getLogger().severe(nfm.replace("KEY", key));;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
public Integer getInt(String key) {
|
|
||||||
int r = config.getInt(key, -38964298);
|
|
||||||
if(r == -38964298) {
|
|
||||||
pl.getLogger().severe(nfm.replace("KEY", key));;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
public String getString(String key) {
|
|
||||||
String r = config.getString(key);
|
|
||||||
if(r == null) {
|
|
||||||
pl.getLogger().severe(nfm.replace("KEY", key));;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
public List<String> getStringList(String key) {
|
|
||||||
List<String> r = config.getStringList(key);
|
|
||||||
if(r == null) {
|
|
||||||
pl.getLogger().severe(nfm.replace("KEY", key));;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
public boolean getBoolean(String key) {
|
|
||||||
return config.getBoolean(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDefaultConfig() throws IOException {
|
|
||||||
BufferedReader stream = new BufferedReader(new InputStreamReader(this.getClass().getResourceAsStream("/config.yml")));
|
|
||||||
StringBuilder configfile = new StringBuilder();
|
|
||||||
String line;
|
|
||||||
while((line = stream.readLine()) != null) {
|
|
||||||
configfile.append(line+"\n");
|
|
||||||
}
|
|
||||||
return configfile.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getConfigString() throws IOException {
|
|
||||||
List<String> lines = Files.readAllLines(Paths.get(pl.getDataFolder().getPath().toString(), "config.yml"));
|
|
||||||
String end = "";
|
|
||||||
for(String line : lines) {
|
|
||||||
end += line+"\n";
|
|
||||||
}
|
|
||||||
return end;
|
|
||||||
}
|
|
||||||
Plugin pl;
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public BungeeConfig(Plugin plugin) {
|
|
||||||
pl = plugin;
|
|
||||||
f = new File(plugin.getDataFolder(), "config.yml");
|
|
||||||
if(!f.exists()) {
|
|
||||||
if(!Files.exists(pl.getDataFolder().toPath())) {
|
|
||||||
try {
|
|
||||||
Files.createDirectory(pl.getDataFolder().toPath());
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
PrintWriter writer = new PrintWriter(pl.getDataFolder()+File.separator+"config.yml", "UTF-8");
|
|
||||||
String[] lines = getDefaultConfig().split("\n");
|
|
||||||
for(String line : lines) {
|
|
||||||
writer.println(line);
|
|
||||||
|
|
||||||
}
|
|
||||||
writer.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
//Bukkit.getLogger().info(configfile.toString());
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
f = new File(pl.getDataFolder(), "config.yml");
|
|
||||||
Configuration oldconfig = cv.load(f);
|
|
||||||
String newConfig = getDefaultConfig();
|
|
||||||
int oldver = oldconfig.getInt("config-version", 0);
|
|
||||||
String strv = newConfig
|
|
||||||
.split("config\\-version: ")[1]
|
|
||||||
.split("\n")[0];
|
|
||||||
//pl.getLogger().info("New config version: "+strv);
|
|
||||||
int newver = Integer.parseInt(strv);
|
|
||||||
if(oldver < newver) {
|
|
||||||
pl.getLogger().info("Starting config converter!");
|
|
||||||
Date date = Calendar.getInstance().getTime();
|
|
||||||
DateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd-hh-mm-ss");
|
|
||||||
String strDate = dateFormat.format(date);
|
|
||||||
duplicateFile(f, new File(pl.getDataFolder(), "config.yml.old."+strDate));
|
|
||||||
String oldConfig = getConfigString();
|
|
||||||
f = new File(pl.getDataFolder(), "config.yml");
|
|
||||||
config = cv.load(f);
|
|
||||||
for(String key : oldconfig.getKeys()) {
|
|
||||||
pl.getLogger().info("Key: "+key);
|
|
||||||
String[] keyParts = key.split("\\.");
|
|
||||||
//pl.getLogger().info("Key len: "+keyParts.length);
|
|
||||||
String keySec = keyParts[keyParts.length-1];
|
|
||||||
pl.getLogger().info("keySec: "+keySec);
|
|
||||||
String newVal = newConfig.split(keySec)[1].split("\n")[0];
|
|
||||||
int i = 0;
|
|
||||||
for(String l : newConfig.split(keySec)[1].split("\n")) {
|
|
||||||
if(i == 0) {
|
|
||||||
i++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
pl.getLogger().info("Scanning: "+l);
|
|
||||||
if(l.startsWith("-")) {
|
|
||||||
newVal += "\n"+l;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String find = keySec+ newVal;
|
|
||||||
String replace = keySec + ": " + oldconfig.get(key);
|
|
||||||
replace = replace.replaceAll("\\[", "\n- ");
|
|
||||||
replace = replace.replaceAll("\\, ", "\n- ");
|
|
||||||
replace = replace.replaceAll("\\]", "");
|
|
||||||
pl.getLogger().info("Find: "+find +" Replace w: "+replace);
|
|
||||||
if(!keySec.equals("config-version")) {
|
|
||||||
newConfig = newConfig.replaceAll(find, replace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PrintWriter writer = new PrintWriter(f, "UTF-8");
|
|
||||||
String[] lines = newConfig.split("\n");
|
|
||||||
for(String line : lines) {
|
|
||||||
writer.println(line);
|
|
||||||
}
|
|
||||||
writer.close();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
pl.getLogger().severe("Unable to load default config! " + e.getMessage() + "\n" + e.getStackTrace().toString());;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
f = new File(pl.getDataFolder(), "config.yml");
|
|
||||||
try {
|
|
||||||
config = cv.load(f);
|
|
||||||
} catch (IOException e) {
|
|
||||||
pl.getLogger().warning("Unable to reload the config:");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void reload() {
|
|
||||||
try {
|
|
||||||
config = cv.load(f);
|
|
||||||
} catch (IOException e) {
|
|
||||||
pl.getLogger().warning("Unable to reload the config:");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static void duplicateFile(File source, File destination) throws IOException {
|
|
||||||
InputStream is = null;
|
|
||||||
OutputStream os = null;
|
|
||||||
try {
|
|
||||||
is = new FileInputStream(source);
|
|
||||||
os = new FileOutputStream(destination);
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
int length;
|
|
||||||
while ((length = is.read(buffer)) > 0) {
|
|
||||||
os.write(buffer, 0, length);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
is.close();
|
|
||||||
os.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
package us.ajg0702.queue.utils;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.chat.BaseComponent;
|
|
||||||
import net.md_5.bungee.api.chat.TextComponent;
|
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
|
||||||
import net.md_5.bungee.config.Configuration;
|
|
||||||
import net.md_5.bungee.config.ConfigurationProvider;
|
|
||||||
import net.md_5.bungee.config.YamlConfiguration;
|
|
||||||
|
|
||||||
public class BungeeMessages {
|
|
||||||
static BungeeMessages INSTANCE = null;
|
|
||||||
public static BungeeMessages getInstance() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
public static BungeeMessages getInstance(Plugin pl) {
|
|
||||||
if(INSTANCE == null) {
|
|
||||||
INSTANCE = new BungeeMessages(pl);
|
|
||||||
}
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
Plugin pl;
|
|
||||||
ConfigurationProvider cv = ConfigurationProvider.getProvider(YamlConfiguration.class);
|
|
||||||
Configuration msgs;
|
|
||||||
File msgFile;
|
|
||||||
private BungeeMessages(Plugin pl) {
|
|
||||||
this.pl = pl;
|
|
||||||
loadMessagesFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadMessagesFile() {
|
|
||||||
msgFile = new File(pl.getDataFolder(), "messages.yml");
|
|
||||||
if(!msgFile.exists()) {
|
|
||||||
try {
|
|
||||||
pl.getDataFolder().mkdirs();
|
|
||||||
msgFile.createNewFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
pl.getLogger().severe("Unable to create messages file:");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
msgs = cv.load(msgFile);
|
|
||||||
} catch (IOException e) {
|
|
||||||
pl.getLogger().severe("Unable to load messages file:");
|
|
||||||
e.printStackTrace();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LinkedHashMap<String, String> d = new LinkedHashMap<>();
|
|
||||||
|
|
||||||
|
|
||||||
d.put("status.offline.base", "&cThe server you are queued for is {STATUS}. &7You are in position &f{POS}&7 of &f{LEN}&7.");
|
|
||||||
|
|
||||||
d.put("status.offline.offline", "offline");
|
|
||||||
d.put("status.offline.restarting", "restarting");
|
|
||||||
d.put("status.offline.full", "full");
|
|
||||||
d.put("status.offline.restricted", "restricted");
|
|
||||||
|
|
||||||
d.put("status.online.base", "&7You are in position &f{POS}&7 of &f{LEN}&7. Estimated time: {TIME}");
|
|
||||||
d.put("status.left-last-queue", "&aYou left the last queue you were in.");
|
|
||||||
d.put("status.now-in-queue", "&aYou are now queued for {SERVER}! &7You are in position &f{POS}&7 of &f{LEN}&7.\n&7Type &f/leavequeue&7 to leave the queue!");
|
|
||||||
d.put("status.now-in-empty-queue", "");
|
|
||||||
d.put("status.sending-now", "&aSending you to &f{SERVER} &anow..");
|
|
||||||
|
|
||||||
d.put("errors.server-not-exist", "&cThat server does not exist!");
|
|
||||||
d.put("errors.already-queued", "&cYou are already queued for that server!");
|
|
||||||
d.put("errors.player-only", "&cThis command can only be executed as a player!");
|
|
||||||
d.put("errors.already-connected", "&cYou are already connected to this server!");
|
|
||||||
|
|
||||||
d.put("commands.leave-queue", "&aYou left the queue for {SERVER}!");
|
|
||||||
d.put("commands.reload", "&aConfig and messages reloaded successfully!");
|
|
||||||
d.put("commands.joinqueue.usage", "&cUsage: /joinqueue <server>");
|
|
||||||
|
|
||||||
d.put("noperm", "&cYou do not have permission to do this!");
|
|
||||||
|
|
||||||
d.put("format.time.mins", "{m}m {s}s");
|
|
||||||
d.put("format.time.secs", "{s} seconds");
|
|
||||||
|
|
||||||
d.put("list.format", "&b{SERVER} &7({COUNT}): {LIST}");
|
|
||||||
d.put("list.playerlist", "&9{NAME}&7, ");
|
|
||||||
d.put("list.total", "&7Total players in queues: &f{TOTAL}");
|
|
||||||
d.put("list.none", "&7None");
|
|
||||||
|
|
||||||
d.put("spigot.actionbar.online", "&7You are queued for &f{SERVER}&7. You are in position &f{POS}&7 of &f{LEN}&7. Estimated time: {TIME}");
|
|
||||||
d.put("spigot.actionbar.offline", "&7You are queued for &f{SERVER}&7. &7You are in position &f{POS}&7 of &f{LEN}&7.");
|
|
||||||
|
|
||||||
d.put("send", "&aAdded &f{PLAYER}&a to the queue for &f{SERVER}");
|
|
||||||
d.put("remove", "&aRemoved &f{PLAYER} from all queues they were in.");
|
|
||||||
|
|
||||||
d.put("placeholders.queued.none", "None");
|
|
||||||
d.put("placeholders.position.none", "None");
|
|
||||||
|
|
||||||
|
|
||||||
for(String k : d.keySet()) {
|
|
||||||
//pl.getLogger().info("Checking "+k);
|
|
||||||
if(!msgs.contains(k)) {
|
|
||||||
msgs.set(k, d.get(k));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
cv.save(msgs, msgFile);
|
|
||||||
} catch (IOException e) {
|
|
||||||
pl.getLogger().severe("Unable to save messages file:");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String get(String key) {
|
|
||||||
String msg = msgs.get(key, "&cMessage '"+key+"' does not exist!");
|
|
||||||
msg = color(msg);
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
public BaseComponent[] getBC(String key, String... placeholders) {
|
|
||||||
String m = get(key);
|
|
||||||
for(String sr : placeholders) {
|
|
||||||
//ProxyServer.getInstance().getLogger().info(sr);
|
|
||||||
String placeholder = sr.split(":")[0];
|
|
||||||
String value = sr.replaceFirst(Matcher.quoteReplacement(placeholder+":"), "");
|
|
||||||
m = m.replaceAll("\\{"+Matcher.quoteReplacement(placeholder)+"\\}", value);
|
|
||||||
}
|
|
||||||
return TextComponent.fromLegacyText(m);
|
|
||||||
}
|
|
||||||
public String color(String msg) {
|
|
||||||
|
|
||||||
return net.md_5.bungee.api.ChatColor.translateAlternateColorCodes('&', msg).replaceAll(Matcher.quoteReplacement("\\n"), "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reload() {
|
|
||||||
loadMessagesFile();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,754 +0,0 @@
|
|||||||
package us.ajg0702.queue.utils;
|
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonPrimitive;
|
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
|
||||||
import net.md_5.bungee.config.Configuration;
|
|
||||||
import net.md_5.bungee.config.ConfigurationProvider;
|
|
||||||
import net.md_5.bungee.config.YamlConfiguration;
|
|
||||||
|
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
|
||||||
import java.io.*;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import java.util.zip.GZIPOutputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bStats collects some data for plugin authors.
|
|
||||||
* <p>
|
|
||||||
* Check out https://bStats.org/ to learn more about bStats!
|
|
||||||
*/
|
|
||||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
|
||||||
public class BungeeStats {
|
|
||||||
|
|
||||||
static {
|
|
||||||
// You can use the property to disable the check in your test environment
|
|
||||||
if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) {
|
|
||||||
// Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D
|
|
||||||
final String defaultPackage = new String(
|
|
||||||
new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'n', 'g', 'e', 'e', 'c', 'o', 'r', 'd'});
|
|
||||||
final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
|
|
||||||
// We want to make sure nobody just copy & pastes the example and use the wrong package names
|
|
||||||
if (BungeeStats.class.getPackage().getName().equals(defaultPackage) || BungeeStats.class.getPackage().getName().equals(examplePackage)) {
|
|
||||||
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The version of this bStats class
|
|
||||||
public static final int B_STATS_VERSION = 1;
|
|
||||||
|
|
||||||
// The url to which the data is sent
|
|
||||||
private static final String URL = "https://bStats.org/submitData/bungeecord";
|
|
||||||
|
|
||||||
// The plugin
|
|
||||||
private final Plugin plugin;
|
|
||||||
|
|
||||||
// The plugin id
|
|
||||||
private final int pluginId;
|
|
||||||
|
|
||||||
// Is bStats enabled on this server?
|
|
||||||
private boolean enabled;
|
|
||||||
|
|
||||||
// The uuid of the server
|
|
||||||
private String serverUUID;
|
|
||||||
|
|
||||||
// Should failed requests be logged?
|
|
||||||
private boolean logFailedRequests = false;
|
|
||||||
|
|
||||||
// Should the sent data be logged?
|
|
||||||
private static boolean logSentData;
|
|
||||||
|
|
||||||
// Should the response text be logged?
|
|
||||||
private static boolean logResponseStatusText;
|
|
||||||
|
|
||||||
// A list with all known metrics class objects including this one
|
|
||||||
private static final List<Object> knownMetricsInstances = new ArrayList<>();
|
|
||||||
|
|
||||||
// A list with all custom charts
|
|
||||||
private final List<CustomChart> charts = new ArrayList<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class constructor.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin which stats should be submitted.
|
|
||||||
* @param pluginId The id of the plugin.
|
|
||||||
* It can be found at <a href="https://bstats.org/what-is-my-plugin-id">What is my plugin id?</a>
|
|
||||||
*/
|
|
||||||
public BungeeStats(Plugin plugin, int pluginId) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
this.pluginId = pluginId;
|
|
||||||
|
|
||||||
try {
|
|
||||||
loadConfig();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// Failed to load configuration
|
|
||||||
plugin.getLogger().log(Level.WARNING, "Failed to load bStats config!", e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We are not allowed to send data about this server :(
|
|
||||||
if (!enabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Class<?> usedMetricsClass = getFirstBStatsClass();
|
|
||||||
if (usedMetricsClass == null) {
|
|
||||||
// Failed to get first metrics class
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (usedMetricsClass == getClass()) {
|
|
||||||
// We are the first! :)
|
|
||||||
linkMetrics(this);
|
|
||||||
startSubmitting();
|
|
||||||
} else {
|
|
||||||
// We aren't the first so we link to the first metrics class
|
|
||||||
try {
|
|
||||||
usedMetricsClass.getMethod("linkMetrics", Object.class).invoke(null, this);
|
|
||||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
|
||||||
if (logFailedRequests) {
|
|
||||||
plugin.getLogger().log(Level.WARNING, "Failed to link to first metrics class " + usedMetricsClass.getName() + "!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if bStats is enabled.
|
|
||||||
*
|
|
||||||
* @return Whether bStats is enabled or not.
|
|
||||||
*/
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a custom chart.
|
|
||||||
*
|
|
||||||
* @param chart The chart to add.
|
|
||||||
*/
|
|
||||||
public void addCustomChart(CustomChart chart) {
|
|
||||||
if (chart == null) {
|
|
||||||
plugin.getLogger().log(Level.WARNING, "Chart cannot be null");
|
|
||||||
}
|
|
||||||
charts.add(chart);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Links an other metrics class with this class.
|
|
||||||
* This method is called using Reflection.
|
|
||||||
*
|
|
||||||
* @param metrics An object of the metrics class to link.
|
|
||||||
*/
|
|
||||||
public static void linkMetrics(Object metrics) {
|
|
||||||
knownMetricsInstances.add(metrics);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the plugin specific data.
|
|
||||||
* This method is called using Reflection.
|
|
||||||
*
|
|
||||||
* @return The plugin specific data.
|
|
||||||
*/
|
|
||||||
public JsonObject getPluginData() {
|
|
||||||
JsonObject data = new JsonObject();
|
|
||||||
|
|
||||||
String pluginName = plugin.getDescription().getName();
|
|
||||||
String pluginVersion = plugin.getDescription().getVersion();
|
|
||||||
|
|
||||||
data.addProperty("pluginName", pluginName);
|
|
||||||
data.addProperty("id", pluginId);
|
|
||||||
data.addProperty("pluginVersion", pluginVersion);
|
|
||||||
|
|
||||||
JsonArray customCharts = new JsonArray();
|
|
||||||
for (CustomChart customChart : charts) {
|
|
||||||
// Add the data of the custom charts
|
|
||||||
JsonObject chart = customChart.getRequestJsonObject(plugin.getLogger(), logFailedRequests);
|
|
||||||
if (chart == null) { // If the chart is null, we skip it
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
customCharts.add(chart);
|
|
||||||
}
|
|
||||||
data.add("customCharts", customCharts);
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startSubmitting() {
|
|
||||||
// The data collection is async, as well as sending the data
|
|
||||||
// Bungeecord does not have a main thread, everything is async
|
|
||||||
plugin.getProxy().getScheduler().schedule(plugin, this::submitData, 2, 30, TimeUnit.MINUTES);
|
|
||||||
// Submit the data every 30 minutes, first time after 2 minutes to give other plugins enough time to start
|
|
||||||
// WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted!
|
|
||||||
// WARNING: Just don't do it!
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the server specific data.
|
|
||||||
*
|
|
||||||
* @return The server specific data.
|
|
||||||
*/
|
|
||||||
private JsonObject getServerData() {
|
|
||||||
// Minecraft specific data
|
|
||||||
int playerAmount = Math.min(plugin.getProxy().getOnlineCount(), 500);
|
|
||||||
int onlineMode = plugin.getProxy().getConfig().isOnlineMode() ? 1 : 0;
|
|
||||||
String bungeecordVersion = plugin.getProxy().getVersion();
|
|
||||||
int managedServers = plugin.getProxy().getServers().size();
|
|
||||||
|
|
||||||
// OS/Java specific data
|
|
||||||
String javaVersion = System.getProperty("java.version");
|
|
||||||
String osName = System.getProperty("os.name");
|
|
||||||
String osArch = System.getProperty("os.arch");
|
|
||||||
String osVersion = System.getProperty("os.version");
|
|
||||||
int coreCount = Runtime.getRuntime().availableProcessors();
|
|
||||||
|
|
||||||
JsonObject data = new JsonObject();
|
|
||||||
|
|
||||||
data.addProperty("serverUUID", serverUUID);
|
|
||||||
|
|
||||||
data.addProperty("playerAmount", playerAmount);
|
|
||||||
data.addProperty("managedServers", managedServers);
|
|
||||||
data.addProperty("onlineMode", onlineMode);
|
|
||||||
data.addProperty("bungeecordVersion", bungeecordVersion);
|
|
||||||
|
|
||||||
data.addProperty("javaVersion", javaVersion);
|
|
||||||
data.addProperty("osName", osName);
|
|
||||||
data.addProperty("osArch", osArch);
|
|
||||||
data.addProperty("osVersion", osVersion);
|
|
||||||
data.addProperty("coreCount", coreCount);
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Collects the data and sends it afterwards.
|
|
||||||
*/
|
|
||||||
private void submitData() {
|
|
||||||
final JsonObject data = getServerData();
|
|
||||||
|
|
||||||
final JsonArray pluginData = new JsonArray();
|
|
||||||
// Search for all other bStats Metrics classes to get their plugin data
|
|
||||||
for (Object metrics : knownMetricsInstances) {
|
|
||||||
try {
|
|
||||||
Object plugin = metrics.getClass().getMethod("getPluginData").invoke(metrics);
|
|
||||||
if (plugin instanceof JsonObject) {
|
|
||||||
pluginData.add((JsonObject) plugin);
|
|
||||||
}
|
|
||||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
data.add("plugins", pluginData);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Send the data
|
|
||||||
sendData(plugin, data);
|
|
||||||
} catch (Exception e) {
|
|
||||||
// Something went wrong! :(
|
|
||||||
if (logFailedRequests) {
|
|
||||||
plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the bStats configuration.
|
|
||||||
*
|
|
||||||
* @throws IOException If something did not work :(
|
|
||||||
*/
|
|
||||||
private void loadConfig() throws IOException {
|
|
||||||
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
|
|
||||||
bStatsFolder.mkdirs();
|
|
||||||
File configFile = new File(bStatsFolder, "config.yml");
|
|
||||||
if (!configFile.exists()) {
|
|
||||||
writeFile(configFile,
|
|
||||||
"#bStats collects some data for plugin authors like how many servers are using their plugins.",
|
|
||||||
"#To honor their work, you should not disable it.",
|
|
||||||
"#This has nearly no effect on the server performance!",
|
|
||||||
"#Check out https://bStats.org/ to learn more :)",
|
|
||||||
"enabled: true",
|
|
||||||
"serverUuid: \"" + UUID.randomUUID() + "\"",
|
|
||||||
"logFailedRequests: false",
|
|
||||||
"logSentData: false",
|
|
||||||
"logResponseStatusText: false");
|
|
||||||
}
|
|
||||||
|
|
||||||
Configuration configuration = ConfigurationProvider.getProvider(YamlConfiguration.class).load(configFile);
|
|
||||||
|
|
||||||
// Load configuration
|
|
||||||
enabled = configuration.getBoolean("enabled", true);
|
|
||||||
serverUUID = configuration.getString("serverUuid");
|
|
||||||
logFailedRequests = configuration.getBoolean("logFailedRequests", false);
|
|
||||||
logSentData = configuration.getBoolean("logSentData", false);
|
|
||||||
logResponseStatusText = configuration.getBoolean("logResponseStatusText", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the first bStat Metrics class.
|
|
||||||
*
|
|
||||||
* @return The first bStats metrics class.
|
|
||||||
*/
|
|
||||||
private Class<?> getFirstBStatsClass() {
|
|
||||||
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
|
|
||||||
bStatsFolder.mkdirs();
|
|
||||||
File tempFile = new File(bStatsFolder, "temp.txt");
|
|
||||||
|
|
||||||
try {
|
|
||||||
String className = readFile(tempFile);
|
|
||||||
if (className != null) {
|
|
||||||
try {
|
|
||||||
// Let's check if a class with the given name exists.
|
|
||||||
return Class.forName(className);
|
|
||||||
} catch (ClassNotFoundException ignored) { }
|
|
||||||
}
|
|
||||||
writeFile(tempFile, getClass().getName());
|
|
||||||
return getClass();
|
|
||||||
} catch (IOException e) {
|
|
||||||
if (logFailedRequests) {
|
|
||||||
plugin.getLogger().log(Level.WARNING, "Failed to get first bStats class!", e);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads the first line of the file.
|
|
||||||
*
|
|
||||||
* @param file The file to read. Cannot be null.
|
|
||||||
* @return The first line of the file or {@code null} if the file does not exist or is empty.
|
|
||||||
* @throws IOException If something did not work :(
|
|
||||||
*/
|
|
||||||
private String readFile(File file) throws IOException {
|
|
||||||
if (!file.exists()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {
|
|
||||||
return bufferedReader.readLine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes a String to a file. It also adds a note for the user,
|
|
||||||
*
|
|
||||||
* @param file The file to write to. Cannot be null.
|
|
||||||
* @param lines The lines to write.
|
|
||||||
* @throws IOException If something did not work :(
|
|
||||||
*/
|
|
||||||
private void writeFile(File file, String... lines) throws IOException {
|
|
||||||
try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file))) {
|
|
||||||
for (String line : lines) {
|
|
||||||
bufferedWriter.write(line);
|
|
||||||
bufferedWriter.newLine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends the data to the bStats server.
|
|
||||||
*
|
|
||||||
* @param plugin Any plugin. It's just used to get a logger instance.
|
|
||||||
* @param data The data to send.
|
|
||||||
* @throws Exception If the request failed.
|
|
||||||
*/
|
|
||||||
private static void sendData(Plugin plugin, JsonObject data) throws Exception {
|
|
||||||
if (data == null) {
|
|
||||||
throw new IllegalArgumentException("Data cannot be null");
|
|
||||||
}
|
|
||||||
if (logSentData) {
|
|
||||||
plugin.getLogger().info("Sending data to bStats: " + data);
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection();
|
|
||||||
|
|
||||||
// Compress the data to save bandwidth
|
|
||||||
byte[] compressedData = compress(data.toString());
|
|
||||||
|
|
||||||
// Add headers
|
|
||||||
connection.setRequestMethod("POST");
|
|
||||||
connection.addRequestProperty("Accept", "application/json");
|
|
||||||
connection.addRequestProperty("Connection", "close");
|
|
||||||
connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
|
|
||||||
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
|
|
||||||
connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
|
|
||||||
connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
|
|
||||||
|
|
||||||
// Send data
|
|
||||||
connection.setDoOutput(true);
|
|
||||||
try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) {
|
|
||||||
outputStream.write(compressedData);
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
|
|
||||||
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
|
|
||||||
String line;
|
|
||||||
while ((line = bufferedReader.readLine()) != null) {
|
|
||||||
builder.append(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (logResponseStatusText) {
|
|
||||||
plugin.getLogger().info("Sent data to bStats and received response: " + builder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gzips the given String.
|
|
||||||
*
|
|
||||||
* @param str The string to gzip.
|
|
||||||
* @return The gzipped String.
|
|
||||||
* @throws IOException If the compression failed.
|
|
||||||
*/
|
|
||||||
private static byte[] compress(final String str) throws IOException {
|
|
||||||
if (str == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
||||||
try (GZIPOutputStream gzip = new GZIPOutputStream(outputStream)) {
|
|
||||||
gzip.write(str.getBytes(StandardCharsets.UTF_8));
|
|
||||||
}
|
|
||||||
return outputStream.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a custom chart.
|
|
||||||
*/
|
|
||||||
public static abstract class CustomChart {
|
|
||||||
|
|
||||||
// The id of the chart
|
|
||||||
private final String chartId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class constructor.
|
|
||||||
*
|
|
||||||
* @param chartId The id of the chart.
|
|
||||||
*/
|
|
||||||
CustomChart(String chartId) {
|
|
||||||
if (chartId == null || chartId.isEmpty()) {
|
|
||||||
throw new IllegalArgumentException("ChartId cannot be null or empty!");
|
|
||||||
}
|
|
||||||
this.chartId = chartId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private JsonObject getRequestJsonObject(Logger logger, boolean logFailedRequests) {
|
|
||||||
JsonObject chart = new JsonObject();
|
|
||||||
chart.addProperty("chartId", chartId);
|
|
||||||
try {
|
|
||||||
JsonObject data = getChartData();
|
|
||||||
if (data == null) {
|
|
||||||
// If the data is null we don't send the chart.
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
chart.add("data", data);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
if (logFailedRequests) {
|
|
||||||
logger.log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return chart;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract JsonObject getChartData() throws Exception;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a custom simple pie.
|
|
||||||
*/
|
|
||||||
public static class SimplePie extends CustomChart {
|
|
||||||
|
|
||||||
private final Callable<String> callable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class constructor.
|
|
||||||
*
|
|
||||||
* @param chartId The id of the chart.
|
|
||||||
* @param callable The callable which is used to request the chart data.
|
|
||||||
*/
|
|
||||||
public SimplePie(String chartId, Callable<String> callable) {
|
|
||||||
super(chartId);
|
|
||||||
this.callable = callable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected JsonObject getChartData() throws Exception {
|
|
||||||
JsonObject data = new JsonObject();
|
|
||||||
String value = callable.call();
|
|
||||||
if (value == null || value.isEmpty()) {
|
|
||||||
// Null = skip the chart
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
data.addProperty("value", value);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a custom advanced pie.
|
|
||||||
*/
|
|
||||||
public static class AdvancedPie extends CustomChart {
|
|
||||||
|
|
||||||
private final Callable<Map<String, Integer>> callable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class constructor.
|
|
||||||
*
|
|
||||||
* @param chartId The id of the chart.
|
|
||||||
* @param callable The callable which is used to request the chart data.
|
|
||||||
*/
|
|
||||||
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
|
|
||||||
super(chartId);
|
|
||||||
this.callable = callable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected JsonObject getChartData() throws Exception {
|
|
||||||
JsonObject data = new JsonObject();
|
|
||||||
JsonObject values = new JsonObject();
|
|
||||||
Map<String, Integer> map = callable.call();
|
|
||||||
if (map == null || map.isEmpty()) {
|
|
||||||
// Null = skip the chart
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
boolean allSkipped = true;
|
|
||||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
|
||||||
if (entry.getValue() == 0) {
|
|
||||||
continue; // Skip this invalid
|
|
||||||
}
|
|
||||||
allSkipped = false;
|
|
||||||
values.addProperty(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
if (allSkipped) {
|
|
||||||
// Null = skip the chart
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
data.add("values", values);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a custom drilldown pie.
|
|
||||||
*/
|
|
||||||
public static class DrilldownPie extends CustomChart {
|
|
||||||
|
|
||||||
private final Callable<Map<String, Map<String, Integer>>> callable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class constructor.
|
|
||||||
*
|
|
||||||
* @param chartId The id of the chart.
|
|
||||||
* @param callable The callable which is used to request the chart data.
|
|
||||||
*/
|
|
||||||
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
|
|
||||||
super(chartId);
|
|
||||||
this.callable = callable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonObject getChartData() throws Exception {
|
|
||||||
JsonObject data = new JsonObject();
|
|
||||||
JsonObject values = new JsonObject();
|
|
||||||
Map<String, Map<String, Integer>> map = callable.call();
|
|
||||||
if (map == null || map.isEmpty()) {
|
|
||||||
// Null = skip the chart
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
boolean reallyAllSkipped = true;
|
|
||||||
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
|
|
||||||
JsonObject value = new JsonObject();
|
|
||||||
boolean allSkipped = true;
|
|
||||||
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
|
|
||||||
value.addProperty(valueEntry.getKey(), valueEntry.getValue());
|
|
||||||
allSkipped = false;
|
|
||||||
}
|
|
||||||
if (!allSkipped) {
|
|
||||||
reallyAllSkipped = false;
|
|
||||||
values.add(entryValues.getKey(), value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (reallyAllSkipped) {
|
|
||||||
// Null = skip the chart
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
data.add("values", values);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a custom single line chart.
|
|
||||||
*/
|
|
||||||
public static class SingleLineChart extends CustomChart {
|
|
||||||
|
|
||||||
private final Callable<Integer> callable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class constructor.
|
|
||||||
*
|
|
||||||
* @param chartId The id of the chart.
|
|
||||||
* @param callable The callable which is used to request the chart data.
|
|
||||||
*/
|
|
||||||
public SingleLineChart(String chartId, Callable<Integer> callable) {
|
|
||||||
super(chartId);
|
|
||||||
this.callable = callable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected JsonObject getChartData() throws Exception {
|
|
||||||
JsonObject data = new JsonObject();
|
|
||||||
int value = callable.call();
|
|
||||||
if (value == 0) {
|
|
||||||
// Null = skip the chart
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
data.addProperty("value", value);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a custom multi line chart.
|
|
||||||
*/
|
|
||||||
public static class MultiLineChart extends CustomChart {
|
|
||||||
|
|
||||||
private final Callable<Map<String, Integer>> callable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class constructor.
|
|
||||||
*
|
|
||||||
* @param chartId The id of the chart.
|
|
||||||
* @param callable The callable which is used to request the chart data.
|
|
||||||
*/
|
|
||||||
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
|
|
||||||
super(chartId);
|
|
||||||
this.callable = callable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected JsonObject getChartData() throws Exception {
|
|
||||||
JsonObject data = new JsonObject();
|
|
||||||
JsonObject values = new JsonObject();
|
|
||||||
Map<String, Integer> map = callable.call();
|
|
||||||
if (map == null || map.isEmpty()) {
|
|
||||||
// Null = skip the chart
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
boolean allSkipped = true;
|
|
||||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
|
||||||
if (entry.getValue() == 0) {
|
|
||||||
continue; // Skip this invalid
|
|
||||||
}
|
|
||||||
allSkipped = false;
|
|
||||||
values.addProperty(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
if (allSkipped) {
|
|
||||||
// Null = skip the chart
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
data.add("values", values);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a custom simple bar chart.
|
|
||||||
*/
|
|
||||||
public static class SimpleBarChart extends CustomChart {
|
|
||||||
|
|
||||||
private final Callable<Map<String, Integer>> callable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class constructor.
|
|
||||||
*
|
|
||||||
* @param chartId The id of the chart.
|
|
||||||
* @param callable The callable which is used to request the chart data.
|
|
||||||
*/
|
|
||||||
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
|
|
||||||
super(chartId);
|
|
||||||
this.callable = callable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected JsonObject getChartData() throws Exception {
|
|
||||||
JsonObject data = new JsonObject();
|
|
||||||
JsonObject values = new JsonObject();
|
|
||||||
Map<String, Integer> map = callable.call();
|
|
||||||
if (map == null || map.isEmpty()) {
|
|
||||||
// Null = skip the chart
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
|
||||||
JsonArray categoryValues = new JsonArray();
|
|
||||||
categoryValues.add(new JsonPrimitive(entry.getValue()));
|
|
||||||
values.add(entry.getKey(), categoryValues);
|
|
||||||
}
|
|
||||||
data.add("values", values);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a custom advanced bar chart.
|
|
||||||
*/
|
|
||||||
public static class AdvancedBarChart extends CustomChart {
|
|
||||||
|
|
||||||
private final Callable<Map<String, int[]>> callable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class constructor.
|
|
||||||
*
|
|
||||||
* @param chartId The id of the chart.
|
|
||||||
* @param callable The callable which is used to request the chart data.
|
|
||||||
*/
|
|
||||||
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
|
|
||||||
super(chartId);
|
|
||||||
this.callable = callable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected JsonObject getChartData() throws Exception {
|
|
||||||
JsonObject data = new JsonObject();
|
|
||||||
JsonObject values = new JsonObject();
|
|
||||||
Map<String, int[]> map = callable.call();
|
|
||||||
if (map == null || map.isEmpty()) {
|
|
||||||
// Null = skip the chart
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
boolean allSkipped = true;
|
|
||||||
for (Map.Entry<String, int[]> entry : map.entrySet()) {
|
|
||||||
if (entry.getValue().length == 0) {
|
|
||||||
continue; // Skip this invalid
|
|
||||||
}
|
|
||||||
allSkipped = false;
|
|
||||||
JsonArray categoryValues = new JsonArray();
|
|
||||||
for (int categoryValue : entry.getValue()) {
|
|
||||||
categoryValues.add(new JsonPrimitive(categoryValue));
|
|
||||||
}
|
|
||||||
values.add(entry.getKey(), categoryValues);
|
|
||||||
}
|
|
||||||
if (allSkipped) {
|
|
||||||
// Null = skip the chart
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
data.add("values", values);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package us.ajg0702.queue.utils;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import com.google.common.io.ByteArrayDataOutput;
|
|
||||||
import com.google.common.io.ByteStreams;
|
|
||||||
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
|
|
||||||
public class BungeeUtils {
|
|
||||||
public static void sendCustomData(ProxiedPlayer player, String channel, String data1) {
|
|
||||||
Collection<ProxiedPlayer> networkPlayers = ProxyServer.getInstance().getPlayers();
|
|
||||||
// perform a check to see if globally are no players
|
|
||||||
if ( networkPlayers == null || networkPlayers.isEmpty()) return;
|
|
||||||
|
|
||||||
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
|
||||||
out.writeUTF( channel );
|
|
||||||
out.writeUTF(player.getName());
|
|
||||||
out.writeUTF( data1 );
|
|
||||||
|
|
||||||
// we send the data to the server
|
|
||||||
// using ServerInfo the packet is being queued if there are no players in the server
|
|
||||||
// using only the server to send data the packet will be lost if no players are in it
|
|
||||||
player.getServer().sendData( "ajqueue:tospigot", out.toByteArray() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user