As Jesse would say... *

This commit is contained in:
MattBDev
2019-06-20 20:05:18 -04:00
parent 9d1117303c
commit 0313320816
146 changed files with 906 additions and 2252 deletions

View File

@ -402,7 +402,7 @@ public class Fawe {
}
} catch (Throwable e) {
debug("====== MEMORY LISTENER ERROR ======");
MainUtil.handleError(e, false);
MainUtil.handleError(e);
debug("===================================");
debug("FAWE needs access to the JVM memory system:");
debug(" - Change your Java security settings");

View File

@ -6,7 +6,6 @@ import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
import com.boydti.fawe.object.number.MutableLong;
import com.boydti.fawe.util.ArrayUtil;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.ReflectionUtils;
@ -191,8 +190,8 @@ public class MCAChunk extends FaweChunk<Void> {
setNibble(endIndex, thisSkyLight, (byte) 0);
setNibble(endIndex, thisBlockLight, (byte) 0);
}
ArrayUtil.fill(thisSkyLight, startIndexShift, endIndexShift + 1, (byte) 0);
ArrayUtil.fill(thisBlockLight, startIndexShift, endIndexShift + 1, (byte) 0);
Arrays.fill(thisSkyLight, startIndexShift, endIndexShift + 1, (byte) 0);
Arrays.fill(thisBlockLight, startIndexShift, endIndexShift + 1, (byte) 0);
}
}
continue;
@ -292,8 +291,8 @@ public class MCAChunk extends FaweChunk<Void> {
if (otherIds == null) {
if (currentIds != null) {
Arrays.fill(currentIds, indexStart, indexEnd, 0);
ArrayUtil.fill(skyLight[thisLayer], indexStartShift, indexEndShift, (byte) 0);
ArrayUtil.fill(blockLight[thisLayer], indexStartShift, indexEndShift, (byte) 0);
Arrays.fill(skyLight[thisLayer], indexStartShift, indexEndShift, (byte) 0);
Arrays.fill(blockLight[thisLayer], indexStartShift, indexEndShift, (byte) 0);
}
} else {
if (currentIds == null) {
@ -320,8 +319,8 @@ public class MCAChunk extends FaweChunk<Void> {
continue;
}
Arrays.fill(thisIds, thisStartIndex, thisStartIndex + 256, 0);
ArrayUtil.fill(this.skyLight[thisLayer], thisStartIndexShift, thisStartIndexShift + 128, (byte) 0);
ArrayUtil.fill(this.blockLight[thisLayer], thisStartIndexShift, thisStartIndexShift + 128, (byte) 0);
Arrays.fill(this.skyLight[thisLayer], thisStartIndexShift, thisStartIndexShift + 128, (byte) 0);
Arrays.fill(this.blockLight[thisLayer], thisStartIndexShift, thisStartIndexShift + 128, (byte) 0);
continue;
} else if (thisIds == null) {
ids[thisLayer] = thisIds = new int[4096];

View File

@ -3,7 +3,6 @@ package com.boydti.fawe.jnbt.anvil.filters;
import com.boydti.fawe.jnbt.anvil.MCAChunk;
import com.boydti.fawe.jnbt.anvil.MCAFilterCounter;
import com.boydti.fawe.object.number.MutableLong;
import com.boydti.fawe.util.ArrayUtil;
import com.sk89q.worldedit.world.block.BlockTypes;
import java.util.Arrays;

View File

@ -10,18 +10,35 @@ import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.object.task.SimpleAsyncNotifyQueue;
import com.boydti.fawe.regions.FaweMaskManager;
import com.boydti.fawe.util.*;
import com.boydti.fawe.util.EditSessionBuilder;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.SetQueue;
import com.boydti.fawe.util.TaskManager;
import com.boydti.fawe.util.WEManager;
import com.boydti.fawe.wrappers.LocationMaskedPlayerWrapper;
import com.boydti.fawe.wrappers.PlayerWrapper;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.worldedit.*;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.EmptyClipboardException;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.extension.platform.*;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.CommandManager;
import com.sk89q.worldedit.extension.platform.PlatformManager;
import com.sk89q.worldedit.extension.platform.PlayerProxy;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.*;
import com.sk89q.worldedit.regions.ConvexPolyhedralRegion;
import com.sk89q.worldedit.regions.CylinderRegion;
import com.sk89q.worldedit.regions.Polygonal2DRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionOperationException;
import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.regions.selector.ConvexPolyhedralRegionSelector;
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
import com.sk89q.worldedit.regions.selector.CylinderRegionSelector;
@ -32,9 +49,12 @@ import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.NumberFormat;
import java.util.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
@ -263,7 +283,7 @@ public abstract class FawePlayer<T> extends Metadatable {
e = e.getCause();
}
if (e instanceof WorldEditException) {
sendMessage(BBC.getPrefix() + e.getLocalizedMessage());
sendMessage(e.getLocalizedMessage());
} else {
FaweException fe = FaweException.get(e);
if (fe != null) {
@ -333,7 +353,7 @@ public abstract class FawePlayer<T> extends Metadatable {
}
} catch (Exception event) {
Fawe.debug("====== INVALID CLIPBOARD ======");
MainUtil.handleError(event, false);
MainUtil.handleError(event);
Fawe.debug("===============---=============");
Fawe.debug("This shouldn't result in any failure");
Fawe.debug("File: " + file.getName() + " (len:" + file.length() + ")");

View File

@ -1,27 +0,0 @@
package com.boydti.fawe.util;
import java.util.Arrays;
public class ArrayUtil {
public static final void fill(byte[] a, int fromIndex, int toIndex, byte val) {
for (int i = fromIndex; i < toIndex; i++) a[i] = val;
}
public static final void fill(char[] a, int fromIndex, int toIndex, char val) {
for (int i = fromIndex; i < toIndex; i++) a[i] = val;
}
public static <T> T[] concatAll(T[] first, T[]... rest) {
int totalLength = first.length;
for (T[] array : rest) {
totalLength += array.length;
}
T[] result = Arrays.copyOf(first, totalLength);
int offset = first.length;
for (T[] array : rest) {
System.arraycopy(array, 0, result, offset, array.length);
offset += array.length;
}
return result;
}
}

View File

@ -52,7 +52,7 @@ public class ColorUtil {
float g = parseComponent(color, rend+1, gend, PARSE_COMPONENT);
float b = parseComponent(color, gend+1, bend, PARSE_COMPONENT);
return new Color(r, g, b);
} catch (NumberFormatException nfe) {}
} catch (NumberFormatException ignored) {}
throw new IllegalArgumentException("Invalid color specification");
}
@ -67,7 +67,7 @@ public class ColorUtil {
float s = parseComponent(color, hend+1, send, PARSE_PERCENT);
float l = parseComponent(color, send+1, lend, PARSE_PERCENT);
return Color.getHSBColor(h, s, l);
} catch (NumberFormatException nfe) {}
} catch (NumberFormatException ignored) {}
throw new IllegalArgumentException("Invalid color specification");
}
@ -102,7 +102,7 @@ public class ColorUtil {
} else {
Color col = null;
try {
Field field = java.awt.Color.class.getField(color.toLowerCase());
Field field = Color.class.getField(color.toLowerCase());
col = (Color) field.get(null);
} catch (Throwable ignore) {}
if (col != null) {
@ -116,7 +116,6 @@ public class ColorUtil {
int r;
int g;
int b;
int a;
if (len == 3) {
r = Integer.parseInt(color.substring(0, 1), 16);
@ -139,7 +138,7 @@ public class ColorUtil {
b = Integer.parseInt(color.substring(4, 6), 16);
return new Color(r, g, b);
}
} catch (NumberFormatException nfe) {}
} catch (NumberFormatException ignored) {}
throw new IllegalArgumentException("Invalid color specification");
}

View File

@ -1,5 +1,7 @@
package com.boydti.fawe.util;
import java.util.Arrays;
public class FaweTimer implements Runnable {
private final double[] history = new double[]{20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d};
@ -7,7 +9,6 @@ public class FaweTimer implements Runnable {
private long lastPoll = System.currentTimeMillis();
private long tickStart = System.currentTimeMillis();
private final long tickInterval = 5;
private final double millisPer20Interval = tickInterval * 50 * 20;
private long tick = 0;
private long tickMod = 0;
@ -24,6 +25,7 @@ public class FaweTimer implements Runnable {
if (timeSpent == 0) {
timeSpent = 1;
}
double millisPer20Interval = tickInterval * 50 * 20;
double tps = millisPer20Interval / timeSpent;
history[historyIndex++] = tps;
if (historyIndex >= history.length) {
@ -39,10 +41,7 @@ public class FaweTimer implements Runnable {
if (tick < lastGetTPSTick + tickInterval) {
return lastGetTPSValue;
}
double total = 0;
for (double tps : history) {
total += tps;
}
double total = Arrays.stream(history).sum();
lastGetTPSValue = total / history.length;
lastGetTPSTick = tick;
return lastGetTPSValue;

View File

@ -1,9 +1,5 @@
package com.boydti.fawe.util;
import com.boydti.fawe.FaweCache;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
@ -41,4 +37,4 @@ public class FilteredTextureUtil extends TextureUtil {
}
this.calculateLayerArrays();
}
}
}

View File

@ -8,6 +8,7 @@ import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Base64;
import java.util.stream.Collectors;
public class ImgurUtility {
public static final String CLIENT_ID = "50e34b65351eb07";
@ -48,17 +49,14 @@ public class ImgurUtility {
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.connect();
StringBuilder stb = new StringBuilder();
String stb;
try (OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream())) {
wr.write(data);
wr.flush();
try (BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
String line;
while ((line = rd.readLine()) != null) {
stb.append(line).append("\n");
}
stb = rd.lines().map(line -> line + "\n").collect(Collectors.joining());
}
}
return stb.toString();
return stb;
}
}

View File

@ -3,19 +3,35 @@ package com.boydti.fawe.util;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.*;
import com.boydti.fawe.object.FaweInputStream;
import com.boydti.fawe.object.FaweOutputStream;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.RegionWrapper;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.object.RunnableVal2;
import com.boydti.fawe.object.changeset.CPUOptimizedChangeSet;
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.*;
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.util.Location;
import net.jpountz.lz4.*;
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 javax.annotation.Nullable;
import javax.imageio.ImageIO;
@ -24,23 +40,41 @@ import java.awt.image.BufferedImage;
import java.io.*;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.net.*;
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.*;
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.List;
import java.util.*;
import java.util.Map.Entry;
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.*;
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;
@ -105,10 +139,6 @@ public class MainUtil {
return Double.parseDouble(version.substring(0, pos));
}
public static void stacktrace() {
new Exception().printStackTrace();
}
public static void traverse(Path path, final BiConsumer<Path, BasicFileAttributes> onEach) {
try {
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@ -201,10 +231,6 @@ public class MainUtil {
return getFile(base, path.endsWith("." + extension) ? path : path + "." + extension);
}
public static FaweOutputStream getCompressedOS(OutputStream os) throws IOException {
return getCompressedOS(os, Settings.IMP.HISTORY.COMPRESSION_LEVEL);
}
public static long getSize(ChangeSet changeSet) {
if (changeSet instanceof FaweStreamChangeSet) {
FaweStreamChangeSet fscs = (FaweStreamChangeSet) changeSet;
@ -230,7 +256,7 @@ public class MainUtil {
return LZ4Utils.maxCompressedLength(size);
}
public static byte[] compress(byte[] bytes, byte[] buffer, Deflater deflate) throws IOException {
public static byte[] compress(byte[] bytes, byte[] buffer, Deflater deflate) {
if (buffer == null) {
buffer = new byte[8192];
}
@ -359,7 +385,7 @@ public class MainUtil {
}
public static URL upload(UUID uuid, String file, String extension, final RunnableVal<OutputStream> writeTask) {
return upload(Settings.IMP.WEB.URL, uuid != null, uuid != null ? uuid.toString() : (String) null, file, extension, 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, final RunnableVal<OutputStream> writeTask) {
@ -397,7 +423,7 @@ public class MainUtil {
writer.append(CRLF).flush();
OutputStream nonClosable = new AbstractDelegateOutputStream(new BufferedOutputStream(output)) {
@Override
public void close() throws IOException {
public void close() {
} // Don't close
};
writeTask.value = nonClosable;
@ -444,36 +470,6 @@ public class MainUtil {
}
}
private static final Class[] parameters = new Class[]{URL.class};
public static ClassLoader loadURLClasspath(URL u) throws IOException {
ClassLoader sysloader = ClassLoader.getSystemClassLoader();
Class sysclass = URLClassLoader.class;
try {
Method method = sysclass.getDeclaredMethod("addURL", parameters);
method.setAccessible(true);
if (sysloader instanceof URLClassLoader) {
method.invoke(sysloader, new Object[]{u});
} else {
ClassLoader loader = MainUtil.class.getClassLoader();
while (!(loader instanceof URLClassLoader) && loader.getParent() != null) {
loader = loader.getParent();
}
if (loader instanceof URLClassLoader) {
method.invoke(sysloader, new Object[]{u});
} else {
loader = new URLClassLoader(new URL[]{u}, MainUtil.class.getClassLoader());
return loader;
}
}
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return sysloader;
}
public static String getText(String url) throws IOException {
try (Scanner scanner = new Scanner(new URL(url).openStream(), "UTF-8")) {
return scanner.useDelimiter("\\A").next();
@ -481,8 +477,8 @@ public class MainUtil {
}
public static void download(URL url, File out) throws IOException {
File parent = out.getParentFile();
if (!out.exists()) {
File parent = out.getParentFile();
if (parent != null) {
parent.mkdirs();
}
@ -666,30 +662,10 @@ public class MainUtil {
}
public static void handleError(Throwable e) {
handleError(e, true);
}
public static void handleError(Throwable e, boolean debug) {
if (e == null) {
return;
}
// if (!debug) {
e.printStackTrace();
return;
// }
// String header = "====== FAWE: " + e.getLocalizedMessage() + " ======";
// Fawe.debug(header);
// String[] trace = getTrace(e);
// for (int i = 0; i < trace.length && i < 8; i++) {
// Fawe.debug(" - " + trace[i]);
// }
// String[] cause = getTrace(e.getCause());
// Fawe.debug("Cause: " + (cause.length == 0 ? "N/A" : ""));
// for (int i = 0; i < cause.length && i < 8; i++) {
// Fawe.debug(" - " + cause[i]);
// }
// Fawe.debug(StringMan.repeat("=", header.length()));
}
e.printStackTrace(); }
public static String[] getTrace(Throwable e) {
if (e == null) {
@ -732,40 +708,10 @@ public class MainUtil {
return msg;
}
public static void warnDeprecated(Class... alternatives) {
StackTraceElement[] stacktrace = new RuntimeException().getStackTrace();
if (stacktrace.length > 1) {
for (int i = 1; i < stacktrace.length; i++) {
StackTraceElement stack = stacktrace[i];
String s = stack.toString();
if (s.startsWith("com.sk89q")) {
continue;
}
try {
StackTraceElement creatorElement = stacktrace[1];
String className = creatorElement.getClassName();
Class clazz = Class.forName(className);
String creator = clazz.getSimpleName();
String packageName = clazz.getPackage().getName();
StackTraceElement deprecatedElement = stack;
String myName = Class.forName(deprecatedElement.getClassName()).getSimpleName();
Fawe.debug("@" + creator + " used by " + myName + "." + deprecatedElement.getMethodName() + "():" + deprecatedElement.getLineNumber() + " is deprecated.");
Fawe.debug(" - Alternatives: " + StringMan.getString(alternatives));
} catch (Throwable throwable) {
throwable.printStackTrace();
} finally {
break;
}
}
}
}
public static int[] regionNameToCoords(String fileName) {
int[] res = new int[2];
int len = fileName.length() - 4;
int val = 0;
boolean neg = false;
boolean reading = false;
int index = 1;
int numIndex = 1;
@ -904,7 +850,9 @@ public class MainUtil {
StringBuilder toreturn = new StringBuilder();
if (time >= 33868800) {
int years = (int) (time / 33868800);
time -= years * 33868800;
int time1 = years * 33868800;
System.out.println(time1);
time -= time1;
toreturn.append(years + "y ");
}
if (time >= 604800) {
@ -980,10 +928,6 @@ public class MainUtil {
return time;
}
public static void deleteOlder(File directory, final long timeDiff) {
deleteOlder(directory, timeDiff, true);
}
public static void deleteOlder(File directory, final long timeDiff, boolean printDebug) {
final long now = System.currentTimeMillis();
ForkJoinPool pool = new ForkJoinPool();
@ -1002,45 +946,6 @@ public class MainUtil {
}
}
public static boolean deleteDirectory(File directory) {
return deleteDirectory(directory, true);
}
public static boolean deleteDirectory(File directory, boolean printDebug) {
if (directory.exists()) {
File[] files = directory.listFiles();
if (null != files) {
for (File file : files) {
if (file.isDirectory()) {
deleteDirectory(file, printDebug);
} else {
file.delete();
if (printDebug) BBC.FILE_DELETED.send(null, file);
}
}
}
}
return (directory.delete());
}
public static boolean isValidTag(Tag tag) {
if (tag instanceof EndTag) {
return false;
} else if (tag instanceof ListTag) {
ListTag lt = (ListTag) tag;
if ((lt).getType() == EndTag.class) {
return false;
}
} else if (tag instanceof CompoundTag) {
for (Entry<String, Tag> entry : ((CompoundTag) tag).getValue().entrySet()) {
if (!isValidTag(entry.getValue())) {
return false;
}
}
}
return true;
}
public enum OS {
LINUX, WINDOWS, MACOS, UNKNOWN;
}

View File

@ -89,12 +89,10 @@ public class RandomTextureUtil extends CachedTextureUtil {
BlockType res = super.getNearestBlock(offsetColor);
if (res == null) return null;
int newColor = getColor(res);
{
byte dr = (byte) (((color >> 16) & 0xFF) - ((newColor >> 16) & 0xFF));
byte dg = (byte) (((color >> 8) & 0xFF) - ((newColor >> 8) & 0xFF));
byte db = (byte) (((color >> 0) & 0xFF) - ((newColor >> 0) & 0xFF));
offsets.put(color, (Integer) ((dr << 16) + (dg << 8) + (db << 0)));
}
byte dr = (byte) (((color >> 16) & 0xFF) - ((newColor >> 16) & 0xFF));
byte dg = (byte) (((color >> 8) & 0xFF) - ((newColor >> 8) & 0xFF));
byte db = (byte) (((color >> 0) & 0xFF) - ((newColor >> 0) & 0xFF));
offsets.put(color, (Integer) ((dr << 16) + (dg << 8) + (db << 0)));
return res;
}
}

View File

@ -1,5 +1,9 @@
package com.boydti.fawe.util;
import sun.reflect.ConstructorAccessor;
import sun.reflect.FieldAccessor;
import sun.reflect.ReflectionFactory;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
@ -7,17 +11,13 @@ import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import sun.reflect.ConstructorAccessor;
import sun.reflect.FieldAccessor;
import sun.reflect.ReflectionFactory;
/**
* @author DPOH-VAR
* @version 1.0
*/
@SuppressWarnings({"UnusedDeclaration", "rawtypes"})
public class ReflectionUtils {
public static <T> T as(Class<T> t, Object o) {
return t.isInstance(o) ? t.cast(o) : null;
@ -77,46 +77,6 @@ public class ReflectionUtils {
}
}
public static <T extends Enum<?>> void clearEnum(Class<T> enumType) {
// 0. Sanity checks
if (!Enum.class.isAssignableFrom(enumType)) {
throw new RuntimeException("class " + enumType + " is not an instance of Enum");
}
// 1. Lookup "$VALUES" holder in enum class and get previous enum instances
Field valuesField = null;
Field[] fields = enumType.getDeclaredFields();
for (Field field : fields) {
if (field.getName().contains("$VALUES")) {
valuesField = field;
break;
}
}
AccessibleObject.setAccessible(new Field[]{valuesField}, true);
try {
setFailsafeFieldValue(valuesField, null, Array.newInstance(enumType, 0));
// 6. Clean enum cache
cleanEnumCache(enumType);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage(), e);
}
}
public static <T extends Enum<?>> void copyEnum(T dest, String value, Class<?>[] additionalTypes, Object[] additionalValues) {
try {
Class<? extends Enum> clazz = dest.getClass();
Object newEnum = makeEnum(clazz, value, dest.ordinal(), additionalTypes, additionalValues);
for (Field field : clazz.getDeclaredFields()) {
if (Modifier.isStatic(field.getModifiers())) continue;
field.setAccessible(true);
Object newValue = field.get(newEnum);
setField(field, dest, newValue);
}
} catch (Throwable e) {
e.printStackTrace();
}
}
public static Object makeEnum(Class<?> enumClass, String value, int ordinal,
Class<?>[] additionalTypes, Object[] additionalValues) throws Exception {
Object[] parms = new Object[additionalValues.length + 2];
@ -358,15 +318,6 @@ public class ReflectionUtils {
}
}
public static void setField(String fieldName, Object instance, Object value) {
try {
Field field = instance.getClass().getDeclaredField(fieldName);
setField(field, instance, value);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
}
public static void setField(final Field field, final Object instance, final Object value) {
if (field == null) {
throw new RuntimeException("No such field");

View File

@ -1,738 +0,0 @@
package com.boydti.fawe.util;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.FlatteningPathIterator;
import java.awt.geom.IllegalPathStateException;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.Vector;
/**
* <a href="https://github.com/Sciss/ShapeInterpolator/blob/master/src/main/java/de/sciss/shapeint/ShapeInterpolator.java">Original source</a><br>
* An interpolator for {@link Shape} objects.
* This class can be used to morph between the geometries
* of two relatively arbitrary shapes with the only restrictions being
* that the two different numbers of sub-paths or two shapes with
* disparate winding rules may not blend together in a pleasing
* manner.
* The ShapeEvaluator will do the best job it can if the shapes do
* not match in winding rule or number of sub-paths, but the geometry
* of the shapes may need to be adjusted by other means to make the
* shapes more like each other for best aesthetic effect.
* <p>
* Note that the process of comparing two geometries and finding similar
* structures between them to blend for the morphing operation can be
* expensive.
* Instances of this class will properly perform the necessary
* geometric analysis of their arguments on every method call and attempt
* to cache the information so that they can operate more quickly if called
* multiple times in a row on the same pair of {@code Shape} objects.
* As a result attempting to mutate a {@code Shape} object that is stored
* in one of their keyframes may not have any effect if the associated
* interpolator has already cached the geometry.
* Also, it is advisable to use different instances of {@code ShapeEvaluator}
* for every pair of keyframes being morphed so that the cached information
* can be reused as much as possible.
*/
public class ShapeInterpolator {
private Shape savedV0;
private Shape savedV1;
private Geometry geom0;
private Geometry geom1;
public static Shape apply(Shape v0, Shape v1, float fraction) {
return apply(v0, v1, fraction, false);
}
public static Shape apply(Shape v0, Shape v1, float fraction, boolean unionBounds) {
final ShapeInterpolator instance = new ShapeInterpolator();
return instance.evaluate(v0, v1, fraction, unionBounds);
}
/**
* Creates an interpolated shape from tight bounds.
*/
public Shape evaluate(Shape v0, Shape v1, float fraction) {
return evaluate(v0, v1, fraction, false);
}
/**
* Creates an interpolated shape.
*
* @param v0 the first shape
* @param v1 the second shape
* @param fraction the fraction from zero (just first shape) to one (just second shape)
* @param unionBounds if `true`, the shape reports bounds which are the union of
* the bounds of both shapes, if `false` it reports "tight" bounds
* using the actual interpolated path.
*/
public Shape evaluate(Shape v0, Shape v1, float fraction, boolean unionBounds) {
if (savedV0 != v0 || savedV1 != v1) {
if (savedV0 == v1 && savedV1 == v0) {
// Just swap the geometries
final Geometry tmp = geom0;
geom0 = geom1;
geom1 = tmp;
} else {
recalculate(v0, v1);
}
savedV0 = v0;
savedV1 = v1;
}
return getShape(fraction, unionBounds);
}
private void recalculate(Shape v0, Shape v1) {
geom0 = new Geometry(v0);
geom1 = new Geometry(v1);
final float[] tVals0 = geom0.getTVals();
final float[] tVals1 = geom1.getTVals();
final float[] masterTVals = mergeTVals(tVals0, tVals1);
geom0.setTVals(masterTVals);
geom1.setTVals(masterTVals);
}
private Shape getShape(float fraction, boolean unionBounds) {
return new MorphedShape(geom0, geom1, fraction, unionBounds);
}
private static float[] mergeTVals(float[] tVals0, float[] tVals1) {
final int count = sortTVals(tVals0, tVals1, null);
final float[] newTVals = new float[count];
sortTVals(tVals0, tVals1, newTVals);
return newTVals;
}
private static int sortTVals(float[] tVals0,
float[] tVals1,
float[] newTVals) {
int i0 = 0;
int i1 = 0;
int numTVals = 0;
while (i0 < tVals0.length && i1 < tVals1.length) {
final float t0 = tVals0[i0];
final float t1 = tVals1[i1];
if (t0 <= t1) {
if (newTVals != null) {
newTVals[numTVals] = t0;
}
i0++;
}
if (t1 <= t0) {
if (newTVals != null) {
newTVals[numTVals] = t1;
}
i1++;
}
numTVals++;
}
return numTVals;
}
private static float interp(float v0, float v1, float t) {
return (v0 + ((v1 - v0) * t));
}
private static class Geometry {
static final float THIRD = (1f / 3f);
static final float MIN_LEN = 0.001f;
final int windingRule;
float[] bezierCoordinates;
int numCoordinates;
float[] myTVals;
public Geometry(Shape s) {
// Multiple of 6 plus 2 more for initial move-to
bezierCoordinates = new float[20];
final PathIterator pi = s.getPathIterator(null);
windingRule = pi.getWindingRule();
if (pi.isDone()) {
// We will have 1 segment and it will be all zeros
// It will have 8 coordinates (2 for move-to, 6 for cubic)
numCoordinates = 8;
}
final float[] coordinates = new float[6];
int type = pi.currentSegment(coordinates);
pi.next();
if (type != PathIterator.SEG_MOVETO) {
throw new IllegalPathStateException("missing initial move-to");
}
float curX, curY, movX, movY;
bezierCoordinates[0] = curX = movX = coordinates[0];
bezierCoordinates[1] = curY = movY = coordinates[1];
float newX, newY;
final Vector<Point2D.Float> savedPathEndPoints = new Vector<>();
numCoordinates = 2;
while (!pi.isDone()) {
switch (pi.currentSegment(coordinates)) {
case PathIterator.SEG_MOVETO:
if (curX != movX || curY != movY) {
appendLineTo(curX, curY, movX, movY);
curX = movX;
curY = movY;
}
newX = coordinates[0];
newY = coordinates[1];
if (curX != newX || curY != newY) {
savedPathEndPoints.add(new Point2D.Float(movX, movY));
appendLineTo(curX, curY, newX, newY);
curX = movX = newX;
curY = movY = newY;
}
break;
case PathIterator.SEG_CLOSE:
if (curX != movX || curY != movY) {
appendLineTo(curX, curY, movX, movY);
curX = movX;
curY = movY;
}
break;
case PathIterator.SEG_LINETO:
newX = coordinates[0];
newY = coordinates[1];
appendLineTo(curX, curY, newX, newY);
curX = newX;
curY = newY;
break;
case PathIterator.SEG_QUADTO:
final float ctrlX = coordinates[0];
final float ctrlY = coordinates[1];
newX = coordinates[2];
newY = coordinates[3];
appendQuadTo(curX, curY, ctrlX, ctrlY, newX, newY);
curX = newX;
curY = newY;
break;
case PathIterator.SEG_CUBICTO:
newX = coordinates[4];
newY = coordinates[5];
appendCubicTo(
coordinates[0], coordinates[1],
coordinates[2], coordinates[3],
newX, newY);
curX = newX;
curY = newY;
break;
}
pi.next();
}
// Add closing segment if either:
// - we only have initial move-to - expand it to an empty cubic
// - or we are not back to the starting point
if ((numCoordinates < 8) || curX != movX || curY != movY) {
appendLineTo(curX, curY, movX, movY);
curX = movX;
curY = movY;
}
// Now retrace our way back through all of the connecting
// inter-sub-path segments
for (int i = savedPathEndPoints.size() - 1; i >= 0; i--) {
final Point2D.Float p = savedPathEndPoints.get(i);
newX = p.x;
newY = p.y;
if (curX != newX || curY != newY) {
appendLineTo(curX, curY, newX, newY);
curX = newX;
curY = newY;
}
}
// Now find the segment endpoint with the smallest Y coordinate
int minPt = 0;
float minX = bezierCoordinates[0];
float minY = bezierCoordinates[1];
for (int ci = 6; ci < numCoordinates; ci += 6) {
float x = bezierCoordinates[ci];
float y = bezierCoordinates[ci + 1];
if (y < minY || (y == minY && x < minX)) {
minPt = ci;
minX = x;
minY = y;
}
}
// If the smallest Y coordinate is not the first coordinate,
// rotate the points so that it is...
if (minPt > 0) {
// Keep in mind that first 2 coordinates == last 2 coordinates
final float[] newCoordinates = new float[numCoordinates];
// Copy all coordinates from minPt to the end of the
// array to the beginning of the new array
System.arraycopy(bezierCoordinates, minPt,
newCoordinates, 0,
numCoordinates - minPt);
// Now we do not want to copy 0,1 as they are duplicates
// of the last 2 coordinates which we just copied. So
// we start the source copy at index 2, but we still
// copy a full minPt coordinates which copies the two
// coordinates that were at minPt to the last two elements
// of the array, thus ensuring that thew new array starts
// and ends with the same pair of coordinates...
System.arraycopy(bezierCoordinates, 2,
newCoordinates, numCoordinates - minPt,
minPt);
bezierCoordinates = newCoordinates;
}
/* Clockwise enforcement:
* - This technique is based on the formula for calculating
* the area of a Polygon. The standard formula is:
* Area(Poly) = 1/2 * sum(x[i]*y[i+1] - x[i+1]y[i])
* - The returned area is negative if the polygon is
* "mostly clockwise" and positive if the polygon is
* "mostly counter-clockwise".
* - One failure mode of the Area calculation is if the
* Polygon is self-intersecting. This is due to the
* fact that the areas on each side of the self-intersection
* are bounded by segments which have opposite winding
* direction. Thus, those areas will have opposite signs
* on the accumulation of their area summations and end
* up canceling each other out partially.
* - This failure mode of the algorithm in determining the
* exact magnitude of the area is not actually a big problem
* for our needs here since we are only using the sign of
* the resulting area to figure out the overall winding
* direction of the path. If self-intersections cause
* different parts of the path to disagree as to the
* local winding direction, that is no matter as we just
* wait for the final answer to tell us which winding
* direction had greater representation. If the final
* result is zero then the path was equal parts clockwise
* and counter-clockwise and we do not care about which
* way we order it as either way will require half of the
* path to unwind and re-wind itself.
*/
float area = 0;
// Note that first and last points are the same so we
// do not need to process coordinates[0,1] against coordinates[n-2,n-1]
curX = bezierCoordinates[0];
curY = bezierCoordinates[1];
for (int i = 2; i < numCoordinates; i += 2) {
newX = bezierCoordinates[i];
newY = bezierCoordinates[i + 1];
area += curX * newY - newX * curY;
curX = newX;
curY = newY;
}
if (area < 0) {
/* The area is negative so the shape was clockwise
* in a Euclidean sense. But, our screen coordinate
* systems have the origin in the upper left so they
* are flipped. Thus, this path "looks" ccw on the
* screen so we are flipping it to "look" clockwise.
* Note that the first and last points are the same
* so we do not need to swap them.
* (Not that it matters whether the paths end up cw
* or ccw in the end as long as all of them are the
* same, but above we called this section "Clockwise
* Enforcement", so we do not want to be liars. ;-)
*/
// Note that [0,1] do not need to be swapped with [n-2,n-1]
// So first pair to swap is [2,3] and [n-4,n-3]
int i = 2;
int j = numCoordinates - 4;
while (i < j) {
curX = bezierCoordinates[i];
curY = bezierCoordinates[i + 1];
bezierCoordinates[i] = bezierCoordinates[j];
bezierCoordinates[i + 1] = bezierCoordinates[j + 1];
bezierCoordinates[j] = curX;
bezierCoordinates[j + 1] = curY;
i += 2;
j -= 2;
}
}
}
private void appendLineTo(float x0, float y0,
float x1, float y1) {
appendCubicTo(// A third of the way from xy0 to xy1:
interp(x0, x1, THIRD),
interp(y0, y1, THIRD),
// A third of the way from xy1 back to xy0:
interp(x1, x0, THIRD),
interp(y1, y0, THIRD),
x1, y1);
}
private void appendQuadTo(float x0, float y0,
float ctrlX, float ctrlY,
float x1, float y1) {
appendCubicTo(// A third of the way from ctrl X/Y back to xy0:
interp(ctrlX, x0, THIRD),
interp(ctrlY, y0, THIRD),
// A third of the way from ctrl X/Y to xy1:
interp(ctrlX, x1, THIRD),
interp(ctrlY, y1, THIRD),
x1, y1);
}
private void appendCubicTo(float ctrlX1, float ctrlY1,
float ctrlX2, float ctrlY2,
float x1, float y1) {
if (numCoordinates + 6 > bezierCoordinates.length) {
// Keep array size to a multiple of 6 plus 2
int newsize = (numCoordinates - 2) * 2 + 2;
final float[] newCoordinates = new float[newsize];
System.arraycopy(bezierCoordinates, 0, newCoordinates, 0, numCoordinates);
bezierCoordinates = newCoordinates;
}
bezierCoordinates[numCoordinates++] = ctrlX1;
bezierCoordinates[numCoordinates++] = ctrlY1;
bezierCoordinates[numCoordinates++] = ctrlX2;
bezierCoordinates[numCoordinates++] = ctrlY2;
bezierCoordinates[numCoordinates++] = x1;
bezierCoordinates[numCoordinates++] = y1;
}
public int getWindingRule() {
return windingRule;
}
public int getNumCoordinates() {
return numCoordinates;
}
public float getCoordinate(int i) {
return bezierCoordinates[i];
}
public float[] getTVals() {
if (myTVals != null) {
return myTVals;
}
// assert(numCoordinates >= 8);
// assert(((numCoordinates - 2) % 6) == 0);
final float[] tVals = new float[(numCoordinates - 2) / 6 + 1];
// First calculate total "length" of path
// Length of each segment is averaged between
// the length between the endpoints (a lower bound for a cubic)
// and the length of the control polygon (an upper bound)
float segX = bezierCoordinates[0];
float segY = bezierCoordinates[1];
float tLen = 0;
int ci = 2;
int ti = 0;
while (ci < numCoordinates) {
float prevX, prevY, newX, newY;
prevX = segX;
prevY = segY;
newX = bezierCoordinates[ci++];
newY = bezierCoordinates[ci++];
prevX -= newX;
prevY -= newY;
float len = (float) Math.sqrt(prevX * prevX + prevY * prevY);
prevX = newX;
prevY = newY;
newX = bezierCoordinates[ci++];
newY = bezierCoordinates[ci++];
prevX -= newX;
prevY -= newY;
len += (float) Math.sqrt(prevX * prevX + prevY * prevY);
prevX = newX;
prevY = newY;
newX = bezierCoordinates[ci++];
newY = bezierCoordinates[ci++];
prevX -= newX;
prevY -= newY;
len += (float) Math.sqrt(prevX * prevX + prevY * prevY);
// len is now the total length of the control polygon
segX -= newX;
segY -= newY;
len += (float) Math.sqrt(segX * segX + segY * segY);
// len is now sum of linear length and control polygon length
len /= 2;
// len is now average of the two lengths
/* If the result is zero length then we will have problems
* below trying to do the math and bookkeeping to split
* the segment or pair it against the segments in the
* other shape. Since these lengths are just estimates
* to map the segments of the two shapes onto corresponding
* segments of "approximately the same length", we will
* simply modify the length of this segment to be at least
* a minimum value and it will simply grow from zero or
* near zero length to a non-trivial size as it morphs.
*/
if (len < MIN_LEN) {
len = MIN_LEN;
}
tLen += len;
tVals[ti++] = tLen;
segX = newX;
segY = newY;
}
// Now set tVals for each segment to its proportional
// part of the length
float prevT = tVals[0];
tVals[0] = 0;
for (ti = 1; ti < tVals.length - 1; ti++) {
final float nextT = tVals[ti];
tVals[ti] = prevT / tLen;
prevT = nextT;
}
tVals[ti] = 1;
return (myTVals = tVals);
}
public void setTVals(float[] newTVals) {
final float[] oldCoordinates = bezierCoordinates;
final float[] newCoordinates = new float[2 + (newTVals.length - 1) * 6];
final float[] oldTVals = getTVals();
int oldCi = 0;
float x0, xc0, xc1, x1;
float y0, yc0, yc1, y1;
x0 = xc0 = xc1 = x1 = oldCoordinates[oldCi++];
y0 = yc0 = yc1 = y1 = oldCoordinates[oldCi++];
int newCi = 0;
newCoordinates[newCi++] = x0;
newCoordinates[newCi++] = y0;
float t0 = 0;
float t1 = 0;
int oldTi = 1;
int newTi = 1;
while (newTi < newTVals.length) {
if (t0 >= t1) {
x0 = x1;
y0 = y1;
xc0 = oldCoordinates[oldCi++];
yc0 = oldCoordinates[oldCi++];
xc1 = oldCoordinates[oldCi++];
yc1 = oldCoordinates[oldCi++];
x1 = oldCoordinates[oldCi++];
y1 = oldCoordinates[oldCi++];
t1 = oldTVals[oldTi++];
}
float nt = newTVals[newTi++];
// assert(nt > t0);
if (nt < t1) {
// Make nt proportional to [t0 => t1] range
float relT = (nt - t0) / (t1 - t0);
newCoordinates[newCi++] = x0 = interp(x0, xc0, relT);
newCoordinates[newCi++] = y0 = interp(y0, yc0, relT);
xc0 = interp(xc0, xc1, relT);
yc0 = interp(yc0, yc1, relT);
xc1 = interp(xc1, x1, relT);
yc1 = interp(yc1, y1, relT);
newCoordinates[newCi++] = x0 = interp(x0, xc0, relT);
newCoordinates[newCi++] = y0 = interp(y0, yc0, relT);
xc0 = interp(xc0, xc1, relT);
yc0 = interp(yc0, yc1, relT);
newCoordinates[newCi++] = x0 = interp(x0, xc0, relT);
newCoordinates[newCi++] = y0 = interp(y0, yc0, relT);
} else {
newCoordinates[newCi++] = xc0;
newCoordinates[newCi++] = yc0;
newCoordinates[newCi++] = xc1;
newCoordinates[newCi++] = yc1;
newCoordinates[newCi++] = x1;
newCoordinates[newCi++] = y1;
}
t0 = nt;
}
bezierCoordinates = newCoordinates;
numCoordinates = newCoordinates.length;
myTVals = newTVals;
}
}
private static class MorphedShape implements Shape {
final Geometry geom0;
final Geometry geom1;
final float t;
final boolean unionBounds;
MorphedShape(Geometry geom0, Geometry geom1, float t, boolean unionBounds) {
this.geom0 = geom0;
this.geom1 = geom1;
this.t = t;
this.unionBounds = unionBounds;
}
public Rectangle getBounds() {
return getBounds2D().getBounds();
}
public Rectangle2D getBounds2D() {
final int n = geom0.getNumCoordinates();
float xMin, yMin, xMax, yMax;
if (unionBounds) {
xMin = xMax = geom0.getCoordinate(0);
yMin = yMax = geom0.getCoordinate(1);
for (int i = 2; i < n; i += 2) {
final float x = geom0.getCoordinate(i);
final float y = geom0.getCoordinate(i + 1);
if (xMin > x) {
xMin = x;
}
if (yMin > y) {
yMin = y;
}
if (xMax < x) {
xMax = x;
}
if (yMax < y) {
yMax = y;
}
}
final int m = geom1.getNumCoordinates();
for (int i = 0; i < m; i += 2) {
final float x = geom1.getCoordinate(i);
final float y = geom1.getCoordinate(i + 1);
if (xMin > x) {
xMin = x;
}
if (yMin > y) {
yMin = y;
}
if (xMax < x) {
xMax = x;
}
if (yMax < y) {
yMax = y;
}
}
} else {
xMin = xMax = interp(geom0.getCoordinate(0), geom1.getCoordinate(0), t);
yMin = yMax = interp(geom0.getCoordinate(1), geom1.getCoordinate(1), t);
for (int i = 2; i < n; i += 2) {
final float x = interp(geom0.getCoordinate(i), geom1.getCoordinate(i), t);
final float y = interp(geom0.getCoordinate(i + 1), geom1.getCoordinate(i + 1), t);
if (xMin > x) {
xMin = x;
}
if (yMin > y) {
yMin = y;
}
if (xMax < x) {
xMax = x;
}
if (yMax < y) {
yMax = y;
}
}
}
return new Rectangle2D.Float(xMin, yMin, xMax - xMin, yMax - yMin);
}
public boolean contains(double x, double y) {
return Path2D.contains(getPathIterator(null), x, y);
}
public boolean contains(Point2D p) {
return Path2D.contains(getPathIterator(null), p);
}
public boolean intersects(double x, double y, double w, double h) {
return Path2D.intersects(getPathIterator(null), x, y, w, h);
}
public boolean intersects(Rectangle2D r) {
return Path2D.intersects(getPathIterator(null), r);
}
public boolean contains(double x, double y, double width, double height) {
return Path2D.contains(getPathIterator(null), x, y, width, height);
}
public boolean contains(Rectangle2D r) {
return Path2D.contains(getPathIterator(null), r);
}
public PathIterator getPathIterator(AffineTransform at) {
return new Iterator(at, geom0, geom1, t);
}
public PathIterator getPathIterator(AffineTransform at, double flatness) {
return new FlatteningPathIterator(getPathIterator(at), flatness);
}
}
private static class Iterator implements PathIterator {
AffineTransform at;
Geometry g0;
Geometry g1;
float t;
int cIndex;
public Iterator(AffineTransform at,
Geometry g0, Geometry g1,
float t) {
this.at = at;
this.g0 = g0;
this.g1 = g1;
this.t = t;
}
/**
* {@inheritDoc}
*/
public int getWindingRule() {
return (t < 0.5 ? g0.getWindingRule() : g1.getWindingRule());
}
/**
* {@inheritDoc}
*/
public boolean isDone() {
return (cIndex > g0.getNumCoordinates());
}
/**
* {@inheritDoc}
*/
public void next() {
if (cIndex == 0) {
cIndex = 2;
} else {
cIndex += 6;
}
}
/**
* {@inheritDoc}
*/
public int currentSegment(float[] coordinates) {
int type;
int n;
if (cIndex == 0) {
type = SEG_MOVETO;
n = 2;
} else if (cIndex >= g0.getNumCoordinates()) {
type = SEG_CLOSE;
n = 0;
} else {
type = SEG_CUBICTO;
n = 6;
}
if (n > 0) {
for (int i = 0; i < n; i++) {
coordinates[i] = interp(
g0.getCoordinate(cIndex + i),
g1.getCoordinate(cIndex + i),
t);
}
if (at != null) {
at.transform(coordinates, 0, coordinates, 0, n / 2);
}
}
return type;
}
public int currentSegment(double[] coordinates) {
final float[] temp = new float[6];
final int res = currentSegment(temp);
for (int i = 0; i < 6; i++) {
coordinates[i] = temp[i];
}
return res;
}
}
}

View File

@ -1,25 +1,19 @@
package com.boydti.fawe.util;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.pattern.PatternExtent;
import com.boydti.fawe.util.image.ImageUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.sk89q.worldedit.util.command.binding.Text;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.registry.BlockMaterial;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntArraySet;
@ -27,12 +21,23 @@ import it.unimi.dsi.fastutil.longs.LongArrayList;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
@ -107,60 +112,60 @@ public class TextureUtil implements TextureHolder {
private BiomeColor[] biomes = new BiomeColor[] {
// ID Name Temperature, rainfall, grass, foliage colors
// - note: the colors here are just placeholders, they are computed in the program
new BiomeColor(0, "Ocean", 0.5f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(0, "ocean", 0.5f, 0.5f, 0x92BD59, 0x77AB2F),
// default values of temp and rain
new BiomeColor(1, "Plains", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(2, "Desert", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(3, "Extreme Hills", 0.2f, 0.3f, 0x92BD59, 0x77AB2F),
new BiomeColor(4, "Forest", 0.7f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(5, "Taiga", 0.25f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(6, "Swampland", 0.8f, 0.9f, 0x92BD59, 0x77AB2F),
new BiomeColor(7, "River", 0.5f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(1, "plains", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(2, "desert", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(3, "mountains", 0.2f, 0.3f, 0x92BD59, 0x77AB2F),
new BiomeColor(4, "forest", 0.7f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(5, "taiga", 0.25f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(6, "swamp", 0.8f, 0.9f, 0x92BD59, 0x77AB2F),
new BiomeColor(7, "river", 0.5f, 0.5f, 0x92BD59, 0x77AB2F),
// default values of temp and rain
new BiomeColor(8, "Nether", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(9, "End", 0.5f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(8, "nether", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(9, "the_end", 0.5f, 0.5f, 0x92BD59, 0x77AB2F),
// default values of temp and rain
new BiomeColor(10, "Frozen Ocean", 0.0f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(11, "Frozen River", 0.0f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(12, "Ice Plains", 0.0f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(13, "Ice Mountains", 0.0f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(14, "Mushroom Island", 0.9f, 1.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(15, "Mushroom Island Shore", 0.9f, 1.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(16, "Beach", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(17, "Desert Hills", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(18, "Forest Hills", 0.7f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(19, "Taiga Hills", 0.25f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(20, "Extreme Hills Edge", 0.2f, 0.3f, 0x92BD59, 0x77AB2F),
new BiomeColor(21, "Jungle", 0.95f, 0.9f, 0x92BD59, 0x77AB2F),
new BiomeColor(22, "Jungle Hills", 0.95f, 0.9f, 0x92BD59, 0x77AB2F),
new BiomeColor(23, "Jungle Edge", 0.95f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(24, "Deep Ocean", 0.5f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(25, "Stone Beach", 0.2f, 0.3f, 0x92BD59, 0x77AB2F),
new BiomeColor(26, "Cold Beach", 0.05f, 0.3f, 0x92BD59, 0x77AB2F),
new BiomeColor(27, "Birch Forest", 0.6f, 0.6f, 0x92BD59, 0x77AB2F),
new BiomeColor(28, "Birch Forest Hills", 0.6f, 0.6f, 0x92BD59, 0x77AB2F),
new BiomeColor(29, "Roofed Forest", 0.7f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(30, "Cold Taiga", -0.5f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(31, "Cold Taiga Hills", -0.5f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(32, "Mega Taiga", 0.3f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(33, "Mega Taiga Hills", 0.3f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(34, "Extreme Hills+", 0.2f, 0.3f, 0x92BD59, 0x77AB2F),
new BiomeColor(35, "Savanna", 1.2f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(36, "Savanna Plateau", 1.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(37, "Mesa", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(38, "Mesa Plateau F", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(39, "Mesa Plateau", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(40, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(41, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(42, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(43, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(44, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(45, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(46, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(47, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(48, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(49, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(50, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(10, "frozen_ocean", 0.0f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(11, "frozen_river", 0.0f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(12, "snowy_tundra", 0.0f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(13, "snowy_mountains", 0.0f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(14, "mushroom_fields", 0.9f, 1.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(15, "mushroom_field_shore", 0.9f, 1.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(16, "beach", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(17, "desert_hills", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(18, "wooded_hills", 0.7f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(19, "taiga_hills", 0.25f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(20, "mountain_edge", 0.2f, 0.3f, 0x92BD59, 0x77AB2F),
new BiomeColor(21, "jungle", 0.95f, 0.9f, 0x92BD59, 0x77AB2F),
new BiomeColor(22, "jungle_hills", 0.95f, 0.9f, 0x92BD59, 0x77AB2F),
new BiomeColor(23, "jungle_edge", 0.95f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(24, "deep_ocean", 0.5f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(25, "stone_shore", 0.2f, 0.3f, 0x92BD59, 0x77AB2F),
new BiomeColor(26, "snowy_beach", 0.05f, 0.3f, 0x92BD59, 0x77AB2F),
new BiomeColor(27, "birch_forest", 0.6f, 0.6f, 0x92BD59, 0x77AB2F),
new BiomeColor(28, "birch_forest_hills", 0.6f, 0.6f, 0x92BD59, 0x77AB2F),
new BiomeColor(29, "dark_forest", 0.7f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(30, "snowy_taiga", -0.5f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(31, "snowy_taiga_hills", -0.5f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(32, "giant_tree_taiga", 0.3f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(33, "giant_tree_taiga_hills", 0.3f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(34, "wooded_mountains", 0.2f, 0.3f, 0x92BD59, 0x77AB2F),
new BiomeColor(35, "savanna", 1.2f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(36, "savanna_plateau", 1.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(37, "badlands", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(38, "wooded_badlands_plateau", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(39, "badlands_plateau", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(40, "small_end_islands", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(41, "end_midlands", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(42, "end_highlands", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(43, "end_barrens", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(44, "warm_ocean", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(45, "lukewarm_ocean", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(46, "cold_ocean", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(47, "deep_warm_ocean", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(48, "deep_lukewarm_ocean", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(49, "deep_cold_ocean", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(50, "deep_frozen_ocean", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(51, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(52, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(53, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
@ -237,21 +242,21 @@ public class TextureUtil implements TextureHolder {
new BiomeColor(124, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(125, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(126, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(127, "The Void", 0.5f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(127, "the_void", 0.5f, 0.5f, 0x92BD59, 0x77AB2F),
// default values of temp and rain; also, no height differences
new BiomeColor(128, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(129, "Sunflower Plains", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(130, "Desert M", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(131, "Extreme Hills M", 0.2f, 0.3f, 0x92BD59, 0x77AB2F),
new BiomeColor(132, "Flower Forest", 0.7f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(133, "Taiga M", 0.25f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(134, "Swampland M", 0.8f, 0.9f, 0x92BD59, 0x77AB2F),
new BiomeColor(129, "sunflower_plains", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(130, "desert_lakes", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(131, "gravelly_mountains", 0.2f, 0.3f, 0x92BD59, 0x77AB2F),
new BiomeColor(132, "flower_forest", 0.7f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(133, "taiga_mountains", 0.25f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(134, "swamp_hills", 0.8f, 0.9f, 0x92BD59, 0x77AB2F),
new BiomeColor(135, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(136, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(137, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(138, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(139, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(140, "Ice Plains Spikes", 0.0f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(140, "ice_spikes", 0.0f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(141, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(142, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(143, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
@ -260,28 +265,28 @@ public class TextureUtil implements TextureHolder {
new BiomeColor(146, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(147, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(148, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(149, "Jungle M", 0.95f, 0.9f, 0x92BD59, 0x77AB2F),
new BiomeColor(149, "modified_jungle", 0.95f, 0.9f, 0x92BD59, 0x77AB2F),
new BiomeColor(150, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(151, "JungleEdge M", 0.95f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(151, "modified_jungle_edge", 0.95f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(152, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(153, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(154, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(155, "Birch Forest M", 0.6f, 0.6f, 0x92BD59, 0x77AB2F),
new BiomeColor(156, "Birch Forest Hills M", 0.6f, 0.6f, 0x92BD59, 0x77AB2F),
new BiomeColor(157, "Roofed Forest M", 0.7f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(158, "Cold Taiga M", -0.5f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(159, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(160, "Mega Spruce Taiga", 0.25f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(155, "tall_birch_forest", 0.6f, 0.6f, 0x92BD59, 0x77AB2F),
new BiomeColor(156, "tall_birch_hills", 0.6f, 0.6f, 0x92BD59, 0x77AB2F),
new BiomeColor(157, "dark_forest_hills", 0.7f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(158, "snowy_taiga_mountains", -0.5f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(159, "Unknown", -0.5f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(160, "giant_spruce_taiga", 0.25f, 0.8f, 0x92BD59, 0x77AB2F),
// special exception, temperature not 0.3
new BiomeColor(161, "Mega Spruce Taiga Hills", 0.25f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(162, "Extreme Hills+ M", 0.2f, 0.3f, 0x92BD59, 0x77AB2F),
new BiomeColor(163, "Savanna M", 1.1f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(164, "Savanna Plateau M", 1.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(165, "Mesa (Bryce)", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(166, "Mesa Plateau F M", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(167, "Mesa Plateau M", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(168, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(169, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(161, "giant_spruce_taiga_hills", 0.25f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(162, "modified_gravelly_mountains", 0.2f, 0.3f, 0x92BD59, 0x77AB2F),
new BiomeColor(163, "shattered_savanna", 1.1f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(164, "shattered_savanna_plateau", 1.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(165, "eroded_badlands", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(166, "modified_wooded_badlands_plateau", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(167, "modified_badlands_plateau", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(168, "bamboo_jungle", 0.95f, 0.9f, 0x92BD59, 0x77AB2F),
new BiomeColor(169, "bamboo_jungle_hills", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(170, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(171, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(172, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
@ -597,23 +602,21 @@ public class TextureUtil implements TextureHolder {
// Get all the groups in the current jar
// The vanilla textures are in `assets/minecraft`
// A jar may contain textures for multiple mods
Enumeration<? extends ZipEntry> entries = zipFile.entries();
Set<String> mods = new HashSet<>();
{
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
String name = entry.getName();
Path path = Paths.get(name);
if (path.startsWith("assets" + File.separator)) {
String[] split =
path.toString().split(Pattern.quote(File.separator));
if (split.length > 1) {
String modId = split[1];
mods.add(modId);
}
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
String name = entry.getName();
Path path = Paths.get(name);
if (path.startsWith("assets" + File.separator)) {
String[] split =
path.toString().split(Pattern.quote(File.separator));
if (split.length > 1) {
String modId = split[1];
mods.add(modId);
}
continue;
}
continue;
}
String modelsDir = "assets/%1$s/models/block/%2$s.json";
String texturesDir = "assets/%1$s/textures/%2$s.png";
@ -632,153 +635,148 @@ public class TextureUtil implements TextureHolder {
String nameSpace = split.length == 1 ? "minecraft" : split[0];
Map<String, String> texturesMap = new ConcurrentHashMap<>();
{ // Read models
String modelFileName = String.format(modelsDir, nameSpace, name);
ZipEntry entry = getEntry(zipFile, modelFileName);
if (entry == null) {
System.out.println("Cannot find " + modelFileName + " in " + file);
// Read models
String modelFileName = String.format(modelsDir, nameSpace, name);
ZipEntry entry = getEntry(zipFile, modelFileName);
if (entry == null) {
System.out.println("Cannot find " + modelFileName + " in " + file);
continue;
}
String textureFileName;
try (InputStream is = zipFile.getInputStream(entry)) {
JsonReader reader = new JsonReader(
new InputStreamReader(is, StandardCharsets.UTF_8));
Map<String, Object> root = gson.fromJson(reader, typeToken);
Map<String, Object> textures = (Map) root.get("textures");
if (textures == null) {
continue;
}
String textureFileName;
try (InputStream is = zipFile.getInputStream(entry)) {
JsonReader reader = new JsonReader(
new InputStreamReader(is, StandardCharsets.UTF_8));
Map<String, Object> root = gson.fromJson(reader, typeToken);
Map<String, Object> textures = (Map) root.get("textures");
if (textures == null) {
continue;
}
Set<String> models = new HashSet<>();
// Get models
for (Map.Entry<String, Object> stringObjectEntry : textures
.entrySet()) {
Object value = stringObjectEntry.getValue();
if (value instanceof String) {
Set<String> models = new HashSet<>();
// Get models
for (Map.Entry<String, Object> stringObjectEntry : textures
.entrySet()) {
Object value = stringObjectEntry.getValue();
if (value instanceof String) {
models.add((String) value);
} else if (value instanceof Map) {
value = ((Map) value).get("model");
if (value != null) {
models.add((String) value);
} else if (value instanceof Map) {
value = ((Map) value).get("model");
if (value != null) {
models.add((String) value);
}
}
}
if (models.size() != 1) {
continue;
}
textureFileName =
String.format(texturesDir, nameSpace, models.iterator().next());
}
BufferedImage image = readImage(zipFile, textureFileName);
if (image == null) {
System.out.println("Cannot find " + textureFileName);
if (models.size() != 1) {
continue;
}
int color = ImageUtil.getColor(image);
long distance = getDistance(image, color);
distanceMap.put(combined, (Long) distance);
colorMap.put(combined, (Integer) color);
textureFileName =
String.format(texturesDir, nameSpace, models.iterator().next());
}
BufferedImage image = readImage(zipFile, textureFileName);
if (image == null) {
System.out.println("Cannot find " + textureFileName);
continue;
}
int color = ImageUtil.getColor(image);
long distance = getDistance(image, color);
distanceMap.put(combined, (Long) distance);
colorMap.put(combined, (Integer) color);
}
Integer grass = null;
{
String grassFileName =
String.format(texturesDir, "minecraft", "grass_block_top");
BufferedImage image = readImage(zipFile, grassFileName);
if (image != null) {
grass = ImageUtil.getColor(image);
}
}
{
Integer grass = null;
{
String grassFileName =
String.format(texturesDir, "minecraft", "grass_block_top");
BufferedImage image = readImage(zipFile, grassFileName);
if (image != null) {
grass = ImageUtil.getColor(image);
}
}
if (grass != null) {
// assets\minecraft\textures\colormap
ZipEntry grassEntry = getEntry(zipFile,
"assets/minecraft/textures/colormap/grass_block.png");
if (grassEntry != null) {
try (InputStream is = zipFile.getInputStream(grassEntry)) {
BufferedImage image = ImageIO.read(is);
// Update biome colors
for (BiomeColor biome : biomes) {
float adjTemp =
MathMan.clamp(biome.temperature, 0.0f, 1.0f);
float adjRainfall =
MathMan.clamp(biome.rainfall, 0.0f, 1.0f) * adjTemp;
int x = (int) (255 - adjTemp * 255);
int z = (int) (255 - adjRainfall * 255);
biome.grass = image.getRGB(x, z);
}
}
// swampland: perlin - avoid
biomes[6].grass = 0;
biomes[134].grass = 0;
// roofed forest: averaged w/ 0x28340A
biomes[29].grass =
multiplyColor(biomes[29].grass, 0x28340A + (255 << 24));
biomes[157].grass =
multiplyColor(biomes[157].grass, 0x28340A + (255 << 24));
// mesa : 0x90814D
biomes[37].grass = 0x90814D + (255 << 24);
biomes[38].grass = 0x90814D + (255 << 24);
biomes[39].grass = 0x90814D + (255 << 24);
biomes[165].grass = 0x90814D + (255 << 24);
biomes[166].grass = 0x90814D + (255 << 24);
biomes[167].grass = 0x90814D + (255 << 24);
List<BiomeColor> valid = new ArrayList<>();
if (grass != null) {
// assets\minecraft\textures\colormap
ZipEntry grassEntry = getEntry(zipFile,
"assets/minecraft/textures/colormap/grass_block.png");
if (grassEntry != null) {
try (InputStream is = zipFile.getInputStream(grassEntry)) {
BufferedImage image = ImageIO.read(is);
// Update biome colors
for (BiomeColor biome : biomes) {
// biome.grass = multiplyColor(biome.grass, grass);
if (biome.grass != 0 && !biome.name
.equalsIgnoreCase("Unknown Biome")) {
valid.add(biome);
}
biome.grassCombined = multiplyColor(grass, biome.grass);
float adjTemp =
MathMan.clamp(biome.temperature, 0.0f, 1.0f);
float adjRainfall =
MathMan.clamp(biome.rainfall, 0.0f, 1.0f) * adjTemp;
int x = (int) (255 - adjTemp * 255);
int z = (int) (255 - adjRainfall * 255);
biome.grass = image.getRGB(x, z);
}
this.validBiomes = valid.toArray(new BiomeColor[valid.size()]);
}
// swampland: perlin - avoid
biomes[6].grass = 0;
biomes[134].grass = 0;
// roofed forest: averaged w/ 0x28340A
biomes[29].grass =
multiplyColor(biomes[29].grass, 0x28340A + (255 << 24));
biomes[157].grass =
multiplyColor(biomes[157].grass, 0x28340A + (255 << 24));
// mesa : 0x90814D
biomes[37].grass = 0x90814D + (255 << 24);
biomes[38].grass = 0x90814D + (255 << 24);
biomes[39].grass = 0x90814D + (255 << 24);
biomes[165].grass = 0x90814D + (255 << 24);
biomes[166].grass = 0x90814D + (255 << 24);
biomes[167].grass = 0x90814D + (255 << 24);
List<BiomeColor> valid = new ArrayList<>();
for (BiomeColor biome : biomes) {
// biome.grass = multiplyColor(biome.grass, grass);
if (biome.grass != 0 && !biome.name
.equalsIgnoreCase("Unknown Biome")) {
valid.add(biome);
}
biome.grassCombined = multiplyColor(grass, biome.grass);
}
this.validBiomes = valid.toArray(new BiomeColor[0]);
{
ArrayList<BiomeColor> uniqueColors = new ArrayList<>();
Set<Integer> uniqueBiomesColors = new IntArraySet();
for (BiomeColor color : validBiomes) {
if (uniqueBiomesColors.add(color.grass)) {
uniqueColors.add(color);
ArrayList<BiomeColor> uniqueColors = new ArrayList<>();
Set<Integer> uniqueBiomesColors = new IntArraySet();
for (BiomeColor color : validBiomes) {
if (uniqueBiomesColors.add(color.grass)) {
uniqueColors.add(color);
}
}
int count = 0;
int count2 = 0;
uniqueBiomesColors.clear();
LongArrayList layerIds = new LongArrayList();
LongArrayList layerColors = new LongArrayList();
for (int i = 0; i < uniqueColors.size(); i++) {
for (int j = i; j < uniqueColors.size(); j++) {
for (int k = j; k < uniqueColors.size(); k++) {
BiomeColor c1 = uniqueColors.get(i);
BiomeColor c2 = uniqueColors.get(j);
BiomeColor c3 = uniqueColors.get(k);
int average =
averageColor(c1.grass, c2.grass, c3.grass);
if (uniqueBiomesColors.add(average)) {
count++;
layerColors.add((long) average);
layerIds.add(
(long) ((c1.id) + (c2.id << 8) + (c3.id
<< 16)));
}
}
int count = 0;
int count2 = 0;
uniqueBiomesColors.clear();
LongArrayList layerIds = new LongArrayList();
LongArrayList layerColors = new LongArrayList();
for (int i = 0; i < uniqueColors.size(); i++) {
for (int j = i; j < uniqueColors.size(); j++) {
for (int k = j; k < uniqueColors.size(); k++) {
BiomeColor c1 = uniqueColors.get(i);
BiomeColor c2 = uniqueColors.get(j);
BiomeColor c3 = uniqueColors.get(k);
int average =
averageColor(c1.grass, c2.grass, c3.grass);
if (uniqueBiomesColors.add(average)) {
count++;
layerColors.add((long) average);
layerIds.add(
(long) ((c1.id) + (c2.id << 8) + (c3.id
<< 16)));
}
}
}
}
validMixBiomeColors = new int[layerColors.size()];
for (int i = 0; i < layerColors.size(); i++) {
validMixBiomeColors[i] = (int) layerColors.getLong(i);
}
validMixBiomeIds = layerIds.toLongArray();
}
}
validMixBiomeColors = new int[layerColors.size()];
for (int i = 0; i < layerColors.size(); i++) {
validMixBiomeColors[i] = (int) layerColors.getLong(i);
}
validMixBiomeIds = layerIds.toLongArray();
}
}
// Close the file
zipFile.close();

View File

@ -20,8 +20,6 @@
package com.sk89q.worldedit;
import com.boydti.fawe.object.schematic.Schematic;
import com.boydti.fawe.util.MainUtil;
import com.sk89q.worldedit.command.ClipboardCommands;
import com.sk89q.worldedit.command.FlattenedClipboardTransform;
import com.sk89q.worldedit.command.SchematicCommands;
@ -97,7 +95,6 @@ public class CuboidClipboard {
*/
public CuboidClipboard(BlockVector3 size) {
checkNotNull(size);
MainUtil.warnDeprecated(BlockArrayClipboard.class, ClipboardFormat.class);
this.size = size;
this.clipboard = this.init(BlockVector3.ZERO, BlockVector3.ZERO);
}
@ -117,7 +114,6 @@ public class CuboidClipboard {
public CuboidClipboard(BlockVector3 size, BlockVector3 origin) {
checkNotNull(size);
checkNotNull(origin);
MainUtil.warnDeprecated(BlockArrayClipboard.class, ClipboardFormat.class);
this.size = size;
this.clipboard = init(BlockVector3.ZERO, origin);
}
@ -134,7 +130,6 @@ public class CuboidClipboard {
checkNotNull(size);
checkNotNull(origin);
checkNotNull(offset);
MainUtil.warnDeprecated(BlockArrayClipboard.class, ClipboardFormat.class);
this.size = size;
this.clipboard = this.init(offset, origin);
}
@ -479,4 +474,4 @@ public class CuboidClipboard {
}
return distribution;
}
}
}

View File

@ -477,7 +477,7 @@ public final class CommandManager {
}
} else {
String message = e.getMessage();
actor.printRaw(BBC.getPrefix() + (message != null ? message : "The command was not used properly (no more help available)."));
actor.printRaw((message != null ? message : "The command was not used properly (no more help available)."));
BBC.COMMAND_SYNTAX.send(actor, e.getSimpleUsageString("/"));
}
} catch (CommandException e) {
@ -534,7 +534,11 @@ public final class CommandManager {
return;
}
}
if (!fp.runAction(() -> handleCommandOnCurrentThread(finalEvent), false, true)) {
if (!fp.runAction(new Runnable() {
@Override public void run() {
CommandManager.this.handleCommandOnCurrentThread(finalEvent);
}
}, false, true)) {
BBC.WORLDEDIT_COMMAND_LIMIT.send(fp);
}
finalEvent.setCancelled(true);

View File

@ -1,27 +1,21 @@
package com.sk89q.worldedit.function.mask;
import com.boydti.fawe.object.collection.FastBitSet;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.StringMan;
import com.sk89q.worldedit.extent.NullExtent;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.NullExtent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.registry.state.AbstractProperty;
import com.sk89q.worldedit.registry.state.Property;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -41,14 +35,12 @@ public class BlockMask extends AbstractExtentMask {
@Deprecated
public BlockMask(Extent extent, Collection<BaseBlock> blocks) {
super(extent);
MainUtil.warnDeprecated(BlockMaskBuilder.class);
this.bitSets = new BlockMaskBuilder().addBlocks(blocks).optimize().getBits();
}
@Deprecated
public BlockMask(Extent extent, BaseBlock... blocks) {
super(extent);
MainUtil.warnDeprecated(BlockMaskBuilder.class);
this.bitSets = new BlockMaskBuilder().addBlocks(blocks).optimize().getBits();
}
@ -125,16 +117,14 @@ public class BlockMask extends AbstractExtentMask {
}
}
BlockType type = BlockTypes.get(indexFound);
{
Mask mask = getOptimizedMask(type, bitSets[indexFound]);
if (mask == null) { // Try with inverse
long[] newBitSet = bitSets[indexFound];
for (int i = 0; i < newBitSet.length; i++) newBitSet[i] = ~newBitSet[i];
mask = getOptimizedMask(type, bitSets[indexFound]);
if (mask != null) mask = mask.inverse();
}
return mask;
Mask mask = getOptimizedMask(type, bitSets[indexFound]);
if (mask == null) { // Try with inverse
long[] newBitSet = bitSets[indexFound];
for (int i = 0; i < newBitSet.length; i++) newBitSet[i] = ~newBitSet[i];
mask = getOptimizedMask(type, bitSets[indexFound]);
if (mask != null) mask = mask.inverse();
}
return mask;
}
private Mask getOptimizedMask(BlockType type, long[] bitSet) {
@ -247,4 +237,4 @@ public class BlockMask extends AbstractExtentMask {
}
}
}

View File

@ -20,25 +20,23 @@
package com.sk89q.worldedit.regions;
import com.boydti.fawe.config.Settings;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.object.collection.BlockVectorSet;
import com.boydti.fawe.object.collection.LocalBlockVectorSet;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.math.MutableBlockVector2;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.storage.ChunkStore;
import org.jetbrains.annotations.NotNull;
import java.util.AbstractSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Set;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* An axis-aligned cuboid. It can be defined using two corners of the cuboid.
*/
@ -313,7 +311,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
final int size = (maxX - minX + 1) * (maxZ - minZ + 1);
return new AbstractSet<BlockVector2>() {
@Override
@NotNull @Override
public Iterator<BlockVector2> iterator() {
return new Iterator<BlockVector2>() {
private MutableBlockVector2 pos = new MutableBlockVector2().setComponents(maxX + 1, maxZ);
@ -403,7 +401,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
return position.containedWithin(min, max);
}
@Override
@NotNull @Override
public Iterator<BlockVector3> iterator() {
if (Settings.IMP.HISTORY.COMPRESSION_LEVEL >= 9 || useOldIterator) {
return iterator_old();
@ -432,7 +430,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
int ctx = Math.min(tx, 15 + (cx << 4));
int ctz = Math.min(tz, 15 + (cz << 4));
public boolean hasNext = true;
boolean hasNext = true;
@Override
@ -535,49 +533,34 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
@Override
public Iterable<BlockVector2> asFlatRegion() {
return new Iterable<BlockVector2>() {
return () -> new Iterator<BlockVector2>() {
private BlockVector3 min = getMinimumPoint();
private BlockVector3 max = getMaximumPoint();
private int nextX = min.getBlockX();
private int nextZ = min.getBlockZ();
@Override
public Iterator<BlockVector2> iterator() {
MutableBlockVector2 mutable = new MutableBlockVector2();
return new Iterator<BlockVector2>() {
private BlockVector3 min = getMinimumPoint();
private BlockVector3 max = getMaximumPoint();
private int nextX = min.getBlockX();
private int nextZ = min.getBlockZ();
public boolean hasNext() {
return (nextZ != Integer.MAX_VALUE);
}
@Override
public boolean hasNext() {
return (nextZ != Integer.MAX_VALUE);
@Override
public BlockVector2 next() {
if (!hasNext()) throw new NoSuchElementException();
BlockVector2 answer = BlockVector2.at(nextX, nextZ);
if (++nextX > max.getBlockX()) {
nextX = min.getBlockX();
if (++nextZ > max.getBlockZ()) {
nextZ = Integer.MAX_VALUE;
nextX = Integer.MAX_VALUE;
}
}
return answer;
}
@Override
public BlockVector2 next() {
if (!hasNext()) throw new java.util.NoSuchElementException();
// BlockVector2 answer = mutable.setComponents(nextX, nextZ);
BlockVector2 answer = BlockVector2.at(nextX, nextZ);
if (++nextX > max.getBlockX()) {
nextX = min.getBlockX();
if (++nextZ > max.getBlockZ()) {
if (nextZ == Integer.MIN_VALUE) {
throw new NoSuchElementException("End of iterator") {
@Override
public Throwable fillInStackTrace() {
return this;
}
};
}
nextZ = Integer.MAX_VALUE;
nextX = Integer.MAX_VALUE;
}
}
return answer;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
@ -625,4 +608,4 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
}
}
}

View File

@ -1,7 +1,5 @@
package com.sk89q.worldedit.util.command.parametric;
import com.boydti.fawe.util.ArrayUtil;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.StringMan;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandException;
@ -10,13 +8,6 @@ import com.sk89q.worldedit.util.command.CommandMapping;
import com.sk89q.worldedit.util.command.MissingParameterException;
import com.sk89q.worldedit.util.command.SimpleDispatcher;
import com.sk89q.worldedit.util.command.binding.Range;
import com.sk89q.worldedit.util.command.parametric.ArgumentStack;
import com.sk89q.worldedit.util.command.parametric.Binding;
import com.sk89q.worldedit.util.command.parametric.BindingBehavior;
import com.sk89q.worldedit.util.command.parametric.BindingMatch;
import com.sk89q.worldedit.util.command.parametric.ParameterData;
import com.sk89q.worldedit.util.command.parametric.ParameterException;
import com.sk89q.worldedit.util.command.parametric.ParametricBuilder;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;

View File

@ -913,31 +913,31 @@ public final class BlockTypes {
return $NAMESPACES;
}
public static final @Nullable BlockType get(final String id) {
public static @Nullable BlockType get(final String id) {
return $REGISTRY.get(id);
}
public static final @Nullable BlockType get(final CharSequence id) {
public static @Nullable BlockType get(final CharSequence id) {
return $REGISTRY.get(id);
}
@Deprecated
public static final BlockType get(final int ordinal) {
public static BlockType get(final int ordinal) {
return values[ordinal];
}
@Deprecated
public static final BlockType getFromStateId(final int internalStateId) {
public static BlockType getFromStateId(final int internalStateId) {
return values[internalStateId & BIT_MASK];
}
@Deprecated
public static final BlockType getFromStateOrdinal(final int internalStateOrdinal) {
public static BlockType getFromStateOrdinal(final int internalStateOrdinal) {
return states[internalStateOrdinal].getBlockType();
}
public static int size() {
return values.length;
}
}