2011-05-22 04:01:43 +02:00
|
|
|
package de.diddiz.util;
|
|
|
|
|
|
2018-07-21 02:41:52 +02:00
|
|
|
import java.io.ByteArrayInputStream;
|
|
|
|
|
import java.io.ByteArrayOutputStream;
|
2011-05-22 04:01:43 +02:00
|
|
|
import java.io.File;
|
2011-10-17 15:24:54 +02:00
|
|
|
import java.io.FilenameFilter;
|
2018-07-21 02:41:52 +02:00
|
|
|
import java.io.IOException;
|
|
|
|
|
import java.io.InputStreamReader;
|
|
|
|
|
import java.io.OutputStreamWriter;
|
2011-05-22 04:01:43 +02:00
|
|
|
import java.text.ParseException;
|
|
|
|
|
import java.text.SimpleDateFormat;
|
2015-03-20 03:56:03 +05:00
|
|
|
import java.util.ArrayList;
|
2011-11-20 19:14:31 +01:00
|
|
|
import java.util.List;
|
2018-11-09 00:40:36 +01:00
|
|
|
import java.util.UUID;
|
2015-03-20 03:56:03 +05:00
|
|
|
import java.util.regex.Matcher;
|
|
|
|
|
import java.util.regex.Pattern;
|
2018-07-21 02:41:52 +02:00
|
|
|
import java.util.zip.GZIPInputStream;
|
|
|
|
|
import java.util.zip.GZIPOutputStream;
|
2018-08-03 14:52:39 +02:00
|
|
|
import java.util.zip.ZipException;
|
2018-07-21 02:41:52 +02:00
|
|
|
|
2018-11-09 00:40:36 +01:00
|
|
|
import org.bukkit.Bukkit;
|
|
|
|
|
import org.bukkit.Chunk;
|
2018-07-21 02:41:52 +02:00
|
|
|
import org.bukkit.configuration.InvalidConfigurationException;
|
|
|
|
|
import org.bukkit.configuration.file.YamlConfiguration;
|
2018-11-09 00:40:36 +01:00
|
|
|
import org.bukkit.entity.Entity;
|
2018-07-21 02:41:52 +02:00
|
|
|
import org.bukkit.inventory.ItemStack;
|
2011-05-22 04:01:43 +02:00
|
|
|
|
2018-07-30 16:41:55 +02:00
|
|
|
import de.diddiz.LogBlock.LogBlock;
|
|
|
|
|
|
2015-03-22 20:15:04 +05:00
|
|
|
public class Utils {
|
|
|
|
|
public static String newline = System.getProperty("line.separator");
|
2012-08-05 21:01:25 +10:00
|
|
|
|
2015-03-22 20:15:04 +05:00
|
|
|
public static boolean isInt(String str) {
|
|
|
|
|
try {
|
|
|
|
|
Integer.parseInt(str);
|
|
|
|
|
return true;
|
|
|
|
|
} catch (final NumberFormatException ex) {
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2011-05-22 04:01:43 +02:00
|
|
|
|
2015-03-22 20:15:04 +05:00
|
|
|
public static boolean isShort(String str) {
|
|
|
|
|
try {
|
|
|
|
|
Short.parseShort(str);
|
|
|
|
|
return true;
|
|
|
|
|
} catch (final NumberFormatException ex) {
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2013-12-04 11:21:34 +00:00
|
|
|
|
2015-03-22 20:15:04 +05:00
|
|
|
public static boolean isByte(String str) {
|
|
|
|
|
try {
|
|
|
|
|
Byte.parseByte(str);
|
|
|
|
|
return true;
|
|
|
|
|
} catch (final NumberFormatException ex) {
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2011-11-04 21:31:24 +01:00
|
|
|
|
2015-03-22 20:15:04 +05:00
|
|
|
public static String listing(String[] entries, String delimiter, String finalDelimiter) {
|
|
|
|
|
final int len = entries.length;
|
|
|
|
|
if (len == 0) {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
if (len == 1) {
|
|
|
|
|
return entries[0];
|
|
|
|
|
}
|
|
|
|
|
final StringBuilder builder = new StringBuilder(entries[0]);
|
|
|
|
|
for (int i = 1; i < len - 1; i++) {
|
|
|
|
|
builder.append(delimiter).append(entries[i]);
|
|
|
|
|
}
|
|
|
|
|
builder.append(finalDelimiter).append(entries[len - 1]);
|
|
|
|
|
return builder.toString();
|
|
|
|
|
}
|
2011-06-29 01:25:48 +02:00
|
|
|
|
2015-03-22 20:15:04 +05:00
|
|
|
public static String listing(List<?> entries, String delimiter, String finalDelimiter) {
|
|
|
|
|
final int len = entries.size();
|
|
|
|
|
if (len == 0) {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
if (len == 1) {
|
|
|
|
|
return entries.get(0).toString();
|
|
|
|
|
}
|
|
|
|
|
final StringBuilder builder = new StringBuilder(entries.get(0).toString());
|
|
|
|
|
for (int i = 1; i < len - 1; i++) {
|
|
|
|
|
builder.append(delimiter).append(entries.get(i).toString());
|
|
|
|
|
}
|
|
|
|
|
builder.append(finalDelimiter).append(entries.get(len - 1).toString());
|
|
|
|
|
return builder.toString();
|
|
|
|
|
}
|
2011-11-20 19:14:31 +01:00
|
|
|
|
2015-03-22 20:15:04 +05:00
|
|
|
public static int parseTimeSpec(String[] spec) {
|
|
|
|
|
if (spec == null || spec.length < 1 || spec.length > 2) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (spec.length == 1 && isInt(spec[0])) {
|
|
|
|
|
return Integer.valueOf(spec[0]);
|
|
|
|
|
}
|
|
|
|
|
if (!spec[0].contains(":") && !spec[0].contains(".")) {
|
|
|
|
|
if (spec.length == 2) {
|
|
|
|
|
if (!isInt(spec[0])) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
int min = Integer.parseInt(spec[0]);
|
|
|
|
|
if (spec[1].startsWith("h")) {
|
|
|
|
|
min *= 60;
|
|
|
|
|
} else if (spec[1].startsWith("d")) {
|
|
|
|
|
min *= 1440;
|
|
|
|
|
}
|
|
|
|
|
return min;
|
|
|
|
|
} else if (spec.length == 1) {
|
|
|
|
|
int days = 0, hours = 0, minutes = 0;
|
|
|
|
|
int lastIndex = 0, currIndex = 1;
|
|
|
|
|
while (currIndex <= spec[0].length()) {
|
|
|
|
|
while (currIndex <= spec[0].length() && isInt(spec[0].substring(lastIndex, currIndex))) {
|
|
|
|
|
currIndex++;
|
|
|
|
|
}
|
|
|
|
|
if (currIndex - 1 != lastIndex) {
|
|
|
|
|
if (currIndex > spec[0].length()) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
final String param = spec[0].substring(currIndex - 1, currIndex).toLowerCase();
|
|
|
|
|
if (param.equals("d")) {
|
|
|
|
|
days = Integer.parseInt(spec[0].substring(lastIndex, currIndex - 1));
|
|
|
|
|
} else if (param.equals("h")) {
|
|
|
|
|
hours = Integer.parseInt(spec[0].substring(lastIndex, currIndex - 1));
|
|
|
|
|
} else if (param.equals("m")) {
|
|
|
|
|
minutes = Integer.parseInt(spec[0].substring(lastIndex, currIndex - 1));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
lastIndex = currIndex;
|
|
|
|
|
currIndex++;
|
|
|
|
|
}
|
|
|
|
|
if (days == 0 && hours == 0 && minutes == 0) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
return minutes + hours * 60 + days * 1440;
|
|
|
|
|
} else {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
final String timestamp;
|
|
|
|
|
if (spec.length == 1) {
|
|
|
|
|
if (spec[0].contains(":")) {
|
|
|
|
|
timestamp = new SimpleDateFormat("dd.MM.yyyy").format(System.currentTimeMillis()) + " " + spec[0];
|
|
|
|
|
} else {
|
|
|
|
|
timestamp = spec[0] + " 00:00:00";
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
timestamp = spec[0] + " " + spec[1];
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
return (int) ((System.currentTimeMillis() - new SimpleDateFormat("dd.MM.yyyy HH:mm:ss").parse(timestamp).getTime()) / 60000);
|
|
|
|
|
} catch (final ParseException ex) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-06-22 20:54:52 +02:00
|
|
|
|
2015-03-22 20:15:04 +05:00
|
|
|
public static String spaces(int count) {
|
|
|
|
|
final StringBuilder filled = new StringBuilder(count);
|
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
|
|
|
filled.append(' ');
|
|
|
|
|
}
|
|
|
|
|
return filled.toString();
|
|
|
|
|
}
|
2011-08-20 22:07:15 +02:00
|
|
|
|
2015-03-22 20:15:04 +05:00
|
|
|
public static String join(String[] s, String delimiter) {
|
|
|
|
|
if (s == null || s.length == 0) {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
final int len = s.length;
|
|
|
|
|
final StringBuilder builder = new StringBuilder(s[0]);
|
|
|
|
|
for (int i = 1; i < len; i++) {
|
|
|
|
|
builder.append(delimiter).append(s[i]);
|
|
|
|
|
}
|
|
|
|
|
return builder.toString();
|
|
|
|
|
}
|
2011-10-17 15:24:54 +02:00
|
|
|
|
2015-03-22 20:15:04 +05:00
|
|
|
/**
|
|
|
|
|
* Converts a list of arguments e.g ['lb', 'clearlog', 'world', '"my', 'world', 'of', 'swag"']
|
|
|
|
|
* into a list of arguments with any text encapsulated by quotes treated as one word
|
|
|
|
|
* For this particular example: ['lb', 'clearlog', 'world', '"my world of swag"']
|
|
|
|
|
*
|
|
|
|
|
* @param args The list of arguments
|
|
|
|
|
* @return A new list with the quoted arguments parsed to single values
|
|
|
|
|
*/
|
|
|
|
|
public static List<String> parseQuotes(List<String> args) {
|
|
|
|
|
List<String> newArguments = new ArrayList<String>();
|
|
|
|
|
String subjectString = join(args.toArray(new String[args.size()]), " ");
|
2015-03-20 03:56:03 +05:00
|
|
|
|
2015-03-22 20:15:04 +05:00
|
|
|
Pattern regex = Pattern.compile("[^\\s\"']+|\"[^\"]*\"|'[^']*'");
|
|
|
|
|
Matcher regexMatcher = regex.matcher(subjectString);
|
|
|
|
|
while (regexMatcher.find()) {
|
|
|
|
|
newArguments.add(regexMatcher.group());
|
|
|
|
|
}
|
2015-03-20 03:56:03 +05:00
|
|
|
|
2015-03-22 20:15:04 +05:00
|
|
|
return newArguments;
|
|
|
|
|
}
|
2015-03-20 03:56:03 +05:00
|
|
|
|
2015-03-22 20:15:04 +05:00
|
|
|
public static class ExtensionFilenameFilter implements FilenameFilter {
|
|
|
|
|
private final String ext;
|
2011-10-17 15:24:54 +02:00
|
|
|
|
2015-03-22 20:15:04 +05:00
|
|
|
public ExtensionFilenameFilter(String ext) {
|
2018-09-05 03:05:41 +02:00
|
|
|
this.ext = "." + ext;
|
2015-03-22 20:15:04 +05:00
|
|
|
}
|
2011-10-17 15:24:54 +02:00
|
|
|
|
2015-03-22 20:15:04 +05:00
|
|
|
@Override
|
|
|
|
|
public boolean accept(File dir, String name) {
|
|
|
|
|
return name.toLowerCase().endsWith(ext);
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-07-27 20:01:15 +01:00
|
|
|
|
2018-07-21 02:41:52 +02:00
|
|
|
private final static char[] hexArray = "0123456789ABCDEF".toCharArray();
|
|
|
|
|
|
|
|
|
|
public static String mysqlEscapeBytes(byte[] bytes) {
|
|
|
|
|
char[] hexChars = new char[bytes.length * 2 + 2];
|
|
|
|
|
hexChars[0] = '0';
|
|
|
|
|
hexChars[1] = 'x';
|
|
|
|
|
for (int j = 0; j < bytes.length; j++) {
|
|
|
|
|
int v = bytes[j] & 0xFF;
|
|
|
|
|
hexChars[j * 2 + 2] = hexArray[v >>> 4];
|
|
|
|
|
hexChars[j * 2 + 3] = hexArray[v & 0x0F];
|
|
|
|
|
}
|
|
|
|
|
return new String(hexChars);
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-03 01:53:28 +02:00
|
|
|
public static String mysqlPrepareBytesForInsertAllowNull(byte[] bytes) {
|
|
|
|
|
if (bytes == null) {
|
|
|
|
|
return "null";
|
|
|
|
|
}
|
|
|
|
|
return "'" + mysqlEscapeBytes(bytes) + "'";
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-27 20:01:15 +01:00
|
|
|
public static String mysqlTextEscape(String untrusted) {
|
|
|
|
|
return untrusted.replace("\\", "\\\\").replace("'", "\\'");
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-21 02:41:52 +02:00
|
|
|
public static ItemStack loadItemStack(byte[] data) {
|
|
|
|
|
if (data == null || data.length == 0) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2018-08-09 05:00:11 +02:00
|
|
|
YamlConfiguration conf = deserializeYamlConfiguration(data);
|
|
|
|
|
return conf == null ? null : conf.getItemStack("stack");
|
2018-07-21 02:41:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static byte[] saveItemStack(ItemStack stack) {
|
2018-07-27 17:19:15 +02:00
|
|
|
if (stack == null || BukkitUtils.isEmpty(stack.getType())) {
|
2018-07-21 02:41:52 +02:00
|
|
|
return null;
|
|
|
|
|
}
|
2018-07-30 16:41:55 +02:00
|
|
|
YamlConfiguration conf = new YamlConfiguration();
|
|
|
|
|
conf.set("stack", stack);
|
|
|
|
|
return serializeYamlConfiguration(conf);
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-09 05:00:11 +02:00
|
|
|
public static YamlConfiguration deserializeYamlConfiguration(byte[] data) {
|
|
|
|
|
if (data == null || data.length == 0) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2018-07-30 16:41:55 +02:00
|
|
|
YamlConfiguration conf = new YamlConfiguration();
|
|
|
|
|
try {
|
|
|
|
|
InputStreamReader reader = new InputStreamReader(new GZIPInputStream(new ByteArrayInputStream(data)), "UTF-8");
|
|
|
|
|
conf.load(reader);
|
|
|
|
|
reader.close();
|
|
|
|
|
return conf;
|
2018-08-09 05:00:11 +02:00
|
|
|
} catch (ZipException | InvalidConfigurationException e) {
|
2018-08-03 14:52:39 +02:00
|
|
|
LogBlock.getInstance().getLogger().warning("Could not deserialize YamlConfiguration: " + e.getMessage());
|
|
|
|
|
return conf;
|
2018-07-30 16:41:55 +02:00
|
|
|
} catch (IOException e) {
|
|
|
|
|
throw new RuntimeException("IOException should be impossible for ByteArrayInputStream", e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static byte[] serializeYamlConfiguration(YamlConfiguration conf) {
|
2018-08-09 05:00:11 +02:00
|
|
|
if (conf == null || conf.getKeys(false).isEmpty()) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2018-07-21 02:41:52 +02:00
|
|
|
try {
|
|
|
|
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
|
|
|
OutputStreamWriter writer = new OutputStreamWriter(new GZIPOutputStream(baos), "UTF-8");
|
|
|
|
|
writer.write(conf.saveToString());
|
|
|
|
|
writer.close();
|
|
|
|
|
return baos.toByteArray();
|
|
|
|
|
} catch (IOException e) {
|
2018-07-30 16:41:55 +02:00
|
|
|
throw new RuntimeException("IOException should be impossible for ByteArrayOutputStream", e);
|
2018-07-21 02:41:52 +02:00
|
|
|
}
|
|
|
|
|
}
|
2018-08-09 05:00:11 +02:00
|
|
|
|
|
|
|
|
public static String serializeForSQL(YamlConfiguration conf) {
|
|
|
|
|
return mysqlPrepareBytesForInsertAllowNull(serializeYamlConfiguration(conf));
|
|
|
|
|
}
|
2018-11-09 00:40:36 +01:00
|
|
|
|
|
|
|
|
public static Entity loadChunksForEntity(Chunk chunk, UUID uuid) {
|
|
|
|
|
Entity e = Bukkit.getEntity(uuid);
|
|
|
|
|
if (e != null) {
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
chunk.load();
|
|
|
|
|
e = Bukkit.getEntity(uuid);
|
|
|
|
|
if (e != null) {
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
int chunkx = chunk.getX();
|
|
|
|
|
int chunkz = chunk.getZ();
|
|
|
|
|
for (int i = 0; i < 8; i++) {
|
|
|
|
|
int x = i < 3 ? chunkx - 1 : (i < 5 ? chunkx : chunkx + 1);
|
|
|
|
|
int z = i == 0 || i == 3 || i == 5 ? chunkz - 1 : (i == 1 || i == 6 ? chunkz : chunkz + 1);
|
|
|
|
|
chunk.getWorld().loadChunk(x, z);
|
|
|
|
|
e = Bukkit.getEntity(uuid);
|
|
|
|
|
if (e != null) {
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2011-05-22 04:01:43 +02:00
|
|
|
}
|