Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-12-25 18:40:05 +01:00
chunk sending / cfi
Dieser Commit ist enthalten in:
Ursprung
1b28dcda40
Commit
8356004ec9
@ -20,6 +20,7 @@ repositories {
|
|||||||
maven { url = uri("https://repo.destroystokyo.com/repository/maven-public//") }
|
maven { url = uri("https://repo.destroystokyo.com/repository/maven-public//") }
|
||||||
maven { url = uri("http://repo.dmulloy2.net/content/groups/public/") }
|
maven { url = uri("http://repo.dmulloy2.net/content/groups/public/") }
|
||||||
maven { url = uri("http://ci.ender.zone/plugin/repository/everything/") }
|
maven { url = uri("http://ci.ender.zone/plugin/repository/everything/") }
|
||||||
|
maven { url = uri("https://repo.inventivetalent.org/content/groups/public/")}
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations.all {
|
configurations.all {
|
||||||
@ -49,6 +50,9 @@ dependencies {
|
|||||||
exclude("com.sk89q.worldedit.worldedit-libs", "bukkit")
|
exclude("com.sk89q.worldedit.worldedit-libs", "bukkit")
|
||||||
exclude("com.sk89q.worldedit.worldedit-libs", "core")
|
exclude("com.sk89q.worldedit.worldedit-libs", "core")
|
||||||
}
|
}
|
||||||
|
"implementation"("org.inventivetalent:mapmanager:1.7.3-SNAPSHOT") { isTransitive = false }
|
||||||
|
"implementation"("org.inventivetalent:mapmanager:1.7.3-SNAPSHOT") { isTransitive = false }
|
||||||
|
|
||||||
"implementation"("com.massivecraft:factions:2.8.0") { isTransitive = false }
|
"implementation"("com.massivecraft:factions:2.8.0") { isTransitive = false }
|
||||||
"implementation"("com.drtshock:factions:1.6.9.5") { isTransitive = false }
|
"implementation"("com.drtshock:factions:1.6.9.5") { isTransitive = false }
|
||||||
"implementation"("com.github.TechFortress:GriefPrevention:16.12.0") { isTransitive = false }
|
"implementation"("com.github.TechFortress:GriefPrevention:16.12.0") { isTransitive = false }
|
||||||
|
@ -3,6 +3,8 @@ package com.boydti.fawe.bukkit;
|
|||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.IFawe;
|
import com.boydti.fawe.IFawe;
|
||||||
import com.boydti.fawe.beta.implementation.QueueHandler;
|
import com.boydti.fawe.beta.implementation.QueueHandler;
|
||||||
|
import com.boydti.fawe.beta.preloader.AsyncPreloader;
|
||||||
|
import com.boydti.fawe.beta.preloader.Preloader;
|
||||||
import com.boydti.fawe.bukkit.adapter.BukkitQueueHandler;
|
import com.boydti.fawe.bukkit.adapter.BukkitQueueHandler;
|
||||||
import com.boydti.fawe.bukkit.listener.BrushListener;
|
import com.boydti.fawe.bukkit.listener.BrushListener;
|
||||||
import com.boydti.fawe.bukkit.listener.BukkitImageListener;
|
import com.boydti.fawe.bukkit.listener.BukkitImageListener;
|
||||||
@ -55,14 +57,14 @@ import org.bukkit.plugin.java.JavaPlugin;
|
|||||||
|
|
||||||
public class FaweBukkit implements IFawe, Listener {
|
public class FaweBukkit implements IFawe, Listener {
|
||||||
|
|
||||||
// private final WorldEditPlugin plugin;
|
|
||||||
private final Plugin plugin;
|
private final Plugin plugin;
|
||||||
private VaultUtil vault;
|
private VaultUtil vault;
|
||||||
private ItemUtil itemUtil;
|
private ItemUtil itemUtil;
|
||||||
|
|
||||||
private boolean listeningImages;
|
private boolean listeningImages;
|
||||||
private BukkitImageListener imageListener;
|
private BukkitImageListener imageListener;
|
||||||
//private CFIPacketListener packetListener;
|
|
||||||
|
public static boolean PAPER;
|
||||||
|
|
||||||
public VaultUtil getVault() {
|
public VaultUtil getVault() {
|
||||||
return this.vault;
|
return this.vault;
|
||||||
@ -70,6 +72,13 @@ public class FaweBukkit implements IFawe, Listener {
|
|||||||
|
|
||||||
public FaweBukkit(Plugin plugin) {
|
public FaweBukkit(Plugin plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
try {
|
||||||
|
Class.forName("com.destroystokyo.paper.Namespaced");
|
||||||
|
PAPER = true;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
// TODO no paper
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
Settings.IMP.TICK_LIMITER.ENABLED = !Bukkit.hasWhitelist();
|
Settings.IMP.TICK_LIMITER.ENABLED = !Bukkit.hasWhitelist();
|
||||||
Fawe.set(this);
|
Fawe.set(this);
|
||||||
@ -398,4 +407,12 @@ public class FaweBukkit implements IFawe, Listener {
|
|||||||
return null;
|
return null;
|
||||||
// return ((BlocksHubBukkit) blocksHubPlugin).getApi();
|
// return ((BlocksHubBukkit) blocksHubPlugin).getApi();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Preloader getPreloader() {
|
||||||
|
if (PAPER) {
|
||||||
|
return new AsyncPreloader();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package com.boydti.fawe.bukkit.adapter.mc1_14;
|
|||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
|
import com.boydti.fawe.bukkit.FaweBukkit;
|
||||||
import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.collection.BitArray4096;
|
import com.boydti.fawe.object.collection.BitArray4096;
|
||||||
@ -21,6 +22,7 @@ import net.minecraft.server.v1_14_R1.DataPaletteBlock;
|
|||||||
import net.minecraft.server.v1_14_R1.DataPaletteLinear;
|
import net.minecraft.server.v1_14_R1.DataPaletteLinear;
|
||||||
import net.minecraft.server.v1_14_R1.GameProfileSerializer;
|
import net.minecraft.server.v1_14_R1.GameProfileSerializer;
|
||||||
import net.minecraft.server.v1_14_R1.IBlockData;
|
import net.minecraft.server.v1_14_R1.IBlockData;
|
||||||
|
import net.minecraft.server.v1_14_R1.PacketPlayOutMapChunk;
|
||||||
import net.minecraft.server.v1_14_R1.PlayerChunk;
|
import net.minecraft.server.v1_14_R1.PlayerChunk;
|
||||||
import net.minecraft.server.v1_14_R1.PlayerChunkMap;
|
import net.minecraft.server.v1_14_R1.PlayerChunkMap;
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.CraftChunk;
|
import org.bukkit.craftbukkit.v1_14_R1.CraftChunk;
|
||||||
@ -133,8 +135,6 @@ public class BukkitAdapter_1_14 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean PAPER = true;
|
|
||||||
|
|
||||||
public static Chunk ensureLoaded(net.minecraft.server.v1_14_R1.World nmsWorld, int X, int Z) {
|
public static Chunk ensureLoaded(net.minecraft.server.v1_14_R1.World nmsWorld, int X, int Z) {
|
||||||
Chunk nmsChunk = nmsWorld.getChunkIfLoaded(X, Z);
|
Chunk nmsChunk = nmsWorld.getChunkIfLoaded(X, Z);
|
||||||
if (nmsChunk != null) {
|
if (nmsChunk != null) {
|
||||||
@ -143,7 +143,7 @@ public class BukkitAdapter_1_14 {
|
|||||||
if (Fawe.isMainThread()) {
|
if (Fawe.isMainThread()) {
|
||||||
return nmsWorld.getChunkAt(X, Z);
|
return nmsWorld.getChunkAt(X, Z);
|
||||||
}
|
}
|
||||||
if (PAPER) {
|
if (FaweBukkit.PAPER) {
|
||||||
CraftWorld craftWorld = nmsWorld.getWorld();
|
CraftWorld craftWorld = nmsWorld.getWorld();
|
||||||
CompletableFuture<org.bukkit.Chunk> future = craftWorld.getChunkAtAsync(X, Z, true);
|
CompletableFuture<org.bukkit.Chunk> future = craftWorld.getChunkAtAsync(X, Z, true);
|
||||||
try {
|
try {
|
||||||
@ -154,8 +154,7 @@ public class BukkitAdapter_1_14 {
|
|||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
System.out.println("Error, cannot load chunk async (paper not installed?)");
|
e.printStackTrace();
|
||||||
PAPER = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO optimize
|
// TODO optimize
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package com.boydti.fawe.bukkit.adapter.mc1_14;
|
package com.boydti.fawe.bukkit.adapter.mc1_14;
|
||||||
|
|
||||||
|
import com.bekvon.bukkit.residence.commands.material;
|
||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
@ -132,6 +133,7 @@ import java.util.Collections;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.OptionalInt;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
@ -590,6 +592,13 @@ public final class Spigot_v1_14_R4 extends CachedBukkitAdapter implements Bukkit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OptionalInt getInternalBlockStateId(BlockState state) {
|
||||||
|
BlockMaterial_1_14 material = (BlockMaterial_1_14) state.getMaterial();
|
||||||
|
IBlockData mcState = material.getCraftBlockData().getState();
|
||||||
|
return OptionalInt.of(Block.REGISTRY_ID.getId(mcState));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState adapt(BlockData blockData) {
|
public BlockState adapt(BlockData blockData) {
|
||||||
CraftBlockData cbd = ((CraftBlockData) blockData);
|
CraftBlockData cbd = ((CraftBlockData) blockData);
|
||||||
|
@ -1,111 +0,0 @@
|
|||||||
package com.boydti.fawe.bukkit.chat;
|
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import org.apache.commons.lang.Validate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a wrapper around an array class of an arbitrary reference type,
|
|
||||||
* which properly implements "value" hash code and equality functions.
|
|
||||||
* <p>
|
|
||||||
* This class is intended for use as a key to a map.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param <E> The type of elements in the array.
|
|
||||||
* @author Glen Husman
|
|
||||||
* @see Arrays
|
|
||||||
*/
|
|
||||||
public final class ArrayWrapper<E> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an array wrapper with some elements.
|
|
||||||
*
|
|
||||||
* @param elements The elements of the array.
|
|
||||||
*/
|
|
||||||
@SafeVarargs
|
|
||||||
public ArrayWrapper(E... elements) {
|
|
||||||
setArray(elements);
|
|
||||||
}
|
|
||||||
|
|
||||||
private E[] _array;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves a reference to the wrapped array instance.
|
|
||||||
*
|
|
||||||
* @return The array wrapped by this instance.
|
|
||||||
*/
|
|
||||||
public E[] getArray() {
|
|
||||||
return _array;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set this wrapper to wrap a new array instance.
|
|
||||||
*
|
|
||||||
* @param array The new wrapped array.
|
|
||||||
*/
|
|
||||||
public void setArray(E[] array) {
|
|
||||||
Validate.notNull(array, "The array must not be null.");
|
|
||||||
_array = array;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if this object has a value equivalent to another object.
|
|
||||||
*
|
|
||||||
* @see Arrays#equals(Object[], Object[])
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object other) {
|
|
||||||
if (!(other instanceof ArrayWrapper)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return Arrays.equals(_array, ((ArrayWrapper) other)._array);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the hash code represented by this objects value.
|
|
||||||
*
|
|
||||||
* @return This object's hash code.
|
|
||||||
* @see Arrays#hashCode(Object[])
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Arrays.hashCode(_array);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts an iterable element collection to an array of elements.
|
|
||||||
* The iteration order of the specified object will be used as the array element order.
|
|
||||||
*
|
|
||||||
* @param list The iterable of objects which will be converted to an array.
|
|
||||||
* @param c The type of the elements of the array.
|
|
||||||
* @return An array of elements in the specified iterable.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static <T> T[] toArray(Iterable<? extends T> list, Class<T> c) {
|
|
||||||
int size = -1;
|
|
||||||
if (list instanceof Collection<?>) {
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
Collection coll = (Collection) list;
|
|
||||||
size = coll.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (size < 0) {
|
|
||||||
size = 0;
|
|
||||||
// Ugly hack: Count it ourselves
|
|
||||||
for (@SuppressWarnings("unused") T element : list) {
|
|
||||||
size++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
T[] result = (T[]) Array.newInstance(c, size);
|
|
||||||
int i = 0;
|
|
||||||
for (T element : list) { // Assumes iteration order is consistent
|
|
||||||
result[i++] = element; // Assign array element at index THEN increment counter
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
package com.boydti.fawe.bukkit.chat;
|
|
||||||
|
|
||||||
import com.google.gson.stream.JsonWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents an object that can be serialized to a JSON writer instance.
|
|
||||||
*/
|
|
||||||
interface JsonRepresentedObject {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes the JSON representation of this object to the specified writer.
|
|
||||||
* @param writer The JSON writer which will receive the object.
|
|
||||||
* @throws IOException If an error occurs writing to the stream.
|
|
||||||
*/
|
|
||||||
public void writeJson(JsonWriter writer) throws IOException;
|
|
||||||
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
package com.boydti.fawe.bukkit.chat;
|
|
||||||
|
|
||||||
import com.google.gson.stream.JsonWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a JSON string value.
|
|
||||||
* Writes by this object will not write name values nor begin/end objects in the JSON stream.
|
|
||||||
* All writes merely write the represented string value.
|
|
||||||
*/
|
|
||||||
final class JsonString implements JsonRepresentedObject, ConfigurationSerializable {
|
|
||||||
|
|
||||||
private String _value;
|
|
||||||
|
|
||||||
public JsonString(CharSequence value) {
|
|
||||||
_value = value == null ? null : value.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeJson(JsonWriter writer) throws IOException {
|
|
||||||
writer.value(getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return _value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, Object> serialize() {
|
|
||||||
HashMap<String, Object> theSingleValue = new HashMap<>();
|
|
||||||
theSingleValue.put("stringValue", _value);
|
|
||||||
return theSingleValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static JsonString deserialize(Map<String, Object> map) {
|
|
||||||
return new JsonString(map.get("stringValue").toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return _value;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,201 +0,0 @@
|
|||||||
package com.boydti.fawe.bukkit.chat;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class containing static utility methods and caches which are intended as reflective conveniences.
|
|
||||||
* Unless otherwise noted, upon failure methods will return {@code null}.
|
|
||||||
*/
|
|
||||||
public final class Reflection {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores loaded classes from the {@code net.minecraft.server} package.
|
|
||||||
*/
|
|
||||||
private static final Map<String, Class<?>> _loadedNMSClasses = new HashMap<>();
|
|
||||||
/**
|
|
||||||
* Stores loaded classes from the {@code org.bukkit.craftbukkit} package (and subpackages).
|
|
||||||
*/
|
|
||||||
private static final Map<String, Class<?>> _loadedOBCClasses = new HashMap<>();
|
|
||||||
private static final Map<Class<?>, Map<String, Field>> _loadedFields = new HashMap<>();
|
|
||||||
/**
|
|
||||||
* Contains loaded methods in a cache.
|
|
||||||
* The map maps [types to maps of [method names to maps of [parameter types to method instances]]].
|
|
||||||
*/
|
|
||||||
private static final Map<Class<?>, Map<String, Map<ArrayWrapper<Class<?>>, Method>>> _loadedMethods = new HashMap<>();
|
|
||||||
private static String _versionString;
|
|
||||||
|
|
||||||
private Reflection() { }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the version string from the package name of the CraftBukkit server implementation.
|
|
||||||
* This is needed to bypass the JAR package name changing on each update.
|
|
||||||
*
|
|
||||||
* @return The version string of the OBC and NMS packages, <em>including the trailing dot</em>.
|
|
||||||
*/
|
|
||||||
public synchronized static String getVersion() {
|
|
||||||
if (_versionString == null) {
|
|
||||||
String name = Bukkit.getServer().getClass().getPackage().getName();
|
|
||||||
_versionString = name.substring(name.lastIndexOf('.') + 1) + ".";
|
|
||||||
}
|
|
||||||
|
|
||||||
return _versionString;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a {@link Class} object representing a type contained within the {@code net.minecraft.server} versioned package.
|
|
||||||
* The class instances returned by this method are cached, such that no lookup will be done twice (unless multiple threads are accessing this method simultaneously).
|
|
||||||
*
|
|
||||||
* @param className The name of the class, excluding the package, within NMS.
|
|
||||||
* @return The class instance representing the specified NMS class, or {@code null} if it could not be loaded.
|
|
||||||
*/
|
|
||||||
public synchronized static Class<?> getNMSClass(String className) {
|
|
||||||
if (_loadedNMSClasses.containsKey(className)) {
|
|
||||||
return _loadedNMSClasses.get(className);
|
|
||||||
}
|
|
||||||
|
|
||||||
String fullName = "net.minecraft.server." + getVersion() + className;
|
|
||||||
Class<?> clazz;
|
|
||||||
try {
|
|
||||||
clazz = Class.forName(fullName);
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
_loadedNMSClasses.put(className, null);
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
_loadedNMSClasses.put(className, clazz);
|
|
||||||
return clazz;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a {@link Class} object representing a type contained within the {@code org.bukkit.craftbukkit} versioned package.
|
|
||||||
* The class instances returned by this method are cached, such that no lookup will be done twice (unless multiple threads are accessing this method simultaneously).
|
|
||||||
*
|
|
||||||
* @param className The name of the class, excluding the package, within OBC. This name may contain a subpackage name, such as {@code inventory.CraftItemStack}.
|
|
||||||
* @return The class instance representing the specified OBC class, or {@code null} if it could not be loaded.
|
|
||||||
*/
|
|
||||||
public synchronized static Class<?> getOBCClass(String className) {
|
|
||||||
if (_loadedOBCClasses.containsKey(className)) {
|
|
||||||
return _loadedOBCClasses.get(className);
|
|
||||||
}
|
|
||||||
|
|
||||||
String fullName = "org.bukkit.craftbukkit." + getVersion() + className;
|
|
||||||
Class<?> clazz;
|
|
||||||
try {
|
|
||||||
clazz = Class.forName(fullName);
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
_loadedOBCClasses.put(className, null);
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
_loadedOBCClasses.put(className, clazz);
|
|
||||||
return clazz;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempts to get the NMS handle of a CraftBukkit object.
|
|
||||||
* <p>
|
|
||||||
* The only match currently attempted by this method is a retrieval by using a parameterless {@code getHandle()} method implemented by the runtime type of the specified object.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param obj The object for which to retrieve an NMS handle.
|
|
||||||
* @return The NMS handle of the specified object, or {@code null} if it could not be retrieved using {@code getHandle()}.
|
|
||||||
*/
|
|
||||||
public synchronized static Object getHandle(Object obj) throws InvocationTargetException, IllegalAccessException, IllegalArgumentException {
|
|
||||||
return getMethod(obj.getClass(), "getHandle").invoke(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves a {@link Field} instance declared by the specified class with the specified name.
|
|
||||||
* Java access modifiers are ignored during this retrieval. No guarantee is made as to whether the field
|
|
||||||
* returned will be an instance or static field.
|
|
||||||
* <p>
|
|
||||||
* A global caching mechanism within this class is used to store fields. Combined with synchronization, this guarantees that
|
|
||||||
* no field will be reflectively looked up twice.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* If a field is deemed suitable for return, {@link Field#setAccessible(boolean) setAccessible} will be invoked with an argument of {@code true} before it is returned.
|
|
||||||
* This ensures that callers do not have to check or worry about Java access modifiers when dealing with the returned instance.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param clazz The class which contains the field to retrieve.
|
|
||||||
* @param name The declared name of the field in the class.
|
|
||||||
* @return A field object with the specified name declared by the specified class.
|
|
||||||
* @see Class#getDeclaredField(String)
|
|
||||||
*/
|
|
||||||
public synchronized static Field getField(Class<?> clazz, String name) {
|
|
||||||
Map<String, Field> loaded;
|
|
||||||
if (!_loadedFields.containsKey(clazz)) {
|
|
||||||
loaded = new HashMap<>();
|
|
||||||
_loadedFields.put(clazz, loaded);
|
|
||||||
} else {
|
|
||||||
loaded = _loadedFields.get(clazz);
|
|
||||||
}
|
|
||||||
if (loaded.containsKey(name)) {
|
|
||||||
// If the field is loaded (or cached as not existing), return the relevant value, which might be null
|
|
||||||
return loaded.get(name);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Field field = clazz.getDeclaredField(name);
|
|
||||||
field.setAccessible(true);
|
|
||||||
loaded.put(name, field);
|
|
||||||
return field;
|
|
||||||
} catch (NoSuchFieldException | SecurityException e) {
|
|
||||||
// Error loading
|
|
||||||
e.printStackTrace();
|
|
||||||
// Cache field as not existing
|
|
||||||
loaded.put(name, null);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves a {@link Method} instance declared by the specified class with the specified name and argument types.
|
|
||||||
* Java access modifiers are ignored during this retrieval. No guarantee is made as to whether the field
|
|
||||||
* returned will be an instance or static field.
|
|
||||||
* <p>
|
|
||||||
* A global caching mechanism within this class is used to store method. Combined with synchronization, this guarantees that
|
|
||||||
* no method will be reflectively looked up twice.
|
|
||||||
* <p>
|
|
||||||
* If a method is deemed suitable for return, {@link Method#setAccessible(boolean) setAccessible} will be invoked with an argument of {@code true} before it is returned.
|
|
||||||
* This ensures that callers do not have to check or worry about Java access modifiers when dealing with the returned instance.
|
|
||||||
* <p>
|
|
||||||
* This method does <em>not</em> search superclasses of the specified type for methods with the specified signature.
|
|
||||||
* Callers wishing this behavior should use {@link Class#getDeclaredMethod(String, Class...)}.
|
|
||||||
*
|
|
||||||
* @param clazz The class which contains the method to retrieve.
|
|
||||||
* @param name The declared name of the method in the class.
|
|
||||||
* @param args The formal argument types of the method.
|
|
||||||
* @return A method object with the specified name declared by the specified class.
|
|
||||||
*/
|
|
||||||
public synchronized static Method getMethod(Class<?> clazz, String name, Class<?>... args) {
|
|
||||||
if (!_loadedMethods.containsKey(clazz)) {
|
|
||||||
_loadedMethods.put(clazz, new HashMap<>());
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, Map<ArrayWrapper<Class<?>>, Method>> loadedMethodNames = _loadedMethods.get(clazz);
|
|
||||||
if (!loadedMethodNames.containsKey(name)) {
|
|
||||||
loadedMethodNames.put(name, new HashMap<>());
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<ArrayWrapper<Class<?>>, Method> loadedSignatures = loadedMethodNames.get(name);
|
|
||||||
ArrayWrapper<Class<?>> wrappedArg = new ArrayWrapper<>(args);
|
|
||||||
if (loadedSignatures.containsKey(wrappedArg)) {
|
|
||||||
return loadedSignatures.get(wrappedArg);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Method m : clazz.getMethods()) {
|
|
||||||
if (m.getName().equals(name) && Arrays.equals(args, m.getParameterTypes())) {
|
|
||||||
m.setAccessible(true);
|
|
||||||
loadedSignatures.put(wrappedArg, m);
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loadedSignatures.put(wrappedArg, null);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
package com.boydti.fawe.bukkit.listener;
|
|
||||||
|
|
||||||
public class ChunkCache {
|
|
||||||
}
|
|
@ -0,0 +1,196 @@
|
|||||||
|
package com.boydti.fawe.bukkit.preloader;
|
||||||
|
|
||||||
|
import com.boydti.fawe.Fawe;
|
||||||
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
import org.bukkit.Server;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
|
import org.bukkit.plugin.PluginBase;
|
||||||
|
import org.bukkit.plugin.PluginDescriptionFile;
|
||||||
|
import org.bukkit.plugin.PluginLoader;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.lang.ref.PhantomReference;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class PluginPreloader extends PluginBase {
|
||||||
|
private World world;
|
||||||
|
private Set<BlockVector2> loaded;
|
||||||
|
private int index;
|
||||||
|
private AtomicBoolean invalidator;
|
||||||
|
private final Object invalidatorLock;
|
||||||
|
|
||||||
|
public PluginPreloader() {
|
||||||
|
invalidator = new AtomicBoolean();
|
||||||
|
invalidatorLock = new Object();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AtomicBoolean invalidate() {
|
||||||
|
synchronized (invalidatorLock) {
|
||||||
|
invalidator.set(false);
|
||||||
|
return invalidator = new AtomicBoolean(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void unload() {
|
||||||
|
World oldWorld = world;
|
||||||
|
if (oldWorld != null) {
|
||||||
|
Set<BlockVector2> toUnload = loaded;
|
||||||
|
if (loaded != null && index > 0) {
|
||||||
|
Iterator<BlockVector2> iter = toUnload.iterator();
|
||||||
|
Fawe.get().getQueueHandler().sync(() -> {
|
||||||
|
for (int i = 0; i < index && iter.hasNext(); i++) {
|
||||||
|
BlockVector2 chunk = iter.next();
|
||||||
|
world.removePluginChunkTicket(chunk.getX(), chunk.getZ(), this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.world = null;
|
||||||
|
this.loaded = null;
|
||||||
|
this.index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(Region region) {
|
||||||
|
AtomicBoolean invalidator = invalidate();
|
||||||
|
synchronized (this) {
|
||||||
|
com.sk89q.worldedit.world.World weWorld = region.getWorld();
|
||||||
|
if (weWorld == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unload();
|
||||||
|
index = 0;
|
||||||
|
world = BukkitAdapter.adapt(weWorld);
|
||||||
|
loaded = region.getChunks();
|
||||||
|
Iterator<BlockVector2> iter = loaded.iterator();
|
||||||
|
|
||||||
|
if (!invalidator.get()) return;
|
||||||
|
Fawe.get().getQueueHandler().syncWhenFree(() -> {
|
||||||
|
for (; iter.hasNext() && invalidator.get();index++) {
|
||||||
|
BlockVector2 chunk = iter.next();
|
||||||
|
if (!world.isChunkLoaded(chunk.getX(), chunk.getZ())) {
|
||||||
|
world.addPluginChunkTicket(chunk.getX(), chunk.getZ(), this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
invalidate();
|
||||||
|
unload();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull File getDataFolder() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull PluginDescriptionFile getDescription() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull FileConfiguration getConfig() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable InputStream getResource(@NotNull String filename) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveConfig() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveDefaultConfig() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveResource(@NotNull String resourcePath, boolean replace) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reloadConfig() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull PluginLoader getPluginLoader() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Server getServer() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNaggable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNaggable(boolean canNag) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable ChunkGenerator getDefaultWorldGenerator(@NotNull String worldName, @Nullable String id) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Logger getLogger() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -19,173 +19,173 @@ import org.bukkit.entity.ItemFrame;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.PlayerInventory;
|
import org.bukkit.inventory.PlayerInventory;
|
||||||
//import org.inventivetalent.mapmanager.MapManagerPlugin;
|
import org.inventivetalent.mapmanager.MapManagerPlugin;
|
||||||
//import org.inventivetalent.mapmanager.controller.MapController;
|
import org.inventivetalent.mapmanager.controller.MapController;
|
||||||
//import org.inventivetalent.mapmanager.controller.MultiMapController;
|
import org.inventivetalent.mapmanager.controller.MultiMapController;
|
||||||
//import org.inventivetalent.mapmanager.manager.MapManager;
|
import org.inventivetalent.mapmanager.manager.MapManager;
|
||||||
//import org.inventivetalent.mapmanager.wrapper.MapWrapper;
|
import org.inventivetalent.mapmanager.wrapper.MapWrapper;
|
||||||
|
|
||||||
public class BukkitImageViewer implements ImageViewer {
|
public class BukkitImageViewer implements ImageViewer {
|
||||||
// private final MapManager mapManager;
|
private final MapManager mapManager;
|
||||||
// private final Player player;
|
private final Player player;
|
||||||
// private BufferedImage last;
|
private BufferedImage last;
|
||||||
private ItemFrame[][] frames;
|
private ItemFrame[][] frames;
|
||||||
// private boolean reverse;
|
private boolean reverse;
|
||||||
|
|
||||||
public BukkitImageViewer(Player player) {
|
public BukkitImageViewer(Player player) {
|
||||||
// mapManager = ((MapManagerPlugin) Bukkit.getPluginManager().getPlugin("MapManager")).getMapManager();
|
mapManager = ((MapManagerPlugin) Bukkit.getPluginManager().getPlugin("MapManager")).getMapManager();
|
||||||
// this.player = player;
|
this.player = player;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
public void selectFrame(ItemFrame start) {
|
public void selectFrame(ItemFrame start) {
|
||||||
// Location pos1 = start.getLocation().clone();
|
Location pos1 = start.getLocation().clone();
|
||||||
// Location pos2 = start.getLocation().clone();
|
Location pos2 = start.getLocation().clone();
|
||||||
//
|
|
||||||
// BlockFace facing = start.getFacing();
|
BlockFace facing = start.getFacing();
|
||||||
// int planeX = facing.getModX() == 0 ? 1 : 0;
|
int planeX = facing.getModX() == 0 ? 1 : 0;
|
||||||
// int planeY = facing.getModY() == 0 ? 1 : 0;
|
int planeY = facing.getModY() == 0 ? 1 : 0;
|
||||||
// int planeZ = facing.getModZ() == 0 ? 1 : 0;
|
int planeZ = facing.getModZ() == 0 ? 1 : 0;
|
||||||
//
|
|
||||||
// ItemFrame[][] res = find(pos1, pos2, facing);
|
ItemFrame[][] res = find(pos1, pos2, facing);
|
||||||
// Location tmp;
|
Location tmp;
|
||||||
// while (true) {
|
while (true) {
|
||||||
// if (res != null) {
|
if (res != null) {
|
||||||
// frames = res;
|
frames = res;
|
||||||
// }
|
|
||||||
// tmp = pos1.clone().subtract(planeX, planeY, planeZ);
|
|
||||||
// if ((res = find(tmp, pos2, facing)) != null) {
|
|
||||||
// pos1 = tmp;
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// tmp = pos2.clone().add(planeX, planeY, planeZ);
|
|
||||||
// if ((res = find(pos1, tmp, facing)) != null) {
|
|
||||||
// pos2 = tmp;
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// tmp = pos1.clone().subtract(planeX, 0, planeZ);
|
|
||||||
// if ((res = find(tmp, pos2, facing)) != null) {
|
|
||||||
// pos1 = tmp;
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// tmp = pos2.clone().add(planeX, 0, planeZ);
|
|
||||||
// if ((res = find(pos1, tmp, facing)) != null) {
|
|
||||||
// pos2 = tmp;
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// tmp = pos1.clone().subtract(0, 1, 0);
|
|
||||||
// if ((res = find(tmp, pos2, facing)) != null) {
|
|
||||||
// pos1 = tmp;
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// tmp = pos2.clone().add(0, 1, 0);
|
|
||||||
// if ((res = find(pos1, tmp, facing)) != null) {
|
|
||||||
// pos2 = tmp;
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
//
|
tmp = pos1.clone().subtract(planeX, planeY, planeZ);
|
||||||
|
if ((res = find(tmp, pos2, facing)) != null) {
|
||||||
|
pos1 = tmp;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tmp = pos2.clone().add(planeX, planeY, planeZ);
|
||||||
|
if ((res = find(pos1, tmp, facing)) != null) {
|
||||||
|
pos2 = tmp;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tmp = pos1.clone().subtract(planeX, 0, planeZ);
|
||||||
|
if ((res = find(tmp, pos2, facing)) != null) {
|
||||||
|
pos1 = tmp;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tmp = pos2.clone().add(planeX, 0, planeZ);
|
||||||
|
if ((res = find(pos1, tmp, facing)) != null) {
|
||||||
|
pos2 = tmp;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tmp = pos1.clone().subtract(0, 1, 0);
|
||||||
|
if ((res = find(tmp, pos2, facing)) != null) {
|
||||||
|
pos1 = tmp;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tmp = pos2.clone().add(0, 1, 0);
|
||||||
|
if ((res = find(pos1, tmp, facing)) != null) {
|
||||||
|
pos2 = tmp;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public ItemFrame[][] getItemFrames() {
|
public ItemFrame[][] getItemFrames() {
|
||||||
return frames;
|
return frames;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// private ItemFrame[][] find(Location pos1, Location pos2, BlockFace facing) {
|
private ItemFrame[][] find(Location pos1, Location pos2, BlockFace facing) {
|
||||||
// try {
|
try {
|
||||||
// Location distance = pos2.clone().subtract(pos1).add(1, 1, 1);
|
Location distance = pos2.clone().subtract(pos1).add(1, 1, 1);
|
||||||
// int width = Math.max(distance.getBlockX(), distance.getBlockZ());
|
int width = Math.max(distance.getBlockX(), distance.getBlockZ());
|
||||||
// ItemFrame[][] frames = new ItemFrame[width][distance.getBlockY()];
|
ItemFrame[][] frames = new ItemFrame[width][distance.getBlockY()];
|
||||||
//
|
|
||||||
// World world = pos1.getWorld();
|
World world = pos1.getWorld();
|
||||||
//
|
|
||||||
// this.reverse = (facing == BlockFace.NORTH || facing == BlockFace.EAST);
|
this.reverse = (facing == BlockFace.NORTH || facing == BlockFace.EAST);
|
||||||
// int v = 0;
|
int v = 0;
|
||||||
// for (double y = pos1.getY(); y <= pos2.getY(); y++, v++) {
|
for (double y = pos1.getY(); y <= pos2.getY(); y++, v++) {
|
||||||
// int h = 0;
|
int h = 0;
|
||||||
// for (double z = pos1.getZ(); z <= pos2.getZ(); z++) {
|
for (double z = pos1.getZ(); z <= pos2.getZ(); z++) {
|
||||||
// for (double x = pos1.getX(); x <= pos2.getX(); x++, h++) {
|
for (double x = pos1.getX(); x <= pos2.getX(); x++, h++) {
|
||||||
// Location pos = new Location(world, x, y, z);
|
Location pos = new Location(world, x, y, z);
|
||||||
// Collection<Entity> entities = world.getNearbyEntities(pos, 0.1, 0.1, 0.1);
|
Collection<Entity> entities = world.getNearbyEntities(pos, 0.1, 0.1, 0.1);
|
||||||
// boolean contains = false;
|
boolean contains = false;
|
||||||
// for (Entity ent : entities) {
|
for (Entity ent : entities) {
|
||||||
// if (ent instanceof ItemFrame && ((ItemFrame) ent).getFacing() == facing) {
|
if (ent instanceof ItemFrame && ((ItemFrame) ent).getFacing() == facing) {
|
||||||
// ItemFrame itemFrame = (ItemFrame) ent;
|
ItemFrame itemFrame = (ItemFrame) ent;
|
||||||
// itemFrame.setRotation(Rotation.NONE);
|
itemFrame.setRotation(Rotation.NONE);
|
||||||
// contains = true;
|
contains = true;
|
||||||
// frames[reverse ? width - 1 - h : h][v] = (ItemFrame) ent;
|
frames[reverse ? width - 1 - h : h][v] = (ItemFrame) ent;
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// if (!contains) return null;
|
if (!contains) return null;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// return frames;
|
return frames;
|
||||||
// } catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
// e.printStackTrace();
|
e.printStackTrace();
|
||||||
// }
|
}
|
||||||
// return null;
|
return null;
|
||||||
// }
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void view(Drawable drawable) {
|
public void view(Drawable drawable) {
|
||||||
// view(null, drawable);
|
view(null, drawable);
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// private void view(@Nullable BufferedImage image, @Nullable Drawable drawable) {
|
private void view(@Nullable BufferedImage image, @Nullable Drawable drawable) {
|
||||||
// if (image == null && drawable == null) throw new IllegalArgumentException("An image or drawable must be provided. Both cannot be null");
|
if (image == null && drawable == null) throw new IllegalArgumentException("An image or drawable must be provided. Both cannot be null");
|
||||||
// boolean initializing = last == null;
|
boolean initializing = last == null;
|
||||||
//
|
|
||||||
// if (this.frames != null) {
|
if (this.frames != null) {
|
||||||
// if (image == null && drawable != null) image = drawable.draw();
|
if (image == null && drawable != null) image = drawable.draw();
|
||||||
// last = image;
|
last = image;
|
||||||
// int width = frames.length;
|
int width = frames.length;
|
||||||
// int height = frames[0].length;
|
int height = frames[0].length;
|
||||||
// BufferedImage scaled = ImageUtil.getScaledInstance(image, 128 * width, 128 * height, RenderingHints.VALUE_INTERPOLATION_BILINEAR, false);
|
BufferedImage scaled = ImageUtil.getScaledInstance(image, 128 * width, 128 * height, RenderingHints.VALUE_INTERPOLATION_BILINEAR, false);
|
||||||
// MapWrapper mapWrapper = mapManager.wrapMultiImage(scaled, width, height);
|
MapWrapper mapWrapper = mapManager.wrapMultiImage(scaled, width, height);
|
||||||
// MultiMapController controller = (MultiMapController) mapWrapper.getController();
|
MultiMapController controller = (MultiMapController) mapWrapper.getController();
|
||||||
// controller.addViewer(player);
|
controller.addViewer(player);
|
||||||
// controller.sendContent(player);
|
controller.sendContent(player);
|
||||||
// controller.showInFrames(player, frames, true);
|
controller.showInFrames(player, frames, true);
|
||||||
// } else {
|
} else {
|
||||||
// int slot = getMapSlot(player);
|
int slot = getMapSlot(player);
|
||||||
// if (slot == -1) {
|
if (slot == -1) {
|
||||||
// if (initializing) {
|
if (initializing) {
|
||||||
// player.getInventory().setItemInMainHand(new ItemStack(Material.MAP));
|
player.getInventory().setItemInMainHand(new ItemStack(Material.MAP));
|
||||||
// } else {
|
} else {
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
// } else if (player.getInventory().getHeldItemSlot() != slot) {
|
} else if (player.getInventory().getHeldItemSlot() != slot) {
|
||||||
// player.getInventory().setHeldItemSlot(slot);
|
player.getInventory().setHeldItemSlot(slot);
|
||||||
// }
|
}
|
||||||
// if (image == null && drawable != null) image = drawable.draw();
|
if (image == null && drawable != null) image = drawable.draw();
|
||||||
// last = image;
|
last = image;
|
||||||
// BufferedImage scaled = ImageUtil.getScaledInstance(image, 128, 128, RenderingHints.VALUE_INTERPOLATION_BILINEAR, false);
|
BufferedImage scaled = ImageUtil.getScaledInstance(image, 128, 128, RenderingHints.VALUE_INTERPOLATION_BILINEAR, false);
|
||||||
// MapWrapper mapWrapper = mapManager.wrapImage(scaled);
|
MapWrapper mapWrapper = mapManager.wrapImage(scaled);
|
||||||
// MapController controller = mapWrapper.getController();
|
MapController controller = mapWrapper.getController();
|
||||||
// controller.addViewer(player);
|
controller.addViewer(player);
|
||||||
// controller.sendContent(player);
|
controller.sendContent(player);
|
||||||
// controller.showInHand(player, true);
|
controller.showInHand(player, true);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// private int getMapSlot(Player player) {
|
private int getMapSlot(Player player) {
|
||||||
// PlayerInventory inventory = player.getInventory();
|
PlayerInventory inventory = player.getInventory();
|
||||||
// for (int i = 0; i < 9; i++) {
|
for (int i = 0; i < 9; i++) {
|
||||||
// ItemStack item = inventory.getItem(i);
|
ItemStack item = inventory.getItem(i);
|
||||||
// if (item != null && item.getType() == Material.MAP) {
|
if (item != null && item.getType() == Material.MAP) {
|
||||||
// return i;
|
return i;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// return -1;
|
return -1;
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
public void refresh() {
|
public void refresh() {
|
||||||
// if (last != null) view(last, null);
|
if (last != null) view(last, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
// last = null;
|
last = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -34,6 +34,7 @@ import javax.annotation.Nullable;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.OptionalInt;
|
||||||
|
|
||||||
public class BukkitBlockRegistry extends BundledBlockRegistry {
|
public class BukkitBlockRegistry extends BundledBlockRegistry {
|
||||||
|
|
||||||
@ -93,6 +94,10 @@ public class BukkitBlockRegistry extends BundledBlockRegistry {
|
|||||||
this.material = bukkitMaterial;
|
this.material = bukkitMaterial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return material.getId();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAir() {
|
public boolean isAir() {
|
||||||
switch (material) {
|
switch (material) {
|
||||||
@ -132,4 +137,9 @@ public class BukkitBlockRegistry extends BundledBlockRegistry {
|
|||||||
}
|
}
|
||||||
return blocks;
|
return blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OptionalInt getInternalBlockStateId(BlockState state) {
|
||||||
|
return WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBlockStateId(state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,10 @@ import com.boydti.fawe.bukkit.FaweBukkit;
|
|||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.RunnableVal;
|
import com.boydti.fawe.object.RunnableVal;
|
||||||
import com.boydti.fawe.util.TaskManager;
|
import com.boydti.fawe.util.TaskManager;
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.ProtocolLibrary;
|
||||||
|
import com.comphenix.protocol.ProtocolManager;
|
||||||
|
import com.comphenix.protocol.injector.netty.WirePacket;
|
||||||
import com.sk89q.util.StringUtil;
|
import com.sk89q.util.StringUtil;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
@ -47,10 +51,13 @@ import com.sk89q.worldedit.world.block.BlockStateHolder;
|
|||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
import com.sk89q.worldedit.world.gamemode.GameMode;
|
import com.sk89q.worldedit.world.gamemode.GameMode;
|
||||||
import com.sk89q.worldedit.world.gamemode.GameModes;
|
import com.sk89q.worldedit.world.gamemode.GameModes;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.function.Supplier;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
@ -359,6 +366,21 @@ public class BukkitPlayer extends AbstractPlayerActor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendFakeChunk(int chunkX, int chunkZ, Supplier<byte[]> data) {
|
||||||
|
ProtocolManager manager = ProtocolLibrary.getProtocolManager();
|
||||||
|
// check if the chunk is in range
|
||||||
|
if (true) {
|
||||||
|
try {
|
||||||
|
byte[] raw = data.get();
|
||||||
|
WirePacket packet = new WirePacket(PacketType.Play.Server.MAP_CHUNK, raw);
|
||||||
|
manager.sendWirePacket(getPlayer(), packet);
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendTitle(String title, String sub) {
|
public void sendTitle(String title, String sub) {
|
||||||
player.sendTitle(ChatColor.GOLD + title, ChatColor.GOLD + sub, 0, 70, 20);
|
player.sendTitle(ChatColor.GOLD + title, ChatColor.GOLD + sub, 0, 70, 20);
|
||||||
|
@ -21,7 +21,9 @@ package com.sk89q.worldedit.bukkit;
|
|||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.beta.IChunkGet;
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
|
import com.boydti.fawe.bukkit.FaweBukkit;
|
||||||
import com.boydti.fawe.bukkit.adapter.mc1_14.BukkitGetBlocks_1_14;
|
import com.boydti.fawe.bukkit.adapter.mc1_14.BukkitGetBlocks_1_14;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
@ -317,8 +319,19 @@ public class BukkitWorld extends AbstractWorld {
|
|||||||
@Override
|
@Override
|
||||||
public void checkLoadedChunk(BlockVector3 pt) {
|
public void checkLoadedChunk(BlockVector3 pt) {
|
||||||
World world = getWorld();
|
World world = getWorld();
|
||||||
|
int X = pt.getBlockX() >> 4;
|
||||||
world.getChunkAt(pt.getBlockX() >> 4, pt.getBlockZ() >> 4);
|
int Z = pt.getBlockZ() >> 4;
|
||||||
|
if (Fawe.isMainThread()) {
|
||||||
|
world.getChunkAt(X, Z);
|
||||||
|
} else if (!world.isChunkLoaded(X, Z)) {
|
||||||
|
if (FaweBukkit.PAPER) {
|
||||||
|
world.getChunkAtAsync(X, Z, true);
|
||||||
|
} else {
|
||||||
|
Fawe.get().getQueueHandler().sync(() -> {
|
||||||
|
world.getChunkAt(X, Z);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -516,7 +529,8 @@ public class BukkitWorld extends AbstractWorld {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendChunk(int X, int Z, int mask) {
|
public void refreshChunk(int X, int Z) {
|
||||||
|
getWorld().refreshChunk(X, Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -84,6 +84,7 @@ import org.bukkit.entity.Player;
|
|||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.world.ChunkUnloadEvent;
|
||||||
import org.bukkit.event.world.WorldInitEvent;
|
import org.bukkit.event.world.WorldInitEvent;
|
||||||
import org.bukkit.metadata.FixedMetadataValue;
|
import org.bukkit.metadata.FixedMetadataValue;
|
||||||
import org.bukkit.metadata.MetadataValue;
|
import org.bukkit.metadata.MetadataValue;
|
||||||
@ -560,16 +561,24 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
|
|||||||
*/
|
*/
|
||||||
public BukkitPlayer wrapPlayer(Player player) {
|
public BukkitPlayer wrapPlayer(Player player) {
|
||||||
synchronized (player) {
|
synchronized (player) {
|
||||||
@NotNull List<MetadataValue> meta = player.getMetadata("WE");
|
BukkitPlayer wePlayer = getCachedPlayer(player);
|
||||||
if (meta == null || meta.isEmpty()) {
|
if (wePlayer == null) {
|
||||||
BukkitPlayer wePlayer = new BukkitPlayer(this, player);
|
wePlayer = new BukkitPlayer(this, player);
|
||||||
player.setMetadata("WE", new FixedMetadataValue(this, wePlayer));
|
player.setMetadata("WE", new FixedMetadataValue(this, wePlayer));
|
||||||
return wePlayer;
|
return wePlayer;
|
||||||
}
|
}
|
||||||
return (BukkitPlayer) meta.get(0).value();
|
return wePlayer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BukkitPlayer getCachedPlayer(Player player) {
|
||||||
|
List<MetadataValue> meta = player.getMetadata("WE");
|
||||||
|
if (meta == null || meta.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (BukkitPlayer) meta.get(0).value();
|
||||||
|
}
|
||||||
|
|
||||||
public Actor wrapCommandSender(CommandSender sender) {
|
public Actor wrapCommandSender(CommandSender sender) {
|
||||||
if (sender instanceof Player) {
|
if (sender instanceof Player) {
|
||||||
return wrapPlayer((Player) sender);
|
return wrapPlayer((Player) sender);
|
||||||
|
@ -228,6 +228,8 @@ public enum FaweCache implements Trimable {
|
|||||||
* Holds data for a palette used in a chunk section
|
* Holds data for a palette used in a chunk section
|
||||||
*/
|
*/
|
||||||
public final class Palette {
|
public final class Palette {
|
||||||
|
public int bitsPerEntry;
|
||||||
|
|
||||||
public int paletteToBlockLength;
|
public int paletteToBlockLength;
|
||||||
/**
|
/**
|
||||||
* Reusable buffer array, MUST check paletteToBlockLength for actual length
|
* Reusable buffer array, MUST check paletteToBlockLength for actual length
|
||||||
@ -319,6 +321,7 @@ public enum FaweCache implements Trimable {
|
|||||||
|
|
||||||
// Construct palette
|
// Construct palette
|
||||||
Palette palette = PALETTE_CACHE.get();
|
Palette palette = PALETTE_CACHE.get();
|
||||||
|
palette.bitsPerEntry = bitsPerEntry;
|
||||||
palette.paletteToBlockLength = num_palette;
|
palette.paletteToBlockLength = num_palette;
|
||||||
palette.paletteToBlock = paletteToBlock;
|
palette.paletteToBlock = paletteToBlock;
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package com.boydti.fawe;
|
package com.boydti.fawe;
|
||||||
|
|
||||||
import com.boydti.fawe.beta.implementation.QueueHandler;
|
import com.boydti.fawe.beta.implementation.QueueHandler;
|
||||||
|
import com.boydti.fawe.beta.preloader.AsyncPreloader;
|
||||||
|
import com.boydti.fawe.beta.preloader.Preloader;
|
||||||
import com.boydti.fawe.object.FaweCommand;
|
import com.boydti.fawe.object.FaweCommand;
|
||||||
import com.boydti.fawe.regions.FaweMaskManager;
|
import com.boydti.fawe.regions.FaweMaskManager;
|
||||||
import com.boydti.fawe.util.TaskManager;
|
import com.boydti.fawe.util.TaskManager;
|
||||||
@ -54,4 +56,6 @@ public interface IFawe {
|
|||||||
|
|
||||||
QueueHandler getQueueHandler();
|
QueueHandler getQueueHandler();
|
||||||
|
|
||||||
|
Preloader getPreloader();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
package com.boydti.fawe.beta;
|
|
||||||
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
|
||||||
|
|
||||||
public class ChunkFuture implements Future<Void> {
|
|
||||||
|
|
||||||
private final IChunk chunk;
|
|
||||||
private volatile boolean cancelled;
|
|
||||||
private volatile boolean done;
|
|
||||||
|
|
||||||
public ChunkFuture(IChunk chunk) {
|
|
||||||
this.chunk = chunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IChunk getChunk() {
|
|
||||||
return chunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
|
||||||
cancelled = true;
|
|
||||||
return !done;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCancelled() {
|
|
||||||
return cancelled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDone() {
|
|
||||||
return done;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void get() throws InterruptedException, ExecutionException {
|
|
||||||
synchronized (chunk) {
|
|
||||||
if (!done) {
|
|
||||||
this.wait();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void get(long timeout, TimeUnit unit)
|
|
||||||
throws InterruptedException, ExecutionException, TimeoutException {
|
|
||||||
synchronized (chunk) {
|
|
||||||
if (!done) {
|
|
||||||
this.wait(unit.toMillis(timeout));
|
|
||||||
if (!done) {
|
|
||||||
throw new TimeoutException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,6 @@
|
|||||||
package com.boydti.fawe.beta;
|
package com.boydti.fawe.beta;
|
||||||
|
|
||||||
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
@ -19,5 +20,20 @@ public interface IBlocks extends Trimable {
|
|||||||
|
|
||||||
BlockState getBlock(int x, int y, int z);
|
BlockState getBlock(int x, int y, int z);
|
||||||
|
|
||||||
|
Map<BlockVector3, CompoundTag> getTiles();
|
||||||
|
|
||||||
|
Set<CompoundTag> getEntities();
|
||||||
|
|
||||||
|
BiomeType getBiomeType(int x, int z);
|
||||||
|
|
||||||
|
default int getBitMask() {
|
||||||
|
int mask = 0;
|
||||||
|
for (int layer = 0; layer < FaweCache.IMP.CHUNK_LAYERS; layer++) {
|
||||||
|
if (hasSection(layer));
|
||||||
|
mask |= (1 << layer);
|
||||||
|
}
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
IBlocks reset();
|
IBlocks reset();
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,10 @@ public interface IChunkGet extends IBlocks, Trimable, InputExtent {
|
|||||||
|
|
||||||
CompoundTag getTag(int x, int y, int z);
|
CompoundTag getTag(int x, int y, int z);
|
||||||
|
|
||||||
|
@Override
|
||||||
Map<BlockVector3, CompoundTag> getTiles();
|
Map<BlockVector3, CompoundTag> getTiles();
|
||||||
|
|
||||||
|
@Override
|
||||||
Set<CompoundTag> getEntities();
|
Set<CompoundTag> getEntities();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -38,8 +38,13 @@ public interface IChunkSet extends IBlocks, OutputExtent {
|
|||||||
|
|
||||||
BiomeType[] getBiomes();
|
BiomeType[] getBiomes();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
BiomeType getBiomeType(int x, int z);
|
||||||
|
|
||||||
|
@Override
|
||||||
Map<BlockVector3, CompoundTag> getTiles();
|
Map<BlockVector3, CompoundTag> getTiles();
|
||||||
|
|
||||||
|
@Override
|
||||||
Set<CompoundTag> getEntities();
|
Set<CompoundTag> getEntities();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -45,16 +45,6 @@ public interface IDelegateQueueExtent extends IQueueExtent {
|
|||||||
return getParent().isQueueEnabled();
|
return getParent().isQueueEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
default void clearBlockUpdates(Player... players) {
|
|
||||||
getParent().clearBlockUpdates(players);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default void sendBlockUpdates(Player... players) {
|
|
||||||
getParent().sendBlockUpdates(players);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default void enableQueue() {
|
default void enableQueue() {
|
||||||
getParent().enableQueue();
|
getParent().enableQueue();
|
||||||
|
@ -31,22 +31,6 @@ public interface IQueueExtent extends Flushable, Trimable, Extent, IBatchProcess
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear any block updates
|
|
||||||
* @param players
|
|
||||||
*/
|
|
||||||
default void clearBlockUpdates(Player... players) {
|
|
||||||
throw new UnsupportedOperationException("TODO NOT IMPLEMENTED");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send all the chunks as block updates
|
|
||||||
* @param players
|
|
||||||
*/
|
|
||||||
default void sendBlockUpdates(Player... players) {
|
|
||||||
throw new UnsupportedOperationException("TODO NOT IMPLEMENTED");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Must ensure that it is enqueued with QueueHandler
|
* Must ensure that it is enqueued with QueueHandler
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,126 @@
|
|||||||
|
package com.boydti.fawe.beta.implementation;
|
||||||
|
|
||||||
|
import com.boydti.fawe.FaweCache;
|
||||||
|
import com.boydti.fawe.beta.IBlocks;
|
||||||
|
import com.boydti.fawe.object.FaweOutputStream;
|
||||||
|
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
||||||
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
|
import com.sk89q.worldedit.extension.platform.Capability;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockID;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
import com.sk89q.worldedit.world.registry.BlockRegistry;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class ChunkPacket implements Function<byte[], byte[]>, Supplier<byte[]> {
|
||||||
|
|
||||||
|
private final boolean full;
|
||||||
|
private final boolean biomes;
|
||||||
|
private final IBlocks chunk;
|
||||||
|
private final int chunkX;
|
||||||
|
private final int chunkZ;
|
||||||
|
|
||||||
|
public ChunkPacket(int chunkX, int chunkZ, IBlocks chunk, boolean replaceAllSections, boolean sendBiomeData) {
|
||||||
|
this.chunkX = chunkX;
|
||||||
|
this.chunkZ = chunkZ;
|
||||||
|
this.chunk = chunk;
|
||||||
|
this.full = replaceAllSections;
|
||||||
|
this.biomes = sendBiomeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public byte[] get() {
|
||||||
|
System.out.println("TODO deprecated, use buffer");
|
||||||
|
return apply(new byte[8192]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] apply(byte[] buffer) {
|
||||||
|
try {
|
||||||
|
FastByteArrayOutputStream baos = new FastByteArrayOutputStream();
|
||||||
|
FaweOutputStream fos = new FaweOutputStream(baos);
|
||||||
|
|
||||||
|
fos.writeInt(this.chunkX);
|
||||||
|
fos.writeInt(this.chunkZ);
|
||||||
|
|
||||||
|
fos.writeBoolean(this.full);
|
||||||
|
|
||||||
|
fos.writeVarInt(this.chunk.getBitMask()); // writeVarInt
|
||||||
|
|
||||||
|
// TODO write NBTTagCompound of HeightMaps
|
||||||
|
fos.writeVarInt(0); // (Entities / NBT)
|
||||||
|
|
||||||
|
// TODO write chunk data to byte[]
|
||||||
|
{
|
||||||
|
BlockRegistry registry = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry();
|
||||||
|
try (FastByteArrayOutputStream sectionByteArray = new FastByteArrayOutputStream(buffer); FaweOutputStream sectionWriter = new FaweOutputStream(sectionByteArray)) {
|
||||||
|
for (int layer = 0; layer < FaweCache.IMP.CHUNK_LAYERS; layer++) {
|
||||||
|
if (!this.chunk.hasSection(layer)) continue;
|
||||||
|
char[] ids = this.chunk.getArray(layer);
|
||||||
|
FaweCache.Palette palette = FaweCache.IMP.toPalette(0, ids);
|
||||||
|
|
||||||
|
int nonEmpty = 0; // TODO optimize into same loop as toPalette
|
||||||
|
for (char id :ids) {
|
||||||
|
if (id != 0) nonEmpty++;
|
||||||
|
}
|
||||||
|
sectionWriter.writeShort(nonEmpty); // non empty
|
||||||
|
sectionWriter.writeByte(palette.bitsPerEntry); // bits per block
|
||||||
|
sectionWriter.writeVarInt(palette.paletteToBlockLength);
|
||||||
|
for (int i = 0; i < palette.paletteToBlockLength; i++) {
|
||||||
|
int ordinal = palette.paletteToBlock[i];
|
||||||
|
switch (ordinal) {
|
||||||
|
case BlockID.CAVE_AIR:
|
||||||
|
case BlockID.VOID_AIR:
|
||||||
|
case BlockID.AIR:
|
||||||
|
case BlockID.__RESERVED__:
|
||||||
|
sectionWriter.writeByte(0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BlockState state = BlockState.getFromOrdinal(ordinal);
|
||||||
|
int mcId = registry.getInternalBlockStateId(state).getAsInt();
|
||||||
|
sectionWriter.writeVarInt(mcId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sectionWriter.writeVarInt(palette.blockStatesLength);
|
||||||
|
for (int i = 0; i < palette.blockStatesLength; i++) {
|
||||||
|
sectionWriter.writeLong(palette.blockStates[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO write biomes
|
||||||
|
// boolean writeBiomes = true;
|
||||||
|
// for (int x = 0; x < 16; x++) {
|
||||||
|
// for (int z = 0; z < 16; z++) {
|
||||||
|
// BiomeType biome = this.chunk.getBiomeType(x, z);
|
||||||
|
// if (biome == null) {
|
||||||
|
// if (writeBiomes) {
|
||||||
|
// break;
|
||||||
|
// } else {
|
||||||
|
// biome = BiomeTypes.FOREST;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
if (this.full) {
|
||||||
|
for (int i = 0; i < 256; i++) {
|
||||||
|
sectionWriter.writeInt(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fos.writeVarInt(sectionByteArray.getSize());
|
||||||
|
for (byte[] arr : sectionByteArray.toByteArrays()) {
|
||||||
|
fos.write(arr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO entities / NBT
|
||||||
|
fos.writeVarInt(0); // (Entities / NBT)
|
||||||
|
return baos.toByteArray();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.boydti.fawe.beta.implementation;
|
||||||
|
|
||||||
|
import com.boydti.fawe.beta.IBatchProcessor;
|
||||||
|
import com.boydti.fawe.beta.IChunk;
|
||||||
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
|
import com.boydti.fawe.object.extent.NullExtent;
|
||||||
|
import com.google.common.base.Suppliers;
|
||||||
|
import com.sk89q.worldedit.entity.Player;
|
||||||
|
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class ChunkSendProcessor extends AbstractDelegateExtent implements IBatchProcessor {
|
||||||
|
private final Supplier<Stream<Player>> players;
|
||||||
|
|
||||||
|
public ChunkSendProcessor(Supplier<Stream<Player>> players) {
|
||||||
|
super(new NullExtent());
|
||||||
|
this.players = players;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
|
int chunkX = chunk.getX();
|
||||||
|
int chunkZ = chunk.getZ();
|
||||||
|
boolean replaceAll = true;
|
||||||
|
boolean sendBiome = set.getBiomes() != null;
|
||||||
|
ChunkPacket packet = new ChunkPacket(chunkX, chunkZ, set, replaceAll, sendBiome);
|
||||||
|
Supplier<byte[]> packetData = Suppliers.memoize(packet::get);
|
||||||
|
players.get().forEach(plr -> plr.sendFakeChunk(chunkX, chunkZ, packetData));
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Extent construct(Extent child) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -170,6 +170,7 @@ public class ParallelQueueExtent extends PassthroughExtent implements IQueueWrap
|
|||||||
if (vset instanceof Region) {
|
if (vset instanceof Region) {
|
||||||
setBlocks((Region) vset, pattern);
|
setBlocks((Region) vset, pattern);
|
||||||
}
|
}
|
||||||
|
// TODO optimize parallel
|
||||||
for (BlockVector3 blockVector3 : vset) {
|
for (BlockVector3 blockVector3 : vset) {
|
||||||
pattern.apply(this, blockVector3, blockVector3);
|
pattern.apply(this, blockVector3, blockVector3);
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import java.lang.ref.WeakReference;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Queue;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
@ -39,6 +40,7 @@ public abstract class QueueHandler implements Trimable, Runnable {
|
|||||||
private ForkJoinPool forkJoinPoolSecondary = new ForkJoinPool();
|
private ForkJoinPool forkJoinPoolSecondary = new ForkJoinPool();
|
||||||
private ThreadPoolExecutor blockingExecutor = FaweCache.IMP.newBlockingExecutor();
|
private ThreadPoolExecutor blockingExecutor = FaweCache.IMP.newBlockingExecutor();
|
||||||
private ConcurrentLinkedQueue<FutureTask> syncTasks = new ConcurrentLinkedQueue<>();
|
private ConcurrentLinkedQueue<FutureTask> syncTasks = new ConcurrentLinkedQueue<>();
|
||||||
|
private ConcurrentLinkedQueue<FutureTask> syncWhenFree = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
private Map<World, WeakReference<IChunkCache<IChunkGet>>> chunkGetCache = new HashMap<>();
|
private Map<World, WeakReference<IChunkCache<IChunkGet>>> chunkGetCache = new HashMap<>();
|
||||||
private CleanableThreadLocal<IQueueExtent> queuePool = new CleanableThreadLocal<>(QueueHandler.this::create);
|
private CleanableThreadLocal<IQueueExtent> queuePool = new CleanableThreadLocal<>(QueueHandler.this::create);
|
||||||
@ -60,6 +62,23 @@ public abstract class QueueHandler implements Trimable, Runnable {
|
|||||||
throw new IllegalStateException("Not main thread");
|
throw new IllegalStateException("Not main thread");
|
||||||
}
|
}
|
||||||
if (!syncTasks.isEmpty()) {
|
if (!syncTasks.isEmpty()) {
|
||||||
|
long currentAllocate = getAllocate();
|
||||||
|
|
||||||
|
if (!MemUtil.isMemoryFree()) {
|
||||||
|
// TODO reduce mem usage
|
||||||
|
// FaweCache trim
|
||||||
|
// Preloader trim
|
||||||
|
}
|
||||||
|
|
||||||
|
operate(syncTasks, last, currentAllocate);
|
||||||
|
} else if (!syncWhenFree.isEmpty()) {
|
||||||
|
operate(syncWhenFree, last, getAllocate());
|
||||||
|
} else {
|
||||||
|
// trim??
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getAllocate() {
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
targetTPS = 18 - Math.max(Settings.IMP.QUEUE.EXTRA_TIME_MS * 0.05, 0);
|
targetTPS = 18 - Math.max(Settings.IMP.QUEUE.EXTRA_TIME_MS * 0.05, 0);
|
||||||
long diff = 50 + this.last - (this.last = now);
|
long diff = 50 + this.last - (this.last = now);
|
||||||
@ -71,25 +90,23 @@ public abstract class QueueHandler implements Trimable, Runnable {
|
|||||||
} else if (!Fawe.get().getTimer().isAbove(targetTPS)) {
|
} else if (!Fawe.get().getTimer().isAbove(targetTPS)) {
|
||||||
allocate = Math.max(5, allocate - 1);
|
allocate = Math.max(5, allocate - 1);
|
||||||
}
|
}
|
||||||
long currentAllocate = allocate - absDiff;
|
return allocate - absDiff;
|
||||||
|
|
||||||
if (!MemUtil.isMemoryFree()) {
|
|
||||||
// TODO reduce mem usage
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void operate(Queue<FutureTask> queue, long start, long currentAllocate) {
|
||||||
boolean wait = false;
|
boolean wait = false;
|
||||||
do {
|
do {
|
||||||
Runnable task = syncTasks.poll();
|
Runnable task = queue.poll();
|
||||||
if (task == null) {
|
if (task == null) {
|
||||||
if (wait) {
|
if (wait) {
|
||||||
synchronized (syncTasks) {
|
synchronized (syncTasks) {
|
||||||
try {
|
try {
|
||||||
syncTasks.wait(1);
|
queue.wait(1);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
task = syncTasks.poll();
|
task = queue.poll();
|
||||||
wait = false;
|
wait = false;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
@ -99,14 +116,7 @@ public abstract class QueueHandler implements Trimable, Runnable {
|
|||||||
task.run();
|
task.run();
|
||||||
wait = true;
|
wait = true;
|
||||||
}
|
}
|
||||||
} while (System.currentTimeMillis() - now < currentAllocate);
|
} while (System.currentTimeMillis() - start < currentAllocate);
|
||||||
}
|
|
||||||
while (!syncTasks.isEmpty()) {
|
|
||||||
final FutureTask task = syncTasks.poll();
|
|
||||||
if (task != null) {
|
|
||||||
task.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends Future<T>> void complete(Future<T> task) {
|
public <T extends Future<T>> void complete(Future<T> task) {
|
||||||
@ -136,50 +146,83 @@ public abstract class QueueHandler implements Trimable, Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public <T> Future<T> sync(Runnable run, T value) {
|
public <T> Future<T> sync(Runnable run, T value) {
|
||||||
|
return sync(run, value, syncTasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> Future<T> sync(Runnable run) {
|
||||||
|
return sync(run, syncTasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> Future<T> sync(Callable<T> call) throws Exception {
|
||||||
|
return sync(call, syncTasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> Future<T> sync(Supplier<T> call) {
|
||||||
|
return sync(call, syncTasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lower priorty sync task (runs only when there are no other tasks)
|
||||||
|
public <T> Future<T> syncWhenFree(Runnable run, T value) {
|
||||||
|
return sync(run, value, syncWhenFree);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> Future<T> syncWhenFree(Runnable run) {
|
||||||
|
return sync(run, syncWhenFree);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> Future<T> syncWhenFree(Callable<T> call) throws Exception {
|
||||||
|
return sync(call, syncWhenFree);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> Future<T> syncWhenFree(Supplier<T> call) {
|
||||||
|
return sync(call, syncWhenFree);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> Future<T> sync(Runnable run, T value, Queue<FutureTask> queue) {
|
||||||
if (Fawe.isMainThread()) {
|
if (Fawe.isMainThread()) {
|
||||||
run.run();
|
run.run();
|
||||||
return Futures.immediateFuture(value);
|
return Futures.immediateFuture(value);
|
||||||
}
|
}
|
||||||
final FutureTask<T> result = new FutureTask<>(run, value);
|
final FutureTask<T> result = new FutureTask<>(run, value);
|
||||||
syncTasks.add(result);
|
queue.add(result);
|
||||||
notifySync();
|
notifySync(queue);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> Future<T> sync(Runnable run) {
|
private <T> Future<T> sync(Runnable run, Queue<FutureTask> queue) {
|
||||||
if (Fawe.isMainThread()) {
|
if (Fawe.isMainThread()) {
|
||||||
run.run();
|
run.run();
|
||||||
return Futures.immediateCancelledFuture();
|
return Futures.immediateCancelledFuture();
|
||||||
}
|
}
|
||||||
final FutureTask<T> result = new FutureTask<>(run, null);
|
final FutureTask<T> result = new FutureTask<>(run, null);
|
||||||
syncTasks.add(result);
|
queue.add(result);
|
||||||
notifySync();
|
notifySync(queue);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> Future<T> sync(Callable<T> call) throws Exception {
|
private <T> Future<T> sync(Callable<T> call, Queue<FutureTask> queue) throws Exception {
|
||||||
if (Fawe.isMainThread()) {
|
if (Fawe.isMainThread()) {
|
||||||
return Futures.immediateFuture(call.call());
|
return Futures.immediateFuture(call.call());
|
||||||
}
|
}
|
||||||
final FutureTask<T> result = new FutureTask<>(call);
|
final FutureTask<T> result = new FutureTask<>(call);
|
||||||
syncTasks.add(result);
|
queue.add(result);
|
||||||
notifySync();
|
notifySync(queue);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> Future<T> sync(Supplier<T> call) {
|
private <T> Future<T> sync(Supplier<T> call, Queue<FutureTask> queue) {
|
||||||
if (Fawe.isMainThread()) {
|
if (Fawe.isMainThread()) {
|
||||||
return Futures.immediateFuture(call.get());
|
return Futures.immediateFuture(call.get());
|
||||||
}
|
}
|
||||||
final FutureTask<T> result = new FutureTask<>(call::get);
|
final FutureTask<T> result = new FutureTask<>(call::get);
|
||||||
syncTasks.add(result);
|
queue.add(result);
|
||||||
notifySync();
|
notifySync(queue);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifySync() {
|
private void notifySync(Object object) {
|
||||||
synchronized (syncTasks) {
|
synchronized (object) {
|
||||||
syncTasks.notifyAll();
|
object.notifyAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +115,11 @@ public class BitSetBlocks implements IChunkSet {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeType getBiomeType(int x, int z) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<BlockVector3, CompoundTag> getTiles() {
|
public Map<BlockVector3, CompoundTag> getTiles() {
|
||||||
return null;
|
return null;
|
||||||
|
@ -11,7 +11,7 @@ import com.sk89q.worldedit.world.block.BlockTypes;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class CharBlocks implements IBlocks {
|
public abstract class CharBlocks implements IBlocks {
|
||||||
|
|
||||||
public static final Section FULL = new Section() {
|
public static final Section FULL = new Section() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -43,6 +43,11 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
|||||||
return biomes;
|
return biomes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeType getBiomeType(int x, int z) {
|
||||||
|
return biomes[(z << 4) | x];
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<BlockVector3, CompoundTag> getTiles() {
|
public Map<BlockVector3, CompoundTag> getTiles() {
|
||||||
return tiles == null ? Collections.emptyMap() : tiles;
|
return tiles == null ? Collections.emptyMap() : tiles;
|
||||||
|
@ -0,0 +1,110 @@
|
|||||||
|
package com.boydti.fawe.beta.preloader;
|
||||||
|
|
||||||
|
import com.boydti.fawe.Fawe;
|
||||||
|
import com.boydti.fawe.object.collection.MutablePair;
|
||||||
|
import com.boydti.fawe.util.FaweTimer;
|
||||||
|
import com.sk89q.worldedit.IncompleteRegionException;
|
||||||
|
import com.sk89q.worldedit.LocalSession;
|
||||||
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
|
import com.sk89q.worldedit.entity.Player;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
import com.sk89q.worldedit.world.World;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
|
||||||
|
public class AsyncPreloader implements Preloader, Runnable {
|
||||||
|
private final ConcurrentHashMap<UUID, MutablePair<World, Set<BlockVector2>>> update;
|
||||||
|
|
||||||
|
public AsyncPreloader() {
|
||||||
|
this.update = new ConcurrentHashMap<>();
|
||||||
|
Fawe.get().getQueueHandler().async(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel(Player player) {
|
||||||
|
cancelAndGet(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
private MutablePair<World, Set<BlockVector2>> cancelAndGet(Player player) {
|
||||||
|
MutablePair<World, Set<BlockVector2>> existing = update.get(player.getUniqueId());
|
||||||
|
if (existing != null) {
|
||||||
|
existing.setValue(null);
|
||||||
|
}
|
||||||
|
return existing;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Player player) {
|
||||||
|
LocalSession session = WorldEdit.getInstance().getSessionManager().getIfPresent(player);
|
||||||
|
if (session == null) return;
|
||||||
|
World world = player.getWorld();
|
||||||
|
MutablePair<World, Set<BlockVector2>> existing = cancelAndGet(player);
|
||||||
|
try {
|
||||||
|
Region region = session.getSelection(world);
|
||||||
|
if (!(region instanceof CuboidRegion) || region.getArea() > 50466816) {
|
||||||
|
// TOO LARGE or NOT CUBOID
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (existing == null) {
|
||||||
|
MutablePair<World, Set<BlockVector2>> previous = update.putIfAbsent(player.getUniqueId(), existing = new MutablePair<>());
|
||||||
|
if (previous != null) {
|
||||||
|
existing = previous;
|
||||||
|
}
|
||||||
|
synchronized (existing) { // Ensure key & value are mutated together
|
||||||
|
existing.setKey(world);
|
||||||
|
existing.setValue(region.getChunks());
|
||||||
|
}
|
||||||
|
synchronized (update) {
|
||||||
|
update.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IncompleteRegionException ignore){}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
FaweTimer timer = Fawe.get().getTimer();
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
if (!update.isEmpty()) {
|
||||||
|
if (timer.getTPS() > 19) {
|
||||||
|
Iterator<Map.Entry<UUID, MutablePair<World, Set<BlockVector2>>>> plrIter = update.entrySet().iterator();
|
||||||
|
Map.Entry<UUID, MutablePair<World, Set<BlockVector2>>> entry = plrIter.next();
|
||||||
|
MutablePair<World, Set<BlockVector2>> pair = entry.getValue();
|
||||||
|
World world = pair.getKey();
|
||||||
|
Set<BlockVector2> chunks = pair.getValue();
|
||||||
|
if (chunks != null) {
|
||||||
|
Iterator<BlockVector2> chunksIter = chunks.iterator();
|
||||||
|
while (chunksIter.hasNext() && pair.getValue() == chunks) { // Ensure the queued load is still valid
|
||||||
|
BlockVector2 chunk = chunksIter.next();
|
||||||
|
queueLoad(world, chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
plrIter.remove();
|
||||||
|
} else {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
synchronized (update) {
|
||||||
|
update.wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void queueLoad(World world, BlockVector2 chunk) {
|
||||||
|
world.checkLoadedChunk(BlockVector3.at(chunk.getX() << 4, 0, chunk.getZ() << 4));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.boydti.fawe.beta.preloader;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.entity.Player;
|
||||||
|
|
||||||
|
public interface Preloader {
|
||||||
|
void cancel(Player player);
|
||||||
|
|
||||||
|
void update(Player player);
|
||||||
|
}
|
@ -432,7 +432,7 @@ public class CFICommands {
|
|||||||
Clipboard clipboard = holder.getClipboard();
|
Clipboard clipboard = holder.getClipboard();
|
||||||
boolean[] ids = new boolean[BlockTypes.size()];
|
boolean[] ids = new boolean[BlockTypes.size()];
|
||||||
for (BlockVector3 pt : clipboard.getRegion()) {
|
for (BlockVector3 pt : clipboard.getRegion()) {
|
||||||
ids[clipboard.getBlock(pt).getInternalBlockTypeId()] = true;
|
ids[clipboard.getBlock(pt).getBlockType().getInternalId()] = true;
|
||||||
}
|
}
|
||||||
blocks = new HashSet<>();
|
blocks = new HashSet<>();
|
||||||
for (int combined = 0; combined < ids.length; combined++) {
|
for (int combined = 0; combined < ids.length; combined++) {
|
||||||
@ -606,7 +606,7 @@ public class CFICommands {
|
|||||||
@CommandPermissions("worldedit.anvil.cfi")
|
@CommandPermissions("worldedit.anvil.cfi")
|
||||||
public void waterId(Player fp, BlockStateHolder block) throws WorldEditException {
|
public void waterId(Player fp, BlockStateHolder block) throws WorldEditException {
|
||||||
CFISettings settings = assertSettings(fp);
|
CFISettings settings = assertSettings(fp);
|
||||||
settings.getGenerator().setWaterId(block.getBlockType().getInternalId());
|
settings.getGenerator().setWater(block.toImmutableState());
|
||||||
|
|
||||||
fp.print("Set water id!");
|
fp.print("Set water id!");
|
||||||
settings.resetComponent();
|
settings.resetComponent();
|
||||||
@ -621,7 +621,7 @@ public class CFICommands {
|
|||||||
@CommandPermissions("worldedit.anvil.cfi")
|
@CommandPermissions("worldedit.anvil.cfi")
|
||||||
public void baseId(Player fp, BlockStateHolder block) throws WorldEditException {
|
public void baseId(Player fp, BlockStateHolder block) throws WorldEditException {
|
||||||
CFISettings settings = assertSettings(fp);
|
CFISettings settings = assertSettings(fp);
|
||||||
settings.getGenerator().setBedrockId(block.getBlockType().getInternalId());
|
settings.getGenerator().setBedrock(block.toImmutableState());
|
||||||
fp.print(TextComponent.of("Set base id!"));
|
fp.print(TextComponent.of("Set base id!"));
|
||||||
settings.resetComponent();
|
settings.resetComponent();
|
||||||
component(fp);
|
component(fp);
|
||||||
|
8
worldedit-core/src/main/java/com/boydti/fawe/object/Lazy.java
Normale Datei
8
worldedit-core/src/main/java/com/boydti/fawe/object/Lazy.java
Normale Datei
@ -0,0 +1,8 @@
|
|||||||
|
package com.boydti.fawe.object;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public interface Lazy<T> extends Supplier<T> {
|
||||||
|
Supplier<T> init();
|
||||||
|
public default T get() { return init().get(); }
|
||||||
|
}
|
@ -47,7 +47,7 @@ public class VisualExtent extends AbstractDelegateExtent {
|
|||||||
@Override
|
@Override
|
||||||
public Operation commit() {
|
public Operation commit() {
|
||||||
IQueueExtent queue = (IQueueExtent) getExtent();
|
IQueueExtent queue = (IQueueExtent) getExtent();
|
||||||
queue.sendBlockUpdates(this.player);
|
System.out.println("Send block updates");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ public class VisualExtent extends AbstractDelegateExtent {
|
|||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
IQueueExtent queue = (IQueueExtent) getExtent();
|
IQueueExtent queue = (IQueueExtent) getExtent();
|
||||||
queue.clearBlockUpdates(player);
|
System.out.println("Clear");
|
||||||
queue.cancel();
|
queue.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,142 @@
|
|||||||
|
package com.boydti.fawe.object.brush.visualization.cfi;
|
||||||
|
|
||||||
|
import com.boydti.fawe.Fawe;
|
||||||
|
import com.boydti.fawe.util.MathMan;
|
||||||
|
import com.boydti.fawe.util.TextureUtil;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockID;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.awt.image.DataBufferInt;
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public final class CFIDrawer {
|
||||||
|
private final HeightMapMCAGenerator gen;
|
||||||
|
private final TextureUtil tu;
|
||||||
|
private final ForkJoinPool pool;
|
||||||
|
|
||||||
|
public CFIDrawer(HeightMapMCAGenerator generator, TextureUtil textureUtil) {
|
||||||
|
this.gen = generator;
|
||||||
|
this.tu = textureUtil;
|
||||||
|
this.pool = new ForkJoinPool();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CFIDrawer(HeightMapMCAGenerator generator) {
|
||||||
|
this(generator, Fawe.get().getCachedTextureUtil(false, 0, 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferedImage draw() {
|
||||||
|
BufferedImage img = new BufferedImage(gen.getWidth(), gen.getLength(), BufferedImage.TYPE_INT_RGB);
|
||||||
|
final char[] overlay = gen.overlay == null ? gen.floor.get() : gen.overlay.get();
|
||||||
|
final char[] floor = gen.floor.get();
|
||||||
|
final char[] main = gen.main.get();
|
||||||
|
final byte[] heights = gen.heights.get();
|
||||||
|
final byte[] biomes = gen.biomes.get();
|
||||||
|
final int waterHeight = gen.primitives.waterHeight;
|
||||||
|
final int width = gen.getWidth();
|
||||||
|
final int length = gen.getLength();
|
||||||
|
|
||||||
|
int[] raw = ((DataBufferInt) img.getRaster().getDataBuffer()).getData();
|
||||||
|
|
||||||
|
int parallelism = pool.getParallelism();
|
||||||
|
int size = (heights.length + parallelism - 1) / parallelism;
|
||||||
|
for (int i = 0; i < parallelism; i++) {
|
||||||
|
int start = i * size;
|
||||||
|
int end = Math.min(heights.length, start + size);
|
||||||
|
pool.submit((Runnable) () -> {
|
||||||
|
for (int index = start; index < end; index ++) {
|
||||||
|
int height = (heights[index] & 0xFF);
|
||||||
|
char ordinal;
|
||||||
|
if ((ordinal = overlay[index]) == 0) {
|
||||||
|
height--;
|
||||||
|
ordinal = floor[index];
|
||||||
|
if (ordinal == 0) {
|
||||||
|
height--;
|
||||||
|
ordinal = main[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// draw ordinal
|
||||||
|
int color;
|
||||||
|
switch (ordinal >> 4) {
|
||||||
|
case 2:
|
||||||
|
color = getAverageBiomeColor(biomes, width, index);
|
||||||
|
break;
|
||||||
|
case 78:
|
||||||
|
color = (0xDD << 16) + (0xDD << 8) + (0xDD << 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
color = tu.getColor(BlockTypes.getFromStateOrdinal(ordinal));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
int slope = getSlope(heights, width, index, height);
|
||||||
|
if (slope != 0) {
|
||||||
|
slope = (slope << 3) + (slope << 2);
|
||||||
|
int r = MathMan.clamp(((color >> 16) & 0xFF) + slope, 0, 255);
|
||||||
|
int g = MathMan.clamp(((color >> 8) & 0xFF) + slope, 0, 255);
|
||||||
|
int b = MathMan.clamp(((color >> 0) & 0xFF) + slope, 0, 255);
|
||||||
|
color = (r << 16) + (g << 8) + (b << 0);
|
||||||
|
}
|
||||||
|
if (height + 1 < waterHeight) {
|
||||||
|
char waterId = gen.primitives.waterOrdinal;
|
||||||
|
int waterColor = 0;
|
||||||
|
switch (waterId) {
|
||||||
|
case BlockID.WATER:
|
||||||
|
color = tu.averageColor((0x11 << 16) + (0x66 << 8) + (0xCC), color);
|
||||||
|
break;
|
||||||
|
case BlockID.LAVA:
|
||||||
|
color = (0xCC << 16) + (0x33 << 8) + (0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
color = tu.getColor(BlockTypes.getFromStateOrdinal(waterId));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
raw[index] = color;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
|
||||||
|
pool.shutdownNow();
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final int getAverageBiomeColor(byte[] biomes, int width, int index) {
|
||||||
|
int c0 = tu.getBiome(biomes[index] & 0xFF).grassCombined;
|
||||||
|
int c2 = getBiome(biomes, index + 1 + width, index);
|
||||||
|
int c1 = getBiome(biomes, index - 1 - width, index);
|
||||||
|
// int c3 = getBiome(biomes, index + width, index);
|
||||||
|
// int c4 = getBiome(biomes, index - width, index);
|
||||||
|
int r = ((c0 >> 16) & 0xFF) + ((c1 >> 16) & 0xFF) + ((c2 >> 16) & 0xFF);// + ((c3 >> 16) & 0xFF) + ((c4 >> 16) & 0xFF);
|
||||||
|
int g = ((c0 >> 8) & 0xFF) + ((c1 >> 8) & 0xFF) + ((c2 >> 8) & 0xFF);// + ((c3 >> 8) & 0xFF) + ((c4 >> 8) & 0xFF);
|
||||||
|
int b = ((c0) & 0xFF) + ((c1) & 0xFF) + ((c2) & 0xFF);// + ((c3) & 0xFF) + ((c4) & 0xFF);
|
||||||
|
r = r * 85 >> 8;
|
||||||
|
g = g * 85 >> 8;
|
||||||
|
b = b * 85 >> 8;
|
||||||
|
return (r << 16) + (g << 8) + (b);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final int getBiome(byte[] biomes, int newIndex, int index) {
|
||||||
|
if (newIndex < 0 || newIndex >= biomes.length) newIndex = index;
|
||||||
|
int biome = biomes[newIndex] & 0xFF;
|
||||||
|
return tu.getBiome(biome).grassCombined;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getSlope(byte[] heights, int width, int index, int height) {
|
||||||
|
return (
|
||||||
|
+ getHeight(heights, index + 1, height)
|
||||||
|
// + getHeight(heights, index + width, height)
|
||||||
|
+ getHeight(heights, index + width + 1, height)
|
||||||
|
- getHeight(heights, index - 1, height)
|
||||||
|
// - getHeight(heights, index - width, height)
|
||||||
|
- getHeight(heights, index - width - 1, height)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getHeight(byte[] heights, int index, int height) {
|
||||||
|
if (index < 0 || index >= heights.length) return height;
|
||||||
|
return heights[index] & 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -3,6 +3,8 @@ package com.boydti.fawe.object.brush.visualization.cfi;
|
|||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.beta.IChunkGet;
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
|
import com.boydti.fawe.beta.implementation.ChunkPacket;
|
||||||
import com.boydti.fawe.beta.implementation.FallbackChunkGet;
|
import com.boydti.fawe.beta.implementation.FallbackChunkGet;
|
||||||
import com.boydti.fawe.object.FaweInputStream;
|
import com.boydti.fawe.object.FaweInputStream;
|
||||||
import com.boydti.fawe.object.FaweOutputStream;
|
import com.boydti.fawe.object.FaweOutputStream;
|
||||||
@ -15,7 +17,6 @@ import com.boydti.fawe.object.collection.DifferentialBlockBuffer;
|
|||||||
import com.boydti.fawe.object.collection.LocalBlockVector2DSet;
|
import com.boydti.fawe.object.collection.LocalBlockVector2DSet;
|
||||||
import com.boydti.fawe.object.collection.SummedAreaTable;
|
import com.boydti.fawe.object.collection.SummedAreaTable;
|
||||||
import com.boydti.fawe.object.exception.FaweChunkLoadException;
|
import com.boydti.fawe.object.exception.FaweChunkLoadException;
|
||||||
import com.boydti.fawe.object.exception.FaweException;
|
|
||||||
import com.boydti.fawe.object.schematic.Schematic;
|
import com.boydti.fawe.object.schematic.Schematic;
|
||||||
import com.boydti.fawe.util.CachedTextureUtil;
|
import com.boydti.fawe.util.CachedTextureUtil;
|
||||||
import com.boydti.fawe.util.RandomTextureUtil;
|
import com.boydti.fawe.util.RandomTextureUtil;
|
||||||
@ -23,6 +24,7 @@ import com.boydti.fawe.util.ReflectionUtils;
|
|||||||
import com.boydti.fawe.util.TextureUtil;
|
import com.boydti.fawe.util.TextureUtil;
|
||||||
import com.boydti.fawe.util.image.Drawable;
|
import com.boydti.fawe.util.image.Drawable;
|
||||||
import com.boydti.fawe.util.image.ImageViewer;
|
import com.boydti.fawe.util.image.ImageViewer;
|
||||||
|
import com.google.common.base.Suppliers;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.LocalSession;
|
import com.sk89q.worldedit.LocalSession;
|
||||||
@ -64,6 +66,7 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
import java.util.function.Supplier;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
// TODO FIXME
|
// TODO FIXME
|
||||||
@ -73,9 +76,9 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
private final DifferentialBlockBuffer blocks;
|
private final DifferentialBlockBuffer blocks;
|
||||||
protected final DifferentialArray<byte[]> heights;
|
protected final DifferentialArray<byte[]> heights;
|
||||||
protected final DifferentialArray<byte[]> biomes;
|
protected final DifferentialArray<byte[]> biomes;
|
||||||
protected final DifferentialArray<int[]> floor;
|
protected final DifferentialArray<char[]> floor;
|
||||||
protected final DifferentialArray<int[]> main;
|
protected final DifferentialArray<char[]> main;
|
||||||
protected DifferentialArray<int[]> overlay;
|
protected DifferentialArray<char[]> overlay;
|
||||||
|
|
||||||
protected final CFIPrimitives primitives = new CFIPrimitives();
|
protected final CFIPrimitives primitives = new CFIPrimitives();
|
||||||
private CFIPrimitives oldPrimitives = new CFIPrimitives();
|
private CFIPrimitives oldPrimitives = new CFIPrimitives();
|
||||||
@ -86,8 +89,8 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
int worldThickness;
|
int worldThickness;
|
||||||
boolean randomVariation = true;
|
boolean randomVariation = true;
|
||||||
int biomePriority;
|
int biomePriority;
|
||||||
int waterId = BlockID.WATER;
|
char waterOrdinal = BlockID.WATER;
|
||||||
int bedrockId = BlockID.BEDROCK;
|
char bedrockOrdinal = BlockID.BEDROCK;
|
||||||
boolean modifiedMain;
|
boolean modifiedMain;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -225,13 +228,13 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
blocks = new DifferentialBlockBuffer(width, length);
|
blocks = new DifferentialBlockBuffer(width, length);
|
||||||
heights = new DifferentialArray<>(new byte[getArea()]);
|
heights = new DifferentialArray<>(new byte[getArea()]);
|
||||||
biomes = new DifferentialArray<>(new byte[getArea()]);
|
biomes = new DifferentialArray<>(new byte[getArea()]);
|
||||||
floor = new DifferentialArray<>(new int[getArea()]);
|
floor = new DifferentialArray<>(new char[getArea()]);
|
||||||
main = new DifferentialArray<>(new int[getArea()]);
|
main = new DifferentialArray<>(new char[getArea()]);
|
||||||
|
|
||||||
int stone = BlockID.STONE;
|
char stone = BlockID.STONE;
|
||||||
int grass = BlockTypes.GRASS_BLOCK.getDefaultState().with(PropertyKey.SNOWY, false).getInternalId();
|
char grass = BlockTypes.GRASS_BLOCK.getDefaultState().with(PropertyKey.SNOWY, false).getOrdinalChar();
|
||||||
Arrays.fill(main.getIntArray(), stone);
|
Arrays.fill(overlay.getCharArray(), stone);
|
||||||
Arrays.fill(floor.getIntArray(), grass);
|
Arrays.fill(overlay.getCharArray(), grass);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Metadatable getMetaData() {
|
public Metadatable getMetaData() {
|
||||||
@ -259,10 +262,10 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int[][][] getChunkArray(int x, int z) {
|
private char[][][] getChunkArray(int x, int z) {
|
||||||
int[][][][][] blocksData = blocks.get();
|
char[][][][][] blocksData = blocks.get();
|
||||||
if (blocksData == null) return null;
|
if (blocksData == null) return null;
|
||||||
int[][][][] arr = blocksData[z];
|
char[][][][] arr = blocksData[z];
|
||||||
return arr != null ? arr[x] : null;
|
return arr != null ? arr[x] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,8 +323,20 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendChunk(int X, int Z, int mask) {
|
public void refreshChunk(int chunkX, int chunkZ) {
|
||||||
throw new UnsupportedOperationException("TODO NOT IMPLEMENTED"); // add method to adapter to send custom chunk
|
IChunkSet chunk = getChunk(chunkX, chunkZ);
|
||||||
|
ChunkPacket packet = new ChunkPacket(chunkX, chunkZ, chunk, true, true);
|
||||||
|
player.sendFakeChunk(chunkX, chunkZ, packet::get);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IChunkSet getChunk(int chunkX, int chunkZ) {
|
||||||
|
// TODO don't generate new Writeable MCA chunk
|
||||||
|
System.out.println("TODO don't generate new Writeable MCA chunk");
|
||||||
|
WritableMCAChunk tmp = new WritableMCAChunk();
|
||||||
|
int bx = chunkX << 4;
|
||||||
|
int bz = chunkZ << 4;
|
||||||
|
write(tmp, bx, bx + 15, bz, bz + 15);
|
||||||
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextureUtil getRawTextureUtil() {
|
public TextureUtil getRawTextureUtil() {
|
||||||
@ -349,8 +364,8 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBedrockId(int bedrockId) {
|
public void setBedrock(BlockState bedrock) {
|
||||||
this.primitives.bedrockId = bedrockId;
|
this.primitives.bedrockOrdinal = bedrock.getOrdinalChar();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFloorThickness(int floorThickness) {
|
public void setFloorThickness(int floorThickness) {
|
||||||
@ -365,8 +380,8 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
this.primitives.waterHeight = waterHeight;
|
this.primitives.waterHeight = waterHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWaterId(int waterId) {
|
public void setWater(BlockState water) {
|
||||||
this.primitives.waterId = waterId;
|
this.primitives.waterOrdinal = water.getOrdinalChar();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTextureRandomVariation(boolean randomVariation) {
|
public void setTextureRandomVariation(boolean randomVariation) {
|
||||||
@ -390,10 +405,10 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void smooth(BlockVector2 min, BlockVector2 max, int radius, int iterations) {
|
public void smooth(BlockVector2 min, BlockVector2 max, int radius, int iterations) {
|
||||||
int snowLayer = BlockTypes.SNOW.getInternalId();
|
int snowLayer = BlockTypes.SNOW.getDefaultState().getOrdinalChar();
|
||||||
int snowBlock = BlockTypes.SNOW_BLOCK.getInternalId();
|
int snowBlock = BlockTypes.SNOW_BLOCK.getDefaultState().getOrdinalChar();
|
||||||
|
|
||||||
int[] floor = this.floor.get();
|
char[] floor = this.floor.get();
|
||||||
byte[] heights = this.heights.get();
|
byte[] heights = this.heights.get();
|
||||||
|
|
||||||
int width = getWidth();
|
int width = getWidth();
|
||||||
@ -421,7 +436,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
int index = zIndex + minX;
|
int index = zIndex + minX;
|
||||||
for (int x = minX; x <= maxX; x++, index++, localIndex++) {
|
for (int x = minX; x <= maxX; x++, index++, localIndex++) {
|
||||||
int combined = floor[index];
|
int combined = floor[index];
|
||||||
if (BlockTypes.getFromStateId(combined) == BlockTypes.SNOW) {
|
if (BlockTypes.getFromStateOrdinal(combined) == BlockTypes.SNOW) {
|
||||||
layers[localIndex] = (char) (((heights[index] & 0xFF) << 3) + (floor[index] >> BlockTypes.BIT_OFFSET) - 7);
|
layers[localIndex] = (char) (((heights[index] & 0xFF) << 3) + (floor[index] >> BlockTypes.BIT_OFFSET) - 7);
|
||||||
} else {
|
} else {
|
||||||
layers[localIndex] = (char) ((heights[index] & 0xFF) << 3);
|
layers[localIndex] = (char) ((heights[index] & 0xFF) << 3);
|
||||||
@ -453,16 +468,15 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
|
|
||||||
private final void setLayerHeight(int index, int blockHeight, int layerHeight) {
|
private final void setLayerHeight(int index, int blockHeight, int layerHeight) {
|
||||||
int floorState = floor.get()[index];
|
int floorState = floor.get()[index];
|
||||||
BlockType type = BlockTypes.getFromStateId(floorState);
|
switch (floorState) {
|
||||||
switch (type.getInternalId()) {
|
|
||||||
case BlockID.SNOW:
|
case BlockID.SNOW:
|
||||||
case BlockID.SNOW_BLOCK:
|
case BlockID.SNOW_BLOCK:
|
||||||
if (layerHeight != 0) {
|
if (layerHeight != 0) {
|
||||||
this.heights.setByte(index, (byte) (blockHeight + 1));
|
this.heights.setByte(index, (byte) (blockHeight + 1));
|
||||||
this.floor.setInt(index, BlockTypes.SNOW.getInternalId() + layerHeight);
|
this.floor.setInt(index, BlockTypes.SNOW.getDefaultState().getOrdinalChar() + layerHeight);
|
||||||
} else {
|
} else {
|
||||||
this.heights.setByte(index, (byte) blockHeight);
|
this.heights.setByte(index, (byte) blockHeight);
|
||||||
this.floor.setInt(index, BlockTypes.SNOW_BLOCK.getInternalId());
|
this.floor.setInt(index, BlockTypes.SNOW_BLOCK.getDefaultState().getOrdinalChar());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -479,16 +493,15 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
|
|
||||||
private final void setLayerHeightRaw(int index, int blockHeight, int layerHeight) {
|
private final void setLayerHeightRaw(int index, int blockHeight, int layerHeight) {
|
||||||
int floorState = floor.get()[index];
|
int floorState = floor.get()[index];
|
||||||
BlockType type = BlockTypes.getFromStateId(floorState);
|
switch (floorState) {
|
||||||
switch (type.getInternalId()) {
|
|
||||||
case BlockID.SNOW:
|
case BlockID.SNOW:
|
||||||
case BlockID.SNOW_BLOCK:
|
case BlockID.SNOW_BLOCK:
|
||||||
if (layerHeight != 0) {
|
if (layerHeight != 0) {
|
||||||
this.heights.getByteArray()[index] = (byte) (blockHeight + 1);
|
this.heights.getByteArray()[index] = (byte) (blockHeight + 1);
|
||||||
this.floor.getIntArray()[index] = BlockTypes.SNOW.getInternalId() + layerHeight;
|
this.overlay.getCharArray()[index] = (char) (BlockTypes.SNOW.getDefaultState().getOrdinalChar() + layerHeight);
|
||||||
} else {
|
} else {
|
||||||
this.heights.getByteArray()[index] = (byte) blockHeight;
|
this.heights.getByteArray()[index] = (byte) blockHeight;
|
||||||
this.floor.getIntArray()[index] = BlockTypes.SNOW_BLOCK.getInternalId();
|
this.overlay.getCharArray()[index] = BlockTypes.SNOW_BLOCK.getDefaultState().getOrdinalChar();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -498,7 +511,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void smooth(BufferedImage img, Mask mask, boolean white, int radius, int iterations) {
|
private void smooth(BufferedImage img, Mask mask, boolean white, int radius, int iterations) {
|
||||||
int[] floor = this.floor.get();
|
char[] floor = this.floor.get();
|
||||||
byte[] heights = this.heights.get();
|
byte[] heights = this.heights.get();
|
||||||
|
|
||||||
long[] copy = new long[heights.length];
|
long[] copy = new long[heights.length];
|
||||||
@ -511,7 +524,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
for (int j = 0; j < iterations; j++) {
|
for (int j = 0; j < iterations; j++) {
|
||||||
for (int i = 0; i < heights.length; i++) {
|
for (int i = 0; i < heights.length; i++) {
|
||||||
int combined = floor[i];
|
int combined = floor[i];
|
||||||
if (BlockTypes.getFromStateId(combined) == BlockTypes.SNOW) {
|
if (BlockTypes.getFromStateOrdinal(combined) == BlockTypes.SNOW) {
|
||||||
layers[i] = (char) (((heights[i] & 0xFF) << 3) + (floor[i] >> BlockTypes.BIT_OFFSET) - 7);
|
layers[i] = (char) (((heights[i] & 0xFF) << 3) + (floor[i] >> BlockTypes.BIT_OFFSET) - 7);
|
||||||
} else {
|
} else {
|
||||||
layers[i] = (char) ((heights[i] & 0xFF) << 3);
|
layers[i] = (char) ((heights[i] & 0xFF) << 3);
|
||||||
@ -704,7 +717,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
return setBlock(position.getBlockX(), position.getBlockY(), position.getBlockZ(), block);
|
return setBlock(position.getBlockX(), position.getBlockY(), position.getBlockZ(), block);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean setBlock(int x, int y, int z, int combined) {
|
private boolean setBlock(int x, int y, int z, char combined) {
|
||||||
int index = z * getWidth() + x;
|
int index = z * getWidth() + x;
|
||||||
if (index < 0 || index >= getArea()) return false;
|
if (index < 0 || index >= getArea()) return false;
|
||||||
int height = heights.getByte(index) & 0xFF;
|
int height = heights.getByte(index) & 0xFF;
|
||||||
@ -713,8 +726,8 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
floor.setInt(index, combined);
|
floor.setInt(index, combined);
|
||||||
return true;
|
return true;
|
||||||
case 1:
|
case 1:
|
||||||
int mainId = main.getInt(index);
|
char mainId = overlay.getChar(index);
|
||||||
int floorId = floor.getInt(index);
|
char floorId = overlay.getChar(index);
|
||||||
floor.setInt(index, combined);
|
floor.setInt(index, combined);
|
||||||
|
|
||||||
byte currentHeight = heights.getByte(index);
|
byte currentHeight = heights.getByte(index);
|
||||||
@ -870,7 +883,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
|
|
||||||
for (int cz = scz; cz <= ecz; cz++) {
|
for (int cz = scz; cz <= ecz; cz++) {
|
||||||
for (int cx = scx; cx <= ecx; cx++) {
|
for (int cx = scx; cx <= ecx; cx++) {
|
||||||
world.sendChunk(cx + OX, cz + OZ, 0);
|
world.refreshChunk(cx + OX, cz + OZ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -890,20 +903,19 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
return BiomeTypes.get(biomes.getByte(index));
|
return BiomeTypes.get(biomes.getByte(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Override
|
public int getOrdinal(int x, int y, int z) throws FaweChunkLoadException {
|
||||||
public int getCombinedId4Data(int x, int y, int z) throws FaweChunkLoadException {
|
|
||||||
int index = z * getWidth() + x;
|
int index = z * getWidth() + x;
|
||||||
if (y < 0) return 0;
|
if (y < 0) return 0;
|
||||||
if (index < 0 || index >= getArea() || x < 0 || x >= getWidth()) return 0;
|
if (index < 0 || index >= getArea() || x < 0 || x >= getWidth()) return 0;
|
||||||
int height = heights.getByte(index) & 0xFF;
|
int height = heights.getByte(index) & 0xFF;
|
||||||
if (y > height) {
|
if (y > height) {
|
||||||
if (y == height + 1) {
|
if (y == height + 1) {
|
||||||
return overlay != null ? overlay.getInt(index) : 0;
|
return overlay != null ? overlay.getChar(index) : 0;
|
||||||
}
|
}
|
||||||
if (blocks != null) {
|
if (blocks != null) {
|
||||||
short chunkX = (short) (x >> 4);
|
short chunkX = (short) (x >> 4);
|
||||||
short chunkZ = (short) (z >> 4);
|
short chunkZ = (short) (z >> 4);
|
||||||
int[][][] map = getChunkArray(chunkX, chunkZ);
|
char[][][] map = getChunkArray(chunkX, chunkZ);
|
||||||
if (map != null) {
|
if (map != null) {
|
||||||
int combined = get(map, x, y, z);
|
int combined = get(map, x, y, z);
|
||||||
if (combined != 0) {
|
if (combined != 0) {
|
||||||
@ -912,16 +924,16 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (y <= primitives.waterHeight) {
|
if (y <= primitives.waterHeight) {
|
||||||
return primitives.waterId << 4;
|
return primitives.waterOrdinal;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
} else if (y == height) {
|
} else if (y == height) {
|
||||||
return floor.getInt(index);
|
return overlay.getChar(index);
|
||||||
} else {
|
} else {
|
||||||
if (blocks != null) {
|
if (blocks != null) {
|
||||||
short chunkX = (short) (x >> 4);
|
short chunkX = (short) (x >> 4);
|
||||||
short chunkZ = (short) (z >> 4);
|
short chunkZ = (short) (z >> 4);
|
||||||
int[][][] map = getChunkArray(chunkX, chunkZ);
|
char[][][] map = getChunkArray(chunkX, chunkZ);
|
||||||
if (map != null) {
|
if (map != null) {
|
||||||
int combined = get(map, x, y, z);
|
int combined = get(map, x, y, z);
|
||||||
if (combined != 0) {
|
if (combined != 0) {
|
||||||
@ -929,13 +941,13 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return main.getInt(index);
|
return overlay.getChar(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBlock(int x, int y, int z, BlockStateHolder block) throws WorldEditException {
|
public boolean setBlock(int x, int y, int z, BlockStateHolder block) throws WorldEditException {
|
||||||
return this.setBlock(x, y, z, block.getInternalId());
|
return this.setBlock(x, y, z, block.getOrdinalChar());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -950,7 +962,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
|
|
||||||
public BlockState getFloor(int x, int z) {
|
public BlockState getFloor(int x, int z) {
|
||||||
int index = z * getWidth() + x;
|
int index = z * getWidth() + x;
|
||||||
return BlockState.getFromInternalId(floor.getInt(index));
|
return BlockState.getFromOrdinal(overlay.getChar(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getHeight(int x, int z) {
|
public int getHeight(int x, int z) {
|
||||||
@ -964,19 +976,19 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
|
|
||||||
public void setFloor(int x, int z, BlockStateHolder block) {
|
public void setFloor(int x, int z, BlockStateHolder block) {
|
||||||
int index = z * getWidth() + x;
|
int index = z * getWidth() + x;
|
||||||
floor.setInt(index, block.getInternalId());
|
floor.setInt(index, block.getOrdinalChar());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getBlock(int x, int y, int z) {
|
public BlockState getBlock(int x, int y, int z) {
|
||||||
return BlockState.getFromInternalId(getCombinedId4Data(x, y, z));
|
return BlockState.getFromOrdinal(getOrdinal(x, y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNearestSurfaceLayer(int x, int z, int y, int minY, int maxY) {
|
public int getNearestSurfaceLayer(int x, int z, int y, int minY, int maxY) {
|
||||||
int index = z * getWidth() + x;
|
int index = z * getWidth() + x;
|
||||||
if (index < 0 || index >= getArea()) index = Math.floorMod(index, getArea());
|
if (index < 0 || index >= getArea()) index = Math.floorMod(index, getArea());
|
||||||
return ((heights.getByte(index) & 0xFF) << 3) + (floor.getInt(index) & 0xFF) + 1;
|
return ((heights.getByte(index) & 0xFF) << 3) + (overlay.getChar(index) & 0xFF) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1017,9 +1029,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BufferedImage draw() {
|
public BufferedImage draw() {
|
||||||
// TODO NOT IMPLEMENTED
|
return new CFIDrawer(this).draw();
|
||||||
// return new HeightMapMCADrawer(this).draw();
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBiomePriority(int value) {
|
public void setBiomePriority(int value) {
|
||||||
@ -1044,12 +1054,12 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
int maxIndex = getArea() - 1;
|
int maxIndex = getArea() - 1;
|
||||||
|
|
||||||
biomes.record(() -> floor.record(() -> main.record(() -> {
|
biomes.record(() -> floor.record(() -> main.record(() -> {
|
||||||
int[] mainArr = main.get();
|
char[] mainArr = main.get();
|
||||||
int[] floorArr = floor.get();
|
char[] floorArr = floor.get();
|
||||||
byte[] biomesArr = biomes.get();
|
byte[] biomesArr = biomes.get();
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
int[] buffer = new int[2];
|
char[] buffer = new char[2];
|
||||||
for (int z = 0; z < img.getHeight(); z++) {
|
for (int z = 0; z < img.getHeight(); z++) {
|
||||||
mutable.mutZ(z);
|
mutable.mutZ(z);
|
||||||
for (int x = 0; x < img.getWidth(); x++, index++) {
|
for (int x = 0; x < img.getWidth(); x++, index++) {
|
||||||
@ -1065,7 +1075,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
}
|
}
|
||||||
int color = img.getRGB(x, z);
|
int color = img.getRGB(x, z);
|
||||||
if (textureUtil.getIsBlockCloserThanBiome(buffer, color, primitives.biomePriority)) {
|
if (textureUtil.getIsBlockCloserThanBiome(buffer, color, primitives.biomePriority)) {
|
||||||
int combined = buffer[0];
|
char combined = buffer[0];
|
||||||
mainArr[index] = combined;
|
mainArr[index] = combined;
|
||||||
floorArr[index] = combined;
|
floorArr[index] = combined;
|
||||||
}
|
}
|
||||||
@ -1079,23 +1089,20 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||||
TextureUtil textureUtil = getTextureUtil();
|
TextureUtil textureUtil = getTextureUtil();
|
||||||
int widthIndex = img.getWidth() - 1;
|
|
||||||
int heightIndex = img.getHeight() - 1;
|
int heightIndex = img.getHeight() - 1;
|
||||||
int maxIndex = getArea() - 1;
|
|
||||||
|
|
||||||
biomes.record(() -> floor.record(() -> main.record(() -> {
|
biomes.record(() -> floor.record(() -> main.record(() -> {
|
||||||
int[] mainArr = main.get();
|
char[] mainArr = main.get();
|
||||||
int[] floorArr = floor.get();
|
char[] floorArr = floor.get();
|
||||||
byte[] biomesArr = biomes.get();
|
byte[] biomesArr = biomes.get();
|
||||||
|
|
||||||
int[] buffer = new int[2];
|
char[] buffer = new char[2];
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int y = 0; y < img.getHeight(); y++) {
|
for (int y = 0; y < img.getHeight(); y++) {
|
||||||
boolean yBiome = y > 0 && y < heightIndex;
|
|
||||||
for (int x = 0; x < img.getWidth(); x++, index++) {
|
for (int x = 0; x < img.getWidth(); x++, index++) {
|
||||||
int color = img.getRGB(x, y);
|
int color = img.getRGB(x, y);
|
||||||
if (textureUtil.getIsBlockCloserThanBiome(buffer, color, primitives.biomePriority)) {
|
if (textureUtil.getIsBlockCloserThanBiome(buffer, color, primitives.biomePriority)) {
|
||||||
int combined = buffer[0];
|
char combined = buffer[0];
|
||||||
mainArr[index] = combined;
|
mainArr[index] = combined;
|
||||||
floorArr[index] = combined;
|
floorArr[index] = combined;
|
||||||
}
|
}
|
||||||
@ -1135,8 +1142,8 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
TextureUtil textureUtil = getTextureUtil();
|
TextureUtil textureUtil = getTextureUtil();
|
||||||
|
|
||||||
floor.record(() -> main.record(() -> {
|
floor.record(() -> main.record(() -> {
|
||||||
int[] mainArr = main.get();
|
char[] mainArr = main.get();
|
||||||
int[] floorArr = floor.get();
|
char[] floorArr = floor.get();
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int z = 0; z < getLength(); z++) {
|
for (int z = 0; z < getLength(); z++) {
|
||||||
@ -1147,7 +1154,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
int color = img.getRGB(x, z);
|
int color = img.getRGB(x, z);
|
||||||
BlockType block = textureUtil.getNearestBlock(color);
|
BlockType block = textureUtil.getNearestBlock(color);
|
||||||
if (block != null) {
|
if (block != null) {
|
||||||
int combined = block.getInternalId();
|
char combined = block.getDefaultState().getOrdinalChar();
|
||||||
mainArr[index] = combined;
|
mainArr[index] = combined;
|
||||||
floorArr[index] = combined;
|
floorArr[index] = combined;
|
||||||
}
|
}
|
||||||
@ -1165,8 +1172,8 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
|
|
||||||
|
|
||||||
floor.record(() -> main.record(() -> {
|
floor.record(() -> main.record(() -> {
|
||||||
int[] mainArr = main.get();
|
char[] mainArr = main.get();
|
||||||
int[] floorArr = floor.get();
|
char[] floorArr = floor.get();
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int z = 0; z < getLength(); z++) {
|
for (int z = 0; z < getLength(); z++) {
|
||||||
@ -1178,7 +1185,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
int color = img.getRGB(x, z);
|
int color = img.getRGB(x, z);
|
||||||
BlockType block = textureUtil.getNearestBlock(color);
|
BlockType block = textureUtil.getNearestBlock(color);
|
||||||
if (block != null) {
|
if (block != null) {
|
||||||
int combined = block.getInternalId();
|
char combined = block.getDefaultState().getOrdinalChar();
|
||||||
mainArr[index] = combined;
|
mainArr[index] = combined;
|
||||||
floorArr[index] = combined;
|
floorArr[index] = combined;
|
||||||
} else {
|
} else {
|
||||||
@ -1197,8 +1204,8 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
TextureUtil textureUtil = getTextureUtil();
|
TextureUtil textureUtil = getTextureUtil();
|
||||||
|
|
||||||
floor.record(() -> main.record(() -> {
|
floor.record(() -> main.record(() -> {
|
||||||
int[] mainArr = main.get();
|
char[] mainArr = main.get();
|
||||||
int[] floorArr = floor.get();
|
char[] floorArr = floor.get();
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int z = 0; z < img.getHeight(); z++) {
|
for (int z = 0; z < img.getHeight(); z++) {
|
||||||
@ -1206,7 +1213,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
int color = img.getRGB(x, z);
|
int color = img.getRGB(x, z);
|
||||||
BlockType block = textureUtil.getNearestBlock(color);
|
BlockType block = textureUtil.getNearestBlock(color);
|
||||||
if (block != null) {
|
if (block != null) {
|
||||||
int combined = block.getInternalId();
|
char combined = block.getDefaultState().getOrdinalChar();
|
||||||
mainArr[index] = combined;
|
mainArr[index] = combined;
|
||||||
floorArr[index] = combined;
|
floorArr[index] = combined;
|
||||||
} else {
|
} else {
|
||||||
@ -1224,8 +1231,8 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
TextureUtil textureUtil = getTextureUtil();
|
TextureUtil textureUtil = getTextureUtil();
|
||||||
|
|
||||||
floor.record(() -> main.record(() -> {
|
floor.record(() -> main.record(() -> {
|
||||||
int[] mainArr = main.get();
|
char[] mainArr = main.get();
|
||||||
int[] floorArr = floor.get();
|
char[] floorArr = floor.get();
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int y = 0; y < img.getHeight(); y++) {
|
for (int y = 0; y < img.getHeight(); y++) {
|
||||||
@ -1233,8 +1240,8 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
int color = img.getRGB(x, y);
|
int color = img.getRGB(x, y);
|
||||||
BlockType[] layer = textureUtil.getNearestLayer(color);
|
BlockType[] layer = textureUtil.getNearestLayer(color);
|
||||||
if (layer != null) {
|
if (layer != null) {
|
||||||
floorArr[index] = layer[0].getInternalId();
|
floorArr[index] = layer[0].getDefaultState().getOrdinalChar();
|
||||||
mainArr[index] = layer[1].getInternalId();
|
mainArr[index] = layer[1].getDefaultState().getOrdinalChar();
|
||||||
}
|
}
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
@ -1260,18 +1267,18 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
|
|
||||||
public void setOverlay(BufferedImage img, Pattern pattern, boolean white) {
|
public void setOverlay(BufferedImage img, Pattern pattern, boolean white) {
|
||||||
if (pattern instanceof BlockStateHolder) {
|
if (pattern instanceof BlockStateHolder) {
|
||||||
setOverlay(img, ((BlockStateHolder) pattern).getInternalId(), white);
|
setOverlay(img, ((BlockStateHolder) pattern).getOrdinalChar(), white);
|
||||||
} else if (pattern instanceof BlockType) {
|
} else if (pattern instanceof BlockType) {
|
||||||
setOverlay(img, ((BlockType) pattern).getInternalId(), white);
|
setOverlay(img, ((BlockType) pattern).getDefaultState().getOrdinalChar(), white);
|
||||||
} else {
|
} else {
|
||||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||||
if (overlay == null) {
|
if (overlay == null) {
|
||||||
overlay = new DifferentialArray<>(new int[getArea()]);
|
overlay = new DifferentialArray<>(new char[getArea()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
overlay.record(() -> {
|
overlay.record(() -> {
|
||||||
int[] overlayArr = overlay.get();
|
char[] overlayArr = overlay.get();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int z = 0; z < getLength(); z++) {
|
for (int z = 0; z < getLength(); z++) {
|
||||||
mutable.mutZ(z);
|
mutable.mutZ(z);
|
||||||
@ -1281,7 +1288,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
.nextInt(256) <= height) {
|
.nextInt(256) <= height) {
|
||||||
mutable.mutX(x);
|
mutable.mutX(x);
|
||||||
mutable.mutY(height);
|
mutable.mutY(height);
|
||||||
overlayArr[index] = pattern.apply(mutable).getInternalId();
|
overlayArr[index] = pattern.apply(mutable).getOrdinalChar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1292,14 +1299,14 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
|
|
||||||
public void setMain(BufferedImage img, Pattern pattern, boolean white) {
|
public void setMain(BufferedImage img, Pattern pattern, boolean white) {
|
||||||
if (pattern instanceof BlockStateHolder) {
|
if (pattern instanceof BlockStateHolder) {
|
||||||
setMain(img, ((BlockStateHolder) pattern).getInternalId(), white);
|
setMain(img, ((BlockStateHolder) pattern).getOrdinalChar(), white);
|
||||||
} else {
|
} else {
|
||||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||||
primitives.modifiedMain = true;
|
primitives.modifiedMain = true;
|
||||||
|
|
||||||
main.record(() -> {
|
main.record(() -> {
|
||||||
int[] mainArr = main.get();
|
char[] mainArr = main.get();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int z = 0; z < getLength(); z++) {
|
for (int z = 0; z < getLength(); z++) {
|
||||||
mutable.mutZ(z);
|
mutable.mutZ(z);
|
||||||
@ -1309,7 +1316,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
.nextInt(256) <= height) {
|
.nextInt(256) <= height) {
|
||||||
mutable.mutX(x);
|
mutable.mutX(x);
|
||||||
mutable.mutY(height);
|
mutable.mutY(height);
|
||||||
mainArr[index] = pattern.apply(mutable).getInternalId();
|
mainArr[index] = pattern.apply(mutable).getOrdinalChar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1319,13 +1326,13 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
|
|
||||||
public void setFloor(BufferedImage img, Pattern pattern, boolean white) {
|
public void setFloor(BufferedImage img, Pattern pattern, boolean white) {
|
||||||
if (pattern instanceof BlockStateHolder) {
|
if (pattern instanceof BlockStateHolder) {
|
||||||
setFloor(img, ((BlockStateHolder) pattern).getInternalId(), white);
|
setFloor(img, ((BlockStateHolder) pattern).getOrdinalChar(), white);
|
||||||
} else {
|
} else {
|
||||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||||
|
|
||||||
floor.record(() -> {
|
floor.record(() -> {
|
||||||
int[] floorArr = floor.get();
|
char[] floorArr = floor.get();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int z = 0; z < getLength(); z++) {
|
for (int z = 0; z < getLength(); z++) {
|
||||||
mutable.mutZ(z);
|
mutable.mutZ(z);
|
||||||
@ -1335,7 +1342,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
.nextInt(256) <= height) {
|
.nextInt(256) <= height) {
|
||||||
mutable.mutX(x);
|
mutable.mutX(x);
|
||||||
mutable.mutY(height);
|
mutable.mutY(height);
|
||||||
floorArr[index] = pattern.apply(mutable).getInternalId();
|
floorArr[index] = pattern.apply(mutable).getOrdinalChar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1345,15 +1352,15 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
|
|
||||||
public void setColumn(BufferedImage img, Pattern pattern, boolean white) {
|
public void setColumn(BufferedImage img, Pattern pattern, boolean white) {
|
||||||
if (pattern instanceof BlockStateHolder) {
|
if (pattern instanceof BlockStateHolder) {
|
||||||
setColumn(img, ((BlockStateHolder) pattern).getInternalId(), white);
|
setColumn(img, ((BlockStateHolder) pattern).getOrdinalChar(), white);
|
||||||
} else {
|
} else {
|
||||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||||
primitives.modifiedMain = true;
|
primitives.modifiedMain = true;
|
||||||
|
|
||||||
main.record(() -> floor.record(() -> {
|
main.record(() -> floor.record(() -> {
|
||||||
int[] floorArr = floor.get();
|
char[] floorArr = floor.get();
|
||||||
int[] mainArr = main.get();
|
char[] mainArr = main.get();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int z = 0; z < getLength(); z++) {
|
for (int z = 0; z < getLength(); z++) {
|
||||||
mutable.mutZ(z);
|
mutable.mutZ(z);
|
||||||
@ -1363,7 +1370,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
.nextInt(256) <= height) {
|
.nextInt(256) <= height) {
|
||||||
mutable.mutX(x);
|
mutable.mutX(x);
|
||||||
mutable.mutY(height);
|
mutable.mutY(height);
|
||||||
int combined = pattern.apply(mutable).getInternalId();
|
char combined = pattern.apply(mutable).getOrdinalChar();
|
||||||
mainArr[index] = combined;
|
mainArr[index] = combined;
|
||||||
floorArr[index] = combined;
|
floorArr[index] = combined;
|
||||||
}
|
}
|
||||||
@ -1375,10 +1382,10 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
|
|
||||||
public void setOverlay(Mask mask, Pattern pattern) {
|
public void setOverlay(Mask mask, Pattern pattern) {
|
||||||
if (pattern instanceof BlockStateHolder) {
|
if (pattern instanceof BlockStateHolder) {
|
||||||
setOverlay(mask, ((BlockStateHolder) pattern).getInternalId());
|
setOverlay(mask, ((BlockStateHolder) pattern).getOrdinalChar());
|
||||||
} else {
|
} else {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if (overlay == null) overlay = new DifferentialArray<>(new int[getArea()]);
|
if (overlay == null) overlay = new DifferentialArray<>(new char[getArea()]);
|
||||||
for (int z = 0; z < getLength(); z++) {
|
for (int z = 0; z < getLength(); z++) {
|
||||||
mutable.mutZ(z);
|
mutable.mutZ(z);
|
||||||
for (int x = 0; x < getWidth(); x++, index++) {
|
for (int x = 0; x < getWidth(); x++, index++) {
|
||||||
@ -1386,7 +1393,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
mutable.mutX(x);
|
mutable.mutX(x);
|
||||||
mutable.mutY(y);
|
mutable.mutY(y);
|
||||||
if (mask.test(mutable)) {
|
if (mask.test(mutable)) {
|
||||||
overlay.setInt(index, pattern.apply(mutable).getInternalId());
|
overlay.setInt(index, pattern.apply(mutable).getOrdinalChar());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1395,7 +1402,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
|
|
||||||
public void setFloor(Mask mask, Pattern pattern) {
|
public void setFloor(Mask mask, Pattern pattern) {
|
||||||
if (pattern instanceof BlockStateHolder) {
|
if (pattern instanceof BlockStateHolder) {
|
||||||
setFloor(mask, ((BlockStateHolder) pattern).getInternalId());
|
setFloor(mask, ((BlockStateHolder) pattern).getOrdinalChar());
|
||||||
} else {
|
} else {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int z = 0; z < getLength(); z++) {
|
for (int z = 0; z < getLength(); z++) {
|
||||||
@ -1405,7 +1412,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
mutable.mutX(x);
|
mutable.mutX(x);
|
||||||
mutable.mutY(y);
|
mutable.mutY(y);
|
||||||
if (mask.test(mutable)) {
|
if (mask.test(mutable)) {
|
||||||
floor.setInt(index, pattern.apply(mutable).getInternalId());
|
floor.setInt(index, pattern.apply(mutable).getOrdinalChar());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1414,7 +1421,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
|
|
||||||
public void setMain(Mask mask, Pattern pattern) {
|
public void setMain(Mask mask, Pattern pattern) {
|
||||||
if (pattern instanceof BlockStateHolder) {
|
if (pattern instanceof BlockStateHolder) {
|
||||||
setMain(mask, ((BlockStateHolder) pattern).getInternalId());
|
setMain(mask, ((BlockStateHolder) pattern).getOrdinalChar());
|
||||||
} else {
|
} else {
|
||||||
primitives.modifiedMain = true;
|
primitives.modifiedMain = true;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
@ -1425,7 +1432,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
mutable.mutX(x);
|
mutable.mutX(x);
|
||||||
mutable.mutY(y);
|
mutable.mutY(y);
|
||||||
if (mask.test(mutable)) {
|
if (mask.test(mutable)) {
|
||||||
main.setInt(index, pattern.apply(mutable).getInternalId());
|
main.setInt(index, pattern.apply(mutable).getOrdinalChar());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1434,7 +1441,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
|
|
||||||
public void setColumn(Mask mask, Pattern pattern) {
|
public void setColumn(Mask mask, Pattern pattern) {
|
||||||
if (pattern instanceof BlockStateHolder) {
|
if (pattern instanceof BlockStateHolder) {
|
||||||
setColumn(mask, ((BlockStateHolder) pattern).getInternalId());
|
setColumn(mask, ((BlockStateHolder) pattern).getOrdinalChar());
|
||||||
} else {
|
} else {
|
||||||
primitives.modifiedMain = true;
|
primitives.modifiedMain = true;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
@ -1445,7 +1452,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
mutable.mutX(x);
|
mutable.mutX(x);
|
||||||
mutable.mutY(y);
|
mutable.mutY(y);
|
||||||
if (mask.test(mutable)) {
|
if (mask.test(mutable)) {
|
||||||
int combined = pattern.apply(mutable).getInternalId();
|
int combined = pattern.apply(mutable).getOrdinalChar();
|
||||||
floor.setInt(index, combined);
|
floor.setInt(index, combined);
|
||||||
main.setInt(index, combined);
|
main.setInt(index, combined);
|
||||||
}
|
}
|
||||||
@ -1460,10 +1467,10 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
|
|
||||||
public void setFloor(Pattern value) {
|
public void setFloor(Pattern value) {
|
||||||
if (value instanceof BlockStateHolder) {
|
if (value instanceof BlockStateHolder) {
|
||||||
setFloor(((BlockStateHolder) value).getInternalId());
|
setFloor(((BlockStateHolder) value).getOrdinalChar());
|
||||||
} else {
|
} else {
|
||||||
floor.record(() -> {
|
floor.record(() -> {
|
||||||
int[] floorArr = floor.get();
|
char[] floorArr = floor.get();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int z = 0; z < getLength(); z++) {
|
for (int z = 0; z < getLength(); z++) {
|
||||||
mutable.mutZ(z);
|
mutable.mutZ(z);
|
||||||
@ -1471,7 +1478,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
int y = heights.getByte(index) & 0xFF;
|
int y = heights.getByte(index) & 0xFF;
|
||||||
mutable.mutX(x);
|
mutable.mutX(x);
|
||||||
mutable.mutY(y);
|
mutable.mutY(y);
|
||||||
floorArr[index] = value.apply(mutable).getInternalId();
|
floorArr[index] = value.apply(mutable).getOrdinalChar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1480,11 +1487,11 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
|
|
||||||
public void setColumn(Pattern value) {
|
public void setColumn(Pattern value) {
|
||||||
if (value instanceof BlockStateHolder) {
|
if (value instanceof BlockStateHolder) {
|
||||||
setColumn(((BlockStateHolder) value).getInternalId());
|
setColumn(((BlockStateHolder) value).getOrdinalChar());
|
||||||
} else {
|
} else {
|
||||||
main.record(() -> floor.record(() -> {
|
main.record(() -> floor.record(() -> {
|
||||||
int[] floorArr = floor.get();
|
char[] floorArr = floor.get();
|
||||||
int[] mainArr = main.get();
|
char[] mainArr = main.get();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int z = 0; z < getLength(); z++) {
|
for (int z = 0; z < getLength(); z++) {
|
||||||
mutable.mutZ(z);
|
mutable.mutZ(z);
|
||||||
@ -1492,7 +1499,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
int y = heights.getByte(index) & 0xFF;
|
int y = heights.getByte(index) & 0xFF;
|
||||||
mutable.mutX(x);
|
mutable.mutX(x);
|
||||||
mutable.mutY(y);
|
mutable.mutY(y);
|
||||||
int combined = value.apply(mutable).getInternalId();
|
char combined = value.apply(mutable).getOrdinalChar();
|
||||||
mainArr[index] = combined;
|
mainArr[index] = combined;
|
||||||
floorArr[index] = combined;
|
floorArr[index] = combined;
|
||||||
}
|
}
|
||||||
@ -1503,10 +1510,10 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
|
|
||||||
public void setMain(Pattern value) {
|
public void setMain(Pattern value) {
|
||||||
if (value instanceof BlockStateHolder) {
|
if (value instanceof BlockStateHolder) {
|
||||||
setMain(((BlockStateHolder) value).getInternalId());
|
setMain(((BlockStateHolder) value).getOrdinalChar());
|
||||||
} else {
|
} else {
|
||||||
main.record(() -> {
|
main.record(() -> {
|
||||||
int[] mainArr = main.get();
|
char[] mainArr = main.get();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int z = 0; z < getLength(); z++) {
|
for (int z = 0; z < getLength(); z++) {
|
||||||
mutable.mutZ(z);
|
mutable.mutZ(z);
|
||||||
@ -1514,7 +1521,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
int y = heights.getByte(index) & 0xFF;
|
int y = heights.getByte(index) & 0xFF;
|
||||||
mutable.mutX(x);
|
mutable.mutX(x);
|
||||||
mutable.mutY(y);
|
mutable.mutY(y);
|
||||||
mainArr[index] = value.apply(mutable).getInternalId();
|
mainArr[index] = value.apply(mutable).getOrdinalChar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1522,12 +1529,12 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setOverlay(Pattern value) {
|
public void setOverlay(Pattern value) {
|
||||||
if (overlay == null) overlay = new DifferentialArray<>(new int[getArea()]);
|
if (overlay == null) overlay = new DifferentialArray<>(new char[getArea()]);
|
||||||
if (value instanceof BlockStateHolder) {
|
if (value instanceof BlockStateHolder) {
|
||||||
setOverlay(((BlockStateHolder) value).getInternalId());
|
setOverlay(((BlockStateHolder) value).getOrdinalChar());
|
||||||
} else {
|
} else {
|
||||||
overlay.record(() -> {
|
overlay.record(() -> {
|
||||||
int[] overlayArr = overlay.get();
|
char[] overlayArr = overlay.get();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int z = 0; z < getLength(); z++) {
|
for (int z = 0; z < getLength(); z++) {
|
||||||
mutable.mutZ(z);
|
mutable.mutZ(z);
|
||||||
@ -1535,7 +1542,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
int y = heights.getByte(index) & 0xFF;
|
int y = heights.getByte(index) & 0xFF;
|
||||||
mutable.mutX(x);
|
mutable.mutX(x);
|
||||||
mutable.mutY(y);
|
mutable.mutY(y);
|
||||||
overlayArr[index] = value.apply(mutable).getInternalId();
|
overlayArr[index] = value.apply(mutable).getOrdinalChar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1567,16 +1574,16 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
public WritableMCAChunk write(WritableMCAChunk chunk, int csx, int cex, int csz, int cez) {
|
public WritableMCAChunk write(WritableMCAChunk chunk, int csx, int cex, int csz, int cez) {
|
||||||
byte[] heights = this.heights.get();
|
byte[] heights = this.heights.get();
|
||||||
byte[] biomes = this.biomes.get();
|
byte[] biomes = this.biomes.get();
|
||||||
int[] main = this.main.get();
|
char[] main = this.main.get();
|
||||||
int[] floor = this.floor.get();
|
char[] floor = this.floor.get();
|
||||||
int[] overlay = this.overlay != null ? this.overlay.get() : null;
|
char[] overlay = this.overlay != null ? this.overlay.get() : null;
|
||||||
try {
|
try {
|
||||||
int[] indexes = FaweCache.IMP.INDEX_STORE.get();
|
int[] indexes = FaweCache.IMP.INDEX_STORE.get();
|
||||||
|
|
||||||
int index;
|
int index;
|
||||||
int maxY = 0;
|
int maxY = 0;
|
||||||
int minY = Integer.MAX_VALUE;
|
int minY = Integer.MAX_VALUE;
|
||||||
int[] heightMap = chunk.biomes;
|
byte[] heightMap = chunk.biomes;
|
||||||
int globalIndex;
|
int globalIndex;
|
||||||
for (int z = csz; z <= cez; z++) {
|
for (int z = csz; z <= cez; z++) {
|
||||||
globalIndex = z * getWidth() + csx;
|
globalIndex = z * getWidth() + csx;
|
||||||
@ -1584,7 +1591,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
for (int x = csx; x <= cex; x++, index++, globalIndex++) {
|
for (int x = csx; x <= cex; x++, index++, globalIndex++) {
|
||||||
indexes[index] = globalIndex;
|
indexes[index] = globalIndex;
|
||||||
int height = heights[globalIndex] & 0xFF;
|
int height = heights[globalIndex] & 0xFF;
|
||||||
heightMap[index] = height;
|
heightMap[index] = (byte) height;
|
||||||
maxY = Math.max(maxY, height);
|
maxY = Math.max(maxY, height);
|
||||||
minY = Math.min(minY, height);
|
minY = Math.min(minY, height);
|
||||||
}
|
}
|
||||||
@ -1599,7 +1606,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
}
|
}
|
||||||
if (primitives.waterHeight != 0) {
|
if (primitives.waterHeight != 0) {
|
||||||
int maxIndex = primitives.waterHeight << 8;
|
int maxIndex = primitives.waterHeight << 8;
|
||||||
Arrays.fill(chunk.blocks, 0, maxIndex, primitives.waterId);
|
Arrays.fill(chunk.blocks, 0, maxIndex, primitives.waterOrdinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (primitives.modifiedMain) { // If the main block is modified, we can't short circuit this
|
if (primitives.modifiedMain) { // If the main block is modified, we can't short circuit this
|
||||||
@ -1607,7 +1614,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
index = (z & 15) << 4;
|
index = (z & 15) << 4;
|
||||||
for (int x = csx; x <= cex; x++, index++) {
|
for (int x = csx; x <= cex; x++, index++) {
|
||||||
globalIndex = indexes[index];
|
globalIndex = indexes[index];
|
||||||
int mainCombined = main[globalIndex];
|
char mainCombined = main[globalIndex];
|
||||||
for (int y = 0; y < minY; y++) {
|
for (int y = 0; y < minY; y++) {
|
||||||
chunk.blocks[index + (y << 8)] = mainCombined;
|
chunk.blocks[index + (y << 8)] = mainCombined;
|
||||||
}
|
}
|
||||||
@ -1615,7 +1622,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int maxIndex = minY << 8;
|
int maxIndex = minY << 8;
|
||||||
Arrays.fill(chunk.blocks, 0, maxIndex, BlockID.STONE);
|
Arrays.fill(chunk.blocks, 0, maxIndex, (char) BlockID.STONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean hasFloorThickness = primitives.floorThickness != 0 || primitives.worldThickness != 0;
|
final boolean hasFloorThickness = primitives.floorThickness != 0 || primitives.worldThickness != 0;
|
||||||
@ -1630,13 +1637,13 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
index = (z & 15) << 4;
|
index = (z & 15) << 4;
|
||||||
for (int x = csx; x <= cex; x++, index++) {
|
for (int x = csx; x <= cex; x++, index++) {
|
||||||
globalIndex = indexes[index];
|
globalIndex = indexes[index];
|
||||||
int height = heightMap[index];
|
int height = heightMap[index] & 0xFF;
|
||||||
int maxMainY = height;
|
int maxMainY = height;
|
||||||
int minMainY = minY;
|
int minMainY = minY;
|
||||||
|
|
||||||
int mainCombined = main[globalIndex];
|
char mainCombined = main[globalIndex];
|
||||||
|
|
||||||
int floorCombined = floor[globalIndex];
|
char floorCombined = floor[globalIndex];
|
||||||
if (hasFloorThickness) {
|
if (hasFloorThickness) {
|
||||||
if (x > 0) maxMainY = Math.min(heights[globalIndex - 1] & 0xFF, maxMainY);
|
if (x > 0) maxMainY = Math.min(heights[globalIndex - 1] & 0xFF, maxMainY);
|
||||||
if (x < getWidth() - 1) maxMainY = Math.min(heights[globalIndex + 1] & 0xFF, maxMainY);
|
if (x < getWidth() - 1) maxMainY = Math.min(heights[globalIndex + 1] & 0xFF, maxMainY);
|
||||||
@ -1671,33 +1678,33 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasOverlay) {
|
if (hasOverlay) {
|
||||||
int overlayCombined = overlay[globalIndex];
|
char overlayCombined = overlay[globalIndex];
|
||||||
int overlayIndex = index + (height + 1 << 8);
|
int overlayIndex = index + (height + 1 << 8);
|
||||||
chunk.blocks[overlayIndex] = overlayCombined;
|
chunk.blocks[overlayIndex] = overlayCombined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (primitives.bedrockId != 0) {
|
if (primitives.bedrockOrdinal != 0) {
|
||||||
chunk.blocks[index] = primitives.bedrockId;
|
chunk.blocks[index] = primitives.bedrockOrdinal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int[][][] localBlocks = getChunkArray(chunk.getX(), chunk.getZ());
|
char[][][] localBlocks = getChunkArray(chunk.getX(), chunk.getZ());
|
||||||
if (localBlocks != null) {
|
if (localBlocks != null) {
|
||||||
index = 0;
|
index = 0;
|
||||||
for (int layer = 0; layer < 16; layer++) {
|
for (int layer = 0; layer < 16; layer++) {
|
||||||
int by = layer << 4;
|
int by = layer << 4;
|
||||||
int ty = by + 15;
|
int ty = by + 15;
|
||||||
for (int y = by; y <= ty; y++, index += 256) {
|
for (int y = by; y <= ty; y++, index += 256) {
|
||||||
int[][] yBlocks = localBlocks[y];
|
char[][] yBlocks = localBlocks[y];
|
||||||
if (yBlocks != null) {
|
if (yBlocks != null) {
|
||||||
chunk.hasSections[layer] = true;
|
chunk.hasSections[layer] = true;
|
||||||
for (int z = 0; z < yBlocks.length; z++) {
|
for (int z = 0; z < yBlocks.length; z++) {
|
||||||
int[] zBlocks = yBlocks[z];
|
char[] zBlocks = yBlocks[z];
|
||||||
if (zBlocks != null) {
|
if (zBlocks != null) {
|
||||||
int zIndex = index + (z << 4);
|
int zIndex = index + (z << 4);
|
||||||
for (int x = 0; x < zBlocks.length; x++, zIndex++) {
|
for (int x = 0; x < zBlocks.length; x++, zIndex++) {
|
||||||
int combined = zBlocks[x];
|
char combined = zBlocks[x];
|
||||||
if (combined == 0) continue;
|
if (combined == 0) continue;
|
||||||
chunk.blocks[zIndex] = combined;
|
chunk.blocks[zIndex] = combined;
|
||||||
}
|
}
|
||||||
@ -1719,24 +1726,24 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUnsafe(int[][][] map, int combined, int x, int y, int z) {
|
private void setUnsafe(char[][][] map, char combined, int x, int y, int z) {
|
||||||
int[][] yMap = map[y];
|
char[][] yMap = map[y];
|
||||||
if (yMap == null) {
|
if (yMap == null) {
|
||||||
map[y] = yMap = new int[16][];
|
map[y] = yMap = new char[16][];
|
||||||
}
|
}
|
||||||
int[] zMap = yMap[z];
|
char[] zMap = yMap[z];
|
||||||
if (zMap == null) {
|
if (zMap == null) {
|
||||||
yMap[z] = zMap = new int[16];
|
yMap[z] = zMap = new char[16];
|
||||||
}
|
}
|
||||||
zMap[x] = combined;
|
zMap[x] = combined;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int get(int[][][] map, int x, int y, int z) {
|
private int get(char[][][] map, int x, int y, int z) {
|
||||||
int[][] yMap = map[y];
|
char[][] yMap = map[y];
|
||||||
if (yMap == null) {
|
if (yMap == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int[] zMap = yMap[z & 15];
|
char[] zMap = yMap[z & 15];
|
||||||
if (zMap == null) {
|
if (zMap == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1745,7 +1752,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
|
|
||||||
private void setOverlay(Mask mask, int combined) {
|
private void setOverlay(Mask mask, int combined) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if (overlay == null) overlay = new DifferentialArray<>(new int[getArea()]);
|
if (overlay == null) overlay = new DifferentialArray<>(new char[getArea()]);
|
||||||
for (int z = 0; z < getLength(); z++) {
|
for (int z = 0; z < getLength(); z++) {
|
||||||
mutable.mutZ(z);
|
mutable.mutZ(z);
|
||||||
for (int x = 0; x < getWidth(); x++, index++) {
|
for (int x = 0; x < getWidth(); x++, index++) {
|
||||||
@ -1807,29 +1814,29 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setFloor(int value) {
|
private void setFloor(char value) {
|
||||||
floor.record(() -> Arrays.fill(floor.get(), value));
|
floor.record(() -> Arrays.fill(floor.get(), value));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setColumn(int value) {
|
private void setColumn(char value) {
|
||||||
setFloor(value);
|
setFloor(value);
|
||||||
setMain(value);
|
setMain(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setMain(int value) {
|
private void setMain(char value) {
|
||||||
primitives.modifiedMain = true;
|
primitives.modifiedMain = true;
|
||||||
main.record(() -> Arrays.fill(main.get(), value));
|
main.record(() -> Arrays.fill(main.get(), value));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setOverlay(int value) {
|
private void setOverlay(char value) {
|
||||||
if (overlay == null) overlay = new DifferentialArray<>(new int[getArea()]);
|
if (overlay == null) overlay = new DifferentialArray<>(new char[getArea()]);
|
||||||
overlay.record(() -> Arrays.fill(overlay.get(), value));
|
overlay.record(() -> Arrays.fill(overlay.get(), value));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setOverlay(BufferedImage img, int combined, boolean white) {
|
private void setOverlay(BufferedImage img, char combined, boolean white) {
|
||||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||||
if (overlay == null) overlay = new DifferentialArray<>(new int[getArea()]);
|
if (overlay == null) overlay = new DifferentialArray<>(new char[getArea()]);
|
||||||
|
|
||||||
overlay.record(() -> {
|
overlay.record(() -> {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
@ -1845,7 +1852,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setMain(BufferedImage img, int combined, boolean white) {
|
private void setMain(BufferedImage img, char combined, boolean white) {
|
||||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||||
primitives.modifiedMain = true;
|
primitives.modifiedMain = true;
|
||||||
@ -1864,7 +1871,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setFloor(BufferedImage img, int combined, boolean white) {
|
private void setFloor(BufferedImage img, char combined, boolean white) {
|
||||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||||
|
|
||||||
@ -1882,7 +1889,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setColumn(BufferedImage img, int combined, boolean white) {
|
private void setColumn(BufferedImage img, char combined, boolean white) {
|
||||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||||
primitives.modifiedMain = true;
|
primitives.modifiedMain = true;
|
||||||
|
@ -84,7 +84,7 @@ public abstract class MCAWriter implements Extent {
|
|||||||
@Override
|
@Override
|
||||||
protected WritableMCAChunk initialValue() {
|
protected WritableMCAChunk initialValue() {
|
||||||
WritableMCAChunk chunk = new WritableMCAChunk();
|
WritableMCAChunk chunk = new WritableMCAChunk();
|
||||||
Arrays.fill(chunk.blocks, BlockID.AIR);
|
Arrays.fill(chunk.blocks, (char) BlockID.AIR);
|
||||||
// Arrays.fill(chunk.skyLight, (byte) 255);
|
// Arrays.fill(chunk.skyLight, (byte) 255);
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
@ -142,11 +142,12 @@ public abstract class MCAWriter implements Extent {
|
|||||||
pool.submit(() -> {
|
pool.submit(() -> {
|
||||||
try {
|
try {
|
||||||
WritableMCAChunk chunk = chunkStore.get();
|
WritableMCAChunk chunk = chunkStore.get();
|
||||||
chunk.clear(fcx, fcz);
|
chunk.reset();
|
||||||
|
chunk.setPosition(fcx, fcz);
|
||||||
chunk = write(chunk, csx, cex, csz, cez);
|
chunk = write(chunk, csx, cex, csz, cez);
|
||||||
if (chunk != null) {
|
if (chunk != null) {
|
||||||
// Generation offset
|
// Generation offset
|
||||||
chunk.setLoc( fcx + (getOffsetX() >> 4), fcz + (getOffsetZ() >> 4));
|
chunk.setPosition( fcx + (getOffsetX() >> 4), fcz + (getOffsetZ() >> 4));
|
||||||
|
|
||||||
// Compress
|
// Compress
|
||||||
byte[] bytes = chunk.toBytes(byteStore1.get());
|
byte[] bytes = chunk.toBytes(byteStore1.get());
|
||||||
|
@ -1,39 +1,44 @@
|
|||||||
package com.boydti.fawe.object.brush.visualization.cfi;
|
package com.boydti.fawe.object.brush.visualization.cfi;
|
||||||
|
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
import com.boydti.fawe.object.collection.BitArray4096;
|
import com.boydti.fawe.object.collection.BitArray4096;
|
||||||
|
import com.boydti.fawe.object.collection.BlockVector3ChunkMap;
|
||||||
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.jnbt.ListTag;
|
import com.sk89q.jnbt.ListTag;
|
||||||
import com.sk89q.jnbt.NBTConstants;
|
import com.sk89q.jnbt.NBTConstants;
|
||||||
import com.sk89q.jnbt.NBTOutputStream;
|
import com.sk89q.jnbt.NBTOutputStream;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.registry.state.Property;
|
import com.sk89q.worldedit.registry.state.Property;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
|
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||||
import com.sk89q.worldedit.world.block.BlockID;
|
import com.sk89q.worldedit.world.block.BlockID;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
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.BlockType;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class WritableMCAChunk {
|
public class WritableMCAChunk implements IChunkSet {
|
||||||
public final boolean[] hasSections = new boolean[16];
|
public final boolean[] hasSections = new boolean[16];
|
||||||
public final byte[] skyLight = new byte[65536];
|
|
||||||
public final byte[] blockLight = new byte[65536];
|
|
||||||
|
|
||||||
public boolean hasBiomes = false;
|
public boolean hasBiomes = false;
|
||||||
public final int[] biomes = new int[256];
|
public final byte[] biomes = new byte[256];
|
||||||
|
|
||||||
public final int[] blocks = new int[65536];
|
public final char[] blocks = new char[65536];
|
||||||
|
|
||||||
public Map<Short, CompoundTag> tiles = new HashMap<>();
|
public BlockVector3ChunkMap<CompoundTag> tiles = new BlockVector3ChunkMap<CompoundTag>();
|
||||||
public Map<UUID, CompoundTag> entities = new HashMap<>();
|
public Map<UUID, CompoundTag> entities = new HashMap<>();
|
||||||
public long inhabitedTime = System.currentTimeMillis();
|
public long inhabitedTime = System.currentTimeMillis();
|
||||||
public long lastUpdate;
|
public long lastUpdate;
|
||||||
@ -54,14 +59,18 @@ public class WritableMCAChunk {
|
|||||||
return chunkZ;
|
return chunkZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLoc(int X, int Z) {
|
@Override
|
||||||
|
public boolean hasSection(int layer) {
|
||||||
|
return hasSections[layer];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosition(int X, int Z) {
|
||||||
this.chunkX = X;
|
this.chunkX = X;
|
||||||
this.chunkZ = Z;
|
this.chunkZ = Z;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear(int X, int Z) {
|
@Override
|
||||||
this.chunkX = X;
|
public IChunkSet reset() {
|
||||||
this.chunkZ = Z;
|
|
||||||
if (!tiles.isEmpty()) {
|
if (!tiles.isEmpty()) {
|
||||||
tiles.clear();
|
tiles.clear();
|
||||||
}
|
}
|
||||||
@ -76,6 +85,7 @@ public class WritableMCAChunk {
|
|||||||
blocks[i] = BlockID.AIR;
|
blocks[i] = BlockID.AIR;
|
||||||
}
|
}
|
||||||
Arrays.fill(hasSections, false);
|
Arrays.fill(hasSections, false);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write(NBTOutputStream nbtOut) throws IOException {
|
public void write(NBTOutputStream nbtOut) throws IOException {
|
||||||
@ -192,13 +202,13 @@ public class WritableMCAChunk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
out.writeNamedTagName("BlockLight", NBTConstants.TYPE_BYTE_ARRAY);
|
// out.writeNamedTagName("BlockLight", NBTConstants.TYPE_BYTE_ARRAY);
|
||||||
out.writeInt(2048);
|
// out.writeInt(2048);
|
||||||
out.write(blockLight, layer << 11, 1 << 11);
|
// out.write(blockLight, layer << 11, 1 << 11);
|
||||||
|
//
|
||||||
out.writeNamedTagName("SkyLight", NBTConstants.TYPE_BYTE_ARRAY);
|
// out.writeNamedTagName("SkyLight", NBTConstants.TYPE_BYTE_ARRAY);
|
||||||
out.writeInt(2048);
|
// out.writeInt(2048);
|
||||||
out.write(skyLight, layer << 11, 1 << 11);
|
// out.write(skyLight, layer << 11, 1 << 11);
|
||||||
|
|
||||||
|
|
||||||
out.writeEndTag();
|
out.writeEndTag();
|
||||||
@ -250,6 +260,15 @@ public class WritableMCAChunk {
|
|||||||
return deleted;
|
return deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
if (deleted) return true;
|
||||||
|
for (boolean hasSection : hasSections) {
|
||||||
|
if (hasSection) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isModified() {
|
public boolean isModified() {
|
||||||
return modified != 0;
|
return modified != 0;
|
||||||
}
|
}
|
||||||
@ -272,15 +291,18 @@ public class WritableMCAChunk {
|
|||||||
return bitMask;
|
return bitMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTile(int x, int y, int z, CompoundTag tile) {
|
@Override
|
||||||
|
public boolean setTile(int x, int y, int z, CompoundTag tile) {
|
||||||
setModified();
|
setModified();
|
||||||
short pair = MathMan.tripleBlockCoord(x, y, z);
|
|
||||||
if (tile != null) {
|
if (tile != null) {
|
||||||
tiles.put(pair, tile);
|
tiles.put(x, y, z, tile);
|
||||||
} else {
|
} else {
|
||||||
tiles.remove(pair);
|
if (tiles.remove(x, y, z) == null) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public void setEntity(CompoundTag entityTag) {
|
public void setEntity(CompoundTag entityTag) {
|
||||||
setModified();
|
setModified();
|
||||||
@ -289,17 +311,39 @@ public class WritableMCAChunk {
|
|||||||
entities.put(new UUID(most, least), entityTag);
|
entities.put(new UUID(most, least), entityTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBiome(int x, int z, BiomeType biome) {
|
@Override
|
||||||
|
public BiomeType getBiomeType(int x, int z) {
|
||||||
|
return BiomeTypes.get(this.biomes[(z << 4) | x] & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeType[] getBiomes() {
|
||||||
|
BiomeType[] tmp = new BiomeType[256];
|
||||||
|
for (int i = 0; i < 256; i++) {
|
||||||
|
tmp[i] = BiomeTypes.get(this.biomes[i] & 0xFF);
|
||||||
|
}
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBiome(BlockVector2 pos, BiomeType biome) {
|
||||||
|
return this.setBiome(pos.getX(), 0, pos.getZ(), biome);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||||
setModified();
|
setModified();
|
||||||
biomes[x + (z << 4)] = biome.getInternalId();
|
biomes[x + (z << 4)] = (byte) biome.getInternalId();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<CompoundTag> getEntities() {
|
public Set<CompoundTag> getEntities() {
|
||||||
return new HashSet<>(entities.values());
|
return new HashSet<>(entities.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Short, CompoundTag> getTiles() {
|
@Override
|
||||||
return tiles == null ? new HashMap<>() : tiles;
|
public Map<BlockVector3, CompoundTag> getTiles() {
|
||||||
|
return tiles == null ? Collections.emptyMap() : tiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompoundTag getTile(int x, int y, int z) {
|
public CompoundTag getTile(int x, int y, int z) {
|
||||||
@ -310,94 +354,51 @@ public class WritableMCAChunk {
|
|||||||
return tiles.get(pair);
|
return tiles.get(pair);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean doesSectionExist(int cy) {
|
|
||||||
return hasSections[cy];
|
|
||||||
}
|
|
||||||
|
|
||||||
private final int getIndex(int x, int y, int z) {
|
private final int getIndex(int x, int y, int z) {
|
||||||
return x | (z << 4) | (y << 8);
|
return x | (z << 4) | (y << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBlockCombinedId(int x, int y, int z) {
|
public int getBlockOrdinal(int x, int y, int z) {
|
||||||
return blocks[x | (z << 4) | (y << 8)];
|
return blocks[x | (z << 4) | (y << 8)];
|
||||||
}
|
}
|
||||||
|
|
||||||
public BiomeType[] getBiomeArray() {
|
@Override
|
||||||
return null;
|
public BlockState getBlock(int x, int y, int z) {
|
||||||
|
int ordinal = getBlockOrdinal(x, y, z);
|
||||||
|
return BlockState.getFromOrdinal(ordinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<UUID> getEntityRemoves() {
|
public Set<UUID> getEntityRemoves() {
|
||||||
return new HashSet<>();
|
return new HashSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSkyLight(int x, int y, int z, int value) {
|
@Override
|
||||||
setNibble(getIndex(x, y, z), skyLight, value);
|
public boolean setBlock(int x, int y, int z, BlockStateHolder holder) {
|
||||||
|
setBlock(x, y, z, holder.getOrdinalChar());
|
||||||
|
holder.applyTileEntity(this, x, y, z);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBlockLight(int x, int y, int z, int value) {
|
@Override
|
||||||
setNibble(getIndex(x, y, z), blockLight, value);
|
public void setBlocks(int layer, char[] data) {
|
||||||
}
|
int offset = layer << 12;
|
||||||
|
for (int i = 0; i < 4096; i++) {
|
||||||
public int getSkyLight(int x, int y, int z) {
|
blocks[offset + i] = data[i];
|
||||||
if (!hasSections[y >> 4]) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return getNibble(getIndex(x, y, z), skyLight);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getBlockLight(int x, int y, int z) {
|
|
||||||
if (!hasSections[y >> 4]) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return getNibble(getIndex(x, y, z), blockLight);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFullbright() {
|
|
||||||
for (int layer = 0; layer < 16; layer++) {
|
|
||||||
if (hasSections[layer]) {
|
|
||||||
Arrays.fill(skyLight, layer << 7, ((layer + 1) << 7), (byte) 255);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeLight() {
|
@Override
|
||||||
for (int i = 0; i < 16; i++) {
|
public char[] getArray(int layer) {
|
||||||
removeLight(i);
|
char[] tmp = FaweCache.IMP.SECTION_BITS_TO_CHAR.get();
|
||||||
|
int offset = layer << 12;
|
||||||
|
for (int i = 0; i < 4096; i++) {
|
||||||
|
tmp[i] = blocks[offset + i];
|
||||||
}
|
}
|
||||||
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeLight(int i) {
|
public void setBlock(int x, int y, int z, char ordinal) {
|
||||||
if (hasSections[i]) {
|
blocks[getIndex(x, y, z)] = ordinal;
|
||||||
Arrays.fill(skyLight, i << 7, ((i + 1) << 7), (byte) 0);
|
|
||||||
Arrays.fill(blockLight, i << 7, ((i + 1) << 7), (byte) 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNibble(int index, byte[] array) {
|
|
||||||
int indexShift = index >> 1;
|
|
||||||
if ((index & 1) == 0) {
|
|
||||||
return array[indexShift] & 15;
|
|
||||||
} else {
|
|
||||||
return array[indexShift] >> 4 & 15;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNibble(int index, byte[] array, int value) {
|
|
||||||
int indexShift = index >> 1;
|
|
||||||
byte existing = array[indexShift];
|
|
||||||
int valueShift = value << 4;
|
|
||||||
if (existing == value + valueShift) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((index & 1) == 0) {
|
|
||||||
array[indexShift] = (byte) (existing & 240 | value);
|
|
||||||
} else {
|
|
||||||
array[indexShift] = (byte) (existing & 15 | valueShift);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBlock(int x, int y, int z, int combinedId) {
|
|
||||||
blocks[getIndex(x, y, z)] = combinedId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBiome(BiomeType biome) {
|
public void setBiome(BiomeType biome) {
|
||||||
@ -407,4 +408,9 @@ public class WritableMCAChunk {
|
|||||||
public void removeEntity(UUID uuid) {
|
public void removeEntity(UUID uuid) {
|
||||||
entities.remove(uuid);
|
entities.remove(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean trim(boolean aggressive) {
|
||||||
|
return isEmpty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,11 @@ public class BlockVector3ChunkMap<T> implements Map<BlockVector3, T>, IAdaptedMa
|
|||||||
return map.put(key, value);
|
return map.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public T remove(int x, int y, int z) {
|
||||||
|
short key = MathMan.tripleBlockCoord(x, y, z);
|
||||||
|
return map.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean contains(int x, int y, int z) {
|
public boolean contains(int x, int y, int z) {
|
||||||
short key = MathMan.tripleBlockCoord(x, y, z);
|
short key = MathMan.tripleBlockCoord(x, y, z);
|
||||||
return map.containsKey(key);
|
return map.containsKey(key);
|
||||||
|
@ -265,9 +265,9 @@ public final class DifferentialArray<T> implements DifferentialCollection<T> {
|
|||||||
return dataBytes[index];
|
return dataBytes[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
// public char getChar(int index) {
|
public char getChar(int index) {
|
||||||
// return dataChars[index];
|
return dataChars[index];
|
||||||
// }
|
}
|
||||||
|
|
||||||
public int getInt(int index) {
|
public int getInt(int index) {
|
||||||
return dataInts[index];
|
return dataInts[index];
|
||||||
|
@ -9,12 +9,12 @@ import java.lang.reflect.Array;
|
|||||||
* Records changes made through the {@link #set(int, int, int, int)} method<br/>
|
* Records changes made through the {@link #set(int, int, int, int)} method<br/>
|
||||||
* Changes are not recorded if you edit the raw data
|
* Changes are not recorded if you edit the raw data
|
||||||
*/
|
*/
|
||||||
public final class DifferentialBlockBuffer implements DifferentialCollection<int[][][][][]> {
|
public final class DifferentialBlockBuffer implements DifferentialCollection<char[][][][][]> {
|
||||||
|
|
||||||
private final int width, length;
|
private final int width, length;
|
||||||
private final int t1, t2;
|
private final int t1, t2;
|
||||||
private int[][][][][] data;
|
private char[][][][][] data;
|
||||||
private int[][][][][] changes;
|
private char[][][][][] changes;
|
||||||
|
|
||||||
public DifferentialBlockBuffer(int width, int length) {
|
public DifferentialBlockBuffer(int width, int length) {
|
||||||
this.width = width;
|
this.width = width;
|
||||||
@ -24,7 +24,7 @@ public final class DifferentialBlockBuffer implements DifferentialCollection<int
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[][][][][] get() {
|
public char[][][][][] get() {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,72 +116,72 @@ public final class DifferentialBlockBuffer implements DifferentialCollection<int
|
|||||||
changes = null;
|
changes = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(int x, int y, int z, int combined) {
|
public void set(int x, int y, int z, char combined) {
|
||||||
if (combined == 0) combined = 1;
|
if (combined == 0) combined = 1;
|
||||||
int localX = x & 15;
|
int localX = x & 15;
|
||||||
int localZ = z & 15;
|
int localZ = z & 15;
|
||||||
int chunkX = x >> 4;
|
int chunkX = x >> 4;
|
||||||
int chunkZ = z >> 4;
|
int chunkZ = z >> 4;
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
data = new int[t1][][][][];
|
data = new char[t1][][][][];
|
||||||
changes = new int[0][][][][];
|
changes = new char[0][][][][];
|
||||||
}
|
}
|
||||||
|
|
||||||
int[][][][] arr = data[chunkZ];
|
char[][][][] arr = data[chunkZ];
|
||||||
if (arr == null) {
|
if (arr == null) {
|
||||||
arr = data[chunkZ] = new int[t2][][][];
|
arr = data[chunkZ] = new char[t2][][][];
|
||||||
}
|
}
|
||||||
int[][][] arr2 = arr[chunkX];
|
char[][][] arr2 = arr[chunkX];
|
||||||
if (arr2 == null) {
|
if (arr2 == null) {
|
||||||
arr2 = arr[chunkX] = new int[256][][];
|
arr2 = arr[chunkX] = new char[256][][];
|
||||||
}
|
}
|
||||||
|
|
||||||
int[][] yMap = arr2[y];
|
char[][] yMap = arr2[y];
|
||||||
if (yMap == null) {
|
if (yMap == null) {
|
||||||
arr2[y] = yMap = new int[16][];
|
arr2[y] = yMap = new char[16][];
|
||||||
}
|
}
|
||||||
boolean newSection;
|
boolean newSection;
|
||||||
int current;
|
int current;
|
||||||
int[] zMap = yMap[localZ];
|
char[] zMap = yMap[localZ];
|
||||||
if (zMap == null) {
|
if (zMap == null) {
|
||||||
yMap[localZ] = zMap = new int[16];
|
yMap[localZ] = zMap = new char[16];
|
||||||
|
|
||||||
if (changes == null) {
|
if (changes == null) {
|
||||||
changes = new int[t1][][][][];
|
changes = new char[t1][][][][];
|
||||||
} else if (changes != null && changes.length != 0) {
|
} else if (changes != null && changes.length != 0) {
|
||||||
initialChange(changes, chunkX, chunkZ, localX, localZ, y, (int) -combined);
|
initialChange(changes, chunkX, chunkZ, localX, localZ, y, (char) -combined);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (changes == null || changes.length == 0) changes = new int[t1][][][][];
|
if (changes == null || changes.length == 0) changes = new char[t1][][][][];
|
||||||
appendChange(changes, chunkX, chunkZ, localX, localZ, y, (int) (zMap[localX] - combined));
|
appendChange(changes, chunkX, chunkZ, localX, localZ, y, (char) (zMap[localX] - combined));
|
||||||
}
|
}
|
||||||
|
|
||||||
zMap[localX] = combined;
|
zMap[localX] = combined;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initialChange(int[][][][][] src, int chunkX, int chunkZ, int localX, int localZ, int y, int combined) {
|
private void initialChange(char[][][][][] src, int chunkX, int chunkZ, int localX, int localZ, int y, char combined) {
|
||||||
int[][][][] arr = src[chunkZ];
|
char[][][][] arr = src[chunkZ];
|
||||||
if (arr == null) {
|
if (arr == null) {
|
||||||
src[chunkZ] = new int[0][][][];
|
src[chunkZ] = new char[0][][][];
|
||||||
return;
|
return;
|
||||||
} else if (arr.length == 0) return;
|
} else if (arr.length == 0) return;
|
||||||
|
|
||||||
int[][][] arr2 = arr[chunkX];
|
char[][][] arr2 = arr[chunkX];
|
||||||
if (arr2 == null) {
|
if (arr2 == null) {
|
||||||
arr[chunkX] = new int[0][][];
|
arr[chunkX] = new char[0][][];
|
||||||
return;
|
return;
|
||||||
} else if (arr2.length == 0) return;
|
} else if (arr2.length == 0) return;
|
||||||
|
|
||||||
int[][] yMap = arr2[y];
|
char[][] yMap = arr2[y];
|
||||||
if (yMap == null) {
|
if (yMap == null) {
|
||||||
arr2[y] = new int[0][];
|
arr2[y] = new char[0][];
|
||||||
return;
|
return;
|
||||||
} else if (yMap.length == 0) return;
|
} else if (yMap.length == 0) return;
|
||||||
|
|
||||||
int[] zMap = yMap[localZ];
|
char[] zMap = yMap[localZ];
|
||||||
if (zMap == null) {
|
if (zMap == null) {
|
||||||
yMap[localZ] = new int[0];
|
yMap[localZ] = new char[0];
|
||||||
return;
|
return;
|
||||||
} else if (zMap.length == 0) return;
|
} else if (zMap.length == 0) return;
|
||||||
|
|
||||||
@ -189,23 +189,23 @@ public final class DifferentialBlockBuffer implements DifferentialCollection<int
|
|||||||
zMap[localX] = combined;
|
zMap[localX] = combined;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void appendChange(int[][][][][] src, int chunkX, int chunkZ, int localX, int localZ, int y, int combined) {
|
private void appendChange(char[][][][][] src, int chunkX, int chunkZ, int localX, int localZ, int y, char combined) {
|
||||||
int[][][][] arr = src[chunkZ];
|
char[][][][] arr = src[chunkZ];
|
||||||
if (arr == null || arr.length == 0) {
|
if (arr == null || arr.length == 0) {
|
||||||
arr = src[chunkZ] = new int[t2][][][];
|
arr = src[chunkZ] = new char[t2][][][];
|
||||||
}
|
}
|
||||||
int[][][] arr2 = arr[chunkX];
|
char[][][] arr2 = arr[chunkX];
|
||||||
if (arr2 == null || arr2.length == 0) {
|
if (arr2 == null || arr2.length == 0) {
|
||||||
arr2 = arr[chunkX] = new int[256][][];
|
arr2 = arr[chunkX] = new char[256][][];
|
||||||
}
|
}
|
||||||
|
|
||||||
int[][] yMap = arr2[y];
|
char[][] yMap = arr2[y];
|
||||||
if (yMap == null || yMap.length == 0) {
|
if (yMap == null || yMap.length == 0) {
|
||||||
arr2[y] = yMap = new int[16][];
|
arr2[y] = yMap = new char[16][];
|
||||||
}
|
}
|
||||||
int[] zMap = yMap[localZ];
|
char[] zMap = yMap[localZ];
|
||||||
if (zMap == null || zMap.length == 0) {
|
if (zMap == null || zMap.length == 0) {
|
||||||
yMap[localZ] = zMap = new int[16];
|
yMap[localZ] = zMap = new char[16];
|
||||||
}
|
}
|
||||||
zMap[localX] = combined;
|
zMap[localX] = combined;
|
||||||
}
|
}
|
||||||
|
@ -220,4 +220,15 @@ public class FastByteArrayOutputStream extends OutputStream {
|
|||||||
size += index;
|
size += index;
|
||||||
index = 0;
|
index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
Arrays.fill(buffer, (byte) 0);
|
||||||
|
index = 0;
|
||||||
|
size = 0;
|
||||||
|
buffers.clear();
|
||||||
|
}
|
||||||
}
|
}
|
@ -122,7 +122,7 @@ public class FaweLocalBlockQueue extends LocalBlockQueue {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void refreshChunk(int x, int z) {
|
public void refreshChunk(int x, int z) {
|
||||||
world.sendChunk(x, z, 0);
|
world.refreshChunk(x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -51,7 +51,7 @@ public class DelegateTextureUtil extends TextureUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getIsBlockCloserThanBiome(int[] blockAndBiomeIdOutput, int color, int biomePriority) {
|
public boolean getIsBlockCloserThanBiome(char[] blockAndBiomeIdOutput, int color, int biomePriority) {
|
||||||
return parent.getIsBlockCloserThanBiome(blockAndBiomeIdOutput, color, biomePriority);
|
return parent.getIsBlockCloserThanBiome(blockAndBiomeIdOutput, color, biomePriority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,11 +10,11 @@ import java.util.Base64;
|
|||||||
|
|
||||||
public enum Jars {
|
public enum Jars {
|
||||||
|
|
||||||
MM_v1_4_0("https://github.com/InventivetalentDev/MapManager/releases/download/1.4.0-SNAPSHOT/MapManager_v1.4.0-SNAPSHOT.jar",
|
MM_v1_4_0("https://github.com/InventivetalentDev/MapManager/releases/download/1.7.3-SNAPSHOT/MapManager_v1.7.3-SNAPSHOT.jar",
|
||||||
"AEO5SKBUGN4YJRS8XGGNLBM2QRZPTI1KF0/1W1URTGA=", 163279),
|
"M3YLUQZZ66K2DMVDCYLEU38U3ZKRKHRAXQGGPVKFO6G=", 554831),
|
||||||
|
|
||||||
PL_v3_6_0("https://github.com/InventivetalentDev/PacketListenerAPI/releases/download/3.6.0-SNAPSHOT/PacketListenerAPI_v3.6.0-SNAPSHOT.jar",
|
PL_v3_6_0("https://github.com/InventivetalentDev/PacketListenerAPI/releases/download/3.7.3-SNAPSHOT/PacketListenerAPI_v3.7.3-SNAPSHOT.jar",
|
||||||
"OYBE75VIU+NNWHRVREBLDARWA+/TBDQZ1RC562QULBA=", 166508),
|
"ETDBRZLN5PRVDFR/MSQDPM6JJER3WQOKHCN8FUXO5ZM=", 167205),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ public class RandomTextureUtil extends CachedTextureUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getIsBlockCloserThanBiome(int[] blockAndBiomeIdOutput, int color, int biomePriority) {
|
public boolean getIsBlockCloserThanBiome(char[] blockAndBiomeIdOutput, int color, int biomePriority) {
|
||||||
BlockType block = getNearestBlock(color);
|
BlockType block = getNearestBlock(color);
|
||||||
int[] mix = biomeMixes.getOrDefault(color, null);
|
int[] mix = biomeMixes.getOrDefault(color, null);
|
||||||
if (mix == null) {
|
if (mix == null) {
|
||||||
@ -55,8 +55,8 @@ public class RandomTextureUtil extends CachedTextureUtil {
|
|||||||
int biomeId = mix[index];
|
int biomeId = mix[index];
|
||||||
int biomeAvColor = mix[3];
|
int biomeAvColor = mix[3];
|
||||||
int blockColor = getColor(block);
|
int blockColor = getColor(block);
|
||||||
blockAndBiomeIdOutput[0] = block.getInternalId();
|
blockAndBiomeIdOutput[0] = block.getDefaultState().getOrdinalChar();
|
||||||
blockAndBiomeIdOutput[1] = biomeId;
|
blockAndBiomeIdOutput[1] = (char) biomeId;
|
||||||
if (colorDistance(biomeAvColor, color) - biomePriority > colorDistance(blockColor, color)) {
|
if (colorDistance(biomeAvColor, color) - biomePriority > colorDistance(blockColor, color)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -497,13 +497,13 @@ public class TextureUtil implements TextureHolder {
|
|||||||
return biomes[biome];
|
return biomes[biome];
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getIsBlockCloserThanBiome(int[] blockAndBiomeIdOutput, int color,
|
public boolean getIsBlockCloserThanBiome(char[] blockAndBiomeIdOutput, int color,
|
||||||
int biomePriority) {
|
int biomePriority) {
|
||||||
BlockType block = getNearestBlock(color);
|
BlockType block = getNearestBlock(color);
|
||||||
TextureUtil.BiomeColor biome = getNearestBiome(color);
|
TextureUtil.BiomeColor biome = getNearestBiome(color);
|
||||||
int blockColor = getColor(block);
|
int blockColor = getColor(block);
|
||||||
blockAndBiomeIdOutput[0] = block.getDefaultState().getOrdinalChar();
|
blockAndBiomeIdOutput[0] = block.getDefaultState().getOrdinalChar();
|
||||||
blockAndBiomeIdOutput[1] = biome.id;
|
blockAndBiomeIdOutput[1] = (char) biome.id;
|
||||||
if (colorDistance(biome.grassCombined, color) - biomePriority > colorDistance(blockColor,
|
if (colorDistance(biome.grassCombined, color) - biomePriority > colorDistance(blockColor,
|
||||||
color)) {
|
color)) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -235,8 +235,8 @@ public class WorldWrapper extends AbstractWorld {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendChunk(int X, int Z, int mask) {
|
public void refreshChunk(int X, int Z) {
|
||||||
parent.sendChunk(X, Z, mask);
|
parent.refreshChunk(X, Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -682,7 +682,12 @@ public class LocalSession implements TextureHolder {
|
|||||||
public Region getSelection(World world) throws IncompleteRegionException {
|
public Region getSelection(World world) throws IncompleteRegionException {
|
||||||
checkNotNull(world);
|
checkNotNull(world);
|
||||||
if (selector.getIncompleteRegion().getWorld() == null || !selector.getIncompleteRegion().getWorld().equals(world)) {
|
if (selector.getIncompleteRegion().getWorld() == null || !selector.getIncompleteRegion().getWorld().equals(world)) {
|
||||||
throw new IncompleteRegionException();
|
throw new IncompleteRegionException() {
|
||||||
|
@Override
|
||||||
|
public synchronized Throwable fillInStackTrace() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return selector.getRegion();
|
return selector.getRegion();
|
||||||
}
|
}
|
||||||
@ -1288,6 +1293,8 @@ public class LocalSession implements TextureHolder {
|
|||||||
public void describeCUI(Actor actor) {
|
public void describeCUI(Actor actor) {
|
||||||
checkNotNull(actor);
|
checkNotNull(actor);
|
||||||
|
|
||||||
|
// TODO preload
|
||||||
|
|
||||||
if (!hasCUISupport) {
|
if (!hasCUISupport) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,8 @@ public class DistanceWand extends BrushTool implements DoubleActionTraceTool {
|
|||||||
private Location getTarget(Player player) {
|
private Location getTarget(Player player) {
|
||||||
Location target;
|
Location target;
|
||||||
Mask mask = getTraceMask();
|
Mask mask = getTraceMask();
|
||||||
if (this.range < MAX_RANGE) {
|
int range = getRange();
|
||||||
|
if (range < MAX_RANGE) {
|
||||||
target = player.getBlockTrace(getRange(), true, mask);
|
target = player.getBlockTrace(getRange(), true, mask);
|
||||||
} else {
|
} else {
|
||||||
target = player.getBlockTrace(MAX_RANGE, false, mask);
|
target = player.getBlockTrace(MAX_RANGE, false, mask);
|
||||||
|
@ -23,6 +23,10 @@ public interface MapMetadatable extends Metadatable {
|
|||||||
return !getRawMeta().isEmpty();
|
return !getRawMeta().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default Object putIfAbsent(String key, Object value) {
|
||||||
|
return getRawMeta().putIfAbsent(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the metadata for a key.
|
* Get the metadata for a key.
|
||||||
*
|
*
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
package com.sk89q.worldedit.entity;
|
package com.sk89q.worldedit.entity;
|
||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.config.BBC;
|
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.brush.visualization.VirtualWorld;
|
import com.boydti.fawe.object.brush.visualization.VirtualWorld;
|
||||||
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
||||||
@ -39,7 +38,6 @@ import com.sk89q.worldedit.function.mask.Mask;
|
|||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.math.Vector3;
|
import com.sk89q.worldedit.math.Vector3;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.regions.RegionOperationException;
|
|
||||||
import com.sk89q.worldedit.regions.RegionSelector;
|
import com.sk89q.worldedit.regions.RegionSelector;
|
||||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||||
import com.sk89q.worldedit.util.Direction;
|
import com.sk89q.worldedit.util.Direction;
|
||||||
@ -49,11 +47,10 @@ import com.sk89q.worldedit.world.World;
|
|||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
import com.sk89q.worldedit.world.gamemode.GameMode;
|
import com.sk89q.worldedit.world.gamemode.GameMode;
|
||||||
import java.io.File;
|
|
||||||
import java.text.NumberFormat;
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import org.enginehub.piston.inject.InjectedValueAccess;
|
import java.io.File;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a player
|
* Represents a player
|
||||||
@ -324,6 +321,8 @@ public interface Player extends Entity, Actor {
|
|||||||
*/
|
*/
|
||||||
<B extends BlockStateHolder<B>> void sendFakeBlock(BlockVector3 pos, @Nullable B block);
|
<B extends BlockStateHolder<B>> void sendFakeBlock(BlockVector3 pos, @Nullable B block);
|
||||||
|
|
||||||
|
void sendFakeChunk(int chunkX, int chunkZ, Supplier<byte[]> data);
|
||||||
|
|
||||||
public Region[] getCurrentRegions();
|
public Region[] getCurrentRegions();
|
||||||
|
|
||||||
Region[] getCurrentRegions(FaweMaskManager.MaskType type);
|
Region[] getCurrentRegions(FaweMaskManager.MaskType type);
|
||||||
|
@ -41,6 +41,7 @@ import com.sk89q.worldedit.world.gamemode.GameMode;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class PlayerProxy extends AbstractPlayerActor {
|
public class PlayerProxy extends AbstractPlayerActor {
|
||||||
|
|
||||||
@ -211,6 +212,11 @@ public class PlayerProxy extends AbstractPlayerActor {
|
|||||||
basePlayer.sendFakeBlock(pos, block);
|
basePlayer.sendFakeBlock(pos, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendFakeChunk(int chunkX, int chunkZ, Supplier<byte[]> data) {
|
||||||
|
basePlayer.sendFakeChunk(chunkX, chunkZ, data);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendTitle(String title, String sub) {
|
public void sendTitle(String title, String sub) {
|
||||||
basePlayer.sendTitle(title, sub);
|
basePlayer.sendTitle(title, sub);
|
||||||
|
@ -148,7 +148,7 @@ public class NullWorld extends AbstractWorld {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendChunk(int X, int Z, int mask) {
|
public void refreshChunk(int X, int Z) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,7 +300,7 @@ public interface World extends Extent, Keyed, IChunkCache<IChunkGet> {
|
|||||||
* @param chunkZ
|
* @param chunkZ
|
||||||
* @param bitMask
|
* @param bitMask
|
||||||
*/
|
*/
|
||||||
void sendChunk(final int X, final int Z, final int mask);
|
void refreshChunk(final int X, final int Z);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
IChunkGet get(int x, int z);
|
IChunkGet get(int x, int z);
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren