Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-12-25 10:30:04 +01:00
Ursprung
74a2f02003
Commit
b4d7562b87
@ -1,11 +1,13 @@
|
|||||||
package com.boydti.fawe.bukkit;
|
package com.boydti.fawe.bukkit;
|
||||||
|
|
||||||
|
import com.boydti.fawe.FAWEPlatformAdapterImpl;
|
||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.IFawe;
|
import com.boydti.fawe.IFawe;
|
||||||
import com.boydti.fawe.beta.implementation.cache.preloader.AsyncPreloader;
|
import com.boydti.fawe.beta.implementation.cache.preloader.AsyncPreloader;
|
||||||
import com.boydti.fawe.beta.implementation.cache.preloader.Preloader;
|
import com.boydti.fawe.beta.implementation.cache.preloader.Preloader;
|
||||||
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
||||||
import com.boydti.fawe.bukkit.adapter.BukkitQueueHandler;
|
import com.boydti.fawe.bukkit.adapter.BukkitQueueHandler;
|
||||||
|
import com.boydti.fawe.bukkit.adapter.NMSAdapter;
|
||||||
import com.boydti.fawe.bukkit.listener.BrushListener;
|
import com.boydti.fawe.bukkit.listener.BrushListener;
|
||||||
import com.boydti.fawe.bukkit.listener.BukkitImageListener;
|
import com.boydti.fawe.bukkit.listener.BukkitImageListener;
|
||||||
import com.boydti.fawe.bukkit.listener.CFIPacketListener;
|
import com.boydti.fawe.bukkit.listener.CFIPacketListener;
|
||||||
@ -58,6 +60,7 @@ public class FaweBukkit implements IFawe, Listener {
|
|||||||
private BukkitImageListener imageListener;
|
private BukkitImageListener imageListener;
|
||||||
private CFIPacketListener packetListener;
|
private CFIPacketListener packetListener;
|
||||||
private final boolean chunksStretched;
|
private final boolean chunksStretched;
|
||||||
|
private final FAWEPlatformAdapterImpl platformAdapter;
|
||||||
|
|
||||||
public FaweBukkit(Plugin plugin) {
|
public FaweBukkit(Plugin plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
@ -81,6 +84,8 @@ public class FaweBukkit implements IFawe, Listener {
|
|||||||
chunksStretched =
|
chunksStretched =
|
||||||
Integer.parseInt(Bukkit.getBukkitVersion().split("-")[0].split("\\.")[1]) >= 16;
|
Integer.parseInt(Bukkit.getBukkitVersion().split("-")[0].split("\\.")[1]) >= 16;
|
||||||
|
|
||||||
|
platformAdapter = new NMSAdapter();
|
||||||
|
|
||||||
//PlotSquared support is limited to Spigot/Paper as of 02/20/2020
|
//PlotSquared support is limited to Spigot/Paper as of 02/20/2020
|
||||||
TaskManager.IMP.later(this::setupPlotSquared, 0);
|
TaskManager.IMP.later(this::setupPlotSquared, 0);
|
||||||
|
|
||||||
@ -294,6 +299,11 @@ public class FaweBukkit implements IFawe, Listener {
|
|||||||
return chunksStretched;
|
return chunksStretched;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FAWEPlatformAdapterImpl getPlatformAdapter() {
|
||||||
|
return platformAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
private void setupPlotSquared() {
|
private void setupPlotSquared() {
|
||||||
Plugin plotSquared = this.plugin.getServer().getPluginManager().getPlugin("PlotSquared");
|
Plugin plotSquared = this.plugin.getServer().getPluginManager().getPlugin("PlotSquared");
|
||||||
if (plotSquared == null) {
|
if (plotSquared == null) {
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.boydti.fawe.bukkit.adapter;
|
||||||
|
|
||||||
|
public interface BukkitGetBlocks {
|
||||||
|
|
||||||
|
void send(int mask, boolean lighting);
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,8 @@
|
|||||||
package com.boydti.fawe.bukkit.adapter;
|
package com.boydti.fawe.bukkit.adapter;
|
||||||
|
|
||||||
|
import com.boydti.fawe.FAWEPlatformAdapterImpl;
|
||||||
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
|
import com.boydti.fawe.beta.implementation.chunk.ChunkHolder;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
@ -10,7 +13,7 @@ import com.sk89q.worldedit.world.block.BlockTypesCache;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class NMSAdapter {
|
public class NMSAdapter implements FAWEPlatformAdapterImpl {
|
||||||
public static int createPalette(int[] blockToPalette, int[] paletteToBlock, int[] blocksCopy,
|
public static int createPalette(int[] blockToPalette, int[] paletteToBlock, int[] blocksCopy,
|
||||||
int[] num_palette_buffer, char[] set, Map<BlockVector3, Integer> ticking_blocks, boolean fastmode) {
|
int[] num_palette_buffer, char[] set, Map<BlockVector3, Integer> ticking_blocks, boolean fastmode) {
|
||||||
int air = 0;
|
int air = 0;
|
||||||
@ -182,4 +185,12 @@ public class NMSAdapter {
|
|||||||
num_palette_buffer[0] = num_palette;
|
num_palette_buffer[0] = num_palette;
|
||||||
return air;
|
return air;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendChunk(IChunkGet chunk, int mask, boolean lighting) {
|
||||||
|
if (!(chunk instanceof BukkitGetBlocks)) {
|
||||||
|
throw new IllegalArgumentException("(IChunkGet) chunk not of type BukkitGetBlocks");
|
||||||
|
}
|
||||||
|
((BukkitGetBlocks) chunk).send(mask, lighting);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import com.boydti.fawe.beta.IChunkSet;
|
|||||||
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
||||||
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
|
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
|
||||||
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
||||||
|
import com.boydti.fawe.bukkit.adapter.BukkitGetBlocks;
|
||||||
import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
||||||
import com.boydti.fawe.bukkit.adapter.mc1_15_2.nbt.LazyCompoundTag_1_15_2;
|
import com.boydti.fawe.bukkit.adapter.mc1_15_2.nbt.LazyCompoundTag_1_15_2;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
@ -74,7 +75,7 @@ import javax.annotation.Nullable;
|
|||||||
|
|
||||||
import static org.slf4j.LoggerFactory.getLogger;
|
import static org.slf4j.LoggerFactory.getLogger;
|
||||||
|
|
||||||
public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
public class BukkitGetBlocks_1_15_2 extends CharGetBlocks implements BukkitGetBlocks {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(BukkitGetBlocks_1_15_2.class);
|
private static final Logger log = LoggerFactory.getLogger(BukkitGetBlocks_1_15_2.class);
|
||||||
|
|
||||||
@ -90,6 +91,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
private boolean createCopy = false;
|
private boolean createCopy = false;
|
||||||
private BukkitGetBlocks_1_15_2_Copy copy = null;
|
private BukkitGetBlocks_1_15_2_Copy copy = null;
|
||||||
private boolean forceLoadSections = true;
|
private boolean forceLoadSections = true;
|
||||||
|
private boolean lightUpdate = false;
|
||||||
|
|
||||||
public BukkitGetBlocks_1_15_2(World world, int chunkX, int chunkZ) {
|
public BukkitGetBlocks_1_15_2(World world, int chunkX, int chunkZ) {
|
||||||
this(((CraftWorld) world).getHandle(), chunkX, chunkZ);
|
this(((CraftWorld) world).getHandle(), chunkX, chunkZ);
|
||||||
@ -120,6 +122,37 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLightingToGet(char[][] light) {
|
||||||
|
if (light != null) {
|
||||||
|
lightUpdate = true;
|
||||||
|
try {
|
||||||
|
fillLightNibble(light, EnumSkyBlock.BLOCK);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSkyLightingToGet(char[][] light) {
|
||||||
|
if (light != null) {
|
||||||
|
lightUpdate = true;
|
||||||
|
try {
|
||||||
|
fillLightNibble(light, EnumSkyBlock.SKY);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeightmapToGet(HeightMapType type, int[] data) {
|
||||||
|
BitArray bitArray = new BitArray(9, 256);
|
||||||
|
bitArray.fromRaw(data);
|
||||||
|
nmsChunk.heightMap.get(HeightMap.Type.valueOf(type.name())).a(bitArray.getData());
|
||||||
|
}
|
||||||
|
|
||||||
public int getChunkZ() {
|
public int getChunkZ() {
|
||||||
return chunkZ;
|
return chunkZ;
|
||||||
}
|
}
|
||||||
@ -141,6 +174,34 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(base)) : null;
|
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(base)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeSectionLighting(int layer, boolean sky) {
|
||||||
|
SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer);
|
||||||
|
NibbleArray nibble = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.BLOCK).a(sectionPosition);
|
||||||
|
if (nibble != null) {
|
||||||
|
lightUpdate = true;
|
||||||
|
synchronized (nibble) {
|
||||||
|
byte[] bytes = nibble.getCloneIfSet();
|
||||||
|
if (bytes != NibbleArray.EMPTY_NIBBLE) {
|
||||||
|
Arrays.fill(bytes, (byte) 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sky) {
|
||||||
|
SectionPosition sectionPositionSky = SectionPosition.a(nmsChunk.getPos(), layer);
|
||||||
|
NibbleArray nibbleSky = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.SKY).a(sectionPositionSky);
|
||||||
|
if (nibble != null) {
|
||||||
|
lightUpdate = true;
|
||||||
|
synchronized (nibbleSky) {
|
||||||
|
byte[] bytes = nibbleSky.getCloneIfSet();
|
||||||
|
if (bytes != NibbleArray.EMPTY_NIBBLE) {
|
||||||
|
Arrays.fill(bytes, (byte) 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag getTile(int x, int y, int z) {
|
public CompoundTag getTile(int x, int y, int z) {
|
||||||
TileEntity tileEntity = getChunk().getTileEntity(new BlockPosition((x & 15) + (
|
TileEntity tileEntity = getChunk().getTileEntity(new BlockPosition((x & 15) + (
|
||||||
@ -436,33 +497,10 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
|
|
||||||
Map<HeightMapType, int[]> heightMaps = set.getHeightMaps();
|
Map<HeightMapType, int[]> heightMaps = set.getHeightMaps();
|
||||||
for (Map.Entry<HeightMapType, int[]> entry : heightMaps.entrySet()) {
|
for (Map.Entry<HeightMapType, int[]> entry : heightMaps.entrySet()) {
|
||||||
BitArray bitArray = new BitArray(9, 256);
|
BukkitGetBlocks_1_15_2.this.setHeightmapToGet(entry.getKey(), entry.getValue());
|
||||||
bitArray.fromRaw(entry.getValue());
|
|
||||||
nmsChunk.heightMap.get(HeightMap.Type.valueOf(entry.getKey().name())).a(bitArray.getData());
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean lightUpdate = false;
|
|
||||||
|
|
||||||
// Lighting
|
|
||||||
char[][] light = set.getLight();
|
|
||||||
if (light != null) {
|
|
||||||
lightUpdate = true;
|
|
||||||
try {
|
|
||||||
fillLightNibble(light, EnumSkyBlock.BLOCK);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char[][] skyLight = set.getSkyLight();
|
|
||||||
if (skyLight != null) {
|
|
||||||
lightUpdate = true;
|
|
||||||
try {
|
|
||||||
fillLightNibble(skyLight, EnumSkyBlock.SKY);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
BukkitGetBlocks_1_15_2.this.setLightingToGet(set.getLight());
|
||||||
|
BukkitGetBlocks_1_15_2.this.setSkyLightingToGet(set.getSkyLight());
|
||||||
|
|
||||||
Runnable[] syncTasks = null;
|
Runnable[] syncTasks = null;
|
||||||
|
|
||||||
@ -584,7 +622,9 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
nmsChunk.mustNotSave = false;
|
nmsChunk.mustNotSave = false;
|
||||||
nmsChunk.markDirty();
|
nmsChunk.markDirty();
|
||||||
// send to player
|
// send to player
|
||||||
BukkitAdapter_1_15_2.sendChunk(nmsWorld, chunkX, chunkZ, finalMask, finalLightUpdate);
|
if (Settings.IMP.LIGHTING.MODE == 0 || !Settings.IMP.LIGHTING.DELAY_PACKET_SENDING) {
|
||||||
|
this.send(finalMask, finalLightUpdate);
|
||||||
|
}
|
||||||
if (finalizer != null) {
|
if (finalizer != null) {
|
||||||
finalizer.run();
|
finalizer.run();
|
||||||
}
|
}
|
||||||
@ -636,6 +676,11 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void send(int mask, boolean lighting) {
|
||||||
|
BukkitAdapter_1_15_2.sendChunk(world, chunkX, chunkZ, mask, lighting);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized char[] update(int layer, char[] data) {
|
public synchronized char[] update(int layer, char[] data) {
|
||||||
ChunkSection section = getSections(true)[layer];
|
ChunkSection section = getSections(true)[layer];
|
||||||
|
@ -104,6 +104,15 @@ public class BukkitGetBlocks_1_15_2_Copy implements IChunkGet {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLightingToGet(char[][] lighting) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSkyLightingToGet(char[][] lighting) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeightmapToGet(HeightMapType type, int[] data) {}
|
||||||
|
|
||||||
protected void storeBiomes(BiomeStorage biomeStorage) {
|
protected void storeBiomes(BiomeStorage biomeStorage) {
|
||||||
this.biomeStorage = new BiomeStorage(BukkitAdapter_1_15_2.getBiomeArray(biomeStorage).clone());
|
this.biomeStorage = new BiomeStorage(BukkitAdapter_1_15_2.getBiomeArray(biomeStorage).clone());
|
||||||
}
|
}
|
||||||
@ -122,6 +131,9 @@ public class BukkitGetBlocks_1_15_2_Copy implements IChunkGet {
|
|||||||
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(base)) : null;
|
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(base)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeSectionLighting(int layer, boolean sky) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean trim(boolean aggressive, int layer) {
|
public boolean trim(boolean aggressive, int layer) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -7,6 +7,7 @@ import com.boydti.fawe.beta.IChunkSet;
|
|||||||
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
||||||
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
|
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
|
||||||
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
||||||
|
import com.boydti.fawe.bukkit.adapter.BukkitGetBlocks;
|
||||||
import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
||||||
import com.boydti.fawe.bukkit.adapter.mc1_16_1.nbt.LazyCompoundTag_1_16_1;
|
import com.boydti.fawe.bukkit.adapter.mc1_16_1.nbt.LazyCompoundTag_1_16_1;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
@ -74,7 +75,7 @@ import javax.annotation.Nullable;
|
|||||||
|
|
||||||
import static org.slf4j.LoggerFactory.getLogger;
|
import static org.slf4j.LoggerFactory.getLogger;
|
||||||
|
|
||||||
public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
public class BukkitGetBlocks_1_16_1 extends CharGetBlocks implements BukkitGetBlocks {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(BukkitGetBlocks_1_16_1.class);
|
private static final Logger log = LoggerFactory.getLogger(BukkitGetBlocks_1_16_1.class);
|
||||||
|
|
||||||
@ -90,6 +91,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
private boolean createCopy = false;
|
private boolean createCopy = false;
|
||||||
private BukkitGetBlocks_1_16_1_Copy copy = null;
|
private BukkitGetBlocks_1_16_1_Copy copy = null;
|
||||||
private boolean forceLoadSections = true;
|
private boolean forceLoadSections = true;
|
||||||
|
private boolean lightUpdate = false;
|
||||||
|
|
||||||
public BukkitGetBlocks_1_16_1(World world, int chunkX, int chunkZ) {
|
public BukkitGetBlocks_1_16_1(World world, int chunkX, int chunkZ) {
|
||||||
this(((CraftWorld) world).getHandle(), chunkX, chunkZ);
|
this(((CraftWorld) world).getHandle(), chunkX, chunkZ);
|
||||||
@ -121,6 +123,37 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLightingToGet(char[][] light) {
|
||||||
|
if (light != null) {
|
||||||
|
lightUpdate = true;
|
||||||
|
try {
|
||||||
|
fillLightNibble(light, EnumSkyBlock.BLOCK);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSkyLightingToGet(char[][] light) {
|
||||||
|
if (light != null) {
|
||||||
|
lightUpdate = true;
|
||||||
|
try {
|
||||||
|
fillLightNibble(light, EnumSkyBlock.SKY);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeightmapToGet(HeightMapType type, int[] data) {
|
||||||
|
BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256);
|
||||||
|
bitArray.fromRaw(data);
|
||||||
|
nmsChunk.heightMap.get(HeightMap.Type.valueOf(type.name())).a(bitArray.getData());
|
||||||
|
}
|
||||||
|
|
||||||
public int getChunkZ() {
|
public int getChunkZ() {
|
||||||
return chunkZ;
|
return chunkZ;
|
||||||
}
|
}
|
||||||
@ -142,6 +175,34 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(base)) : null;
|
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(base)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeSectionLighting(int layer, boolean sky) {
|
||||||
|
SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer);
|
||||||
|
NibbleArray nibble = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.BLOCK).a(sectionPosition);
|
||||||
|
if (nibble != null) {
|
||||||
|
lightUpdate = true;
|
||||||
|
synchronized (nibble) {
|
||||||
|
byte[] bytes = nibble.getCloneIfSet();
|
||||||
|
if (bytes != NibbleArray.EMPTY_NIBBLE) {
|
||||||
|
Arrays.fill(bytes, (byte) 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sky) {
|
||||||
|
SectionPosition sectionPositionSky = SectionPosition.a(nmsChunk.getPos(), layer);
|
||||||
|
NibbleArray nibbleSky = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.SKY).a(sectionPositionSky);
|
||||||
|
if (nibble != null) {
|
||||||
|
lightUpdate = true;
|
||||||
|
synchronized (nibbleSky) {
|
||||||
|
byte[] bytes = nibbleSky.getCloneIfSet();
|
||||||
|
if (bytes != NibbleArray.EMPTY_NIBBLE) {
|
||||||
|
Arrays.fill(bytes, (byte) 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag getTile(int x, int y, int z) {
|
public CompoundTag getTile(int x, int y, int z) {
|
||||||
TileEntity tileEntity = getChunk().getTileEntity(new BlockPosition((x & 15) + (
|
TileEntity tileEntity = getChunk().getTileEntity(new BlockPosition((x & 15) + (
|
||||||
@ -438,33 +499,10 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
|
|
||||||
Map<HeightMapType, int[]> heightMaps = set.getHeightMaps();
|
Map<HeightMapType, int[]> heightMaps = set.getHeightMaps();
|
||||||
for (Map.Entry<HeightMapType, int[]> entry : heightMaps.entrySet()) {
|
for (Map.Entry<HeightMapType, int[]> entry : heightMaps.entrySet()) {
|
||||||
BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256);
|
BukkitGetBlocks_1_16_1.this.setHeightmapToGet(entry.getKey(), entry.getValue());
|
||||||
bitArray.fromRaw(entry.getValue());
|
|
||||||
nmsChunk.heightMap.get(HeightMap.Type.valueOf(entry.getKey().name())).a(bitArray.getData());
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean lightUpdate = false;
|
|
||||||
|
|
||||||
// Lighting
|
|
||||||
char[][] light = set.getLight();
|
|
||||||
if (light != null) {
|
|
||||||
lightUpdate = true;
|
|
||||||
try {
|
|
||||||
fillLightNibble(light, EnumSkyBlock.BLOCK);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char[][] skyLight = set.getSkyLight();
|
|
||||||
if (skyLight != null) {
|
|
||||||
lightUpdate = true;
|
|
||||||
try {
|
|
||||||
fillLightNibble(skyLight, EnumSkyBlock.SKY);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
BukkitGetBlocks_1_16_1.this.setLightingToGet(set.getLight());
|
||||||
|
BukkitGetBlocks_1_16_1.this.setSkyLightingToGet(set.getSkyLight());
|
||||||
|
|
||||||
Runnable[] syncTasks = null;
|
Runnable[] syncTasks = null;
|
||||||
|
|
||||||
@ -586,7 +624,9 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
nmsChunk.mustNotSave = false;
|
nmsChunk.mustNotSave = false;
|
||||||
nmsChunk.markDirty();
|
nmsChunk.markDirty();
|
||||||
// send to player
|
// send to player
|
||||||
BukkitAdapter_1_16_1.sendChunk(nmsWorld, chunkX, chunkZ, finalMask, finalLightUpdate);
|
if (Settings.IMP.LIGHTING.MODE == 0 || !Settings.IMP.LIGHTING.DELAY_PACKET_SENDING) {
|
||||||
|
this.send(finalMask, finalLightUpdate);
|
||||||
|
}
|
||||||
if (finalizer != null) {
|
if (finalizer != null) {
|
||||||
finalizer.run();
|
finalizer.run();
|
||||||
}
|
}
|
||||||
@ -638,6 +678,11 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void send(int mask, boolean lighting) {
|
||||||
|
BukkitAdapter_1_16_1.sendChunk(world, chunkX, chunkZ, mask, lighting);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized char[] update(int layer, char[] data) {
|
public synchronized char[] update(int layer, char[] data) {
|
||||||
ChunkSection section = getSections(true)[layer];
|
ChunkSection section = getSections(true)[layer];
|
||||||
|
@ -104,6 +104,15 @@ public class BukkitGetBlocks_1_16_1_Copy implements IChunkGet {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLightingToGet(char[][] lighting) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSkyLightingToGet(char[][] lighting) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeightmapToGet(HeightMapType type, int[] data) {}
|
||||||
|
|
||||||
protected void storeBiomes(BiomeStorage biomeStorage) {
|
protected void storeBiomes(BiomeStorage biomeStorage) {
|
||||||
this.biomeStorage = new BiomeStorage(BukkitAdapter_1_16_1.getBiomeArray(biomeStorage).clone());
|
this.biomeStorage = new BiomeStorage(BukkitAdapter_1_16_1.getBiomeArray(biomeStorage).clone());
|
||||||
}
|
}
|
||||||
@ -122,6 +131,9 @@ public class BukkitGetBlocks_1_16_1_Copy implements IChunkGet {
|
|||||||
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(base)) : null;
|
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(base)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeSectionLighting(int layer, boolean sky) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean trim(boolean aggressive, int layer) {
|
public boolean trim(boolean aggressive, int layer) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -7,6 +7,7 @@ import com.boydti.fawe.beta.IChunkSet;
|
|||||||
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
||||||
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
|
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
|
||||||
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
||||||
|
import com.boydti.fawe.bukkit.adapter.BukkitGetBlocks;
|
||||||
import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
||||||
import com.boydti.fawe.bukkit.adapter.mc1_16_2.nbt.LazyCompoundTag_1_16_2;
|
import com.boydti.fawe.bukkit.adapter.mc1_16_2.nbt.LazyCompoundTag_1_16_2;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
@ -75,7 +76,7 @@ import java.util.function.Function;
|
|||||||
|
|
||||||
import static org.slf4j.LoggerFactory.getLogger;
|
import static org.slf4j.LoggerFactory.getLogger;
|
||||||
|
|
||||||
public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
public class BukkitGetBlocks_1_16_2 extends CharGetBlocks implements BukkitGetBlocks {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(BukkitGetBlocks_1_16_2.class);
|
private static final Logger log = LoggerFactory.getLogger(BukkitGetBlocks_1_16_2.class);
|
||||||
|
|
||||||
@ -91,6 +92,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
private boolean createCopy = false;
|
private boolean createCopy = false;
|
||||||
private BukkitGetBlocks_1_16_2_Copy copy = null;
|
private BukkitGetBlocks_1_16_2_Copy copy = null;
|
||||||
private boolean forceLoadSections = true;
|
private boolean forceLoadSections = true;
|
||||||
|
private boolean lightUpdate = false;
|
||||||
|
|
||||||
public BukkitGetBlocks_1_16_2(World world, int chunkX, int chunkZ) {
|
public BukkitGetBlocks_1_16_2(World world, int chunkX, int chunkZ) {
|
||||||
this(((CraftWorld) world).getHandle(), chunkX, chunkZ);
|
this(((CraftWorld) world).getHandle(), chunkX, chunkZ);
|
||||||
@ -121,6 +123,37 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLightingToGet(char[][] light) {
|
||||||
|
if (light != null) {
|
||||||
|
lightUpdate = true;
|
||||||
|
try {
|
||||||
|
fillLightNibble(light, EnumSkyBlock.BLOCK);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSkyLightingToGet(char[][] light) {
|
||||||
|
if (light != null) {
|
||||||
|
lightUpdate = true;
|
||||||
|
try {
|
||||||
|
fillLightNibble(light, EnumSkyBlock.SKY);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeightmapToGet(HeightMapType type, int[] data) {
|
||||||
|
BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256);
|
||||||
|
bitArray.fromRaw(data);
|
||||||
|
nmsChunk.heightMap.get(HeightMap.Type.valueOf(type.name())).a(bitArray.getData());
|
||||||
|
}
|
||||||
|
|
||||||
public int getChunkZ() {
|
public int getChunkZ() {
|
||||||
return chunkZ;
|
return chunkZ;
|
||||||
}
|
}
|
||||||
@ -142,6 +175,34 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(world.r().b(IRegistry.ay), base)) : null;
|
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(world.r().b(IRegistry.ay), base)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeSectionLighting(int layer, boolean sky) {
|
||||||
|
SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer);
|
||||||
|
NibbleArray nibble = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.BLOCK).a(sectionPosition);
|
||||||
|
if (nibble != null) {
|
||||||
|
lightUpdate = true;
|
||||||
|
synchronized (nibble) {
|
||||||
|
byte[] bytes = nibble.getCloneIfSet();
|
||||||
|
if (bytes != NibbleArray.EMPTY_NIBBLE) {
|
||||||
|
Arrays.fill(bytes, (byte) 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sky) {
|
||||||
|
SectionPosition sectionPositionSky = SectionPosition.a(nmsChunk.getPos(), layer);
|
||||||
|
NibbleArray nibbleSky = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.SKY).a(sectionPositionSky);
|
||||||
|
if (nibble != null) {
|
||||||
|
lightUpdate = true;
|
||||||
|
synchronized (nibbleSky) {
|
||||||
|
byte[] bytes = nibbleSky.getCloneIfSet();
|
||||||
|
if (bytes != NibbleArray.EMPTY_NIBBLE) {
|
||||||
|
Arrays.fill(bytes, (byte) 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag getTile(int x, int y, int z) {
|
public CompoundTag getTile(int x, int y, int z) {
|
||||||
TileEntity tileEntity = getChunk().getTileEntity(new BlockPosition((x & 15) + (
|
TileEntity tileEntity = getChunk().getTileEntity(new BlockPosition((x & 15) + (
|
||||||
@ -441,33 +502,10 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
|
|
||||||
Map<HeightMapType, int[]> heightMaps = set.getHeightMaps();
|
Map<HeightMapType, int[]> heightMaps = set.getHeightMaps();
|
||||||
for (Map.Entry<HeightMapType, int[]> entry : heightMaps.entrySet()) {
|
for (Map.Entry<HeightMapType, int[]> entry : heightMaps.entrySet()) {
|
||||||
BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256);
|
BukkitGetBlocks_1_16_2.this.setHeightmapToGet(entry.getKey(), entry.getValue());
|
||||||
bitArray.fromRaw(entry.getValue());
|
|
||||||
nmsChunk.heightMap.get(HeightMap.Type.valueOf(entry.getKey().name())).a(bitArray.getData());
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean lightUpdate = false;
|
|
||||||
|
|
||||||
// Lighting
|
|
||||||
char[][] light = set.getLight();
|
|
||||||
if (light != null) {
|
|
||||||
lightUpdate = true;
|
|
||||||
try {
|
|
||||||
fillLightNibble(light, EnumSkyBlock.BLOCK);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char[][] skyLight = set.getSkyLight();
|
|
||||||
if (skyLight != null) {
|
|
||||||
lightUpdate = true;
|
|
||||||
try {
|
|
||||||
fillLightNibble(skyLight, EnumSkyBlock.SKY);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
BukkitGetBlocks_1_16_2.this.setLightingToGet(set.getLight());
|
||||||
|
BukkitGetBlocks_1_16_2.this.setSkyLightingToGet(set.getSkyLight());
|
||||||
|
|
||||||
Runnable[] syncTasks = null;
|
Runnable[] syncTasks = null;
|
||||||
|
|
||||||
@ -589,7 +627,9 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
nmsChunk.mustNotSave = false;
|
nmsChunk.mustNotSave = false;
|
||||||
nmsChunk.markDirty();
|
nmsChunk.markDirty();
|
||||||
// send to player
|
// send to player
|
||||||
BukkitAdapter_1_16_2.sendChunk(nmsWorld, chunkX, chunkZ, finalMask, finalLightUpdate);
|
if (Settings.IMP.LIGHTING.MODE == 0 || !Settings.IMP.LIGHTING.DELAY_PACKET_SENDING) {
|
||||||
|
this.send(finalMask, finalLightUpdate);
|
||||||
|
}
|
||||||
if (finalizer != null) {
|
if (finalizer != null) {
|
||||||
finalizer.run();
|
finalizer.run();
|
||||||
}
|
}
|
||||||
@ -641,6 +681,11 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void send(int mask, boolean lighting) {
|
||||||
|
BukkitAdapter_1_16_2.sendChunk(world, chunkX, chunkZ, mask, lighting);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized char[] update(int layer, char[] data) {
|
public synchronized char[] update(int layer, char[] data) {
|
||||||
ChunkSection section = getSections(true)[layer];
|
ChunkSection section = getSections(true)[layer];
|
||||||
|
@ -105,6 +105,15 @@ public class BukkitGetBlocks_1_16_2_Copy implements IChunkGet {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLightingToGet(char[][] lighting) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSkyLightingToGet(char[][] lighting) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeightmapToGet(HeightMapType type, int[] data) {}
|
||||||
|
|
||||||
protected void storeBiomes(BiomeStorage biomeStorage) {
|
protected void storeBiomes(BiomeStorage biomeStorage) {
|
||||||
this.biomeStorage = new BiomeStorage(biomeStorage.g, BukkitAdapter_1_16_2.getBiomeArray(biomeStorage).clone());
|
this.biomeStorage = new BiomeStorage(biomeStorage.g, BukkitAdapter_1_16_2.getBiomeArray(biomeStorage).clone());
|
||||||
}
|
}
|
||||||
@ -123,6 +132,9 @@ public class BukkitGetBlocks_1_16_2_Copy implements IChunkGet {
|
|||||||
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(world.r().b(IRegistry.ay), base)) : null;
|
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(world.r().b(IRegistry.ay), base)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeSectionLighting(int layer, boolean sky) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean trim(boolean aggressive, int layer) {
|
public boolean trim(boolean aggressive, int layer) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -7,6 +7,7 @@ import com.boydti.fawe.beta.IChunkSet;
|
|||||||
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
||||||
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
|
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
|
||||||
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
||||||
|
import com.boydti.fawe.bukkit.adapter.BukkitGetBlocks;
|
||||||
import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
||||||
import com.boydti.fawe.bukkit.adapter.mc1_16_4.nbt.LazyCompoundTag_1_16_4;
|
import com.boydti.fawe.bukkit.adapter.mc1_16_4.nbt.LazyCompoundTag_1_16_4;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
@ -75,7 +76,7 @@ import java.util.function.Function;
|
|||||||
|
|
||||||
import static org.slf4j.LoggerFactory.getLogger;
|
import static org.slf4j.LoggerFactory.getLogger;
|
||||||
|
|
||||||
public class BukkitGetBlocks_1_16_4 extends CharGetBlocks {
|
public class BukkitGetBlocks_1_16_4 extends CharGetBlocks implements BukkitGetBlocks {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(BukkitGetBlocks_1_16_4.class);
|
private static final Logger log = LoggerFactory.getLogger(BukkitGetBlocks_1_16_4.class);
|
||||||
|
|
||||||
@ -91,6 +92,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks {
|
|||||||
private boolean createCopy = false;
|
private boolean createCopy = false;
|
||||||
private BukkitGetBlocks_1_16_4_Copy copy = null;
|
private BukkitGetBlocks_1_16_4_Copy copy = null;
|
||||||
private boolean forceLoadSections = true;
|
private boolean forceLoadSections = true;
|
||||||
|
private boolean lightUpdate = false;
|
||||||
|
|
||||||
public BukkitGetBlocks_1_16_4(World world, int chunkX, int chunkZ) {
|
public BukkitGetBlocks_1_16_4(World world, int chunkX, int chunkZ) {
|
||||||
this(((CraftWorld) world).getHandle(), chunkX, chunkZ);
|
this(((CraftWorld) world).getHandle(), chunkX, chunkZ);
|
||||||
@ -121,6 +123,37 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks {
|
|||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLightingToGet(char[][] light) {
|
||||||
|
if (light != null) {
|
||||||
|
lightUpdate = true;
|
||||||
|
try {
|
||||||
|
fillLightNibble(light, EnumSkyBlock.BLOCK);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSkyLightingToGet(char[][] light) {
|
||||||
|
if (light != null) {
|
||||||
|
lightUpdate = true;
|
||||||
|
try {
|
||||||
|
fillLightNibble(light, EnumSkyBlock.SKY);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeightmapToGet(HeightMapType type, int[] data) {
|
||||||
|
BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256);
|
||||||
|
bitArray.fromRaw(data);
|
||||||
|
nmsChunk.heightMap.get(HeightMap.Type.valueOf(type.name())).a(bitArray.getData());
|
||||||
|
}
|
||||||
|
|
||||||
public int getChunkZ() {
|
public int getChunkZ() {
|
||||||
return chunkZ;
|
return chunkZ;
|
||||||
}
|
}
|
||||||
@ -142,6 +175,34 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks {
|
|||||||
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(world.r().b(IRegistry.ay), base)) : null;
|
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(world.r().b(IRegistry.ay), base)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeSectionLighting(int layer, boolean sky) {
|
||||||
|
SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer);
|
||||||
|
NibbleArray nibble = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.BLOCK).a(sectionPosition);
|
||||||
|
if (nibble != null) {
|
||||||
|
lightUpdate = true;
|
||||||
|
synchronized (nibble) {
|
||||||
|
byte[] bytes = nibble.getCloneIfSet();
|
||||||
|
if (bytes != NibbleArray.EMPTY_NIBBLE) {
|
||||||
|
Arrays.fill(bytes, (byte) 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sky) {
|
||||||
|
SectionPosition sectionPositionSky = SectionPosition.a(nmsChunk.getPos(), layer);
|
||||||
|
NibbleArray nibbleSky = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.SKY).a(sectionPositionSky);
|
||||||
|
if (nibble != null) {
|
||||||
|
lightUpdate = true;
|
||||||
|
synchronized (nibbleSky) {
|
||||||
|
byte[] bytes = nibbleSky.getCloneIfSet();
|
||||||
|
if (bytes != NibbleArray.EMPTY_NIBBLE) {
|
||||||
|
Arrays.fill(bytes, (byte) 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag getTile(int x, int y, int z) {
|
public CompoundTag getTile(int x, int y, int z) {
|
||||||
TileEntity tileEntity = getChunk().getTileEntity(new BlockPosition((x & 15) + (
|
TileEntity tileEntity = getChunk().getTileEntity(new BlockPosition((x & 15) + (
|
||||||
@ -441,33 +502,10 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks {
|
|||||||
|
|
||||||
Map<HeightMapType, int[]> heightMaps = set.getHeightMaps();
|
Map<HeightMapType, int[]> heightMaps = set.getHeightMaps();
|
||||||
for (Map.Entry<HeightMapType, int[]> entry : heightMaps.entrySet()) {
|
for (Map.Entry<HeightMapType, int[]> entry : heightMaps.entrySet()) {
|
||||||
BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256);
|
BukkitGetBlocks_1_16_4.this.setHeightmapToGet(entry.getKey(), entry.getValue());
|
||||||
bitArray.fromRaw(entry.getValue());
|
|
||||||
nmsChunk.heightMap.get(HeightMap.Type.valueOf(entry.getKey().name())).a(bitArray.getData());
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean lightUpdate = false;
|
|
||||||
|
|
||||||
// Lighting
|
|
||||||
char[][] light = set.getLight();
|
|
||||||
if (light != null) {
|
|
||||||
lightUpdate = true;
|
|
||||||
try {
|
|
||||||
fillLightNibble(light, EnumSkyBlock.BLOCK);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char[][] skyLight = set.getSkyLight();
|
|
||||||
if (skyLight != null) {
|
|
||||||
lightUpdate = true;
|
|
||||||
try {
|
|
||||||
fillLightNibble(skyLight, EnumSkyBlock.SKY);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
BukkitGetBlocks_1_16_4.this.setLightingToGet(set.getLight());
|
||||||
|
BukkitGetBlocks_1_16_4.this.setSkyLightingToGet(set.getSkyLight());
|
||||||
|
|
||||||
Runnable[] syncTasks = null;
|
Runnable[] syncTasks = null;
|
||||||
|
|
||||||
@ -589,7 +627,9 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks {
|
|||||||
nmsChunk.mustNotSave = false;
|
nmsChunk.mustNotSave = false;
|
||||||
nmsChunk.markDirty();
|
nmsChunk.markDirty();
|
||||||
// send to player
|
// send to player
|
||||||
BukkitAdapter_1_16_4.sendChunk(nmsWorld, chunkX, chunkZ, finalMask, finalLightUpdate);
|
if (Settings.IMP.LIGHTING.MODE == 0 || !Settings.IMP.LIGHTING.DELAY_PACKET_SENDING) {
|
||||||
|
this.send(finalMask, finalLightUpdate);
|
||||||
|
}
|
||||||
if (finalizer != null) {
|
if (finalizer != null) {
|
||||||
finalizer.run();
|
finalizer.run();
|
||||||
}
|
}
|
||||||
@ -641,6 +681,11 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void send(int mask, boolean lighting) {
|
||||||
|
BukkitAdapter_1_16_4.sendChunk(world, chunkX, chunkZ, mask, lighting);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized char[] update(int layer, char[] data) {
|
public synchronized char[] update(int layer, char[] data) {
|
||||||
ChunkSection section = getSections(true)[layer];
|
ChunkSection section = getSections(true)[layer];
|
||||||
|
@ -105,6 +105,15 @@ public class BukkitGetBlocks_1_16_4_Copy implements IChunkGet {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLightingToGet(char[][] lighting) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSkyLightingToGet(char[][] lighting) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeightmapToGet(HeightMapType type, int[] data) {}
|
||||||
|
|
||||||
protected void storeBiomes(BiomeStorage biomeStorage) {
|
protected void storeBiomes(BiomeStorage biomeStorage) {
|
||||||
this.biomeStorage = new BiomeStorage(biomeStorage.g, BukkitAdapter_1_16_4.getBiomeArray(biomeStorage).clone());
|
this.biomeStorage = new BiomeStorage(biomeStorage.g, BukkitAdapter_1_16_4.getBiomeArray(biomeStorage).clone());
|
||||||
}
|
}
|
||||||
@ -123,6 +132,9 @@ public class BukkitGetBlocks_1_16_4_Copy implements IChunkGet {
|
|||||||
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(world.r().b(IRegistry.ay), base)) : null;
|
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(world.r().b(IRegistry.ay), base)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeSectionLighting(int layer, boolean sky) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean trim(boolean aggressive, int layer) {
|
public boolean trim(boolean aggressive, int layer) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.boydti.fawe;
|
||||||
|
|
||||||
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
|
|
||||||
|
public interface FAWEPlatformAdapterImpl {
|
||||||
|
|
||||||
|
void sendChunk(IChunkGet chunk, int mask, boolean lighting);
|
||||||
|
|
||||||
|
}
|
@ -361,7 +361,7 @@ public class FaweAPI {
|
|||||||
} else {
|
} else {
|
||||||
relighter.removeLighting();
|
relighter.removeLighting();
|
||||||
}
|
}
|
||||||
relighter.sendChunks();
|
relighter.flush();
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,4 +43,6 @@ public interface IFawe {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FAWEPlatformAdapterImpl getPlatformAdapter();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,12 @@ public class CombinedBlocks implements IBlocks {
|
|||||||
return bitMask;
|
return bitMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeSectionLighting(int layer, boolean sky) {
|
||||||
|
primary.removeSectionLighting(layer, sky);
|
||||||
|
secondary.removeSectionLighting(layer, sky);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasSection(int layer) {
|
public boolean hasSection(int layer) {
|
||||||
return primary.hasSection(layer) || secondary.hasSection(layer);
|
return primary.hasSection(layer) || secondary.hasSection(layer);
|
||||||
|
@ -3,6 +3,7 @@ package com.boydti.fawe.beta;
|
|||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.beta.implementation.processors.EmptyBatchProcessor;
|
import com.boydti.fawe.beta.implementation.processors.EmptyBatchProcessor;
|
||||||
import com.boydti.fawe.beta.implementation.processors.MultiBatchProcessor;
|
import com.boydti.fawe.beta.implementation.processors.MultiBatchProcessor;
|
||||||
|
import com.boydti.fawe.beta.implementation.processors.ProcessorScope;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
@ -126,4 +127,11 @@ public interface IBatchProcessor {
|
|||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default to CUSTOM ProcessorScope as we want custom processors people add to be before we write history, but after FAWE does it's own stuff.
|
||||||
|
*/
|
||||||
|
default ProcessorScope getScope() {
|
||||||
|
return ProcessorScope.CUSTOM;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,8 @@ public interface IBlocks extends Trimable {
|
|||||||
.map(layer -> (1 << layer)).sum();
|
.map(layer -> (1 << layer)).sum();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void removeSectionLighting(int layer, boolean sky);
|
||||||
|
|
||||||
boolean trim(boolean aggressive, int layer);
|
boolean trim(boolean aggressive, int layer);
|
||||||
|
|
||||||
IBlocks reset();
|
IBlocks reset();
|
||||||
|
@ -56,4 +56,10 @@ public interface IChunkGet extends IBlocks, Trimable, InputExtent, ITileInput {
|
|||||||
default IChunkGet getCopy() {
|
default IChunkGet getCopy() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setLightingToGet(char[][] lighting);
|
||||||
|
|
||||||
|
void setSkyLightingToGet(char[][] lighting);
|
||||||
|
|
||||||
|
void setHeightmapToGet(HeightMapType type, int[] data);
|
||||||
}
|
}
|
||||||
|
@ -50,8 +50,6 @@ public interface IChunkSet extends IBlocks, OutputExtent {
|
|||||||
|
|
||||||
void setSkyLightLayer(int layer, char[] toSet);
|
void setSkyLightLayer(int layer, char[] toSet);
|
||||||
|
|
||||||
void removeSectionLighting(int layer, boolean sky);
|
|
||||||
|
|
||||||
void setFullBright(int layer);
|
void setFullBright(int layer);
|
||||||
|
|
||||||
void setEntity(CompoundTag tag);
|
void setEntity(CompoundTag tag);
|
||||||
|
@ -44,6 +44,11 @@ public class FallbackChunkGet implements IChunkGet {
|
|||||||
return extent.getBiomeType(bx + x, y, bz + z);
|
return extent.getBiomeType(bx + x, y, bz + z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeSectionLighting(int layer, boolean sky) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getBlock(int x, int y, int z) {
|
public BlockState getBlock(int x, int y, int z) {
|
||||||
return extent.getBlock(bx + x, y, bz + z);
|
return extent.getBlock(bx + x, y, bz + z);
|
||||||
@ -106,6 +111,21 @@ public class FallbackChunkGet implements IChunkGet {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLightingToGet(char[][] lighting) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSkyLightingToGet(char[][] lighting) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeightmapToGet(HeightMapType type, int[] data) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean trim(boolean aggressive) {
|
public boolean trim(boolean aggressive) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -38,6 +38,9 @@ public final class NullChunkGet implements IChunkGet {
|
|||||||
return BiomeTypes.FOREST;
|
return BiomeTypes.FOREST;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeSectionLighting(int layer, boolean sky) {}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public BlockState getBlock(int x, int y, int z) {
|
public BlockState getBlock(int x, int y, int z) {
|
||||||
return BlockTypes.AIR.getDefaultState();
|
return BlockTypes.AIR.getDefaultState();
|
||||||
@ -69,6 +72,15 @@ public final class NullChunkGet implements IChunkGet {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLightingToGet(char[][] lighting) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSkyLightingToGet(char[][] lighting) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeightmapToGet(HeightMapType type, int[] data) {}
|
||||||
|
|
||||||
public boolean trim(boolean aggressive) {
|
public boolean trim(boolean aggressive) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -151,6 +151,25 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
return createCopy;
|
return createCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLightingToGet(char[][] lighting) {
|
||||||
|
delegate.setLightingToGet(this, lighting);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSkyLightingToGet(char[][] lighting) {
|
||||||
|
delegate.setSkyLightingToGet(this, lighting);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeightmapToGet(HeightMapType type, int[] data) {
|
||||||
|
delegate.setHeightmapToGet(this, type, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flushLightToGet(boolean heightmaps) {
|
||||||
|
delegate.flushLightToGet(this, heightmaps);
|
||||||
|
}
|
||||||
|
|
||||||
private static final IBlockDelegate BOTH = new IBlockDelegate() {
|
private static final IBlockDelegate BOTH = new IBlockDelegate() {
|
||||||
@Override
|
@Override
|
||||||
public IChunkGet get(ChunkHolder chunk) {
|
public IChunkGet get(ChunkHolder chunk) {
|
||||||
@ -187,6 +206,7 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
@Override
|
@Override
|
||||||
public void removeSectionLighting(ChunkHolder chunk, int layer, boolean sky) {
|
public void removeSectionLighting(ChunkHolder chunk, int layer, boolean sky) {
|
||||||
chunk.chunkSet.removeSectionLighting(layer, sky);
|
chunk.chunkSet.removeSectionLighting(layer, sky);
|
||||||
|
chunk.chunkExisting.removeSectionLighting(layer, sky);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -264,6 +284,27 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
@Override public int[] getHeightMap(ChunkHolder chunk, HeightMapType type) {
|
@Override public int[] getHeightMap(ChunkHolder chunk, HeightMapType type) {
|
||||||
return chunk.chunkExisting.getHeightMap(type);
|
return chunk.chunkExisting.getHeightMap(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flushLightToGet(ChunkHolder chunk, boolean heightmaps) {
|
||||||
|
chunk.chunkExisting.setLightingToGet(chunk.chunkSet.getLight());
|
||||||
|
chunk.chunkExisting.setSkyLightingToGet(chunk.chunkSet.getSkyLight());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLightingToGet(ChunkHolder chunk, char[][] lighting) {
|
||||||
|
chunk.chunkExisting.setLightingToGet(lighting);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSkyLightingToGet(ChunkHolder chunk, char[][] lighting) {
|
||||||
|
chunk.chunkExisting.setSkyLightingToGet(lighting);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeightmapToGet(ChunkHolder chunk, HeightMapType type, int[] data) {
|
||||||
|
chunk.chunkExisting.setHeightmapToGet(type, data);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final IBlockDelegate GET = new IBlockDelegate() {
|
private static final IBlockDelegate GET = new IBlockDelegate() {
|
||||||
@ -382,6 +423,26 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
@Override public int[] getHeightMap(ChunkHolder chunk, HeightMapType type) {
|
@Override public int[] getHeightMap(ChunkHolder chunk, HeightMapType type) {
|
||||||
return chunk.chunkExisting.getHeightMap(type);
|
return chunk.chunkExisting.getHeightMap(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flushLightToGet(ChunkHolder chunk, boolean heightmaps) {
|
||||||
|
// Do nothing as no lighting to flush to GET
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLightingToGet(ChunkHolder chunk, char[][] lighting) {
|
||||||
|
chunk.chunkExisting.setLightingToGet(lighting);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSkyLightingToGet(ChunkHolder chunk, char[][] lighting) {
|
||||||
|
chunk.chunkExisting.setSkyLightingToGet(lighting);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeightmapToGet(ChunkHolder chunk, HeightMapType type, int[] data) {
|
||||||
|
chunk.chunkExisting.setHeightmapToGet(type, data);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final IBlockDelegate SET = new IBlockDelegate() {
|
private static final IBlockDelegate SET = new IBlockDelegate() {
|
||||||
@ -421,7 +482,9 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeSectionLighting(ChunkHolder chunk, int layer, boolean sky) {
|
public void removeSectionLighting(ChunkHolder chunk, int layer, boolean sky) {
|
||||||
chunk.chunkSet.removeSectionLighting(layer, sky);
|
chunk.getOrCreateGet();
|
||||||
|
chunk.delegate = BOTH;
|
||||||
|
chunk.removeSectionLighting(layer, sky);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -524,6 +587,39 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
chunk.chunkExisting.trim(false);
|
chunk.chunkExisting.trim(false);
|
||||||
return chunk.getHeightMap(type);
|
return chunk.getHeightMap(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flushLightToGet(ChunkHolder chunk, boolean heightmaps) {
|
||||||
|
chunk.getOrCreateGet();
|
||||||
|
chunk.delegate = BOTH;
|
||||||
|
chunk.chunkExisting.trim(false);
|
||||||
|
chunk.chunkExisting.setLightingToGet(chunk.chunkSet.getLight());
|
||||||
|
chunk.chunkExisting.setSkyLightingToGet(chunk.chunkSet.getSkyLight());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLightingToGet(ChunkHolder chunk, char[][] lighting) {
|
||||||
|
chunk.getOrCreateGet();
|
||||||
|
chunk.delegate = BOTH;
|
||||||
|
chunk.chunkExisting.trim(false);
|
||||||
|
chunk.chunkExisting.setLightingToGet(lighting);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSkyLightingToGet(ChunkHolder chunk, char[][] lighting) {
|
||||||
|
chunk.getOrCreateGet();
|
||||||
|
chunk.delegate = BOTH;
|
||||||
|
chunk.chunkExisting.trim(false);
|
||||||
|
chunk.chunkExisting.setSkyLightingToGet(lighting);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeightmapToGet(ChunkHolder chunk, HeightMapType type, int[] data) {
|
||||||
|
chunk.getOrCreateGet();
|
||||||
|
chunk.delegate = BOTH;
|
||||||
|
chunk.chunkExisting.trim(false);
|
||||||
|
chunk.chunkExisting.setHeightmapToGet(type, data);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final IBlockDelegate NULL = new IBlockDelegate() {
|
private static final IBlockDelegate NULL = new IBlockDelegate() {
|
||||||
@ -597,8 +693,9 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeSectionLighting(ChunkHolder chunk, int layer, boolean sky) {
|
public void removeSectionLighting(ChunkHolder chunk, int layer, boolean sky) {
|
||||||
|
chunk.getOrCreateGet();
|
||||||
chunk.getOrCreateSet();
|
chunk.getOrCreateSet();
|
||||||
chunk.delegate = SET;
|
chunk.delegate = BOTH;
|
||||||
chunk.removeSectionLighting(layer, sky);
|
chunk.removeSectionLighting(layer, sky);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -667,6 +764,35 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
chunk.chunkExisting.trim(false);
|
chunk.chunkExisting.trim(false);
|
||||||
return chunk.getHeightMap(type);
|
return chunk.getHeightMap(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flushLightToGet(ChunkHolder chunk, boolean heightmaps) {
|
||||||
|
// Do nothing as no light to flush
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLightingToGet(ChunkHolder chunk, char[][] lighting) {
|
||||||
|
chunk.getOrCreateGet();
|
||||||
|
chunk.delegate = GET;
|
||||||
|
chunk.chunkExisting.trim(false);
|
||||||
|
chunk.setLightingToGet(lighting);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSkyLightingToGet(ChunkHolder chunk, char[][] lighting) {
|
||||||
|
chunk.getOrCreateGet();
|
||||||
|
chunk.delegate = GET;
|
||||||
|
chunk.chunkExisting.trim(false);
|
||||||
|
chunk.setSkyLightingToGet(lighting);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeightmapToGet(ChunkHolder chunk, HeightMapType type, int[] data) {
|
||||||
|
chunk.getOrCreateGet();
|
||||||
|
chunk.delegate = GET;
|
||||||
|
chunk.chunkExisting.trim(false);
|
||||||
|
chunk.setHeightmapToGet(type, data);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -947,5 +1073,13 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
int getOpacity(ChunkHolder chunk, int x, int y, int z);
|
int getOpacity(ChunkHolder chunk, int x, int y, int z);
|
||||||
|
|
||||||
int[] getHeightMap(ChunkHolder chunk, HeightMapType type);
|
int[] getHeightMap(ChunkHolder chunk, HeightMapType type);
|
||||||
|
|
||||||
|
void flushLightToGet(ChunkHolder chunk, boolean heightmaps);
|
||||||
|
|
||||||
|
void setLightingToGet(ChunkHolder chunk, char[][] lighting);
|
||||||
|
|
||||||
|
void setSkyLightingToGet(ChunkHolder chunk, char[][] lighting);
|
||||||
|
|
||||||
|
void setHeightmapToGet(ChunkHolder chunk, HeightMapType type, int[] data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,6 +177,15 @@ public final class NullChunk implements IQueueChunk {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLightingToGet(char[][] lighting) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSkyLightingToGet(char[][] lighting) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeightmapToGet(HeightMapType type, int[] data) {}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public <T extends Future<T>> T call(@Nullable IChunkSet set, @Nullable Runnable finalize) {
|
public <T extends Future<T>> T call(@Nullable IChunkSet set, @Nullable Runnable finalize) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package com.boydti.fawe.beta.implementation.lighting;
|
package com.boydti.fawe.beta.implementation.lighting;
|
||||||
|
|
||||||
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.beta.IQueueChunk;
|
import com.boydti.fawe.beta.IQueueChunk;
|
||||||
import com.boydti.fawe.beta.IQueueExtent;
|
import com.boydti.fawe.beta.IQueueExtent;
|
||||||
import com.boydti.fawe.beta.implementation.chunk.ChunkHolder;
|
import com.boydti.fawe.beta.implementation.chunk.ChunkHolder;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
|
import com.boydti.fawe.object.RelightMode;
|
||||||
import com.boydti.fawe.object.RunnableVal;
|
import com.boydti.fawe.object.RunnableVal;
|
||||||
import com.boydti.fawe.object.collection.BlockVectorSet;
|
import com.boydti.fawe.object.collection.BlockVectorSet;
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
@ -34,6 +36,7 @@ import java.util.Queue;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class NMSRelighter implements Relighter {
|
public class NMSRelighter implements Relighter {
|
||||||
@ -64,11 +67,17 @@ public class NMSRelighter implements Relighter {
|
|||||||
private final Map<Long, long[][][] /* z y x */> lightQueue;
|
private final Map<Long, long[][][] /* z y x */> lightQueue;
|
||||||
private final AtomicBoolean lightLock = new AtomicBoolean(false);
|
private final AtomicBoolean lightLock = new AtomicBoolean(false);
|
||||||
private final ConcurrentHashMap<Long, long[][][]> concurrentLightQueue;
|
private final ConcurrentHashMap<Long, long[][][]> concurrentLightQueue;
|
||||||
|
private final RelightMode relightMode;
|
||||||
private final int maxY;
|
private final int maxY;
|
||||||
private final boolean calculateHeightMaps;
|
private final boolean calculateHeightMaps;
|
||||||
|
private final ReentrantLock lightingLock;
|
||||||
private boolean removeFirst;
|
private boolean removeFirst;
|
||||||
|
|
||||||
public NMSRelighter(IQueueExtent<IQueueChunk> queue, boolean calculateHeightMaps) {
|
public NMSRelighter(IQueueExtent<IQueueChunk> queue, boolean calculateHeightMaps) {
|
||||||
|
this(queue, calculateHeightMaps, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NMSRelighter(IQueueExtent<IQueueChunk> queue, boolean calculateHeightMaps, RelightMode relightMode) {
|
||||||
this.queue = queue;
|
this.queue = queue;
|
||||||
this.skyToRelight = new Long2ObjectOpenHashMap<>(12);
|
this.skyToRelight = new Long2ObjectOpenHashMap<>(12);
|
||||||
this.lightQueue = new Long2ObjectOpenHashMap<>(12);
|
this.lightQueue = new Long2ObjectOpenHashMap<>(12);
|
||||||
@ -77,12 +86,19 @@ public class NMSRelighter implements Relighter {
|
|||||||
this.heightMaps = new Long2ObjectOpenHashMap<>(12);
|
this.heightMaps = new Long2ObjectOpenHashMap<>(12);
|
||||||
this.maxY = queue.getMaxY();
|
this.maxY = queue.getMaxY();
|
||||||
this.calculateHeightMaps = calculateHeightMaps;
|
this.calculateHeightMaps = calculateHeightMaps;
|
||||||
|
this.relightMode = relightMode != null ? relightMode : RelightMode.valueOf(Settings.IMP.LIGHTING.MODE);
|
||||||
|
this.lightingLock = new ReentrantLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean isEmpty() {
|
@Override public boolean isEmpty() {
|
||||||
return skyToRelight.isEmpty() && lightQueue.isEmpty() && extentdSkyToRelight.isEmpty() && concurrentLightQueue.isEmpty();
|
return skyToRelight.isEmpty() && lightQueue.isEmpty() && extentdSkyToRelight.isEmpty() && concurrentLightQueue.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized ReentrantLock getLock() {
|
||||||
|
return lightingLock;
|
||||||
|
}
|
||||||
|
|
||||||
@Override public synchronized void removeAndRelight(boolean sky) {
|
@Override public synchronized void removeAndRelight(boolean sky) {
|
||||||
removeFirst = true;
|
removeFirst = true;
|
||||||
fixLightingSafe(sky);
|
fixLightingSafe(sky);
|
||||||
@ -778,6 +794,7 @@ public class NMSRelighter implements Relighter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fixBlockLighting();
|
fixBlockLighting();
|
||||||
|
sendChunks();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -786,7 +803,11 @@ public class NMSRelighter implements Relighter {
|
|||||||
public void fixBlockLighting() {
|
public void fixBlockLighting() {
|
||||||
synchronized (lightQueue) {
|
synchronized (lightQueue) {
|
||||||
while (!lightLock.compareAndSet(false, true)) {
|
while (!lightLock.compareAndSet(false, true)) {
|
||||||
;
|
try {
|
||||||
|
lightLock.wait(50);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
updateBlockLight(this.lightQueue);
|
updateBlockLight(this.lightQueue);
|
||||||
@ -796,7 +817,7 @@ public class NMSRelighter implements Relighter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void sendChunks() {
|
public synchronized void flush() {
|
||||||
Iterator<Map.Entry<Long, Integer>> iter = chunksToSend.entrySet().iterator();
|
Iterator<Map.Entry<Long, Integer>> iter = chunksToSend.entrySet().iterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Map.Entry<Long, Integer> entry = iter.next();
|
Map.Entry<Long, Integer> entry = iter.next();
|
||||||
@ -827,6 +848,40 @@ public class NMSRelighter implements Relighter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized void sendChunks() {
|
||||||
|
RunnableVal<Object> runnable = new RunnableVal<Object>() {
|
||||||
|
@Override
|
||||||
|
public void run(Object value) {
|
||||||
|
Iterator<Map.Entry<Long, Integer>> iter = chunksToSend.entrySet().iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
Map.Entry<Long, Integer> entry = iter.next();
|
||||||
|
long pair = entry.getKey();
|
||||||
|
int bitMask = entry.getValue();
|
||||||
|
int x = MathMan.unpairIntX(pair);
|
||||||
|
int z = MathMan.unpairIntY(pair);
|
||||||
|
ChunkHolder<?> chunk = (ChunkHolder<?>) queue.getOrCreateChunk(x, z);
|
||||||
|
chunk.setBitMask(bitMask);
|
||||||
|
if (calculateHeightMaps && heightMaps != null) {
|
||||||
|
Map<HeightMapType, int[]> heightMapList = heightMaps.get(pair);
|
||||||
|
if (heightMapList != null) {
|
||||||
|
for (Map.Entry<HeightMapType, int[]> heightMapEntry : heightMapList.entrySet()) {
|
||||||
|
chunk.setHeightMap(heightMapEntry.getKey(), heightMapEntry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chunk.flushLightToGet(true);
|
||||||
|
Fawe.imp().getPlatformAdapter().sendChunk(chunk.getOrCreateGet(), bitMask, true);
|
||||||
|
iter.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (Settings.IMP.LIGHTING.ASYNC) {
|
||||||
|
runnable.run();
|
||||||
|
} else {
|
||||||
|
TaskManager.IMP.sync(runnable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized void fixSkyLighting() {
|
public synchronized void fixSkyLighting() {
|
||||||
// Order chunks
|
// Order chunks
|
||||||
Map<Long, RelightSkyEntry> map = getSkyMap();
|
Map<Long, RelightSkyEntry> map = getSkyMap();
|
||||||
@ -913,7 +968,7 @@ public class NMSRelighter implements Relighter {
|
|||||||
for (RelightSkyEntry chunk : chunks) { // Propagate skylight
|
for (RelightSkyEntry chunk : chunks) { // Propagate skylight
|
||||||
int layer = y >> 4;
|
int layer = y >> 4;
|
||||||
byte[] mask = chunk.mask;
|
byte[] mask = chunk.mask;
|
||||||
if ((y & 15) == 15 && chunk.fix[layer] != SkipReason.NONE) {
|
if (chunk.fix[layer] != SkipReason.NONE) {
|
||||||
if ((y & 15) == 0 && layer != 0 && chunk.fix[layer - 1] == SkipReason.NONE) {
|
if ((y & 15) == 0 && layer != 0 && chunk.fix[layer - 1] == SkipReason.NONE) {
|
||||||
fill(mask, chunk.x, y, chunk.z, chunk.fix[layer]);
|
fill(mask, chunk.x, y, chunk.z, chunk.fix[layer]);
|
||||||
}
|
}
|
||||||
@ -945,7 +1000,7 @@ public class NMSRelighter implements Relighter {
|
|||||||
BlockMaterial material = state.getMaterial();
|
BlockMaterial material = state.getMaterial();
|
||||||
int opacity = material.getLightOpacity();
|
int opacity = material.getLightOpacity();
|
||||||
int brightness = material.getLightValue();
|
int brightness = material.getLightValue();
|
||||||
if (brightness > 1) {
|
if (brightness != iChunk.getEmmittedLight(x, y, z)) {
|
||||||
addLightUpdate(bx + x, y, bz + z);
|
addLightUpdate(bx + x, y, bz + z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -957,25 +1012,26 @@ public class NMSRelighter implements Relighter {
|
|||||||
if (heightMapList.get(HeightMapType.OCEAN_FLOOR)[j] == 0 && material.isSolid()) {
|
if (heightMapList.get(HeightMapType.OCEAN_FLOOR)[j] == 0 && material.isSolid()) {
|
||||||
heightMapList.get(HeightMapType.OCEAN_FLOOR)[j] = y + 1;
|
heightMapList.get(HeightMapType.OCEAN_FLOOR)[j] = y + 1;
|
||||||
}
|
}
|
||||||
|
Map<Property<?>, Object> states = state.getStates();
|
||||||
try {
|
try {
|
||||||
if (heightMapList.get(HeightMapType.MOTION_BLOCKING)[j] == 0 && (material.isSolid() || material.isLiquid() || (
|
if (heightMapList.get(HeightMapType.MOTION_BLOCKING)[j] == 0 && (material.isSolid() || material.isLiquid() || (
|
||||||
state.getStates().containsKey(waterLogged) && state.getState(waterLogged)))) {
|
states.containsKey(waterLogged) && state.getState(waterLogged)))) {
|
||||||
heightMapList.get(HeightMapType.MOTION_BLOCKING)[j] = y + 1;
|
heightMapList.get(HeightMapType.MOTION_BLOCKING)[j] = y + 1;
|
||||||
}
|
}
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
log.debug("Error calculating waterlogged state for BlockState: " + state.getBlockType().getId() + ". States:");
|
log.debug("Error calculating waterlogged state for BlockState: " + state.getBlockType().getId() + ". States:");
|
||||||
log.debug(state.getStates().entrySet().stream().map(e -> e.getKey() + "=" + e.getValue())
|
log.debug(states.entrySet().stream().map(e -> e.getKey() + "=" + e.getValue())
|
||||||
.collect(Collectors.joining(", ", "{", "}")));
|
.collect(Collectors.joining(", ", "{", "}")));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (heightMapList.get(HeightMapType.MOTION_BLOCKING_NO_LEAVES)[j] == 0 && (material.isSolid() || material.isLiquid() || (
|
if (heightMapList.get(HeightMapType.MOTION_BLOCKING_NO_LEAVES)[j] == 0 && (material.isSolid() || material.isLiquid() || (
|
||||||
state.getStates().containsKey(waterLogged) && state.getState(waterLogged))) && !state.getBlockType().getId()
|
states.containsKey(waterLogged) && state.getState(waterLogged))) && !state.getBlockType().getId()
|
||||||
.toLowerCase().contains("leaves")) {
|
.toLowerCase().contains("leaves")) {
|
||||||
heightMapList.get(HeightMapType.MOTION_BLOCKING_NO_LEAVES)[j] = y + 1;
|
heightMapList.get(HeightMapType.MOTION_BLOCKING_NO_LEAVES)[j] = y + 1;
|
||||||
}
|
}
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
log.debug("Error calculating waterlogged state for BlockState: " + state.getBlockType().getId() + ". States:");
|
log.debug("Error calculating waterlogged state for BlockState: " + state.getBlockType().getId() + ". States:");
|
||||||
log.debug(state.getStates().entrySet().stream().map(e -> e.getKey() + "=" + e.getValue())
|
log.debug(states.entrySet().stream().map(e -> e.getKey() + "=" + e.getValue())
|
||||||
.collect(Collectors.joining(", ", "{", "}")));
|
.collect(Collectors.joining(", ", "{", "}")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package com.boydti.fawe.beta.implementation.lighting;
|
package com.boydti.fawe.beta.implementation.lighting;
|
||||||
|
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
public class NullRelighter implements Relighter {
|
public class NullRelighter implements Relighter {
|
||||||
|
|
||||||
public static NullRelighter INSTANCE = new NullRelighter();
|
public static NullRelighter INSTANCE = new NullRelighter();
|
||||||
@ -46,4 +48,9 @@ public class NullRelighter implements Relighter {
|
|||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ReentrantLock getLock() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.boydti.fawe.beta.implementation.lighting;
|
||||||
|
|
||||||
|
import com.boydti.fawe.beta.IBatchProcessor;
|
||||||
|
import com.boydti.fawe.beta.IChunk;
|
||||||
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
|
import com.boydti.fawe.beta.implementation.processors.ProcessorScope;
|
||||||
|
import com.boydti.fawe.config.Settings;
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
public class RelightProcessor implements IBatchProcessor {
|
||||||
|
|
||||||
|
private final Relighter relighter;
|
||||||
|
|
||||||
|
public RelightProcessor(Relighter relighter) {
|
||||||
|
if (relighter instanceof NullRelighter) {
|
||||||
|
throw new IllegalArgumentException("NullRelighter cannot be used for a RelightProcessor");
|
||||||
|
}
|
||||||
|
this.relighter = relighter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
|
if (Settings.IMP.LIGHTING.MODE == 2) {
|
||||||
|
relighter.addChunk(chunk.getX(), chunk.getZ(), null, chunk.getBitMask());
|
||||||
|
} else if (Settings.IMP.LIGHTING.MODE == 1) {
|
||||||
|
byte[] fix = new byte[16];
|
||||||
|
boolean relight = false;
|
||||||
|
for (int i = 15; i >= 0; i--) {
|
||||||
|
if (!set.hasSection(i)) {
|
||||||
|
fix[i] = Relighter.SkipReason.AIR;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
relight = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (relight) {
|
||||||
|
relighter.addChunk(chunk.getX(), chunk.getZ(), fix, chunk.getBitMask());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<IChunkSet> postProcessSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
|
return CompletableFuture.completedFuture(set);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Extent construct(Extent child) {
|
||||||
|
throw new UnsupportedOperationException("Processing only");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProcessorScope getScope() {
|
||||||
|
return ProcessorScope.READING_SET_BLOCKS;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package com.boydti.fawe.beta.implementation.lighting;
|
package com.boydti.fawe.beta.implementation.lighting;
|
||||||
|
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
public interface Relighter {
|
public interface Relighter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,6 +68,8 @@ public interface Relighter {
|
|||||||
*/
|
*/
|
||||||
boolean isEmpty();
|
boolean isEmpty();
|
||||||
|
|
||||||
|
ReentrantLock getLock();
|
||||||
|
|
||||||
class SkipReason {
|
class SkipReason {
|
||||||
public static final byte NONE = 0;
|
public static final byte NONE = 0;
|
||||||
public static final byte AIR = 1;
|
public static final byte AIR = 1;
|
||||||
|
@ -51,4 +51,9 @@ public class BatchProcessorHolder implements IBatchProcessorHolder {
|
|||||||
IBatchProcessor tmp = getProcessor();
|
IBatchProcessor tmp = getProcessor();
|
||||||
return super.toString() + "{" + (tmp == this ? "" : getProcessor()) + "}";
|
return super.toString() + "{" + (tmp == this ? "" : getProcessor()) + "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProcessorScope getScope() {
|
||||||
|
return getProcessor().getScope();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,4 +81,9 @@ public class ChunkSendProcessor implements IBatchProcessor {
|
|||||||
public Extent construct(Extent child) {
|
public Extent construct(Extent child) {
|
||||||
throw new UnsupportedOperationException("Processing only");
|
throw new UnsupportedOperationException("Processing only");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProcessorScope getScope() {
|
||||||
|
return ProcessorScope.READING_SET_BLOCKS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,4 +49,9 @@ public final class EmptyBatchProcessor implements IBatchProcessor {
|
|||||||
private EmptyBatchProcessor() {
|
private EmptyBatchProcessor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProcessorScope getScope() {
|
||||||
|
return ProcessorScope.ADDING_BLOCKS;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,21 +9,30 @@ import com.boydti.fawe.beta.IChunkSet;
|
|||||||
import com.boydti.fawe.util.StringMan;
|
import com.boydti.fawe.util.StringMan;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class MultiBatchProcessor implements IBatchProcessor {
|
public class MultiBatchProcessor implements IBatchProcessor {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(MultiBatchProcessor.class);
|
||||||
|
|
||||||
private IBatchProcessor[] processors;
|
private IBatchProcessor[] processors;
|
||||||
private final LoadingCache<Class<?>, Map<Long, Filter>> classToThreadIdToFilter =
|
private final LoadingCache<Class<?>, Map<Long, Filter>> classToThreadIdToFilter =
|
||||||
FaweCache.IMP.createCache((Supplier<Map<Long, Filter>>) ConcurrentHashMap::new);
|
FaweCache.IMP.createCache((Supplier<Map<Long, Filter>>) ConcurrentHashMap::new);
|
||||||
|
|
||||||
public MultiBatchProcessor(IBatchProcessor... processors) {
|
public MultiBatchProcessor(IBatchProcessor... processors) {
|
||||||
this.processors = processors;
|
this.processors = processors;
|
||||||
}
|
}
|
||||||
@ -65,18 +74,31 @@ public class MultiBatchProcessor implements IBatchProcessor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
|
Map<Integer, Set<IBatchProcessor>> ordered = new HashMap<>();
|
||||||
try {
|
try {
|
||||||
IChunkSet chunkSet = set;
|
IChunkSet chunkSet = set;
|
||||||
for (int i = processors.length - 1; i >= 0; i--) {
|
for (IBatchProcessor processor : processors) {
|
||||||
IBatchProcessor processor = processors[i];
|
if (processor.getScope() != ProcessorScope.ADDING_BLOCKS) {
|
||||||
if (processor instanceof Filter) {
|
ordered.merge(processor.getScope().intValue(), new HashSet<>(Collections.singleton(processor)), (existing, theNew) -> {
|
||||||
chunkSet = ((IBatchProcessor) classToThreadIdToFilter.getUnchecked(processor.getClass())
|
existing.add(processor);
|
||||||
.computeIfAbsent(Thread.currentThread().getId(), k -> ((Filter) processor).fork())).processSet(chunk, get, chunkSet);
|
return existing;
|
||||||
} else {
|
});
|
||||||
chunkSet = processor.processSet(chunk, get, chunkSet);
|
continue;
|
||||||
}
|
}
|
||||||
if (chunkSet == null) {
|
chunkSet = processSet(processor, chunk, get, chunkSet);
|
||||||
return null;
|
}
|
||||||
|
if (ordered.size() > 0) {
|
||||||
|
for (int i = 1; i <= 4; i++) {
|
||||||
|
Set<IBatchProcessor> processors = ordered.get(i);
|
||||||
|
if (processors == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (IBatchProcessor processor : processors) {
|
||||||
|
chunkSet = processSet(processor,chunk, get, chunkSet);
|
||||||
|
if (chunkSet == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return chunkSet;
|
return chunkSet;
|
||||||
@ -86,11 +108,25 @@ public class MultiBatchProcessor implements IBatchProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private IChunkSet processSet(IBatchProcessor processor, IChunk chunk, IChunkGet get, IChunkSet chunkSet) {
|
||||||
|
if (processor instanceof Filter) {
|
||||||
|
chunkSet = ((IBatchProcessor) classToThreadIdToFilter.getUnchecked(processor.getClass())
|
||||||
|
.computeIfAbsent(Thread.currentThread().getId(), k -> ((Filter) processor).fork())).processSet(chunk, get, chunkSet);
|
||||||
|
} else {
|
||||||
|
chunkSet = processor.processSet(chunk, get, chunkSet);
|
||||||
|
}
|
||||||
|
return chunkSet;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Future<IChunkSet> postProcessSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
public Future<IChunkSet> postProcessSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
try {
|
try {
|
||||||
for (int i = processors.length - 1 ; i >= 0; i--) {
|
for (IBatchProcessor processor : processors) {
|
||||||
IBatchProcessor processor = processors[i];
|
// We do NOT want to edit blocks in post processing
|
||||||
|
if (processor.getScope() != ProcessorScope.READING_SET_BLOCKS) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
set = processor.postProcessSet(chunk, get, set).get();
|
set = processor.postProcessSet(chunk, get, set).get();
|
||||||
if (set == null) {
|
if (set == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -163,4 +199,13 @@ public class MultiBatchProcessor implements IBatchProcessor {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return super.toString() + "{" + StringMan.join(processors, ",") + "}";
|
return super.toString() + "{" + StringMan.join(processors, ",") + "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProcessorScope getScope() {
|
||||||
|
int scope = 0;
|
||||||
|
for (IBatchProcessor processor : processors) {
|
||||||
|
scope = Math.max(scope, processor.getScope().intValue());
|
||||||
|
}
|
||||||
|
return ProcessorScope.valueOf(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,4 +36,9 @@ public final class NullProcessor implements IBatchProcessor {
|
|||||||
private NullProcessor() {
|
private NullProcessor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProcessorScope getScope() {
|
||||||
|
return ProcessorScope.ADDING_BLOCKS;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.boydti.fawe.beta.implementation.processors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The scope of a processor.
|
||||||
|
* Order in which processors are executed:
|
||||||
|
* - ADDING_BLOCKS (processors that strictly ADD blocks to an edit ONLY)
|
||||||
|
* - CHANGING_BLOCKS (processors that strictly ADD or CHANGE blocks being set)
|
||||||
|
* - REMOVING_BLOCKS (processors that string ADD, CHANGE or REMOVE blocks being set)
|
||||||
|
* - CUSTOM (processors that do not specify a SCOPE)
|
||||||
|
* - READING_SET_BLOCKS (processors that do not alter blocks at all, and read the blocks that are actually going to set, e.g. history processors)
|
||||||
|
*/
|
||||||
|
public enum ProcessorScope {
|
||||||
|
ADDING_BLOCKS(0), CHANGING_BLOCKS(1), REMOVING_BLOCKS(2), CUSTOM(3), READING_SET_BLOCKS(4);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
ProcessorScope(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int intValue() {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ProcessorScope valueOf(int value) {
|
||||||
|
switch (value) {
|
||||||
|
case 0:
|
||||||
|
return ProcessorScope.ADDING_BLOCKS;
|
||||||
|
case 1:
|
||||||
|
return ProcessorScope.CHANGING_BLOCKS;
|
||||||
|
case 2:
|
||||||
|
return ProcessorScope.REMOVING_BLOCKS;
|
||||||
|
case 4:
|
||||||
|
return ProcessorScope.READING_SET_BLOCKS;
|
||||||
|
case 3:
|
||||||
|
default:
|
||||||
|
return ProcessorScope.CUSTOM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,7 @@ import com.boydti.fawe.beta.implementation.filter.block.CharFilterBlock;
|
|||||||
import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock;
|
import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock;
|
||||||
import com.boydti.fawe.beta.implementation.processors.EmptyBatchProcessor;
|
import com.boydti.fawe.beta.implementation.processors.EmptyBatchProcessor;
|
||||||
import com.boydti.fawe.beta.implementation.processors.ExtentBatchProcessorHolder;
|
import com.boydti.fawe.beta.implementation.processors.ExtentBatchProcessorHolder;
|
||||||
|
import com.boydti.fawe.beta.implementation.processors.ProcessorScope;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
import com.boydti.fawe.util.MemUtil;
|
import com.boydti.fawe.util.MemUtil;
|
||||||
@ -352,4 +353,9 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen
|
|||||||
public ChunkFilterBlock initFilterBlock() {
|
public ChunkFilterBlock initFilterBlock() {
|
||||||
return new CharFilterBlock(this);
|
return new CharFilterBlock(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProcessorScope getScope() {
|
||||||
|
return ProcessorScope.ADDING_BLOCKS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -623,6 +623,15 @@ public class MCAChunk implements IChunk {
|
|||||||
return createCopy;
|
return createCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLightingToGet(char[][] lighting) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSkyLightingToGet(char[][] lighting) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeightmapToGet(HeightMapType type, int[] data) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Future call(IChunkSet set, Runnable finalize) {
|
public Future call(IChunkSet set, Runnable finalize) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -6,6 +6,7 @@ import com.boydti.fawe.beta.IBatchProcessor;
|
|||||||
import com.boydti.fawe.beta.IChunk;
|
import com.boydti.fawe.beta.IChunk;
|
||||||
import com.boydti.fawe.beta.IChunkGet;
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
import com.boydti.fawe.beta.IChunkSet;
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
|
import com.boydti.fawe.beta.implementation.processors.ProcessorScope;
|
||||||
import com.boydti.fawe.object.HistoryExtent;
|
import com.boydti.fawe.object.HistoryExtent;
|
||||||
import com.boydti.fawe.util.EditSessionBuilder;
|
import com.boydti.fawe.util.EditSessionBuilder;
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
@ -212,6 +213,11 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
|
|||||||
return (Future<IChunkSet>) addWriteTask(() -> processSet(chunk, get, set));
|
return (Future<IChunkSet>) addWriteTask(() -> processSet(chunk, get, set));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProcessorScope getScope() {
|
||||||
|
return ProcessorScope.READING_SET_BLOCKS;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract void addTileCreate(CompoundTag tag);
|
public abstract void addTileCreate(CompoundTag tag);
|
||||||
|
|
||||||
public abstract void addTileRemove(CompoundTag tag);
|
public abstract void addTileRemove(CompoundTag tag);
|
||||||
|
@ -2,6 +2,7 @@ package com.boydti.fawe.object.extent;
|
|||||||
|
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.beta.IBatchProcessor;
|
import com.boydti.fawe.beta.IBatchProcessor;
|
||||||
|
import com.boydti.fawe.beta.implementation.processors.ProcessorScope;
|
||||||
import com.boydti.fawe.object.FaweLimit;
|
import com.boydti.fawe.object.FaweLimit;
|
||||||
import com.boydti.fawe.util.ExtentTraverser;
|
import com.boydti.fawe.util.ExtentTraverser;
|
||||||
import com.boydti.fawe.util.WEManager;
|
import com.boydti.fawe.util.WEManager;
|
||||||
@ -147,4 +148,9 @@ public abstract class FaweRegionExtent extends ResettableExtent implements IBatc
|
|||||||
}
|
}
|
||||||
return super.createEntity(location, entity);
|
return super.createEntity(location, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProcessorScope getScope() {
|
||||||
|
return ProcessorScope.READING_SET_BLOCKS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import com.boydti.fawe.beta.IBatchProcessor;
|
|||||||
import com.boydti.fawe.beta.IChunk;
|
import com.boydti.fawe.beta.IChunk;
|
||||||
import com.boydti.fawe.beta.IChunkGet;
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
import com.boydti.fawe.beta.IChunkSet;
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
|
import com.boydti.fawe.beta.implementation.processors.ProcessorScope;
|
||||||
import com.boydti.fawe.object.FaweLimit;
|
import com.boydti.fawe.object.FaweLimit;
|
||||||
import com.boydti.fawe.object.exception.FaweException;
|
import com.boydti.fawe.object.exception.FaweException;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
@ -355,4 +356,9 @@ public class NullExtent extends FaweRegionExtent implements IBatchProcessor {
|
|||||||
public Extent construct(Extent child) {
|
public Extent construct(Extent child) {
|
||||||
throw reason;
|
throw reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProcessorScope getScope() {
|
||||||
|
return ProcessorScope.ADDING_BLOCKS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.boydti.fawe.regions;
|
package com.boydti.fawe.regions;
|
||||||
|
|
||||||
|
import com.boydti.fawe.beta.implementation.processors.ProcessorScope;
|
||||||
import com.sk89q.worldedit.entity.Player;
|
import com.sk89q.worldedit.entity.Player;
|
||||||
import com.sk89q.worldedit.regions.IDelegateRegion;
|
import com.sk89q.worldedit.regions.IDelegateRegion;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
@ -24,4 +25,9 @@ public class FaweMask implements IDelegateRegion {
|
|||||||
public Region clone() {
|
public Region clone() {
|
||||||
throw new UnsupportedOperationException("Clone not supported");
|
throw new UnsupportedOperationException("Clone not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProcessorScope getScope() {
|
||||||
|
return ProcessorScope.REMOVING_BLOCKS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,10 @@ import com.boydti.fawe.Fawe;
|
|||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.beta.IQueueChunk;
|
import com.boydti.fawe.beta.IQueueChunk;
|
||||||
import com.boydti.fawe.beta.IQueueExtent;
|
import com.boydti.fawe.beta.IQueueExtent;
|
||||||
|
import com.boydti.fawe.beta.implementation.lighting.NMSRelighter;
|
||||||
|
import com.boydti.fawe.beta.implementation.lighting.NullRelighter;
|
||||||
|
import com.boydti.fawe.beta.implementation.lighting.RelightProcessor;
|
||||||
|
import com.boydti.fawe.beta.implementation.lighting.Relighter;
|
||||||
import com.boydti.fawe.beta.implementation.processors.LimitExtent;
|
import com.boydti.fawe.beta.implementation.processors.LimitExtent;
|
||||||
import com.boydti.fawe.beta.implementation.queue.ParallelQueueExtent;
|
import com.boydti.fawe.beta.implementation.queue.ParallelQueueExtent;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
@ -67,6 +71,7 @@ public class EditSessionBuilder {
|
|||||||
private EditSessionEvent event;
|
private EditSessionEvent event;
|
||||||
private String command;
|
private String command;
|
||||||
private RelightMode relightMode;
|
private RelightMode relightMode;
|
||||||
|
private Relighter relighter;
|
||||||
private Boolean wnaMode;
|
private Boolean wnaMode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -396,6 +401,14 @@ public class EditSessionBuilder {
|
|||||||
allowedRegions = new Region[]{RegionWrapper.GLOBAL()};
|
allowedRegions = new Region[]{RegionWrapper.GLOBAL()};
|
||||||
// this.extent = new HeightBoundExtent(this.extent, this.limit, 0, world.getMaxY());
|
// this.extent = new HeightBoundExtent(this.extent, this.limit, 0, world.getMaxY());
|
||||||
}
|
}
|
||||||
|
// There's no need to do lighting (and it'll also just be a pain to implement) if we're not placing chunks
|
||||||
|
if (placeChunks && ((relightMode != null && relightMode != RelightMode.NONE) || (relightMode == null && Settings.IMP.LIGHTING.MODE > 0))) {
|
||||||
|
relighter = new NMSRelighter(queue, Settings.IMP.LIGHTING.DO_HEIGHTMAPS,
|
||||||
|
relightMode != null ? relightMode : RelightMode.valueOf(Settings.IMP.LIGHTING.MODE));
|
||||||
|
extent.addProcessor(new RelightProcessor(relighter));
|
||||||
|
} else {
|
||||||
|
relighter = NullRelighter.INSTANCE;
|
||||||
|
}
|
||||||
if (limit != null && !limit.isUnlimited() && regionExtent != null) {
|
if (limit != null && !limit.isUnlimited() && regionExtent != null) {
|
||||||
this.extent = new LimitExtent(regionExtent, limit);
|
this.extent = new LimitExtent(regionExtent, limit);
|
||||||
} else if (limit != null && !limit.isUnlimited()) {
|
} else if (limit != null && !limit.isUnlimited()) {
|
||||||
@ -454,6 +467,10 @@ public class EditSessionBuilder {
|
|||||||
return blockBag;
|
return blockBag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Relighter getRelighter() {
|
||||||
|
return relighter;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isWNAMode() {
|
public boolean isWNAMode() {
|
||||||
return wnaMode;
|
return wnaMode;
|
||||||
}
|
}
|
||||||
@ -462,5 +479,4 @@ public class EditSessionBuilder {
|
|||||||
public Region[] getAllowedRegions() {
|
public Region[] getAllowedRegions() {
|
||||||
return allowedRegions;
|
return allowedRegions;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
package com.sk89q.worldedit;
|
package com.sk89q.worldedit;
|
||||||
|
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
|
import com.boydti.fawe.beta.implementation.lighting.NullRelighter;
|
||||||
|
import com.boydti.fawe.beta.implementation.lighting.Relighter;
|
||||||
import com.boydti.fawe.config.Caption;
|
import com.boydti.fawe.config.Caption;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.FaweLimit;
|
import com.boydti.fawe.object.FaweLimit;
|
||||||
@ -224,12 +226,12 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
|||||||
private final int maxY;
|
private final int maxY;
|
||||||
private final List<WatchdogTickingExtent> watchdogExtents = new ArrayList<>(2);
|
private final List<WatchdogTickingExtent> watchdogExtents = new ArrayList<>(2);
|
||||||
|
|
||||||
|
private final Relighter relighter;
|
||||||
private final boolean wnaMode;
|
private final boolean wnaMode;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final Region[] allowedRegions;
|
private final Region[] allowedRegions;
|
||||||
|
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public EditSession(@NotNull EventBus bus, World world, @Nullable Player player,
|
public EditSession(@NotNull EventBus bus, World world, @Nullable Player player,
|
||||||
@Nullable FaweLimit limit, @Nullable AbstractChangeSet changeSet,
|
@Nullable FaweLimit limit, @Nullable AbstractChangeSet changeSet,
|
||||||
@ -264,6 +266,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
|||||||
this.maxY = world.getMaxY();
|
this.maxY = world.getMaxY();
|
||||||
this.blockBag = builder.getBlockBag();
|
this.blockBag = builder.getBlockBag();
|
||||||
this.history = changeSet != null;
|
this.history = changeSet != null;
|
||||||
|
this.relighter = builder.getRelighter();
|
||||||
this.wnaMode = builder.isWNAMode();
|
this.wnaMode = builder.isWNAMode();
|
||||||
this.allowedRegions = builder.getAllowedRegions() != null ? builder.getAllowedRegions().clone() : null;
|
this.allowedRegions = builder.getAllowedRegions() != null ? builder.getAllowedRegions().clone() : null;
|
||||||
}
|
}
|
||||||
@ -1093,6 +1096,25 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
|||||||
}
|
}
|
||||||
// Reset limit
|
// Reset limit
|
||||||
limit.set(originalLimit);
|
limit.set(originalLimit);
|
||||||
|
try {
|
||||||
|
if (relighter != null && !(relighter instanceof NullRelighter)) {
|
||||||
|
// Only relight once!
|
||||||
|
if (!relighter.getLock().tryLock()) {
|
||||||
|
relighter.getLock().lock();
|
||||||
|
relighter.getLock().unlock();
|
||||||
|
} else {
|
||||||
|
if (Settings.IMP.LIGHTING.REMOVE_FIRST) {
|
||||||
|
relighter.removeAndRelight(true);
|
||||||
|
} else {
|
||||||
|
relighter.fixSkyLighting();
|
||||||
|
relighter.fixBlockLighting();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
player.printError(TranslatableComponent.of("fawe.error.lighting"));
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
// Enqueue it
|
// Enqueue it
|
||||||
if (getChangeSet() != null) {
|
if (getChangeSet() != null) {
|
||||||
if (Settings.IMP.HISTORY.COMBINE_STAGES) {
|
if (Settings.IMP.HISTORY.COMBINE_STAGES) {
|
||||||
|
@ -23,6 +23,7 @@ import com.boydti.fawe.FaweCache;
|
|||||||
import com.boydti.fawe.beta.Filter;
|
import com.boydti.fawe.beta.Filter;
|
||||||
import com.boydti.fawe.beta.IBatchProcessor;
|
import com.boydti.fawe.beta.IBatchProcessor;
|
||||||
import com.boydti.fawe.beta.implementation.filter.block.ExtentFilterBlock;
|
import com.boydti.fawe.beta.implementation.filter.block.ExtentFilterBlock;
|
||||||
|
import com.boydti.fawe.beta.implementation.processors.ProcessorScope;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.changeset.AbstractChangeSet;
|
import com.boydti.fawe.object.changeset.AbstractChangeSet;
|
||||||
import com.boydti.fawe.object.clipboard.WorldCopyClipboard;
|
import com.boydti.fawe.object.clipboard.WorldCopyClipboard;
|
||||||
@ -707,6 +708,9 @@ public interface Extent extends InputExtent, OutputExtent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
default Extent addPostProcessor(IBatchProcessor processor) {
|
default Extent addPostProcessor(IBatchProcessor processor) {
|
||||||
|
if (processor.getScope() == ProcessorScope.READING_SET_BLOCKS) {
|
||||||
|
throw new IllegalArgumentException("You cannot alter blocks in a PostProcessor");
|
||||||
|
}
|
||||||
return processor.construct(this);
|
return processor.construct(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ import com.boydti.fawe.beta.IChunkSet;
|
|||||||
import com.boydti.fawe.beta.implementation.filter.block.CharFilterBlock;
|
import com.boydti.fawe.beta.implementation.filter.block.CharFilterBlock;
|
||||||
import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock;
|
import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock;
|
||||||
import com.boydti.fawe.beta.implementation.filter.block.FilterBlock;
|
import com.boydti.fawe.beta.implementation.filter.block.FilterBlock;
|
||||||
|
import com.boydti.fawe.beta.implementation.processors.ProcessorScope;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
@ -128,4 +129,9 @@ public class MaskingExtent extends AbstractDelegateExtent implements IBatchProce
|
|||||||
public Filter fork() {
|
public Filter fork() {
|
||||||
return new MaskingExtent(getExtent(), this.mask.copy(), this.threadIdToFilter);
|
return new MaskingExtent(getExtent(), this.mask.copy(), this.threadIdToFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProcessorScope getScope() {
|
||||||
|
return ProcessorScope.REMOVING_BLOCKS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ import com.boydti.fawe.beta.IChunk;
|
|||||||
import com.boydti.fawe.beta.IChunkGet;
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
import com.boydti.fawe.beta.IChunkSet;
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock;
|
import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock;
|
||||||
|
import com.boydti.fawe.beta.implementation.processors.ProcessorScope;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.collection.BlockVectorSet;
|
import com.boydti.fawe.object.collection.BlockVectorSet;
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
@ -774,5 +775,4 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ import com.boydti.fawe.beta.IChunk;
|
|||||||
import com.boydti.fawe.beta.IChunkGet;
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
import com.boydti.fawe.beta.IChunkSet;
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock;
|
import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock;
|
||||||
|
import com.boydti.fawe.beta.implementation.processors.ProcessorScope;
|
||||||
import com.boydti.fawe.object.FaweLimit;
|
import com.boydti.fawe.object.FaweLimit;
|
||||||
import com.boydti.fawe.object.extent.SingleRegionExtent;
|
import com.boydti.fawe.object.extent.SingleRegionExtent;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
@ -365,4 +366,9 @@ public interface Region extends Iterable<BlockVector3>, Cloneable, IBatchProcess
|
|||||||
}
|
}
|
||||||
return new SingleRegionExtent(child, FaweLimit.MAX, this);
|
return new SingleRegionExtent(child, FaweLimit.MAX, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default ProcessorScope getScope() {
|
||||||
|
return ProcessorScope.REMOVING_BLOCKS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,6 +104,7 @@
|
|||||||
"fawe.error.worldedit.some.fails.blockbag": "Missing blocks: {0}",
|
"fawe.error.worldedit.some.fails.blockbag": "Missing blocks: {0}",
|
||||||
"fawe.error.mask.angle": "Cannot combine degree with block-step",
|
"fawe.error.mask.angle": "Cannot combine degree with block-step",
|
||||||
"fawe.error.invalid-flag": "The flag {0} is not applicable here",
|
"fawe.error.invalid-flag": "The flag {0} is not applicable here",
|
||||||
|
"fawe.error.lighting": "Error when attempting lighting. You may need to reload the chunks to see the edit.",
|
||||||
|
|
||||||
"fawe.cancel.worldedit.cancel.count": "Cancelled {0} edits.",
|
"fawe.cancel.worldedit.cancel.count": "Cancelled {0} edits.",
|
||||||
"fawe.cancel.worldedit.cancel.reason.confirm": "Use //confirm to execute {2}",
|
"fawe.cancel.worldedit.cancel.reason.confirm": "Use //confirm to execute {2}",
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren