mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-06-11 20:13:55 +00:00
Fix relight and removelight (#475)
* Start work on lighting engine (does not build) * Implement getLighting * Setting, flushing light etc works. Getting light should be working..? * Better queue/chunk handling * Use correct location for lighting update * Correct set location, remove debug * cleanup a little * Fix fixlight * Apply to all versions for the numpties * Remove lighting extent if not using * Actually bitmask blocks when setting in chunks * Initialise Maps and Dequeues with inital size * format * Documentation maybe
This commit is contained in:
@ -30,6 +30,7 @@ import net.minecraft.server.v1_14_R1.DataPaletteBlock;
|
||||
import net.minecraft.server.v1_14_R1.DataPaletteLinear;
|
||||
import net.minecraft.server.v1_14_R1.GameProfileSerializer;
|
||||
import net.minecraft.server.v1_14_R1.IBlockData;
|
||||
import net.minecraft.server.v1_14_R1.PacketPlayOutLightUpdate;
|
||||
import net.minecraft.server.v1_14_R1.PlayerChunk;
|
||||
import net.minecraft.server.v1_14_R1.PlayerChunkMap;
|
||||
import net.minecraft.server.v1_14_R1.World;
|
||||
@ -167,7 +168,7 @@ public final class BukkitAdapter_1_14 extends NMSAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendChunk(net.minecraft.server.v1_14_R1.WorldServer nmsWorld, int X, int Z, int mask) {
|
||||
public static void sendChunk(net.minecraft.server.v1_14_R1.WorldServer nmsWorld, int X, int Z, int mask, boolean lighting) {
|
||||
PlayerChunk playerChunk = getPlayerChunk(nmsWorld, X, Z);
|
||||
if (playerChunk == null) {
|
||||
return;
|
||||
@ -187,6 +188,15 @@ public final class BukkitAdapter_1_14 extends NMSAdapter {
|
||||
|
||||
fieldDirtyBits.set(playerChunk, dirtyBits);
|
||||
fieldDirtyCount.set(playerChunk, 64);
|
||||
|
||||
if (lighting) {
|
||||
ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(X, Z);
|
||||
PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine());
|
||||
playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> {
|
||||
p.playerConnection.sendPacket(packet);
|
||||
});
|
||||
}
|
||||
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -54,10 +54,13 @@ import net.minecraft.server.v1_14_R1.DataPaletteHash;
|
||||
import net.minecraft.server.v1_14_R1.DataPaletteLinear;
|
||||
import net.minecraft.server.v1_14_R1.Entity;
|
||||
import net.minecraft.server.v1_14_R1.EntityTypes;
|
||||
import net.minecraft.server.v1_14_R1.EnumSkyBlock;
|
||||
import net.minecraft.server.v1_14_R1.IBlockData;
|
||||
import net.minecraft.server.v1_14_R1.LightEngineThreaded;
|
||||
import net.minecraft.server.v1_14_R1.NBTTagCompound;
|
||||
import net.minecraft.server.v1_14_R1.NBTTagInt;
|
||||
import net.minecraft.server.v1_14_R1.NibbleArray;
|
||||
import net.minecraft.server.v1_14_R1.SectionPosition;
|
||||
import net.minecraft.server.v1_14_R1.TileEntity;
|
||||
import net.minecraft.server.v1_14_R1.WorldServer;
|
||||
import org.bukkit.World;
|
||||
@ -72,6 +75,8 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
|
||||
public Chunk nmsChunk;
|
||||
public WorldServer world;
|
||||
public int X, Z;
|
||||
public NibbleArray[] blockLight = new NibbleArray[16];
|
||||
public NibbleArray[] skyLight = new NibbleArray[16];
|
||||
|
||||
public BukkitGetBlocks_1_14(World world, int X, int Z) {
|
||||
this(((CraftWorld) world).getHandle(), X, Z);
|
||||
@ -119,6 +124,26 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
|
||||
return AdaptedMap.immutable(nmsTiles, posNms2We, nmsTile2We);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkyLight(int x, int y, int z) {
|
||||
int layer = y >> 4;
|
||||
if (skyLight[layer] == null) {
|
||||
skyLight[layer] = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.SKY).a(SectionPosition.a(nmsChunk.getPos(), layer));
|
||||
}
|
||||
long l = BlockPosition.a(x, y, z);
|
||||
return skyLight[layer].a(SectionPosition.b(BlockPosition.b(l)), SectionPosition.b(BlockPosition.c(l)), SectionPosition.b(BlockPosition.d(l)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEmmittedLight(int x, int y, int z) {
|
||||
int layer = y >> 4;
|
||||
if (blockLight[layer] == null) {
|
||||
blockLight[layer] = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.BLOCK).a(SectionPosition.a(nmsChunk.getPos(), layer));
|
||||
}
|
||||
long l = BlockPosition.a(x, y, z);
|
||||
return blockLight[layer].a(SectionPosition.b(BlockPosition.b(l)), SectionPosition.b(BlockPosition.c(l)), SectionPosition.b(BlockPosition.d(l)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getEntity(UUID uuid) {
|
||||
Entity entity = world.getEntity(uuid);
|
||||
@ -322,6 +347,29 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
Runnable[] syncTasks = null;
|
||||
|
||||
int bx = X << 4;
|
||||
@ -427,24 +475,19 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
|
||||
};
|
||||
}
|
||||
|
||||
{//Lighting
|
||||
// TODO optimize, cause this is really slow
|
||||
LightEngineThreaded engine = (LightEngineThreaded) nmsChunk.e();
|
||||
engine.a(nmsChunk, false);
|
||||
}
|
||||
|
||||
Runnable callback;
|
||||
if (bitMask == 0 && biomes == null) {
|
||||
if (bitMask == 0 && biomes == null && !lightUpdate) {
|
||||
callback = null;
|
||||
} else {
|
||||
int finalMask = bitMask;
|
||||
int finalMask = bitMask != 0 ? bitMask : lightUpdate ? set.getBitMask() : 0;
|
||||
boolean finalLightUpdate = lightUpdate;
|
||||
callback = () -> {
|
||||
// Set Modified
|
||||
nmsChunk.d(true); // Set Modified
|
||||
nmsChunk.mustNotSave = false;
|
||||
nmsChunk.markDirty();
|
||||
// send to player
|
||||
BukkitAdapter_1_14.sendChunk(nmsWorld, X, Z, finalMask);
|
||||
BukkitAdapter_1_14.sendChunk(nmsWorld, X, Z, finalMask, finalLightUpdate);
|
||||
if (finalizer != null) finalizer.run();
|
||||
};
|
||||
}
|
||||
@ -617,6 +660,25 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
private void fillLightNibble(char[][] light, EnumSkyBlock skyBlock) {
|
||||
for (int Y = 0; Y < 16; Y++) {
|
||||
if (light[Y] == null) {
|
||||
continue;
|
||||
}
|
||||
NibbleArray nibble = world.getChunkProvider().getLightEngine().a(skyBlock).a(SectionPosition.a(nmsChunk.getPos(), Y));
|
||||
if (nibble == null) {
|
||||
continue;
|
||||
}
|
||||
synchronized (nibble) {
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
if (light[Y][i] < 16) {
|
||||
nibble.a(i, light[Y][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSection(int layer) {
|
||||
return getSections()[layer] != null;
|
||||
|
@ -24,6 +24,7 @@ import net.minecraft.server.v1_15_R1.DataPaletteBlock;
|
||||
import net.minecraft.server.v1_15_R1.DataPaletteLinear;
|
||||
import net.minecraft.server.v1_15_R1.GameProfileSerializer;
|
||||
import net.minecraft.server.v1_15_R1.IBlockData;
|
||||
import net.minecraft.server.v1_15_R1.PacketPlayOutLightUpdate;
|
||||
import net.minecraft.server.v1_15_R1.PlayerChunk;
|
||||
import net.minecraft.server.v1_15_R1.PlayerChunkMap;
|
||||
import net.minecraft.server.v1_15_R1.World;
|
||||
@ -85,6 +86,8 @@ public final class BukkitAdapter_1_15 extends NMSAdapter {
|
||||
fieldDirtyBits = PlayerChunk.class.getDeclaredField("r");
|
||||
fieldDirtyBits.setAccessible(true);
|
||||
|
||||
fieldTickingBlockCount.setAccessible(true);
|
||||
|
||||
Method declaredGetVisibleChunk = PlayerChunkMap.class.getDeclaredMethod("getVisibleChunk", long.class);
|
||||
declaredGetVisibleChunk.setAccessible(true);
|
||||
methodGetVisibleChunk = MethodHandles.lookup().unreflect(declaredGetVisibleChunk);
|
||||
@ -165,7 +168,7 @@ public final class BukkitAdapter_1_15 extends NMSAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendChunk(net.minecraft.server.v1_15_R1.WorldServer nmsWorld, int X, int Z, int mask) {
|
||||
public static void sendChunk(net.minecraft.server.v1_15_R1.WorldServer nmsWorld, int X, int Z, int mask, boolean lighting) {
|
||||
PlayerChunk playerChunk = getPlayerChunk(nmsWorld, X, Z);
|
||||
if (playerChunk == null) {
|
||||
return;
|
||||
@ -185,6 +188,15 @@ public final class BukkitAdapter_1_15 extends NMSAdapter {
|
||||
|
||||
fieldDirtyBits.set(playerChunk, dirtyBits);
|
||||
fieldDirtyCount.set(playerChunk, 64);
|
||||
|
||||
if (lighting) {
|
||||
ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(X, Z);
|
||||
PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine());
|
||||
playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> {
|
||||
p.playerConnection.sendPacket(packet);
|
||||
});
|
||||
}
|
||||
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -55,10 +55,13 @@ import net.minecraft.server.v1_15_R1.DataPaletteHash;
|
||||
import net.minecraft.server.v1_15_R1.DataPaletteLinear;
|
||||
import net.minecraft.server.v1_15_R1.Entity;
|
||||
import net.minecraft.server.v1_15_R1.EntityTypes;
|
||||
import net.minecraft.server.v1_15_R1.EnumSkyBlock;
|
||||
import net.minecraft.server.v1_15_R1.IBlockData;
|
||||
import net.minecraft.server.v1_15_R1.LightEngineThreaded;
|
||||
import net.minecraft.server.v1_15_R1.NBTTagCompound;
|
||||
import net.minecraft.server.v1_15_R1.NBTTagInt;
|
||||
import net.minecraft.server.v1_15_R1.NibbleArray;
|
||||
import net.minecraft.server.v1_15_R1.SectionPosition;
|
||||
import net.minecraft.server.v1_15_R1.TileEntity;
|
||||
import net.minecraft.server.v1_15_R1.WorldServer;
|
||||
import org.bukkit.World;
|
||||
@ -75,6 +78,8 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks {
|
||||
public Chunk nmsChunk;
|
||||
public WorldServer world;
|
||||
public int X, Z;
|
||||
public NibbleArray[] blockLight = new NibbleArray[16];
|
||||
public NibbleArray[] skyLight = new NibbleArray[16];
|
||||
|
||||
public BukkitGetBlocks_1_15(World world, int X, int Z) {
|
||||
this(((CraftWorld) world).getHandle(), X, Z);
|
||||
@ -127,6 +132,26 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks {
|
||||
return AdaptedMap.immutable(nmsTiles, posNms2We, nmsTile2We);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkyLight(int x, int y, int z) {
|
||||
int layer = y >> 4;
|
||||
if (skyLight[layer] == null) {
|
||||
skyLight[layer] = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.SKY).a(SectionPosition.a(nmsChunk.getPos(), layer));
|
||||
}
|
||||
long l = BlockPosition.a(x, y, z);
|
||||
return skyLight[layer].a(SectionPosition.b(BlockPosition.b(l)), SectionPosition.b(BlockPosition.c(l)), SectionPosition.b(BlockPosition.d(l)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEmmittedLight(int x, int y, int z) {
|
||||
int layer = y >> 4;
|
||||
if (blockLight[layer] == null) {
|
||||
blockLight[layer] = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.BLOCK).a(SectionPosition.a(nmsChunk.getPos(), layer));
|
||||
}
|
||||
long l = BlockPosition.a(x, y, z);
|
||||
return blockLight[layer].a(SectionPosition.b(BlockPosition.b(l)), SectionPosition.b(BlockPosition.c(l)), SectionPosition.b(BlockPosition.d(l)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getEntity(UUID uuid) {
|
||||
Entity entity = world.getEntity(uuid);
|
||||
@ -335,6 +360,29 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks {
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
Runnable[] syncTasks = null;
|
||||
|
||||
int bx = X << 4;
|
||||
@ -440,25 +488,19 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks {
|
||||
};
|
||||
}
|
||||
|
||||
//Lighting
|
||||
// TODO optimize, cause this is really slow
|
||||
LightEngineThreaded engine = (LightEngineThreaded) nmsChunk.e();
|
||||
//lightChunk()
|
||||
engine.a(nmsChunk, false);
|
||||
|
||||
Runnable callback;
|
||||
if (bitMask == 0 && biomes == null) {
|
||||
if (bitMask == 0 && biomes == null && !lightUpdate) {
|
||||
callback = null;
|
||||
} else {
|
||||
int finalMask = bitMask;
|
||||
int finalMask = bitMask != 0 ? bitMask : lightUpdate ? set.getBitMask() : 0;
|
||||
boolean finalLightUpdate = lightUpdate;
|
||||
callback = () -> {
|
||||
// Set Modified
|
||||
//setLastSaveHadEntities
|
||||
nmsChunk.d(true); // Set Modified
|
||||
nmsChunk.mustNotSave = false;
|
||||
nmsChunk.markDirty();
|
||||
// send to player
|
||||
BukkitAdapter_1_15.sendChunk(nmsWorld, X, Z, finalMask);
|
||||
BukkitAdapter_1_15.sendChunk(nmsWorld, X, Z, finalMask, finalLightUpdate);
|
||||
if (finalizer != null) finalizer.run();
|
||||
};
|
||||
}
|
||||
@ -637,6 +679,25 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
private void fillLightNibble(char[][] light, EnumSkyBlock skyBlock) {
|
||||
for (int Y = 0; Y < 16; Y++) {
|
||||
if (light[Y] == null) {
|
||||
continue;
|
||||
}
|
||||
NibbleArray nibble = world.getChunkProvider().getLightEngine().a(skyBlock).a(SectionPosition.a(nmsChunk.getPos(), Y));
|
||||
if (nibble == null) {
|
||||
continue;
|
||||
}
|
||||
synchronized (nibble) {
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
if (light[Y][i] < 16) {
|
||||
nibble.a(i, light[Y][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSection(int layer) {
|
||||
return getSections()[layer] != null;
|
||||
|
@ -13,12 +13,6 @@ import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import net.jpountz.util.UnsafeUtils;
|
||||
import net.minecraft.server.v1_15_R1.Block;
|
||||
import net.minecraft.server.v1_15_R1.Chunk;
|
||||
@ -30,6 +24,11 @@ import net.minecraft.server.v1_15_R1.DataPaletteBlock;
|
||||
import net.minecraft.server.v1_15_R1.DataPaletteLinear;
|
||||
import net.minecraft.server.v1_15_R1.GameProfileSerializer;
|
||||
import net.minecraft.server.v1_15_R1.IBlockData;
|
||||
import net.minecraft.server.v1_15_R1.LightEngine;
|
||||
import net.minecraft.server.v1_15_R1.LightEngineLayer;
|
||||
import net.minecraft.server.v1_15_R1.LightEngineStorage;
|
||||
import net.minecraft.server.v1_15_R1.NibbleArray;
|
||||
import net.minecraft.server.v1_15_R1.PacketPlayOutLightUpdate;
|
||||
import net.minecraft.server.v1_15_R1.PlayerChunk;
|
||||
import net.minecraft.server.v1_15_R1.PlayerChunkMap;
|
||||
import net.minecraft.server.v1_15_R1.World;
|
||||
@ -38,9 +37,15 @@ import org.bukkit.craftbukkit.v1_15_R1.CraftChunk;
|
||||
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Function;
|
||||
|
||||
public final class BukkitAdapter_1_15_2 extends NMSAdapter {
|
||||
@ -60,6 +65,8 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter {
|
||||
|
||||
private final static MethodHandle methodGetVisibleChunk;
|
||||
|
||||
public final static MethodHandle methodSetLightNibbleArray;
|
||||
|
||||
private static final int CHUNKSECTION_BASE;
|
||||
private static final int CHUNKSECTION_SHIFT;
|
||||
|
||||
@ -90,6 +97,10 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter {
|
||||
declaredGetVisibleChunk.setAccessible(true);
|
||||
methodGetVisibleChunk = MethodHandles.lookup().unreflect(declaredGetVisibleChunk);
|
||||
|
||||
Method declaredSetLightNibbleArray = LightEngineStorage.class.getDeclaredMethod("a", long.class, NibbleArray.class);
|
||||
declaredSetLightNibbleArray.setAccessible(true);
|
||||
methodSetLightNibbleArray = MethodHandles.lookup().unreflect(declaredSetLightNibbleArray);
|
||||
|
||||
Field tmp = DataPaletteBlock.class.getDeclaredField("j");
|
||||
ReflectionUtils.setAccessibleNonFinal(tmp);
|
||||
fieldLock = tmp;
|
||||
@ -167,7 +178,7 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendChunk(WorldServer nmsWorld, int X, int Z, int mask) {
|
||||
public static void sendChunk(WorldServer nmsWorld, int X, int Z, int mask, boolean lighting) {
|
||||
PlayerChunk playerChunk = getPlayerChunk(nmsWorld, X, Z);
|
||||
if (playerChunk == null) {
|
||||
return;
|
||||
@ -187,6 +198,15 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter {
|
||||
|
||||
fieldDirtyBits.set(playerChunk, dirtyBits);
|
||||
fieldDirtyCount.set(playerChunk, 64);
|
||||
|
||||
if (lighting) {
|
||||
ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(X, Z);
|
||||
PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine());
|
||||
playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> {
|
||||
p.playerConnection.sendPacket(packet);
|
||||
});
|
||||
}
|
||||
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -38,10 +38,12 @@ import net.minecraft.server.v1_15_R1.DataPaletteHash;
|
||||
import net.minecraft.server.v1_15_R1.DataPaletteLinear;
|
||||
import net.minecraft.server.v1_15_R1.Entity;
|
||||
import net.minecraft.server.v1_15_R1.EntityTypes;
|
||||
import net.minecraft.server.v1_15_R1.EnumSkyBlock;
|
||||
import net.minecraft.server.v1_15_R1.IBlockData;
|
||||
import net.minecraft.server.v1_15_R1.LightEngineThreaded;
|
||||
import net.minecraft.server.v1_15_R1.NBTTagCompound;
|
||||
import net.minecraft.server.v1_15_R1.NBTTagInt;
|
||||
import net.minecraft.server.v1_15_R1.NibbleArray;
|
||||
import net.minecraft.server.v1_15_R1.SectionPosition;
|
||||
import net.minecraft.server.v1_15_R1.TileEntity;
|
||||
import net.minecraft.server.v1_15_R1.WorldServer;
|
||||
import org.bukkit.World;
|
||||
@ -80,6 +82,8 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
||||
public Chunk nmsChunk;
|
||||
public WorldServer world;
|
||||
public int X, Z;
|
||||
public NibbleArray[] blockLight = new NibbleArray[16];
|
||||
public NibbleArray[] skyLight = new NibbleArray[16];
|
||||
|
||||
public BukkitGetBlocks_1_15_2(World world, int X, int Z) {
|
||||
this(((CraftWorld) world).getHandle(), X, Z);
|
||||
@ -132,6 +136,26 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
||||
return AdaptedMap.immutable(nmsTiles, posNms2We, nmsTile2We);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkyLight(int x, int y, int z) {
|
||||
int layer = y >> 4;
|
||||
if (skyLight[layer] == null) {
|
||||
skyLight[layer] = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.SKY).a(SectionPosition.a(nmsChunk.getPos(), layer));
|
||||
}
|
||||
long l = BlockPosition.a(x, y, z);
|
||||
return skyLight[layer].a(SectionPosition.b(BlockPosition.b(l)), SectionPosition.b(BlockPosition.c(l)), SectionPosition.b(BlockPosition.d(l)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEmmittedLight(int x, int y, int z) {
|
||||
int layer = y >> 4;
|
||||
if (blockLight[layer] == null) {
|
||||
blockLight[layer] = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.BLOCK).a(SectionPosition.a(nmsChunk.getPos(), layer));
|
||||
}
|
||||
long l = BlockPosition.a(x, y, z);
|
||||
return blockLight[layer].a(SectionPosition.b(BlockPosition.b(l)), SectionPosition.b(BlockPosition.c(l)), SectionPosition.b(BlockPosition.d(l)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getEntity(UUID uuid) {
|
||||
Entity entity = world.getEntity(uuid);
|
||||
@ -347,6 +371,29 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
Runnable[] syncTasks = null;
|
||||
|
||||
int bx = X << 4;
|
||||
@ -452,23 +499,19 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
||||
};
|
||||
}
|
||||
|
||||
//Lighting
|
||||
// TODO optimize, cause this is really slow
|
||||
LightEngineThreaded engine = (LightEngineThreaded) nmsChunk.e();
|
||||
engine.a(nmsChunk, false);
|
||||
|
||||
Runnable callback;
|
||||
if (bitMask == 0 && biomes == null) {
|
||||
if (bitMask == 0 && biomes == null && !lightUpdate) {
|
||||
callback = null;
|
||||
} else {
|
||||
int finalMask = bitMask;
|
||||
int finalMask = bitMask != 0 ? bitMask : lightUpdate ? set.getBitMask() : 0;
|
||||
boolean finalLightUpdate = lightUpdate;
|
||||
callback = () -> {
|
||||
// Set Modified
|
||||
nmsChunk.d(true); // Set Modified
|
||||
nmsChunk.mustNotSave = false;
|
||||
nmsChunk.markDirty();
|
||||
// send to player
|
||||
BukkitAdapter_1_15_2.sendChunk(nmsWorld, X, Z, finalMask);
|
||||
BukkitAdapter_1_15_2.sendChunk(nmsWorld, X, Z, finalMask, finalLightUpdate);
|
||||
if (finalizer != null) finalizer.run();
|
||||
};
|
||||
}
|
||||
@ -641,6 +684,25 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
private void fillLightNibble(char[][] light, EnumSkyBlock skyBlock) {
|
||||
for (int Y = 0; Y < 16; Y++) {
|
||||
if (light[Y] == null) {
|
||||
continue;
|
||||
}
|
||||
NibbleArray nibble = world.getChunkProvider().getLightEngine().a(skyBlock).a(SectionPosition.a(nmsChunk.getPos(), Y));
|
||||
if (nibble == null) {
|
||||
continue;
|
||||
}
|
||||
synchronized (nibble) {
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
if (light[Y][i] < 16) {
|
||||
nibble.a(i, light[Y][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSection(int layer) {
|
||||
return getSections()[layer] != null;
|
||||
@ -648,6 +710,8 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
||||
|
||||
@Override
|
||||
public boolean trim(boolean aggressive) {
|
||||
skyLight = new NibbleArray[16];
|
||||
blockLight = new NibbleArray[16];
|
||||
if (aggressive) {
|
||||
sections = null;
|
||||
nmsChunk = null;
|
||||
|
Reference in New Issue
Block a user