mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2024-11-24 19:46:34 +01:00
Various
Keep chunks loaded for at least 10s Optimizations for 1.10 Fix cast for 1.8 Memory/Disk Optimizations for relighting large areas in unloaded chunks Fix for clipboard entities
This commit is contained in:
parent
1ed87eabbc
commit
5c0ae62b17
@ -6,6 +6,7 @@ import com.boydti.fawe.example.CharFaweChunk;
|
||||
import com.boydti.fawe.example.NMSMappedFaweQueue;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||
@ -16,12 +17,14 @@ import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.ChunkUnloadEvent;
|
||||
import org.bukkit.event.world.WorldInitEvent;
|
||||
|
||||
public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMappedFaweQueue<World, CHUNK, CHUNKSECTIONS, SECTION> implements Listener {
|
||||
@ -80,6 +83,22 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
|
||||
}
|
||||
}
|
||||
|
||||
public static ConcurrentHashMap<Long, Long> keepLoaded = new ConcurrentHashMap<>();
|
||||
|
||||
@EventHandler
|
||||
public static void onChunkUnload(ChunkUnloadEvent event) {
|
||||
Chunk chunk = event.getChunk();
|
||||
long pair = MathMan.pairInt(chunk.getX(), chunk.getZ());
|
||||
Long lastLoad = keepLoaded.get(pair);
|
||||
if (lastLoad != null) {
|
||||
if (System.currentTimeMillis() - lastLoad < 10000) {
|
||||
event.setCancelled(true);
|
||||
} else {
|
||||
keepLoaded.remove(pair);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public World createWorld(final WorldCreator creator) {
|
||||
World world = TaskManager.IMP.sync(new RunnableVal<World>() {
|
||||
@Override
|
||||
@ -154,7 +173,11 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
|
||||
|
||||
@Override
|
||||
public boolean loadChunk(World impWorld, int x, int z, boolean generate) {
|
||||
return impWorld.loadChunk(x, z, generate);
|
||||
if (impWorld.loadChunk(x, z, generate)) {
|
||||
keepLoaded.put(MathMan.pairInt(x, z), System.currentTimeMillis());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private volatile boolean timingsEnabled;
|
||||
|
@ -33,7 +33,6 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.server.v1_10_R1.Block;
|
||||
import net.minecraft.server.v1_10_R1.BlockPosition;
|
||||
import net.minecraft.server.v1_10_R1.Blocks;
|
||||
import net.minecraft.server.v1_10_R1.ChunkSection;
|
||||
import net.minecraft.server.v1_10_R1.DataBits;
|
||||
import net.minecraft.server.v1_10_R1.DataPaletteBlock;
|
||||
@ -64,7 +63,6 @@ import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.World.Environment;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.craftbukkit.v1_10_R1.CraftChunk;
|
||||
import org.bukkit.craftbukkit.v1_10_R1.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_10_R1.CraftWorld;
|
||||
@ -79,6 +77,8 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
private static Field fieldBits;
|
||||
private static Method getEntitySlices;
|
||||
|
||||
public static final IBlockData[] IBD_CACHE = new IBlockData[Character.MAX_VALUE];
|
||||
|
||||
public BukkitQueue_1_10(final String world) {
|
||||
super(world);
|
||||
checkVersion("v1_10_R1");
|
||||
@ -95,6 +95,11 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
Fawe.debug("Using adapter: " + adapter);
|
||||
Fawe.debug("=========================================");
|
||||
}
|
||||
for (int i = 0; i < Character.MAX_VALUE; i++) {
|
||||
try {
|
||||
IBD_CACHE[i] = Block.getById(i >> 4).fromLegacyData(i & 0xF);
|
||||
} catch (Throwable ignore) {}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@ -658,9 +663,11 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
DataPaletteBlock nibble = section.getBlocks();
|
||||
int nonEmptyBlockCount = 0;
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
char combinedId = array[FaweCache.CACHE_J[y][x][z]];
|
||||
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]];
|
||||
switch (combinedId) {
|
||||
case 0:
|
||||
IBlockData existing = nibble.a(x, y, z);
|
||||
@ -669,11 +676,11 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
}
|
||||
continue;
|
||||
case 1:
|
||||
nibble.setBlock(x, y, z, Blocks.AIR.getBlockData());
|
||||
nibble.setBlock(x, y, z, air);
|
||||
continue;
|
||||
default:
|
||||
nonEmptyBlockCount++;
|
||||
nibble.setBlock(x, y, z, Block.getById(combinedId >> 4).fromLegacyData(combinedId & 0xF));
|
||||
nibble.setBlock(x, y, z, IBD_CACHE[(int) combinedId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -715,23 +722,6 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
} catch (Throwable e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
final int[][] biomes = fs.getBiomeArray();
|
||||
final Biome[] values = Biome.values();
|
||||
if (biomes != null) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
final int[] array = biomes[x];
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
for (int z = 0; z < 16; z++) {
|
||||
final int biome = array[z];
|
||||
if (biome == 0) {
|
||||
continue;
|
||||
}
|
||||
chunk.getBlock(x, 0, z).setBiome(values[biome]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -579,12 +579,7 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkS
|
||||
|
||||
@Override
|
||||
public FaweChunk getFaweChunk(int x, int z) {
|
||||
return new CharFaweChunk<Chunk>(this, x, z) {
|
||||
@Override
|
||||
public Chunk getNewChunk() {
|
||||
return BukkitQueue18R3.this.getWorld().getChunkAt(getX(), getZ());
|
||||
}
|
||||
};
|
||||
return new BukkitChunk_1_8(this, x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -8,6 +8,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class NMSRelighter {
|
||||
@ -15,6 +16,8 @@ public class NMSRelighter {
|
||||
private final HashMap<Long, RelightSkyEntry> skyToRelight;
|
||||
private final HashMap<Long, RelightBlockEntry> blocksToRelight;
|
||||
|
||||
private static final int DISPATCH_SIZE = 64;
|
||||
|
||||
public NMSRelighter(NMSMappedFaweQueue queue) {
|
||||
this.queue = queue;
|
||||
skyToRelight = new HashMap<>();
|
||||
@ -127,7 +130,22 @@ public class NMSRelighter {
|
||||
// Order chunks
|
||||
ArrayList<RelightSkyEntry> chunksList = new ArrayList<>(skyToRelight.values());
|
||||
Collections.sort(chunksList);
|
||||
RelightSkyEntry[] chunks = chunksList.toArray(new RelightSkyEntry[chunksList.size()]);
|
||||
int size = chunksList.size();
|
||||
if (size > DISPATCH_SIZE) {
|
||||
int amount = (size + 1) / DISPATCH_SIZE;
|
||||
for (int i = 0; i <= amount; i++) {
|
||||
int start = i * DISPATCH_SIZE;
|
||||
int end = Math.min(size, start + DISPATCH_SIZE);
|
||||
List<RelightSkyEntry> sub = chunksList.subList(start, end);
|
||||
fixSkyLighting(sub);
|
||||
}
|
||||
} else {
|
||||
fixSkyLighting(chunksList);
|
||||
}
|
||||
}
|
||||
|
||||
private void fixSkyLighting(List<RelightSkyEntry> sorted) {
|
||||
RelightSkyEntry[] chunks = sorted.toArray(new RelightSkyEntry[sorted.size()]);
|
||||
byte[] cacheX = FaweCache.CACHE_X[0];
|
||||
byte[] cacheZ = FaweCache.CACHE_Z[0];
|
||||
for (int y = 255; y > 0; y--) {
|
||||
|
@ -83,7 +83,7 @@ public class SchematicStreamer extends NBTStreamer {
|
||||
ListTag positionTag = compound.getListTag("Pos");
|
||||
ListTag directionTag = compound.getListTag("Rotation");
|
||||
BaseEntity state = new BaseEntity(id, compound);
|
||||
fc.createEntity(null, positionTag.asDouble(0), positionTag.asDouble(1), positionTag.asDouble(2), (float) directionTag.asDouble(0), (float) directionTag.asDouble(1), state);
|
||||
fc.createEntity(clipboard, positionTag.asDouble(0), positionTag.asDouble(1), positionTag.asDouble(2), (float) directionTag.asDouble(0), (float) directionTag.asDouble(1), state);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ public abstract class FaweClipboard {
|
||||
|
||||
public ClipboardEntity(Extent world, double x, double y, double z, float yaw, float pitch, BaseEntity entity) {
|
||||
checkNotNull(entity);
|
||||
checkNotNull(world);
|
||||
this.world = world;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
|
@ -159,7 +159,11 @@ public class MainUtil {
|
||||
}
|
||||
int highAmount = amount > 3 ? 1 : 0;
|
||||
for (int i = 0; i < highAmount; i++) {
|
||||
os = new LZ4OutputStream(os, buffer, factory.highCompressor());
|
||||
if (amount == 9) {
|
||||
os = new LZ4OutputStream(os, buffer, factory.highCompressor(17));
|
||||
} else {
|
||||
os = new LZ4OutputStream(os, buffer, factory.highCompressor());
|
||||
}
|
||||
}
|
||||
return new FaweOutputStream(os);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user