mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2024-12-01 07:03:52 +01:00
Optimizations for BukkitQueue_All
This queue is used to place blocks when no (fast) NMS one is found. - Exploits a bug in vanilla relight algorithm for faster placement
This commit is contained in:
parent
80045cfa6c
commit
eb62377c0f
@ -1,6 +1,7 @@
|
|||||||
package com.boydti.fawe.bukkit.v0;
|
package com.boydti.fawe.bukkit.v0;
|
||||||
|
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.example.CharFaweChunk;
|
import com.boydti.fawe.example.CharFaweChunk;
|
||||||
import com.boydti.fawe.object.FaweQueue;
|
import com.boydti.fawe.object.FaweQueue;
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
@ -43,8 +44,9 @@ public class BukkitChunk_All extends CharFaweChunk<Chunk> {
|
|||||||
public void execute(long start) {
|
public void execute(long start) {
|
||||||
int recommended = 25 + BukkitQueue_All.ALLOCATE;
|
int recommended = 25 + BukkitQueue_All.ALLOCATE;
|
||||||
boolean more = true;
|
boolean more = true;
|
||||||
FaweQueue parent = getParent();
|
BukkitQueue_All parent = (BukkitQueue_All) getParent();
|
||||||
final Chunk chunk = getChunk();
|
final Chunk chunk = getChunk();
|
||||||
|
Object[] disableResult = parent.disableLighting(chunk);
|
||||||
chunk.load(true);
|
chunk.load(true);
|
||||||
final World world = chunk.getWorld();
|
final World world = chunk.getWorld();
|
||||||
char[][] sections = getCombinedIdArrays();
|
char[][] sections = getCombinedIdArrays();
|
||||||
@ -106,12 +108,15 @@ public class BukkitChunk_All extends CharFaweChunk<Chunk> {
|
|||||||
if (newArray == null) {
|
if (newArray == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
final byte[] cacheX = FaweCache.CACHE_X[layer];
|
||||||
|
final short[] cacheY = FaweCache.CACHE_Y[layer];
|
||||||
|
final byte[] cacheZ = FaweCache.CACHE_Z[layer];
|
||||||
boolean checkTime = !((getAir(layer) == 4096 || (getCount(layer) == 4096 && getAir(layer) == 0) || (getCount(layer) == getAir(layer))) && getRelight(layer) == 0);
|
boolean checkTime = !((getAir(layer) == 4096 || (getCount(layer) == 4096 && getAir(layer) == 0) || (getCount(layer) == getAir(layer))) && getRelight(layer) == 0);
|
||||||
if (!checkTime) {
|
if (!checkTime) {
|
||||||
ArrayList<Thread> threads = new ArrayList<Thread>();
|
ArrayList<Thread> threads = new ArrayList<Thread>();
|
||||||
for (int k = 0; k < 16; k++) {
|
for (int k = 0; k < 16; k++) {
|
||||||
final int l = k << 8;
|
final int l = k << 8;
|
||||||
final int y = FaweCache.CACHE_Y[layer][l];
|
final int y = cacheY[l];
|
||||||
Thread thread = new Thread(new Runnable() {
|
Thread thread = new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -122,23 +127,18 @@ public class BukkitChunk_All extends CharFaweChunk<Chunk> {
|
|||||||
continue;
|
continue;
|
||||||
case 1:
|
case 1:
|
||||||
if (!place) {
|
if (!place) {
|
||||||
int x = FaweCache.CACHE_X[layer][m];
|
int x = cacheX[m];
|
||||||
int z = FaweCache.CACHE_Z[layer][m];
|
int z = cacheZ[m];
|
||||||
chunk.getBlock(x, y, z).setTypeId(0, false);
|
setBlock(chunk.getBlock(x, y, z), 0, (byte) 0);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
if (place) {
|
if (place) {
|
||||||
int x = FaweCache.CACHE_X[layer][m];
|
int x = cacheX[m];
|
||||||
int z = FaweCache.CACHE_Z[layer][m];
|
int z = cacheZ[m];
|
||||||
int id = combined >> 4;
|
int id = combined >> 4;
|
||||||
int data = combined & 0xF;
|
|
||||||
Block block = chunk.getBlock(x, y, z);
|
Block block = chunk.getBlock(x, y, z);
|
||||||
if (data == 0) {
|
setBlock(block, id, (byte) (combined & 0xF));
|
||||||
block.setTypeId(id, false);
|
|
||||||
} else {
|
|
||||||
block.setTypeIdAndData(id, (byte) data, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -157,28 +157,41 @@ public class BukkitChunk_All extends CharFaweChunk<Chunk> {
|
|||||||
char combined = newArray[j];
|
char combined = newArray[j];
|
||||||
switch (combined) {
|
switch (combined) {
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
continue;
|
||||||
case 1:
|
case 1:
|
||||||
if (!place) {
|
if (!place) {
|
||||||
int x = FaweCache.CACHE_X[layer][j];
|
int x = cacheX[j];
|
||||||
int z = FaweCache.CACHE_Z[layer][j];
|
int z = cacheZ[j];
|
||||||
int y = FaweCache.CACHE_Y[layer][j];
|
int y = cacheY[j];
|
||||||
chunk.getBlock(x, y, z).setTypeId(0, false);
|
setBlock(chunk.getBlock(x, y, z), 0, (byte) 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (place) {
|
int id = combined >> 4;
|
||||||
int id = combined >> 4;
|
boolean light = FaweCache.hasLight(id);
|
||||||
int data = combined & 0xF;
|
if (light) {
|
||||||
int x = FaweCache.CACHE_X[layer][j];
|
if (place) {
|
||||||
int z = FaweCache.CACHE_Z[layer][j];
|
continue;
|
||||||
int y = FaweCache.CACHE_Y[layer][j];
|
|
||||||
Block block = chunk.getBlock(x, y, z);
|
|
||||||
if (data == 0) {
|
|
||||||
block.setTypeId(id, false);
|
|
||||||
} else {
|
|
||||||
block.setTypeIdAndData(id, (byte) data, false);
|
|
||||||
}
|
}
|
||||||
|
} else if (!place) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (light != place) {
|
||||||
|
light = light && Settings.LIGHTING.MODE != 0;
|
||||||
|
if (light) {
|
||||||
|
parent.enableLighting(disableResult);
|
||||||
|
}
|
||||||
|
int data = combined & 0xF;
|
||||||
|
int x = cacheX[j];
|
||||||
|
int z = cacheZ[j];
|
||||||
|
int y = cacheY[j];
|
||||||
|
Block block = chunk.getBlock(x, y, z);
|
||||||
|
setBlock(block, id, (byte) data);
|
||||||
|
if (light) {
|
||||||
|
parent.disableLighting(disableResult);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -196,5 +209,10 @@ public class BukkitChunk_All extends CharFaweChunk<Chunk> {
|
|||||||
if (more || place) {
|
if (more || place) {
|
||||||
this.addToQueue();
|
this.addToQueue();
|
||||||
}
|
}
|
||||||
|
parent.resetLighting(disableResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBlock(Block block, int id, byte data) {
|
||||||
|
block.setTypeIdAndData(id, data, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@ import com.boydti.fawe.object.FaweChunk;
|
|||||||
import com.boydti.fawe.object.RunnableVal;
|
import com.boydti.fawe.object.RunnableVal;
|
||||||
import com.boydti.fawe.util.TaskManager;
|
import com.boydti.fawe.util.TaskManager;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
@ -15,6 +17,7 @@ public class BukkitQueue_All extends BukkitQueue_0<Chunk, Chunk, Chunk> {
|
|||||||
|
|
||||||
public static int ALLOCATE;
|
public static int ALLOCATE;
|
||||||
public static double TPS_TARGET = 18.5;
|
public static double TPS_TARGET = 18.5;
|
||||||
|
private static int LIGHT_MASK = 0x739C0;
|
||||||
|
|
||||||
public BukkitQueue_All(String world) {
|
public BukkitQueue_All(String world) {
|
||||||
super(world);
|
super(world);
|
||||||
@ -124,6 +127,62 @@ public class BukkitQueue_All extends BukkitQueue_0<Chunk, Chunk, Chunk> {
|
|||||||
super.startSet(true);
|
super.startSet(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Field fieldNeighbors;
|
||||||
|
private Method chunkGetHandle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exploiting a bug in the vanilla lighting algorithm for faster block placement
|
||||||
|
* - Could have been achieved without reflection by force unloading specific chunks
|
||||||
|
* - Much faster just setting the variable manually though
|
||||||
|
* @param chunk
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected Object[] disableLighting(Chunk chunk) {
|
||||||
|
try {
|
||||||
|
if (chunkGetHandle == null) {
|
||||||
|
chunkGetHandle = chunk.getClass().getDeclaredMethod("getHandle");
|
||||||
|
chunkGetHandle.setAccessible(true);
|
||||||
|
}
|
||||||
|
Object nmsChunk = chunkGetHandle.invoke(chunk);
|
||||||
|
if (fieldNeighbors == null) {
|
||||||
|
fieldNeighbors = nmsChunk.getClass().getDeclaredField("neighbors");
|
||||||
|
fieldNeighbors.setAccessible(true);
|
||||||
|
}
|
||||||
|
Object value = fieldNeighbors.get(nmsChunk);
|
||||||
|
fieldNeighbors.set(nmsChunk, 0);
|
||||||
|
return new Object[] {nmsChunk, value};
|
||||||
|
} catch (Throwable ignore) {}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void disableLighting(Object[] disableResult) {
|
||||||
|
if (disableResult != null) {
|
||||||
|
try {
|
||||||
|
fieldNeighbors.set(disableResult[0], 0);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void resetLighting(Object[] disableResult) {
|
||||||
|
if (disableResult != null) {
|
||||||
|
try {
|
||||||
|
fieldNeighbors.set(disableResult[0], disableResult[1]);
|
||||||
|
} catch (Throwable ignore) {
|
||||||
|
ignore.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void enableLighting(Object[] disableResult) {
|
||||||
|
if (disableResult != null) {
|
||||||
|
try {
|
||||||
|
fieldNeighbors.set(disableResult[0], 0x739C0);
|
||||||
|
} catch (Throwable ignore) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void endSet(boolean parallel) {
|
public void endSet(boolean parallel) {
|
||||||
super.endSet(true);
|
super.endSet(true);
|
||||||
|
@ -317,6 +317,30 @@ public class FaweCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean hasLight(int id) {
|
||||||
|
switch (id) {
|
||||||
|
case 39:
|
||||||
|
case 40:
|
||||||
|
case 50:
|
||||||
|
case 51:
|
||||||
|
case 76:
|
||||||
|
case 10:
|
||||||
|
case 11:
|
||||||
|
case 62:
|
||||||
|
case 74:
|
||||||
|
case 89:
|
||||||
|
case 122:
|
||||||
|
case 124:
|
||||||
|
case 130:
|
||||||
|
case 138:
|
||||||
|
case 169:
|
||||||
|
case 213:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public enum LightType {
|
public enum LightType {
|
||||||
TRANSPARENT, OCCLUDING, SOLID_EMIT, TRANSPARENT_EMIT
|
TRANSPARENT, OCCLUDING, SOLID_EMIT, TRANSPARENT_EMIT
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user