diff --git a/bukkit0/src/main/java/com/boydti/fawe/bukkit/ABukkitMain.java b/bukkit0/src/main/java/com/boydti/fawe/bukkit/ABukkitMain.java
index 8db62b31..e9cccb5b 100644
--- a/bukkit0/src/main/java/com/boydti/fawe/bukkit/ABukkitMain.java
+++ b/bukkit0/src/main/java/com/boydti/fawe/bukkit/ABukkitMain.java
@@ -55,4 +55,6 @@ public abstract class ABukkitMain extends JavaPlugin {
}
public abstract FaweQueue getQueue(World world);
+
+ public abstract FaweQueue getQueue(String world);
}
\ No newline at end of file
diff --git a/bukkit0/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java b/bukkit0/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java
index 4ccb41ee..10ac9db0 100644
--- a/bukkit0/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java
+++ b/bukkit0/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java
@@ -150,6 +150,47 @@ public class FaweBukkit implements IFawe, Listener {
private boolean hasNMS = true;
private boolean playerChunk = false;
+ @Override
+ public FaweQueue getNewQueue(String world, boolean fast) {
+ if (playerChunk != (playerChunk = true)) {
+ try {
+ Field fieldDirtyCount = ReflectionUtils.getRefClass("{nms}.PlayerChunk").getField("dirtyCount").getRealField();
+ fieldDirtyCount.setAccessible(true);
+ int mod = fieldDirtyCount.getModifiers();
+ if ((mod & Modifier.VOLATILE) == 0) {
+ Field modifiersField = Field.class.getDeclaredField("modifiers");
+ modifiersField.setAccessible(true);
+ modifiersField.setInt(fieldDirtyCount, mod + Modifier.VOLATILE);
+ }
+ } catch (Throwable ignore) {}
+ }
+ try {
+ return plugin.getQueue(world);
+ } catch (Throwable ignore) {}
+ // Disable incompatible settings
+ Settings.QUEUE.PARALLEL_THREADS = 1; // BukkitAPI placer is too slow to parallel thread at the chunk level
+ Settings.HISTORY.COMBINE_STAGES = false; // Performing a chunk copy (if possible) wouldn't be faster using the BukkitAPI
+ if (hasNMS) {
+ debug("====== NO NMS BLOCK PLACER FOUND ======");
+ debug("FAWE couldn't find a fast block placer");
+ debug("Bukkit version: " + Bukkit.getVersion());
+ debug("NMS label: " + plugin.getClass().getSimpleName().split("_")[1]);
+ debug("Fallback placer: " + BukkitQueue_All.class);
+ debug("=======================================");
+ debug("Download the version of FAWE for your platform");
+ debug(" - http://ci.athion.net/job/FastAsyncWorldEdit/lastSuccessfulBuild/artifact/target");
+ debug("=======================================");
+ TaskManager.IMP.laterAsync(new Runnable() {
+ @Override
+ public void run() {
+ MainUtil.sendAdmin("&cNo NMS placer found, see console!");
+ }
+ }, 1);
+ hasNMS = false;
+ }
+ return new BukkitQueue_All(world);
+ }
+
/**
* The FaweQueue is a core part of block placement
* - The queue returned here is used in the SetQueue class (SetQueue handles the implementation specific queue)
diff --git a/bukkit0/src/main/java/com/boydti/fawe/bukkit/v0/BukkitChunk_All.java b/bukkit0/src/main/java/com/boydti/fawe/bukkit/v0/BukkitChunk_All.java
index 25957507..08ff48b5 100644
--- a/bukkit0/src/main/java/com/boydti/fawe/bukkit/v0/BukkitChunk_All.java
+++ b/bukkit0/src/main/java/com/boydti/fawe/bukkit/v0/BukkitChunk_All.java
@@ -3,6 +3,7 @@ package com.boydti.fawe.bukkit.v0;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.example.CharFaweChunk;
+import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.util.MainUtil;
import com.sk89q.jnbt.CompoundTag;
@@ -17,7 +18,7 @@ import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.block.Block;
-public class BukkitChunk_All extends CharFaweChunk {
+public class BukkitChunk_All extends CharFaweChunk {
/**
* A FaweSections object represents a chunk and the blocks that you wish to change in it.
@@ -39,17 +40,23 @@ public class BukkitChunk_All extends CharFaweChunk {
private int index;
private boolean place = true;
+ @Override
+ public void start() {
+ getChunk().load(true);
+ }
+
/**
*
* @return
*/
- public void execute(long start) {
+ @Override
+ public FaweChunk call() {
+ long start = System.currentTimeMillis();
int recommended = 25 + BukkitQueue_All.ALLOCATE;
boolean more = true;
BukkitQueue_All parent = (BukkitQueue_All) getParent();
final Chunk chunk = getChunk();
Object[] disableResult = parent.disableLighting(chunk);
- chunk.load(true);
final World world = chunk.getWorld();
char[][] sections = getCombinedIdArrays();
if (layer == -1) {
@@ -220,6 +227,7 @@ public class BukkitChunk_All extends CharFaweChunk {
this.addToQueue();
}
parent.resetLighting(disableResult);
+ return this;
}
public void setBlock(Block block, int id, byte data) {
diff --git a/bukkit0/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_0.java b/bukkit0/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_0.java
index 6a5e97fc..79a5eb68 100644
--- a/bukkit0/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_0.java
+++ b/bukkit0/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_0.java
@@ -42,6 +42,15 @@ public abstract class BukkitQueue_0 extends NMSMa
}
}
+ public BukkitQueue_0(String world) {
+ super(world);
+ setupAdapter(null);
+ if (!registered) {
+ registered = true;
+ Bukkit.getServer().getPluginManager().registerEvents(this, ((FaweBukkit) Fawe.imp()).getPlugin());
+ }
+ }
+
@Override
public File getSaveFolder() {
return new File(Bukkit.getWorldContainer(), getWorldName() + File.separator + "region");
@@ -210,14 +219,4 @@ public abstract class BukkitQueue_0 extends NMSMa
try { Class.forName("org.spigotmc.AsyncCatcher").getField("enabled").set(null, true); } catch (Throwable ignore) {}
}
}
-
- @Override
- public FaweChunk getFaweChunk(int x, int z) {
- return new CharFaweChunk(this, x, z) {
- @Override
- public Chunk getNewChunk() {
- return BukkitQueue_0.this.getWorld().getChunkAt(getX(), getZ());
- }
- };
- }
}
diff --git a/bukkit0/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_All.java b/bukkit0/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_All.java
index 8edbbebe..44c69866 100644
--- a/bukkit0/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_All.java
+++ b/bukkit0/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_All.java
@@ -1,6 +1,5 @@
package com.boydti.fawe.bukkit.v0;
-import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.FaweChunk;
@@ -26,6 +25,16 @@ public class BukkitQueue_All extends BukkitQueue_0 {
if (Settings.QUEUE.EXTRA_TIME_MS != Integer.MIN_VALUE) {
ALLOCATE = Settings.QUEUE.EXTRA_TIME_MS;
Settings.QUEUE.EXTRA_TIME_MS = Integer.MIN_VALUE;
+ Settings.QUEUE.PARALLEL_THREADS = 1;
+ }
+ }
+
+ public BukkitQueue_All(String world) {
+ super(world);
+ if (Settings.QUEUE.EXTRA_TIME_MS != Integer.MIN_VALUE) {
+ ALLOCATE = Settings.QUEUE.EXTRA_TIME_MS;
+ Settings.QUEUE.EXTRA_TIME_MS = Integer.MIN_VALUE;
+ Settings.QUEUE.PARALLEL_THREADS = 1;
}
}
@@ -114,21 +123,6 @@ public class BukkitQueue_All extends BukkitQueue_0 {
private int skip;
- @Override
- public boolean setComponents(FaweChunk fc, RunnableVal changeTask) {
- if (skip > 0) {
- skip--;
- fc.addToQueue();
- return true;
- }
- long start = System.currentTimeMillis();
- ((BukkitChunk_All) fc).execute(start);
- if (System.currentTimeMillis() - start > 50 || Fawe.get().getTPS() < TPS_TARGET) {
- skip = 10;
- }
- return true;
- }
-
@Override
public void startSet(boolean parallel) {
super.startSet(true);
diff --git a/bukkit0/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncWorld.java b/bukkit0/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncWorld.java
index 3a6e0a55..3754cbbb 100644
--- a/bukkit0/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncWorld.java
+++ b/bukkit0/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncWorld.java
@@ -129,7 +129,7 @@ public class AsyncWorld implements World {
* @return
*/
public synchronized static AsyncWorld create(final WorldCreator creator) {
- BukkitQueue_0 queue = (BukkitQueue_0) SetQueue.IMP.getNewQueue(FaweAPI.getWorld(creator.name()), true, false);
+ BukkitQueue_0 queue = (BukkitQueue_0) SetQueue.IMP.getNewQueue(creator.name(), true, false);
World world = queue.createWorld(creator);
return wrap(world);
}
diff --git a/bukkit110/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitChunk_1_10.java b/bukkit110/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitChunk_1_10.java
index 999c3468..0fc62c25 100644
--- a/bukkit110/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitChunk_1_10.java
+++ b/bukkit110/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitChunk_1_10.java
@@ -1,20 +1,49 @@
package com.boydti.fawe.bukkit.v1_10;
+import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.example.CharFaweChunk;
+import com.boydti.fawe.object.BytePair;
+import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.util.MainUtil;
+import com.boydti.fawe.util.MathMan;
+import com.boydti.fawe.util.ReflectionUtils;
+import com.sk89q.jnbt.CompoundTag;
+import com.sk89q.jnbt.ListTag;
+import com.sk89q.jnbt.LongTag;
+import com.sk89q.jnbt.StringTag;
+import com.sk89q.jnbt.Tag;
+import com.sk89q.worldedit.internal.Constants;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
import net.minecraft.server.v1_10_R1.Block;
+import net.minecraft.server.v1_10_R1.BlockPosition;
+import net.minecraft.server.v1_10_R1.ChunkSection;
import net.minecraft.server.v1_10_R1.DataBits;
import net.minecraft.server.v1_10_R1.DataPalette;
import net.minecraft.server.v1_10_R1.DataPaletteBlock;
import net.minecraft.server.v1_10_R1.DataPaletteGlobal;
+import net.minecraft.server.v1_10_R1.Entity;
+import net.minecraft.server.v1_10_R1.EntityPlayer;
+import net.minecraft.server.v1_10_R1.EntityTypes;
import net.minecraft.server.v1_10_R1.IBlockData;
+import net.minecraft.server.v1_10_R1.NBTTagCompound;
+import net.minecraft.server.v1_10_R1.TileEntity;
import org.bukkit.Chunk;
+import org.bukkit.World;
+import org.bukkit.craftbukkit.v1_10_R1.CraftChunk;
+import org.bukkit.event.entity.CreatureSpawnEvent;
-public class BukkitChunk_1_10 extends CharFaweChunk {
+public class BukkitChunk_1_10 extends CharFaweChunk {
public DataPaletteBlock[] sectionPalettes;
@@ -35,7 +64,7 @@ public class BukkitChunk_1_10 extends CharFaweChunk {
}
@Override
- public CharFaweChunk copy(boolean shallow) {
+ public CharFaweChunk copy(boolean shallow) {
BukkitChunk_1_10 value = (BukkitChunk_1_10) super.copy(shallow);
if (sectionPalettes != null) {
value.sectionPalettes = new DataPaletteBlock[16];
@@ -125,4 +154,229 @@ public class BukkitChunk_1_10 extends CharFaweChunk {
}
}
}
+
+ @Override
+ public void start() {
+ getChunk().load(true);
+ }
+
+ @Override
+ public FaweChunk call() {
+ try {
+ final Chunk chunk = this.getChunk();
+ final World world = chunk.getWorld();
+ final boolean flag = world.getEnvironment() == World.Environment.NORMAL;
+ net.minecraft.server.v1_10_R1.Chunk nmsChunk = ((CraftChunk) chunk).getHandle();
+ nmsChunk.f(true); // Set Modified
+ nmsChunk.mustSave = true;
+ net.minecraft.server.v1_10_R1.World nmsWorld = nmsChunk.world;
+ ChunkSection[] sections = nmsChunk.getSections();
+ Class extends net.minecraft.server.v1_10_R1.Chunk> clazzChunk = nmsChunk.getClass();
+ final Collection[] entities = (Collection[]) getParent().getEntitySlices.invoke(nmsChunk);
+ Map tiles = nmsChunk.getTileEntities();
+ // Remove entities
+ for (int i = 0; i < entities.length; i++) {
+ int count = this.getCount(i);
+ if (count == 0) {
+ continue;
+ } else if (count >= 4096) {
+ entities[i].clear();
+ } else {
+ char[] array = this.getIdArray(i);
+ Collection ents = new ArrayList<>(entities[i]);
+ for (Entity entity : ents) {
+ if (entity instanceof EntityPlayer) {
+ continue;
+ }
+ int x = ((int) Math.round(entity.locX) & 15);
+ int z = ((int) Math.round(entity.locZ) & 15);
+ int y = (int) Math.round(entity.locY);
+ if (array == null || y < 0 || y > 255) {
+ continue;
+ }
+ if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][z][x]] != 0) {
+ nmsWorld.removeEntity(entity);
+ }
+ }
+ }
+ }
+ HashSet entsToRemove = this.getEntityRemoves();
+ if (entsToRemove.size() > 0) {
+ for (int i = 0; i < entities.length; i++) {
+ Collection ents = new ArrayList<>(entities[i]);
+ for (Entity entity : ents) {
+ if (entsToRemove.contains(entity.getUniqueID())) {
+ nmsWorld.removeEntity(entity);
+ }
+ }
+ }
+ }
+ // Set entities
+ Set createdEntities = new HashSet<>();
+ Set entitiesToSpawn = this.getEntities();
+ for (CompoundTag nativeTag : entitiesToSpawn) {
+ Map entityTagMap = ReflectionUtils.getMap(nativeTag.getValue());
+ StringTag idTag = (StringTag) entityTagMap.get("Id");
+ ListTag posTag = (ListTag) entityTagMap.get("Pos");
+ ListTag rotTag = (ListTag) entityTagMap.get("Rotation");
+ if (idTag == null || posTag == null || rotTag == null) {
+ Fawe.debug("Unknown entity tag: " + nativeTag);
+ continue;
+ }
+ double x = posTag.getDouble(0);
+ double y = posTag.getDouble(1);
+ double z = posTag.getDouble(2);
+ float yaw = rotTag.getFloat(0);
+ float pitch = rotTag.getFloat(1);
+ String id = idTag.getValue();
+ Entity entity = EntityTypes.createEntityByName(id, nmsWorld);
+ if (entity != null) {
+ UUID uuid = entity.getUniqueID();
+ entityTagMap.put("UUIDMost", new LongTag(uuid.getMostSignificantBits()));
+ entityTagMap.put("UUIDLeast", new LongTag(uuid.getLeastSignificantBits()));
+ if (nativeTag != null) {
+ NBTTagCompound tag = (NBTTagCompound) BukkitQueue_1_10.methodFromNative.invoke(BukkitQueue_1_10.adapter, nativeTag);
+ for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
+ tag.remove(name);
+ }
+ entity.f(tag);
+ }
+ entity.setLocation(x, y, z, yaw, pitch);
+ nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM);
+ createdEntities.add(entity.getUniqueID());
+ }
+ }
+ // Change task?
+ if (getParent().getChangeTask() != null) {
+ BukkitChunk_1_10 previous = getParent().getPrevious(this, sections, tiles, entities, createdEntities, false);
+ getParent().getChangeTask().run(previous, this);
+ }
+ // Trim tiles
+ Iterator> iterator = tiles.entrySet().iterator();
+ HashMap toRemove = null;
+ while (iterator.hasNext()) {
+ Map.Entry tile = iterator.next();
+ BlockPosition pos = tile.getKey();
+ int lx = pos.getX() & 15;
+ int ly = pos.getY();
+ int lz = pos.getZ() & 15;
+ int j = FaweCache.CACHE_I[ly][lz][lx];
+ char[] array = this.getIdArray(j);
+ if (array == null) {
+ continue;
+ }
+ int k = FaweCache.CACHE_J[ly][lz][lx];
+ if (array[k] != 0) {
+ if (toRemove == null) {
+ toRemove = new HashMap<>();
+ }
+ toRemove.put(tile.getKey(), tile.getValue());
+ }
+ }
+ if (toRemove != null) {
+ for (Map.Entry entry : toRemove.entrySet()) {
+ BlockPosition bp = entry.getKey();
+ TileEntity tile = entry.getValue();
+ tiles.remove(bp);
+ tile.y();
+ nmsWorld.s(bp);
+ tile.invalidateBlockCache();
+ }
+
+ }
+ // Set blocks
+ for (int j = 0; j < sections.length; j++) {
+ int count = this.getCount(j);
+ if (count == 0) {
+ continue;
+ }
+ final char[] array = this.getIdArray(j);
+ if (array == null) {
+ continue;
+ }
+ ChunkSection section = sections[j];
+ if (section == null) {
+ if (this.sectionPalettes != null && this.sectionPalettes[j] != null) {
+ section = sections[j] = getParent().newChunkSection(j << 4, flag, null);
+ getParent().setPalette(section, this.sectionPalettes[j]);
+ getParent().setCount(0, count - this.getAir(j), section);
+ continue;
+ } else {
+ sections[j] = getParent().newChunkSection(j << 4, flag, array);
+ }
+ continue;
+ } else if (count >= 4096) {
+ if (this.sectionPalettes != null && this.sectionPalettes[j] != null) {
+ getParent().setPalette(section, this.sectionPalettes[j]);
+ getParent().setCount(0, count - this.getAir(j), section);
+ continue;
+ } else {
+ sections[j] = getParent().newChunkSection(j << 4, flag, array);
+ }
+ continue;
+ }
+ DataPaletteBlock nibble = section.getBlocks();
+ int nonEmptyBlockCount = 0;
+ for (int y = 0; y < 16; y++) {
+ short[][] i1 = FaweCache.CACHE_J[y];
+ for (int z = 0; z < 16; z++) {
+ short[] i2 = i1[z];
+ for (int x= 0; x < 16; x++) {
+ char combinedId = array[i2[x]];
+ switch (combinedId) {
+ case 0:
+ IBlockData existing = nibble.a(x, y, z);
+ if (existing != BukkitQueue_1_10.air) {
+ nonEmptyBlockCount++;
+ }
+ continue;
+ case 1:
+ nibble.setBlock(x, y, z, BukkitQueue_1_10.air);
+ continue;
+ default:
+ nonEmptyBlockCount++;
+ nibble.setBlock(x, y, z, getParent().IBD_CACHE[(int) combinedId]);
+ }
+ }
+ }
+ }
+ getParent().setCount(0, nonEmptyBlockCount, section);
+ }
+ // Set biomes
+ int[][] biomes = this.biomes;
+ if (biomes != null) {
+ for (int x = 0; x < 16; x++) {
+ int[] array = biomes[x];
+ if (array == null) {
+ continue;
+ }
+ for (int z = 0; z < 16; z++) {
+ int biome = array[z];
+ if (biome == 0) {
+ continue;
+ }
+ nmsChunk.getBiomeIndex()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome;
+ }
+ }
+ }
+ // Set tiles
+ Map tilesToSpawn = this.getTiles();
+ int bx = this.getX() << 4;
+ int bz = this.getZ() << 4;
+
+ for (Map.Entry entry : tilesToSpawn.entrySet()) {
+ CompoundTag nativeTag = entry.getValue();
+ BytePair pair = entry.getKey();
+ BlockPosition pos = new BlockPosition(MathMan.unpair16x((byte) pair.get0()) + bx, pair.get1() & 0xFF, MathMan.unpair16y((byte) pair.get0()) + bz); // Set pos
+ TileEntity tileEntity = nmsWorld.getTileEntity(pos);
+ if (tileEntity != null) {
+ NBTTagCompound tag = (NBTTagCompound) BukkitQueue_1_10.methodFromNative.invoke(BukkitQueue_1_10.adapter, nativeTag);
+ tileEntity.a(tag); // ReadTagIntoTile
+ }
+ }
+ } catch (Throwable e) {
+ MainUtil.handleError(e);
+ }
+ return this;
+ }
}
diff --git a/bukkit110/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitMain_110.java b/bukkit110/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitMain_110.java
index 5dd09b73..a062d1cd 100644
--- a/bukkit110/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitMain_110.java
+++ b/bukkit110/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitMain_110.java
@@ -3,6 +3,7 @@ package com.boydti.fawe.bukkit.v1_10;
import com.boydti.fawe.bukkit.ABukkitMain;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
import com.boydti.fawe.config.Settings;
+import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.io.BufferedRandomAccessFile;
import com.boydti.fawe.object.io.FastByteArrayInputStream;
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
@@ -31,6 +32,11 @@ public class BukkitMain_110 extends ABukkitMain {
return new BukkitQueue_1_10(world);
}
+ @Override
+ public FaweQueue getQueue(String world) {
+ return new BukkitQueue_1_10(world);
+ }
+
@Override
public void onEnable() {
super.onEnable();
diff --git a/bukkit110/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitQueue_1_10.java b/bukkit110/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitQueue_1_10.java
index 23d364bf..d882f39d 100644
--- a/bukkit110/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitQueue_1_10.java
+++ b/bukkit110/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitQueue_1_10.java
@@ -4,7 +4,6 @@ import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
import com.boydti.fawe.example.CharFaweChunk;
-import com.boydti.fawe.object.BytePair;
import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.util.MainUtil;
@@ -12,26 +11,19 @@ import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.ReflectionUtils;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.jnbt.CompoundTag;
-import com.sk89q.jnbt.ListTag;
-import com.sk89q.jnbt.LongTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
-import com.sk89q.worldedit.internal.Constants;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
+import java.util.concurrent.ExecutorCompletionService;
import net.minecraft.server.v1_10_R1.Block;
import net.minecraft.server.v1_10_R1.BlockPosition;
import net.minecraft.server.v1_10_R1.ChunkSection;
@@ -62,26 +54,33 @@ import net.minecraft.server.v1_10_R1.WorldType;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
-import org.bukkit.World.Environment;
import org.bukkit.WorldCreator;
import org.bukkit.craftbukkit.v1_10_R1.CraftChunk;
import org.bukkit.craftbukkit.v1_10_R1.CraftServer;
import org.bukkit.craftbukkit.v1_10_R1.CraftWorld;
-import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.world.WorldInitEvent;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.generator.ChunkGenerator;
public class BukkitQueue_1_10 extends BukkitQueue_0 {
- private static IBlockData air;
- private static Field fieldBits;
- private static Method getEntitySlices;
+ protected static IBlockData air;
+ protected static Field fieldBits;
+ protected static Method getEntitySlices;
public static final IBlockData[] IBD_CACHE = new IBlockData[Character.MAX_VALUE];
public BukkitQueue_1_10(final com.sk89q.worldedit.world.World world) {
super(world);
+ init();
+ }
+
+ public BukkitQueue_1_10(final String world) {
+ super(world);
+ init();
+ }
+
+ private void init() {
checkVersion("v1_10_R1");
if (air == null) {
try {
@@ -108,6 +107,11 @@ public class BukkitQueue_1_10 extends BukkitQueue_0 tilesGeneric, Collection>[] entitiesGeneric, Set createdEntities, boolean all) throws Exception {
+ public BukkitChunk_1_10 getPrevious(CharFaweChunk fs, ChunkSection[] sections, Map, ?> tilesGeneric, Collection>[] entitiesGeneric, Set createdEntities, boolean all) throws Exception {
Map tiles = (Map) tilesGeneric;
Collection[] entities = (Collection[]) entitiesGeneric;
- CharFaweChunk previous = (CharFaweChunk) getFaweChunk(fs.getX(), fs.getZ());
+ BukkitChunk_1_10 previous = getFaweChunk(fs.getX(), fs.getZ());
// Copy blocks
char[][] idPrevious = new char[16][];
for (int layer = 0; layer < sections.length; layer++) {
@@ -481,7 +485,7 @@ public class BukkitQueue_1_10 extends BukkitQueue_0 changeTask) {
- final com.boydti.fawe.bukkit.v1_10.BukkitChunk_1_10 fs = (com.boydti.fawe.bukkit.v1_10.BukkitChunk_1_10) fc;
- final Chunk chunk = (Chunk) fs.getChunk();
- final World world = chunk.getWorld();
- chunk.load(true);
- try {
- final boolean flag = world.getEnvironment() == Environment.NORMAL;
- net.minecraft.server.v1_10_R1.Chunk nmsChunk = ((CraftChunk) chunk).getHandle();
- nmsChunk.f(true); // Set Modified
- nmsChunk.mustSave = true;
- net.minecraft.server.v1_10_R1.World nmsWorld = nmsChunk.world;
- ChunkSection[] sections = nmsChunk.getSections();
- Class extends net.minecraft.server.v1_10_R1.Chunk> clazzChunk = nmsChunk.getClass();
- final Collection[] entities = (Collection[]) getEntitySlices.invoke(nmsChunk);
- Map tiles = nmsChunk.getTileEntities();
- // Remove entities
- for (int i = 0; i < entities.length; i++) {
- int count = fs.getCount(i);
- if (count == 0) {
- continue;
- } else if (count >= 4096) {
- entities[i].clear();
- } else {
- char[] array = fs.getIdArray(i);
- Collection ents = new ArrayList<>(entities[i]);
- for (Entity entity : ents) {
- if (entity instanceof EntityPlayer) {
- continue;
- }
- int x = ((int) Math.round(entity.locX) & 15);
- int z = ((int) Math.round(entity.locZ) & 15);
- int y = (int) Math.round(entity.locY);
- if (array == null || y < 0 || y > 255) {
- continue;
- }
- if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][z][x]] != 0) {
- nmsWorld.removeEntity(entity);
- }
- }
- }
- }
- HashSet entsToRemove = fs.getEntityRemoves();
- if (entsToRemove.size() > 0) {
- for (int i = 0; i < entities.length; i++) {
- Collection ents = new ArrayList<>(entities[i]);
- for (Entity entity : ents) {
- if (entsToRemove.contains(entity.getUniqueID())) {
- nmsWorld.removeEntity(entity);
- }
- }
- }
- }
- // Set entities
- Set createdEntities = new HashSet<>();
- Set entitiesToSpawn = fs.getEntities();
- for (CompoundTag nativeTag : entitiesToSpawn) {
- Map entityTagMap = ReflectionUtils.getMap(nativeTag.getValue());
- StringTag idTag = (StringTag) entityTagMap.get("Id");
- ListTag posTag = (ListTag) entityTagMap.get("Pos");
- ListTag rotTag = (ListTag) entityTagMap.get("Rotation");
- if (idTag == null || posTag == null || rotTag == null) {
- Fawe.debug("Unknown entity tag: " + nativeTag);
- continue;
- }
- double x = posTag.getDouble(0);
- double y = posTag.getDouble(1);
- double z = posTag.getDouble(2);
- float yaw = rotTag.getFloat(0);
- float pitch = rotTag.getFloat(1);
- String id = idTag.getValue();
- Entity entity = EntityTypes.createEntityByName(id, nmsWorld);
- if (entity != null) {
- UUID uuid = entity.getUniqueID();
- entityTagMap.put("UUIDMost", new LongTag(uuid.getMostSignificantBits()));
- entityTagMap.put("UUIDLeast", new LongTag(uuid.getLeastSignificantBits()));
- if (nativeTag != null) {
- NBTTagCompound tag = (NBTTagCompound) methodFromNative.invoke(adapter, nativeTag);
- for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
- tag.remove(name);
- }
- entity.f(tag);
- }
- entity.setLocation(x, y, z, yaw, pitch);
- nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM);
- createdEntities.add(entity.getUniqueID());
- }
- }
- // Change task?
- if (changeTask != null) {
- CharFaweChunk previous = getPrevious(fs, sections, tiles, entities, createdEntities, false);
- changeTask.run(previous);
- }
- // Trim tiles
- Iterator> iterator = tiles.entrySet().iterator();
- HashMap toRemove = null;
- while (iterator.hasNext()) {
- Map.Entry tile = iterator.next();
- BlockPosition pos = tile.getKey();
- int lx = pos.getX() & 15;
- int ly = pos.getY();
- int lz = pos.getZ() & 15;
- int j = FaweCache.CACHE_I[ly][lz][lx];
- char[] array = fs.getIdArray(j);
- if (array == null) {
- continue;
- }
- int k = FaweCache.CACHE_J[ly][lz][lx];
- if (array[k] != 0) {
- if (toRemove == null) {
- toRemove = new HashMap<>();
- }
- toRemove.put(tile.getKey(), tile.getValue());
- }
- }
- if (toRemove != null) {
- for (Entry entry : toRemove.entrySet()) {
- BlockPosition bp = entry.getKey();
- TileEntity tile = entry.getValue();
- tiles.remove(bp);
- tile.y();
- nmsWorld.s(bp);
- tile.invalidateBlockCache();
- }
-
- }
- // Set blocks
- for (int j = 0; j < sections.length; j++) {
- int count = fs.getCount(j);
- if (count == 0) {
- continue;
- }
- final char[] array = fs.getIdArray(j);
- if (array == null) {
- continue;
- }
- ChunkSection section = sections[j];
- if (section == null) {
- if (fs.sectionPalettes != null && fs.sectionPalettes[j] != null) {
- section = sections[j] = newChunkSection(j << 4, flag, null);
- setPalette(section, fs.sectionPalettes[j]);
- setCount(0, count - fs.getAir(j), section);
- continue;
- } else {
- sections[j] = newChunkSection(j << 4, flag, array);
- }
- continue;
- } else if (count >= 4096) {
- if (fs.sectionPalettes != null && fs.sectionPalettes[j] != null) {
- setPalette(section, fs.sectionPalettes[j]);
- setCount(0, count - fs.getAir(j), section);
- continue;
- } else {
- sections[j] = newChunkSection(j << 4, flag, array);
- }
- continue;
- }
- DataPaletteBlock nibble = section.getBlocks();
- int nonEmptyBlockCount = 0;
- for (int y = 0; y < 16; y++) {
- short[][] i1 = FaweCache.CACHE_J[y];
- for (int z = 0; z < 16; z++) {
- short[] i2 = i1[z];
- for (int x= 0; x < 16; x++) {
- char combinedId = array[i2[x]];
- switch (combinedId) {
- case 0:
- IBlockData existing = nibble.a(x, y, z);
- if (existing != air) {
- nonEmptyBlockCount++;
- }
- continue;
- case 1:
- nibble.setBlock(x, y, z, air);
- continue;
- default:
- nonEmptyBlockCount++;
- nibble.setBlock(x, y, z, IBD_CACHE[(int) combinedId]);
- }
- }
- }
- }
- setCount(0, nonEmptyBlockCount, section);
- }
- // Set biomes
- int[][] biomes = fs.biomes;
- if (biomes != null) {
- for (int x = 0; x < 16; x++) {
- int[] array = biomes[x];
- if (array == null) {
- continue;
- }
- for (int z = 0; z < 16; z++) {
- int biome = array[z];
- if (biome == 0) {
- continue;
- }
- nmsChunk.getBiomeIndex()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome;
- }
- }
- }
- // Set tiles
- Map tilesToSpawn = fs.getTiles();
- int bx = fs.getX() << 4;
- int bz = fs.getZ() << 4;
-
- for (Map.Entry entry : tilesToSpawn.entrySet()) {
- CompoundTag nativeTag = entry.getValue();
- BytePair pair = entry.getKey();
- BlockPosition pos = new BlockPosition(MathMan.unpair16x((byte) pair.get0()) + bx, pair.get1() & 0xFF, MathMan.unpair16y((byte) pair.get0()) + bz); // Set pos
- TileEntity tileEntity = nmsWorld.getTileEntity(pos);
- if (tileEntity != null) {
- NBTTagCompound tag = (NBTTagCompound) methodFromNative.invoke(adapter, nativeTag);
- tileEntity.a(tag); // ReadTagIntoTile
- }
- }
- } catch (Throwable e) {
- MainUtil.handleError(e);
- }
- return true;
- }
-
@Deprecated
public boolean unloadChunk(final String world, final Chunk chunk) {
net.minecraft.server.v1_10_R1.Chunk c = ((CraftChunk) chunk).getHandle();
@@ -740,7 +522,7 @@ public class BukkitQueue_1_10 extends BukkitQueue_0 {
+public class BukkitChunk_1_7 extends CharFaweChunk {
@Override
public Chunk getNewChunk() {
@@ -87,7 +114,7 @@ public class BukkitChunk_1_7 extends CharFaweChunk {
}
@Override
- public CharFaweChunk copy(boolean shallow) {
+ public BukkitChunk_1_7 copy(boolean shallow) {
BukkitChunk_1_7 copy = new BukkitChunk_1_7(getParent(), getX(), getZ());
if (shallow) {
copy.byteIds = byteIds;
@@ -108,4 +135,232 @@ public class BukkitChunk_1_7 extends CharFaweChunk {
}
return copy;
}
+
+ @Override
+ public void start() {
+ getChunk().load(true);
+ }
+
+ @Override
+ public FaweChunk call() {
+ CraftChunk chunk = (CraftChunk) this.getChunk();
+ net.minecraft.server.v1_7_R4.Chunk nmsChunk = chunk.getHandle();
+ nmsChunk.e(); // Modified
+ nmsChunk.mustSave = true;
+ net.minecraft.server.v1_7_R4.World nmsWorld = nmsChunk.world;
+ try {
+ final boolean flag = getParent().getWorld().getEnvironment() == World.Environment.NORMAL;
+ // Sections
+ ChunkSection[] sections = nmsChunk.getSections();
+ Map tiles = nmsChunk.tileEntities;
+ Collection[] entities = nmsChunk.entitySlices;
+
+ // Remove entities
+ for (int i = 0; i < 16; i++) {
+ int count = this.getCount(i);
+ if (count == 0) {
+ continue;
+ } else if (count >= 4096) {
+ entities[i].clear();
+ } else {
+ char[] array = this.getIdArray(i);
+ Collection ents = new ArrayList<>(entities[i]);
+ for (Entity entity : ents) {
+ if (entity instanceof EntityPlayer) {
+ continue;
+ }
+ int x = ((int) Math.round(entity.locX) & 15);
+ int z = ((int) Math.round(entity.locZ) & 15);
+ int y = (int) Math.round(entity.locY);
+ if (array == null) {
+ continue;
+ }
+ if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][z][x]] != 0) {
+ nmsWorld.removeEntity(entity);
+ }
+ }
+ }
+ }
+ // Set entities
+ Set createdEntities = new HashSet<>();
+ Set entitiesToSpawn = this.getEntities();
+ for (CompoundTag nativeTag : entitiesToSpawn) {
+ Map entityTagMap = nativeTag.getValue();
+ StringTag idTag = (StringTag) entityTagMap.get("Id");
+ ListTag posTag = (ListTag) entityTagMap.get("Pos");
+ ListTag rotTag = (ListTag) entityTagMap.get("Rotation");
+ if (idTag == null || posTag == null || rotTag == null) {
+ Fawe.debug("Unknown entity tag: " + nativeTag);
+ continue;
+ }
+ double x = posTag.getDouble(0);
+ double y = posTag.getDouble(1);
+ double z = posTag.getDouble(2);
+ float yaw = rotTag.getFloat(0);
+ float pitch = rotTag.getFloat(1);
+ String id = idTag.getValue();
+ Entity entity = EntityTypes.createEntityByName(id, nmsWorld);
+ if (entity != null) {
+ if (nativeTag != null) {
+ NBTTagCompound tag = (NBTTagCompound) BukkitQueue17.methodFromNative.invoke(BukkitQueue17.adapter, nativeTag);
+ for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
+ tag.remove(name);
+ }
+ entity.f(tag);
+ }
+ entity.setLocation(x, y, z, yaw, pitch);
+ nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM);
+ createdEntities.add(entity.getUniqueID());
+ }
+ }
+ // Run change task if applicable
+ if (getParent().getChangeTask() != null) {
+ CharFaweChunk previous = getParent().getPrevious(this, sections, tiles, entities, createdEntities, false);
+ getParent().getChangeTask().run(previous, this);
+ }
+ // Trim tiles
+ Iterator> iterator = tiles.entrySet().iterator();
+ HashMap toRemove = null;
+ while (iterator.hasNext()) {
+ Map.Entry tile = iterator.next();
+ ChunkPosition pos = tile.getKey();
+ int lx = pos.x & 15;
+ int ly = pos.y;
+ int lz = pos.z & 15;
+ int j = FaweCache.CACHE_I[ly][lz][lx];
+ char[] array = this.getIdArray(j);
+ if (array == null) {
+ continue;
+ }
+ int k = FaweCache.CACHE_J[ly][lz][lx];
+ if (array[k] != 0) {
+ if (toRemove == null) {
+ toRemove = new HashMap<>();
+ }
+ toRemove.put(tile.getKey(), tile.getValue());
+ }
+ }
+ if (toRemove != null) {
+ for (Map.Entry entry : toRemove.entrySet()) {
+ ChunkPosition bp = entry.getKey();
+ TileEntity tile = entry.getValue();
+ tiles.remove(bp);
+ tile.s();
+ nmsWorld.p(bp.x, bp.y, bp.z);
+ tile.u();
+ }
+
+ }
+ HashSet entsToRemove = this.getEntityRemoves();
+ if (entsToRemove.size() > 0) {
+ for (int i = 0; i < entities.length; i++) {
+ Collection ents = new ArrayList<>(entities[i]);
+ for (Entity entity : ents) {
+ if (entsToRemove.contains(entity.getUniqueID())) {
+ nmsWorld.removeEntity(entity);
+ }
+ }
+ }
+ }
+ // Set blocks
+ for (int j = 0; j < sections.length; j++) {
+ if (this.getCount(j) == 0) {
+ continue;
+ }
+ byte[] newIdArray = this.getByteIdArray(j);
+ if (newIdArray == null) {
+ continue;
+ }
+ NibbleArray newDataArray = this.getDataArray(j);
+ ChunkSection section = sections[j];
+ if ((section == null) || (this.getCount(j) >= 4096)) {
+ sections[j] = section = new ChunkSection(j << 4, flag);
+ section.setIdArray(newIdArray);
+ if (newDataArray != null) {
+ section.setDataArray(newDataArray);
+ }
+ continue;
+ }
+ byte[] currentIdArray = (byte[]) BukkitQueue17.fieldIds.get(section);
+ NibbleArray currentDataArray = (NibbleArray) BukkitQueue17.fieldData.get(section);
+ boolean data = currentDataArray != null && newDataArray != null;
+ if (!data) {
+ section.setDataArray(newDataArray);
+ }
+ if (currentIdArray == null) {
+ section.setIdArray(newIdArray);
+ continue;
+ }
+ boolean fill = true;
+ int solid = 0;
+ char[] charArray = this.getIdArray(j);
+ for (int k = 0; k < newIdArray.length; k++) {
+ char combined = charArray[k];
+ switch (combined) {
+ case 0:
+ fill = false;
+ continue;
+ case 1:
+ fill = false;
+ if (currentIdArray[k] != 0) {
+ solid++;
+ }
+ currentIdArray[k] = 0;
+ continue;
+ default:
+ solid++;
+ currentIdArray[k] = newIdArray[k];
+ if (data) {
+ int dataByte = FaweCache.getData(combined);
+ int x = FaweCache.CACHE_X[0][k];
+ int y = FaweCache.CACHE_Y[0][k];
+ int z = FaweCache.CACHE_Z[0][k];
+ int newData = newDataArray.a(x, y, z);
+ currentDataArray.a(x, y, z, newData);
+ }
+ continue;
+ }
+ }
+ getParent().setCount(0, solid, section);
+ if (fill) {
+ this.setCount(j, Short.MAX_VALUE);
+ }
+ }
+
+ // Set biomes
+ int[][] biomes = this.biomes;
+ if (biomes != null) {
+ for (int x = 0; x < 16; x++) {
+ int[] array = biomes[x];
+ if (array == null) {
+ continue;
+ }
+ for (int z = 0; z < 16; z++) {
+ int biome = array[z];
+ if (biome == 0) {
+ continue;
+ }
+ nmsChunk.m()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome; // Biome array
+ }
+ }
+ }
+ // Set tiles
+ Map tilesToSpawn = this.getTiles();
+ int bx = this.getX() << 4;
+ int bz = this.getZ() << 4;
+
+ for (Map.Entry entry : tilesToSpawn.entrySet()) {
+ CompoundTag nativeTag = entry.getValue();
+ BytePair pair = entry.getKey();
+ TileEntity tileEntity = nmsWorld.getTileEntity(MathMan.unpair16x((byte) pair.get0()) + bx, pair.get1() & 0xFF, MathMan.unpair16y((byte) pair.get0()) + bz);
+ if (tileEntity != null) {
+ NBTTagCompound tag = (NBTTagCompound) BukkitQueue17.methodFromNative.invoke(BukkitQueue17.adapter, nativeTag);
+ tileEntity.a(tag); // ReadTagIntoTile
+ }
+ }
+ } catch (Throwable e) {
+ MainUtil.handleError(e);
+ }
+ return this;
+ }
}
diff --git a/bukkit1710/src/main/java/com/boydti/fawe/bukkit/v1_7/BukkitMain_17.java b/bukkit1710/src/main/java/com/boydti/fawe/bukkit/v1_7/BukkitMain_17.java
index d6dc0dc0..ef93dd81 100644
--- a/bukkit1710/src/main/java/com/boydti/fawe/bukkit/v1_7/BukkitMain_17.java
+++ b/bukkit1710/src/main/java/com/boydti/fawe/bukkit/v1_7/BukkitMain_17.java
@@ -2,6 +2,7 @@ package com.boydti.fawe.bukkit.v1_7;
import com.boydti.fawe.bukkit.ABukkitMain;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
+import com.boydti.fawe.object.FaweQueue;
import com.sk89q.worldedit.world.World;
public class BukkitMain_17 extends ABukkitMain {
@@ -10,4 +11,9 @@ public class BukkitMain_17 extends ABukkitMain {
public BukkitQueue_0 getQueue(World world) {
return new BukkitQueue17(world);
}
+
+ @Override
+ public FaweQueue getQueue(String world) {
+ return new BukkitQueue17(world);
+ }
}
diff --git a/bukkit1710/src/main/java/com/boydti/fawe/bukkit/v1_7/BukkitQueue17.java b/bukkit1710/src/main/java/com/boydti/fawe/bukkit/v1_7/BukkitQueue17.java
index 7083a128..3f384ad2 100644
--- a/bukkit1710/src/main/java/com/boydti/fawe/bukkit/v1_7/BukkitQueue17.java
+++ b/bukkit1710/src/main/java/com/boydti/fawe/bukkit/v1_7/BukkitQueue17.java
@@ -1,10 +1,8 @@
package com.boydti.fawe.bukkit.v1_7;
-import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
import com.boydti.fawe.example.CharFaweChunk;
-import com.boydti.fawe.object.BytePair;
import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.util.MainUtil;
@@ -12,19 +10,14 @@ import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.ReflectionUtils;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.jnbt.CompoundTag;
-import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
-import com.sk89q.worldedit.internal.Constants;
import java.io.File;
import java.lang.reflect.Field;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -59,18 +52,26 @@ import org.bukkit.WorldCreator;
import org.bukkit.craftbukkit.v1_7_R4.CraftChunk;
import org.bukkit.craftbukkit.v1_7_R4.CraftServer;
import org.bukkit.craftbukkit.v1_7_R4.CraftWorld;
-import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.world.WorldInitEvent;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.generator.ChunkGenerator;
public class BukkitQueue17 extends BukkitQueue_0 {
- private static Field fieldData;
- private static Field fieldIds;
+ protected static Field fieldData;
+ protected static Field fieldIds;
public BukkitQueue17(final com.sk89q.worldedit.world.World world) {
super(world);
+ init();
+ }
+
+ public BukkitQueue17(final String world) {
+ super(world);
+ init();
+ }
+
+ private void init() {
checkVersion("v1_7_R4");
if (fieldData == null) {
try {
@@ -236,230 +237,6 @@ public class BukkitQueue17 extends BukkitQueue_0 changeTask) {
- BukkitChunk_1_7 fs = (BukkitChunk_1_7) fc;
- CraftChunk chunk = (CraftChunk) fs.getChunk();
- net.minecraft.server.v1_7_R4.Chunk nmsChunk = chunk.getHandle();
- nmsChunk.e(); // Modified
- nmsChunk.mustSave = true;
- net.minecraft.server.v1_7_R4.World nmsWorld = nmsChunk.world;
- try {
- final boolean flag = getWorld().getEnvironment() == World.Environment.NORMAL;
- // Sections
- ChunkSection[] sections = nmsChunk.getSections();
- Map tiles = nmsChunk.tileEntities;
- Collection[] entities = nmsChunk.entitySlices;
-
- // Remove entities
- for (int i = 0; i < 16; i++) {
- int count = fs.getCount(i);
- if (count == 0) {
- continue;
- } else if (count >= 4096) {
- entities[i].clear();
- } else {
- char[] array = fs.getIdArray(i);
- Collection ents = new ArrayList<>(entities[i]);
- for (Entity entity : ents) {
- if (entity instanceof EntityPlayer) {
- continue;
- }
- int x = ((int) Math.round(entity.locX) & 15);
- int z = ((int) Math.round(entity.locZ) & 15);
- int y = (int) Math.round(entity.locY);
- if (array == null) {
- continue;
- }
- if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][z][x]] != 0) {
- nmsWorld.removeEntity(entity);
- }
- }
- }
- }
- // Set entities
- Set createdEntities = new HashSet<>();
- Set entitiesToSpawn = fs.getEntities();
- for (CompoundTag nativeTag : entitiesToSpawn) {
- Map entityTagMap = nativeTag.getValue();
- StringTag idTag = (StringTag) entityTagMap.get("Id");
- ListTag posTag = (ListTag) entityTagMap.get("Pos");
- ListTag rotTag = (ListTag) entityTagMap.get("Rotation");
- if (idTag == null || posTag == null || rotTag == null) {
- Fawe.debug("Unknown entity tag: " + nativeTag);
- continue;
- }
- double x = posTag.getDouble(0);
- double y = posTag.getDouble(1);
- double z = posTag.getDouble(2);
- float yaw = rotTag.getFloat(0);
- float pitch = rotTag.getFloat(1);
- String id = idTag.getValue();
- Entity entity = EntityTypes.createEntityByName(id, nmsWorld);
- if (entity != null) {
- if (nativeTag != null) {
- NBTTagCompound tag = (NBTTagCompound)methodFromNative.invoke(adapter, nativeTag);
- for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
- tag.remove(name);
- }
- entity.f(tag);
- }
- entity.setLocation(x, y, z, yaw, pitch);
- nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM);
- createdEntities.add(entity.getUniqueID());
- }
- }
- // Run change task if applicable
- if (changeTask != null) {
- CharFaweChunk previous = getPrevious(fs, sections, tiles, entities, createdEntities, false);
- changeTask.run(previous);
- }
- // Trim tiles
- Iterator> iterator = tiles.entrySet().iterator();
- HashMap toRemove = null;
- while (iterator.hasNext()) {
- Map.Entry tile = iterator.next();
- ChunkPosition pos = tile.getKey();
- int lx = pos.x & 15;
- int ly = pos.y;
- int lz = pos.z & 15;
- int j = FaweCache.CACHE_I[ly][lz][lx];
- char[] array = fs.getIdArray(j);
- if (array == null) {
- continue;
- }
- int k = FaweCache.CACHE_J[ly][lz][lx];
- if (array[k] != 0) {
- if (toRemove == null) {
- toRemove = new HashMap<>();
- }
- toRemove.put(tile.getKey(), tile.getValue());
- }
- }
- if (toRemove != null) {
- for (Map.Entry entry : toRemove.entrySet()) {
- ChunkPosition bp = entry.getKey();
- TileEntity tile = entry.getValue();
- tiles.remove(bp);
- tile.s();
- nmsWorld.p(bp.x, bp.y, bp.z);
- tile.u();
- }
-
- }
- HashSet entsToRemove = fs.getEntityRemoves();
- if (entsToRemove.size() > 0) {
- for (int i = 0; i < entities.length; i++) {
- Collection ents = new ArrayList<>(entities[i]);
- for (Entity entity : ents) {
- if (entsToRemove.contains(entity.getUniqueID())) {
- nmsWorld.removeEntity(entity);
- }
- }
- }
- }
- // Set blocks
- for (int j = 0; j < sections.length; j++) {
- if (fs.getCount(j) == 0) {
- continue;
- }
- byte[] newIdArray = fs.getByteIdArray(j);
- if (newIdArray == null) {
- continue;
- }
- NibbleArray newDataArray = fs.getDataArray(j);
- ChunkSection section = sections[j];
- if ((section == null) || (fs.getCount(j) >= 4096)) {
- sections[j] = section = new ChunkSection(j << 4, flag);
- section.setIdArray(newIdArray);
- if (newDataArray != null) {
- section.setDataArray(newDataArray);
- }
- continue;
- }
- byte[] currentIdArray = (byte[]) fieldIds.get(section);
- NibbleArray currentDataArray = (NibbleArray) fieldData.get(section);
- boolean data = currentDataArray != null && newDataArray != null;
- if (!data) {
- section.setDataArray(newDataArray);
- }
- if (currentIdArray == null) {
- section.setIdArray(newIdArray);
- continue;
- }
- boolean fill = true;
- int solid = 0;
- char[] charArray = fs.getIdArray(j);
- for (int k = 0; k < newIdArray.length; k++) {
- char combined = charArray[k];
- switch (combined) {
- case 0:
- fill = false;
- continue;
- case 1:
- fill = false;
- if (currentIdArray[k] != 0) {
- solid++;
- }
- currentIdArray[k] = 0;
- continue;
- default:
- solid++;
- currentIdArray[k] = newIdArray[k];
- if (data) {
- int dataByte = FaweCache.getData(combined);
- int x = FaweCache.CACHE_X[0][k];
- int y = FaweCache.CACHE_Y[0][k];
- int z = FaweCache.CACHE_Z[0][k];
- int newData = newDataArray.a(x, y, z);
- currentDataArray.a(x, y, z, newData);
- }
- continue;
- }
- }
- setCount(0, solid, section);
- if (fill) {
- fs.setCount(j, Short.MAX_VALUE);
- }
- }
-
- // Set biomes
- int[][] biomes = fs.biomes;
- if (biomes != null) {
- for (int x = 0; x < 16; x++) {
- int[] array = biomes[x];
- if (array == null) {
- continue;
- }
- for (int z = 0; z < 16; z++) {
- int biome = array[z];
- if (biome == 0) {
- continue;
- }
- nmsChunk.m()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome; // Biome array
- }
- }
- }
- // Set tiles
- Map tilesToSpawn = fs.getTiles();
- int bx = fs.getX() << 4;
- int bz = fs.getZ() << 4;
-
- for (Map.Entry entry : tilesToSpawn.entrySet()) {
- CompoundTag nativeTag = entry.getValue();
- BytePair pair = entry.getKey();
- TileEntity tileEntity = nmsWorld.getTileEntity(MathMan.unpair16x((byte) pair.get0()) + bx, pair.get1() & 0xFF, MathMan.unpair16y((byte) pair.get0()) + bz);
- if (tileEntity != null) {
- NBTTagCompound tag = (NBTTagCompound) methodFromNative.invoke(adapter, nativeTag);
- tileEntity.a(tag); // ReadTagIntoTile
- }
- }
- } catch (Throwable e) {
- MainUtil.handleError(e);
- }
- return true;
- }
-
public void setCount(int tickingBlockCount, int nonEmptyBlockCount, ChunkSection section) throws NoSuchFieldException, IllegalAccessException {
Class extends ChunkSection> clazz = section.getClass();
Field fieldTickingBlockCount = clazz.getDeclaredField("tickingBlockCount");
@@ -625,7 +402,7 @@ public class BukkitQueue17 extends BukkitQueue_0 {
+public class BukkitChunk_1_8 extends CharFaweChunk {
/**
* A FaweSections object represents a chunk and the blocks that you wish to change in it.
*
@@ -21,4 +49,208 @@ public class BukkitChunk_1_8 extends CharFaweChunk {
public Chunk getNewChunk() {
return Bukkit.getWorld(getParent().getWorldName()).getChunkAt(getX(), getZ());
}
+
+ @Override
+ public void start() {
+ getChunk().load(true);
+ }
+
+ @Override
+ public FaweChunk call() {
+ CraftChunk chunk = (CraftChunk) this.getChunk();
+ net.minecraft.server.v1_8_R3.Chunk nmsChunk = chunk.getHandle();
+ nmsChunk.f(true); // Modified
+ nmsChunk.mustSave = true;
+ net.minecraft.server.v1_8_R3.World nmsWorld = nmsChunk.getWorld();
+ try {
+ final boolean flag = getParent().getWorld().getEnvironment() == World.Environment.NORMAL;
+ // Sections
+ ChunkSection[] sections = nmsChunk.getSections();
+ Map tiles = nmsChunk.getTileEntities();
+ Collection[] entities = nmsChunk.getEntitySlices();
+
+ // Remove entities
+ for (int i = 0; i < 16; i++) {
+ int count = this.getCount(i);
+ if (count == 0) {
+ continue;
+ } else if (count >= 4096) {
+ entities[i].clear();
+ } else {
+ char[] array = this.getIdArray(i);
+ Collection ents = new ArrayList<>(entities[i]);
+ for (Entity entity : ents) {
+ if (entity instanceof EntityPlayer) {
+ continue;
+ }
+ int x = ((int) Math.round(entity.locX) & 15);
+ int z = ((int) Math.round(entity.locZ) & 15);
+ int y = (int) Math.round(entity.locY);
+ if (array == null) {
+ continue;
+ }
+ if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][z][x]] != 0) {
+ nmsWorld.removeEntity(entity);
+ }
+ }
+ }
+ }
+ // Set entities
+ Set createdEntities = new HashSet<>();
+ Set entitiesToSpawn = this.getEntities();
+ for (CompoundTag nativeTag : entitiesToSpawn) {
+ Map entityTagMap = nativeTag.getValue();
+ StringTag idTag = (StringTag) entityTagMap.get("Id");
+ ListTag posTag = (ListTag) entityTagMap.get("Pos");
+ ListTag rotTag = (ListTag) entityTagMap.get("Rotation");
+ if (idTag == null || posTag == null || rotTag == null) {
+ Fawe.debug("Unknown entity tag: " + nativeTag);
+ continue;
+ }
+ double x = posTag.getDouble(0);
+ double y = posTag.getDouble(1);
+ double z = posTag.getDouble(2);
+ float yaw = rotTag.getFloat(0);
+ float pitch = rotTag.getFloat(1);
+ String id = idTag.getValue();
+ Entity entity = EntityTypes.createEntityByName(id, nmsWorld);
+ if (entity != null) {
+ if (nativeTag != null) {
+ NBTTagCompound tag = (NBTTagCompound)BukkitQueue18R3.methodFromNative.invoke(BukkitQueue18R3.adapter, nativeTag);
+ for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
+ tag.remove(name);
+ }
+ entity.f(tag);
+ }
+ entity.setLocation(x, y, z, yaw, pitch);
+ nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM);
+ createdEntities.add(entity.getUniqueID());
+ }
+ }
+ // Run change task if applicable
+ if (getParent().getChangeTask() != null) {
+ CharFaweChunk previous = getParent().getPrevious(this, sections, tiles, entities, createdEntities, false);
+ getParent().getChangeTask().run(previous, this);
+ }
+ // Trim tiles
+ Iterator> iterator = tiles.entrySet().iterator();
+ HashMap toRemove = null;
+ while (iterator.hasNext()) {
+ Map.Entry tile = iterator.next();
+ BlockPosition pos = tile.getKey();
+ int lx = pos.getX() & 15;
+ int ly = pos.getY();
+ int lz = pos.getZ() & 15;
+ int j = FaweCache.CACHE_I[ly][lz][lx];
+ char[] array = this.getIdArray(j);
+ if (array == null) {
+ continue;
+ }
+ int k = FaweCache.CACHE_J[ly][lz][lx];
+ if (array[k] != 0) {
+ if (toRemove == null) {
+ toRemove = new HashMap<>();
+ }
+ toRemove.put(tile.getKey(), tile.getValue());
+ }
+ }
+ if (toRemove != null) {
+ for (Map.Entry entry : toRemove.entrySet()) {
+ BlockPosition bp = entry.getKey();
+ TileEntity tile = entry.getValue();
+ tiles.remove(bp);
+ tile.y();
+ nmsWorld.t(bp);
+ tile.E();
+ }
+
+ }
+ HashSet entsToRemove = this.getEntityRemoves();
+ if (entsToRemove.size() > 0) {
+ for (int i = 0; i < entities.length; i++) {
+ Collection ents = new ArrayList<>(entities[i]);
+ for (Entity entity : ents) {
+ if (entsToRemove.contains(entity.getUniqueID())) {
+ nmsWorld.removeEntity(entity);
+ }
+ }
+ }
+ }
+ // Set blocks
+ for (int j = 0; j < sections.length; j++) {
+ if (this.getCount(j) == 0) {
+ continue;
+ }
+ char[] newArray = this.getIdArray(j);
+ if (newArray == null) {
+ continue;
+ }
+ ChunkSection section = sections[j];
+ if (section != null && BukkitQueue18R3.isDirty != null) {
+ BukkitQueue18R3.isDirty.set(section, true);
+ }
+ if ((section == null) || (this.getCount(j) >= 4096)) {
+ section = new ChunkSection(j << 4, flag, newArray);
+ sections[j] = section;
+ continue;
+ }
+ char[] currentArray = section.getIdArray();
+ int solid = 0;
+ for (int k = 0; k < newArray.length; k++) {
+ char n = newArray[k];
+ switch (n) {
+ case 0:
+ continue;
+ case 1:
+ if (currentArray[k] > 1) {
+ solid++;
+ currentArray[k] = 0;
+ }
+ continue;
+ default:
+ solid++;
+ currentArray[k] = n;
+ continue;
+ }
+ }
+ getParent().setCount(0, solid, section);
+ }
+
+ // Set biomes
+ int[][] biomes = this.biomes;
+ if (biomes != null) {
+ for (int x = 0; x < 16; x++) {
+ int[] array = biomes[x];
+ if (array == null) {
+ continue;
+ }
+ for (int z = 0; z < 16; z++) {
+ int biome = array[z];
+ if (biome == 0) {
+ continue;
+ }
+ nmsChunk.getBiomeIndex()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome;
+ }
+ }
+ }
+ // Set tiles
+ Map tilesToSpawn = this.getTiles();
+ int bx = this.getX() << 4;
+ int bz = this.getZ() << 4;
+
+ for (Map.Entry entry : tilesToSpawn.entrySet()) {
+ CompoundTag nativeTag = entry.getValue();
+ BytePair pair = entry.getKey();
+ BlockPosition pos = new BlockPosition(pair.get0x() + bx, pair.get1() & 0xFF, pair.get0y() + bz); // Set pos
+ TileEntity tileEntity = nmsWorld.getTileEntity(pos);
+ if (tileEntity != null) {
+ NBTTagCompound tag = (NBTTagCompound) BukkitQueue18R3.methodFromNative.invoke(BukkitQueue18R3.adapter, nativeTag);
+ tileEntity.a(tag); // ReadTagIntoTile
+ }
+ }
+ } catch (Throwable e) {
+ MainUtil.handleError(e);
+ }
+ return this;
+ }
}
diff --git a/bukkit18/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitMain_18.java b/bukkit18/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitMain_18.java
index 5ad82ddd..d6bda43a 100644
--- a/bukkit18/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitMain_18.java
+++ b/bukkit18/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitMain_18.java
@@ -2,6 +2,7 @@ package com.boydti.fawe.bukkit.v1_8;
import com.boydti.fawe.bukkit.ABukkitMain;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
+import com.boydti.fawe.object.FaweQueue;
import com.sk89q.worldedit.world.World;
public class BukkitMain_18 extends ABukkitMain {
@@ -10,4 +11,9 @@ public class BukkitMain_18 extends ABukkitMain {
public BukkitQueue_0 getQueue(World world) {
return new BukkitQueue18R3(world);
}
+
+ @Override
+ public FaweQueue getQueue(String world) {
+ return new BukkitQueue18R3(world);
+ }
}
diff --git a/bukkit18/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitQueue18R3.java b/bukkit18/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitQueue18R3.java
index e8af4d8d..1d45c291 100644
--- a/bukkit18/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitQueue18R3.java
+++ b/bukkit18/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitQueue18R3.java
@@ -4,7 +4,6 @@ import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
import com.boydti.fawe.example.CharFaweChunk;
-import com.boydti.fawe.object.BytePair;
import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.util.MainUtil;
@@ -12,20 +11,14 @@ import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.ReflectionUtils;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.jnbt.CompoundTag;
-import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
-import com.sk89q.worldedit.internal.Constants;
import java.io.File;
import java.lang.reflect.Field;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -60,7 +53,6 @@ import org.bukkit.WorldCreator;
import org.bukkit.craftbukkit.v1_8_R3.CraftChunk;
import org.bukkit.craftbukkit.v1_8_R3.CraftServer;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
-import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.world.WorldInitEvent;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.generator.ChunkGenerator;
@@ -74,6 +66,11 @@ public class BukkitQueue18R3 extends BukkitQueue_0 changeTask) {
- CharFaweChunk fs = (CharFaweChunk) fc;
- CraftChunk chunk = (CraftChunk) fs.getChunk();
- net.minecraft.server.v1_8_R3.Chunk nmsChunk = chunk.getHandle();
- nmsChunk.f(true); // Modified
- nmsChunk.mustSave = true;
- net.minecraft.server.v1_8_R3.World nmsWorld = nmsChunk.getWorld();
- try {
- final boolean flag = getWorld().getEnvironment() == World.Environment.NORMAL;
- // Sections
- ChunkSection[] sections = nmsChunk.getSections();
- Map tiles = nmsChunk.getTileEntities();
- Collection[] entities = nmsChunk.getEntitySlices();
-
- // Remove entities
- for (int i = 0; i < 16; i++) {
- int count = fs.getCount(i);
- if (count == 0) {
- continue;
- } else if (count >= 4096) {
- entities[i].clear();
- } else {
- char[] array = fs.getIdArray(i);
- Collection ents = new ArrayList<>(entities[i]);
- for (Entity entity : ents) {
- if (entity instanceof EntityPlayer) {
- continue;
- }
- int x = ((int) Math.round(entity.locX) & 15);
- int z = ((int) Math.round(entity.locZ) & 15);
- int y = (int) Math.round(entity.locY);
- if (array == null) {
- continue;
- }
- if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][z][x]] != 0) {
- nmsWorld.removeEntity(entity);
- }
- }
- }
- }
- // Set entities
- Set createdEntities = new HashSet<>();
- Set entitiesToSpawn = fs.getEntities();
- for (CompoundTag nativeTag : entitiesToSpawn) {
- Map entityTagMap = nativeTag.getValue();
- StringTag idTag = (StringTag) entityTagMap.get("Id");
- ListTag posTag = (ListTag) entityTagMap.get("Pos");
- ListTag rotTag = (ListTag) entityTagMap.get("Rotation");
- if (idTag == null || posTag == null || rotTag == null) {
- Fawe.debug("Unknown entity tag: " + nativeTag);
- continue;
- }
- double x = posTag.getDouble(0);
- double y = posTag.getDouble(1);
- double z = posTag.getDouble(2);
- float yaw = rotTag.getFloat(0);
- float pitch = rotTag.getFloat(1);
- String id = idTag.getValue();
- Entity entity = EntityTypes.createEntityByName(id, nmsWorld);
- if (entity != null) {
- if (nativeTag != null) {
- NBTTagCompound tag = (NBTTagCompound)methodFromNative.invoke(adapter, nativeTag);
- for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
- tag.remove(name);
- }
- entity.f(tag);
- }
- entity.setLocation(x, y, z, yaw, pitch);
- nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM);
- createdEntities.add(entity.getUniqueID());
- }
- }
- // Run change task if applicable
- if (changeTask != null) {
- CharFaweChunk previous = getPrevious(fs, sections, tiles, entities, createdEntities, false);
- changeTask.run(previous);
- }
- // Trim tiles
- Iterator> iterator = tiles.entrySet().iterator();
- HashMap toRemove = null;
- while (iterator.hasNext()) {
- Map.Entry tile = iterator.next();
- BlockPosition pos = tile.getKey();
- int lx = pos.getX() & 15;
- int ly = pos.getY();
- int lz = pos.getZ() & 15;
- int j = FaweCache.CACHE_I[ly][lz][lx];
- char[] array = fs.getIdArray(j);
- if (array == null) {
- continue;
- }
- int k = FaweCache.CACHE_J[ly][lz][lx];
- if (array[k] != 0) {
- if (toRemove == null) {
- toRemove = new HashMap<>();
- }
- toRemove.put(tile.getKey(), tile.getValue());
- }
- }
- if (toRemove != null) {
- for (Map.Entry entry : toRemove.entrySet()) {
- BlockPosition bp = entry.getKey();
- TileEntity tile = entry.getValue();
- tiles.remove(bp);
- tile.y();
- nmsWorld.t(bp);
- tile.E();
- }
-
- }
- HashSet entsToRemove = fs.getEntityRemoves();
- if (entsToRemove.size() > 0) {
- for (int i = 0; i < entities.length; i++) {
- Collection ents = new ArrayList<>(entities[i]);
- for (Entity entity : ents) {
- if (entsToRemove.contains(entity.getUniqueID())) {
- nmsWorld.removeEntity(entity);
- }
- }
- }
- }
- // Set blocks
- for (int j = 0; j < sections.length; j++) {
- if (fs.getCount(j) == 0) {
- continue;
- }
- char[] newArray = fs.getIdArray(j);
- if (newArray == null) {
- continue;
- }
- ChunkSection section = sections[j];
- if (section != null && isDirty != null) {
- isDirty.set(section, true);
- }
- if ((section == null) || (fs.getCount(j) >= 4096)) {
- section = new ChunkSection(j << 4, flag, newArray);
- sections[j] = section;
- continue;
- }
- char[] currentArray = section.getIdArray();
- int solid = 0;
- for (int k = 0; k < newArray.length; k++) {
- char n = newArray[k];
- switch (n) {
- case 0:
- continue;
- case 1:
- if (currentArray[k] > 1) {
- solid++;
- currentArray[k] = 0;
- }
- continue;
- default:
- solid++;
- currentArray[k] = n;
- continue;
- }
- }
- setCount(0, solid, section);
- }
-
- // Set biomes
- int[][] biomes = fs.biomes;
- if (biomes != null) {
- for (int x = 0; x < 16; x++) {
- int[] array = biomes[x];
- if (array == null) {
- continue;
- }
- for (int z = 0; z < 16; z++) {
- int biome = array[z];
- if (biome == 0) {
- continue;
- }
- nmsChunk.getBiomeIndex()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome;
- }
- }
- }
- // Set tiles
- Map tilesToSpawn = fs.getTiles();
- int bx = fs.getX() << 4;
- int bz = fs.getZ() << 4;
-
- for (Map.Entry entry : tilesToSpawn.entrySet()) {
- CompoundTag nativeTag = entry.getValue();
- BytePair pair = entry.getKey();
- BlockPosition pos = new BlockPosition(pair.get0x() + bx, pair.get1() & 0xFF, pair.get0y() + bz); // Set pos
- TileEntity tileEntity = nmsWorld.getTileEntity(pos);
- if (tileEntity != null) {
- NBTTagCompound tag = (NBTTagCompound) methodFromNative.invoke(adapter, nativeTag);
- tileEntity.a(tag); // ReadTagIntoTile
- }
- }
- } catch (Throwable e) {
- MainUtil.handleError(e);
- }
- return true;
- }
-
public void setCount(int tickingBlockCount, int nonEmptyBlockCount, ChunkSection section) throws NoSuchFieldException, IllegalAccessException {
Class extends ChunkSection> clazz = section.getClass();
Field fieldTickingBlockCount = clazz.getDeclaredField("tickingBlockCount");
diff --git a/bukkit19/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitChunk_1_9.java b/bukkit19/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitChunk_1_9.java
index ffcfd6a2..57192c2b 100644
--- a/bukkit19/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitChunk_1_9.java
+++ b/bukkit19/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitChunk_1_9.java
@@ -1,20 +1,51 @@
package com.boydti.fawe.bukkit.v1_9;
+import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.example.CharFaweChunk;
+import com.boydti.fawe.object.BytePair;
+import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.util.MainUtil;
+import com.boydti.fawe.util.MathMan;
+import com.boydti.fawe.util.ReflectionUtils;
+import com.sk89q.jnbt.CompoundTag;
+import com.sk89q.jnbt.ListTag;
+import com.sk89q.jnbt.LongTag;
+import com.sk89q.jnbt.StringTag;
+import com.sk89q.jnbt.Tag;
+import com.sk89q.worldedit.internal.Constants;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
import net.minecraft.server.v1_9_R2.Block;
+import net.minecraft.server.v1_9_R2.BlockPosition;
+import net.minecraft.server.v1_9_R2.Blocks;
+import net.minecraft.server.v1_9_R2.ChunkSection;
import net.minecraft.server.v1_9_R2.DataBits;
import net.minecraft.server.v1_9_R2.DataPalette;
import net.minecraft.server.v1_9_R2.DataPaletteBlock;
import net.minecraft.server.v1_9_R2.DataPaletteGlobal;
+import net.minecraft.server.v1_9_R2.Entity;
+import net.minecraft.server.v1_9_R2.EntityPlayer;
+import net.minecraft.server.v1_9_R2.EntityTypes;
import net.minecraft.server.v1_9_R2.IBlockData;
+import net.minecraft.server.v1_9_R2.NBTTagCompound;
+import net.minecraft.server.v1_9_R2.TileEntity;
import org.bukkit.Chunk;
+import org.bukkit.World;
+import org.bukkit.block.Biome;
+import org.bukkit.craftbukkit.v1_9_R2.CraftChunk;
+import org.bukkit.event.entity.CreatureSpawnEvent;
-public class BukkitChunk_1_9 extends CharFaweChunk {
+public class BukkitChunk_1_9 extends CharFaweChunk {
public DataPaletteBlock[] sectionPalettes;
@@ -35,7 +66,7 @@ public class BukkitChunk_1_9 extends CharFaweChunk {
}
@Override
- public CharFaweChunk copy(boolean shallow) {
+ public BukkitChunk_1_9 copy(boolean shallow) {
BukkitChunk_1_9 value = (BukkitChunk_1_9) super.copy(shallow);
if (sectionPalettes != null) {
value.sectionPalettes = new DataPaletteBlock[16];
@@ -125,4 +156,252 @@ public class BukkitChunk_1_9 extends CharFaweChunk {
}
}
}
+
+ @Override
+ public void start() {
+ getChunk().load(true);
+ }
+
+ @Override
+ public FaweChunk call() {
+ final Chunk chunk = (Chunk) this.getChunk();
+ final World world = chunk.getWorld();
+ try {
+ final boolean flag = world.getEnvironment() == World.Environment.NORMAL;
+ net.minecraft.server.v1_9_R2.Chunk nmsChunk = ((CraftChunk) chunk).getHandle();
+ nmsChunk.f(true); // Modified
+ nmsChunk.mustSave = true;
+ net.minecraft.server.v1_9_R2.World nmsWorld = nmsChunk.world;
+ ChunkSection[] sections = nmsChunk.getSections();
+ Class extends net.minecraft.server.v1_9_R2.Chunk> clazzChunk = nmsChunk.getClass();
+ final Field ef = clazzChunk.getDeclaredField("entitySlices");
+ final Collection[] entities = (Collection[]) ef.get(nmsChunk);
+ Map tiles = nmsChunk.getTileEntities();
+ // Remove entities
+ for (int i = 0; i < entities.length; i++) {
+ int count = this.getCount(i);
+ if (count == 0) {
+ continue;
+ } else if (count >= 4096) {
+ entities[i].clear();
+ } else {
+ char[] array = this.getIdArray(i);
+ Collection ents = new ArrayList<>(entities[i]);
+ for (Entity entity : ents) {
+ if (entity instanceof EntityPlayer) {
+ continue;
+ }
+ int x = ((int) Math.round(entity.locX) & 15);
+ int z = ((int) Math.round(entity.locZ) & 15);
+ int y = (int) Math.round(entity.locY);
+ if (array == null || y < 0 || y > 255) {
+ continue;
+ }
+ if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][z][x]] != 0) {
+ nmsWorld.removeEntity(entity);
+ }
+ }
+ }
+ }
+ HashSet entsToRemove = this.getEntityRemoves();
+ if (entsToRemove.size() > 0) {
+ for (int i = 0; i < entities.length; i++) {
+ Collection ents = new ArrayList<>(entities[i]);
+ for (Entity entity : ents) {
+ if (entsToRemove.contains(entity.getUniqueID())) {
+ nmsWorld.removeEntity(entity);
+ }
+ }
+ }
+ }
+ // Set entities
+ Set createdEntities = new HashSet<>();
+ Set entitiesToSpawn = this.getEntities();
+ for (CompoundTag nativeTag : entitiesToSpawn) {
+ Map entityTagMap = ReflectionUtils.getMap(nativeTag.getValue());
+ StringTag idTag = (StringTag) entityTagMap.get("Id");
+ ListTag posTag = (ListTag) entityTagMap.get("Pos");
+ ListTag rotTag = (ListTag) entityTagMap.get("Rotation");
+ if (idTag == null || posTag == null || rotTag == null) {
+ Fawe.debug("Unknown entity tag: " + nativeTag);
+ continue;
+ }
+ double x = posTag.getDouble(0);
+ double y = posTag.getDouble(1);
+ double z = posTag.getDouble(2);
+ float yaw = rotTag.getFloat(0);
+ float pitch = rotTag.getFloat(1);
+ String id = idTag.getValue();
+ Entity entity = EntityTypes.createEntityByName(id, nmsWorld);
+ if (entity != null) {
+ UUID uuid = entity.getUniqueID();
+ entityTagMap.put("UUIDMost", new LongTag(uuid.getMostSignificantBits()));
+ entityTagMap.put("UUIDLeast", new LongTag(uuid.getLeastSignificantBits()));
+ if (nativeTag != null) {
+ NBTTagCompound tag = (NBTTagCompound) BukkitQueue_1_9_R1.methodFromNative.invoke(BukkitQueue_1_9_R1.adapter, nativeTag);
+ for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
+ tag.remove(name);
+ }
+ entity.f(tag);
+ }
+ entity.setLocation(x, y, z, yaw, pitch);
+ nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM);
+ createdEntities.add(entity.getUniqueID());
+ }
+ }
+ // Change task?
+ if (getParent().getChangeTask() != null) {
+ CharFaweChunk previous = getParent().getPrevious(this, sections, tiles, entities, createdEntities, false);
+ getParent().getChangeTask().run(previous, this);
+ }
+ // Trim tiles
+ Iterator> iterator = tiles.entrySet().iterator();
+ HashMap toRemove = null;
+ while (iterator.hasNext()) {
+ Map.Entry tile = iterator.next();
+ BlockPosition pos = tile.getKey();
+ int lx = pos.getX() & 15;
+ int ly = pos.getY();
+ int lz = pos.getZ() & 15;
+ int j = FaweCache.CACHE_I[ly][lz][lx];
+ char[] array = this.getIdArray(j);
+ if (array == null) {
+ continue;
+ }
+ int k = FaweCache.CACHE_J[ly][lz][lx];
+ if (array[k] != 0) {
+ if (toRemove == null) {
+ toRemove = new HashMap<>();
+ }
+ toRemove.put(tile.getKey(), tile.getValue());
+ }
+ }
+ if (toRemove != null) {
+ for (Map.Entry entry : toRemove.entrySet()) {
+ BlockPosition bp = entry.getKey();
+ TileEntity tile = entry.getValue();
+ tiles.remove(bp);
+ tile.y();
+ nmsWorld.s(bp);
+ tile.invalidateBlockCache();
+ }
+
+ }
+ // Set blocks
+ for (int j = 0; j < sections.length; j++) {
+ int count = this.getCount(j);
+ if (count == 0) {
+ continue;
+ }
+ final char[] array = this.getIdArray(j);
+ if (array == null) {
+ continue;
+ }
+ ChunkSection section = sections[j];
+ if (section == null) {
+ if (this.sectionPalettes != null && this.sectionPalettes[j] != null) {
+ section = sections[j] = getParent().newChunkSection(j << 4, flag, null);
+ getParent().setPalette(section, this.sectionPalettes[j]);
+ getParent().setCount(0, count - this.getAir(j), section);
+ continue;
+ } else {
+ sections[j] = getParent().newChunkSection(j << 4, flag, array);
+ }
+ continue;
+ } else if (count >= 4096) {
+ if (this.sectionPalettes != null && this.sectionPalettes[j] != null) {
+ getParent().setPalette(section, this.sectionPalettes[j]);
+ getParent().setCount(0, count - this.getAir(j), section);
+ continue;
+ } else {
+ sections[j] = getParent().newChunkSection(j << 4, flag, array);
+ }
+ continue;
+ }
+ DataPaletteBlock nibble = section.getBlocks();
+ Field fieldBits = nibble.getClass().getDeclaredField("b");
+ fieldBits.setAccessible(true);
+ DataBits bits = (DataBits) fieldBits.get(nibble);
+
+ Field fieldPalette = nibble.getClass().getDeclaredField("c");
+ fieldPalette.setAccessible(true);
+ DataPalette palette = (DataPalette) fieldPalette.get(nibble);
+ int nonEmptyBlockCount = 0;
+ for (int y = 0; y < 16; y++) {
+ for (int z = 0; z < 16; z++) {
+ for (int x = 0; x < 16; x++) {
+ char combinedId = array[FaweCache.CACHE_J[y][z][x]];
+ switch (combinedId) {
+ case 0:
+ IBlockData existing = nibble.a(x, y, z);
+ if (existing != BukkitQueue_1_9_R1.air) {
+ nonEmptyBlockCount++;
+ }
+ continue;
+ case 1:
+ nibble.setBlock(x, y, z, Blocks.AIR.getBlockData());
+ continue;
+ default:
+ nonEmptyBlockCount++;
+ nibble.setBlock(x, y, z, Block.getById(combinedId >> 4).fromLegacyData(combinedId & 0xF));
+ }
+ }
+ }
+ }
+ getParent().setCount(0, nonEmptyBlockCount, section);
+ }
+ // Set biomes
+ int[][] biomes = this.biomes;
+ if (biomes != null) {
+ for (int x = 0; x < 16; x++) {
+ int[] array = biomes[x];
+ if (array == null) {
+ continue;
+ }
+ for (int z = 0; z < 16; z++) {
+ int biome = array[z];
+ if (biome == 0) {
+ continue;
+ }
+ nmsChunk.getBiomeIndex()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome;
+ }
+ }
+ }
+ // Set tiles
+ Map tilesToSpawn = this.getTiles();
+ int bx = this.getX() << 4;
+ int bz = this.getZ() << 4;
+
+ for (Map.Entry entry : tilesToSpawn.entrySet()) {
+ CompoundTag nativeTag = entry.getValue();
+ BytePair pair = entry.getKey();
+ BlockPosition pos = new BlockPosition(MathMan.unpair16x((byte) pair.get0()) + bx, pair.get1() & 0xFF, MathMan.unpair16y((byte) pair.get0()) + bz); // Set pos
+ TileEntity tileEntity = nmsWorld.getTileEntity(pos);
+ if (tileEntity != null) {
+ NBTTagCompound tag = (NBTTagCompound) BukkitQueue_1_9_R1.methodFromNative.invoke(BukkitQueue_1_9_R1.adapter, nativeTag);
+ tileEntity.a(tag); // ReadTagIntoTile
+ }
+ }
+ } catch (Throwable e) {
+ MainUtil.handleError(e);
+ }
+ final int[][] biomes = this.getBiomeArray();
+ final Biome[] values = Biome.values();
+ if (biomes != null) {
+ for (int x = 0; x < 16; x++) {
+ final int[] array = biomes[x];
+ if (array == null) {
+ continue;
+ }
+ for (int z = 0; z < 16; z++) {
+ final int biome = array[z];
+ if (biome == 0) {
+ continue;
+ }
+ chunk.getBlock(x, 0, z).setBiome(values[biome]);
+ }
+ }
+ }
+ return this;
+ }
}
diff --git a/bukkit19/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitMain_19.java b/bukkit19/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitMain_19.java
index 7c9237ce..031832d3 100644
--- a/bukkit19/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitMain_19.java
+++ b/bukkit19/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitMain_19.java
@@ -2,6 +2,7 @@ package com.boydti.fawe.bukkit.v1_9;
import com.boydti.fawe.bukkit.ABukkitMain;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
+import com.boydti.fawe.object.FaweQueue;
import com.sk89q.worldedit.world.World;
public class BukkitMain_19 extends ABukkitMain {
@@ -9,4 +10,9 @@ public class BukkitMain_19 extends ABukkitMain {
public BukkitQueue_0 getQueue(World world) {
return new BukkitQueue_1_9_R1(world);
}
+
+ @Override
+ public FaweQueue getQueue(String world) {
+ return new BukkitQueue_1_9_R1(world);
+ }
}
diff --git a/bukkit19/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java b/bukkit19/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java
index 2329ce3f..baea56a0 100644
--- a/bukkit19/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java
+++ b/bukkit19/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java
@@ -4,7 +4,6 @@ import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
import com.boydti.fawe.example.CharFaweChunk;
-import com.boydti.fawe.object.BytePair;
import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.util.MainUtil;
@@ -12,32 +11,22 @@ import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.ReflectionUtils;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.jnbt.CompoundTag;
-import com.sk89q.jnbt.ListTag;
-import com.sk89q.jnbt.LongTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
-import com.sk89q.worldedit.internal.Constants;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import net.minecraft.server.v1_9_R2.Block;
import net.minecraft.server.v1_9_R2.BlockPosition;
-import net.minecraft.server.v1_9_R2.Blocks;
import net.minecraft.server.v1_9_R2.ChunkSection;
import net.minecraft.server.v1_9_R2.DataBits;
-import net.minecraft.server.v1_9_R2.DataPalette;
import net.minecraft.server.v1_9_R2.DataPaletteBlock;
import net.minecraft.server.v1_9_R2.Entity;
import net.minecraft.server.v1_9_R2.EntityPlayer;
@@ -63,24 +52,30 @@ import net.minecraft.server.v1_9_R2.WorldType;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
-import org.bukkit.World.Environment;
import org.bukkit.WorldCreator;
-import org.bukkit.block.Biome;
import org.bukkit.craftbukkit.v1_9_R2.CraftChunk;
import org.bukkit.craftbukkit.v1_9_R2.CraftServer;
import org.bukkit.craftbukkit.v1_9_R2.CraftWorld;
-import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.world.WorldInitEvent;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.generator.ChunkGenerator;
public class BukkitQueue_1_9_R1 extends BukkitQueue_0 {
- private static IBlockData air;
- private static Field fieldBits;
+ protected static IBlockData air;
+ protected static Field fieldBits;
public BukkitQueue_1_9_R1(final com.sk89q.worldedit.world.World world) {
super(world);
+ init();
+ }
+
+ public BukkitQueue_1_9_R1(final String world) {
+ super(world);
+ init();
+ }
+
+ private void init() {
checkVersion("v1_9_R2");
if (air == null) {
try {
@@ -287,7 +282,7 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0 changeTask) {
- final BukkitChunk_1_9 fs = (BukkitChunk_1_9) fc;
- final Chunk chunk = (Chunk) fs.getChunk();
- final World world = chunk.getWorld();
- chunk.load(true);
- try {
- final boolean flag = world.getEnvironment() == Environment.NORMAL;
- net.minecraft.server.v1_9_R2.Chunk nmsChunk = ((CraftChunk) chunk).getHandle();
- nmsChunk.f(true); // Modified
- nmsChunk.mustSave = true;
- net.minecraft.server.v1_9_R2.World nmsWorld = nmsChunk.world;
- ChunkSection[] sections = nmsChunk.getSections();
- Class extends net.minecraft.server.v1_9_R2.Chunk> clazzChunk = nmsChunk.getClass();
- final Field ef = clazzChunk.getDeclaredField("entitySlices");
- final Collection[] entities = (Collection[]) ef.get(nmsChunk);
- Map tiles = nmsChunk.getTileEntities();
- // Remove entities
- for (int i = 0; i < entities.length; i++) {
- int count = fs.getCount(i);
- if (count == 0) {
- continue;
- } else if (count >= 4096) {
- entities[i].clear();
- } else {
- char[] array = fs.getIdArray(i);
- Collection ents = new ArrayList<>(entities[i]);
- for (Entity entity : ents) {
- if (entity instanceof EntityPlayer) {
- continue;
- }
- int x = ((int) Math.round(entity.locX) & 15);
- int z = ((int) Math.round(entity.locZ) & 15);
- int y = (int) Math.round(entity.locY);
- if (array == null || y < 0 || y > 255) {
- continue;
- }
- if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][z][x]] != 0) {
- nmsWorld.removeEntity(entity);
- }
- }
- }
- }
- HashSet entsToRemove = fs.getEntityRemoves();
- if (entsToRemove.size() > 0) {
- for (int i = 0; i < entities.length; i++) {
- Collection ents = new ArrayList<>(entities[i]);
- for (Entity entity : ents) {
- if (entsToRemove.contains(entity.getUniqueID())) {
- nmsWorld.removeEntity(entity);
- }
- }
- }
- }
- // Set entities
- Set createdEntities = new HashSet<>();
- Set entitiesToSpawn = fs.getEntities();
- for (CompoundTag nativeTag : entitiesToSpawn) {
- Map entityTagMap = ReflectionUtils.getMap(nativeTag.getValue());
- StringTag idTag = (StringTag) entityTagMap.get("Id");
- ListTag posTag = (ListTag) entityTagMap.get("Pos");
- ListTag rotTag = (ListTag) entityTagMap.get("Rotation");
- if (idTag == null || posTag == null || rotTag == null) {
- Fawe.debug("Unknown entity tag: " + nativeTag);
- continue;
- }
- double x = posTag.getDouble(0);
- double y = posTag.getDouble(1);
- double z = posTag.getDouble(2);
- float yaw = rotTag.getFloat(0);
- float pitch = rotTag.getFloat(1);
- String id = idTag.getValue();
- Entity entity = EntityTypes.createEntityByName(id, nmsWorld);
- if (entity != null) {
- UUID uuid = entity.getUniqueID();
- entityTagMap.put("UUIDMost", new LongTag(uuid.getMostSignificantBits()));
- entityTagMap.put("UUIDLeast", new LongTag(uuid.getLeastSignificantBits()));
- if (nativeTag != null) {
- NBTTagCompound tag = (NBTTagCompound) methodFromNative.invoke(adapter, nativeTag);
- for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
- tag.remove(name);
- }
- entity.f(tag);
- }
- entity.setLocation(x, y, z, yaw, pitch);
- nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM);
- createdEntities.add(entity.getUniqueID());
- }
- }
- // Change task?
- if (changeTask != null) {
- CharFaweChunk previous = getPrevious(fs, sections, tiles, entities, createdEntities, false);
- changeTask.run(previous);
- }
- // Trim tiles
- Iterator> iterator = tiles.entrySet().iterator();
- HashMap toRemove = null;
- while (iterator.hasNext()) {
- Map.Entry tile = iterator.next();
- BlockPosition pos = tile.getKey();
- int lx = pos.getX() & 15;
- int ly = pos.getY();
- int lz = pos.getZ() & 15;
- int j = FaweCache.CACHE_I[ly][lz][lx];
- char[] array = fs.getIdArray(j);
- if (array == null) {
- continue;
- }
- int k = FaweCache.CACHE_J[ly][lz][lx];
- if (array[k] != 0) {
- if (toRemove == null) {
- toRemove = new HashMap<>();
- }
- toRemove.put(tile.getKey(), tile.getValue());
- }
- }
- if (toRemove != null) {
- for (Entry entry : toRemove.entrySet()) {
- BlockPosition bp = entry.getKey();
- TileEntity tile = entry.getValue();
- tiles.remove(bp);
- tile.y();
- nmsWorld.s(bp);
- tile.invalidateBlockCache();
- }
-
- }
- // Set blocks
- for (int j = 0; j < sections.length; j++) {
- int count = fs.getCount(j);
- if (count == 0) {
- continue;
- }
- final char[] array = fs.getIdArray(j);
- if (array == null) {
- continue;
- }
- ChunkSection section = sections[j];
- if (section == null) {
- if (fs.sectionPalettes != null && fs.sectionPalettes[j] != null) {
- section = sections[j] = newChunkSection(j << 4, flag, null);
- setPalette(section, fs.sectionPalettes[j]);
- setCount(0, count - fs.getAir(j), section);
- continue;
- } else {
- sections[j] = newChunkSection(j << 4, flag, array);
- }
- continue;
- } else if (count >= 4096) {
- if (fs.sectionPalettes != null && fs.sectionPalettes[j] != null) {
- setPalette(section, fs.sectionPalettes[j]);
- setCount(0, count - fs.getAir(j), section);
- continue;
- } else {
- sections[j] = newChunkSection(j << 4, flag, array);
- }
- continue;
- }
- DataPaletteBlock nibble = section.getBlocks();
- Field fieldBits = nibble.getClass().getDeclaredField("b");
- fieldBits.setAccessible(true);
- DataBits bits = (DataBits) fieldBits.get(nibble);
-
- Field fieldPalette = nibble.getClass().getDeclaredField("c");
- fieldPalette.setAccessible(true);
- DataPalette palette = (DataPalette) fieldPalette.get(nibble);
- int nonEmptyBlockCount = 0;
- for (int y = 0; y < 16; y++) {
- for (int z = 0; z < 16; z++) {
- for (int x = 0; x < 16; x++) {
- char combinedId = array[FaweCache.CACHE_J[y][z][x]];
- switch (combinedId) {
- case 0:
- IBlockData existing = nibble.a(x, y, z);
- if (existing != air) {
- nonEmptyBlockCount++;
- }
- continue;
- case 1:
- nibble.setBlock(x, y, z, Blocks.AIR.getBlockData());
- continue;
- default:
- nonEmptyBlockCount++;
- nibble.setBlock(x, y, z, Block.getById(combinedId >> 4).fromLegacyData(combinedId & 0xF));
- }
- }
- }
- }
- setCount(0, nonEmptyBlockCount, section);
- }
- // Set biomes
- int[][] biomes = fs.biomes;
- if (biomes != null) {
- for (int x = 0; x < 16; x++) {
- int[] array = biomes[x];
- if (array == null) {
- continue;
- }
- for (int z = 0; z < 16; z++) {
- int biome = array[z];
- if (biome == 0) {
- continue;
- }
- nmsChunk.getBiomeIndex()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome;
- }
- }
- }
- // Set tiles
- Map tilesToSpawn = fs.getTiles();
- int bx = fs.getX() << 4;
- int bz = fs.getZ() << 4;
-
- for (Map.Entry entry : tilesToSpawn.entrySet()) {
- CompoundTag nativeTag = entry.getValue();
- BytePair pair = entry.getKey();
- BlockPosition pos = new BlockPosition(MathMan.unpair16x((byte) pair.get0()) + bx, pair.get1() & 0xFF, MathMan.unpair16y((byte) pair.get0()) + bz); // Set pos
- TileEntity tileEntity = nmsWorld.getTileEntity(pos);
- if (tileEntity != null) {
- NBTTagCompound tag = (NBTTagCompound) methodFromNative.invoke(adapter, nativeTag);
- tileEntity.a(tag); // ReadTagIntoTile
- }
- }
- } catch (Throwable e) {
- MainUtil.handleError(e);
- }
- final int[][] biomes = fs.getBiomeArray();
- final Biome[] values = Biome.values();
- if (biomes != null) {
- for (int x = 0; x < 16; x++) {
- final int[] array = biomes[x];
- if (array == null) {
- continue;
- }
- for (int z = 0; z < 16; z++) {
- final int biome = array[z];
- if (biome == 0) {
- continue;
- }
- chunk.getBlock(x, 0, z).setBiome(values[biome]);
- }
- }
- }
- return true;
- }
-
@Deprecated
public boolean unloadChunk(final String world, final Chunk chunk) {
net.minecraft.server.v1_9_R2.Chunk c = ((CraftChunk) chunk).getHandle();
@@ -769,8 +519,8 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0 99) {
return;
}
try {
diff --git a/core/src/main/java/com/boydti/fawe/FaweAPI.java b/core/src/main/java/com/boydti/fawe/FaweAPI.java
index a0dab3c8..8271923e 100644
--- a/core/src/main/java/com/boydti/fawe/FaweAPI.java
+++ b/core/src/main/java/com/boydti/fawe/FaweAPI.java
@@ -98,9 +98,8 @@ public class FaweAPI {
return FawePlayer.wrap(obj);
}
- @Deprecated
public static FaweQueue createQueue(String worldName, boolean autoqueue) {
- return SetQueue.IMP.getNewQueue(getWorld(worldName), true, autoqueue);
+ return SetQueue.IMP.getNewQueue(worldName, true, autoqueue);
}
/**
diff --git a/core/src/main/java/com/boydti/fawe/IFawe.java b/core/src/main/java/com/boydti/fawe/IFawe.java
index 2f4d9ccd..6a85a55e 100644
--- a/core/src/main/java/com/boydti/fawe/IFawe.java
+++ b/core/src/main/java/com/boydti/fawe/IFawe.java
@@ -25,6 +25,8 @@ public interface IFawe {
public FaweQueue getNewQueue(World world, boolean fast);
+ public FaweQueue getNewQueue(String world, boolean fast);
+
public String getWorldName(World world);
public Collection getMaskManagers();
diff --git a/core/src/main/java/com/boydti/fawe/example/CharFaweChunk.java b/core/src/main/java/com/boydti/fawe/example/CharFaweChunk.java
index 65c35b92..50ed82e3 100644
--- a/core/src/main/java/com/boydti/fawe/example/CharFaweChunk.java
+++ b/core/src/main/java/com/boydti/fawe/example/CharFaweChunk.java
@@ -15,7 +15,7 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
-public abstract class CharFaweChunk extends FaweChunk {
+public abstract class CharFaweChunk extends FaweChunk {
public char[][] ids;
public short[] count;
@@ -47,6 +47,11 @@ public abstract class CharFaweChunk extends FaweChunk {
this.relight = new short[HEIGHT >> 4];
}
+ @Override
+ public V getParent() {
+ return (V) super.getParent();
+ }
+
@Override
public T getChunk() {
if (this.chunk == null) {
@@ -358,8 +363,8 @@ public abstract class CharFaweChunk extends FaweChunk {
}
@Override
- public CharFaweChunk copy(boolean shallow) {
- CharFaweChunk copy = (CharFaweChunk) getParent().getFaweChunk(getX(), getZ());
+ public CharFaweChunk copy(boolean shallow) {
+ CharFaweChunk copy = (CharFaweChunk) getParent().getFaweChunk(getX(), getZ());
if (shallow) {
copy.ids = ids;
copy.air = air;
diff --git a/core/src/main/java/com/boydti/fawe/example/DefaultFaweQueueMap.java b/core/src/main/java/com/boydti/fawe/example/DefaultFaweQueueMap.java
index 8763f6d8..19ccbdf5 100644
--- a/core/src/main/java/com/boydti/fawe/example/DefaultFaweQueueMap.java
+++ b/core/src/main/java/com/boydti/fawe/example/DefaultFaweQueueMap.java
@@ -3,12 +3,13 @@ package com.boydti.fawe.example;
import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.RunnableVal;
-import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.MathMan;
import java.util.Collection;
import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.ExecutorCompletionService;
public class DefaultFaweQueueMap implements IFaweQueueMap {
@@ -21,26 +22,25 @@ public class DefaultFaweQueueMap implements IFaweQueueMap {
/**
* Map of chunks in the queue
*/
- public ConcurrentHashMap blocks = new ConcurrentHashMap<>(8, 0.9f, 1);
- public ConcurrentLinkedDeque chunks = new ConcurrentLinkedDeque() {
+ public ConcurrentHashMap blocks = new ConcurrentHashMap(8, 0.9f, 1) {
@Override
- public boolean add(FaweChunk o) {
+ public FaweChunk put(Long key, FaweChunk value) {
if (parent.getProgressTask() != null) {
parent.getProgressTask().run(FaweQueue.ProgressType.QUEUE, size() + 1);
}
- return super.add(o);
+ return super.put(key, value);
}
};
@Override
public Collection getFaweCunks() {
- return new HashSet<>(chunks);
+ return new HashSet<>(blocks.values());
}
@Override
public void forEachChunk(RunnableVal onEach) {
- for (FaweChunk chunk : chunks) {
- onEach.run(chunk);
+ for (Map.Entry entry : blocks.entrySet()) {
+ onEach.run(entry.getValue());
}
}
@@ -59,7 +59,6 @@ public class DefaultFaweQueueMap implements IFaweQueueMap {
return previous;
}
this.blocks.put(pair, chunk);
- chunks.add(chunk);
}
return chunk;
}
@@ -77,9 +76,7 @@ public class DefaultFaweQueueMap implements IFaweQueueMap {
public void add(FaweChunk chunk) {
long pair = MathMan.pairInt(chunk.getX(), chunk.getZ());
FaweChunk previous = this.blocks.put(pair, chunk);
- if (previous == null) {
- chunks.add(chunk);
- } else {
+ if (previous != null) {
blocks.put(pair, previous);
}
}
@@ -88,12 +85,11 @@ public class DefaultFaweQueueMap implements IFaweQueueMap {
@Override
public void clear() {
blocks.clear();
- chunks.clear();
}
@Override
public int size() {
- return chunks.size();
+ return blocks.size();
}
private FaweChunk getNewFaweChunk(int cx, int cz) {
@@ -105,24 +101,59 @@ public class DefaultFaweQueueMap implements IFaweQueueMap {
private int lastZ = Integer.MIN_VALUE;
@Override
- public boolean next() {
+ public boolean next(int amount, ExecutorCompletionService pool, long time) {
+ lastWrappedChunk = null;
lastX = Integer.MIN_VALUE;
lastZ = Integer.MIN_VALUE;
try {
- if (this.blocks.isEmpty()) {
- return false;
+ int added = 0;
+ Iterator> iter = blocks.entrySet().iterator();
+ if (amount == 1) {
+ long start = System.currentTimeMillis();
+ do {
+ if (iter.hasNext()) {
+ FaweChunk chunk = iter.next().getValue();
+ iter.remove();
+ parent.start(chunk);
+ chunk.call();
+ parent.end(chunk);
+ } else {
+ break;
+ }
+ } while (System.currentTimeMillis() - start < time);
+ return !blocks.isEmpty();
}
- synchronized (blocks) {
- FaweChunk chunk = chunks.poll();
- if (chunk != null) {
- blocks.remove(chunk.longHash());
- parent.execute(chunk);
- return true;
+ boolean result = true;
+ for (int i = 0; i < amount && (result = iter.hasNext()); i++, added++) {
+ Map.Entry item = iter.next();
+ FaweChunk chunk = item.getValue();
+ parent.start(chunk);
+ pool.submit(chunk);
+ iter.remove();
+ }
+ if (result) {
+ long start = System.currentTimeMillis();
+ while (System.currentTimeMillis() - start < time) {
+ for (int i = 0; i < amount && (iter.hasNext()); i++, added++) {
+ Map.Entry item = iter.next();
+ FaweChunk chunk = item.getValue();
+ parent.start(chunk);
+ pool.submit(chunk);
+ iter.remove();
+ }
+ for (int i = 0; i < amount; i++, added--) {
+ FaweChunk fc = ((FaweChunk) pool.take().get());
+ parent.end(fc);
+ }
}
}
+ for (int i = 0; i < added; i++) {
+ FaweChunk fc = ((FaweChunk) pool.take().get());
+ parent.end(fc);
+ }
} catch (Throwable e) {
- MainUtil.handleError(e);
+ e.printStackTrace();
}
- return false;
+ return !blocks.isEmpty();
}
}
diff --git a/core/src/main/java/com/boydti/fawe/example/IFaweQueueMap.java b/core/src/main/java/com/boydti/fawe/example/IFaweQueueMap.java
index a3e1b5be..e20d1b41 100644
--- a/core/src/main/java/com/boydti/fawe/example/IFaweQueueMap.java
+++ b/core/src/main/java/com/boydti/fawe/example/IFaweQueueMap.java
@@ -3,6 +3,7 @@ package com.boydti.fawe.example;
import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.RunnableVal;
import java.util.Collection;
+import java.util.concurrent.ExecutorCompletionService;
public interface IFaweQueueMap {
@@ -20,5 +21,5 @@ public interface IFaweQueueMap {
int size();
- boolean next();
+ boolean next(int size, ExecutorCompletionService dispatcher, long time);
}
diff --git a/core/src/main/java/com/boydti/fawe/example/MappedFaweQueue.java b/core/src/main/java/com/boydti/fawe/example/MappedFaweQueue.java
index 52ea52fc..356b6761 100644
--- a/core/src/main/java/com/boydti/fawe/example/MappedFaweQueue.java
+++ b/core/src/main/java/com/boydti/fawe/example/MappedFaweQueue.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.UUID;
import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
@@ -36,6 +37,11 @@ public abstract class MappedFaweQueue extends FaweQueue {
this(world, null);
}
+ public MappedFaweQueue(final String world) {
+ super(world);
+ map = new DefaultFaweQueueMap(this);
+ }
+
public MappedFaweQueue(final World world, IFaweQueueMap map) {
super(world);
if (map == null) {
@@ -99,8 +105,6 @@ public abstract class MappedFaweQueue extends FaweQueue {
public abstract boolean regenerateChunk(WORLD world, int x, int z);
- public abstract boolean setComponents(FaweChunk fc, RunnableVal changeTask);
-
@Override
public abstract FaweChunk getFaweChunk(int x, int z);
@@ -192,10 +196,19 @@ public abstract class MappedFaweQueue extends FaweQueue {
}
@Override
- public boolean next() {
- return map.next();
+ public boolean next(int amount, ExecutorCompletionService pool, long time) {
+ return map.next(amount, pool, time);
}
+ public void start(FaweChunk chunk) {
+ chunk.start();
+ }
+
+ public void end(FaweChunk chunk) {
+ chunk.end();
+ }
+
+ @Override
public void runTasks() {
if (getProgressTask() != null) {
getProgressTask().run(ProgressType.DONE, 1);
@@ -224,31 +237,6 @@ public abstract class MappedFaweQueue extends FaweQueue {
private int dispatched = 0;
- public boolean execute(final FaweChunk fc) {
- if (fc == null) {
- return false;
- }
- // Set blocks / entities / biome
- if (getProgressTask() != null) {
- getProgressTask().run(ProgressType.QUEUE, map.size());
- getProgressTask().run(ProgressType.DISPATCH, ++dispatched);
- }
- if (getChangeTask() != null) {
- if (!this.setComponents(fc, new RunnableVal() {
- @Override
- public void run(FaweChunk before) {
- getChangeTask().run(before, fc);
- }
- })) {
- return false;
- }
- } else if (!this.setComponents(fc, null)) {
- return false;
- }
- fc.executeNotifyTasks();
- return true;
- }
-
@Override
public void clear() {
map.clear();
diff --git a/core/src/main/java/com/boydti/fawe/example/NMSMappedFaweQueue.java b/core/src/main/java/com/boydti/fawe/example/NMSMappedFaweQueue.java
index dd76da3d..98e88b2a 100644
--- a/core/src/main/java/com/boydti/fawe/example/NMSMappedFaweQueue.java
+++ b/core/src/main/java/com/boydti/fawe/example/NMSMappedFaweQueue.java
@@ -22,6 +22,12 @@ public abstract class NMSMappedFaweQueue ex
addRelightTask();
}
+ public NMSMappedFaweQueue(String world) {
+ super(world);
+ this.maxY = 256;
+ addRelightTask();
+ }
+
public NMSMappedFaweQueue(World world, IFaweQueueMap map) {
super(world, map);
this.maxY = world.getMaxY();
@@ -47,35 +53,32 @@ public abstract class NMSMappedFaweQueue ex
private NMSRelighter relighter;
@Override
- public boolean execute(FaweChunk fc) {
- if (super.execute(fc)) {
- sendChunk(fc);
- if (Settings.LIGHTING.MODE == 0) {
- return true;
+ public void end(FaweChunk chunk) {
+ super.end(chunk);
+ if (Settings.LIGHTING.MODE == 0) {
+ return;
+ }
+ if (relighter == null) {
+ relighter = new NMSRelighter(this);
+ }
+ if (Settings.LIGHTING.MODE == 2) {
+ relighter.addChunk(chunk.getX(), chunk.getZ(), null);
+ return;
+ }
+ CharFaweChunk cfc = (CharFaweChunk) chunk;
+ boolean relight = false;
+ boolean[] fix = new boolean[(maxY + 1) >> 4];
+ boolean sky = hasSky();
+ for (int i = 0; i < cfc.ids.length; i++) {
+ if ((sky && ((cfc.getAir(i) & 4095) != 0 || (cfc.getCount(i) & 4095) != 0)) || cfc.getRelight(i) != 0) {
+ relight = true;
+ fix[i] = true;
}
- if (relighter == null) {
- relighter = new NMSRelighter(this);
- }
- if (Settings.LIGHTING.MODE == 2) {
- relighter.addChunk(fc.getX(), fc.getZ(), null);
- return true;
- }
- CharFaweChunk chunk = (CharFaweChunk) fc;
- boolean relight = false;
- boolean[] fix = new boolean[(maxY + 1) >> 4];
- boolean sky = hasSky();
- for (int i = 0; i < chunk.ids.length; i++) {
- if ((sky && ((chunk.getAir(i) & 4095) != 0 || (chunk.getCount(i) & 4095) != 0)) || chunk.getRelight(i) != 0) {
- relight = true;
- fix[i] = true;
- }
- }
- if (relight) {
- relighter.addChunk(chunk.getX(), chunk.getZ(), fix);
- }
- return true;
+ }
+ if (relight) {
+ relighter.addChunk(chunk.getX(), chunk.getZ(), fix);
} else {
- return false;
+ refreshChunk(chunk);
}
}
diff --git a/core/src/main/java/com/boydti/fawe/example/NullFaweChunk.java b/core/src/main/java/com/boydti/fawe/example/NullFaweChunk.java
index 8f462803..e48f391f 100644
--- a/core/src/main/java/com/boydti/fawe/example/NullFaweChunk.java
+++ b/core/src/main/java/com/boydti/fawe/example/NullFaweChunk.java
@@ -92,4 +92,9 @@ public class NullFaweChunk extends FaweChunk {
public FaweChunk copy(boolean shallow) {
return this;
}
+
+ @Override
+ public FaweChunk call() {
+ return null;
+ }
}
diff --git a/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java b/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java
index 8ac538d9..c3ec6405 100644
--- a/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java
+++ b/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java
@@ -402,4 +402,9 @@ public class MCAChunk extends FaweChunk {
public Void getChunk() {
throw new UnsupportedOperationException("Not applicable for this");
}
+
+ @Override
+ public FaweChunk call() {
+ throw new UnsupportedOperationException("Not supported");
+ }
}
diff --git a/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueue.java b/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueue.java
index 217a7c06..41f5c958 100644
--- a/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueue.java
+++ b/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueue.java
@@ -5,7 +5,6 @@ import com.boydti.fawe.example.CharFaweChunk;
import com.boydti.fawe.example.NMSMappedFaweQueue;
import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.FaweQueue;
-import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.object.RunnableVal4;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.jnbt.CompoundTag;
@@ -141,11 +140,6 @@ public class MCAQueue extends NMSMappedFaweQueue changeTask) {
- throw new UnsupportedOperationException("Not supported");
- }
-
@Override
public CharFaweChunk getPrevious(CharFaweChunk fs, FaweChunk sections, Map, ?> tiles, Collection>[] entities, Set createdEntities, boolean all) throws Exception {
throw new UnsupportedOperationException("Not supported");
diff --git a/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueueMap.java b/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueueMap.java
index 3ae3b92a..88ed4fa1 100644
--- a/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueueMap.java
+++ b/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueueMap.java
@@ -14,6 +14,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorCompletionService;
public class MCAQueueMap implements IFaweQueueMap {
@@ -150,20 +151,26 @@ public class MCAQueueMap implements IFaweQueueMap {
}
@Override
- public boolean next() {
+ public boolean next(int size, ExecutorCompletionService dispatcher, long time) {
lastX = Integer.MIN_VALUE;
lastZ = Integer.MIN_VALUE;
lastFileX = Integer.MIN_VALUE;
lastFileZ = Integer.MIN_VALUE;
if (!mcaFileMap.isEmpty()) {
Iterator> iter = mcaFileMap.entrySet().iterator();
- if (iter.hasNext()) {
- MCAFile file = iter.next().getValue();
- iter.remove();
- file.flush();
- file.close();
- return true;
- }
+ boolean result;
+ long start = System.currentTimeMillis();
+ do {
+ if (result = iter.hasNext()) {
+ MCAFile file = iter.next().getValue();
+ iter.remove();
+ file.flush();
+ file.close();
+ } else {
+ break;
+ }
+ } while (System.currentTimeMillis() - start < time);
+ return result;
}
if (isHybridQueue) {
boolean value = queue.next();
diff --git a/core/src/main/java/com/boydti/fawe/object/FaweChunk.java b/core/src/main/java/com/boydti/fawe/object/FaweChunk.java
index f9d4b628..df4d0df3 100644
--- a/core/src/main/java/com/boydti/fawe/object/FaweChunk.java
+++ b/core/src/main/java/com/boydti/fawe/object/FaweChunk.java
@@ -9,8 +9,9 @@ import java.util.ArrayDeque;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
+import java.util.concurrent.Callable;
-public abstract class FaweChunk {
+public abstract class FaweChunk implements Callable {
private FaweQueue parent;
private int x,z;
@@ -267,4 +268,11 @@ public abstract class FaweChunk {
}
public abstract FaweChunk copy(boolean shallow);
+
+ public void start() {};
+
+ public void end() {};
+
+ @Override
+ public abstract FaweChunk call();
}
diff --git a/core/src/main/java/com/boydti/fawe/object/FawePlayer.java b/core/src/main/java/com/boydti/fawe/object/FawePlayer.java
index 44835203..1444b370 100644
--- a/core/src/main/java/com/boydti/fawe/object/FawePlayer.java
+++ b/core/src/main/java/com/boydti/fawe/object/FawePlayer.java
@@ -82,10 +82,7 @@ public abstract class FawePlayer {
Field fieldPlayer = actor.getClass().getDeclaredField("player");
fieldPlayer.setAccessible(true);
return wrap(fieldPlayer.get(actor));
- } catch (Throwable e) {
- MainUtil.handleError(e);
- return Fawe.imp().wrap(actor.getName());
- }
+ } catch (Throwable ignore) {}
}
}
if (obj instanceof Actor) {
diff --git a/core/src/main/java/com/boydti/fawe/object/FaweQueue.java b/core/src/main/java/com/boydti/fawe/object/FaweQueue.java
index 9d610d43..fc79512c 100644
--- a/core/src/main/java/com/boydti/fawe/object/FaweQueue.java
+++ b/core/src/main/java/com/boydti/fawe/object/FaweQueue.java
@@ -1,8 +1,10 @@
package com.boydti.fawe.object;
import com.boydti.fawe.Fawe;
+import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.config.BBC;
+import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.MathMan;
@@ -23,6 +25,7 @@ import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.atomic.AtomicBoolean;
public abstract class FaweQueue {
@@ -34,6 +37,10 @@ public abstract class FaweQueue {
private RunnableVal2 changeTask;
private RunnableVal2 progressTask;
+ public FaweQueue(String world) {
+ this.world = world;
+ }
+
public FaweQueue(World world) {
this.weWorld = world;
this.world = Fawe.imp().getWorldName(world);
@@ -62,7 +69,7 @@ public abstract class FaweQueue {
}
public World getWEWorld() {
- return weWorld;
+ return weWorld != null ? weWorld : (weWorld = FaweAPI.getWorld(world));
}
public String getWorldName() {
@@ -226,11 +233,19 @@ public abstract class FaweQueue {
return count;
}
+ @Deprecated
+ public boolean next() {
+ int amount = Settings.QUEUE.PARALLEL_THREADS;
+ ExecutorCompletionService service = SetQueue.IMP.getCompleterService();
+ long time = 20; // 30ms
+ return next(amount, service, time);
+ }
+
/**
* Gets the FaweChunk and sets the requested blocks
* @return
*/
- public abstract boolean next();
+ public abstract boolean next(int amount, ExecutorCompletionService pool, long time);
public void saveMemory() {
MainUtil.sendAdmin(BBC.OOM.s());
@@ -369,6 +384,8 @@ public abstract class FaweQueue {
}
}
+ public abstract void runTasks();
+
public boolean enqueue() {
return SetQueue.IMP.enqueue(this);
}
diff --git a/core/src/main/java/com/boydti/fawe/object/player/DefaultFawePlayer.java b/core/src/main/java/com/boydti/fawe/object/player/DefaultFawePlayer.java
new file mode 100644
index 00000000..b8c75714
--- /dev/null
+++ b/core/src/main/java/com/boydti/fawe/object/player/DefaultFawePlayer.java
@@ -0,0 +1,4 @@
+package com.boydti.fawe.object.player;
+
+public class DefaultFawePlayer {
+}
diff --git a/core/src/main/java/com/boydti/fawe/regions/general/plot/PlotSquaredFeature.java b/core/src/main/java/com/boydti/fawe/regions/general/plot/PlotSquaredFeature.java
index 4185e6fc..1b2aa981 100644
--- a/core/src/main/java/com/boydti/fawe/regions/general/plot/PlotSquaredFeature.java
+++ b/core/src/main/java/com/boydti/fawe/regions/general/plot/PlotSquaredFeature.java
@@ -31,7 +31,7 @@ public class PlotSquaredFeature extends FaweMaskManager {
try {
// If it's going to fail, throw an error now rather than later
QueueProvider provider = QueueProvider.of(FaweLocalBlockQueue.class, null);
- GlobalBlockQueue.IMP.setProvider(provider);
+ GlobalBlockQueue.IMP = new GlobalBlockQueue(provider, 1);
HybridPlotManager.REGENERATIVE_CLEAR = false;
Fawe.debug(" - QueueProvider: " + FaweLocalBlockQueue.class);
Fawe.debug(" - HybridPlotManager.REGENERATIVE_CLEAR: " + HybridPlotManager.REGENERATIVE_CLEAR);
diff --git a/core/src/main/java/com/boydti/fawe/util/DelegateFaweQueue.java b/core/src/main/java/com/boydti/fawe/util/DelegateFaweQueue.java
index 1b1aa7b4..70e96649 100644
--- a/core/src/main/java/com/boydti/fawe/util/DelegateFaweQueue.java
+++ b/core/src/main/java/com/boydti/fawe/util/DelegateFaweQueue.java
@@ -12,6 +12,7 @@ import java.util.Collection;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.ExecutorCompletionService;
public class DelegateFaweQueue extends FaweQueue {
private FaweQueue parent;
@@ -169,6 +170,11 @@ public class DelegateFaweQueue extends FaweQueue {
return parent.next();
}
+ @Override
+ public boolean next(int amount, ExecutorCompletionService pool, long time) {
+ return parent.next(amount, pool, time);
+ }
+
@Override
public void saveMemory() {
parent.saveMemory();
@@ -234,6 +240,11 @@ public class DelegateFaweQueue extends FaweQueue {
return parent.size();
}
+ @Override
+ public void runTasks() {
+ parent.runTasks();
+ }
+
@Override
public boolean enqueue() {
return parent.enqueue();
diff --git a/core/src/main/java/com/boydti/fawe/util/SetQueue.java b/core/src/main/java/com/boydti/fawe/util/SetQueue.java
index be02f7b7..7f052a9e 100644
--- a/core/src/main/java/com/boydti/fawe/util/SetQueue.java
+++ b/core/src/main/java/com/boydti/fawe/util/SetQueue.java
@@ -3,13 +3,13 @@ package com.boydti.fawe.util;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.FaweQueue;
-import com.boydti.fawe.object.RunnableVal2;
import com.sk89q.worldedit.world.World;
import java.util.ArrayList;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
@@ -40,23 +40,17 @@ public class SetQueue {
*/
private final ConcurrentLinkedDeque emptyTasks = new ConcurrentLinkedDeque<>();
- private final RunnableVal2 SET_TASK = new RunnableVal2() {
- @Override
- public void run(Long free, FaweQueue queue) {
- do {
- final boolean current = queue.next();
- if (current == false) {
- lastSuccess = last;
- if (inactiveQueues.size() == 0 && activeQueues.size() == 0) {
- runEmptyTasks();
- }
- return;
- }
- } while (((SetQueue.this.secondLast = System.currentTimeMillis()) - SetQueue.this.last) < free);
- }
- };
-
private ForkJoinPool pool = new ForkJoinPool();
+ private ExecutorCompletionService completer = new ExecutorCompletionService(pool);
+
+ /**
+ * @see TaskManager#getPublicForkJoinPool()
+ * @return ForkJoinPool
+ */
+ @Deprecated
+ public ExecutorCompletionService getCompleterService() {
+ return completer;
+ }
public SetQueue() {
tasks = new ConcurrentLinkedDeque<>();
@@ -65,56 +59,55 @@ public class SetQueue {
TaskManager.IMP.repeat(new Runnable() {
@Override
public void run() {
- while (!tasks.isEmpty() && Fawe.get().getTimer().isAbove(18.5)) {
- tasks.poll().run();
- }
- if (inactiveQueues.isEmpty() && activeQueues.isEmpty()) {
- lastSuccess = System.currentTimeMillis();
- runEmptyTasks();
- return;
- }
- if (!MemUtil.isMemoryFree()) {
- final int mem = MemUtil.calculateMemory();
- if (mem != Integer.MAX_VALUE) {
- if ((mem <= 1) && Settings.CRASH_MITIGATION) {
- for (FaweQueue queue : getAllQueues()) {
- queue.saveMemory();
+ try {
+ while (!tasks.isEmpty() && Fawe.get().getTimer().isAbove(18.5)) {
+ tasks.poll().run();
+ }
+ if (inactiveQueues.isEmpty() && activeQueues.isEmpty()) {
+ lastSuccess = System.currentTimeMillis();
+ runEmptyTasks();
+ return;
+ }
+ if (!MemUtil.isMemoryFree()) {
+ final int mem = MemUtil.calculateMemory();
+ if (mem != Integer.MAX_VALUE) {
+ if ((mem <= 1) && Settings.CRASH_MITIGATION) {
+ for (FaweQueue queue : getAllQueues()) {
+ queue.saveMemory();
+ }
+ return;
+ }
+ if (SetQueue.this.forceChunkSet()) {
+ System.gc();
+ } else {
+ SetQueue.this.runEmptyTasks();
}
return;
}
- if (SetQueue.this.forceChunkSet()) {
- System.gc();
- } else {
- SetQueue.this.runEmptyTasks();
- }
+ }
+ FaweQueue queue = getNextQueue();
+ if (queue == null || !Fawe.get().getTimer().isAbove(18.5)) {
return;
}
- }
- SET_TASK.value1 = Settings.QUEUE.EXTRA_TIME_MS + 50 + Math.min((50 + SetQueue.this.last) - (SetQueue.this.last = System.currentTimeMillis()), SetQueue.this.secondLast - System.currentTimeMillis());
- SET_TASK.value2 = getNextQueue();
- if (SET_TASK.value2 == null) {
- return;
- }
- if (Thread.currentThread() != Fawe.get().getMainThread()) {
- throw new IllegalStateException("This shouldn't be possible for placement to occur off the main thread");
- }
- // Disable the async catcher as it can't discern async vs parallel
- boolean parallel = Settings.QUEUE.PARALLEL_THREADS > 1;
- SET_TASK.value2.startSet(parallel);
- try {
- if (Settings.QUEUE.PARALLEL_THREADS <= 1 || !Fawe.get().isJava8()) {
- SET_TASK.run();
- } else {
- for (int i = 0; i < Settings.QUEUE.PARALLEL_THREADS; i++) {
- pool.submit(SET_TASK);
- }
- pool.awaitQuiescence(Settings.QUEUE.DISCARD_AFTER_MS, TimeUnit.MILLISECONDS);
+ if (Thread.currentThread() != Fawe.get().getMainThread()) {
+ throw new IllegalStateException("This shouldn't be possible for placement to occur off the main thread");
}
+ long time = Settings.QUEUE.EXTRA_TIME_MS + 50 + Math.min((50 + SetQueue.this.last) - (SetQueue.this.last = System.currentTimeMillis()), SetQueue.this.secondLast - System.currentTimeMillis());
+ // Disable the async catcher as it can't discern async vs parallel
+ boolean parallel = Settings.QUEUE.PARALLEL_THREADS > 1;
+ queue.startSet(parallel);
+ try {
+ if (!queue.next(Settings.QUEUE.PARALLEL_THREADS, getCompleterService(), time)) {
+ queue.runTasks();
+ }
+ } catch (Throwable e) {
+ pool.awaitQuiescence(Settings.QUEUE.DISCARD_AFTER_MS, TimeUnit.MILLISECONDS);
+ completer = new ExecutorCompletionService(pool);
+ e.printStackTrace();
+ }
+ secondLast = System.currentTimeMillis();
} catch (Throwable e) {
- MainUtil.handleError(e);
- } finally {
- // Enable it again (note that we are still on the main thread)
- SET_TASK.value2.endSet(parallel);
+ e.printStackTrace();
}
}
}, 1);
@@ -156,6 +149,7 @@ public class SetQueue {
public void dequeue(FaweQueue queue) {
inactiveQueues.remove(queue);
activeQueues.remove(queue);
+ queue.runTasks();
}
public Collection getAllQueues() {
@@ -181,44 +175,34 @@ public class SetQueue {
return queue;
}
+ public FaweQueue getNewQueue(String world, boolean fast, boolean autoqueue) {
+ FaweQueue queue = Fawe.imp().getNewQueue(world, fast);
+ if (autoqueue) {
+ inactiveQueues.add(queue);
+ }
+ return queue;
+ }
+
public void flush(FaweQueue queue) {
- SET_TASK.value1 = Long.MAX_VALUE;
- SET_TASK.value2 = queue;
- if (SET_TASK.value2 == null) {
- return;
- }
- if (Thread.currentThread() != Fawe.get().getMainThread()) {
- throw new IllegalStateException("Must be flushed on the main thread!");
- }
- // Disable the async catcher as it can't discern async vs parallel
- boolean parallel = Settings.QUEUE.PARALLEL_THREADS > 1;
- SET_TASK.value2.startSet(parallel);
+ queue.startSet(Settings.QUEUE.PARALLEL_THREADS > 1);
try {
- if (!parallel || !Fawe.get().isJava8()) {
- SET_TASK.run();
- } else {
- for (int i = 0; i < Settings.QUEUE.PARALLEL_THREADS; i++) {
- pool.submit(SET_TASK);
- }
- pool.awaitQuiescence(Settings.QUEUE.DISCARD_AFTER_MS, TimeUnit.MILLISECONDS);
- }
+ queue.next(Settings.QUEUE.PARALLEL_THREADS, getCompleterService(), Long.MAX_VALUE);
} catch (Throwable e) {
+ pool.awaitQuiescence(Settings.QUEUE.DISCARD_AFTER_MS, TimeUnit.MILLISECONDS);
+ completer = new ExecutorCompletionService(pool);
MainUtil.handleError(e);
- } finally {
- // Enable it again (note that we are still on the main thread)
- SET_TASK.value2.endSet(parallel);
- dequeue(queue);
}
}
public FaweQueue getNextQueue() {
long now = System.currentTimeMillis();
- while (activeQueues.size() > 0) {
+ while (!activeQueues.isEmpty()) {
FaweQueue queue = activeQueues.peek();
if (queue != null && queue.size() > 0) {
queue.setModified(now);
return queue;
} else {
+ queue.runTasks();
activeQueues.poll();
}
}
@@ -234,6 +218,7 @@ public class SetQueue {
total += queue.size();
if (queue.size() == 0) {
if (age > Settings.QUEUE.DISCARD_AFTER_MS) {
+ queue.runTasks();
iter.remove();
}
continue;
@@ -265,6 +250,8 @@ public class SetQueue {
if (set) {
activeQueues.add(queue);
return set;
+ } else {
+ queue.runTasks();
}
}
}
@@ -285,6 +272,9 @@ public class SetQueue {
}
if (diff > Settings.QUEUE.DISCARD_AFTER_MS) {
// These edits never finished
+ for (FaweQueue queue : tmp) {
+ queue.runTasks();
+ }
inactiveQueues.clear();
}
return false;
diff --git a/core/src/main/java/com/boydti/fawe/wrappers/PlayerWrapper.java b/core/src/main/java/com/boydti/fawe/wrappers/PlayerWrapper.java
index 9c1dc454..20d43776 100644
--- a/core/src/main/java/com/boydti/fawe/wrappers/PlayerWrapper.java
+++ b/core/src/main/java/com/boydti/fawe/wrappers/PlayerWrapper.java
@@ -214,7 +214,7 @@ public class PlayerWrapper implements Player {
TaskManager.IMP.sync(new RunnableVal