Delete util directory

This commit is contained in:
JoelStoner authored and GitHub committed 2024-08-14 15:26:57 -05:00
1 parent 5ebaf97732
commit e032e6a996
22 files changed
-4100

No files matched your search

-72
View File
@@ -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;//*/
}
-89
View File
@@ -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;
}
}
-60
View File
@@ -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);
}
}
-30
View File
@@ -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;
}
}
-76
View File
@@ -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();
}
}
-558
View File
@@ -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);
}
}
-36
View File
@@ -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;
}
}
-94
View File
@@ -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);
}
}
-848
View File
@@ -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;
}
}
}
}
-732
View File
@@ -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;
}
}
}
-445
View File
@@ -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());
}
}
-130
View File
@@ -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();
}
}
-88
View File
@@ -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();
}
}
-128
View File
@@ -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
View File
@@ -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;}
}
}
-143
View File
@@ -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));
}
}
-222
View File
@@ -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();
}//*/
}
-114
View File
@@ -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;
}
}
-44
View File
@@ -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());
}
}
-44
View File
@@ -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;
}
}
-16
View File
@@ -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;
}
}
-16
View File
@@ -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;
}
}