mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2024-12-28 20:19:09 +01:00
Various
More work on anvil API Fix IO exception with history on disk Optimize chunk index caching
This commit is contained in:
parent
4267bf1c27
commit
4ddffb197b
@ -115,7 +115,7 @@ public class BukkitChunk_1_10 extends CharFaweChunk<Chunk> {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
char combinedId = blocks[FaweCache.CACHE_J[y][x][z]];
|
||||
char combinedId = blocks[FaweCache.CACHE_J[y][z][x]];
|
||||
if (combinedId > 1) {
|
||||
palette.setBlock(x, y, z, Block.getById(combinedId >> 4).fromLegacyData(combinedId & 0xF));
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
lastBits = (DataBits) fieldBits.get(dataPaletteBlock);
|
||||
lastBlocks = dataPaletteBlock;
|
||||
}
|
||||
int i = FaweCache.CACHE_J[y][x & 15][z & 15];
|
||||
int i = FaweCache.CACHE_J[y][z & 15][x & 15];
|
||||
return lastBits.a(i) != 0;
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
@ -456,12 +456,12 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
int x = ((int) Math.round(ent.locX) & 15);
|
||||
int z = ((int) Math.round(ent.locZ) & 15);
|
||||
int y = (int) Math.round(ent.locY);
|
||||
int i = FaweCache.CACHE_I[y][x][z];
|
||||
int i = FaweCache.CACHE_I[y][z][x];
|
||||
char[] array = fs.getIdArray(i);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int j = FaweCache.CACHE_J[y][x][z];
|
||||
int j = FaweCache.CACHE_J[y][z][x];
|
||||
if (array[j] != 0) {
|
||||
String id = EntityTypes.b(ent);
|
||||
if (id != null) {
|
||||
@ -541,7 +541,7 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
if (array == null || y < 0 || y > 255) {
|
||||
continue;
|
||||
}
|
||||
if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][x][z]] != 0) {
|
||||
if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][z][x]] != 0) {
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
@ -607,12 +607,12 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
int lx = pos.getX() & 15;
|
||||
int ly = pos.getY();
|
||||
int lz = pos.getZ() & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lx][lz];
|
||||
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||
char[] array = fs.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lx][lz];
|
||||
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||
if (array[k] != 0) {
|
||||
if (toRemove == null) {
|
||||
toRemove = new HashMap<>();
|
||||
@ -666,10 +666,10 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
int nonEmptyBlockCount = 0;
|
||||
for (int y = 0; y < 16; y++) {
|
||||
short[][] i1 = FaweCache.CACHE_J[y];
|
||||
for (int x= 0; x < 16; x++) {
|
||||
short[] i2 = i1[x];
|
||||
for (int z = 0; z < 16; z++) {
|
||||
char combinedId = array[i2[z]];
|
||||
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);
|
||||
|
@ -34,8 +34,8 @@ public class BukkitChunk_1_7 extends CharFaweChunk<Chunk> {
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, int id, int data) {
|
||||
int i = FaweCache.CACHE_I[y][x][z];
|
||||
int j = FaweCache.CACHE_J[y][x][z];
|
||||
int i = FaweCache.CACHE_I[y][z][x];
|
||||
int j = FaweCache.CACHE_J[y][z][x];
|
||||
byte[] vs = this.byteIds[i];
|
||||
char[] vs2 = this.ids[i];
|
||||
if (vs2 == null) {
|
||||
|
@ -116,7 +116,7 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
|
||||
public int getCombinedId4Data(ChunkSection ls, int x, int y, int z) {
|
||||
byte[] ids = ls.getIdArray();
|
||||
NibbleArray datasNibble = ls.getDataArray();
|
||||
int i = FaweCache.CACHE_J[y & 15][x & 15][z & 15];
|
||||
int i = FaweCache.CACHE_J[y & 15][z & 15][x & 15];
|
||||
int combined = (ids[i] << 4) + (datasNibble == null ? 0 : datasNibble.a(x & 15, y & 15, z & 15));
|
||||
return combined;
|
||||
}
|
||||
@ -174,12 +174,12 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
|
||||
int x = ((int) Math.round(ent.locX) & 15);
|
||||
int z = ((int) Math.round(ent.locZ) & 15);
|
||||
int y = (int) Math.round(ent.locY);
|
||||
int i = FaweCache.CACHE_I[y][x][z];
|
||||
int i = FaweCache.CACHE_I[y][z][x];
|
||||
char[] array = fs.getIdArray(i);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int j = FaweCache.CACHE_J[y][x][z];
|
||||
int j = FaweCache.CACHE_J[y][z][x];
|
||||
if (array[j] != 0) {
|
||||
String id = EntityTypes.b(ent);
|
||||
if (id != null) {
|
||||
@ -257,7 +257,7 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][x][z]] != 0) {
|
||||
if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][z][x]] != 0) {
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
@ -309,12 +309,12 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
|
||||
int lx = pos.x & 15;
|
||||
int ly = pos.y;
|
||||
int lz = pos.z & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lx][lz];
|
||||
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||
char[] array = fs.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lx][lz];
|
||||
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||
if (array[k] != 0) {
|
||||
if (toRemove == null) {
|
||||
toRemove = new HashMap<>();
|
||||
@ -642,7 +642,7 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
|
||||
|
||||
@Override
|
||||
public boolean hasBlock(ChunkSection section, int x, int y, int z) {
|
||||
int i = FaweCache.CACHE_J[y & 15][x & 15][z & 15];
|
||||
int i = FaweCache.CACHE_J[y & 15][z & 15][x & 15];
|
||||
return section.getIdArray()[i] != 0;
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,7 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkS
|
||||
@Override
|
||||
public int getCombinedId4Data(ChunkSection section, int x, int y, int z) {
|
||||
char[] ls = section.getIdArray();
|
||||
return ls[FaweCache.CACHE_J[y][x & 15][z & 15]];
|
||||
return ls[FaweCache.CACHE_J[y][z & 15][x & 15]];
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -169,12 +169,12 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkS
|
||||
int x = ((int) Math.round(ent.locX) & 15);
|
||||
int z = ((int) Math.round(ent.locZ) & 15);
|
||||
int y = (int) Math.round(ent.locY);
|
||||
int i = FaweCache.CACHE_I[y][x][z];
|
||||
int i = FaweCache.CACHE_I[y][z][x];
|
||||
char[] array = fs.getIdArray(i);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int j = FaweCache.CACHE_J[y][x][z];
|
||||
int j = FaweCache.CACHE_J[y][z][x];
|
||||
if (array[j] != 0) {
|
||||
String id = EntityTypes.b(ent);
|
||||
if (id != null) {
|
||||
@ -254,7 +254,7 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkS
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][x][z]] != 0) {
|
||||
if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][z][x]] != 0) {
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
@ -306,12 +306,12 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkS
|
||||
int lx = pos.getX() & 15;
|
||||
int ly = pos.getY();
|
||||
int lz = pos.getZ() & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lx][lz];
|
||||
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||
char[] array = fs.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lx][lz];
|
||||
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||
if (array[k] != 0) {
|
||||
if (toRemove == null) {
|
||||
toRemove = new HashMap<>();
|
||||
@ -634,7 +634,7 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkS
|
||||
|
||||
@Override
|
||||
public boolean hasBlock(ChunkSection section, int x, int y, int z) {
|
||||
int i = FaweCache.CACHE_J[y & 15][x & 15][z & 15];
|
||||
int i = FaweCache.CACHE_J[y & 15][z & 15][x & 15];
|
||||
return section.getIdArray()[i] != 0;
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,7 @@ public class BukkitChunk_1_9 extends CharFaweChunk<Chunk> {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
char combinedId = blocks[FaweCache.CACHE_J[y][x][z]];
|
||||
char combinedId = blocks[FaweCache.CACHE_J[y][z][x]];
|
||||
if (combinedId > 1) {
|
||||
palette.setBlock(x, y, z, Block.getById(combinedId >> 4).fromLegacyData(combinedId & 0xF));
|
||||
}
|
||||
|
@ -297,12 +297,12 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Chu
|
||||
if ((y < 0) || (y > 255)) {
|
||||
return 1;
|
||||
}
|
||||
final int i = FaweCache.CACHE_I[y][x][z];
|
||||
final int i = FaweCache.CACHE_I[y][z][x];
|
||||
final char[] section = sections[i];
|
||||
if (section == null) {
|
||||
return 0;
|
||||
}
|
||||
final int j = FaweCache.CACHE_J[y][x][z];
|
||||
final int j = FaweCache.CACHE_J[y][z][x];
|
||||
return section[j] >> 4;
|
||||
}
|
||||
|
||||
@ -401,12 +401,12 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Chu
|
||||
int x = ((int) Math.round(ent.locX) & 15);
|
||||
int z = ((int) Math.round(ent.locZ) & 15);
|
||||
int y = (int) Math.round(ent.locY);
|
||||
int i = FaweCache.CACHE_I[y][x][z];
|
||||
int i = FaweCache.CACHE_I[y][z][x];
|
||||
char[] array = fs.getIdArray(i);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int j = FaweCache.CACHE_J[y][x][z];
|
||||
int j = FaweCache.CACHE_J[y][z][x];
|
||||
if (array[j] != 0) {
|
||||
String id = EntityTypes.b(ent);
|
||||
if (id != null) {
|
||||
@ -487,7 +487,7 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Chu
|
||||
if (array == null || y < 0 || y > 255) {
|
||||
continue;
|
||||
}
|
||||
if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][x][z]] != 0) {
|
||||
if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][z][x]] != 0) {
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
@ -553,12 +553,12 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Chu
|
||||
int lx = pos.getX() & 15;
|
||||
int ly = pos.getY();
|
||||
int lz = pos.getZ() & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lx][lz];
|
||||
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||
char[] array = fs.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lx][lz];
|
||||
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||
if (array[k] != 0) {
|
||||
if (toRemove == null) {
|
||||
toRemove = new HashMap<>();
|
||||
@ -620,7 +620,7 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Chu
|
||||
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][x][z]];
|
||||
char combinedId = array[FaweCache.CACHE_J[y][z][x]];
|
||||
switch (combinedId) {
|
||||
case 0:
|
||||
IBlockData existing = nibble.a(x, y, z);
|
||||
@ -762,7 +762,7 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Chu
|
||||
lastBits = (DataBits) fieldBits.get(dataPaletteBlock);
|
||||
lastBlocks = dataPaletteBlock;
|
||||
}
|
||||
int i = FaweCache.CACHE_J[y][x & 15][z & 15];
|
||||
int i = FaweCache.CACHE_J[y][z & 15][x & 15];
|
||||
return lastBits.a(i) != 0;
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
|
@ -27,11 +27,11 @@ import java.util.Map;
|
||||
|
||||
public class FaweCache {
|
||||
/**
|
||||
* [ y | x | z ] => index
|
||||
* [ y | z | x ] => index
|
||||
*/
|
||||
public final static short[][][] CACHE_I = new short[256][16][16];
|
||||
/**
|
||||
* [ y | x | z ] => index
|
||||
* [ y | z | x ] => index
|
||||
*/
|
||||
public final static short[][][] CACHE_J = new short[256][16][16];
|
||||
|
||||
@ -128,8 +128,8 @@ public class FaweCache {
|
||||
for (int y = 0; y < 256; y++) {
|
||||
final short i = (short) (y >> 4);
|
||||
final short j = (short) (((y & 0xF) << 8) | (z << 4) | x);
|
||||
CACHE_I[y][x][z] = i;
|
||||
CACHE_J[y][x][z] = j;
|
||||
CACHE_I[y][z][x] = i;
|
||||
CACHE_J[y][z][x] = j;
|
||||
CACHE_X[i][j] = (byte) x;
|
||||
CACHE_Y[i][j] = (short) y;
|
||||
CACHE_Z[i][j] = (byte) z;
|
||||
@ -622,9 +622,12 @@ public class FaweCache {
|
||||
return asTag((Collection) value);
|
||||
} else if (value instanceof byte[]) {
|
||||
return asTag((byte[]) value);
|
||||
} else if (value instanceof int[]) {
|
||||
return asTag((int[]) value);
|
||||
} else if (value instanceof Tag) {
|
||||
return (Tag) value;
|
||||
} else if (value == null) {
|
||||
System.out.println("Invalid nbt: " + value);
|
||||
return null;
|
||||
} else {
|
||||
Class<? extends Object> clazz = value.getClass();
|
||||
@ -640,6 +643,7 @@ public class FaweCache {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
System.out.println("Invalid nbt: " + value);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,12 @@ public abstract class CharFaweChunk<T> extends FaweChunk<T> {
|
||||
public int[][] biomes;
|
||||
private int bitMask = -1;
|
||||
|
||||
public HashMap<BytePair, CompoundTag> tiles;
|
||||
|
||||
public HashSet<CompoundTag> entities;
|
||||
|
||||
public HashSet<UUID> entityRemoves;
|
||||
|
||||
public T chunk;
|
||||
|
||||
/**
|
||||
@ -139,16 +145,14 @@ public abstract class CharFaweChunk<T> extends FaweChunk<T> {
|
||||
}
|
||||
|
||||
public int getCombinedId(int x, int y, int z) {
|
||||
short i = FaweCache.CACHE_I[y][x][z];
|
||||
short i = FaweCache.CACHE_I[y][z][x];
|
||||
char[] array = getIdArray(i);
|
||||
if (array == null) {
|
||||
return 0;
|
||||
}
|
||||
return array[FaweCache.CACHE_J[y][x][z]];
|
||||
return array[FaweCache.CACHE_J[y][z][x]];
|
||||
}
|
||||
|
||||
public HashMap<BytePair, CompoundTag> tiles;
|
||||
|
||||
@Override
|
||||
public void setTile(int x, int y, int z, CompoundTag tile) {
|
||||
if (tiles == null) {
|
||||
@ -181,12 +185,6 @@ public abstract class CharFaweChunk<T> extends FaweChunk<T> {
|
||||
return entities == null ? new HashSet<CompoundTag>() : entities;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public HashSet<CompoundTag> entities;
|
||||
|
||||
public HashSet<UUID> entityRemoves;
|
||||
|
||||
@Override
|
||||
public void setEntity(CompoundTag tag) {
|
||||
if (entities == null) {
|
||||
@ -210,8 +208,8 @@ public abstract class CharFaweChunk<T> extends FaweChunk<T> {
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, int id) {
|
||||
final int i = FaweCache.CACHE_I[y][x][z];
|
||||
final int j = FaweCache.CACHE_J[y][x][z];
|
||||
final int i = FaweCache.CACHE_I[y][z][x];
|
||||
final int j = FaweCache.CACHE_J[y][z][x];
|
||||
char[] vs = this.ids[i];
|
||||
if (vs == null) {
|
||||
vs = this.ids[i] = new char[4096];
|
||||
@ -249,8 +247,8 @@ public abstract class CharFaweChunk<T> extends FaweChunk<T> {
|
||||
|
||||
@Override
|
||||
public void setBlock(final int x, final int y, final int z, final int id, int data) {
|
||||
final int i = FaweCache.CACHE_I[y][x][z];
|
||||
final int j = FaweCache.CACHE_J[y][x][z];
|
||||
final int i = FaweCache.CACHE_I[y][z][x];
|
||||
final int j = FaweCache.CACHE_J[y][z][x];
|
||||
char[] vs = this.ids[i];
|
||||
if (vs == null) {
|
||||
vs = this.ids[i] = new char[4096];
|
||||
|
@ -0,0 +1,118 @@
|
||||
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 java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
|
||||
public class DefaultFaweQueueMap implements IFaweQueueMap {
|
||||
|
||||
private final MappedFaweQueue parent;
|
||||
|
||||
public DefaultFaweQueueMap(MappedFaweQueue parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map of chunks in the queue
|
||||
*/
|
||||
public ConcurrentHashMap<Long, FaweChunk> blocks = new ConcurrentHashMap<>();
|
||||
public ConcurrentLinkedDeque<FaweChunk> chunks = new ConcurrentLinkedDeque<FaweChunk>() {
|
||||
@Override
|
||||
public boolean add(FaweChunk o) {
|
||||
if (parent.getProgressTask() != null) {
|
||||
parent.getProgressTask().run(FaweQueue.ProgressType.QUEUE, size() + 1);
|
||||
}
|
||||
return super.add(o);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public Collection<FaweChunk> getFaweCunks() {
|
||||
return new HashSet<>(chunks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachChunk(RunnableVal<FaweChunk> onEach) {
|
||||
for (FaweChunk chunk : chunks) {
|
||||
onEach.run(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk getFaweChunk(int cx, int cz) {
|
||||
if (cx == lastX && cz == lastZ) {
|
||||
return lastWrappedChunk;
|
||||
}
|
||||
long pair = (long) (lastX = cx) << 32 | (lastX = cz) & 0xFFFFFFFFL;
|
||||
FaweChunk chunk = this.blocks.get(pair);
|
||||
if (chunk == null) {
|
||||
chunk = this.getNewFaweChunk(cx, cz);
|
||||
FaweChunk previous = this.blocks.put(pair, chunk);
|
||||
if (previous != null) {
|
||||
blocks.put(pair, previous);
|
||||
return previous;
|
||||
}
|
||||
this.blocks.put(pair, previous);
|
||||
chunks.add(previous);
|
||||
}
|
||||
return chunk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(FaweChunk chunk) {
|
||||
long pair = (long) (chunk.getX()) << 32 | (chunk.getZ()) & 0xFFFFFFFFL;
|
||||
FaweChunk previous = this.blocks.put(pair, chunk);
|
||||
if (previous == null) {
|
||||
chunks.add(chunk);
|
||||
} else {
|
||||
blocks.put(pair, previous);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
blocks.clear();
|
||||
chunks.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return chunks.size();
|
||||
}
|
||||
|
||||
private FaweChunk getNewFaweChunk(int cx, int cz) {
|
||||
return parent.getFaweChunk(cx, cz);
|
||||
}
|
||||
|
||||
private FaweChunk lastWrappedChunk;
|
||||
private int lastX = Integer.MIN_VALUE;
|
||||
private int lastZ = Integer.MIN_VALUE;
|
||||
|
||||
@Override
|
||||
public boolean next() {
|
||||
lastX = Integer.MIN_VALUE;
|
||||
lastZ = Integer.MIN_VALUE;
|
||||
try {
|
||||
if (this.blocks.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
synchronized (blocks) {
|
||||
FaweChunk chunk = chunks.poll();
|
||||
if (chunk != null) {
|
||||
blocks.remove(chunk.longHash());
|
||||
parent.execute(chunk);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.boydti.fawe.example;
|
||||
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import java.util.Collection;
|
||||
|
||||
public interface IFaweQueueMap {
|
||||
|
||||
Collection<FaweChunk> getFaweCunks();
|
||||
|
||||
void forEachChunk(RunnableVal<FaweChunk> onEach);
|
||||
|
||||
FaweChunk getFaweChunk(int cx, int cz);
|
||||
|
||||
void add(FaweChunk chunk);
|
||||
|
||||
void clear();
|
||||
|
||||
int size();
|
||||
|
||||
boolean next();
|
||||
}
|
@ -19,48 +19,53 @@ import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
|
||||
public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
|
||||
private WORLD impWorld;
|
||||
|
||||
/**
|
||||
* Map of chunks in the queue
|
||||
*/
|
||||
public ConcurrentHashMap<Long, FaweChunk> blocks = new ConcurrentHashMap<>();
|
||||
public ConcurrentLinkedDeque<FaweChunk> chunks = new ConcurrentLinkedDeque<FaweChunk>() {
|
||||
@Override
|
||||
public boolean add(FaweChunk o) {
|
||||
if (getProgressTask() != null) {
|
||||
getProgressTask().run(ProgressType.QUEUE, size() + 1);
|
||||
}
|
||||
return super.add(o);
|
||||
}
|
||||
};
|
||||
private IFaweQueueMap map;
|
||||
public ArrayDeque<Runnable> tasks = new ArrayDeque<>();
|
||||
|
||||
public MappedFaweQueue(final String world) {
|
||||
this(world, null);
|
||||
}
|
||||
|
||||
public MappedFaweQueue(final String world, IFaweQueueMap map) {
|
||||
super(world);
|
||||
if (map == null) {
|
||||
map = new DefaultFaweQueueMap(this);
|
||||
}
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public IFaweQueueMap getFaweQueueMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<FaweChunk> getFaweChunks() {
|
||||
return Collections.unmodifiableCollection(chunks);
|
||||
return map.getFaweCunks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void optimize() {
|
||||
ArrayList<Thread> threads = new ArrayList<Thread>();
|
||||
for (final FaweChunk chunk : chunks) {
|
||||
Thread thread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
chunk.optimize();
|
||||
}
|
||||
});
|
||||
threads.add(thread);
|
||||
thread.start();
|
||||
}
|
||||
final ArrayList<Thread> threads = new ArrayList<Thread>();
|
||||
map.forEachChunk(new RunnableVal<FaweChunk>() {
|
||||
@Override
|
||||
public void run(final FaweChunk chunk) {
|
||||
Thread thread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
chunk.optimize();
|
||||
}
|
||||
});
|
||||
threads.add(thread);
|
||||
thread.start();
|
||||
}
|
||||
});
|
||||
for (Thread thread : threads) {
|
||||
try {
|
||||
thread.join();
|
||||
@ -76,10 +81,6 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
size();
|
||||
}
|
||||
|
||||
public MappedFaweQueue(final String world) {
|
||||
super(world);
|
||||
}
|
||||
|
||||
public abstract WORLD getImpWorld();
|
||||
|
||||
public abstract boolean isChunkLoaded(WORLD world, int x, int z);
|
||||
@ -114,50 +115,16 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
|
||||
@Override
|
||||
public void addNotifyTask(int x, int z, Runnable runnable) {
|
||||
long pair = (long) (x) << 32 | (z) & 0xFFFFFFFFL;
|
||||
FaweChunk result = this.blocks.get(pair);
|
||||
if (result == null) {
|
||||
result = this.getFaweChunk(x, z);
|
||||
result.addNotifyTask(runnable);
|
||||
FaweChunk previous = this.blocks.put(pair, result);
|
||||
if (previous == null) {
|
||||
chunks.add(result);
|
||||
return;
|
||||
}
|
||||
this.blocks.put(pair, previous);
|
||||
result = previous;
|
||||
}
|
||||
result.addNotifyTask(runnable);
|
||||
FaweChunk chunk = map.getFaweChunk(x, z);
|
||||
chunk.addNotifyTask(runnable);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private FaweChunk lastWrappedChunk;
|
||||
private int lastX = Integer.MIN_VALUE;
|
||||
private int lastZ = Integer.MIN_VALUE;
|
||||
|
||||
@Override
|
||||
public boolean setBlock(int x, int y, int z, int id, int data) {
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
if (cx != lastX || cz != lastZ) {
|
||||
lastX = cx;
|
||||
lastZ = cz;
|
||||
long pair = (long) (cx) << 32 | (cz) & 0xFFFFFFFFL;
|
||||
lastWrappedChunk = this.blocks.get(pair);
|
||||
if (lastWrappedChunk == null) {
|
||||
lastWrappedChunk = this.getFaweChunk(cx, cz);
|
||||
lastWrappedChunk.setBlock(x & 15, y, z & 15, id, data);
|
||||
FaweChunk previous = this.blocks.put(pair, lastWrappedChunk);
|
||||
if (previous == null) {
|
||||
chunks.add(lastWrappedChunk);
|
||||
return true;
|
||||
}
|
||||
this.blocks.put(pair, previous);
|
||||
lastWrappedChunk = previous;
|
||||
}
|
||||
}
|
||||
lastWrappedChunk.setBlock(x & 15, y, z & 15, id, data);
|
||||
FaweChunk chunk = map.getFaweChunk(cx, cz);
|
||||
chunk.setBlock(x & 15, y, z & 15, id, data);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -165,24 +132,8 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
public boolean setBlock(int x, int y, int z, int id) {
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
if (cx != lastX || cz != lastZ) {
|
||||
lastX = cx;
|
||||
lastZ = cz;
|
||||
long pair = (long) (cx) << 32 | (cz) & 0xFFFFFFFFL;
|
||||
lastWrappedChunk = this.blocks.get(pair);
|
||||
if (lastWrappedChunk == null) {
|
||||
lastWrappedChunk = this.getFaweChunk(x >> 4, z >> 4);
|
||||
lastWrappedChunk.setBlock(x & 15, y, z & 15, id);
|
||||
FaweChunk previous = this.blocks.put(pair, lastWrappedChunk);
|
||||
if (previous == null) {
|
||||
chunks.add(lastWrappedChunk);
|
||||
return true;
|
||||
}
|
||||
this.blocks.put(pair, previous);
|
||||
lastWrappedChunk = previous;
|
||||
}
|
||||
}
|
||||
lastWrappedChunk.setBlock(x & 15, y, z & 15, id);
|
||||
FaweChunk chunk = map.getFaweChunk(cx, cz);
|
||||
chunk.setBlock(x & 15, y, z & 15, id);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -193,24 +144,8 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
}
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
if (cx != lastX || cz != lastZ) {
|
||||
lastX = cx;
|
||||
lastZ = cz;
|
||||
long pair = (long) (cx) << 32 | (cz) & 0xFFFFFFFFL;
|
||||
lastWrappedChunk = this.blocks.get(pair);
|
||||
if (lastWrappedChunk == null) {
|
||||
lastWrappedChunk = this.getFaweChunk(x >> 4, z >> 4);
|
||||
lastWrappedChunk.setTile(x & 15, y, z & 15, tag);
|
||||
FaweChunk previous = this.blocks.put(pair, lastWrappedChunk);
|
||||
if (previous == null) {
|
||||
chunks.add(lastWrappedChunk);
|
||||
return;
|
||||
}
|
||||
this.blocks.put(pair, previous);
|
||||
lastWrappedChunk = previous;
|
||||
}
|
||||
}
|
||||
lastWrappedChunk.setTile(x & 15, y, z & 15, tag);
|
||||
FaweChunk chunk = map.getFaweChunk(cx, cz);
|
||||
chunk.setTile(x & 15, y, z & 15, tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -220,24 +155,8 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
}
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
if (cx != lastX || cz != lastZ) {
|
||||
lastX = cx;
|
||||
lastZ = cz;
|
||||
long pair = (long) (cx) << 32 | (cz) & 0xFFFFFFFFL;
|
||||
lastWrappedChunk = this.blocks.get(pair);
|
||||
if (lastWrappedChunk == null) {
|
||||
lastWrappedChunk = this.getFaweChunk(x >> 4, z >> 4);
|
||||
lastWrappedChunk.setEntity(tag);
|
||||
FaweChunk previous = this.blocks.put(pair, lastWrappedChunk);
|
||||
if (previous == null) {
|
||||
chunks.add(lastWrappedChunk);
|
||||
return;
|
||||
}
|
||||
this.blocks.put(pair, previous);
|
||||
lastWrappedChunk = previous;
|
||||
}
|
||||
}
|
||||
lastWrappedChunk.setEntity(tag);
|
||||
FaweChunk chunk = map.getFaweChunk(cx, cz);
|
||||
chunk.setEntity(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -247,64 +166,22 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
}
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
if (cx != lastX || cz != lastZ) {
|
||||
lastX = cx;
|
||||
lastZ = cz;
|
||||
long pair = (long) (cx) << 32 | (cz) & 0xFFFFFFFFL;
|
||||
lastWrappedChunk = this.blocks.get(pair);
|
||||
if (lastWrappedChunk == null) {
|
||||
lastWrappedChunk = this.getFaweChunk(x >> 4, z >> 4);
|
||||
lastWrappedChunk.removeEntity(uuid);
|
||||
FaweChunk previous = this.blocks.put(pair, lastWrappedChunk);
|
||||
if (previous == null) {
|
||||
chunks.add(lastWrappedChunk);
|
||||
return;
|
||||
}
|
||||
this.blocks.put(pair, previous);
|
||||
lastWrappedChunk = previous;
|
||||
}
|
||||
}
|
||||
lastWrappedChunk.removeEntity(uuid);
|
||||
FaweChunk chunk = map.getFaweChunk(cx, cz);
|
||||
chunk.removeEntity(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(int x, int z, BaseBiome biome) {
|
||||
long pair = (long) (x >> 4) << 32 | (z >> 4) & 0xFFFFFFFFL;
|
||||
FaweChunk result = this.blocks.get(pair);
|
||||
if (result == null) {
|
||||
result = this.getFaweChunk(x >> 4, z >> 4);
|
||||
FaweChunk previous = this.blocks.put(pair, result);
|
||||
if (previous != null) {
|
||||
this.blocks.put(pair, previous);
|
||||
result = previous;
|
||||
} else {
|
||||
chunks.add(result);
|
||||
}
|
||||
}
|
||||
result.setBiome(x & 15, z & 15, biome);
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
FaweChunk chunk = map.getFaweChunk(cx, cz);
|
||||
chunk.setBiome(x & 15, z & 15, biome);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk next() {
|
||||
lastX = Integer.MIN_VALUE;
|
||||
lastZ = Integer.MIN_VALUE;
|
||||
try {
|
||||
if (this.blocks.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
synchronized (blocks) {
|
||||
FaweChunk chunk = chunks.poll();
|
||||
if (chunk != null) {
|
||||
blocks.remove(chunk.longHash());
|
||||
this.execute(chunk);
|
||||
return chunk;
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
return null;
|
||||
public boolean next() {
|
||||
return map.next();
|
||||
}
|
||||
|
||||
public void runTasks() {
|
||||
@ -324,7 +201,7 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
int size = chunks.size();
|
||||
int size = map.size();
|
||||
if (size == 0 && SetQueue.IMP.getStage(this) != SetQueue.QueueStage.INACTIVE) {
|
||||
runTasks();
|
||||
}
|
||||
@ -341,7 +218,7 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
}
|
||||
// Set blocks / entities / biome
|
||||
if (getProgressTask() != null) {
|
||||
getProgressTask().run(ProgressType.QUEUE, chunks.size());
|
||||
getProgressTask().run(ProgressType.QUEUE, map.size());
|
||||
getProgressTask().run(ProgressType.DISPATCH, ++dispatched);
|
||||
}
|
||||
if (getChangeTask() != null) {
|
||||
@ -362,18 +239,13 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.blocks.clear();
|
||||
this.chunks.clear();
|
||||
map.clear();
|
||||
runTasks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChunk(FaweChunk chunk) {
|
||||
FaweChunk previous = this.blocks.put(chunk.longHash(), (FaweChunk) chunk);
|
||||
if (previous != null) {
|
||||
chunks.remove(previous);
|
||||
}
|
||||
chunks.add((FaweChunk) chunk);
|
||||
map.add(chunk);
|
||||
}
|
||||
|
||||
public int lastChunkX = Integer.MIN_VALUE;
|
||||
|
@ -16,6 +16,10 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
|
||||
super(world);
|
||||
}
|
||||
|
||||
public NMSMappedFaweQueue(String world, IFaweQueueMap map) {
|
||||
super(world, map);
|
||||
}
|
||||
|
||||
private NMSRelighter relighter;
|
||||
|
||||
@Override
|
||||
@ -87,12 +91,12 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
|
||||
if ((y < 0) || (y > 255)) {
|
||||
return 1;
|
||||
}
|
||||
final int i = FaweCache.CACHE_I[y][x][z];
|
||||
final int i = FaweCache.CACHE_I[y][z][x];
|
||||
final char[] section = sections[i];
|
||||
if (section == null) {
|
||||
return 0;
|
||||
}
|
||||
final int j = FaweCache.CACHE_J[y][x][z];
|
||||
final int j = FaweCache.CACHE_J[y][z][x];
|
||||
return section[j] >> 4;
|
||||
}
|
||||
|
||||
|
@ -1,22 +0,0 @@
|
||||
package com.boydti.fawe.jnbt;
|
||||
|
||||
import com.boydti.fawe.example.CharFaweChunk;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
|
||||
public class MCAChunk extends CharFaweChunk<Void> {
|
||||
/**
|
||||
* A FaweSections object represents a chunk and the blocks that you wish to change in it.
|
||||
*
|
||||
* @param parent
|
||||
* @param x
|
||||
* @param z
|
||||
*/
|
||||
public MCAChunk(FaweQueue parent, int x, int z) {
|
||||
super(parent, x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void getNewChunk() {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,146 +0,0 @@
|
||||
package com.boydti.fawe.jnbt;
|
||||
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.RunnableVal3;
|
||||
import com.boydti.fawe.object.io.BufferedRandomAccessFile;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.zip.Inflater;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
|
||||
public class MCAFile {
|
||||
private final File file;
|
||||
private final BufferedRandomAccessFile raf;
|
||||
public final byte[] locations;
|
||||
private Field fieldBuf1;
|
||||
private Field fieldBuf2;
|
||||
private Field fieldBuf3;
|
||||
|
||||
private byte[] buffer1 = new byte[Settings.HISTORY.BUFFER_SIZE];
|
||||
private byte[] buffer2 = new byte[Settings.HISTORY.BUFFER_SIZE];
|
||||
private byte[] buffer3 = new byte[720];
|
||||
|
||||
|
||||
public MCAFile(File file) throws Exception {
|
||||
this.file = file;
|
||||
if (!file.exists()) {
|
||||
throw new FileNotFoundException(file.toString());
|
||||
}
|
||||
this.locations = new byte[4096];
|
||||
this.raf = new BufferedRandomAccessFile(file, "rw", Settings.HISTORY.BUFFER_SIZE);
|
||||
raf.read(locations);
|
||||
fieldBuf1 = BufferedInputStream.class.getDeclaredField("buf");
|
||||
fieldBuf1.setAccessible(true);
|
||||
fieldBuf2 = InflaterInputStream.class.getDeclaredField("buf");
|
||||
fieldBuf2.setAccessible(true);
|
||||
fieldBuf3 = NBTInputStream.class.getDeclaredField("buf");
|
||||
fieldBuf3.setAccessible(true);
|
||||
}
|
||||
|
||||
|
||||
public MCAFile(File regionFolder, int mcrX, int mcrZ) throws Exception {
|
||||
this(new File(regionFolder, "r." + mcrX + "." + mcrZ + ".mca"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param onEach cx, cz, offset
|
||||
*/
|
||||
public void forEachChunk(RunnableVal3<Integer, Integer, Integer> onEach) {
|
||||
int i = 0;
|
||||
for (int z = 0; z < 32; z++) {
|
||||
for (int x = 0; x < 32; x++, i += 4) {
|
||||
int offset = (((locations[i] & 0xFF) << 16) + ((locations[i + 1] & 0xFF) << 8) + ((locations[i+ 2] & 0xFF)));
|
||||
int size = locations[i + 3] & 0xFF;
|
||||
if (size != 0) {
|
||||
onEach.run(x, z, offset << 12);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getOffset(int cx, int cz) {
|
||||
int i = (cx << 2) + (cz << 7);
|
||||
int offset = (((locations[i] & 0xFF) << 16) + ((locations[i + 1] & 0xFF) << 8) + ((locations[i+ 2] & 0xFF)));
|
||||
int size = locations[i + 3] & 0xFF;
|
||||
return offset << 12;
|
||||
}
|
||||
|
||||
|
||||
private NBTStreamer getChunkReader(int offset) throws Exception {
|
||||
raf.seek(offset);
|
||||
int size = raf.readInt();
|
||||
int compression = raf.readByte();
|
||||
byte[] data = new byte[size];
|
||||
raf.read(data);
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(data);
|
||||
InflaterInputStream iis = new InflaterInputStream(bais, new Inflater(), 1);
|
||||
fieldBuf2.set(iis, buffer2);
|
||||
BufferedInputStream bis = new BufferedInputStream(iis, 1);
|
||||
fieldBuf1.set(bis, buffer1);
|
||||
NBTInputStream nis = new NBTInputStream(bis);
|
||||
fieldBuf3.set(nis, buffer3);
|
||||
return new NBTStreamer(nis);
|
||||
}
|
||||
|
||||
public int countId(int offset, final int id) throws Exception {
|
||||
try {
|
||||
NBTStreamer streamer = getChunkReader(offset);
|
||||
NBTStreamer.ByteReader reader = new NBTStreamer.ByteReader() {
|
||||
public int countId = id;
|
||||
public int count = 0;
|
||||
@Override
|
||||
public void run(int index, int byteValue) {
|
||||
if (byteValue == countId) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
};
|
||||
streamer.addReader(".Level.Sections.#.Blocks.#", reader);
|
||||
streamer.readFully();
|
||||
return reader.getClass().getField("count").getInt(reader);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
File folder = new File("../../mc/world/region");
|
||||
long start = System.nanoTime();
|
||||
final AtomicInteger count = new AtomicInteger();
|
||||
final int id = 1;
|
||||
for (File file : folder.listFiles()) {
|
||||
// {
|
||||
// File file = new File(folder, "r.0.0.mca");
|
||||
System.out.println(file);
|
||||
final MCAFile mca = new MCAFile(file);
|
||||
mca.forEachChunk(new RunnableVal3<Integer, Integer, Integer>() {
|
||||
@Override
|
||||
public void run(Integer cx, Integer cz, Integer offset) {
|
||||
try {
|
||||
count.addAndGet(mca.countId(offset, id));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
long diff = System.nanoTime() - start;
|
||||
System.out.println(diff / 1000000d);
|
||||
|
||||
System.out.println("Count: " + count);
|
||||
|
||||
// My results
|
||||
// 496,772,342 stone
|
||||
// 35,164 chunks
|
||||
// 17.175 seconds
|
||||
|
||||
|
||||
}
|
||||
}
|
397
core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java
Normal file
397
core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java
Normal file
@ -0,0 +1,397 @@
|
||||
package com.boydti.fawe.jnbt.anvil;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.jnbt.NBTStreamer;
|
||||
import com.boydti.fawe.object.BytePair;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.RunnableVal2;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class MCAChunk extends FaweChunk<Void> {
|
||||
|
||||
// ids: byte[16][4096]
|
||||
// data: byte[16][2048]
|
||||
// skylight: byte[16][2048]
|
||||
// blocklight: byte[16][2048]
|
||||
// entities: Map<BytePair, CompoundTag>
|
||||
// tiles: List<CompoundTag>
|
||||
// biomes: byte[256]
|
||||
// compressedSize: int
|
||||
// modified: boolean
|
||||
// deleted: boolean
|
||||
|
||||
public byte[][] ids;
|
||||
public byte[][] data;
|
||||
public byte[][] skyLight;
|
||||
public byte[][] blockLight;
|
||||
public byte[] biomes;
|
||||
public Map<BytePair, CompoundTag> tiles = new HashMap<>();
|
||||
public Map<UUID, CompoundTag> entities = new HashMap<>();
|
||||
private long inhabitedTime;
|
||||
private long lastUpdate;
|
||||
private int[] heightMap;
|
||||
|
||||
public int compressedSize;
|
||||
private boolean modified;
|
||||
private boolean deleted;
|
||||
|
||||
public CompoundTag toTag() {
|
||||
if (deleted) {
|
||||
return null;
|
||||
}
|
||||
// TODO optimize this as it's slow
|
||||
// e.g. by precalculating the length
|
||||
HashMap<String, Object> level = new HashMap<String, Object>();
|
||||
level.put("Entities", new ListTag(CompoundTag.class, new ArrayList<CompoundTag>(entities.values())));
|
||||
level.put("TileEntities", new ListTag(CompoundTag.class, new ArrayList<CompoundTag>(tiles.values())));
|
||||
level.put("InhabitedTime", inhabitedTime);
|
||||
level.put("LastUpdate", lastUpdate);
|
||||
level.put("LightPopulated", (byte) 0);
|
||||
level.put("TerrainPopulated", (byte) 1);
|
||||
level.put("V", (byte) 1);
|
||||
level.put("xPos", getX());
|
||||
level.put("zPos", getZ());
|
||||
if (biomes != null) {
|
||||
level.put("Biomes", biomes);
|
||||
}
|
||||
level.put("HeightMap", heightMap);
|
||||
ArrayList<HashMap<String, Object>> sections = new ArrayList<>();
|
||||
for (int layer = 0; layer < ids.length; layer++) {
|
||||
byte[] idLayer = ids[layer];
|
||||
if (idLayer == null) {
|
||||
continue;
|
||||
}
|
||||
HashMap<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("Y", (byte) layer);
|
||||
map.put("BlockLight", blockLight[layer]);
|
||||
map.put("SkyLight", skyLight[layer]);
|
||||
map.put("Blocks", idLayer);
|
||||
map.put("Data", data[layer]);
|
||||
sections.add(map);
|
||||
}
|
||||
level.put("Sections", sections);
|
||||
HashMap<String, Object> root = new HashMap<>();
|
||||
root.put("Level", level);
|
||||
return FaweCache.asTag(root);
|
||||
}
|
||||
|
||||
public MCAChunk(MCAChunk parent, boolean shallow) {
|
||||
super(parent.getParent(), parent.getX(), parent.getZ());
|
||||
if (shallow) {
|
||||
this.ids = parent.ids;
|
||||
this.data = parent.data;
|
||||
this.skyLight = parent.skyLight;
|
||||
this.blockLight = parent.blockLight;
|
||||
this.biomes = parent.biomes;
|
||||
this.tiles = parent.tiles;
|
||||
this.entities = parent.entities;
|
||||
this.inhabitedTime = parent.inhabitedTime;
|
||||
this.lastUpdate = parent.lastUpdate;
|
||||
this.heightMap = parent.heightMap;
|
||||
this.compressedSize = parent.compressedSize;
|
||||
this.modified = parent.modified;
|
||||
this.deleted = parent.deleted;
|
||||
} else {
|
||||
this.ids = (byte[][]) MainUtil.copyNd(parent.ids);
|
||||
this.data = (byte[][]) MainUtil.copyNd(parent.data);
|
||||
this.skyLight = (byte[][]) MainUtil.copyNd(parent.skyLight);
|
||||
this.blockLight = (byte[][]) MainUtil.copyNd(parent.blockLight);
|
||||
this.biomes = parent.biomes.clone();
|
||||
this.tiles = new HashMap<>(parent.tiles);
|
||||
this.entities = new HashMap<>(parent.entities);
|
||||
this.inhabitedTime = parent.inhabitedTime;
|
||||
this.lastUpdate = parent.lastUpdate;
|
||||
this.heightMap = parent.heightMap.clone();
|
||||
this.compressedSize = parent.compressedSize;
|
||||
this.modified = parent.modified;
|
||||
this.deleted = parent.deleted;
|
||||
}
|
||||
}
|
||||
|
||||
public MCAChunk(NBTInputStream nis, FaweQueue parent, int x, int z, int compressedSize) throws IOException {
|
||||
super(parent, x, z);
|
||||
ids = new byte[16][];
|
||||
data = new byte[16][];
|
||||
skyLight = new byte[16][];
|
||||
blockLight = new byte[16][];
|
||||
this.compressedSize = compressedSize;
|
||||
// NamedTag tag = nis.readNamedTag();
|
||||
NBTStreamer streamer = new NBTStreamer(nis);
|
||||
streamer.addReader(".Level.InhabitedTime", new RunnableVal2<Integer, Long>() {
|
||||
@Override
|
||||
public void run(Integer index, Long value) {
|
||||
inhabitedTime = value;
|
||||
}
|
||||
});
|
||||
streamer.addReader(".Level.LastUpdate", new RunnableVal2<Integer, Long>() {
|
||||
@Override
|
||||
public void run(Integer index, Long value) {
|
||||
lastUpdate = value;
|
||||
}
|
||||
});
|
||||
streamer.addReader(".Level.Sections.#", new RunnableVal2<Integer, CompoundTag>() {
|
||||
@Override
|
||||
public void run(Integer index, CompoundTag tag) {
|
||||
int layer = tag.getByte("Y");
|
||||
ids[layer] = tag.getByteArray("Blocks");
|
||||
data[layer] = tag.getByteArray("Data");
|
||||
skyLight[layer] = tag.getByteArray("SkyLight");
|
||||
blockLight[layer] = tag.getByteArray("BlockLight");
|
||||
}
|
||||
});
|
||||
streamer.addReader(".Level.Entities.#", new RunnableVal2<Integer, CompoundTag>() {
|
||||
@Override
|
||||
public void run(Integer index, CompoundTag tile) {
|
||||
int x = tile.getInt("x") & 15;
|
||||
int y = tile.getInt("y");
|
||||
int z = tile.getInt("z") & 15;
|
||||
byte i = MathMan.pair16((byte) x, (byte) z);
|
||||
byte j = (byte) y;
|
||||
BytePair pair = new BytePair(i, j);
|
||||
tiles.put(pair, tile);
|
||||
}
|
||||
});
|
||||
streamer.addReader(".Level.TileEntities.#", new RunnableVal2<Integer, CompoundTag>() {
|
||||
@Override
|
||||
public void run(Integer index, CompoundTag entityTag) {
|
||||
if (entities == null) {
|
||||
entities = new HashMap<UUID, CompoundTag>();
|
||||
}
|
||||
long least = entityTag.getLong("UUIDLeast");
|
||||
long most = entityTag.getLong("UUIDMost");
|
||||
entities.put(new UUID(most, least), entityTag);
|
||||
}
|
||||
});
|
||||
streamer.addReader(".Level.Biomes", new RunnableVal2<Integer, byte[]>() {
|
||||
@Override
|
||||
public void run(Integer index, byte[] value) {
|
||||
biomes = value;
|
||||
}
|
||||
});
|
||||
streamer.addReader(".Level.HeightMap", new RunnableVal2<Integer, int[]>() {
|
||||
@Override
|
||||
public void run(Integer index, int[] value) {
|
||||
heightMap = value;
|
||||
}
|
||||
});
|
||||
streamer.readFully();
|
||||
}
|
||||
|
||||
public boolean isModified() {
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBitMask() {
|
||||
int bitMask = 0;
|
||||
for (int section = 0; section < ids.length; section++) {
|
||||
if (ids[section] != null) {
|
||||
bitMask += 1 << section;
|
||||
}
|
||||
}
|
||||
return bitMask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTile(int x, int y, int z, CompoundTag tile) {
|
||||
modified = true;
|
||||
byte i = MathMan.pair16((byte) x, (byte) z);
|
||||
byte j = (byte) y;
|
||||
BytePair pair = new BytePair(i, j);
|
||||
tiles.put(pair, tile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEntity(CompoundTag entityTag) {
|
||||
modified = true;
|
||||
long least = entityTag.getLong("UUIDLeast");
|
||||
long most = entityTag.getLong("UUIDMost");
|
||||
entities.put(new UUID(most, least), entityTag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiome(int x, int z, BaseBiome biome) {
|
||||
modified = true;
|
||||
biomes[x + (z << 4)] = (byte) biome.getId();;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<CompoundTag> getEntities() {
|
||||
return new HashSet<>(entities.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<BytePair, CompoundTag> getTiles() {
|
||||
return tiles == null ? new HashMap<BytePair, CompoundTag>() : tiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getTile(int x, int y, int z) {
|
||||
if (tiles == null || tiles.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
byte i = MathMan.pair16((byte) x, (byte) z);
|
||||
byte j = (byte) y;
|
||||
BytePair pair = new BytePair(i, j);
|
||||
return tiles.get(pair);
|
||||
}
|
||||
|
||||
public boolean doesSectionExist(int cy) {
|
||||
return ids[cy] != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk<Void> copy(boolean shallow) {
|
||||
return new MCAChunk(this, shallow);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlockCombinedId(int x, int y, int z) {
|
||||
int layer = y >> 4;
|
||||
byte[] idLayer = ids[layer];
|
||||
if (idLayer == null) {
|
||||
return 0;
|
||||
}
|
||||
int j = FaweCache.CACHE_J[y][z & 15][x & 15];
|
||||
int id = idLayer[j];
|
||||
if (FaweCache.hasData(id)) {
|
||||
byte[] dataLayer = data[layer];
|
||||
if (dataLayer != null) {
|
||||
return (id << 4) + dataLayer[j];
|
||||
}
|
||||
}
|
||||
return id << 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> getEntityRemoves() {
|
||||
return new HashSet<>();
|
||||
}
|
||||
|
||||
public void setSkyLight(int x, int y, int z, int value) {
|
||||
modified = true;
|
||||
int layer = y >> 4;
|
||||
byte[] skyLayer = skyLight[layer];
|
||||
if (skyLayer == null) {
|
||||
return;
|
||||
}
|
||||
int index = FaweCache.CACHE_J[y][z & 15][x & 15];
|
||||
setNibble(index, skyLayer, value);
|
||||
}
|
||||
|
||||
public void setBlockLight(int x, int y, int z, int value) {
|
||||
modified = true;
|
||||
int layer = y >> 4;
|
||||
byte[] blockLayer = blockLight[layer];
|
||||
if (blockLayer == null) {
|
||||
return;
|
||||
}
|
||||
int index = FaweCache.CACHE_J[y][z & 15][x & 15];
|
||||
setNibble(index, blockLayer, value);
|
||||
}
|
||||
|
||||
public int getSkyLight(int x, int y, int z) {
|
||||
modified = true;
|
||||
int layer = y >> 4;
|
||||
byte[] skyLayer = skyLight[layer];
|
||||
if (skyLayer == null) {
|
||||
return 0;
|
||||
}
|
||||
int index = FaweCache.CACHE_J[y][z & 15][x & 15];
|
||||
return getNibble(index, skyLayer);
|
||||
}
|
||||
|
||||
public int getBlockLight(int x, int y, int z) {
|
||||
modified = true;
|
||||
int layer = y >> 4;
|
||||
byte[] blockLayer = blockLight[layer];
|
||||
if (blockLayer == null) {
|
||||
return 0;
|
||||
}
|
||||
int index = FaweCache.CACHE_J[y][z & 15][x & 15];
|
||||
return getNibble(index, blockLayer);
|
||||
}
|
||||
|
||||
public void setFullbright() {
|
||||
modified = true;
|
||||
for (byte[] array : skyLight) {
|
||||
if (array != null) {
|
||||
Arrays.fill(array, (byte) 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeLight() {
|
||||
for (int i = 0; i < skyLight.length; i++) {
|
||||
byte[] array1 = skyLight[i];
|
||||
if (array1 == null) {
|
||||
continue;
|
||||
}
|
||||
byte[] array2 = blockLight[i];
|
||||
Arrays.fill(array1, (byte) 0);
|
||||
Arrays.fill(array2, (byte) 0);
|
||||
}
|
||||
}
|
||||
|
||||
private int getNibble(int index, byte[] array) {
|
||||
int indexShift = index >> 1;
|
||||
if((index & 1) == 0) {
|
||||
return array[index] & 15;
|
||||
} else {
|
||||
return array[index] >> 4 & 15;
|
||||
}
|
||||
}
|
||||
|
||||
private void setNibble(int index, byte[] array, int value) {
|
||||
int indexShift = index >> 1;
|
||||
if((index & 1) == 0) {
|
||||
array[indexShift] = (byte)(array[indexShift] & 240 | value & 15);
|
||||
} else {
|
||||
array[indexShift] = (byte)(array[indexShift] & 15 | (value & 15) << 4);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, int id, int data) {
|
||||
modified = true;
|
||||
int layer = y >> 4;
|
||||
byte[] idsLayer = ids[layer];
|
||||
if (idsLayer == null) {
|
||||
return;
|
||||
}
|
||||
int j = FaweCache.CACHE_J[y][z & 15][x & 15];
|
||||
idsLayer[j] = (byte) id;
|
||||
byte[] dataLayer = this.data[layer];
|
||||
dataLayer[j] = (byte) data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEntity(UUID uuid) {
|
||||
modified = true;
|
||||
entities.remove(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void getChunk() {
|
||||
throw new UnsupportedOperationException("Not applicable for this");
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[][] getCombinedIdArrays() {
|
||||
throw new UnsupportedOperationException("Not applicable for this");
|
||||
}
|
||||
}
|
347
core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAFile.java
Normal file
347
core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAFile.java
Normal file
@ -0,0 +1,347 @@
|
||||
package com.boydti.fawe.jnbt.anvil;
|
||||
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.jnbt.NBTStreamer;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.RunnableVal4;
|
||||
import com.boydti.fawe.object.io.BufferedRandomAccessFile;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.NBTOutputStream;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
import java.util.zip.Inflater;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
|
||||
/**
|
||||
* Chunk format: http://minecraft.gamepedia.com/Chunk_format#Entity_format
|
||||
* e.g.: `.Level.Entities.#` (Starts with a . as the root tag is unnamed)
|
||||
*/
|
||||
public class MCAFile {
|
||||
private final File file;
|
||||
private final BufferedRandomAccessFile raf;
|
||||
private final byte[] locations;
|
||||
private final FaweQueue queue;
|
||||
private Field fieldBuf1;
|
||||
private Field fieldBuf2;
|
||||
private Field fieldBuf3;
|
||||
private Field fieldBuf4;
|
||||
private Field fieldBuf5;
|
||||
private Field fieldBuf6;
|
||||
|
||||
private byte[] buffer1 = new byte[Settings.HISTORY.BUFFER_SIZE];
|
||||
private byte[] buffer2 = new byte[Settings.HISTORY.BUFFER_SIZE];
|
||||
private byte[] buffer3 = new byte[720];
|
||||
|
||||
private Map<Integer, MCAChunk> chunks = new HashMap<>();
|
||||
|
||||
public MCAFile(FaweQueue parent, File file) throws Exception {
|
||||
this.queue = parent;
|
||||
this.file = file;
|
||||
if (!file.exists()) {
|
||||
throw new FileNotFoundException(file.toString());
|
||||
}
|
||||
this.locations = new byte[4096];
|
||||
this.raf = new BufferedRandomAccessFile(file, "rw", Settings.HISTORY.BUFFER_SIZE);
|
||||
raf.read(locations);
|
||||
fieldBuf1 = BufferedInputStream.class.getDeclaredField("buf");
|
||||
fieldBuf1.setAccessible(true);
|
||||
fieldBuf2 = InflaterInputStream.class.getDeclaredField("buf");
|
||||
fieldBuf2.setAccessible(true);
|
||||
fieldBuf3 = NBTInputStream.class.getDeclaredField("buf");
|
||||
fieldBuf3.setAccessible(true);
|
||||
fieldBuf4 = ByteArrayOutputStream.class.getDeclaredField("buf");
|
||||
fieldBuf4.setAccessible(true);
|
||||
fieldBuf5 = DeflaterOutputStream.class.getDeclaredField("buf");
|
||||
fieldBuf5.setAccessible(true);
|
||||
fieldBuf6 = BufferedOutputStream.class.getDeclaredField("buf");
|
||||
fieldBuf6.setAccessible(true);
|
||||
}
|
||||
|
||||
public MCAFile(FaweQueue parent, int mcrX, int mcrZ) throws Exception {
|
||||
this(parent, new File(parent.getSaveFolder(), "r." + mcrX + "." + mcrZ + ".mca"));
|
||||
}
|
||||
|
||||
public MCAChunk getCachedChunk(int cx, int cz) {
|
||||
int pair = MathMan.pair((short) (cx & 31), (short) (cz & 31));
|
||||
return chunks.get(pair);
|
||||
}
|
||||
|
||||
public MCAChunk getChunk(int cx, int cz) throws IOException {
|
||||
MCAChunk cached = getCachedChunk(cx, cz);
|
||||
if (cached != null) {
|
||||
return cached;
|
||||
} else {
|
||||
return readChunk(cx, cz);
|
||||
}
|
||||
}
|
||||
|
||||
public MCAChunk readChunk(int cx, int cz) throws IOException {
|
||||
int i = (cx << 2) + (cz << 7);
|
||||
int offset = (((locations[i] & 0xFF) << 16) + ((locations[i + 1] & 0xFF) << 8) + ((locations[i+ 2] & 0xFF))) << 12;
|
||||
int size = (locations[i + 3] & 0xFF) << 12;
|
||||
NBTInputStream nis = getChunkIS(offset);
|
||||
MCAChunk chunk = new MCAChunk(nis, queue, cx, cz, size);
|
||||
int pair = MathMan.pair((short) (cx & 31), (short) (cz & 31));
|
||||
chunks.put(pair, chunk);
|
||||
return chunk;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param onEach cx, cz, offset, size
|
||||
*/
|
||||
public void forEachChunk(RunnableVal4<Integer, Integer, Integer, Integer> onEach) {
|
||||
int i = 0;
|
||||
for (int z = 0; z < 32; z++) {
|
||||
for (int x = 0; x < 32; x++, i += 4) {
|
||||
int offset = (((locations[i] & 0xFF) << 16) + ((locations[i + 1] & 0xFF) << 8) + ((locations[i+ 2] & 0xFF)));
|
||||
int size = locations[i + 3] & 0xFF;
|
||||
if (size != 0) {
|
||||
onEach.run(x, z, offset << 12, size << 12);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getOffset(int cx, int cz) {
|
||||
int i = (cx << 2) + (cz << 7);
|
||||
int offset = (((locations[i] & 0xFF) << 16) + ((locations[i + 1] & 0xFF) << 8) + ((locations[i+ 2] & 0xFF)));
|
||||
return offset << 12;
|
||||
}
|
||||
|
||||
public int getSize(int cx, int cz) {
|
||||
int i = (cx << 2) + (cz << 7);
|
||||
return (locations[i + 3] & 0xFF) << 12;
|
||||
}
|
||||
|
||||
public List<Integer> getChunks() {
|
||||
final List<Integer> values = new ArrayList<>(chunks.size());
|
||||
for (int i = 0; i < locations.length; i+=4) {
|
||||
int offset = (((locations[i] & 0xFF) << 16) + ((locations[i + 1] & 0xFF) << 8) + ((locations[i+ 2] & 0xFF)));
|
||||
values.add(offset);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
private byte[] getChunkCompressedBytes(int offset) throws IOException{
|
||||
raf.seek(offset);
|
||||
int size = raf.readInt();
|
||||
int compression = raf.readByte();
|
||||
byte[] data = new byte[size];
|
||||
raf.read(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
private void writeSafe(int offset, byte[] data) throws IOException {
|
||||
int len = data.length + 5;
|
||||
raf.seek(offset);
|
||||
if (raf.length() - offset < len) {
|
||||
raf.setLength(offset + len);
|
||||
}
|
||||
raf.writeInt(data.length);
|
||||
raf.writeByte(2);
|
||||
raf.write(data);
|
||||
}
|
||||
|
||||
private NBTInputStream getChunkIS(int offset) throws IOException {
|
||||
try {
|
||||
byte[] data = getChunkCompressedBytes(offset);
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(data);
|
||||
InflaterInputStream iis = new InflaterInputStream(bais, new Inflater(), 1);
|
||||
fieldBuf2.set(iis, buffer2);
|
||||
BufferedInputStream bis = new BufferedInputStream(iis, 1);
|
||||
fieldBuf1.set(bis, buffer1);
|
||||
NBTInputStream nis = new NBTInputStream(bis);
|
||||
fieldBuf3.set(nis, buffer3);
|
||||
return nis;
|
||||
} catch (IllegalAccessException unlikely) {
|
||||
unlikely.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void streamChunk(int cx, int cz, RunnableVal<NBTStreamer> addReaders) throws IOException {
|
||||
streamChunk(getOffset(cx, cz), addReaders);
|
||||
}
|
||||
|
||||
public void streamChunk(int offset, RunnableVal<NBTStreamer> addReaders) throws IOException {
|
||||
NBTInputStream is = getChunkIS(offset);
|
||||
NBTStreamer ns = new NBTStreamer(is);
|
||||
addReaders.run(ns);
|
||||
ns.readFully();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param onEach chunk
|
||||
*/
|
||||
public void forEachCachedChunk(RunnableVal<MCAChunk> onEach) {
|
||||
for (Map.Entry<Integer, MCAChunk> entry : chunks.entrySet()) {
|
||||
onEach.run(entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public List<MCAChunk> getCachedChunks() {
|
||||
return new ArrayList<>(chunks.values());
|
||||
}
|
||||
|
||||
private NBTStreamer getChunkReader(int offset) throws Exception {
|
||||
return new NBTStreamer(getChunkIS(offset));
|
||||
}
|
||||
|
||||
public void uncache(int cx, int cz) {
|
||||
int pair = MathMan.pair((short) (cx & 31), (short) (cz & 31));
|
||||
chunks.remove(pair);
|
||||
}
|
||||
|
||||
private byte[] toBytes(MCAChunk chunk) throws Exception {
|
||||
CompoundTag tag = chunk.toTag();
|
||||
if (tag == null) {
|
||||
return null;
|
||||
}
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(0);
|
||||
fieldBuf4.set(baos, buffer3);
|
||||
DeflaterOutputStream deflater = new DeflaterOutputStream(baos, new Deflater(9), 1, true);
|
||||
fieldBuf5.set(deflater, buffer2);
|
||||
BufferedOutputStream bos = new BufferedOutputStream(deflater, 1);
|
||||
fieldBuf6.set(bos, buffer1);
|
||||
NBTOutputStream nos = new NBTOutputStream(bos);
|
||||
nos.writeNamedTag("", tag);
|
||||
bos.flush();
|
||||
byte[] result = baos.toByteArray();
|
||||
return result;
|
||||
}
|
||||
|
||||
private byte[] getChunkBytes(int cx, int cz) throws Exception{
|
||||
MCAChunk mca = getCachedChunk(cx, cz);
|
||||
if (mca == null) {
|
||||
int offset = getOffset(cx, cz);
|
||||
if (offset == 0) {
|
||||
return null;
|
||||
}
|
||||
return getChunkCompressedBytes(offset);
|
||||
}
|
||||
return toBytes(mca);
|
||||
}
|
||||
|
||||
private void writeHeader(int cx, int cz, int offsetMedium, int sizeByte) throws IOException {
|
||||
int i = (cx << 2) + (cz << 7);
|
||||
raf.seek(i);
|
||||
raf.write((offsetMedium >>> 16) & 0xFF);
|
||||
raf.write((offsetMedium >>> 8) & 0xFF);
|
||||
raf.write((offsetMedium >>> 0) & 0xFF);
|
||||
raf.write(sizeByte);
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
final HashMap<Integer, Integer> offsetMap = new HashMap<>(); // Offset -> <byte cx, byte cz, short size>
|
||||
|
||||
forEachChunk(new RunnableVal4<Integer, Integer, Integer, Integer>() {
|
||||
@Override
|
||||
public void run(Integer cx, Integer cz, Integer offset, Integer size) {
|
||||
short pair1 = MathMan.pairByte((byte) (cx & 31), (byte) (cz & 31));
|
||||
short pair2 = (short) (size >> 12);
|
||||
offsetMap.put(offset, MathMan.pair(pair1, pair2));
|
||||
}
|
||||
});
|
||||
|
||||
HashMap<Integer, byte[]> relocate = new HashMap<Integer, byte[]>();
|
||||
int start = 8192;
|
||||
int end = 8192;
|
||||
int nextOffset = 8192;
|
||||
try {
|
||||
for (int count = 0; count < offsetMap.size(); count++) {
|
||||
int loc = offsetMap.get(nextOffset);
|
||||
int offset = nextOffset;
|
||||
short cxz = MathMan.unpairX(loc);
|
||||
int cx = MathMan.unpairShortX(cxz);
|
||||
int cz = MathMan.unpairShortY(cxz);
|
||||
int size = MathMan.unpairY(loc) << 12;
|
||||
nextOffset += size;
|
||||
end += size;
|
||||
int pair = MathMan.pair((short) (cx & 31), (short) (cz & 31));
|
||||
byte[] newBytes = relocate.get(pair);
|
||||
if (newBytes == null) {
|
||||
if (offset == start) {
|
||||
MCAChunk cached = getCachedChunk(cx, cz);
|
||||
if (cached == null || !cached.isModified()) {
|
||||
start += size;
|
||||
continue;
|
||||
} else {
|
||||
newBytes = toBytes(cached);
|
||||
}
|
||||
} else {
|
||||
newBytes = getChunkBytes(cx, cz);
|
||||
}
|
||||
}
|
||||
if (newBytes == null) {
|
||||
System.out.println("Deleting: " + cx + "," + cz);
|
||||
// Don't write
|
||||
continue;
|
||||
}
|
||||
int len = newBytes.length + 5;
|
||||
int oldSize = (size + 4095) >> 12;
|
||||
int newSize = (len + 4095) >> 12;
|
||||
int nextOffset2 = nextOffset;
|
||||
while (start + len > end) {
|
||||
int nextLoc = offsetMap.get(nextOffset2);
|
||||
short nextCXZ = MathMan.unpairX(nextLoc);
|
||||
int nextCX = MathMan.unpairShortX(nextCXZ);
|
||||
int nextCZ = MathMan.unpairShortY(nextCXZ);
|
||||
if (getCachedChunk(nextCX, nextCZ) == null) {
|
||||
byte[] nextBytes = getChunkCompressedBytes(nextOffset2);
|
||||
relocate.put(pair, nextBytes);
|
||||
}
|
||||
System.out.println("Relocating " + nextCX + "," + nextCZ);
|
||||
int nextSize = MathMan.unpairY(nextLoc) << 12;
|
||||
end += nextSize;
|
||||
nextOffset2 += nextSize;
|
||||
}
|
||||
System.out.println("Writing: " + cx + "," + cz);
|
||||
writeSafe(start, newBytes);
|
||||
if (offset != start || end != start + size) {
|
||||
System.out.println("Header: " + cx + "," + cz + " | " + offset + "," + start + " | " + end + "," + (start + size) + " | " + size + " | " + start);
|
||||
writeHeader(cx, cz, offset >> 12, newSize);
|
||||
}
|
||||
start += newSize << 12;
|
||||
}
|
||||
raf.flush();
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// TODO write header
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// io benchmark
|
||||
File folder = new File("../../mc/world/region");
|
||||
long start = System.nanoTime();
|
||||
final AtomicInteger count = new AtomicInteger();
|
||||
final int id = 1;
|
||||
// for (File file : folder.listFiles()) {
|
||||
{ // Testing read/write
|
||||
File file = new File(folder, "r.-2.-3.mca");
|
||||
final MCAFile mca = new MCAFile(null, file);
|
||||
MCAChunk chunk = mca.getChunk(29, 30);
|
||||
System.out.println("Block ID: " + chunk.getBlockCombinedId(0, 0, 0));
|
||||
chunk.setBlock(0,0,0, 5);
|
||||
mca.flush();
|
||||
}
|
||||
long diff = System.nanoTime() - start;
|
||||
System.out.println(diff / 1000000d); // Time diff
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.boydti.fawe.jnbt;
|
||||
package com.boydti.fawe.jnbt.anvil;
|
||||
|
||||
import com.boydti.fawe.example.CharFaweChunk;
|
||||
import com.boydti.fawe.example.NMSMappedFaweQueue;
|
||||
@ -12,127 +12,139 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, MCAChunk, MCAChunk, char[]> {
|
||||
public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, MCAChunk, MCAChunk, MCAChunk> {
|
||||
|
||||
private final FaweQueue parent;
|
||||
|
||||
public MCAQueue(FaweQueue parent) {
|
||||
super(parent.getWorldName());
|
||||
super(parent.getWorldName(), new MCAQueueMap());
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFullbright(MCAChunk sections) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeLighting(MCAChunk sections, RelightMode mode, boolean hasSky) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void relight(int x, int y, int z) {
|
||||
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void relightBlock(int x, int y, int z) {
|
||||
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void relightSky(int x, int y, int z) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyLight(char[] chars, int x, int y, int z, int value) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockLight(char[] chars, int x, int y, int z, int value) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshChunk(FaweChunk fs) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharFaweChunk getPrevious(CharFaweChunk fs, MCAChunk sections, Map<?, ?> tiles, Collection<?>[] entities, Set<UUID> createdEntities, boolean all) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getTileEntity(MCAChunk mcaChunk, int x, int y, int z) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MCAChunk getChunk(FaweQueue faweQueue, int x, int z) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweQueue getImpWorld() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkLoaded(FaweQueue faweQueue, int x, int z) {
|
||||
return false;
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean regenerateChunk(FaweQueue faweQueue, int x, int z) {
|
||||
return false;
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setComponents(FaweChunk fc, RunnableVal<FaweChunk> changeTask) {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharFaweChunk getPrevious(CharFaweChunk fs, MCAChunk sections, Map<?, ?> tiles, Collection<?>[] entities, Set<UUID> createdEntities, boolean all) throws Exception {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public MCAChunk getChunk(FaweQueue faweQueue, int x, int z) {
|
||||
return (MCAChunk) getFaweChunk(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweQueue getImpWorld() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFullbright(MCAChunk sections) {
|
||||
sections.setFullbright();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeLighting(MCAChunk sections, RelightMode mode, boolean hasSky) {
|
||||
if (mode != RelightMode.NONE) {
|
||||
sections.removeLight();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyLight(MCAChunk chars, int x, int y, int z, int value) {
|
||||
chars.setSkyLight(x, y, z, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockLight(MCAChunk chars, int x, int y, int z, int value) {
|
||||
chars.setBlockLight(x, y, z, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshChunk(FaweChunk fs) {
|
||||
// Nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getTileEntity(MCAChunk mcaChunk, int x, int y, int z) {
|
||||
return mcaChunk.getTile(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkLoaded(FaweQueue faweQueue, int x, int z) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk getFaweChunk(int x, int z) {
|
||||
return null;
|
||||
return getFaweQueueMap().getFaweChunk(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getSaveFolder() {
|
||||
return null;
|
||||
return parent.getSaveFolder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSky() {
|
||||
return false;
|
||||
return parent.hasSky();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadChunk(FaweQueue faweQueue, int x, int z, boolean generate) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MCAChunk getCachedSections(FaweQueue faweQueue, int cx, int cz) {
|
||||
return (MCAChunk) getFaweQueueMap().getFaweChunk(cx, cz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MCAChunk getCachedSection(MCAChunk mcaChunk, int cy) {
|
||||
if (mcaChunk.doesSectionExist(cy)) {
|
||||
return mcaChunk;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCombinedId4Data(char[] chars, int x, int y, int z) {
|
||||
return 0;
|
||||
public int getCombinedId4Data(MCAChunk chars, int x, int y, int z) {
|
||||
return chars.getBlockCombinedId(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkyLight(char[] sections, int x, int y, int z) {
|
||||
return 0;
|
||||
public int getSkyLight(MCAChunk sections, int x, int y, int z) {
|
||||
return sections.getSkyLight(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEmmittedLight(char[] sections, int x, int y, int z) {
|
||||
return 0;
|
||||
public int getEmmittedLight(MCAChunk sections, int x, int y, int z) {
|
||||
return sections.getBlockLight(x, y, z);
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package com.boydti.fawe.jnbt.anvil;
|
||||
|
||||
import com.boydti.fawe.example.IFaweQueueMap;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import java.util.Collection;
|
||||
|
||||
public class MCAQueueMap implements IFaweQueueMap {
|
||||
@Override
|
||||
public Collection<FaweChunk> getFaweCunks() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachChunk(RunnableVal<FaweChunk> onEach) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk getFaweChunk(int cx, int cz) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(FaweChunk chunk) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean next() {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -109,7 +109,7 @@ public abstract class FaweChunk<T> {
|
||||
public int getBlockCombinedId(int x, int y, int z) {
|
||||
char[][] arrays = getCombinedIdArrays();
|
||||
char[] array = arrays[y >> 4];
|
||||
return array != null ? (array[FaweCache.CACHE_J[y][x][z]]) : 0;
|
||||
return array != null ? (array[FaweCache.CACHE_J[y][z][x]]) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -132,11 +132,11 @@ public abstract class FaweQueue {
|
||||
|
||||
public abstract boolean setBiome(final int x, final int z, final BaseBiome biome);
|
||||
|
||||
public abstract FaweChunk<?> getFaweChunk(int x, int z);
|
||||
public abstract FaweChunk getFaweChunk(int x, int z);
|
||||
|
||||
public abstract Collection<FaweChunk> getFaweChunks();
|
||||
|
||||
public abstract void setChunk(final FaweChunk<?> chunk);
|
||||
public abstract void setChunk(final FaweChunk chunk);
|
||||
|
||||
public abstract File getSaveFolder();
|
||||
|
||||
@ -219,7 +219,7 @@ public abstract class FaweQueue {
|
||||
* Gets the FaweChunk and sets the requested blocks
|
||||
* @return
|
||||
*/
|
||||
public abstract FaweChunk next();
|
||||
public abstract boolean next();
|
||||
|
||||
public void saveMemory() {
|
||||
MainUtil.sendAdmin(BBC.OOM.s());
|
||||
|
24
core/src/main/java/com/boydti/fawe/object/RunnableVal4.java
Normal file
24
core/src/main/java/com/boydti/fawe/object/RunnableVal4.java
Normal file
@ -0,0 +1,24 @@
|
||||
package com.boydti.fawe.object;
|
||||
|
||||
public abstract class RunnableVal4<T, U, V, W> implements Runnable {
|
||||
public T value1;
|
||||
public U value2;
|
||||
public V value3;
|
||||
public W value4;
|
||||
|
||||
public RunnableVal4() {}
|
||||
|
||||
public RunnableVal4(T value1, U value2, V value3, W value4) {
|
||||
this.value1 = value1;
|
||||
this.value2 = value2;
|
||||
this.value3 = value3;
|
||||
this.value4 = value4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
run(value1, value2, value3, value4);
|
||||
}
|
||||
|
||||
public abstract void run(T value1, U value2, V value3, W value4);
|
||||
}
|
@ -202,12 +202,12 @@ public abstract class FaweChangeSet implements ChangeSet {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
short[][] i1 = FaweCache.CACHE_J[y];
|
||||
int yy = y + startY;
|
||||
for (int x = 0; x < 16; x++) {
|
||||
int xx = x + bx;
|
||||
short[] i2 = i1[x];
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int zz = z + bz;
|
||||
int index = i2[z];
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int zz = z + bz;
|
||||
short[] i2 = i1[z];
|
||||
for (int x = 0; x < 16; x++) {
|
||||
int xx = x + bx;
|
||||
int index = i2[x];
|
||||
int combinedIdCurrent = currentLayer[index];
|
||||
switch (combinedIdCurrent) {
|
||||
case 0:
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.boydti.fawe.object.extent;
|
||||
|
||||
import com.boydti.fawe.jnbt.MCAFile;
|
||||
import com.boydti.fawe.jnbt.anvil.MCAFile;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
|
@ -103,6 +103,9 @@ public class ProcessedWEExtent extends FaweRegionExtent {
|
||||
return super.setBiome(position, biome);
|
||||
} else if (!limit.MAX_FAILS()) {
|
||||
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ public class FaweLocalBlockQueue extends LocalBlockQueue {
|
||||
|
||||
@Override
|
||||
public boolean next() {
|
||||
return IMP.next() != null;
|
||||
return IMP.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -130,7 +130,7 @@ public class DelegateFaweQueue extends FaweQueue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChunk(FaweChunk<?> chunk) {
|
||||
public void setChunk(FaweChunk chunk) {
|
||||
parent.setChunk(chunk);
|
||||
}
|
||||
|
||||
@ -165,7 +165,7 @@ public class DelegateFaweQueue extends FaweQueue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk next() {
|
||||
public boolean next() {
|
||||
return parent.next();
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@ package com.boydti.fawe.util;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.RunnableVal2;
|
||||
import java.util.ArrayList;
|
||||
@ -42,8 +41,8 @@ public class SetQueue {
|
||||
@Override
|
||||
public void run(Long free, FaweQueue queue) {
|
||||
do {
|
||||
final FaweChunk<?> current = queue.next();
|
||||
if (current == null) {
|
||||
final boolean current = queue.next();
|
||||
if (current == false) {
|
||||
lastSuccess = last;
|
||||
if (inactiveQueues.size() == 0 && activeQueues.size() == 0) {
|
||||
runEmptyTasks();
|
||||
@ -269,12 +268,12 @@ public class SetQueue {
|
||||
return null;
|
||||
}
|
||||
|
||||
public FaweChunk<?> next() {
|
||||
public boolean next() {
|
||||
while (activeQueues.size() > 0) {
|
||||
FaweQueue queue = activeQueues.poll();
|
||||
if (queue != null) {
|
||||
final FaweChunk<?> set = queue.next();
|
||||
if (set != null) {
|
||||
final boolean set = queue.next();
|
||||
if (set) {
|
||||
activeQueues.add(queue);
|
||||
return set;
|
||||
}
|
||||
@ -290,8 +289,8 @@ public class SetQueue {
|
||||
long diff = now - lastSuccess;
|
||||
if (diff > Settings.QUEUE.MAX_WAIT_MS) {
|
||||
for (FaweQueue queue : tmp) {
|
||||
FaweChunk result = queue.next();
|
||||
if (result != null) {
|
||||
boolean result = queue.next();
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -299,7 +298,7 @@ public class SetQueue {
|
||||
// These edits never finished
|
||||
inactiveQueues.clear();
|
||||
}
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (Settings.QUEUE.TARGET_SIZE != -1) {
|
||||
@ -309,19 +308,19 @@ public class SetQueue {
|
||||
}
|
||||
if (total > Settings.QUEUE.TARGET_SIZE) {
|
||||
for (FaweQueue queue : tmp) {
|
||||
FaweChunk result = queue.next();
|
||||
if (result != null) {
|
||||
boolean result = queue.next();
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean forceChunkSet() {
|
||||
return next() != null;
|
||||
return next();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -315,7 +315,7 @@ public class LocalSession {
|
||||
File file = MainUtil.getFile(Fawe.imp().getDirectory(), Settings.PATHS.HISTORY + File.separator + Fawe.imp().getWorldName(world) + File.separator + uuid + File.separator + "index");
|
||||
if (getHistoryNegativeIndex() != 0) {
|
||||
try {
|
||||
if (file.exists()) {
|
||||
if (!file.exists()) {
|
||||
file.getParentFile().mkdirs();
|
||||
file.createNewFile();
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ public class ForgeChunk_All extends CharFaweChunk<Chunk> {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
char combinedId = blocks[FaweCache.CACHE_J[y][x][z]];
|
||||
char combinedId = blocks[FaweCache.CACHE_J[y][z][x]];
|
||||
if (combinedId > 1) {
|
||||
palette.set(x, y, z, Block.getBlockById(combinedId >> 4).getStateFromMeta(combinedId & 0xF));
|
||||
}
|
||||
|
@ -269,12 +269,12 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
int x = ((int) Math.round(ent.posX) & 15);
|
||||
int z = ((int) Math.round(ent.posZ) & 15);
|
||||
int y = (int) Math.round(ent.posY);
|
||||
int i = FaweCache.CACHE_I[y][x][z];
|
||||
int i = FaweCache.CACHE_I[y][z][x];
|
||||
char[] array = fs.getIdArray(i);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int j = FaweCache.CACHE_J[y][x][z];
|
||||
int j = FaweCache.CACHE_J[y][z][x];
|
||||
if (array[j] != 0) {
|
||||
String id = EntityList.getEntityString(ent);
|
||||
if (id != null) {
|
||||
@ -327,7 +327,7 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][x][z]] != 0) {
|
||||
if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][z][x]] != 0) {
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
@ -372,12 +372,12 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
int lx = pos.getX() & 15;
|
||||
int ly = pos.getY();
|
||||
int lz = pos.getZ() & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lx][lz];
|
||||
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||
char[] array = fs.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lx][lz];
|
||||
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||
if (array[k] != 0) {
|
||||
tile.getValue().invalidate();;
|
||||
iterator.remove();
|
||||
@ -428,7 +428,7 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
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][x][z]];
|
||||
char combinedId = array[FaweCache.CACHE_J[y][z][x]];
|
||||
switch (combinedId) {
|
||||
case 0:
|
||||
IBlockState existing = nibble.get(x, y, z);
|
||||
|
@ -35,8 +35,8 @@ public class ForgeChunk_All extends CharFaweChunk<Chunk> {
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, int id, int data) {
|
||||
int i = FaweCache.CACHE_I[y][x][z];
|
||||
int j = FaweCache.CACHE_J[y][x][z];
|
||||
int i = FaweCache.CACHE_I[y][z][x];
|
||||
int j = FaweCache.CACHE_J[y][z][x];
|
||||
byte[] vs = this.byteIds[i];
|
||||
char[] vs2 = this.ids[i];
|
||||
if (vs2 == null) {
|
||||
|
@ -122,7 +122,7 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
public int getCombinedId4Data(ExtendedBlockStorage ls, int x, int y, int z) {
|
||||
byte[] ids = ls.getBlockLSBArray();
|
||||
NibbleArray datasNibble = ls.getBlockMSBArray();
|
||||
int i = FaweCache.CACHE_J[y & 15][x & 15][z & 15];
|
||||
int i = FaweCache.CACHE_J[y & 15][z & 15][x & 15];
|
||||
int combined = (ids[i] << 4) + (datasNibble == null ? 0 : datasNibble.get(x & 15, y & 15, z & 15));
|
||||
return combined;
|
||||
}
|
||||
@ -299,7 +299,7 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][x][z]] != 0) {
|
||||
if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][z][x]] != 0) {
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
@ -344,12 +344,12 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
int lx = pos.chunkPosX & 15;
|
||||
int ly = pos.chunkPosY;
|
||||
int lz = pos.chunkPosZ & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lx][lz];
|
||||
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||
char[] array = fs.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lx][lz];
|
||||
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||
if (array[k] != 0) {
|
||||
tile.getValue().invalidate();;
|
||||
iterator.remove();
|
||||
@ -535,12 +535,12 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
int x = ((int) Math.round(ent.posX) & 15);
|
||||
int z = ((int) Math.round(ent.posZ) & 15);
|
||||
int y = (int) Math.round(ent.posY);
|
||||
int i = FaweCache.CACHE_I[y][x][z];
|
||||
int i = FaweCache.CACHE_I[y][z][x];
|
||||
char[] array = fs.getIdArray(i);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int j = FaweCache.CACHE_J[y][x][z];
|
||||
int j = FaweCache.CACHE_J[y][z][x];
|
||||
if (array[j] != 0) {
|
||||
String id = EntityList.getEntityString(ent);
|
||||
if (id != null) {
|
||||
@ -663,7 +663,7 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
|
||||
@Override
|
||||
public boolean hasBlock(ExtendedBlockStorage section, int x, int y, int z) {
|
||||
int i = FaweCache.CACHE_J[y & 15][x & 15][z & 15];
|
||||
int i = FaweCache.CACHE_J[y & 15][z & 15][x & 15];
|
||||
return section.getBlockLSBArray()[i] != 0;
|
||||
}
|
||||
|
||||
|
@ -159,7 +159,7 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
|
||||
@Override
|
||||
public int getCombinedId4Data(ExtendedBlockStorage ls, int x, int y, int z) {
|
||||
return ls.getData()[FaweCache.CACHE_J[y][x & 15][z & 15]];
|
||||
return ls.getData()[FaweCache.CACHE_J[y][z & 15][x & 15]];
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -219,12 +219,12 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
int x = ((int) Math.round(ent.posX) & 15);
|
||||
int z = ((int) Math.round(ent.posZ) & 15);
|
||||
int y = (int) Math.round(ent.posY);
|
||||
int i = FaweCache.CACHE_I[y][x][z];
|
||||
int i = FaweCache.CACHE_I[y][z][x];
|
||||
char[] array = fs.getIdArray(i);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int j = FaweCache.CACHE_J[y][x][z];
|
||||
int j = FaweCache.CACHE_J[y][z][x];
|
||||
if (array[j] != 0) {
|
||||
String id = EntityList.getEntityString(ent);
|
||||
if (id != null) {
|
||||
@ -276,7 +276,7 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][x][z]] != 0) {
|
||||
if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][z][x]] != 0) {
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
@ -321,12 +321,12 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
int lx = pos.getX() & 15;
|
||||
int ly = pos.getY();
|
||||
int lz = pos.getZ() & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lx][lz];
|
||||
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||
char[] array = fs.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lx][lz];
|
||||
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||
if (array[k] != 0) {
|
||||
tile.getValue().invalidate();;
|
||||
iterator.remove();
|
||||
@ -515,13 +515,13 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
if (y < 0 || y > 255) {
|
||||
return 1;
|
||||
}
|
||||
int i = FaweCache.CACHE_I[y][x][z];
|
||||
int i = FaweCache.CACHE_I[y][z][x];
|
||||
ExtendedBlockStorage section = sections[i];
|
||||
if (section == null) {
|
||||
return 0;
|
||||
}
|
||||
char[] array = section.getData();
|
||||
int j = FaweCache.CACHE_J[y][x][z];
|
||||
int j = FaweCache.CACHE_J[y][z][x];
|
||||
return array[j] >> 4;
|
||||
}
|
||||
|
||||
@ -627,7 +627,7 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
|
||||
@Override
|
||||
public boolean hasBlock(ExtendedBlockStorage section, int x, int y, int z) {
|
||||
int i = FaweCache.CACHE_J[y & 15][x & 15][z & 15];
|
||||
int i = FaweCache.CACHE_J[y & 15][z & 15][x & 15];
|
||||
return section.getData()[i] != 0;
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ public class ForgeChunk_All extends CharFaweChunk<Chunk> {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
char combinedId = blocks[FaweCache.CACHE_J[y][x][z]];
|
||||
char combinedId = blocks[FaweCache.CACHE_J[y][z][x]];
|
||||
if (combinedId > 1) {
|
||||
palette.set(x, y, z, Block.getBlockById(combinedId >> 4).getStateFromMeta(combinedId & 0xF));
|
||||
}
|
||||
|
@ -269,12 +269,12 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
int x = ((int) Math.round(ent.posX) & 15);
|
||||
int z = ((int) Math.round(ent.posZ) & 15);
|
||||
int y = (int) Math.round(ent.posY);
|
||||
int i = FaweCache.CACHE_I[y][x][z];
|
||||
int i = FaweCache.CACHE_I[y][z][x];
|
||||
char[] array = fs.getIdArray(i);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int j = FaweCache.CACHE_J[y][x][z];
|
||||
int j = FaweCache.CACHE_J[y][z][x];
|
||||
if (array[j] != 0) {
|
||||
String id = EntityList.getEntityString(ent);
|
||||
if (id != null) {
|
||||
@ -327,7 +327,7 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][x][z]] != 0) {
|
||||
if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][z][x]] != 0) {
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
@ -372,12 +372,12 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
int lx = pos.getX() & 15;
|
||||
int ly = pos.getY();
|
||||
int lz = pos.getZ() & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lx][lz];
|
||||
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||
char[] array = fs.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lx][lz];
|
||||
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||
if (array[k] != 0) {
|
||||
tile.getValue().invalidate();;
|
||||
iterator.remove();
|
||||
@ -428,7 +428,7 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
||||
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][x][z]];
|
||||
char combinedId = array[FaweCache.CACHE_J[y][z][x]];
|
||||
switch (combinedId) {
|
||||
case 0:
|
||||
IBlockState existing = nibble.get(x, y, z);
|
||||
|
@ -279,12 +279,12 @@ public class SpongeQueue_1_8 extends NMSMappedFaweQueue<World, net.minecraft.wor
|
||||
int x = ((int) Math.round(ent.posX) & 15);
|
||||
int z = ((int) Math.round(ent.posZ) & 15);
|
||||
int y = (int) Math.round(ent.posY);
|
||||
int i = FaweCache.CACHE_I[y][x][z];
|
||||
int i = FaweCache.CACHE_I[y][z][x];
|
||||
char[] array = fs.getIdArray(i);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int j = FaweCache.CACHE_J[y][x][z];
|
||||
int j = FaweCache.CACHE_J[y][z][x];
|
||||
if (array[j] != 0) {
|
||||
String id = EntityList.getEntityString(ent);
|
||||
if (id != null) {
|
||||
@ -334,7 +334,7 @@ public class SpongeQueue_1_8 extends NMSMappedFaweQueue<World, net.minecraft.wor
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][x][z]] != 0) {
|
||||
if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][z][x]] != 0) {
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
@ -379,12 +379,12 @@ public class SpongeQueue_1_8 extends NMSMappedFaweQueue<World, net.minecraft.wor
|
||||
int lx = pos.getX() & 15;
|
||||
int ly = pos.getY();
|
||||
int lz = pos.getZ() & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lx][lz];
|
||||
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||
char[] array = fs.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lx][lz];
|
||||
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||
if (array[k] != 0) {
|
||||
tile.getValue().invalidate();
|
||||
iterator.remove();
|
||||
@ -642,13 +642,13 @@ public class SpongeQueue_1_8 extends NMSMappedFaweQueue<World, net.minecraft.wor
|
||||
if (y < 0 || y > 255) {
|
||||
return 1;
|
||||
}
|
||||
int i = FaweCache.CACHE_I[y][x][z];
|
||||
int i = FaweCache.CACHE_I[y][z][x];
|
||||
ExtendedBlockStorage section = sections[i];
|
||||
if (section == null) {
|
||||
return 0;
|
||||
}
|
||||
char[] array = section.getData();
|
||||
int j = FaweCache.CACHE_J[y][x][z];
|
||||
int j = FaweCache.CACHE_J[y][z][x];
|
||||
return array[j] >> 4;
|
||||
}
|
||||
|
||||
@ -673,7 +673,7 @@ public class SpongeQueue_1_8 extends NMSMappedFaweQueue<World, net.minecraft.wor
|
||||
|
||||
@Override
|
||||
public int getCombinedId4Data(char[] chars, int x, int y, int z) {
|
||||
return chars[FaweCache.CACHE_J[y][x & 15][z & 15]];
|
||||
return chars[FaweCache.CACHE_J[y][z & 15][x & 15]];
|
||||
}
|
||||
|
||||
|
||||
|
@ -250,12 +250,12 @@ public class SpongeQueue_ALL extends NMSMappedFaweQueue<World, net.minecraft.wor
|
||||
public BlockState map(UnmodifiableBlockVolume volume, int xx, int y, int zz) {
|
||||
int x = xx & 15;
|
||||
int z = zz & 15;
|
||||
int i = FaweCache.CACHE_I[y][x][z];
|
||||
int i = FaweCache.CACHE_I[y][z][x];
|
||||
char[] array = ids[i];
|
||||
if (array == null) {
|
||||
return null;
|
||||
}
|
||||
int combinedId = array[FaweCache.CACHE_J[y][x][z]];
|
||||
int combinedId = array[FaweCache.CACHE_J[y][z][x]];
|
||||
switch (combinedId) {
|
||||
case 0:
|
||||
return null;
|
||||
@ -421,13 +421,13 @@ public class SpongeQueue_ALL extends NMSMappedFaweQueue<World, net.minecraft.wor
|
||||
if (y < 0 || y > 255) {
|
||||
return 1;
|
||||
}
|
||||
int i = FaweCache.CACHE_I[y][x][z];
|
||||
int i = FaweCache.CACHE_I[y][z][x];
|
||||
ExtendedBlockStorage section = sections[i];
|
||||
if (section == null) {
|
||||
return 0;
|
||||
}
|
||||
char[] array = section.getData();
|
||||
int j = FaweCache.CACHE_J[y][x][z];
|
||||
int j = FaweCache.CACHE_J[y][z][x];
|
||||
return array[j] >> 4;
|
||||
}
|
||||
|
||||
@ -453,6 +453,6 @@ public class SpongeQueue_ALL extends NMSMappedFaweQueue<World, net.minecraft.wor
|
||||
|
||||
@Override
|
||||
public int getCombinedId4Data(char[] chars, int x, int y, int z) {
|
||||
return chars[FaweCache.CACHE_J[y][x & 15][z & 15]];
|
||||
return chars[FaweCache.CACHE_J[y][z & 15][x & 15]];
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user