Delete util directory
This commit is contained in:
1 parent
5ebaf97732
commit
e032e6a996
22 files changed
-4100
No files matched your search
@@ -1,72 +0,0 @@
|
||||
package com.github.joelgodofwar.mmh.util;
|
||||
|
||||
//import org.bukkit.ChatColor;
|
||||
|
||||
public class Ansi {
|
||||
public static final String RESET = "\u001B[0m";
|
||||
|
||||
public static final String BOLD = "\u001B[1m";
|
||||
public static final String NORMAL = "\u001B[2m";
|
||||
|
||||
public static final String ITALIC = "\u001B[3m";
|
||||
public static final String UNDERLINE = "\u001B[4m";
|
||||
public static final String BLINK = "\u001B[5m";
|
||||
public static final String RAPID_BLINK = "\u001B[6m";
|
||||
|
||||
public static final String BLACK = "\u001B[30m";
|
||||
public static final String RED = "\u001B[31m";
|
||||
public static final String GREEN = "\u001B[32m";
|
||||
public static final String YELLOW = "\u001B[33m";
|
||||
public static final String BLUE = "\u001B[34m";
|
||||
public static final String MAGENTA = "\u001B[35m";
|
||||
public static final String CYAN = "\u001B[36m";
|
||||
public static final String WHITE = "\u001B[37m";
|
||||
|
||||
|
||||
public static final String LIGHT_BLACK = "\u001B[90m";
|
||||
public static final String LIGHT_RED = "\u001B[91m";
|
||||
public static final String LIGHT_GREEN = "\u001B[92m";
|
||||
public static final String LIGHT_YELLOW = "\u001B[93m";
|
||||
public static final String LIGHT_BLUE = "\u001B[94m";
|
||||
public static final String LIGHT_MAGENTA = "\u001B[95m";
|
||||
public static final String LIGHT_CYAN = "\u001B[96m";
|
||||
public static final String LIGHT_WHITE = "\u001B[97m";
|
||||
|
||||
public static String stripAnsi(String string) {
|
||||
string = string.replace("" + Ansi.BLACK , "").replace("" + Ansi.BLINK , "").replace("" + Ansi.BLUE , "").replace("" + Ansi.BOLD , "")
|
||||
.replace("" + Ansi.CYAN , "").replace("" + Ansi.GREEN , "").replace("" + Ansi.ITALIC , "").replace("" + Ansi.LIGHT_BLACK , "")
|
||||
.replace("" + Ansi.LIGHT_BLUE , "").replace("" + Ansi.LIGHT_CYAN , "").replace("" + Ansi.LIGHT_GREEN , "").replace("" + Ansi.LIGHT_MAGENTA , "")
|
||||
.replace("" + Ansi.LIGHT_RED , "").replace("" + Ansi.LIGHT_WHITE , "").replace("" + Ansi.LIGHT_YELLOW , "").replace("" + Ansi.MAGENTA , "")
|
||||
.replace("" + Ansi.NORMAL , "").replace("" + Ansi.RAPID_BLINK , "").replace("" + Ansi.RED , "").replace("" + Ansi.RESET , "").replace("" + Ansi.UNDERLINE , "")
|
||||
.replace("" + Ansi.WHITE , "").replace("" + Ansi.YELLOW , "");
|
||||
return string;
|
||||
}
|
||||
|
||||
|
||||
/**public static final ChatColor AQUA = ChatColor.AQUA;
|
||||
public static final ChatColor BLACK = ChatColor.BLACK;
|
||||
public static final ChatColor BLUE = ChatColor.BLUE;
|
||||
public static final ChatColor DARK_AQUA = ChatColor.DARK_AQUA;
|
||||
public static final ChatColor DARK_BLUE = ChatColor.DARK_BLUE;
|
||||
public static final ChatColor DARK_GRAY = ChatColor.DARK_GRAY;
|
||||
public static final ChatColor DARK_GREEN = ChatColor.DARK_GREEN;
|
||||
public static final ChatColor DARK_PURPLE = ChatColor.DARK_PURPLE;
|
||||
public static final ChatColor DARK_RED = ChatColor.DARK_RED;
|
||||
public static final ChatColor GOLD = ChatColor.GOLD;
|
||||
public static final ChatColor GRAY = ChatColor.GRAY;
|
||||
public static final ChatColor GREEN = ChatColor.GREEN;
|
||||
public static final ChatColor MAGENTA = ChatColor.LIGHT_PURPLE;
|
||||
public static final ChatColor RED = ChatColor.RED;
|
||||
public static final ChatColor WHITE = ChatColor.WHITE;
|
||||
public static final ChatColor YELLOW = ChatColor.YELLOW;
|
||||
|
||||
public static final ChatColor BOLD = ChatColor.BOLD;
|
||||
public static final ChatColor ITALIC = ChatColor.ITALIC;
|
||||
public static final ChatColor MAGIC = ChatColor.MAGIC;
|
||||
public static final ChatColor RESET = ChatColor.RESET;
|
||||
public static final ChatColor STRIKETHROUGH = ChatColor.STRIKETHROUGH;
|
||||
public static final ChatColor UNDERLINE = ChatColor.UNDERLINE;//*/
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
package com.github.joelgodofwar.mmh.util;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
public class ChatColorUtils
|
||||
{
|
||||
public static String setNametoRGB(String s){
|
||||
String prefix = "§x";
|
||||
s = s.replace("<BLACK>", prefix + "000000").replace("<DARK_BLUE>", prefix + "0000AA")
|
||||
.replace("<DARK_GREEN>", prefix + "00AA00").replace("<DARK_AQUA>", prefix + "00AAAA")
|
||||
.replace("<DARK_RED>", prefix + "AA0000").replace("<DARK_PURPLE>", prefix + "AA00AA")
|
||||
.replace("<GOLD>", prefix + "FFAA00").replace("<GRAY>", prefix + "AAAAAA")
|
||||
.replace("<DARK_GRAY>", prefix + "555555").replace("<BLUE>", prefix + "5555FF")
|
||||
.replace("<GREEN>", prefix + "55FF55").replace("<AQUA>", prefix + "55FFFF")
|
||||
.replace("<RED>", prefix + "FF5555").replace("<LIGHT_PURPLE>", prefix + "FF55FF")
|
||||
.replace("<YELLOW>", prefix + "FFFF55").replace("<WHITE>", prefix + "FFFFFF");
|
||||
return s;
|
||||
}
|
||||
|
||||
public static String setColorsByCode(String s)
|
||||
{
|
||||
s = s.replace("&0", "" + ChatColor.BLACK).replace("&1", "" + ChatColor.DARK_BLUE)
|
||||
.replace("&2", "" + ChatColor.DARK_GREEN).replace("&3", "" + ChatColor.DARK_AQUA)
|
||||
.replace("&4", "" + ChatColor.DARK_RED).replace("&5", "" + ChatColor.DARK_PURPLE)
|
||||
.replace("&6", "" + ChatColor.GOLD).replace("&7", "" + ChatColor.GRAY)
|
||||
.replace("&8", "" + ChatColor.DARK_GRAY).replace("&9", "" + ChatColor.BLUE)
|
||||
.replace("&a", "" + ChatColor.GREEN).replace("&b", "" + ChatColor.AQUA)
|
||||
.replace("&c", "" + ChatColor.RED).replace("&d", "" + ChatColor.LIGHT_PURPLE)
|
||||
.replace("&e", "" + ChatColor.YELLOW).replace("&f", "" + ChatColor.WHITE)
|
||||
.replace("&k", "" + ChatColor.MAGIC).replace("&l", "" + ChatColor.BOLD)
|
||||
.replace("&m", "" + ChatColor.STRIKETHROUGH).replace("&n", "" + ChatColor.UNDERLINE)
|
||||
.replace("&o", "" + ChatColor.ITALIC).replace("&r", "" + ChatColor.RESET)
|
||||
.replace("&A", "" + ChatColor.GREEN).replace("&B", "" + ChatColor.AQUA)
|
||||
.replace("&C", "" + ChatColor.RED).replace("&D", "" + ChatColor.LIGHT_PURPLE)
|
||||
.replace("&E", "" + ChatColor.YELLOW).replace("&F", "" + ChatColor.WHITE)
|
||||
.replace("&K", "" + ChatColor.MAGIC).replace("&L", "" + ChatColor.BOLD)
|
||||
.replace("&M", "" + ChatColor.STRIKETHROUGH).replace("&N", "" + ChatColor.UNDERLINE)
|
||||
.replace("&O", "" + ChatColor.ITALIC).replace("&R", "" + ChatColor.RESET);
|
||||
return s;
|
||||
}
|
||||
public static String setColorsByName(String s){
|
||||
s = s.replace("<BLACK>", "" + ChatColor.BLACK).replace("<DARK_BLUE>", "" + ChatColor.DARK_BLUE)
|
||||
.replace("<DARK_GREEN>", "" + ChatColor.DARK_GREEN).replace("<DARK_AQUA>", "" + ChatColor.DARK_AQUA)
|
||||
.replace("<DARK_RED>", "" + ChatColor.DARK_RED).replace("<DARK_PURPLE>", "" + ChatColor.DARK_PURPLE)
|
||||
.replace("<GOLD>", "" + ChatColor.GOLD).replace("<GRAY>", "" + ChatColor.GRAY)
|
||||
.replace("<DARK_GRAY>", "" + ChatColor.DARK_GRAY).replace("<BLUE>", "" + ChatColor.BLUE)
|
||||
.replace("<GREEN>", "" + ChatColor.GREEN).replace("<AQUA>", "" + ChatColor.AQUA)
|
||||
.replace("<RED>", "" + ChatColor.RED).replace("<LIGHT_PURPLE>", "" + ChatColor.LIGHT_PURPLE)
|
||||
.replace("<YELLOW>", "" + ChatColor.YELLOW).replace("<WHITE>", "" + ChatColor.WHITE)
|
||||
.replace("<MAGIC>", "" + ChatColor.MAGIC).replace("<BOLD>", "" + ChatColor.BOLD)
|
||||
.replace("<STRIKETHROUGH>", "" + ChatColor.STRIKETHROUGH).replace("<UNDERLINE>", "" + ChatColor.UNDERLINE)
|
||||
.replace("<ITALIC>", "" + ChatColor.ITALIC).replace("<RESET>", "" + ChatColor.RESET);
|
||||
return s;
|
||||
}
|
||||
public static String setColors(String string) {
|
||||
// Replace color placeholders while ignoring case
|
||||
Pattern pattern = Pattern.compile("<(\\w+)>", Pattern.CASE_INSENSITIVE);
|
||||
Matcher matcher = pattern.matcher(string);
|
||||
while (matcher.find()) {
|
||||
String colorPlaceholder = matcher.group(1);
|
||||
String color = setColors2("<" + colorPlaceholder.toUpperCase() + ">");
|
||||
if (color != null) {
|
||||
string = string.replaceFirst(Pattern.quote(matcher.group()), color);
|
||||
}
|
||||
}
|
||||
|
||||
// Apply color formatting
|
||||
string = ChatColor.translateAlternateColorCodes('&', string);
|
||||
|
||||
return string;
|
||||
}
|
||||
public static String setColors2(String string) {
|
||||
string = string.replace("<BLACK>", "&0" ) .replace("<DARK_BLUE>", "&1" )
|
||||
.replace("<DARK_GREEN>", "&2" ) .replace("<DARK_AQUA>", "&3" )
|
||||
.replace("<DARK_RED>", "&4" ) .replace("<DARK_PURPLE>", "&5" )
|
||||
.replace("<GOLD>", "&6" ) .replace("<GRAY>", "&7" )
|
||||
.replace("<DARK_GRAY>", "&8" ) .replace("<BLUE>", "&9" )
|
||||
.replace("<GREEN>", "&a" ) .replace("<AQUA>", "&b" )
|
||||
.replace("<RED>", "&c" ) .replace("<LIGHT_PURPLE>", "&d" )
|
||||
.replace("<YELLOW>", "&e" ) .replace("<WHITE>", "&f" )
|
||||
.replace("<MAGIC>", "&k" ) .replace("<BOLD>", "&l" )
|
||||
.replace("<STRIKETHROUGH>", "&m" ) .replace("<UNDERLINE>", "&n" )
|
||||
.replace("<ITALIC>", "&o" ) .replace("<RESET>", "&r" );
|
||||
return string;
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
package com.github.joelgodofwar.mmh.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
import com.github.joelgodofwar.mmh.MoreMobHeads;
|
||||
|
||||
public class ConfigAPI {
|
||||
|
||||
public final static Logger logger = Logger.getLogger("Minecraft");
|
||||
|
||||
public void CheckForConfig(MoreMobHeads plugin){
|
||||
try{
|
||||
if(!plugin.getDataFolder().exists()){
|
||||
log(": Data Folder doesn't exist");
|
||||
log(": Creating Data Folder");
|
||||
plugin.getDataFolder().mkdirs();
|
||||
log(": Data Folder Created at " + plugin.getDataFolder());
|
||||
}
|
||||
File file = new File(plugin.getDataFolder(), "config.yml");
|
||||
plugin.getLogger().info("" + file);
|
||||
if(!file.exists()){
|
||||
log("config.yml not found, creating!");
|
||||
plugin.saveDefaultConfig();
|
||||
FileConfiguration config = plugin.getConfig();
|
||||
|
||||
config.options().copyDefaults(true);
|
||||
plugin.saveConfig();
|
||||
}
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Reloadconfig(MoreMobHeads plugin){
|
||||
// Load config.
|
||||
FileConfiguration config = plugin.getConfig();
|
||||
String daString = config.getString("debug").replace("'", "") + ",";
|
||||
|
||||
if(daString.contains("true")){
|
||||
plugin.debug = true;
|
||||
}else{
|
||||
plugin.debug = false;
|
||||
}
|
||||
String daString2 = config.getString("auto_update_check").replace("'", "") + ",";
|
||||
if(daString2.contains("true")){
|
||||
plugin.UpdateCheck = true;
|
||||
}else{
|
||||
plugin.UpdateCheck = false;
|
||||
}
|
||||
|
||||
if(plugin.debug){log("UpdateCheck = " + plugin.UpdateCheck);} //TODO: Logger
|
||||
}
|
||||
public static void log(String dalog){
|
||||
Bukkit.getLogger().info(dalog);
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.github.joelgodofwar.mmh.util;
|
||||
|
||||
public class ConfigHelper {
|
||||
|
||||
public static Double Double(YmlConfiguration config, String get, Double def) {
|
||||
String str = config.getString(get);
|
||||
if (str == null || str.isEmpty()) {
|
||||
if(def != null) {
|
||||
return def;
|
||||
}else {
|
||||
return 0.00;
|
||||
}
|
||||
}
|
||||
if(str.indexOf('\'') >= 0) {
|
||||
str = removeQuotes(str);
|
||||
return Double.parseDouble(str);
|
||||
}
|
||||
return Double.parseDouble(str);
|
||||
}
|
||||
|
||||
public static String removeQuotes(String string) {
|
||||
if (string.length() >= 2 && string.charAt(0) == '"' && string.charAt(string.length() - 1) == '"'){
|
||||
string = string.substring(1, string.length() - 1);
|
||||
}
|
||||
if (string.length() >= 2 && string.charAt(0) == '\'' && string.charAt(string.length() - 1) == '\''){
|
||||
string = string.substring(1, string.length() - 1);
|
||||
}
|
||||
return string;
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
package com.github.joelgodofwar.mmh.util;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
|
||||
/**
|
||||
* Utility for resolving the {@link EquipmentSlot} containing a player's weapon for an
|
||||
* {@link EntityDamageByEntityEvent}. This is used since that event type doesn't provide a
|
||||
* way for finding out the equipment slot.
|
||||
*/
|
||||
public class EquipmentSlotResolver {
|
||||
|
||||
public static Optional<ItemStack> resolveDamagingWeapon(PlayerInventory playerInventory, DamageCause damageCause) {
|
||||
//System.out.println("damageCause=" + damageCause.toString());
|
||||
switch (damageCause) {
|
||||
case ENTITY_ATTACK:
|
||||
// Check if the player is holding any item in the main hand
|
||||
ItemStack mainHandItem = playerInventory.getItemInMainHand();
|
||||
//System.out.println("mainHandItem=" + mainHandItem.getType().toString());
|
||||
if (!mainHandItem.getType().equals(Material.AIR)) {
|
||||
return Optional.of(mainHandItem);
|
||||
}
|
||||
break;
|
||||
case PROJECTILE:
|
||||
// Ranged damage
|
||||
Optional<ItemStack> bowItem = getWeaponItem(playerInventory, Material.BOW);
|
||||
if (bowItem.isPresent()) {
|
||||
return bowItem;
|
||||
}
|
||||
Optional<ItemStack> crossbowItem = getWeaponItem(playerInventory, Material.CROSSBOW);
|
||||
if (crossbowItem.isPresent()) {
|
||||
return crossbowItem;
|
||||
}
|
||||
Optional<ItemStack> tridentItem = getWeaponItem(playerInventory, Material.TRIDENT);
|
||||
if (tridentItem.isPresent()) {
|
||||
return tridentItem;
|
||||
}
|
||||
Optional<ItemStack> snowItem = getWeaponItem(playerInventory, Material.SNOWBALL);
|
||||
if (snowItem.isPresent()) {
|
||||
return snowItem;
|
||||
}
|
||||
Optional<ItemStack> eggItem = getWeaponItem(playerInventory, Material.EGG);
|
||||
if (eggItem.isPresent()) {
|
||||
return eggItem;
|
||||
}
|
||||
break;
|
||||
case MAGIC:
|
||||
// Potion
|
||||
return getWeaponItem(playerInventory, Material.SPLASH_POTION);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private static Optional<ItemStack> getWeaponItem(PlayerInventory playerInventory, Material material) {
|
||||
ItemStack mainHandItem = playerInventory.getItemInMainHand();
|
||||
ItemStack offHandItem = playerInventory.getItemInOffHand();
|
||||
|
||||
if (mainHandItem.getType() == material) {
|
||||
return Optional.of(mainHandItem);
|
||||
} else if (offHandItem.getType() == material) {
|
||||
return Optional.of(offHandItem);
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
@@ -1,558 +0,0 @@
|
||||
package com.github.joelgodofwar.mmh.util;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
//This class is where all formatting methods are stored.
|
||||
@SuppressWarnings("unused")
|
||||
public class Format {
|
||||
//private static MineverseChat plugin = MineverseChat.getInstance();
|
||||
|
||||
public static final int LEGACY_COLOR_CODE_LENGTH = 2;
|
||||
public static final int HEX_COLOR_CODE_LENGTH = 14;
|
||||
public static final String DEFAULT_COLOR_CODE = String.valueOf(ChatColor.WHITE);
|
||||
public static final String HEX_COLOR_CODE_PREFIX = "#";
|
||||
public static final String BUKKIT_COLOR_CODE_PREFIX = "�";
|
||||
public static final String BUKKIT_HEX_COLOR_CODE_PREFIX = "x";
|
||||
|
||||
/**public static String convertToJson(MineverseChatPlayer sender, String format, String chat) {
|
||||
JsonFormat JSONformat = MineverseChat.jfInfo.getJsonFormat(sender.getJsonFormat());
|
||||
String f = format.replace("\\", "\\\\").replace("\"", "\\\"");
|
||||
String c = chat.replace("\\", "\\\\").replace("\"", "\\\"");
|
||||
String json = "[\"\",{\"text\":\"\",\"extra\":[";
|
||||
String prefix = "";
|
||||
String suffix = "";
|
||||
try {
|
||||
prefix = FormatStringAll(MineverseChat.chat.getPlayerPrefix(sender.getPlayer()));
|
||||
suffix = FormatStringAll(MineverseChat.chat.getPlayerSuffix(sender.getPlayer()));
|
||||
if(suffix.equals("")) {
|
||||
suffix = "venturechat_no_suffix_code";
|
||||
}
|
||||
if(prefix.equals("")) {
|
||||
prefix = "venturechat_no_prefix_code";
|
||||
}
|
||||
}
|
||||
catch(Exception e) {
|
||||
System.out.println("Exception?" + e.getLocalizedMessage());
|
||||
if(plugin.getConfig().getString("loglevel", "info").equals("debug")) {
|
||||
Bukkit.getConsoleSender().sendMessage(Format.FormatStringAll("&8[&eVentureChat&8]&e - Prefix and / or suffix don't exist, setting to nothing."));
|
||||
}
|
||||
suffix = "venturechat_no_suffix_code";
|
||||
prefix = "venturechat_no_prefix_code";
|
||||
}
|
||||
String nickname = "";
|
||||
if(sender.getPlayer() != null) {
|
||||
nickname = FormatStringAll(sender.getPlayer().getDisplayName());
|
||||
}
|
||||
json += convertPlaceholders(f, JSONformat, prefix, nickname, suffix, sender);
|
||||
json += "]}";
|
||||
json += "," + convertLinks(c);
|
||||
json += "]";
|
||||
if(plugin.getConfig().getString("loglevel", "info").equals("debug")) {
|
||||
System.out.println(json);
|
||||
System.out.println("END OF JSON");
|
||||
System.out.println("END OF JSON");
|
||||
System.out.println("END OF JSON");
|
||||
System.out.println("END OF JSON");
|
||||
System.out.println("END OF JSON");
|
||||
}
|
||||
return json;
|
||||
}*/
|
||||
|
||||
/**private static String convertPlaceholders(String s, JsonFormat format, String prefix, String nickname, String suffix, MineverseChatPlayer icp) {
|
||||
String remaining = s;
|
||||
String temp = "";
|
||||
int indexStart = -1;
|
||||
int indexEnd = -1;
|
||||
String placeholder = "";
|
||||
String lastCode = "�f";
|
||||
do {
|
||||
Pattern pattern = Pattern.compile("(" + escapeAllRegex(prefix) + "|" + escapeAllRegex(nickname) + "|" + escapeAllRegex(suffix) + ")");
|
||||
Matcher matcher = pattern.matcher(remaining);
|
||||
if(matcher.find()) {
|
||||
indexStart = matcher.start();
|
||||
indexEnd = matcher.end();
|
||||
placeholder = remaining.substring(indexStart, indexEnd);
|
||||
temp += convertToJsonColors(lastCode + remaining.substring(0, indexStart)) + ",";
|
||||
lastCode = getLastCode(lastCode + remaining.substring(0, indexStart));
|
||||
String action = "";
|
||||
String text = "";
|
||||
String hover = "";
|
||||
if(placeholder.contains(prefix)) {
|
||||
action = format.getClickPrefix();
|
||||
text = PlaceholderAPI.setBracketPlaceholders(icp.getPlayer(), format.getClickPrefixText());
|
||||
for(String st : format.getHoverTextPrefix()) {
|
||||
hover += Format.FormatStringAll(st) + "\n";
|
||||
}
|
||||
}
|
||||
if(placeholder.contains(nickname)) {
|
||||
action = format.getClickName();
|
||||
text = PlaceholderAPI.setBracketPlaceholders(icp.getPlayer(), format.getClickNameText());
|
||||
for(String st : format.getHoverTextName()) {
|
||||
hover += Format.FormatStringAll(st) + "\n";
|
||||
}
|
||||
}
|
||||
if(placeholder.contains(suffix)) {
|
||||
action = format.getClickSuffix();
|
||||
text = PlaceholderAPI.setBracketPlaceholders(icp.getPlayer(), format.getClickSuffixText());
|
||||
for(String st : format.getHoverTextSuffix()) {
|
||||
hover += Format.FormatStringAll(st) + "\n";
|
||||
}
|
||||
}
|
||||
hover = PlaceholderAPI.setBracketPlaceholders(icp.getPlayer(), hover.substring(0, hover.length() - 1));
|
||||
temp += convertToJsonColors(lastCode + placeholder, ",\"clickEvent\":{\"action\":\"" + action + "\",\"value\":\"" + text + "\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":{\"text\":\"\",\"extra\":[" + convertToJsonColors(hover) + "]}}") + ",";
|
||||
lastCode = getLastCode(lastCode + placeholder);
|
||||
remaining = remaining.substring(indexEnd);
|
||||
}
|
||||
else {
|
||||
temp += convertToJsonColors(lastCode + remaining);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while(true);
|
||||
return temp;
|
||||
}*/
|
||||
|
||||
/**private static String convertLinks(String s) {
|
||||
String remaining = s;
|
||||
String temp = "";
|
||||
int indexLink = -1;
|
||||
int indexLinkEnd = -1;
|
||||
String link = "";
|
||||
String lastCode = "�f";
|
||||
do {
|
||||
Pattern pattern = Pattern.compile("([a-zA-Z0-9�\\-:/]+\\.[a-zA-Z/0-9�\\-:_#]+(\\.[a-zA-Z/0-9.�\\-:#\\?\\+=_]+)?)");
|
||||
Matcher matcher = pattern.matcher(remaining);
|
||||
if(matcher.find()) {
|
||||
indexLink = matcher.start();
|
||||
indexLinkEnd = matcher.end();
|
||||
link = remaining.substring(indexLink, indexLinkEnd);
|
||||
temp += convertToJsonColors(lastCode + remaining.substring(0, indexLink)) + ",";
|
||||
lastCode = getLastCode(lastCode + remaining.substring(0, indexLink));
|
||||
String https = "";
|
||||
if(ChatColor.stripColor(link).contains("https://"))
|
||||
https = "s";
|
||||
temp += convertToJsonColors(lastCode + link, ",\"underlined\":\"" + underlineURLs() + "\",\"clickEvent\":{\"action\":\"open_url\",\"value\":\"http" + https + "://" + ChatColor.stripColor(link.replace("http://", "").replace("https://", "")) + "\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":{\"text\":\"\",\"extra\":[" + convertToJsonColors(lastCode + link) + "]}}") + ",";
|
||||
lastCode = getLastCode(lastCode + link);
|
||||
remaining = remaining.substring(indexLinkEnd);
|
||||
}
|
||||
else {
|
||||
temp += convertToJsonColors(lastCode + remaining);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while(true);
|
||||
return temp;
|
||||
}*/
|
||||
|
||||
public static String getLastCode(String s) {
|
||||
String ts = "";
|
||||
char[] ch = s.toCharArray();
|
||||
for(int a = 0; a < s.length() - 1; a ++) {
|
||||
if(String.valueOf(ch[a + 1]).matches("[lkomnLKOMN]") && ch[a] == '�') {
|
||||
ts += String.valueOf(ch[a]) + ch[a + 1];
|
||||
a ++;
|
||||
}
|
||||
else if(String.valueOf(ch[a + 1]).matches("[0123456789abcdefrABCDEFR]") && ch[a] == '�') {
|
||||
ts = String.valueOf(ch[a]) + ch[a + 1];
|
||||
a ++;
|
||||
}
|
||||
else if(ch[a + 1] == 'x' && ch[a] == '�') {
|
||||
if(ch.length > a + 13) {
|
||||
if(String.valueOf(ch[a + 3]).matches("[0123456789abcdefABCDEF]") && String.valueOf(ch[a + 5]).matches("[0123456789abcdefABCDEF]") && String.valueOf(ch[a + 7]).matches("[0123456789abcdefABCDEF]") && String.valueOf(ch[a + 9]).matches("[0123456789abcdefABCDEF]") && String.valueOf(ch[a + 11]).matches("[0123456789abcdefABCDEF]") && String.valueOf(ch[a + 13]).matches("[0123456789abcdefABCDEF]") && ch[a + 2] == '�' && ch[a + 4] == '�' && ch[a + 6] == '�' && ch[a + 8] == '�' && ch[a + 10] == '�' && ch[a + 12] == '�') {
|
||||
ts = String.valueOf(ch[a]) + ch[a + 1] + ch[a + 2] + ch[a + 3] + ch[a + 4] + ch[a + 5] + ch[a + 6] + ch[a + 7] + ch[a + 8] + ch[a + 9] + ch[a + 10] + ch[a + 11] + ch[a + 12] + ch[a + 13];
|
||||
a += 13;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
private static String convertToJsonColors(String s) {
|
||||
return convertToJsonColors(s, "");
|
||||
}
|
||||
|
||||
private static String convertToJsonColors(String s, String extensions) {
|
||||
String remaining = s;
|
||||
String temp = "";
|
||||
int indexColor = -1;
|
||||
int indexNextColor = -1;
|
||||
String color = "";
|
||||
String modifier = "";
|
||||
boolean bold = false;
|
||||
boolean obfuscated = false;
|
||||
boolean italic = false;
|
||||
boolean strikethrough = false;
|
||||
boolean underlined = false;
|
||||
String previousColor = "";
|
||||
int colorLength = LEGACY_COLOR_CODE_LENGTH;
|
||||
do {
|
||||
if(remaining.length() < LEGACY_COLOR_CODE_LENGTH) {
|
||||
temp = "{\"text\":\"" + remaining + "\"},";
|
||||
break;
|
||||
}
|
||||
modifier = "";
|
||||
indexColor = remaining.indexOf(BUKKIT_COLOR_CODE_PREFIX);
|
||||
previousColor = color;
|
||||
|
||||
color = remaining.substring(1, indexColor + LEGACY_COLOR_CODE_LENGTH);
|
||||
if(color.equals(BUKKIT_HEX_COLOR_CODE_PREFIX)) {
|
||||
if(remaining.length() >= HEX_COLOR_CODE_LENGTH) {
|
||||
color = HEX_COLOR_CODE_PREFIX + remaining.substring(LEGACY_COLOR_CODE_LENGTH, indexColor + HEX_COLOR_CODE_LENGTH).replace(BUKKIT_COLOR_CODE_PREFIX, "");
|
||||
colorLength = HEX_COLOR_CODE_LENGTH;
|
||||
bold = false;
|
||||
obfuscated = false;
|
||||
italic = false;
|
||||
strikethrough = false;
|
||||
underlined = false;
|
||||
}
|
||||
}
|
||||
else if(!color.matches("[0123456789abcdefABCDEF]")) {
|
||||
switch(color) {
|
||||
case "l":
|
||||
case "L": {
|
||||
bold = true;
|
||||
break;
|
||||
}
|
||||
case "k":
|
||||
case "K": {
|
||||
obfuscated = true;
|
||||
break;
|
||||
}
|
||||
case "o":
|
||||
case "O": {
|
||||
italic = true;
|
||||
break;
|
||||
}
|
||||
case "m":
|
||||
case "M": {
|
||||
strikethrough = true;
|
||||
break;
|
||||
}
|
||||
case "n":
|
||||
case "N": {
|
||||
underlined = true;
|
||||
break;
|
||||
}
|
||||
case "r":
|
||||
case "R": {
|
||||
bold = false;
|
||||
obfuscated = false;
|
||||
italic = false;
|
||||
strikethrough = false;
|
||||
underlined = false;
|
||||
color = "f";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!color.equals("f"))
|
||||
color = previousColor;
|
||||
if(color.length() == 0)
|
||||
color = "f";
|
||||
}
|
||||
else {
|
||||
bold = false;
|
||||
obfuscated = false;
|
||||
italic = false;
|
||||
strikethrough = false;
|
||||
underlined = false;
|
||||
}
|
||||
if(bold)
|
||||
modifier += ",\"bold\":\"true\"";
|
||||
if(obfuscated)
|
||||
modifier += ",\"obfuscated\":\"true\"";
|
||||
if(italic)
|
||||
modifier += ",\"italic\":\"true\"";
|
||||
if(underlined)
|
||||
modifier += ",\"underlined\":\"true\"";
|
||||
if(strikethrough)
|
||||
modifier += ",\"strikethrough\":\"true\"";
|
||||
remaining = remaining.substring(colorLength);
|
||||
colorLength = LEGACY_COLOR_CODE_LENGTH;
|
||||
indexNextColor = remaining.indexOf(BUKKIT_COLOR_CODE_PREFIX);
|
||||
if(indexNextColor == -1) {
|
||||
indexNextColor = remaining.length();
|
||||
}
|
||||
temp += "{\"text\":\"" + remaining.substring(0, indexNextColor) + "\",\"color\":\"" + hexidecimalToJsonColorRGB(color) + "\"" + modifier + extensions + "},";
|
||||
remaining = remaining.substring(indexNextColor);
|
||||
}
|
||||
while(remaining.length() > 1 && indexColor != -1);
|
||||
if(temp.length() > 1)
|
||||
temp = temp.substring(0, temp.length() - 1);
|
||||
return temp;
|
||||
}
|
||||
|
||||
private static String hexidecimalToJsonColorRGB(String c) {
|
||||
if(c.length() == 1) {
|
||||
switch(c) {
|
||||
case "0": return "black";
|
||||
case "1": return "dark_blue";
|
||||
case "2": return "dark_green";
|
||||
case "3": return "dark_aqua";
|
||||
case "4": return "dark_red";
|
||||
case "5": return "dark_purple";
|
||||
case "6": return "gold";
|
||||
case "7": return "gray";
|
||||
case "8": return "dark_gray";
|
||||
case "9": return "blue";
|
||||
case "a":
|
||||
case "A": return "green";
|
||||
case "b":
|
||||
case "B": return "aqua";
|
||||
case "c":
|
||||
case "C": return "red";
|
||||
case "d":
|
||||
case "D": return "light_purple";
|
||||
case "e":
|
||||
case "E": return "yellow";
|
||||
case "f":
|
||||
case "F": return "white";
|
||||
default: return "white";
|
||||
}
|
||||
}
|
||||
if(isValidHexColor(c)) {
|
||||
return c;
|
||||
}
|
||||
return "white";
|
||||
}
|
||||
|
||||
/**public static String convertPlainTextToJson(String s, boolean convertURL) {
|
||||
if(convertURL) {
|
||||
return "[" + Format.convertLinks(s) + "]";
|
||||
}
|
||||
else {
|
||||
return "[" + convertToJsonColors("�f" + s) + "]";
|
||||
}
|
||||
}
|
||||
|
||||
/**public static String formatModerationGUI(String json, Player player, String sender, String channelName, int hash) {
|
||||
if(player.hasPermission("venturechat.gui")) {
|
||||
json = json.substring(0, json.length() - 1);
|
||||
json += "," + Format.convertToJsonColors(Format.FormatStringAll(plugin.getConfig().getString("guiicon")), ",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/vchatgui " + sender + " " + channelName + " " + hash +"\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":{\"text\":\"\",\"extra\":[" + Format.convertToJsonColors(Format.FormatStringAll(plugin.getConfig().getString("guitext"))) + "]}}") + "]";
|
||||
}
|
||||
return json;
|
||||
}*/
|
||||
|
||||
/**public static PacketContainer createPacketPlayOutChat(String json) {
|
||||
WrappedChatComponent component = WrappedChatComponent.fromJson(json);
|
||||
PacketContainer container = new PacketContainer(PacketType.Play.Server.CHAT);
|
||||
container.getModifier().writeDefaults();
|
||||
container.getChatComponents().write(0, component);
|
||||
return container;
|
||||
}
|
||||
|
||||
public static PacketContainer createPacketPlayOutChat(WrappedChatComponent component) {
|
||||
PacketContainer container = new PacketContainer(PacketType.Play.Server.CHAT);
|
||||
container.getModifier().writeDefaults();
|
||||
container.getChatComponents().write(0, component);
|
||||
return container;
|
||||
}
|
||||
|
||||
public static void sendPacketPlayOutChat(Player player, PacketContainer packet) {
|
||||
try {
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet);
|
||||
}
|
||||
catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static String toPlainText(Object o, Class<?> c) {
|
||||
List<Object> finalList = new ArrayList<>();
|
||||
StringBuilder stringbuilder = new StringBuilder();
|
||||
try {
|
||||
splitComponents(finalList, o, c);
|
||||
for(Object component : finalList) {
|
||||
if(VersionHandler.is1_7_10()) {
|
||||
stringbuilder.append((String) component.getClass().getMethod("e").invoke(component));
|
||||
}
|
||||
else {
|
||||
stringbuilder.append((String) component.getClass().getMethod("getText").invoke(component));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(plugin.getConfig().getString("loglevel", "info").equals("debug")) {
|
||||
System.out.println("my string");
|
||||
System.out.println("my string");
|
||||
System.out.println("my string");
|
||||
System.out.println("my string");
|
||||
System.out.println("my string");
|
||||
System.out.println(stringbuilder.toString());
|
||||
}
|
||||
return stringbuilder.toString();
|
||||
}
|
||||
|
||||
private static void splitComponents(List<Object> finalList, Object o, Class<?> c) throws Exception {
|
||||
if(plugin.getConfig().getString("loglevel", "info").equals("debug")) {
|
||||
for(Method m : c.getMethods()) {
|
||||
System.out.println(m.getName());
|
||||
}
|
||||
}
|
||||
if(VersionHandler.is1_7() || VersionHandler.is1_8() || VersionHandler.is1_9() || VersionHandler.is1_10() || VersionHandler.is1_11() || VersionHandler.is1_12() || VersionHandler.is1_13() || (VersionHandler.is1_14() && !VersionHandler.is1_14_4())) {
|
||||
ArrayList<?> list = (ArrayList<?>) c.getMethod("a").invoke(o, new Object[0]);
|
||||
for(Object component : list) {
|
||||
ArrayList<?> innerList = (ArrayList<?>) c.getMethod("a").invoke(component, new Object[0]);
|
||||
if(innerList.size() > 0) {
|
||||
splitComponents(finalList, component, c);
|
||||
}
|
||||
else {
|
||||
finalList.add(component);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ArrayList<?> list = (ArrayList<?>) c.getMethod("getSiblings").invoke(o, new Object[0]);
|
||||
for(Object component : list) {
|
||||
ArrayList<?> innerList = (ArrayList<?>) c.getMethod("getSiblings").invoke(component, new Object[0]);
|
||||
if(innerList.size() > 0) {
|
||||
splitComponents(finalList, component, c);
|
||||
}
|
||||
else {
|
||||
finalList.add(component);
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
protected static Pattern chatHexColorPattern = Pattern.compile("(?i)&([X])");
|
||||
protected static Pattern chatColorPattern = Pattern.compile("(?i)&([0-9A-F])");
|
||||
protected static Pattern chatMagicPattern = Pattern.compile("(?i)&([K])");
|
||||
protected static Pattern chatBoldPattern = Pattern.compile("(?i)&([L])");
|
||||
protected static Pattern chatStrikethroughPattern = Pattern.compile("(?i)&([M])");
|
||||
protected static Pattern chatUnderlinePattern = Pattern.compile("(?i)&([N])");
|
||||
protected static Pattern chatItalicPattern = Pattern.compile("(?i)&([O])");
|
||||
protected static Pattern chatResetPattern = Pattern.compile("(?i)&([R])");
|
||||
|
||||
public static String FormatStringColor(String string) {
|
||||
String allFormated = string;
|
||||
allFormated = chatColorPattern.matcher(allFormated).replaceAll("\u00A7$1");
|
||||
allFormated = chatHexColorPattern.matcher(allFormated).replaceAll("\u00A7$1");
|
||||
allFormated = allFormated.replaceAll("%", "\\%");
|
||||
|
||||
allFormated = convertHexColorCodeStringToBukkitColorCodeString(allFormated);
|
||||
return allFormated;
|
||||
}
|
||||
|
||||
public static String FormatString(String string) {
|
||||
String allFormated = string;
|
||||
allFormated = chatMagicPattern.matcher(allFormated).replaceAll("\u00A7$1");
|
||||
allFormated = chatBoldPattern.matcher(allFormated).replaceAll("\u00A7$1");
|
||||
allFormated = chatStrikethroughPattern.matcher(allFormated).replaceAll("\u00A7$1");
|
||||
allFormated = chatUnderlinePattern.matcher(allFormated).replaceAll("\u00A7$1");
|
||||
allFormated = chatItalicPattern.matcher(allFormated).replaceAll("\u00A7$1");
|
||||
allFormated = chatResetPattern.matcher(allFormated).replaceAll("\u00A7$1");
|
||||
allFormated = allFormated.replaceAll("%", "\\%");
|
||||
return allFormated;
|
||||
}
|
||||
|
||||
public static String FormatStringAll(String string) {
|
||||
String allFormated = Format.FormatString(string);
|
||||
allFormated = Format.FormatStringColor(allFormated);
|
||||
return allFormated;
|
||||
}
|
||||
|
||||
public static String FormatPlayerName(String playerPrefix, String playerDisplayName, String playerSuffix) {
|
||||
playerPrefix = chatColorPattern.matcher(playerPrefix).replaceAll("\u00A7$1");
|
||||
playerPrefix = chatMagicPattern.matcher(playerPrefix).replaceAll("\u00A7$1");
|
||||
playerPrefix = chatBoldPattern.matcher(playerPrefix).replaceAll("\u00A7$1");
|
||||
playerPrefix = chatStrikethroughPattern.matcher(playerPrefix).replaceAll("\u00A7$1");
|
||||
playerPrefix = chatUnderlinePattern.matcher(playerPrefix).replaceAll("\u00A7$1");
|
||||
playerPrefix = chatItalicPattern.matcher(playerPrefix).replaceAll("\u00A7$1");
|
||||
playerPrefix = chatResetPattern.matcher(playerPrefix).replaceAll("\u00A7$1");
|
||||
|
||||
playerSuffix = chatColorPattern.matcher(playerSuffix).replaceAll("\u00A7$1");
|
||||
playerSuffix = chatMagicPattern.matcher(playerSuffix).replaceAll("\u00A7$1");
|
||||
playerSuffix = chatBoldPattern.matcher(playerSuffix).replaceAll("\u00A7$1");
|
||||
playerSuffix = chatStrikethroughPattern.matcher(playerSuffix).replaceAll("\u00A7$1");
|
||||
playerSuffix = chatUnderlinePattern.matcher(playerSuffix).replaceAll("\u00A7$1");
|
||||
playerSuffix = chatItalicPattern.matcher(playerSuffix).replaceAll("\u00A7$1");
|
||||
playerSuffix = chatResetPattern.matcher(playerSuffix).replaceAll("\u00A7$1");
|
||||
return playerPrefix + playerDisplayName.trim() + playerSuffix;
|
||||
}
|
||||
|
||||
/**public static String FilterChat(String msg) {
|
||||
int t = 0;
|
||||
List<String> filters = plugin.getConfig().getStringList("filters");
|
||||
for(String s : filters) {
|
||||
t = 0;
|
||||
String[] pparse = new String[2];
|
||||
pparse[0] = " ";
|
||||
pparse[1] = " ";
|
||||
StringTokenizer st = new StringTokenizer(s, ",");
|
||||
while(st.hasMoreTokens()) {
|
||||
if(t < 2) {
|
||||
pparse[t++] = st.nextToken();
|
||||
}
|
||||
}
|
||||
msg = msg.replaceAll("(?i)" + pparse[0], pparse[1]);
|
||||
}
|
||||
return msg;
|
||||
}*/
|
||||
|
||||
public static boolean isValidColor(String color) {
|
||||
Boolean bFound = false;
|
||||
for(ChatColor bkColors : ChatColor.values()) {
|
||||
if(color.equalsIgnoreCase(bkColors.name())) {
|
||||
bFound = true;
|
||||
}
|
||||
}
|
||||
return bFound;
|
||||
}
|
||||
|
||||
public static boolean isValidHexColor(String color) {
|
||||
Pattern pattern = Pattern.compile("(^#[0-9a-fA-F]{6}\\b)");
|
||||
Matcher matcher = pattern.matcher(color);
|
||||
return matcher.find();
|
||||
}
|
||||
|
||||
public static String convertHexColorCodeToBukkitColorCode(String color) {
|
||||
StringBuilder bukkitColorCode = new StringBuilder(BUKKIT_COLOR_CODE_PREFIX + BUKKIT_HEX_COLOR_CODE_PREFIX);
|
||||
for(int a = 1; a < color.length(); a++) {
|
||||
bukkitColorCode.append(BUKKIT_COLOR_CODE_PREFIX + color.charAt(a));
|
||||
}
|
||||
return bukkitColorCode.toString();
|
||||
}
|
||||
|
||||
public static String convertHexColorCodeStringToBukkitColorCodeString(String string) {
|
||||
Pattern pattern = Pattern.compile("(#[0-9a-fA-F]{6})");
|
||||
Matcher matcher = pattern.matcher(string);
|
||||
while(matcher.find()) {
|
||||
int indexStart = matcher.start();
|
||||
int indexEnd = matcher.end();
|
||||
String hexColor = string.substring(indexStart, indexEnd);
|
||||
String bukkitColor = convertHexColorCodeToBukkitColorCode(hexColor);
|
||||
string = string.replaceAll(hexColor, bukkitColor);
|
||||
matcher.reset(string);
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
public static String escapeAllRegex(String input) {
|
||||
return input.replace("[", "\\[").replace("]", "\\]").replace("{", "\\{").replace("}", "\\}").replace("(", "\\(").replace(")", "\\)").replace("|", "\\|").replace("+", "\\+").replace("*", "\\*");
|
||||
}
|
||||
|
||||
/**public static boolean underlineURLs() {
|
||||
return plugin.getConfig().getBoolean("underlineurls", true);
|
||||
}*/
|
||||
public static final char colorChar = '\u00a7';
|
||||
//code taken from bukkit, so it can work on bungee too
|
||||
public static String color(String textToTranslate){
|
||||
if (textToTranslate == null) return null;
|
||||
if (!textToTranslate.contains("&")) return textToTranslate;
|
||||
char[] b = textToTranslate.toCharArray();
|
||||
for (int i = 0; i < b.length - 1; i++) {
|
||||
if ((b[i] == '&') && ("0123456789AaBbCcDdEeFfKkLlMmNnOoRr".indexOf(b[(i + 1)]) > -1)){
|
||||
b[i] = colorChar;
|
||||
b[(i + 1)] = Character.toLowerCase(b[(i + 1)]);
|
||||
}
|
||||
}
|
||||
return new String(b);
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package com.github.joelgodofwar.mmh.util;
|
||||
|
||||
import org.apache.commons.lang.math.NumberUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public class GetMCVersion {
|
||||
private String Version;
|
||||
private int Major;
|
||||
private int Minor;
|
||||
private int Patch;
|
||||
private int Build;
|
||||
public GetMCVersion(){
|
||||
Version = Bukkit.getVersion();
|
||||
Version = Version.substring(Version.indexOf("MC: "), Version.length()).replace("MC: ", "").replace(")", "");
|
||||
String[] strArray = Version.split(".");
|
||||
Major = NumberUtils.toInt(strArray[0]);
|
||||
Minor = NumberUtils.toInt(strArray[1]);
|
||||
Patch = NumberUtils.toInt(strArray[2], 0);
|
||||
}
|
||||
|
||||
public String VERSION(){
|
||||
return Version;
|
||||
}
|
||||
public int MAJOR(){
|
||||
return Major;
|
||||
}
|
||||
public int MINOR(){
|
||||
return Minor;
|
||||
}
|
||||
public int PATCH(){
|
||||
return Patch;
|
||||
}
|
||||
public int BUILD(){
|
||||
return Build;
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
package com.github.joelgodofwar.mmh.util;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 p000ison
|
||||
*
|
||||
* This work is licensed under the Creative Commons
|
||||
* Attribution-NonCommercial-NoDerivs 3.0 Unported License. To view a copy of
|
||||
* this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/ or send
|
||||
* a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco,
|
||||
* California, 94105, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.FileHandler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.SimpleFormatter;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* This should be get initialised when the plugin loads (It contains the Logging
|
||||
* system)
|
||||
*
|
||||
* @author Max
|
||||
*/
|
||||
public class Logging
|
||||
{
|
||||
|
||||
private static Logger log;
|
||||
private static final Logger debugLogger = Logger.getLogger("Logging");
|
||||
private FileHandler debugFileHandler;
|
||||
|
||||
/**
|
||||
* Gets the logger for your plugin
|
||||
*
|
||||
* @param plugin The plugin to apply
|
||||
*/
|
||||
public Logging(Plugin plugin)
|
||||
{
|
||||
|
||||
log = plugin.getLogger();
|
||||
|
||||
try {
|
||||
|
||||
debugFileHandler = new FileHandler(plugin.getDataFolder().getAbsolutePath() + File.pathSeparator + plugin.getName() + ".log", true);
|
||||
SimpleFormatter formatter = new SimpleFormatter();
|
||||
|
||||
debugLogger.addHandler(debugFileHandler);
|
||||
debugFileHandler.setFormatter(formatter);
|
||||
|
||||
} catch (IOException ex) {
|
||||
debug(null, ex, false);
|
||||
} catch (SecurityException ex) {
|
||||
debug(null, ex, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a message
|
||||
*
|
||||
* @param level The level to log
|
||||
* @param msg The message to log
|
||||
* @param toFile log to own log?
|
||||
*/
|
||||
public static void debug(Level level, String msg, boolean toFile){
|
||||
if (toFile) {
|
||||
if (debugLogger != null) {
|
||||
debugLogger.log(level, msg);
|
||||
}
|
||||
}
|
||||
log.log(level, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a Exception
|
||||
*
|
||||
* @param msg The message to log
|
||||
* @param exception the exception
|
||||
* @param toFile log to own log?
|
||||
*/
|
||||
public static void debug(String msg, Throwable exception, boolean toFile){
|
||||
if (toFile) {
|
||||
if (debugLogger != null) {
|
||||
debugLogger.log(Level.SEVERE, msg, exception);
|
||||
}
|
||||
}
|
||||
log.log(Level.SEVERE, msg, exception);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,848 +0,0 @@
|
||||
package com.github.joelgodofwar.mmh.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class Metrics {
|
||||
|
||||
private final Plugin plugin;
|
||||
|
||||
private final MetricsBase metricsBase;
|
||||
|
||||
/**
|
||||
* Creates a new Metrics instance.
|
||||
*
|
||||
* @param plugin Your plugin instance.
|
||||
* @param serviceId The id of the service. It can be found at <a
|
||||
* href="https://bstats.org/what-is-my-plugin-id">What is my plugin id?</a>
|
||||
*/
|
||||
public Metrics(JavaPlugin plugin, int serviceId) {
|
||||
this.plugin = plugin;
|
||||
// Get the config file
|
||||
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
|
||||
File configFile = new File(bStatsFolder, "config.yml");
|
||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
|
||||
if (!config.isSet("serverUuid")) {
|
||||
config.addDefault("enabled", true);
|
||||
config.addDefault("serverUuid", UUID.randomUUID().toString());
|
||||
config.addDefault("logFailedRequests", false);
|
||||
config.addDefault("logSentData", false);
|
||||
config.addDefault("logResponseStatusText", false);
|
||||
// Inform the server owners about bStats
|
||||
config
|
||||
.options()
|
||||
.header(
|
||||
"bStats (https://bStats.org) collects some basic information for plugin authors, like how\n"
|
||||
+ "many people use their plugin and their total player count. It's recommended to keep bStats\n"
|
||||
+ "enabled, but if you're not comfortable with this, you can turn this setting off. There is no\n"
|
||||
+ "performance penalty associated with having metrics enabled, and data sent to bStats is fully\n"
|
||||
+ "anonymous.")
|
||||
.copyDefaults(true);
|
||||
try {
|
||||
config.save(configFile);
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
// Load the data
|
||||
boolean enabled = config.getBoolean("enabled", true);
|
||||
String serverUUID = config.getString("serverUuid");
|
||||
boolean logErrors = config.getBoolean("logFailedRequests", false);
|
||||
boolean logSentData = config.getBoolean("logSentData", false);
|
||||
boolean logResponseStatusText = config.getBoolean("logResponseStatusText", false);
|
||||
metricsBase =
|
||||
new MetricsBase(
|
||||
"bukkit",
|
||||
serverUUID,
|
||||
serviceId,
|
||||
enabled,
|
||||
this::appendPlatformData,
|
||||
this::appendServiceData,
|
||||
submitDataTask -> Bukkit.getScheduler().runTask(plugin, submitDataTask),
|
||||
plugin::isEnabled,
|
||||
(message, error) -> this.plugin.getLogger().log(Level.WARNING, message, error),
|
||||
(message) -> this.plugin.getLogger().log(Level.INFO, message),
|
||||
logErrors,
|
||||
logSentData,
|
||||
logResponseStatusText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a custom chart.
|
||||
*
|
||||
* @param chart The chart to add.
|
||||
*/
|
||||
public void addCustomChart(CustomChart chart) {
|
||||
metricsBase.addCustomChart(chart);
|
||||
}
|
||||
|
||||
private void appendPlatformData(JsonObjectBuilder builder) {
|
||||
builder.appendField("playerAmount", getPlayerAmount());
|
||||
builder.appendField("onlineMode", Bukkit.getOnlineMode() ? 1 : 0);
|
||||
builder.appendField("bukkitVersion", Bukkit.getVersion());
|
||||
builder.appendField("bukkitName", Bukkit.getName());
|
||||
builder.appendField("javaVersion", System.getProperty("java.version"));
|
||||
builder.appendField("osName", System.getProperty("os.name"));
|
||||
builder.appendField("osArch", System.getProperty("os.arch"));
|
||||
builder.appendField("osVersion", System.getProperty("os.version"));
|
||||
builder.appendField("coreCount", Runtime.getRuntime().availableProcessors());
|
||||
}
|
||||
|
||||
private void appendServiceData(JsonObjectBuilder builder) {
|
||||
builder.appendField("pluginVersion", plugin.getDescription().getVersion());
|
||||
}
|
||||
|
||||
private int getPlayerAmount() {
|
||||
try {
|
||||
// Around MC 1.8 the return type was changed from an array to a collection,
|
||||
// This fixes java.lang.NoSuchMethodError:
|
||||
// org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
|
||||
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
|
||||
return onlinePlayersMethod.getReturnType().equals(Collection.class)
|
||||
? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size()
|
||||
: ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length;
|
||||
} catch (Exception e) {
|
||||
// Just use the new method if the reflection failed
|
||||
return Bukkit.getOnlinePlayers().size();
|
||||
}
|
||||
}
|
||||
|
||||
public static class MetricsBase {
|
||||
|
||||
/** The version of the Metrics class. */
|
||||
public static final String METRICS_VERSION = "2.2.1";
|
||||
|
||||
private static final ScheduledExecutorService scheduler =
|
||||
Executors.newScheduledThreadPool(1, task -> new Thread(task, "bStats-Metrics"));
|
||||
|
||||
private static final String REPORT_URL = "https://bStats.org/api/v2/data/%s";
|
||||
|
||||
private final String platform;
|
||||
|
||||
private final String serverUuid;
|
||||
|
||||
private final int serviceId;
|
||||
|
||||
private final Consumer<JsonObjectBuilder> appendPlatformDataConsumer;
|
||||
|
||||
private final Consumer<JsonObjectBuilder> appendServiceDataConsumer;
|
||||
|
||||
private final Consumer<Runnable> submitTaskConsumer;
|
||||
|
||||
private final Supplier<Boolean> checkServiceEnabledSupplier;
|
||||
|
||||
private final BiConsumer<String, Throwable> errorLogger;
|
||||
|
||||
private final Consumer<String> infoLogger;
|
||||
|
||||
private final boolean logErrors;
|
||||
|
||||
private final boolean logSentData;
|
||||
|
||||
private final boolean logResponseStatusText;
|
||||
|
||||
private final Set<CustomChart> customCharts = new HashSet<>();
|
||||
|
||||
private final boolean enabled;
|
||||
|
||||
/**
|
||||
* Creates a new MetricsBase class instance.
|
||||
*
|
||||
* @param platform The platform of the service.
|
||||
* @param serviceId The id of the service.
|
||||
* @param serverUuid The server uuid.
|
||||
* @param enabled Whether or not data sending is enabled.
|
||||
* @param appendPlatformDataConsumer A consumer that receives a {@code JsonObjectBuilder} and
|
||||
* appends all platform-specific data.
|
||||
* @param appendServiceDataConsumer A consumer that receives a {@code JsonObjectBuilder} and
|
||||
* appends all service-specific data.
|
||||
* @param submitTaskConsumer A consumer that takes a runnable with the submit task. This can be
|
||||
* used to delegate the data collection to a another thread to prevent errors caused by
|
||||
* concurrency. Can be {@code null}.
|
||||
* @param checkServiceEnabledSupplier A supplier to check if the service is still enabled.
|
||||
* @param errorLogger A consumer that accepts log message and an error.
|
||||
* @param infoLogger A consumer that accepts info log messages.
|
||||
* @param logErrors Whether or not errors should be logged.
|
||||
* @param logSentData Whether or not the sent data should be logged.
|
||||
* @param logResponseStatusText Whether or not the response status text should be logged.
|
||||
*/
|
||||
public MetricsBase(
|
||||
String platform,
|
||||
String serverUuid,
|
||||
int serviceId,
|
||||
boolean enabled,
|
||||
Consumer<JsonObjectBuilder> appendPlatformDataConsumer,
|
||||
Consumer<JsonObjectBuilder> appendServiceDataConsumer,
|
||||
Consumer<Runnable> submitTaskConsumer,
|
||||
Supplier<Boolean> checkServiceEnabledSupplier,
|
||||
BiConsumer<String, Throwable> errorLogger,
|
||||
Consumer<String> infoLogger,
|
||||
boolean logErrors,
|
||||
boolean logSentData,
|
||||
boolean logResponseStatusText) {
|
||||
this.platform = platform;
|
||||
this.serverUuid = serverUuid;
|
||||
this.serviceId = serviceId;
|
||||
this.enabled = enabled;
|
||||
this.appendPlatformDataConsumer = appendPlatformDataConsumer;
|
||||
this.appendServiceDataConsumer = appendServiceDataConsumer;
|
||||
this.submitTaskConsumer = submitTaskConsumer;
|
||||
this.checkServiceEnabledSupplier = checkServiceEnabledSupplier;
|
||||
this.errorLogger = errorLogger;
|
||||
this.infoLogger = infoLogger;
|
||||
this.logErrors = logErrors;
|
||||
this.logSentData = logSentData;
|
||||
this.logResponseStatusText = logResponseStatusText;
|
||||
checkRelocation();
|
||||
if (enabled) {
|
||||
startSubmitting();
|
||||
}
|
||||
}
|
||||
|
||||
public void addCustomChart(CustomChart chart) {
|
||||
this.customCharts.add(chart);
|
||||
}
|
||||
|
||||
private void startSubmitting() {
|
||||
final Runnable submitTask =
|
||||
() -> {
|
||||
if (!enabled || !checkServiceEnabledSupplier.get()) {
|
||||
// Submitting data or service is disabled
|
||||
scheduler.shutdown();
|
||||
return;
|
||||
}
|
||||
if (submitTaskConsumer != null) {
|
||||
submitTaskConsumer.accept(this::submitData);
|
||||
} else {
|
||||
this.submitData();
|
||||
}
|
||||
};
|
||||
// Many servers tend to restart at a fixed time at xx:00 which causes an uneven distribution
|
||||
// of requests on the
|
||||
// bStats backend. To circumvent this problem, we introduce some randomness into the initial
|
||||
// and second delay.
|
||||
// WARNING: You must not modify and part of this Metrics class, including the submit delay or
|
||||
// frequency!
|
||||
// WARNING: Modifying this code will get your plugin banned on bStats. Just don't do it!
|
||||
long initialDelay = (long) (1000 * 60 * (3 + Math.random() * 3));
|
||||
long secondDelay = (long) (1000 * 60 * (Math.random() * 30));
|
||||
scheduler.schedule(submitTask, initialDelay, TimeUnit.MILLISECONDS);
|
||||
scheduler.scheduleAtFixedRate(
|
||||
submitTask, initialDelay + secondDelay, 1000 * 60 * 30, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void submitData() {
|
||||
final JsonObjectBuilder baseJsonBuilder = new JsonObjectBuilder();
|
||||
appendPlatformDataConsumer.accept(baseJsonBuilder);
|
||||
final JsonObjectBuilder serviceJsonBuilder = new JsonObjectBuilder();
|
||||
appendServiceDataConsumer.accept(serviceJsonBuilder);
|
||||
JsonObjectBuilder.JsonObject[] chartData =
|
||||
customCharts.stream()
|
||||
.map(customChart -> customChart.getRequestJsonObject(errorLogger, logErrors))
|
||||
.filter(Objects::nonNull)
|
||||
.toArray(JsonObjectBuilder.JsonObject[]::new);
|
||||
serviceJsonBuilder.appendField("id", serviceId);
|
||||
serviceJsonBuilder.appendField("customCharts", chartData);
|
||||
baseJsonBuilder.appendField("service", serviceJsonBuilder.build());
|
||||
baseJsonBuilder.appendField("serverUUID", serverUuid);
|
||||
baseJsonBuilder.appendField("metricsVersion", METRICS_VERSION);
|
||||
JsonObjectBuilder.JsonObject data = baseJsonBuilder.build();
|
||||
scheduler.execute(
|
||||
() -> {
|
||||
try {
|
||||
// Send the data
|
||||
sendData(data);
|
||||
} catch (Exception e) {
|
||||
// Something went wrong! :(
|
||||
if (logErrors) {
|
||||
errorLogger.accept("Could not submit bStats metrics data", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void sendData(JsonObjectBuilder.JsonObject data) throws Exception {
|
||||
if (logSentData) {
|
||||
infoLogger.accept("Sent bStats metrics data: " + data.toString());
|
||||
}
|
||||
String url = String.format(REPORT_URL, platform);
|
||||
HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
|
||||
// Compress the data to save bandwidth
|
||||
byte[] compressedData = compress(data.toString());
|
||||
connection.setRequestMethod("POST");
|
||||
connection.addRequestProperty("Accept", "application/json");
|
||||
connection.addRequestProperty("Connection", "close");
|
||||
connection.addRequestProperty("Content-Encoding", "gzip");
|
||||
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
|
||||
connection.setRequestProperty("Content-Type", "application/json");
|
||||
connection.setRequestProperty("User-Agent", "Metrics-Service/1");
|
||||
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) {
|
||||
infoLogger.accept("Sent data to bStats and received response: " + builder);
|
||||
}
|
||||
}
|
||||
|
||||
/** Checks that the class was properly relocated. */
|
||||
private void checkRelocation() {
|
||||
// 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'});
|
||||
final String examplePackage =
|
||||
new String(new byte[] {'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
|
||||
// We want to make sure no one just copy & pastes the example and uses the wrong package
|
||||
// names
|
||||
if (MetricsBase.class.getPackage().getName().startsWith(defaultPackage)
|
||||
|| MetricsBase.class.getPackage().getName().startsWith(examplePackage)) {
|
||||
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gzips the given string.
|
||||
*
|
||||
* @param str The string to gzip.
|
||||
* @return The gzipped string.
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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 JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||
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) {
|
||||
// Skip this invalid
|
||||
continue;
|
||||
}
|
||||
allSkipped = false;
|
||||
valuesBuilder.appendField(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
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 JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||
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()) {
|
||||
valuesBuilder.appendField(entry.getKey(), new int[] {entry.getValue()});
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
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 JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||
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) {
|
||||
// Skip this invalid
|
||||
continue;
|
||||
}
|
||||
allSkipped = false;
|
||||
valuesBuilder.appendField(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
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 JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||
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) {
|
||||
// Skip this invalid
|
||||
continue;
|
||||
}
|
||||
allSkipped = false;
|
||||
valuesBuilder.appendField(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class CustomChart {
|
||||
|
||||
private final String chartId;
|
||||
|
||||
protected CustomChart(String chartId) {
|
||||
if (chartId == null) {
|
||||
throw new IllegalArgumentException("chartId must not be null");
|
||||
}
|
||||
this.chartId = chartId;
|
||||
}
|
||||
|
||||
public JsonObjectBuilder.JsonObject getRequestJsonObject(
|
||||
BiConsumer<String, Throwable> errorLogger, boolean logErrors) {
|
||||
JsonObjectBuilder builder = new JsonObjectBuilder();
|
||||
builder.appendField("chartId", chartId);
|
||||
try {
|
||||
JsonObjectBuilder.JsonObject data = getChartData();
|
||||
if (data == null) {
|
||||
// If the data is null we don't send the chart.
|
||||
return null;
|
||||
}
|
||||
builder.appendField("data", data);
|
||||
} catch (Throwable t) {
|
||||
if (logErrors) {
|
||||
errorLogger.accept("Failed to get data for custom chart with id " + chartId, t);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
protected abstract JsonObjectBuilder.JsonObject getChartData() throws Exception;
|
||||
}
|
||||
|
||||
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 JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
int value = callable.call();
|
||||
if (value == 0) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("value", value).build();
|
||||
}
|
||||
}
|
||||
|
||||
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 JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
String value = callable.call();
|
||||
if (value == null || value.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("value", value).build();
|
||||
}
|
||||
}
|
||||
|
||||
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 JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||
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()) {
|
||||
JsonObjectBuilder valueBuilder = new JsonObjectBuilder();
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
|
||||
valueBuilder.appendField(valueEntry.getKey(), valueEntry.getValue());
|
||||
allSkipped = false;
|
||||
}
|
||||
if (!allSkipped) {
|
||||
reallyAllSkipped = false;
|
||||
valuesBuilder.appendField(entryValues.getKey(), valueBuilder.build());
|
||||
}
|
||||
}
|
||||
if (reallyAllSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An extremely simple JSON builder.
|
||||
*
|
||||
* <p>While this class is neither feature-rich nor the most performant one, it's sufficient enough
|
||||
* for its use-case.
|
||||
*/
|
||||
public static class JsonObjectBuilder {
|
||||
|
||||
private StringBuilder builder = new StringBuilder();
|
||||
|
||||
private boolean hasAtLeastOneField = false;
|
||||
|
||||
public JsonObjectBuilder() {
|
||||
builder.append("{");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a null field to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendNull(String key) {
|
||||
appendFieldUnescaped(key, "null");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a string field to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param value The value of the field.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, String value) {
|
||||
if (value == null) {
|
||||
throw new IllegalArgumentException("JSON value must not be null");
|
||||
}
|
||||
appendFieldUnescaped(key, "\"" + escape(value) + "\"");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends an integer field to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param value The value of the field.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, int value) {
|
||||
appendFieldUnescaped(key, String.valueOf(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends an object to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param object The object.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, JsonObject object) {
|
||||
if (object == null) {
|
||||
throw new IllegalArgumentException("JSON object must not be null");
|
||||
}
|
||||
appendFieldUnescaped(key, object.toString());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a string array to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param values The string array.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, String[] values) {
|
||||
if (values == null) {
|
||||
throw new IllegalArgumentException("JSON values must not be null");
|
||||
}
|
||||
String escapedValues =
|
||||
Arrays.stream(values)
|
||||
.map(value -> "\"" + escape(value) + "\"")
|
||||
.collect(Collectors.joining(","));
|
||||
appendFieldUnescaped(key, "[" + escapedValues + "]");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends an integer array to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param values The integer array.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, int[] values) {
|
||||
if (values == null) {
|
||||
throw new IllegalArgumentException("JSON values must not be null");
|
||||
}
|
||||
String escapedValues =
|
||||
Arrays.stream(values).mapToObj(String::valueOf).collect(Collectors.joining(","));
|
||||
appendFieldUnescaped(key, "[" + escapedValues + "]");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends an object array to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param values The integer array.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, JsonObject[] values) {
|
||||
if (values == null) {
|
||||
throw new IllegalArgumentException("JSON values must not be null");
|
||||
}
|
||||
String escapedValues =
|
||||
Arrays.stream(values).map(JsonObject::toString).collect(Collectors.joining(","));
|
||||
appendFieldUnescaped(key, "[" + escapedValues + "]");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a field to the object.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param escapedValue The escaped value of the field.
|
||||
*/
|
||||
private void appendFieldUnescaped(String key, String escapedValue) {
|
||||
if (builder == null) {
|
||||
throw new IllegalStateException("JSON has already been built");
|
||||
}
|
||||
if (key == null) {
|
||||
throw new IllegalArgumentException("JSON key must not be null");
|
||||
}
|
||||
if (hasAtLeastOneField) {
|
||||
builder.append(",");
|
||||
}
|
||||
builder.append("\"").append(escape(key)).append("\":").append(escapedValue);
|
||||
hasAtLeastOneField = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the JSON string and invalidates this builder.
|
||||
*
|
||||
* @return The built JSON string.
|
||||
*/
|
||||
public JsonObject build() {
|
||||
if (builder == null) {
|
||||
throw new IllegalStateException("JSON has already been built");
|
||||
}
|
||||
JsonObject object = new JsonObject(builder.append("}").toString());
|
||||
builder = null;
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes the given string like stated in https://www.ietf.org/rfc/rfc4627.txt.
|
||||
*
|
||||
* <p>This method escapes only the necessary characters '"', '\'. and '\u0000' - '\u001F'.
|
||||
* Compact escapes are not used (e.g., '\n' is escaped as "\u000a" and not as "\n").
|
||||
*
|
||||
* @param value The value to escape.
|
||||
* @return The escaped value.
|
||||
*/
|
||||
private static String escape(String value) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < value.length(); i++) {
|
||||
char c = value.charAt(i);
|
||||
if (c == '"') {
|
||||
builder.append("\\\"");
|
||||
} else if (c == '\\') {
|
||||
builder.append("\\\\");
|
||||
} else if (c <= '\u000F') {
|
||||
builder.append("\\u000").append(Integer.toHexString(c));
|
||||
} else if (c <= '\u001F') {
|
||||
builder.append("\\u00").append(Integer.toHexString(c));
|
||||
} else {
|
||||
builder.append(c);
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* A super simple representation of a JSON object.
|
||||
*
|
||||
* <p>This class only exists to make methods of the {@link JsonObjectBuilder} type-safe and not
|
||||
* allow a raw string inputs for methods like {@link JsonObjectBuilder#appendField(String,
|
||||
* JsonObject)}.
|
||||
*/
|
||||
public static class JsonObject {
|
||||
|
||||
private final String value;
|
||||
|
||||
private JsonObject(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,732 +0,0 @@
|
||||
package com.github.joelgodofwar.mmh.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
/**
|
||||
* bStats collects some data for plugin authors.
|
||||
* <p>
|
||||
* Check out https://bStats.org/ to learn more about bStats!
|
||||
*/
|
||||
//@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
public class Metrics2 {
|
||||
|
||||
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', 'k', 'k', 'i', 't'});
|
||||
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 (Metrics2.class.getPackage().getName().equals(defaultPackage) || Metrics2.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/bukkit";
|
||||
|
||||
// Is bStats enabled on this server?
|
||||
private boolean enabled;
|
||||
|
||||
// Should failed requests be logged?
|
||||
private static boolean logFailedRequests;
|
||||
|
||||
// Should the sent data be logged?
|
||||
private static boolean logSentData;
|
||||
|
||||
// Should the response text be logged?
|
||||
private static boolean logResponseStatusText;
|
||||
|
||||
// The uuid of the server
|
||||
private static String serverUUID;
|
||||
|
||||
// The plugin
|
||||
private final Plugin plugin;
|
||||
|
||||
// A list with all custom charts
|
||||
private final List<CustomChart> charts = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param plugin The plugin which stats should be submitted.
|
||||
*/
|
||||
public Metrics2(Plugin plugin) {
|
||||
if (plugin == null) {
|
||||
throw new IllegalArgumentException("Plugin cannot be null!");
|
||||
}
|
||||
this.plugin = plugin;
|
||||
|
||||
// Get the config file
|
||||
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
|
||||
File configFile = new File(bStatsFolder, "config.yml");
|
||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
|
||||
|
||||
// Check if the config file exists
|
||||
if (!config.isSet("serverUuid")) {
|
||||
|
||||
// Add default values
|
||||
config.addDefault("enabled", true);
|
||||
// Every server gets it's unique random id.
|
||||
config.addDefault("serverUuid", UUID.randomUUID().toString());
|
||||
// Should failed request be logged?
|
||||
config.addDefault("logFailedRequests", false);
|
||||
// Should the sent data be logged?
|
||||
config.addDefault("logSentData", false);
|
||||
// Should the response text be logged?
|
||||
config.addDefault("logResponseStatusText", false);
|
||||
|
||||
// Inform the server owners about bStats
|
||||
config.options().header(
|
||||
"bStats collects some data for plugin authors like how many servers are using their plugins.\n" +
|
||||
"To honor their work, you should not disable it.\n" +
|
||||
"This has nearly no effect on the server performance!\n" +
|
||||
"Check out https://bStats.org/ to learn more :)"
|
||||
).copyDefaults(true);
|
||||
try {
|
||||
config.save(configFile);
|
||||
} catch (IOException ignored) { }
|
||||
}
|
||||
|
||||
// Load the data
|
||||
enabled = config.getBoolean("enabled", true);
|
||||
serverUUID = config.getString("serverUuid");
|
||||
logFailedRequests = config.getBoolean("logFailedRequests", false);
|
||||
logSentData = config.getBoolean("logSentData", false);
|
||||
logResponseStatusText = config.getBoolean("logResponseStatusText", false);
|
||||
|
||||
if (enabled) {
|
||||
boolean found = false;
|
||||
// Search for all other bStats Metrics classes to see if we are the first one
|
||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||
try {
|
||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||
found = true; // We aren't the first
|
||||
break;
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
}
|
||||
// Register our service
|
||||
Bukkit.getServicesManager().register(Metrics2.class, this, plugin, ServicePriority.Normal);
|
||||
if (!found) {
|
||||
// We are the first!
|
||||
startSubmitting();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
throw new IllegalArgumentException("Chart cannot be null!");
|
||||
}
|
||||
charts.add(chart);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the Scheduler which submits our data every 30 minutes.
|
||||
*/
|
||||
private void startSubmitting() {
|
||||
final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags
|
||||
timer.scheduleAtFixedRate(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!plugin.isEnabled()) { // Plugin was disabled
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
// Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler
|
||||
// Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;)
|
||||
Bukkit.getScheduler().runTask(plugin, () -> submitData());
|
||||
}
|
||||
}, 1000 * 60 * 5, 1000 * 60 * 30);
|
||||
// Submit the data every 30 minutes, first time after 5 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 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); // Append the name of the plugin
|
||||
data.addProperty("pluginVersion", pluginVersion); // Append the version of the plugin
|
||||
JsonArray customCharts = new JsonArray();
|
||||
for (CustomChart customChart : charts) {
|
||||
// Add the data of the custom charts
|
||||
JsonObject chart = customChart.getRequestJsonObject();
|
||||
if (chart == null) { // If the chart is null, we skip it
|
||||
continue;
|
||||
}
|
||||
customCharts.add(chart);
|
||||
}
|
||||
data.add("customCharts", customCharts);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the server specific data.
|
||||
*
|
||||
* @return The server specific data.
|
||||
*/
|
||||
private JsonObject getServerData() {
|
||||
// Minecraft specific data
|
||||
int playerAmount;
|
||||
try {
|
||||
// Around MC 1.8 the return type was changed to a collection from an array,
|
||||
// This fixes java.lang.NoSuchMethodError: org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
|
||||
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
|
||||
playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class)
|
||||
? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size()
|
||||
: ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length;
|
||||
} catch (Exception e) {
|
||||
playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed
|
||||
}
|
||||
int onlineMode = Bukkit.getOnlineMode() ? 1 : 0;
|
||||
String bukkitVersion = Bukkit.getVersion();
|
||||
String bukkitName = Bukkit.getName();
|
||||
|
||||
// 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("onlineMode", onlineMode);
|
||||
data.addProperty("bukkitVersion", bukkitVersion);
|
||||
data.addProperty("bukkitName", bukkitName);
|
||||
|
||||
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();
|
||||
|
||||
JsonArray pluginData = new JsonArray();
|
||||
// Search for all other bStats Metrics classes to get their plugin data
|
||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||
try {
|
||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||
|
||||
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
|
||||
try {
|
||||
Object plugin = provider.getService().getMethod("getPluginData").invoke(provider.getProvider());
|
||||
if (plugin instanceof JsonObject) {
|
||||
pluginData.add((JsonObject) plugin);
|
||||
} else { // old bstats version compatibility
|
||||
try {
|
||||
Class<?> jsonObjectJsonSimple = Class.forName("org.json.simple.JSONObject");
|
||||
if (plugin.getClass().isAssignableFrom(jsonObjectJsonSimple)) {
|
||||
Method jsonStringGetter = jsonObjectJsonSimple.getDeclaredMethod("toJSONString");
|
||||
jsonStringGetter.setAccessible(true);
|
||||
String jsonString = (String) jsonStringGetter.invoke(plugin);
|
||||
JsonObject object = new JsonParser().parse(jsonString).getAsJsonObject();
|
||||
pluginData.add(object);
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
// minecraft version 1.14+
|
||||
if (logFailedRequests) {
|
||||
this.plugin.getLogger().log(Level.SEVERE, "Encountered unexpected exception", e);
|
||||
}
|
||||
continue; // continue looping since we cannot do any other thing.
|
||||
}
|
||||
}
|
||||
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { }
|
||||
}
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
}
|
||||
|
||||
data.add("plugins", pluginData);
|
||||
|
||||
// Create a new thread for the connection to the bStats server
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
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 of " + plugin.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 (Bukkit.isPrimaryThread()) {
|
||||
throw new IllegalAccessException("This method must not be called from the main thread!");
|
||||
}
|
||||
if (logSentData) {
|
||||
plugin.getLogger().info("Sending data to bStats: " + data.toString());
|
||||
}
|
||||
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);
|
||||
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
|
||||
outputStream.write(compressedData);
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
String line;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
builder.append(line);
|
||||
}
|
||||
bufferedReader.close();
|
||||
if (logResponseStatusText) {
|
||||
plugin.getLogger().info("Sent data to bStats and received response: " + builder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
|
||||
gzip.write(str.getBytes(StandardCharsets.UTF_8));
|
||||
gzip.close();
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom chart.
|
||||
*/
|
||||
public static abstract class CustomChart {
|
||||
|
||||
// The id of the chart
|
||||
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() {
|
||||
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) {
|
||||
Bukkit.getLogger().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(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(categoryValue);
|
||||
}
|
||||
values.add(entry.getKey(), categoryValues);
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.add("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,445 +0,0 @@
|
||||
package com.github.joelgodofwar.mmh.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import com.google.common.collect.ComparisonChain;
|
||||
import com.google.common.collect.Ordering;
|
||||
|
||||
/**
|
||||
* Determine the current Minecraft version.
|
||||
*
|
||||
* @author Kristian
|
||||
*/
|
||||
public final class MinecraftVersion implements Comparable<MinecraftVersion>, Serializable {
|
||||
/**
|
||||
* The minimum version ProtocolLib has been tested with.
|
||||
*/
|
||||
public static final String MINIMUM_MINECRAFT_VERSION = "1.20";
|
||||
|
||||
/**
|
||||
* The maximum version ProtocolLib has been tested with.
|
||||
*/
|
||||
public static final String MAXIMUM_MINECRAFT_VERSION = "1.20.4";
|
||||
|
||||
/**
|
||||
* The date (with ISO 8601 or YYYY-MM-DD) when the most recent version (1.20.4) was released.
|
||||
*/
|
||||
public static final String MINECRAFT_LAST_RELEASE_DATE = "2023-12-07";
|
||||
/**
|
||||
* Version 1.20.4 - the decorated pot update
|
||||
*/
|
||||
public static final MinecraftVersion v1_20_4 = new MinecraftVersion("1.20.4");
|
||||
|
||||
/**
|
||||
* Version 1.20.2 - the update that added the configuration protocol phase.
|
||||
*/
|
||||
public static final MinecraftVersion CONFIG_PHASE_PROTOCOL_UPDATE = new MinecraftVersion("1.20.2");
|
||||
/**
|
||||
* Version 1.20 - the trails and tails update
|
||||
*/
|
||||
public static final MinecraftVersion TRAILS_AND_TAILS = new MinecraftVersion("1.20");
|
||||
|
||||
/**
|
||||
* Version 1.19.4 - the rest of the feature preview
|
||||
*/
|
||||
public static final MinecraftVersion FEATURE_PREVIEW_2 = new MinecraftVersion("1.19.4");
|
||||
|
||||
/**
|
||||
* Version 1.19.3 - introducing feature preview
|
||||
*/
|
||||
public static final MinecraftVersion FEATURE_PREVIEW_UPDATE = new MinecraftVersion("1.19.3");
|
||||
/**
|
||||
* Version 1.19 - the wild update
|
||||
*/
|
||||
public static final MinecraftVersion WILD_UPDATE = new MinecraftVersion("1.19");
|
||||
/**
|
||||
* Version 1.18 - caves and cliffs part 2
|
||||
*/
|
||||
public static final MinecraftVersion CAVES_CLIFFS_2 = new MinecraftVersion("1.18");
|
||||
/**
|
||||
* Version 1.17 - caves and cliffs part 1
|
||||
*/
|
||||
public static final MinecraftVersion CAVES_CLIFFS_1 = new MinecraftVersion("1.17");
|
||||
/**
|
||||
* Version 1.16.4
|
||||
*/
|
||||
public static final MinecraftVersion NETHER_UPDATE_4 = new MinecraftVersion("1.16.4");
|
||||
/**
|
||||
* Version 1.16.2 - breaking change to the nether update
|
||||
*/
|
||||
public static final MinecraftVersion NETHER_UPDATE_2 = new MinecraftVersion("1.16.2");
|
||||
/**
|
||||
* Version 1.16.0 - the nether update
|
||||
*/
|
||||
public static final MinecraftVersion NETHER_UPDATE = new MinecraftVersion("1.16");
|
||||
/**
|
||||
* Version 1.15 - the bee update
|
||||
*/
|
||||
public static final MinecraftVersion BEE_UPDATE = new MinecraftVersion("1.15");
|
||||
/**
|
||||
* Version 1.14 - village and pillage update.
|
||||
*/
|
||||
public static final MinecraftVersion VILLAGE_UPDATE = new MinecraftVersion("1.14");
|
||||
/**
|
||||
* Version 1.13 - update aquatic.
|
||||
*/
|
||||
public static final MinecraftVersion AQUATIC_UPDATE = new MinecraftVersion("1.13");
|
||||
/**
|
||||
* Version 1.12 - the world of color update.
|
||||
*/
|
||||
public static final MinecraftVersion COLOR_UPDATE = new MinecraftVersion("1.12");
|
||||
/**
|
||||
* Version 1.11 - the exploration update.
|
||||
*/
|
||||
public static final MinecraftVersion EXPLORATION_UPDATE = new MinecraftVersion("1.11");
|
||||
/**
|
||||
* Version 1.10 - the frostburn update.
|
||||
*/
|
||||
public static final MinecraftVersion FROSTBURN_UPDATE = new MinecraftVersion("1.10");
|
||||
/**
|
||||
* Version 1.9 - the combat update.
|
||||
*/
|
||||
public static final MinecraftVersion COMBAT_UPDATE = new MinecraftVersion("1.9");
|
||||
/**
|
||||
* Version 1.8 - the "bountiful" update.
|
||||
*/
|
||||
public static final MinecraftVersion BOUNTIFUL_UPDATE = new MinecraftVersion("1.8");
|
||||
/**
|
||||
* Version 1.7.8 - the update that changed the skin format (and distribution - R.I.P. player disguise)
|
||||
*/
|
||||
public static final MinecraftVersion SKIN_UPDATE = new MinecraftVersion("1.7.8");
|
||||
/**
|
||||
* Version 1.7.2 - the update that changed the world.
|
||||
*/
|
||||
public static final MinecraftVersion WORLD_UPDATE = new MinecraftVersion("1.7.2");
|
||||
/**
|
||||
* Version 1.6.1 - the horse update.
|
||||
*/
|
||||
public static final MinecraftVersion HORSE_UPDATE = new MinecraftVersion("1.6.1");
|
||||
/**
|
||||
* Version 1.5.0 - the redstone update.
|
||||
*/
|
||||
public static final MinecraftVersion REDSTONE_UPDATE = new MinecraftVersion("1.5.0");
|
||||
/**
|
||||
* Version 1.4.2 - the scary update (Wither Boss).
|
||||
*/
|
||||
public static final MinecraftVersion SCARY_UPDATE = new MinecraftVersion("1.4.2");
|
||||
|
||||
/**
|
||||
* The latest release version of minecraft.
|
||||
*/
|
||||
public static final MinecraftVersion LATEST = v1_20_4;
|
||||
|
||||
// used when serializing
|
||||
private static final long serialVersionUID = -8695133558996459770L;
|
||||
|
||||
/**
|
||||
* Regular expression used to parse version strings.
|
||||
*/
|
||||
private static final Pattern VERSION_PATTERN = Pattern.compile(".*\\(.*MC.\\s*([a-zA-z0-9\\-.]+).*");
|
||||
|
||||
/**
|
||||
* The current version of minecraft, lazy initialized by MinecraftVersion.currentVersion()
|
||||
*/
|
||||
private static MinecraftVersion currentVersion;
|
||||
|
||||
private final int major;
|
||||
private final int minor;
|
||||
private final int build;
|
||||
// The development stage
|
||||
private final String development;
|
||||
|
||||
// Snapshot?
|
||||
private final SnapshotVersion snapshot;
|
||||
private volatile Boolean atCurrentOrAbove;
|
||||
|
||||
/**
|
||||
* Determine the current Minecraft version.
|
||||
*
|
||||
* @param server - the Bukkit server that will be used to examine the MC version.
|
||||
*/
|
||||
public MinecraftVersion(Server server) {
|
||||
this(extractVersion(server.getVersion()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a version object from the format major.minor.build, or the snapshot format.
|
||||
*
|
||||
* @param versionOnly - the version in text form.
|
||||
*/
|
||||
public MinecraftVersion(String versionOnly) {
|
||||
this(versionOnly, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a version format from the standard release version or the snapshot verison.
|
||||
*
|
||||
* @param versionOnly - the version.
|
||||
* @param parseSnapshot - TRUE to parse the snapshot, FALSE otherwise.
|
||||
*/
|
||||
private MinecraftVersion(String versionOnly, boolean parseSnapshot) {
|
||||
String[] section = versionOnly.split("-");
|
||||
SnapshotVersion snapshot = null;
|
||||
int[] numbers = new int[3];
|
||||
|
||||
try {
|
||||
numbers = this.parseVersion(section[0]);
|
||||
} catch (NumberFormatException cause) {
|
||||
// Skip snapshot parsing
|
||||
if (!parseSnapshot) {
|
||||
throw cause;
|
||||
}
|
||||
|
||||
try {
|
||||
// Determine if the snapshot is newer than the current release version
|
||||
snapshot = new SnapshotVersion(section[0]);
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
|
||||
|
||||
MinecraftVersion latest = new MinecraftVersion(MAXIMUM_MINECRAFT_VERSION, false);
|
||||
boolean newer = snapshot.getSnapshotDate().compareTo(
|
||||
format.parse(MINECRAFT_LAST_RELEASE_DATE)) > 0;
|
||||
|
||||
numbers[0] = latest.getMajor();
|
||||
numbers[1] = latest.getMinor() + (newer ? 1 : -1);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Cannot parse " + section[0], e);
|
||||
}
|
||||
}
|
||||
|
||||
this.major = numbers[0];
|
||||
this.minor = numbers[1];
|
||||
this.build = numbers[2];
|
||||
this.development = section.length > 1 ? section[1] : (snapshot != null ? "snapshot" : null);
|
||||
this.snapshot = snapshot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a version object directly.
|
||||
*
|
||||
* @param major - major version number.
|
||||
* @param minor - minor version number.
|
||||
* @param build - build version number.
|
||||
*/
|
||||
public MinecraftVersion(int major, int minor, int build) {
|
||||
this(major, minor, build, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a version object directly.
|
||||
*
|
||||
* @param major - major version number.
|
||||
* @param minor - minor version number.
|
||||
* @param build - build version number.
|
||||
* @param development - development stage.
|
||||
*/
|
||||
public MinecraftVersion(int major, int minor, int build, String development) {
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
this.build = build;
|
||||
this.development = development;
|
||||
this.snapshot = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the Minecraft version from CraftBukkit itself.
|
||||
*
|
||||
* @param text - the server version in text form.
|
||||
* @return The underlying MC version.
|
||||
* @throws IllegalStateException If we could not parse the version string.
|
||||
*/
|
||||
public static String extractVersion(String text) {
|
||||
Matcher version = VERSION_PATTERN.matcher(text);
|
||||
|
||||
if (version.matches() && (version.group(1) != null)) {
|
||||
return version.group(1);
|
||||
} else {
|
||||
throw new IllegalStateException("Cannot parse version String '" + text + "'");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given server version into a Minecraft version.
|
||||
*
|
||||
* @param serverVersion - the server version.
|
||||
* @return The resulting Minecraft version.
|
||||
*/
|
||||
public static MinecraftVersion fromServerVersion(String serverVersion) {
|
||||
return new MinecraftVersion(extractVersion(serverVersion));
|
||||
}
|
||||
|
||||
public static MinecraftVersion getCurrentVersion() {
|
||||
if (currentVersion == null) {
|
||||
currentVersion = fromServerVersion(Bukkit.getVersion());
|
||||
}
|
||||
|
||||
return currentVersion;
|
||||
}
|
||||
|
||||
public static void setCurrentVersion(MinecraftVersion version) {
|
||||
currentVersion = version;
|
||||
}
|
||||
|
||||
private static boolean atOrAbove(MinecraftVersion version) {
|
||||
return getCurrentVersion().isAtLeast(version);
|
||||
}
|
||||
|
||||
private int[] parseVersion(String version) {
|
||||
String[] elements = version.split("\\.");
|
||||
int[] numbers = new int[3];
|
||||
|
||||
// Make sure it's even a valid version
|
||||
if (elements.length < 1) {
|
||||
throw new IllegalStateException("Corrupt MC version: " + version);
|
||||
}
|
||||
|
||||
// The String 1 or 1.2 is interpreted as 1.0.0 and 1.2.0 respectively.
|
||||
for (int i = 0; i < Math.min(numbers.length, elements.length); i++) {
|
||||
numbers[i] = Integer.parseInt(elements[i].trim());
|
||||
}
|
||||
return numbers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Major version number
|
||||
*
|
||||
* @return Current major version number.
|
||||
*/
|
||||
public int getMajor() {
|
||||
return this.major;
|
||||
}
|
||||
|
||||
/**
|
||||
* Minor version number
|
||||
*
|
||||
* @return Current minor version number.
|
||||
*/
|
||||
public int getMinor() {
|
||||
return this.minor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build version number
|
||||
*
|
||||
* @return Current build version number.
|
||||
*/
|
||||
public int getBuild() {
|
||||
return this.build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the development stage.
|
||||
*
|
||||
* @return Development stage, or NULL if this is a release.
|
||||
*/
|
||||
public String getDevelopmentStage() {
|
||||
return this.development;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the snapshot version, or NULL if this is a release.
|
||||
*
|
||||
* @return The snapshot version.
|
||||
*/
|
||||
public SnapshotVersion getSnapshot() {
|
||||
return this.snapshot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if this version is a snapshot.
|
||||
*
|
||||
* @return The snapshot version.
|
||||
*/
|
||||
public boolean isSnapshot() {
|
||||
return this.snapshot != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this version is at or above the current version the server is running.
|
||||
*
|
||||
* @return true if this version is equal or newer than the server version, false otherwise.
|
||||
*/
|
||||
public boolean atOrAbove() {
|
||||
if (this.atCurrentOrAbove == null) {
|
||||
this.atCurrentOrAbove = atOrAbove(this);
|
||||
}
|
||||
|
||||
return this.atCurrentOrAbove;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the version String (major.minor.build) only.
|
||||
*
|
||||
* @return A normal version string.
|
||||
*/
|
||||
public String getVersion() {
|
||||
if (this.getDevelopmentStage() == null) {
|
||||
return String.format("%s.%s.%s", this.getMajor(), this.getMinor(), this.getBuild());
|
||||
} else {
|
||||
return String.format("%s.%s.%s-%s%s", this.getMajor(), this.getMinor(), this.getBuild(),
|
||||
this.getDevelopmentStage(), this.isSnapshot() ? this.snapshot : "");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(MinecraftVersion o) {
|
||||
if (o == null) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return ComparisonChain.start()
|
||||
.compare(this.getMajor(), o.getMajor())
|
||||
.compare(this.getMinor(), o.getMinor())
|
||||
.compare(this.getBuild(), o.getBuild())
|
||||
.compare(this.getDevelopmentStage(), o.getDevelopmentStage(), Ordering.natural().nullsLast())
|
||||
.compare(this.getSnapshot(), o.getSnapshot(), Ordering.natural().nullsFirst())
|
||||
.result();
|
||||
}
|
||||
|
||||
public boolean isAtLeast(MinecraftVersion other) {
|
||||
if (other == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.compareTo(other) >= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj instanceof MinecraftVersion) {
|
||||
MinecraftVersion other = (MinecraftVersion) obj;
|
||||
|
||||
return (this.getMajor() == other.getMajor()) &&
|
||||
(this.getMinor() == other.getMinor()) &&
|
||||
(this.getBuild() == other.getBuild()) &&
|
||||
Objects.equals(this.getDevelopmentStage(), other.getDevelopmentStage());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.getMajor(), this.getMinor(), this.getBuild());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
// Convert to a String that we can parse back again
|
||||
return String.format("(MC: %s)", this.getVersion());
|
||||
}
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
package com.github.joelgodofwar.mmh.util;
|
||||
import java.io.Serializable;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.google.common.collect.ComparisonChain;
|
||||
|
||||
/**
|
||||
* Used to parse a snapshot version.
|
||||
*
|
||||
* @author Kristian
|
||||
*/
|
||||
public class SnapshotVersion implements Comparable<SnapshotVersion>, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 2778655372579322310L;
|
||||
private static final Pattern SNAPSHOT_PATTERN = Pattern.compile("(\\d{2}w\\d{2})([a-z])");
|
||||
|
||||
private final Date snapshotDate;
|
||||
private final int snapshotWeekVersion;
|
||||
|
||||
private transient String rawString;
|
||||
|
||||
public SnapshotVersion(String version) {
|
||||
Matcher matcher = SNAPSHOT_PATTERN.matcher(version.trim());
|
||||
|
||||
if (matcher.matches()) {
|
||||
try {
|
||||
this.snapshotDate = getDateFormat().parse(matcher.group(1));
|
||||
this.snapshotWeekVersion = matcher.group(2).charAt(0) - 'a';
|
||||
this.rawString = version;
|
||||
} catch (ParseException e) {
|
||||
throw new IllegalArgumentException("Date implied by snapshot version is invalid.", e);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("Cannot parse " + version + " as a snapshot version.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the snapshot date parser.
|
||||
* <p>
|
||||
* We have to create a new instance of SimpleDateFormat every time as it is not thread safe.
|
||||
*
|
||||
* @return The date formatter.
|
||||
*/
|
||||
private static SimpleDateFormat getDateFormat() {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yy'w'ww", Locale.US);
|
||||
format.setLenient(false);
|
||||
return format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the snapshot version within a week, starting at zero.
|
||||
*
|
||||
* @return The weekly version
|
||||
*/
|
||||
public int getSnapshotWeekVersion() {
|
||||
return this.snapshotWeekVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the week this snapshot was released.
|
||||
*
|
||||
* @return The week.
|
||||
*/
|
||||
public Date getSnapshotDate() {
|
||||
return this.snapshotDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the raw snapshot string (yy'w'ww[a-z]).
|
||||
*
|
||||
* @return The snapshot string.
|
||||
*/
|
||||
public String getSnapshotString() {
|
||||
if (this.rawString == null) {
|
||||
// It's essential that we use the same locale
|
||||
Calendar current = Calendar.getInstance(Locale.US);
|
||||
current.setTime(this.snapshotDate);
|
||||
this.rawString = String.format("%02dw%02d%s",
|
||||
current.get(Calendar.YEAR) % 100,
|
||||
current.get(Calendar.WEEK_OF_YEAR),
|
||||
(char) ('a' + this.snapshotWeekVersion));
|
||||
}
|
||||
return this.rawString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(SnapshotVersion o) {
|
||||
if (o == null) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return ComparisonChain.start()
|
||||
.compare(this.snapshotDate, o.getSnapshotDate())
|
||||
.compare(this.snapshotWeekVersion, o.getSnapshotWeekVersion())
|
||||
.result();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj instanceof SnapshotVersion) {
|
||||
SnapshotVersion other = (SnapshotVersion) obj;
|
||||
return Objects.equals(this.snapshotDate, other.getSnapshotDate())
|
||||
&& (this.snapshotWeekVersion == other.getSnapshotWeekVersion());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.snapshotDate, this.snapshotWeekVersion);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getSnapshotString();
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
package com.github.joelgodofwar.mmh.util;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
public class StrUtils {
|
||||
/**
|
||||
* Returns the rightmost characters of a string up to the specified length.
|
||||
*
|
||||
* @param input The input string.
|
||||
* @param chars The number of characters to retrieve from the right.
|
||||
* @return The rightmost characters of the input string, or the full string if its length is less than or equal to the specified length.
|
||||
*/
|
||||
public static String Right(String input, int chars){
|
||||
if (input.length() > chars){
|
||||
//System.out.println("Right input=" + input);
|
||||
return input.substring(input.length() - chars);
|
||||
}
|
||||
else{
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the leftmost characters of a string up to the specified length.
|
||||
*
|
||||
* @param input The input string.
|
||||
* @param chars The number of characters to retrieve from the left.
|
||||
* @return The leftmost characters of the input string, or the full string if its length is less than or equal to the specified length.
|
||||
*/
|
||||
public static String Left(String input, int chars){
|
||||
if (input.length() > chars){
|
||||
//System.out.println("Left input=" + input);
|
||||
//System.out.println("Left chars=" + chars);
|
||||
return input.substring(0, chars);
|
||||
}
|
||||
else{
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a string contains a specified substring, ignoring case.
|
||||
*
|
||||
* @param string The input string to search within (comma-separated values).
|
||||
* @param string2 The substring to check for.
|
||||
* @return True if the substring is found in the input string; otherwise, false.
|
||||
*/
|
||||
public static boolean stringContains(String string, String string2){
|
||||
String[] string3 = string.toUpperCase().split(", ");
|
||||
for(int i = 0; i < string3.length; i++){
|
||||
if(string3[i].equals(string2.toUpperCase())){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two strings for equality after removing color codes.
|
||||
*
|
||||
* @param string1 The first string to compare.
|
||||
* @param string2 The second string to compare.
|
||||
* @return True if the strings are equal (ignoring color codes); otherwise, false.
|
||||
*/
|
||||
public static boolean stringEquals(String string1, String string2) {
|
||||
//string1 = ChatColor.stripColor(string1);
|
||||
//string2 = ChatColor.stripColor(string2);
|
||||
if(ChatColor.stripColor(string1).equals(ChatColor.stripColor(string2))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the first character of a string to uppercase and the remaining characters to lowercase,
|
||||
* creating a title case format.
|
||||
*
|
||||
* @param input The input string to convert to title case.
|
||||
* @return The input string in Title Case.
|
||||
*/
|
||||
public static String toTitleCase(String input) {
|
||||
if ((input == null) || input.isEmpty()) {
|
||||
return input;
|
||||
}
|
||||
|
||||
return input.substring(0, 1).toUpperCase() + input.substring(1).toLowerCase();
|
||||
}
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
package com.github.joelgodofwar.mmh.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
||||
import org.apache.commons.lang.math.NumberUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class UpdateChecker {
|
||||
private static int project;
|
||||
private URL checkURL;
|
||||
private String newVersion;
|
||||
private String newMinVers;
|
||||
private String oldVersion;
|
||||
private String oldMinVers;
|
||||
private JavaPlugin plugin;
|
||||
String[] strVersionNew; // [0]=1.14 [1]=1.0.0.?
|
||||
String[] strVersionCurrent; // [0]=1.14 [1]=1.0.0.?
|
||||
|
||||
|
||||
public UpdateChecker(JavaPlugin plugin, int projectID, String verURL) {
|
||||
this.plugin = plugin;
|
||||
project = projectID;
|
||||
newVersion = plugin.getDescription().getVersion();
|
||||
try {
|
||||
checkURL = new URL(verURL.replace("{vers}", newVersion.substring(0, 4)));
|
||||
}catch(MalformedURLException e) {
|
||||
Bukkit.getLogger().warning(Ansi.RED + "Could not connect to update server.");
|
||||
//Bukkit.getPluginManager().disablePlugin(plugin);
|
||||
}
|
||||
}
|
||||
public UpdateChecker(String plugin, int projectID, String verURL) {
|
||||
newVersion = plugin;
|
||||
try {
|
||||
checkURL = new URL(verURL.replace("{vers}", newVersion.substring(0, 4)));
|
||||
}catch(MalformedURLException e) {
|
||||
Bukkit.getLogger().warning(Ansi.RED + "Could not connect to update server.");
|
||||
//Bukkit.getPluginManager().disablePlugin(plugin);
|
||||
}
|
||||
}
|
||||
public static String getResourceUrl() {return "https://spigotmc.org/resources/" + project;}
|
||||
public boolean checkForUpdates() throws Exception {
|
||||
boolean isOutdated = false;
|
||||
|
||||
URLConnection con = checkURL.openConnection();
|
||||
con.setConnectTimeout(30000);
|
||||
con.setReadTimeout(15000);
|
||||
newVersion = new BufferedReader(new InputStreamReader(con.getInputStream())).readLine();
|
||||
strVersionNew = newVersion.split("_"); // Split into minimum MC version and version
|
||||
|
||||
newMinVers = strVersionNew[0];
|
||||
newVersion = strVersionNew[1];
|
||||
//System.out.println("newVersion=" + newVersion);
|
||||
Version newVers = new Version(newVersion);
|
||||
|
||||
strVersionCurrent = plugin.getDescription().getVersion().split("_");
|
||||
|
||||
oldMinVers = strVersionCurrent[0];
|
||||
oldVersion = strVersionCurrent[1];
|
||||
//System.out.println("oldVersion=" + oldVersion);
|
||||
Version oldVers = new Version(oldVersion);
|
||||
|
||||
if(oldVers.isDev()){ /** If currently on Dev version, ignore build -1 from Patch */
|
||||
if(newVers.Major() > oldVers.Major()){isOutdated = true;}
|
||||
if(newVers.Major() == oldVers.Major()){/** same do nothing */}
|
||||
if(newVers.Minor() > oldVers.Minor()){isOutdated = true;}
|
||||
else if(newVers.Minor() == oldVers.Minor()){/** same do nothing */}
|
||||
if(newVers.Patch() > (oldVers.Patch() - 1)){isOutdated = true;}
|
||||
else if(newVers.Patch() == (oldVers.Patch() - 1)){/** same do nothing */}
|
||||
/**if(newVers.Build() > oldVers.Build()){isOutdated = true;}
|
||||
else if(newVers.Build() == oldVers.Build()){/** same do nothing }*/
|
||||
}else {
|
||||
if(newVers.Major() > oldVers.Major()){isOutdated = true;}
|
||||
if(newVers.Major() == oldVers.Major()){/** same do nothing */}
|
||||
if(newVers.Minor() > oldVers.Minor()){isOutdated = true;}
|
||||
else if(newVers.Minor() == oldVers.Minor()){/** same do nothing */}
|
||||
if(newVers.Patch() > oldVers.Patch()){isOutdated = true;}
|
||||
else if(newVers.Patch() == oldVers.Patch()){/** same do nothing */}
|
||||
if(newVers.Build() > oldVers.Build()){isOutdated = true;}
|
||||
else if(newVers.Build() == oldVers.Build()){/** same do nothing */}
|
||||
}
|
||||
return isOutdated; //plugin.getDescription().getVersion().equals(newVersion); TODO:
|
||||
}
|
||||
public String newVersion(){
|
||||
return newMinVers + "_" + newVersion;
|
||||
}
|
||||
public String oldVersion(){
|
||||
return oldMinVers + "_" + oldVersion;
|
||||
}
|
||||
|
||||
public class Version{
|
||||
private int Major; // 1
|
||||
private int Minor; // 16
|
||||
private int Patch; // 1
|
||||
private int Build; // ?
|
||||
private boolean isDev = false;
|
||||
private String[] string2 = {"0","0","0","0"};
|
||||
public Version(String string){
|
||||
//System.out.println("string=" + string);
|
||||
string2 = string.split("\\.");
|
||||
//for (String a : string2)
|
||||
//System.out.println(a);
|
||||
//System.out.println("string2=" + string2.toString());
|
||||
//System.out.println("string2.length=" + string2.length);
|
||||
this.Major = NumberUtils.toInt(string2[0]);
|
||||
this.Minor = NumberUtils.toInt(string2[1]);
|
||||
this.Patch = NumberUtils.toInt(string2[2]);
|
||||
if(string2.length >= 4){
|
||||
if(string2[3].toUpperCase().contains("D")){
|
||||
isDev = true;
|
||||
string2[3] = string2[3].toUpperCase().replace("D", "");
|
||||
}
|
||||
this.Build = NumberUtils.toInt(string2[3]);
|
||||
}else{
|
||||
this.Build = 0;
|
||||
}
|
||||
}
|
||||
public int Major(){return Major;}
|
||||
public int Minor(){return Minor;}
|
||||
public int Patch(){return Patch;}
|
||||
public int Build(){return Build;}
|
||||
public boolean isDev(){return isDev;}
|
||||
}
|
||||
}
|
||||
-115
@@ -1,115 +0,0 @@
|
||||
package com.github.joelgodofwar.mmh.util;
|
||||
|
||||
import org.apache.commons.lang.math.NumberUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
|
||||
public class Utils {
|
||||
|
||||
public static void sendJson(CommandSender player, String string){
|
||||
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "tellraw \"" + player.getName() + "\" " + string);
|
||||
}
|
||||
|
||||
public static void sendJson(Player player, String string){
|
||||
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "tellraw \"" + player.getName() + "\" " + string);
|
||||
}
|
||||
|
||||
public String parsePAPI(String string) {
|
||||
if(Bukkit.getServer().getPluginManager().getPlugin("PlaceholderAPI") != null){
|
||||
return PlaceholderAPI.setPlaceholders(null, string);
|
||||
}else {
|
||||
return string;
|
||||
}
|
||||
}
|
||||
|
||||
public String parsePAPI(Player player, String string) {
|
||||
if(Bukkit.getServer().getPluginManager().getPlugin("PlaceholderAPI") != null){
|
||||
return PlaceholderAPI.setPlaceholders(player, string);
|
||||
}else {
|
||||
return string;
|
||||
}
|
||||
}
|
||||
|
||||
public String parsePAPI(OfflinePlayer player, String string) {
|
||||
if(Bukkit.getServer().getPluginManager().getPlugin("PlaceholderAPI") != null){
|
||||
return PlaceholderAPI.setPlaceholders(player, string);
|
||||
}else {
|
||||
return string;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the server version is supported based on minimum Minecraft version and build number.
|
||||
*
|
||||
* @param minMCVersion Minimum Minecraft version in the format "Major.Minor.BugFix.Build" (e.g., "1.20.2.3936").
|
||||
* @return True if the server version is not supported; otherwise, false.
|
||||
*/
|
||||
public static boolean isSupportedVersion(String minMCVersion) {
|
||||
// 3936-Spigot-dba3cdc-5a2d905 (MC: 1.20.2)
|
||||
// 0 1 2
|
||||
//String[] minVersion = minMCVersion.split("\\.");
|
||||
Version minVersion = new Version(minMCVersion);
|
||||
|
||||
String serverVersion = Bukkit.getVersion(); // Get the server version string
|
||||
String[] versionParts = serverVersion.split(" "); // Split by space to get the MC version and build number
|
||||
String daVersion = versionParts[2].replace(")", ".").concat(serverVersion.split("-")[0]);
|
||||
/**System.out.println("Bukkit.getVersion()=" + Bukkit.getVersion());
|
||||
System.out.println("versionParts.length=" + versionParts.length);
|
||||
System.out.println("versionParts.0=" + versionParts[0]);
|
||||
System.out.println("versionParts.1=" + versionParts[1]);
|
||||
System.out.println("versionParts.1=" + versionParts[2]);//*/
|
||||
Version checkVersion = new Version(daVersion);
|
||||
|
||||
if(minVersion.Major() > checkVersion.Major()){return true;}
|
||||
if(minVersion.Major() == checkVersion.Major()){/** same do nothing */}
|
||||
if(minVersion.Minor() > checkVersion.Minor()){return true;}
|
||||
else if(minVersion.Minor() == checkVersion.Minor()){/** same do nothing */}
|
||||
if(minVersion.Patch() > checkVersion.Patch()){return true;}
|
||||
else if(minVersion.Patch() == checkVersion.Patch()){/** same do nothing */}
|
||||
if(minVersion.Build() > checkVersion.Build()){return true;}
|
||||
else if(minVersion.Build() == checkVersion.Build()){/** same do nothing */}
|
||||
|
||||
return true; // Server version is not supported
|
||||
}
|
||||
|
||||
public static class Version{
|
||||
private int Major; // 1
|
||||
private int Minor; // 16
|
||||
private int Patch; // 1
|
||||
private int Build; // ?
|
||||
private boolean isDev = false;
|
||||
private String[] string2 = {"0","0","0","0"};
|
||||
public Version(String string){
|
||||
//System.out.println("string=" + string);
|
||||
string2 = string.split("\\.");
|
||||
/**for (String a : string2) {
|
||||
System.out.println(a);
|
||||
System.out.println("string2=" + string2.toString());
|
||||
System.out.println("string2.length=" + string2.length);
|
||||
}//*/
|
||||
this.Major = NumberUtils.toInt(string2[0]);
|
||||
this.Minor = NumberUtils.toInt(string2[1]);
|
||||
this.Patch = NumberUtils.toInt(string2[2]);
|
||||
if(string2.length >= 4){
|
||||
if(string2[3].toUpperCase().contains("D")){
|
||||
isDev = true;
|
||||
string2[3] = string2[3].toUpperCase().replace("D", "");
|
||||
}
|
||||
this.Build = NumberUtils.toInt(string2[3]);
|
||||
}else{
|
||||
this.Build = 0;
|
||||
}
|
||||
}
|
||||
public int Major(){return Major;}
|
||||
public int Minor(){return Minor;}
|
||||
public int Patch(){return Patch;}
|
||||
public int Build(){return Build;}
|
||||
public boolean isDev(){return isDev;}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
package com.github.joelgodofwar.mmh.util;
|
||||
|
||||
import com.github.joelgodofwar.mmh.MoreMobHeads;
|
||||
|
||||
/**
|
||||
* Utility class for verifying and retrieving values from a FileConfiguration.
|
||||
*/
|
||||
public class VerifyConfig {
|
||||
MoreMobHeads mmh;
|
||||
|
||||
/**
|
||||
* Constructs a VerifyConfig object with the given FileConfiguration.
|
||||
*
|
||||
* @param config The FileConfiguration to be verified.
|
||||
*/
|
||||
public VerifyConfig(final MoreMobHeads plugin) {
|
||||
this.mmh = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a string value from the configuration for the specified path.
|
||||
* If the value is null, the specified defaultValue is returned.
|
||||
*
|
||||
* @param path The path to the configuration value.
|
||||
* @param defaultValue The default value to be returned if the specified path is null.
|
||||
* @return The retrieved string value or the defaultValue if null.
|
||||
*/
|
||||
public String getString(String path, String defaultValue ) {
|
||||
try {
|
||||
String stringValue = mmh.getConfig().getString(path, null);
|
||||
if (stringValue == null) {
|
||||
throw new NullPointerException("Could not read value of: " + path);
|
||||
}
|
||||
return stringValue;
|
||||
}catch (NullPointerException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a boolean value from the configuration for the specified path.
|
||||
* If the value is null, the specified defaultValue is returned.
|
||||
*
|
||||
* @param path The path to the configuration value.
|
||||
* @param defaultValue The default value to be returned if the specified path is null.
|
||||
* @return The retrieved boolean value or the defaultValue if null.
|
||||
*/
|
||||
public boolean getBoolean(String path, boolean defaultValue ) {
|
||||
try {
|
||||
String stringValue = mmh.getConfig().getString(path, null);
|
||||
if (stringValue == null) {
|
||||
throw new NullPointerException("Could not read value of: " + path);
|
||||
}
|
||||
return Boolean.parseBoolean(stringValue);
|
||||
}catch (NullPointerException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an integer value from the configuration for the specified path.
|
||||
* If the value is null, the specified defaultValue is returned.
|
||||
*
|
||||
* @param path The path to the configuration value.
|
||||
* @param defaultValue The default value to be returned if the specified path is null.
|
||||
* @return The retrieved integer value or the defaultValue if null.
|
||||
*/
|
||||
public int getInt(String path, int defaultValue ) {
|
||||
try {
|
||||
String stringValue = mmh.getConfig().getString(path, null);
|
||||
if (stringValue == null) {
|
||||
throw new NullPointerException("Could not read value of: " + path);
|
||||
}
|
||||
return Integer.parseInt(stringValue);
|
||||
}catch (NullPointerException | NumberFormatException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public boolean checkString(String path){
|
||||
try {
|
||||
String stringValue = mmh.getConfig().getString(path, null);
|
||||
if(stringValue != null) {
|
||||
return true;
|
||||
}else {
|
||||
return false;
|
||||
}
|
||||
}catch(Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void verifyValues() {
|
||||
mmh.LOGGER.log("plugin_settings.auto_update_check " + getBoolean("plugin_settings.auto_update_check", true));
|
||||
mmh.LOGGER.log("plugin_settings.debug " + getBoolean("plugin_settings.debug", false));
|
||||
mmh.LOGGER.log("plugin_settings.lang " + getString("plugin_settings.lang", "en_US"));
|
||||
mmh.LOGGER.log("global_settings.console.colorful_console " + getBoolean("global_settings.console.colorful_console", true));
|
||||
mmh.LOGGER.log("global_settings.console.silent_console " + getBoolean("global_settings.console.silent_console", true));
|
||||
mmh.LOGGER.log("global_settings.console.longpluginname " + getBoolean("global_settings.console.longpluginname", true));
|
||||
mmh.LOGGER.log("global_settings.world.whitelist " + getString("global_settings.world.whitelist", ""));
|
||||
mmh.LOGGER.log("global_settings.world.blacklist " + getString("global_settings.world.blacklist", ""));
|
||||
mmh.LOGGER.log("global_settings.event.piston_extend " + getBoolean("global_settings.event.piston_extend", true));
|
||||
mmh.LOGGER.log("head_settings.apply_looting " + getBoolean("head_settings.apply_looting", true));
|
||||
mmh.LOGGER.log("head_settings.lore.show_killer " + getBoolean("head_settings.lore.show_killer", true));
|
||||
mmh.LOGGER.log("head_settings.lore.show_plugin_name " + getBoolean("head_settings.lore.show_plugin_name", true));
|
||||
mmh.LOGGER.log("head_settings.player_heads.announce_kill.enabled" + getBoolean("head_settings.player_heads.announce_kill.enabled", false));
|
||||
mmh.LOGGER.log("head_settings.player_heads.announce_kill.displayname " + getBoolean("head_settings.player_heads.announce_kill.displayname", true));
|
||||
mmh.LOGGER.log("head_settings.player_heads.whitelist.enforce " + getBoolean("head_settings.player_heads.whitelist.enforce", true));
|
||||
mmh.LOGGER.log("head_settings.player_heads.whitelist.player_head_whitelist " + getString("head_settings.player_heads.whitelist.player_head_whitelist", ""));
|
||||
mmh.LOGGER.log("head_settings.player_heads.blacklist.enforce " + getBoolean("head_settings.player_heads.blacklist.enforce", true));
|
||||
mmh.LOGGER.log("head_settings.player_heads.blacklist.player_head_blacklist " + getString("head_settings.player_heads.blacklist.player_head_blacklist", ""));
|
||||
mmh.LOGGER.log("head_settings.mob_heads.announce_kill.enabled " + getBoolean("head_settings.mob_heads.announce_kill.enabled", false));
|
||||
mmh.LOGGER.log("head_settings.mob_heads.announce_kill.displayname " + getBoolean("head_settings.mob_heads.announce_kill.displayname", true));
|
||||
mmh.LOGGER.log("head_settings.mob_heads.whitelist " + getString("head_settings.mob_heads.whitelist", ""));
|
||||
mmh.LOGGER.log("head_settings.mob_heads.blacklist " + getString("head_settings.mob_heads.blacklist", ""));
|
||||
mmh.LOGGER.log("head_settings.mob_heads.nametag " + getBoolean("head_settings.mob_heads.nametag", false));
|
||||
mmh.LOGGER.log("head_settings.mob_heads.vanilla_heads.creepers " + getBoolean("head_settings.mob_heads.vanilla_heads.creepers", true));
|
||||
mmh.LOGGER.log("head_settings.mob_heads.vanilla_heads.ender_dragon " + getBoolean("head_settings.mob_heads.vanilla_heads.ender_dragon", true));
|
||||
mmh.LOGGER.log("head_settings.mob_heads.vanilla_heads.piglin " + getBoolean("head_settings.mob_heads.vanilla_heads.piglin", true));
|
||||
mmh.LOGGER.log("head_settings.mob_heads.vanilla_heads.skeleton " + getBoolean("head_settings.mob_heads.vanilla_heads.skeleton", true));
|
||||
mmh.LOGGER.log("head_settings.mob_heads.vanilla_heads.wither_skeleto " + getBoolean("head_settings.mob_heads.vanilla_heads.wither_skeleton", true));
|
||||
mmh.LOGGER.log("head_settings.mob_heads.vanilla_heads.zombie " + getBoolean("head_settings.mob_heads.vanilla_heads.zombie", true));
|
||||
mmh.LOGGER.log("wandering_trades.custom_wandering_trader " + getBoolean("wandering_trades.custom_wandering_trader", true));
|
||||
mmh.LOGGER.log("wandering_trades.keep_default_trades " + getBoolean("wandering_trades.keep_default_trades", true));
|
||||
mmh.LOGGER.log("wandering_trades.player_heads.enabled " + getBoolean("wandering_trades.player_heads.enabled", true));
|
||||
mmh.LOGGER.log("wandering_trades.player_heads.min " + getInt("wandering_trades.player_heads.min", 0));
|
||||
mmh.LOGGER.log("wandering_trades.player_heads.max " + getInt("wandering_trades.player_heads.max", 5));
|
||||
mmh.LOGGER.log("wandering_trades.block_heads.enabled " + getBoolean("wandering_trades.block_heads.enabled", true));
|
||||
mmh.LOGGER.log("wandering_trades.block_heads.pre_116.min" + getInt("wandering_trades.block_heads.pre_116.min", 0));
|
||||
mmh.LOGGER.log("wandering_trades.block_heads.pre_116.max " + getInt("wandering_trades.block_heads.pre_116.max", 5));
|
||||
mmh.LOGGER.log("wandering_trades.block_heads.is_116.min" + getInt("wandering_trades.block_heads.is_116.min", 0));
|
||||
mmh.LOGGER.log("wandering_trades.block_heads.is_116.max " + getInt("wandering_trades.block_heads.is_116.max", 5));
|
||||
mmh.LOGGER.log("wandering_trades.block_heads.is_117.min " + getInt("wandering_trades.block_heads.is_117.min", 0));
|
||||
mmh.LOGGER.log("wandering_trades.block_heads.is_117.max " + getInt("wandering_trades.block_heads.is_117.max", 5));
|
||||
mmh.LOGGER.log("wandering_trades.custom_trades.enabled " + getBoolean("wandering_trades.custom_trades.enabled", true));
|
||||
mmh.LOGGER.log("wandering_trades.custom_trades.min " + getInt("wandering_trades.custom_trades.min", 0));
|
||||
mmh.LOGGER.log("wandering_trades.custom_trades.max " + getInt("wandering_trades.custom_trades.max", 5));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,222 +0,0 @@
|
||||
package com.github.joelgodofwar.mmh.util;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import com.github.joelgodofwar.mmh.MoreMobHeads;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class VersionChecker {
|
||||
private String pluginName;
|
||||
private JavaPlugin plugin;
|
||||
private int projectID;
|
||||
private String currentVersion;
|
||||
private String githubURL; // = "https://github.com/JoelGodOfwar/MoreMobHeads/raw/master/versioncheck/1.15/versions.xml";
|
||||
String versionType;
|
||||
private List<String> releaseList = new ArrayList<>();
|
||||
private List<String> developerList = new ArrayList<>();
|
||||
private String recommendedVersion = "uptodate";
|
||||
private MoreMobHeads mmh;
|
||||
|
||||
public VersionChecker(MoreMobHeads plugin, int projectID, String githubURL) {
|
||||
this.mmh = plugin;
|
||||
this.projectID = projectID;
|
||||
this.currentVersion = plugin.getDescription().getVersion();
|
||||
this.githubURL = githubURL;
|
||||
}
|
||||
|
||||
public VersionChecker(String plugin, int projectID, String githubURL) {
|
||||
this.currentVersion = plugin;
|
||||
this.projectID = projectID;
|
||||
this.githubURL = githubURL;
|
||||
}
|
||||
|
||||
public String getReleaseUrl() {return "https://dev.bukkit.org/projects/moremobheads2";}
|
||||
|
||||
public boolean checkForUpdates() throws Exception {
|
||||
URL url = new URL(githubURL);
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
URLConnection connection = url.openConnection();
|
||||
connection.setUseCaches(false);
|
||||
connection.setRequestProperty("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||
Document doc = db.parse(connection.getInputStream());
|
||||
doc.getDocumentElement().normalize();
|
||||
NodeList releaseNodes = doc.getElementsByTagName("release");
|
||||
for (int i = 0; i < releaseNodes.getLength(); i++) {
|
||||
Node node = releaseNodes.item(i);
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element element = (Element) node;
|
||||
releaseList.add(element.getElementsByTagName("version").item(0).getTextContent().replace("<version>", "").replace("</version>", ""));
|
||||
releaseList.add(element.getElementsByTagName("notes").item(0).getTextContent().replace("<notes>", "").replace("</notes>", ""));
|
||||
releaseList.add(element.getElementsByTagName("link").item(0).getTextContent().replace("<link>", "").replace("</link>", ""));
|
||||
}
|
||||
}
|
||||
NodeList developerNodes = doc.getElementsByTagName("developer");
|
||||
for (int i = 0; i < developerNodes.getLength(); i++) {
|
||||
Node node = developerNodes.item(i);
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element element = (Element) node;
|
||||
developerList.add(element.getElementsByTagName("version").item(0).getTextContent().replace("<version>", "").replace("</version>", ""));
|
||||
developerList.add(element.getElementsByTagName("notes").item(0).getTextContent().replace("<notes>", "").replace("</notes>", ""));
|
||||
developerList.add(element.getElementsByTagName("link").item(0).getTextContent().replace("<link>", "").replace("</link>", ""));
|
||||
}
|
||||
}
|
||||
|
||||
if (connection != null) {
|
||||
connection.getInputStream().close();
|
||||
}
|
||||
String releaseVersion = releaseList.get(0);
|
||||
String developerVersion = developerList.get(0);
|
||||
mmh.LOGGER.debug(ChatColor.RED + "currentVersion=" + currentVersion);
|
||||
mmh.LOGGER.debug(ChatColor.RED + "releaseVersion=" + releaseVersion);
|
||||
mmh.LOGGER.debug(ChatColor.RED + "developerVersion=" + developerVersion);
|
||||
if (currentVersion.compareTo(releaseVersion) < 0) {
|
||||
recommendedVersion = "release";
|
||||
return true;
|
||||
} else if (currentVersion.equals(releaseVersion)) {
|
||||
recommendedVersion = "uptodate";
|
||||
return false;
|
||||
} else if (currentVersion.contains(".D")) {
|
||||
String[] splitCurrentVersion = currentVersion.split("\\.D");
|
||||
String currentReleaseVersion = splitCurrentVersion[0];
|
||||
String[] splitDeveloperVersion = developerVersion.split("\\.D");
|
||||
String developerReleaseVersion = splitDeveloperVersion[0];
|
||||
if (currentReleaseVersion.equals(releaseVersion) && (developerReleaseVersion.compareTo(currentReleaseVersion) <= 0)) {
|
||||
recommendedVersion = "release";
|
||||
return true;
|
||||
} else if ((developerReleaseVersion.compareTo(releaseVersion) < 0) && developerReleaseVersion.equals(currentReleaseVersion)) {
|
||||
recommendedVersion = "You are Up To Date";
|
||||
return false;
|
||||
} else if (developerVersion.compareTo(currentVersion) > 0) {
|
||||
recommendedVersion = "developer";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
public List<String> getReleaseList() {
|
||||
return releaseList;
|
||||
}
|
||||
public List<String> getDeveloperList() {
|
||||
return developerList;
|
||||
}
|
||||
public String getRecommendedVersion() {
|
||||
return recommendedVersion;
|
||||
}
|
||||
public String oldVersion() {
|
||||
return currentVersion;
|
||||
}
|
||||
public String newVersion() {
|
||||
if(recommendedVersion.equalsIgnoreCase("release")) {
|
||||
return releaseList.get(0);
|
||||
}else if(recommendedVersion.equalsIgnoreCase("developer")) {
|
||||
return developerList.get(0);
|
||||
}else {
|
||||
return "UpToDate";
|
||||
}
|
||||
}
|
||||
public String newVersionNotes() {
|
||||
if (recommendedVersion.equalsIgnoreCase("release")) {
|
||||
return releaseList.get(1);
|
||||
} else if (recommendedVersion.equalsIgnoreCase("developer")) {
|
||||
return developerList.get(1);
|
||||
} else {
|
||||
return "UpToDate";
|
||||
}
|
||||
}
|
||||
public String getDownloadLink() {
|
||||
if (recommendedVersion.equalsIgnoreCase("release")) {
|
||||
return releaseList.get(2);//"https://www.spigotmc.org/resources/no-enderman-grief2.71236/history";
|
||||
} else if (recommendedVersion.equalsIgnoreCase("developer")) {
|
||||
return developerList.get(2);//"https://discord.com/channels/654087250665144321/654444482372173875";
|
||||
} else {
|
||||
return "UpToDate";
|
||||
}
|
||||
}
|
||||
|
||||
/**public boolean checkForUpdates2() {
|
||||
if(currentVersion.contains(".D")){
|
||||
versionType = "developer";
|
||||
}else{
|
||||
versionType = "release";
|
||||
}
|
||||
String[] versionArray = getLatestVersion(versionType);
|
||||
|
||||
if (versionArray == null) {
|
||||
Bukkit.getLogger().warning(Ansi.RED + "Could not connect to update server.");
|
||||
return false;
|
||||
}
|
||||
|
||||
String latestVersion = versionArray[0];
|
||||
String latestNotes = versionArray[1];
|
||||
|
||||
if (latestVersion.equals(currentVersion)) {
|
||||
return false;
|
||||
} else {
|
||||
System.out.println("There is a new version of " + pluginName + " available!");
|
||||
System.out.println("Your version: " + currentVersion);
|
||||
System.out.println("Latest version: " + latestVersion);
|
||||
System.out.println("Update notes: " + latestNotes);
|
||||
System.out.println("Please update to the newest version.");
|
||||
System.out.println("Download: https://www.spigotmc.org/resources/" + pluginName + ".75749/history");
|
||||
System.out.println("Donate: <donation link>");
|
||||
return true;
|
||||
}
|
||||
}//*/
|
||||
|
||||
/**private String[] getLatestVersion(String versionType) {
|
||||
try {
|
||||
URL url = new URL(githubURL);
|
||||
InputStream stream = url.openStream();
|
||||
Scanner scanner = new Scanner(stream);
|
||||
scanner.useDelimiter("\\Z");
|
||||
String xmlContent = scanner.next();
|
||||
scanner.close();
|
||||
stream.close();
|
||||
|
||||
String versionTag = "<" + versionType + ">";
|
||||
String notesTag = "<" + versionType + "-notes>";
|
||||
String endTag = "</" + versionType + ">";
|
||||
|
||||
int versionStartIndex = xmlContent.indexOf(versionTag);
|
||||
int notesStartIndex = xmlContent.indexOf(notesTag);
|
||||
int versionEndIndex = xmlContent.indexOf(endTag);
|
||||
|
||||
if (versionStartIndex == -1 || notesStartIndex == -1 || versionEndIndex == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String versionNumber = xmlContent.substring(versionStartIndex + versionTag.length(), versionEndIndex);
|
||||
String notes = xmlContent.substring(notesStartIndex + notesTag.length(), xmlContent.indexOf(endTag + "-notes>"));
|
||||
String[] versionArray = new String[2];
|
||||
versionArray[0] = versionNumber;
|
||||
versionArray[1] = notes;
|
||||
return versionArray;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}//*/
|
||||
|
||||
/**public static void main(String[] args) {
|
||||
//String pluginName = "MyPlugin";
|
||||
String currentVersion = "1.14_1.0.4";
|
||||
String githubURL = "https://github.com/JoelGodOfwar/NoEndermanGrief/raw/master/versions/1.14/versions.xml";
|
||||
VersionChecker checker = new VersionChecker(currentVersion, 71236, githubURL);
|
||||
checker.checkForUpdates();
|
||||
}//*/
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
package com.github.joelgodofwar.mmh.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConstructor;
|
||||
import org.bukkit.configuration.file.YamlRepresenter;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.representer.Representer;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
|
||||
import jdk.internal.joptsimple.internal.Strings;
|
||||
|
||||
/*
|
||||
* @author: Aoife (Josh)
|
||||
* @date: 2020-04-25
|
||||
* @project: WarpConverter
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class YmlConfiguration extends YamlConfiguration {
|
||||
|
||||
private final DumperOptions yamlOptions = new DumperOptions();
|
||||
private final Representer yamlRepresenter = new YamlRepresenter();
|
||||
private final Yaml yaml = new Yaml(new YamlConstructor(), yamlRepresenter, yamlOptions);
|
||||
private Map<Integer, String> commentContainer = new HashMap<>();
|
||||
|
||||
@Override public void save(File file) throws IOException {
|
||||
Validate.notNull(file);
|
||||
try (Writer writer = new OutputStreamWriter(new FileOutputStream(file), Charsets.UTF_8)) {
|
||||
writer.write(saveToString());
|
||||
}
|
||||
}
|
||||
|
||||
public static void saveConfig(File file, YmlConfiguration config) {
|
||||
try {
|
||||
config.save(file);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String saveToString(){
|
||||
yamlOptions.setIndent(options().indent());
|
||||
yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
String header = "";//buildHeader();
|
||||
String dump = yaml.dump(getValues(false));
|
||||
|
||||
if (dump.equals(BLANK_CONFIG)) {
|
||||
dump = Strings.EMPTY;
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int line = 0;
|
||||
for(String s : dump.split("\n")) {
|
||||
line++;
|
||||
while (commentContainer.containsKey(line)) {
|
||||
sb.append(commentContainer.get(line)).append("\n");
|
||||
line++;
|
||||
}
|
||||
sb.append(s).append("\n");
|
||||
}
|
||||
|
||||
dump = sb.toString();
|
||||
}
|
||||
return header.length() > 0 ? header + dump : dump;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(Reader reader) throws IOException, InvalidConfigurationException {
|
||||
BufferedReader input = reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader);
|
||||
StringBuilder builder = new StringBuilder();
|
||||
try {
|
||||
String line;
|
||||
int count = 0;
|
||||
while ((line = input.readLine()) != null) {
|
||||
count++;
|
||||
if (line.contains(COMMENT_PREFIX)|| line.isEmpty()) {
|
||||
commentContainer.put(count, line);
|
||||
}
|
||||
builder.append(line).append('\n');
|
||||
}
|
||||
} finally {
|
||||
input.close();
|
||||
}
|
||||
loadFromString(builder.toString());
|
||||
}
|
||||
|
||||
public static YamlConfiguration loadConfiguration(File file, YmlConfiguration config) {
|
||||
Validate.notNull(file, "File cannot be null");
|
||||
try {
|
||||
config.load(file);
|
||||
} catch (FileNotFoundException ex) {
|
||||
} catch (IOException | InvalidConfigurationException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Cannot load " + file, ex);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package com.github.joelgodofwar.mmh.util.datatypes;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.bukkit.persistence.PersistentDataAdapterContext;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
/**
|
||||
* Lets you store arbitrary data in PDC.
|
||||
* @param <T>
|
||||
*/
|
||||
public class JsonDataType<T> implements PersistentDataType<String, T> {
|
||||
|
||||
private static final Gson gson = new Gson();
|
||||
private final Class<T> typeClass;
|
||||
|
||||
public JsonDataType(Class<T> typeClass) {
|
||||
this.typeClass = typeClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nonnull Class<String> getPrimitiveType() {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nonnull Class<T> getComplexType() {
|
||||
return typeClass;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String toPrimitive(@Nonnull T complex, @Nonnull PersistentDataAdapterContext persistentDataAdapterContext) {
|
||||
return gson.toJson(complex);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public T fromPrimitive(@Nonnull String primitive, @Nonnull PersistentDataAdapterContext context) {
|
||||
return gson.fromJson(primitive, getComplexType());
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package com.github.joelgodofwar.mmh.util.mob;
|
||||
|
||||
import org.bukkit.entity.Drowned;
|
||||
import org.bukkit.entity.Evoker;
|
||||
import org.bukkit.entity.Husk;
|
||||
import org.bukkit.entity.Illusioner;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.PigZombie;
|
||||
import org.bukkit.entity.Pillager;
|
||||
import org.bukkit.entity.Skeleton;
|
||||
import org.bukkit.entity.Stray;
|
||||
import org.bukkit.entity.Vex;
|
||||
import org.bukkit.entity.Villager;
|
||||
import org.bukkit.entity.Vindicator;
|
||||
import org.bukkit.entity.WanderingTrader;
|
||||
import org.bukkit.entity.WitherSkeleton;
|
||||
import org.bukkit.entity.Zombie;
|
||||
import org.bukkit.entity.ZombieVillager;
|
||||
|
||||
import com.github.joelgodofwar.mmh.MoreMobHeads;
|
||||
|
||||
public class NameTag {
|
||||
|
||||
public static boolean canWearHead(LivingEntity mob) {
|
||||
if((mob instanceof Skeleton)||(mob instanceof Zombie)||(mob instanceof PigZombie)||(mob instanceof Villager)||
|
||||
(mob instanceof Drowned)||(mob instanceof Stray)||(mob instanceof Husk)||(mob instanceof WitherSkeleton)||
|
||||
(mob instanceof ZombieVillager)||(mob instanceof Evoker)||(mob instanceof WanderingTrader)||(mob instanceof Vex)||
|
||||
(mob instanceof Illusioner)||(mob instanceof Pillager)||(mob instanceof Vindicator)){
|
||||
return true;
|
||||
}
|
||||
double vers = Double.parseDouble( MoreMobHeads.getMCVersion().substring(2, 4) ); // 1.16.2
|
||||
if (vers >= 16) {
|
||||
if(NameTag_1_16.canWearHead(mob)) {
|
||||
return true;
|
||||
}
|
||||
if (vers >= 16.2) {
|
||||
if(NameTag_1_16_2.canWearHead(mob)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.github.joelgodofwar.mmh.util.mob;
|
||||
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Piglin;
|
||||
|
||||
public class NameTag_1_16 {
|
||||
|
||||
public static boolean canWearHead(LivingEntity mob) {
|
||||
if(mob instanceof Piglin) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.github.joelgodofwar.mmh.util.mob;
|
||||
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.PiglinBrute;
|
||||
|
||||
public class NameTag_1_16_2 {
|
||||
|
||||
public static boolean canWearHead(LivingEntity mob) {
|
||||
if(mob instanceof PiglinBrute) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user