Plex-FAWE/worldedit-core/src/main/java/com/boydti/fawe/util/MainUtil.java

897 lines
32 KiB
Java

package com.boydti.fawe.util;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.FaweInputStream;
import com.boydti.fawe.object.FaweOutputStream;
import com.boydti.fawe.object.RegionWrapper;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.object.RunnableVal2;
import com.boydti.fawe.object.changeset.FaweStreamChangeSet;
import com.boydti.fawe.object.io.AbstractDelegateOutputStream;
import com.github.luben.zstd.ZstdInputStream;
import com.github.luben.zstd.ZstdOutputStream;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.DoubleTag;
import com.sk89q.jnbt.IntTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
import com.sk89q.worldedit.history.changeset.ChangeSet;
import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import it.unimi.dsi.fastutil.io.FastBufferedInputStream;
import net.jpountz.lz4.LZ4BlockInputStream;
import net.jpountz.lz4.LZ4BlockOutputStream;
import net.jpountz.lz4.LZ4Compressor;
import net.jpountz.lz4.LZ4Factory;
import net.jpountz.lz4.LZ4FastDecompressor;
import net.jpountz.lz4.LZ4InputStream;
import net.jpountz.lz4.LZ4Utils;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.imageio.ImageIO;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.lang.reflect.Array;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Scanner;
import java.util.UUID;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.regex.Pattern;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import static java.lang.System.arraycopy;
public class MainUtil {
private static final Logger LOGGER = LogManagerCompat.getLogger();
public static List<String> filter(String prefix, List<String> suggestions) {
if (prefix.isEmpty()) {
return suggestions;
}
if (suggestions.getClass() != ArrayList.class) {
suggestions = new ArrayList<>(suggestions);
}
suggestions.removeIf(s -> !s.startsWith(prefix));
return suggestions;
}
public static <T> T getOf(Object[] arr, Class<T> ofType) {
for (Object a : arr) {
if (a != null && a.getClass() == ofType) {
return (T) a;
}
}
return null;
}
public static long getTotalSize(Path path) {
final AtomicLong size = new AtomicLong(0);
traverse(path, new RunnableVal2<Path, BasicFileAttributes>() {
@Override
public void run(Path path, BasicFileAttributes attrs) {
size.addAndGet(attrs.size());
}
});
return size.get();
}
public static void traverse(Path path, final BiConsumer<Path, BasicFileAttributes> onEach) {
try {
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult
visitFile(Path file, BasicFileAttributes attrs) {
onEach.accept(file, attrs);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult
visitFileFailed(Path file, IOException exc) {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult
postVisitDirectory(Path dir, IOException exc) {
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
throw new AssertionError("walkFileTree will not throw IOException if the FileVisitor does not");
}
}
public static File resolveRelative(File file) {
if (!file.exists()) {
return new File(relativize(file.getPath()));
}
return file;
}
public static String relativize(String path) {
String[] split = path.split(Pattern.quote(File.separator));
StringBuilder out = new StringBuilder();
int skip = 0;
int len = split.length - 1;
for (int i = len; i >= 0; i--) {
if (skip > 0) {
skip--;
} else {
String arg = split[i];
if (arg.equals("..")) {
skip++;
} else {
out.insert(0, arg + (i == len ? "" : File.separator));
}
}
}
return out.toString();
}
public static void forEachFile(Path path, final RunnableVal2<Path, BasicFileAttributes> onEach, Comparator<File> comparator) {
File dir = path.toFile();
if (!dir.exists()) {
return;
}
File[] files = path.toFile().listFiles();
if (comparator != null) {
Arrays.sort(files, comparator);
}
for (File file : files) {
Path filePath = file.toPath();
try {
BasicFileAttributes attr = Files.readAttributes(filePath, BasicFileAttributes.class);
onEach.run(file.toPath(), attr);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static int getMaxFileId(File folder) {
final int[] max = new int[1];
folder.listFiles(pathname -> {
String name = pathname.getName();
Integer val = null;
if (pathname.isDirectory()) {
val = StringMan.toInteger(name, 0, name.length());
} else {
int i = name.lastIndexOf('.');
if (i != -1) {
val = StringMan.toInteger(name, 0, i);
}
}
if (val != null && val > max[0]) {
max[0] = val;
}
return false;
});
return max[0] + 1;
}
public static File getFile(File base, String path) {
if (Paths.get(path).isAbsolute()) {
return new File(path);
}
return new File(base, path);
}
public static File getFile(File base, String path, String extension) {
return getFile(base, path.endsWith("." + extension) ? path : path + "." + extension);
}
public static long getSize(ChangeSet changeSet) {
if (changeSet instanceof FaweStreamChangeSet) {
FaweStreamChangeSet fscs = (FaweStreamChangeSet) changeSet;
return fscs.getSizeOnDisk() + fscs.getSizeInMemory();
// } else if (changeSet instanceof CPUOptimizedChangeSet) {
// return changeSet.size() + 32;
} else if (changeSet != null) {
return changeSet.size() * 128;
} else {
return 0;
}
}
public static FaweOutputStream getCompressedOS(OutputStream os, int amount) throws IOException {
return getCompressedOS(os, amount, Settings.IMP.HISTORY.BUFFER_SIZE);
}
private static final LZ4Factory FACTORY = LZ4Factory.fastestInstance();
private static final LZ4Compressor COMPRESSOR = FACTORY.fastCompressor();
private static final LZ4FastDecompressor DECOMPRESSOR = FACTORY.fastDecompressor();
public static int getMaxCompressedLength(int size) {
return LZ4Utils.maxCompressedLength(size);
}
public static int compress(byte[] bytes, int length, byte[] buffer, OutputStream out, Deflater deflate) throws IOException {
if (buffer == null) {
buffer = new byte[8192];
}
if (deflate == null) {
deflate = new Deflater(1, false);
} else {
deflate.reset();
}
deflate.setInput(bytes, 0, length);
deflate.finish();
int written = 0;
while (!deflate.finished()) {
int n = deflate.deflate(buffer);
if (n != 0) {
written += n;
out.write(buffer, 0, n);
}
}
return written;
}
public static byte[] decompress(byte[] bytes, byte[] buffer, Inflater inflater) throws DataFormatException {
if (buffer == null) {
buffer = new byte[8192];
}
if (inflater == null) {
inflater = new Inflater(false);
} else {
inflater.reset();
}
inflater.setInput(bytes);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while (!inflater.finished()) {
int n = inflater.inflate(buffer);
if (n != 0) {
baos.write(buffer, 0, n);
}
}
return baos.toByteArray();
}
public static byte[] compress(byte[] bytes, byte[] buffer, int level) {
if (level == 0) {
return bytes;
}
LZ4Compressor compressor = level == 1 ? COMPRESSOR : FACTORY.highCompressor(level);
int decompressedLength = bytes.length;
if (buffer == null) {
int maxCompressedLength = compressor.maxCompressedLength(decompressedLength);
buffer = new byte[maxCompressedLength];
}
int compressLen = compressor.compress(bytes, 0, decompressedLength, buffer, 0, buffer.length);
return Arrays.copyOf(buffer, compressLen);
}
public static byte[] decompress(byte[] bytes, byte[] buffer, int length, int level) {
if (level == 0) {
return bytes;
}
if (buffer == null) {
buffer = new byte[length];
}
DECOMPRESSOR.decompress(bytes, buffer);
return buffer;
}
public static FaweOutputStream getCompressedOS(OutputStream os, int amount, int buffer) throws IOException {
os.write((byte) 10 + amount);
os = new BufferedOutputStream(os, buffer);
if (amount == 0) {
return new FaweOutputStream(os);
}
int gzipAmount = amount > 6 ? 1 : 0;
for (int i = 0; i < gzipAmount; i++) {
os = new ZstdOutputStream(os, 22);
}
LZ4Factory factory = LZ4Factory.fastestInstance();
int fastAmount = 1 + ((amount - 1) % 3);
for (int i = 0; i < fastAmount; i++) {
os = new LZ4BlockOutputStream(os, buffer, factory.fastCompressor());
}
int highAmount = amount > 3 ? 1 : 0;
for (int i = 0; i < highAmount; i++) {
if (amount == 9) {
os = new LZ4BlockOutputStream(os, buffer, factory.highCompressor(17));
} else {
os = new LZ4BlockOutputStream(os, buffer, factory.highCompressor());
}
}
os = new BufferedOutputStream(os, buffer);
return new FaweOutputStream(os);
}
public static FaweInputStream getCompressedIS(InputStream is) throws IOException {
return getCompressedIS(is, Settings.IMP.HISTORY.BUFFER_SIZE);
}
public static FaweInputStream getCompressedIS(InputStream is, int buffer) throws IOException {
int mode = (byte) is.read();
is = new FastBufferedInputStream(is, buffer);
if (mode == 0) {
return new FaweInputStream(is);
}
boolean legacy;
if (mode >= 10) {
legacy = false;
mode = -mode + 10;
} else {
legacy = true;
}
if (mode == 0) {
return new FaweInputStream(is);
}
int amountAbs = Math.abs(mode);
if (amountAbs > 6) {
if (mode > 0) {
is = new FastBufferedInputStream(new GZIPInputStream(is, buffer));
} else {
is = new ZstdInputStream(is);
}
}
amountAbs = (1 + ((amountAbs - 1) % 3)) + (amountAbs > 3 ? 1 : 0);
for (int i = 0; i < amountAbs; i++) {
if (legacy) {
is = new LZ4InputStream(is);
} else {
is = new LZ4BlockInputStream(is);
}
}
return new FaweInputStream(new FastBufferedInputStream(is));
}
public static URL upload(UUID uuid, String file, String extension, @NotNull final RunnableVal<OutputStream> writeTask) {
return upload(Settings.IMP.WEB.URL, uuid != null, uuid != null ? uuid.toString() : null, file, extension, writeTask);
}
public static URL upload(String urlStr, boolean save, String uuid, String file, String extension, @NotNull final RunnableVal<OutputStream> writeTask) {
String filename = (file == null ? "plot" : file) + (extension != null ? "." + extension : "");
uuid = uuid == null ? UUID.randomUUID().toString() : uuid;
final String website;
if (!save) {
website = urlStr + "upload.php?" + uuid;
} else {
website = urlStr + "save.php?" + uuid;
}
final URL url;
try {
url = new URL(urlStr + "?key=" + uuid + "&type=" + "" + extension);
String boundary = Long.toHexString(System.currentTimeMillis());
URLConnection con = new URL(website).openConnection();
con.setDoOutput(true);
con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
try (OutputStream output = con.getOutputStream(); PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8), true)) {
String crlf = "\r\n";
writer.append("--" + boundary).append(crlf);
writer.append("Content-Disposition: form-data; name=\"param\"").append(crlf);
writer.append("Content-Type: text/plain; charset=" + StandardCharsets.UTF_8.displayName()).append(crlf);
String param = "value";
writer.append(crlf).append(param).append(crlf).flush();
writer.append("--" + boundary).append(crlf);
writer.append("Content-Disposition: form-data; name=\"schematicFile\"; filename=\"" + filename + '"').append(crlf);
writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(filename)).append(crlf);
writer.append("Content-Transfer-Encoding: binary").append(crlf);
writer.append(crlf).flush();
OutputStream nonClosable = new AbstractDelegateOutputStream(new BufferedOutputStream(output)) {
@Override
public void close() {
} // Don't close
};
writeTask.value = nonClosable;
writeTask.run();
nonClosable.flush();
writer.append(crlf).flush();
writer.append("--" + boundary + "--").append(crlf).flush();
}
int responseCode = ((HttpURLConnection) con).getResponseCode();
String content;
try (Scanner scanner = new Scanner(con.getInputStream()).useDelimiter("\\A")) {
content = scanner.next().trim();
}
if (!content.startsWith("<")) {
LOGGER.debug(content);
}
if (responseCode == 200) {
return url;
}
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
/**
* Create a copy of the tag and modify the (x, y, z) coordinates
*
* @param tag Tag to copy
* @param x New X coordinate
* @param y New Y coordinate
* @param z New Z coordinate
* @return New tag
*/
public static @NotNull CompoundTag setPosition(@Nonnull CompoundTag tag, int x, int y, int z) {
Map<String, Tag> value = new HashMap<>(tag.getValue());
value.put("x", new IntTag(x));
value.put("y", new IntTag(y));
value.put("z", new IntTag(z));
return new CompoundTag(value);
}
/**
* Create a copy of the tag and modify the entity inf
*
* @param tag Tag to copy
* @param entity Entity
* @return New tag
*/
public static @NotNull CompoundTag setEntityInfo(@NotNull CompoundTag tag, @NotNull Entity entity) {
Map<String, Tag> map = new HashMap<>(tag.getValue());
map.put("Id", new StringTag(entity.getState().getType().getId()));
ListTag pos = (ListTag) map.get("Pos");
if (pos != null) {
Location loc = entity.getLocation();
// Create a copy, because the list is immutable...
List<Tag> posList = new ArrayList<>(pos.getValue());
posList.set(0, new DoubleTag(loc.getX()));
posList.set(1, new DoubleTag(loc.getY()));
posList.set(2, new DoubleTag(loc.getZ()));
map.put("Pos", new ListTag(pos.getType(), posList));
}
return new CompoundTag(map);
}
public static String getText(String url) throws IOException {
try (Scanner scanner = new Scanner(new URL(url).openStream(), "UTF-8")) {
return scanner.useDelimiter("\\A").next();
}
}
public static void download(URL url, File out) throws IOException {
if (!out.exists()) {
File parent = out.getParentFile();
if (parent != null) {
parent.mkdirs();
}
File tempFile = File.createTempFile(UUID.randomUUID().toString(), ".tmp", parent);
tempFile.deleteOnExit();
try (InputStream is = url.openStream(); ReadableByteChannel rbc = Channels.newChannel(is);
FileOutputStream fos = new FileOutputStream(tempFile)) {
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
}
Files.copy(tempFile.toPath(), out.toPath(), StandardCopyOption.REPLACE_EXISTING);
tempFile.delete();
}
}
public static File getJarFile() {
try {
return getJarFile(Fawe.class);
} catch (MalformedURLException | URISyntaxException | SecurityException e) {
return new File(Fawe.imp().getDirectory().getParentFile(), "FastAsyncWorldEdit.jar");
}
}
public static File getJarFile(Class<?> clazz) throws URISyntaxException, MalformedURLException {
URL url = clazz.getProtectionDomain().getCodeSource().getLocation();
return new File(new URL(url.toURI().toString().split("\\!")[0].replaceAll("jar:file", "file")).toURI().getPath());
}
public static Thread[] getThreads() {
ThreadGroup rootGroup = Thread.currentThread( ).getThreadGroup( );
ThreadGroup parentGroup;
while ( ( parentGroup = rootGroup.getParent() ) != null ) {
rootGroup = parentGroup;
}
Thread[] threads = new Thread[ rootGroup.activeCount() ];
if (threads.length != 0) {
while (rootGroup.enumerate(threads, true) == threads.length) {
threads = new Thread[threads.length * 2];
}
}
return threads;
}
public static File copyFile(File sourceFile, File destFile) throws IOException {
if (!destFile.exists()) {
File parent = destFile.getParentFile();
if (parent != null) {
parent.mkdirs();
}
destFile.createNewFile();
}
try (FileInputStream fIn = new FileInputStream(sourceFile); FileChannel source = fIn.getChannel();
FileOutputStream fOut = new FileOutputStream(destFile); FileChannel destination = fOut.getChannel()) {
long transferred = 0;
long bytes = source.size();
while (transferred < bytes) {
transferred += destination.transferFrom(source, 0, source.size());
destination.position(transferred);
}
}
return destFile;
}
public static BufferedImage readImage(InputStream in) throws IOException {
return MainUtil.toRGB(ImageIO.read(in));
}
public static BufferedImage readImage(URL url) throws IOException {
return readImage(url.openStream());
}
public static BufferedImage readImage(File file) throws IOException {
return readImage(new FileInputStream(file));
}
public static BufferedImage toRGB(BufferedImage src) {
if (src == null) {
return src;
}
BufferedImage img = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.drawImage(src, 0, 0, null);
g2d.dispose();
return img;
}
public static File copyFile(File jar, String resource, File output) {
return copyFile(jar, resource, output, resource);
}
public static File copyFile(File jar, String resource, File output, String fileName) {
try {
if (output == null) {
output = Fawe.imp().getDirectory();
}
if (!output.exists()) {
output.mkdirs();
}
File newFile = new File(output, fileName);
if (newFile.exists()) {
return newFile;
}
try (InputStream stream = Fawe.class.getResourceAsStream(resource.startsWith("/") ? resource : "/" + resource)) {
byte[] buffer = new byte[2048];
if (stream == null) {
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(jar))) {
ZipEntry ze = zis.getNextEntry();
while (ze != null) {
String name = ze.getName();
if (name.equals(resource)) {
try (FileOutputStream fos = new FileOutputStream(newFile)) {
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
}
ze = null;
} else {
ze = zis.getNextEntry();
}
}
zis.closeEntry();
}
return newFile;
}
File parent = newFile.getParentFile();
if (!parent.exists()) {
parent.mkdirs();
}
newFile.createNewFile();
try (FileOutputStream fos = new FileOutputStream(newFile)) {
int len;
while ((len = stream.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
}
return newFile;
}
} catch (IOException e) {
LOGGER.debug("Could not save " + resource, e);
}
return null;
}
public static int[] regionNameToCoords(String fileName) {
int[] res = new int[2];
int len = fileName.length() - 4;
int val = 0;
boolean reading = false;
int index = 1;
int numIndex = 1;
for (int i = len; i >= 2; i--) {
char c = fileName.charAt(i);
if (!reading) {
reading = (c == '.');
continue;
}
switch (c) {
case '-':
val = -val;
break;
case '.':
res[index--] = val;
if (index == -1) {
return res;
}
val = 0;
numIndex = 1;
break;
default:
val = val + (c - 48) * numIndex;
numIndex *= 10;
break;
}
}
res[index] = val;
return res;
}
public static File resolve(File dir, String filename, @Nullable ClipboardFormat format, boolean allowDir) {
if (format != null) {
if (!filename.matches(".*\\.[\\w].*")) {
filename = filename + "." + format.getPrimaryFileExtension();
}
return MainUtil.resolveRelative(new File(dir, filename));
}
if (allowDir) {
File file = MainUtil.resolveRelative(new File(dir, filename));
if (file.exists() && file.isDirectory()) {
return file;
}
}
for (ClipboardFormat f : ClipboardFormats.getAll()) {
File file = MainUtil.resolveRelative(new File(dir, filename + "." + f.getPrimaryFileExtension()));
if (file.exists()) {
return file;
}
}
return null;
}
public static boolean isInSubDirectory(File dir, File file) throws IOException {
if (file == null) {
return false;
}
if (file.equals(dir)) {
return true;
}
file = file.getCanonicalFile();
dir = dir.getCanonicalFile();
return isInSubDirectory(dir, file.getParentFile());
}
public static void iterateFiles(File directory, Consumer<File> task) {
if (directory.exists()) {
File[] files = directory.listFiles();
if (null != files) {
for (File file : files) {
if (file.isDirectory()) {
iterateFiles(file, task);
} else {
task.accept(file);
}
}
}
}
}
/**
* The int[] will be in the form: [chunkx, chunkz, pos1x, pos1z, pos2x, pos2z, isedge] and will represent the bottom and top parts of the chunk
*/
public static void chunkTaskSync(RegionWrapper region, final RunnableVal<int[]> task) {
final int p1x = region.minX;
final int p1z = region.minZ;
final int p2x = region.maxX;
final int p2z = region.maxZ;
final int bcx = p1x >> 4;
final int bcz = p1z >> 4;
final int tcx = p2x >> 4;
final int tcz = p2z >> 4;
task.value = new int[7];
for (int x = bcx; x <= tcx; x++) {
for (int z = bcz; z <= tcz; z++) {
task.value[0] = x;
task.value[1] = z;
task.value[2] = task.value[0] << 4;
task.value[3] = task.value[1] << 4;
task.value[4] = task.value[2] + 15;
task.value[5] = task.value[3] + 15;
task.value[6] = 0;
if (task.value[0] == bcx) {
task.value[2] = p1x;
task.value[6] = 1;
}
if (task.value[0] == tcx) {
task.value[4] = p2x;
task.value[6] = 1;
}
if (task.value[1] == bcz) {
task.value[3] = p1z;
task.value[6] = 1;
}
if (task.value[1] == tcz) {
task.value[5] = p2z;
task.value[6] = 1;
}
task.run();
}
}
}
public static Object copyNd(Object arr) {
if (arr.getClass().isArray()) {
int innerArrayLength = Array.getLength(arr);
Class<?> component = arr.getClass().getComponentType();
Object newInnerArray = Array.newInstance(component, innerArrayLength);
if (component.isPrimitive()) {
arraycopy(arr, 0, newInnerArray, 0, innerArrayLength);
} else {
//copy each elem of the array
for (int i = 0; i < innerArrayLength; i++) {
Object elem = copyNd(Array.get(arr, i));
Array.set(newInnerArray, i, elem);
}
}
return newInnerArray;
} else {
return arr;//can't deep copy an opac object??
}
}
public static String secToTime(long time) {
StringBuilder toreturn = new StringBuilder();
if (time >= 33868800) {
int years = (int) (time / 33868800);
int time1 = years * 33868800;
time -= time1;
toreturn.append(years + "y ");
}
if (time >= 604800) {
int weeks = (int) (time / 604800);
time -= weeks * 604800;
toreturn.append(weeks + "w ");
}
if (time >= 86400) {
int days = (int) (time / 86400);
time -= days * 86400;
toreturn.append(days + "d ");
}
if (time >= 3600) {
int hours = (int) (time / 3600);
time -= hours * 3600;
toreturn.append(hours + "h ");
}
if (time >= 60) {
int minutes = (int) (time / 60);
time -= minutes * 60;
toreturn.append(minutes + "m ");
}
if (toreturn.equals("") || time > 0) {
toreturn.append((time) + "s ");
}
return toreturn.toString().trim();
}
public static long timeToSec(String string) {
if (MathMan.isInteger(string)) {
return Long.parseLong(string);
}
string = string.toLowerCase(Locale.ROOT).trim().toLowerCase(Locale.ROOT);
if (string.equalsIgnoreCase("false")) {
return 0;
}
String[] split = string.split(" ");
long time = 0;
for (String value : split) {
int nums = Integer.parseInt(value.replaceAll("[^\\d]", ""));
String letters = value.replaceAll("[^a-z]", "");
switch (letters) {
case "week":
case "weeks":
case "wks":
case "w":
time += 604800 * nums;
case "days":
case "day":
case "d":
time += 86400 * nums;
case "hour":
case "hr":
case "hrs":
case "hours":
case "h":
time += 3600 * nums;
case "minutes":
case "minute":
case "mins":
case "min":
case "m":
time += 60 * nums;
case "seconds":
case "second":
case "secs":
case "sec":
case "s":
time += nums;
}
}
return time;
}
public static void deleteOlder(File directory, final long timeDiff, boolean printDebug) {
final long now = System.currentTimeMillis();
ForkJoinPool pool = new ForkJoinPool();
iterateFiles(directory, file -> {
long age = now - file.lastModified();
if (age > timeDiff) {
pool.submit(file::delete);
Component msg = TranslatableComponent.of("worldedit.schematic.delete.deleted");
if (printDebug) {
LOGGER.debug(msg.toString());
}
}
});
pool.shutdown();
try {
pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}