mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-06-23 08:16:52 +00:00
fix: some improvements to GET chunk writing (#2853)
* fix: some improvements to GET chunk writing - ensure levelChunk is loaded before giving to copy GET - this is not necessarily guaranteed to be nonnull if two edits overlap. Whilst not advised, such an easy failure should not occur when two edits collide * Prevent writing chunk sections when FAWE is also sending packets for a chunk and vice versa - alter IntPair hashcode to be more often unique - Utilise ConcurrentHashMap for free synchronisation * Minor comment changes * Use one-per-world-instance FaweBukkitWorld to store world chunk map
This commit is contained in:
@ -7,6 +7,7 @@ import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType;
|
||||
import com.fastasyncworldedit.core.math.BitArrayUnstretched;
|
||||
import com.fastasyncworldedit.core.math.IntPair;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||
import com.fastasyncworldedit.core.queue.IChunkSet;
|
||||
@ -106,6 +107,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
private final ServerLevel serverLevel;
|
||||
private final int chunkX;
|
||||
private final int chunkZ;
|
||||
private final IntPair chunkPos;
|
||||
private final int minHeight;
|
||||
private final int maxHeight;
|
||||
private final int minSectionPosition;
|
||||
@ -140,6 +142,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
this.blockLight = new DataLayer[getSectionCount()];
|
||||
this.biomeRegistry = serverLevel.registryAccess().registryOrThrow(BIOME);
|
||||
this.biomeHolderIdMap = biomeRegistry.asHolderIdMap();
|
||||
this.chunkPos = new IntPair(chunkX, chunkZ);
|
||||
}
|
||||
|
||||
public int getChunkX() {
|
||||
@ -425,7 +428,8 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
throw new IllegalStateException("Attempted to call chunk GET but chunk was not call-locked.");
|
||||
}
|
||||
forceLoadSections = false;
|
||||
PaperweightGetBlocks_Copy copy = createCopy ? new PaperweightGetBlocks_Copy(levelChunk) : null;
|
||||
LevelChunk nmsChunk = ensureLoaded(serverLevel, chunkX, chunkZ);
|
||||
PaperweightGetBlocks_Copy copy = createCopy ? new PaperweightGetBlocks_Copy(nmsChunk) : null;
|
||||
if (createCopy) {
|
||||
if (copies.containsKey(copyKey)) {
|
||||
throw new IllegalStateException("Copy key already used.");
|
||||
@ -433,9 +437,6 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
copies.put(copyKey, copy);
|
||||
}
|
||||
try {
|
||||
ServerLevel nmsWorld = serverLevel;
|
||||
LevelChunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ);
|
||||
|
||||
// Remove existing tiles. Create a copy so that we can remove blocks
|
||||
Map<BlockPos, BlockEntity> chunkTiles = new HashMap<>(nmsChunk.getBlockEntities());
|
||||
List<BlockEntity> beacons = null;
|
||||
@ -507,6 +508,8 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
biomeData
|
||||
);
|
||||
if (PaperweightPlatformAdapter.setSectionAtomic(
|
||||
serverLevel.getWorld().getName(),
|
||||
chunkPos,
|
||||
levelChunkSections,
|
||||
null,
|
||||
newSection,
|
||||
@ -584,6 +587,8 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
biomeData
|
||||
);
|
||||
if (PaperweightPlatformAdapter.setSectionAtomic(
|
||||
serverLevel.getWorld().getName(),
|
||||
chunkPos,
|
||||
levelChunkSections,
|
||||
null,
|
||||
newSection,
|
||||
@ -649,6 +654,8 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
biomeData != null ? biomeData : (PalettedContainer<Holder<Biome>>) existingSection.getBiomes()
|
||||
);
|
||||
if (!PaperweightPlatformAdapter.setSectionAtomic(
|
||||
serverLevel.getWorld().getName(),
|
||||
chunkPos,
|
||||
levelChunkSections,
|
||||
existingSection,
|
||||
newSection,
|
||||
@ -722,7 +729,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
}
|
||||
if (Settings.settings().EXPERIMENTAL.REMOVE_ENTITY_FROM_WORLD_ON_CHUNK_FAIL) {
|
||||
for (UUID uuid : entityRemoves) {
|
||||
Entity entity = nmsWorld.getEntities().get(uuid);
|
||||
Entity entity = serverLevel.getEntities().get(uuid);
|
||||
if (entity != null) {
|
||||
removeEntity(entity);
|
||||
}
|
||||
@ -761,7 +768,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
|
||||
EntityType<?> type = EntityType.byString(id).orElse(null);
|
||||
if (type != null) {
|
||||
Entity entity = type.create(nmsWorld);
|
||||
Entity entity = type.create(serverLevel);
|
||||
if (entity != null) {
|
||||
final CompoundTag tag = (CompoundTag) adapter.fromNativeLin(linTag);
|
||||
for (final String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
|
||||
@ -770,11 +777,11 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
entity.load(tag);
|
||||
entity.absMoveTo(x, y, z, yaw, pitch);
|
||||
entity.setUUID(NbtUtils.uuid(nativeTag));
|
||||
if (!nmsWorld.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM)) {
|
||||
if (!serverLevel.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM)) {
|
||||
LOGGER.warn(
|
||||
"Error creating entity of type `{}` in world `{}` at location `{},{},{}`",
|
||||
id,
|
||||
nmsWorld.getWorld().getName(),
|
||||
serverLevel.getWorld().getName(),
|
||||
x,
|
||||
y,
|
||||
z
|
||||
@ -804,11 +811,11 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
final int z = blockHash.z() + bz;
|
||||
final BlockPos pos = new BlockPos(x, y, z);
|
||||
|
||||
synchronized (nmsWorld) {
|
||||
BlockEntity tileEntity = nmsWorld.getBlockEntity(pos);
|
||||
synchronized (serverLevel) {
|
||||
BlockEntity tileEntity = serverLevel.getBlockEntity(pos);
|
||||
if (tileEntity == null || tileEntity.isRemoved()) {
|
||||
nmsWorld.removeBlockEntity(pos);
|
||||
tileEntity = nmsWorld.getBlockEntity(pos);
|
||||
serverLevel.removeBlockEntity(pos);
|
||||
tileEntity = serverLevel.getBlockEntity(pos);
|
||||
}
|
||||
if (tileEntity != null) {
|
||||
final CompoundTag tag = (CompoundTag) adapter.fromNativeLin(nativeTag.linTag());
|
||||
@ -827,7 +834,6 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
callback = null;
|
||||
} else {
|
||||
int finalMask = bitMask != 0 ? bitMask : lightUpdate ? set.getBitMask() : 0;
|
||||
boolean finalLightUpdate = lightUpdate;
|
||||
callback = () -> {
|
||||
// Set Modified
|
||||
nmsChunk.setLightCorrect(true); // Set Modified
|
||||
@ -933,7 +939,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
@Override
|
||||
public void send() {
|
||||
synchronized (sendLock) {
|
||||
PaperweightPlatformAdapter.sendChunk(this, serverLevel, chunkX, chunkZ);
|
||||
PaperweightPlatformAdapter.sendChunk(new IntPair(chunkX, chunkZ), serverLevel, chunkX, chunkZ);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,8 @@ import com.fastasyncworldedit.bukkit.adapter.NMSAdapter;
|
||||
import com.fastasyncworldedit.core.Fawe;
|
||||
import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.math.BitArrayUnstretched;
|
||||
import com.fastasyncworldedit.core.math.IntPair;
|
||||
import com.fastasyncworldedit.core.util.MathMan;
|
||||
import com.fastasyncworldedit.core.util.ReflectionUtils;
|
||||
import com.fastasyncworldedit.core.util.TaskManager;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
@ -243,15 +243,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
}
|
||||
|
||||
static boolean setSectionAtomic(
|
||||
String worldName,
|
||||
IntPair pair,
|
||||
LevelChunkSection[] sections,
|
||||
LevelChunkSection expected,
|
||||
LevelChunkSection value,
|
||||
int layer
|
||||
) {
|
||||
if (layer >= 0 && layer < sections.length) {
|
||||
return ReflectionUtils.compareAndSet(sections, expected, value, layer);
|
||||
}
|
||||
return false;
|
||||
return NMSAdapter.setSectionAtomic(worldName, pair, sections, expected, value, layer);
|
||||
}
|
||||
|
||||
// There is no point in having a functional semaphore for paper servers.
|
||||
@ -349,7 +348,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void sendChunk(Object chunk, ServerLevel nmsWorld, int chunkX, int chunkZ) {
|
||||
public static void sendChunk(IntPair pair, ServerLevel nmsWorld, int chunkX, int chunkZ) {
|
||||
ChunkHolder chunkHolder = getPlayerChunk(nmsWorld, chunkX, chunkZ);
|
||||
if (chunkHolder == null) {
|
||||
return;
|
||||
@ -370,26 +369,35 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
if (levelChunk == null) {
|
||||
return;
|
||||
}
|
||||
StampLockHolder lockHolder = new StampLockHolder();
|
||||
NMSAdapter.beginChunkPacketSend(nmsWorld.getWorld().getName(), pair, lockHolder);
|
||||
if (lockHolder.chunkLock == null) {
|
||||
return;
|
||||
}
|
||||
MinecraftServer.getServer().execute(() -> {
|
||||
ClientboundLevelChunkWithLightPacket packet;
|
||||
if (PaperLib.isPaper()) {
|
||||
packet = new ClientboundLevelChunkWithLightPacket(
|
||||
levelChunk,
|
||||
nmsWorld.getChunkSource().getLightEngine(),
|
||||
null,
|
||||
null,
|
||||
false // last false is to not bother with x-ray
|
||||
);
|
||||
} else {
|
||||
// deprecated on paper - deprecation suppressed
|
||||
packet = new ClientboundLevelChunkWithLightPacket(
|
||||
levelChunk,
|
||||
nmsWorld.getChunkSource().getLightEngine(),
|
||||
null,
|
||||
null
|
||||
);
|
||||
try {
|
||||
ClientboundLevelChunkWithLightPacket packet;
|
||||
if (PaperLib.isPaper()) {
|
||||
packet = new ClientboundLevelChunkWithLightPacket(
|
||||
levelChunk,
|
||||
nmsWorld.getChunkSource().getLightEngine(),
|
||||
null,
|
||||
null,
|
||||
false // last false is to not bother with x-ray
|
||||
);
|
||||
} else {
|
||||
// deprecated on paper - deprecation suppressed
|
||||
packet = new ClientboundLevelChunkWithLightPacket(
|
||||
levelChunk,
|
||||
nmsWorld.getChunkSource().getLightEngine(),
|
||||
null,
|
||||
null
|
||||
);
|
||||
}
|
||||
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
|
||||
} finally {
|
||||
NMSAdapter.endChunkPacketSend(nmsWorld.getWorld().getName(), pair, lockHolder);
|
||||
}
|
||||
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R2;
|
||||
|
||||
import com.fastasyncworldedit.bukkit.adapter.StarlightRelighter;
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.math.IntPair;
|
||||
import com.fastasyncworldedit.core.queue.IQueueExtent;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
@ -67,7 +68,7 @@ public class PaperweightStarlightRelighter extends StarlightRelighter<ServerLeve
|
||||
int x = pos.x;
|
||||
int z = pos.z;
|
||||
if (delay) { // we still need to send the block changes of that chunk
|
||||
PaperweightPlatformAdapter.sendChunk(pos, serverLevel, x, z);
|
||||
PaperweightPlatformAdapter.sendChunk(new IntPair(x, z), serverLevel, x, z);
|
||||
}
|
||||
serverLevel.getChunkSource().removeTicketAtLevel(FAWE_TICKET, pos, LIGHT_LEVEL, Unit.INSTANCE);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType;
|
||||
import com.fastasyncworldedit.core.math.BitArrayUnstretched;
|
||||
import com.fastasyncworldedit.core.math.IntPair;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||
import com.fastasyncworldedit.core.queue.IChunkSet;
|
||||
@ -106,6 +107,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
private final ServerLevel serverLevel;
|
||||
private final int chunkX;
|
||||
private final int chunkZ;
|
||||
private final IntPair chunkPos;
|
||||
private final int minHeight;
|
||||
private final int maxHeight;
|
||||
private final int minSectionPosition;
|
||||
@ -140,6 +142,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
this.blockLight = new DataLayer[getSectionCount()];
|
||||
this.biomeRegistry = serverLevel.registryAccess().registryOrThrow(BIOME);
|
||||
this.biomeHolderIdMap = biomeRegistry.asHolderIdMap();
|
||||
this.chunkPos = new IntPair(chunkX, chunkZ);
|
||||
}
|
||||
|
||||
public int getChunkX() {
|
||||
@ -425,7 +428,8 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
throw new IllegalStateException("Attempted to call chunk GET but chunk was not call-locked.");
|
||||
}
|
||||
forceLoadSections = false;
|
||||
PaperweightGetBlocks_Copy copy = createCopy ? new PaperweightGetBlocks_Copy(levelChunk) : null;
|
||||
LevelChunk nmsChunk = ensureLoaded(serverLevel, chunkX, chunkZ);
|
||||
PaperweightGetBlocks_Copy copy = createCopy ? new PaperweightGetBlocks_Copy(nmsChunk) : null;
|
||||
if (createCopy) {
|
||||
if (copies.containsKey(copyKey)) {
|
||||
throw new IllegalStateException("Copy key already used.");
|
||||
@ -433,9 +437,6 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
copies.put(copyKey, copy);
|
||||
}
|
||||
try {
|
||||
ServerLevel nmsWorld = serverLevel;
|
||||
LevelChunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ);
|
||||
|
||||
// Remove existing tiles. Create a copy so that we can remove blocks
|
||||
Map<BlockPos, BlockEntity> chunkTiles = new HashMap<>(nmsChunk.getBlockEntities());
|
||||
List<BlockEntity> beacons = null;
|
||||
@ -507,6 +508,8 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
biomeData
|
||||
);
|
||||
if (PaperweightPlatformAdapter.setSectionAtomic(
|
||||
serverLevel.getWorld().getName(),
|
||||
chunkPos,
|
||||
levelChunkSections,
|
||||
null,
|
||||
newSection,
|
||||
@ -584,6 +587,8 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
biomeData
|
||||
);
|
||||
if (PaperweightPlatformAdapter.setSectionAtomic(
|
||||
serverLevel.getWorld().getName(),
|
||||
chunkPos,
|
||||
levelChunkSections,
|
||||
null,
|
||||
newSection,
|
||||
@ -649,6 +654,8 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
biomeData != null ? biomeData : (PalettedContainer<Holder<Biome>>) existingSection.getBiomes()
|
||||
);
|
||||
if (!PaperweightPlatformAdapter.setSectionAtomic(
|
||||
serverLevel.getWorld().getName(),
|
||||
chunkPos,
|
||||
levelChunkSections,
|
||||
existingSection,
|
||||
newSection,
|
||||
@ -722,7 +729,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
}
|
||||
if (Settings.settings().EXPERIMENTAL.REMOVE_ENTITY_FROM_WORLD_ON_CHUNK_FAIL) {
|
||||
for (UUID uuid : entityRemoves) {
|
||||
Entity entity = nmsWorld.getEntities().get(uuid);
|
||||
Entity entity = serverLevel.getEntities().get(uuid);
|
||||
if (entity != null) {
|
||||
removeEntity(entity);
|
||||
}
|
||||
@ -761,7 +768,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
|
||||
EntityType<?> type = EntityType.byString(id).orElse(null);
|
||||
if (type != null) {
|
||||
Entity entity = type.create(nmsWorld);
|
||||
Entity entity = type.create(serverLevel);
|
||||
if (entity != null) {
|
||||
final net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(linTag);
|
||||
for (final String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
|
||||
@ -770,11 +777,11 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
entity.load(tag);
|
||||
entity.absMoveTo(x, y, z, yaw, pitch);
|
||||
entity.setUUID(NbtUtils.uuid(nativeTag));
|
||||
if (!nmsWorld.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM)) {
|
||||
if (!serverLevel.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM)) {
|
||||
LOGGER.warn(
|
||||
"Error creating entity of type `{}` in world `{}` at location `{},{},{}`",
|
||||
id,
|
||||
nmsWorld.getWorld().getName(),
|
||||
serverLevel.getWorld().getName(),
|
||||
x,
|
||||
y,
|
||||
z
|
||||
@ -804,11 +811,11 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
final int z = blockHash.z() + bz;
|
||||
final BlockPos pos = new BlockPos(x, y, z);
|
||||
|
||||
synchronized (nmsWorld) {
|
||||
BlockEntity tileEntity = nmsWorld.getBlockEntity(pos);
|
||||
synchronized (serverLevel) {
|
||||
BlockEntity tileEntity = serverLevel.getBlockEntity(pos);
|
||||
if (tileEntity == null || tileEntity.isRemoved()) {
|
||||
nmsWorld.removeBlockEntity(pos);
|
||||
tileEntity = nmsWorld.getBlockEntity(pos);
|
||||
serverLevel.removeBlockEntity(pos);
|
||||
tileEntity = serverLevel.getBlockEntity(pos);
|
||||
}
|
||||
if (tileEntity != null) {
|
||||
final net.minecraft.nbt.CompoundTag tag = (CompoundTag) adapter.fromNativeLin(nativeTag.linTag());
|
||||
@ -827,7 +834,6 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
callback = null;
|
||||
} else {
|
||||
int finalMask = bitMask != 0 ? bitMask : lightUpdate ? set.getBitMask() : 0;
|
||||
boolean finalLightUpdate = lightUpdate;
|
||||
callback = () -> {
|
||||
// Set Modified
|
||||
nmsChunk.setLightCorrect(true); // Set Modified
|
||||
@ -932,7 +938,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
|
||||
@Override
|
||||
public void send() {
|
||||
PaperweightPlatformAdapter.sendChunk(this, serverLevel, chunkX, chunkZ);
|
||||
PaperweightPlatformAdapter.sendChunk(new IntPair(chunkX, chunkZ), serverLevel, chunkX, chunkZ);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7,8 +7,8 @@ import com.fastasyncworldedit.bukkit.adapter.NMSAdapter;
|
||||
import com.fastasyncworldedit.core.Fawe;
|
||||
import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.math.BitArrayUnstretched;
|
||||
import com.fastasyncworldedit.core.math.IntPair;
|
||||
import com.fastasyncworldedit.core.util.MathMan;
|
||||
import com.fastasyncworldedit.core.util.ReflectionUtils;
|
||||
import com.fastasyncworldedit.core.util.TaskManager;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
@ -243,15 +243,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
}
|
||||
|
||||
static boolean setSectionAtomic(
|
||||
String worldName,
|
||||
IntPair pair,
|
||||
LevelChunkSection[] sections,
|
||||
LevelChunkSection expected,
|
||||
LevelChunkSection value,
|
||||
int layer
|
||||
) {
|
||||
if (layer >= 0 && layer < sections.length) {
|
||||
return ReflectionUtils.compareAndSet(sections, expected, value, layer);
|
||||
}
|
||||
return false;
|
||||
return NMSAdapter.setSectionAtomic(worldName, pair, sections, expected, value, layer);
|
||||
}
|
||||
|
||||
// There is no point in having a functional semaphore for paper servers.
|
||||
@ -349,7 +348,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void sendChunk(Object chunk, ServerLevel nmsWorld, int chunkX, int chunkZ) {
|
||||
public static void sendChunk(IntPair pair, ServerLevel nmsWorld, int chunkX, int chunkZ) {
|
||||
ChunkHolder chunkHolder = getPlayerChunk(nmsWorld, chunkX, chunkZ);
|
||||
if (chunkHolder == null) {
|
||||
return;
|
||||
@ -370,26 +369,35 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
if (levelChunk == null) {
|
||||
return;
|
||||
}
|
||||
StampLockHolder lockHolder = new StampLockHolder();
|
||||
NMSAdapter.beginChunkPacketSend(nmsWorld.getWorld().getName(), pair, lockHolder);
|
||||
if (lockHolder.chunkLock == null) {
|
||||
return;
|
||||
}
|
||||
MinecraftServer.getServer().execute(() -> {
|
||||
ClientboundLevelChunkWithLightPacket packet;
|
||||
if (PaperLib.isPaper()) {
|
||||
packet = new ClientboundLevelChunkWithLightPacket(
|
||||
levelChunk,
|
||||
nmsWorld.getChunkSource().getLightEngine(),
|
||||
null,
|
||||
null,
|
||||
false // last false is to not bother with x-ray
|
||||
);
|
||||
} else {
|
||||
// deprecated on paper - deprecation suppressed
|
||||
packet = new ClientboundLevelChunkWithLightPacket(
|
||||
levelChunk,
|
||||
nmsWorld.getChunkSource().getLightEngine(),
|
||||
null,
|
||||
null
|
||||
);
|
||||
try {
|
||||
ClientboundLevelChunkWithLightPacket packet;
|
||||
if (PaperLib.isPaper()) {
|
||||
packet = new ClientboundLevelChunkWithLightPacket(
|
||||
levelChunk,
|
||||
nmsWorld.getChunkSource().getLightEngine(),
|
||||
null,
|
||||
null,
|
||||
false // last false is to not bother with x-ray
|
||||
);
|
||||
} else {
|
||||
// deprecated on paper - deprecation suppressed
|
||||
packet = new ClientboundLevelChunkWithLightPacket(
|
||||
levelChunk,
|
||||
nmsWorld.getChunkSource().getLightEngine(),
|
||||
null,
|
||||
null
|
||||
);
|
||||
}
|
||||
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
|
||||
} finally {
|
||||
NMSAdapter.endChunkPacketSend(nmsWorld.getWorld().getName(), pair, lockHolder);
|
||||
}
|
||||
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R3;
|
||||
|
||||
import com.fastasyncworldedit.bukkit.adapter.StarlightRelighter;
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.math.IntPair;
|
||||
import com.fastasyncworldedit.core.queue.IQueueExtent;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
@ -67,7 +68,7 @@ public class PaperweightStarlightRelighter extends StarlightRelighter<ServerLeve
|
||||
int x = pos.x;
|
||||
int z = pos.z;
|
||||
if (delay) { // we still need to send the block changes of that chunk
|
||||
PaperweightPlatformAdapter.sendChunk(pos, serverLevel, x, z);
|
||||
PaperweightPlatformAdapter.sendChunk(new IntPair(x, z), serverLevel, x, z);
|
||||
}
|
||||
serverLevel.getChunkSource().removeTicketAtLevel(FAWE_TICKET, pos, LIGHT_LEVEL, Unit.INSTANCE);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType;
|
||||
import com.fastasyncworldedit.core.math.BitArrayUnstretched;
|
||||
import com.fastasyncworldedit.core.math.IntPair;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||
import com.fastasyncworldedit.core.queue.IChunkSet;
|
||||
@ -107,6 +108,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
private final ServerLevel serverLevel;
|
||||
private final int chunkX;
|
||||
private final int chunkZ;
|
||||
private final IntPair chunkPos;
|
||||
private final int minHeight;
|
||||
private final int maxHeight;
|
||||
private final int minSectionPosition;
|
||||
@ -141,6 +143,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
this.blockLight = new DataLayer[getSectionCount()];
|
||||
this.biomeRegistry = serverLevel.registryAccess().registryOrThrow(BIOME);
|
||||
this.biomeHolderIdMap = biomeRegistry.asHolderIdMap();
|
||||
this.chunkPos = new IntPair(chunkX, chunkZ);
|
||||
}
|
||||
|
||||
public int getChunkX() {
|
||||
@ -426,7 +429,8 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
throw new IllegalStateException("Attempted to call chunk GET but chunk was not call-locked.");
|
||||
}
|
||||
forceLoadSections = false;
|
||||
PaperweightGetBlocks_Copy copy = createCopy ? new PaperweightGetBlocks_Copy(levelChunk) : null;
|
||||
LevelChunk nmsChunk = ensureLoaded(serverLevel, chunkX, chunkZ);
|
||||
PaperweightGetBlocks_Copy copy = createCopy ? new PaperweightGetBlocks_Copy(nmsChunk) : null;
|
||||
if (createCopy) {
|
||||
if (copies.containsKey(copyKey)) {
|
||||
throw new IllegalStateException("Copy key already used.");
|
||||
@ -434,9 +438,6 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
copies.put(copyKey, copy);
|
||||
}
|
||||
try {
|
||||
ServerLevel nmsWorld = serverLevel;
|
||||
LevelChunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ);
|
||||
|
||||
// Remove existing tiles. Create a copy so that we can remove blocks
|
||||
Map<BlockPos, BlockEntity> chunkTiles = new HashMap<>(nmsChunk.getBlockEntities());
|
||||
List<BlockEntity> beacons = null;
|
||||
@ -508,6 +509,8 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
biomeData
|
||||
);
|
||||
if (PaperweightPlatformAdapter.setSectionAtomic(
|
||||
serverLevel.getWorld().getName(),
|
||||
chunkPos,
|
||||
levelChunkSections,
|
||||
null,
|
||||
newSection,
|
||||
@ -585,6 +588,8 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
biomeData
|
||||
);
|
||||
if (PaperweightPlatformAdapter.setSectionAtomic(
|
||||
serverLevel.getWorld().getName(),
|
||||
chunkPos,
|
||||
levelChunkSections,
|
||||
null,
|
||||
newSection,
|
||||
@ -649,7 +654,11 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
biomeRegistry,
|
||||
biomeData != null ? biomeData : (PalettedContainer<Holder<Biome>>) existingSection.getBiomes()
|
||||
);
|
||||
if (!PaperweightPlatformAdapter.setSectionAtomic(levelChunkSections, existingSection,
|
||||
if (!PaperweightPlatformAdapter.setSectionAtomic(
|
||||
serverLevel.getWorld().getName(),
|
||||
chunkPos,
|
||||
levelChunkSections,
|
||||
existingSection,
|
||||
newSection,
|
||||
getSectionIndex
|
||||
)) {
|
||||
@ -721,7 +730,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
}
|
||||
if (Settings.settings().EXPERIMENTAL.REMOVE_ENTITY_FROM_WORLD_ON_CHUNK_FAIL) {
|
||||
for (UUID uuid : entityRemoves) {
|
||||
Entity entity = nmsWorld.getEntities().get(uuid);
|
||||
Entity entity = serverLevel.getEntities().get(uuid);
|
||||
if (entity != null) {
|
||||
removeEntity(entity);
|
||||
}
|
||||
@ -760,7 +769,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
|
||||
EntityType<?> type = EntityType.byString(id).orElse(null);
|
||||
if (type != null) {
|
||||
Entity entity = type.create(nmsWorld);
|
||||
Entity entity = type.create(serverLevel);
|
||||
if (entity != null) {
|
||||
final net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(linTag);
|
||||
for (final String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
|
||||
@ -769,11 +778,11 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
entity.load(tag);
|
||||
entity.absMoveTo(x, y, z, yaw, pitch);
|
||||
entity.setUUID(NbtUtils.uuid(nativeTag));
|
||||
if (!nmsWorld.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM)) {
|
||||
if (!serverLevel.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM)) {
|
||||
LOGGER.warn(
|
||||
"Error creating entity of type `{}` in world `{}` at location `{},{},{}`",
|
||||
id,
|
||||
nmsWorld.getWorld().getName(),
|
||||
serverLevel.getWorld().getName(),
|
||||
x,
|
||||
y,
|
||||
z
|
||||
@ -803,11 +812,11 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
final int z = blockHash.z() + bz;
|
||||
final BlockPos pos = new BlockPos(x, y, z);
|
||||
|
||||
synchronized (nmsWorld) {
|
||||
BlockEntity tileEntity = nmsWorld.getBlockEntity(pos);
|
||||
synchronized (serverLevel) {
|
||||
BlockEntity tileEntity = serverLevel.getBlockEntity(pos);
|
||||
if (tileEntity == null || tileEntity.isRemoved()) {
|
||||
nmsWorld.removeBlockEntity(pos);
|
||||
tileEntity = nmsWorld.getBlockEntity(pos);
|
||||
serverLevel.removeBlockEntity(pos);
|
||||
tileEntity = serverLevel.getBlockEntity(pos);
|
||||
}
|
||||
if (tileEntity != null) {
|
||||
final net.minecraft.nbt.CompoundTag tag = (CompoundTag) adapter.fromNativeLin(nativeTag.linTag());
|
||||
@ -826,7 +835,6 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
callback = null;
|
||||
} else {
|
||||
int finalMask = bitMask != 0 ? bitMask : lightUpdate ? set.getBitMask() : 0;
|
||||
boolean finalLightUpdate = lightUpdate;
|
||||
callback = () -> {
|
||||
// Set Modified
|
||||
nmsChunk.setLightCorrect(true); // Set Modified
|
||||
@ -932,7 +940,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
@Override
|
||||
public void send() {
|
||||
synchronized (sendLock) {
|
||||
PaperweightPlatformAdapter.sendChunk(this, serverLevel, chunkX, chunkZ);
|
||||
PaperweightPlatformAdapter.sendChunk(new IntPair(chunkX, chunkZ), serverLevel, chunkX, chunkZ);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,9 +7,10 @@ import com.fastasyncworldedit.bukkit.adapter.NMSAdapter;
|
||||
import com.fastasyncworldedit.core.Fawe;
|
||||
import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.math.BitArrayUnstretched;
|
||||
import com.fastasyncworldedit.core.math.IntPair;
|
||||
import com.fastasyncworldedit.core.util.MathMan;
|
||||
import com.fastasyncworldedit.core.util.ReflectionUtils;
|
||||
import com.fastasyncworldedit.core.util.TaskManager;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
||||
@ -76,6 +77,7 @@ import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -241,15 +243,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
}
|
||||
|
||||
static boolean setSectionAtomic(
|
||||
String worldName,
|
||||
IntPair pair,
|
||||
LevelChunkSection[] sections,
|
||||
LevelChunkSection expected,
|
||||
LevelChunkSection value,
|
||||
int layer
|
||||
) {
|
||||
if (layer >= 0 && layer < sections.length) {
|
||||
return ReflectionUtils.compareAndSet(sections, expected, value, layer);
|
||||
}
|
||||
return false;
|
||||
return NMSAdapter.setSectionAtomic(worldName, pair, sections, expected, value, layer);
|
||||
}
|
||||
|
||||
// There is no point in having a functional semaphore for paper servers.
|
||||
@ -347,7 +348,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void sendChunk(Object chunk, ServerLevel nmsWorld, int chunkX, int chunkZ) {
|
||||
public static void sendChunk(IntPair pair, ServerLevel nmsWorld, int chunkX, int chunkZ) {
|
||||
ChunkHolder chunkHolder = getPlayerChunk(nmsWorld, chunkX, chunkZ);
|
||||
if (chunkHolder == null) {
|
||||
return;
|
||||
@ -360,32 +361,43 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
.getChunkSource()
|
||||
.getChunkAtIfLoadedImmediately(chunkX, chunkZ);
|
||||
} else {
|
||||
levelChunk = chunkHolder.getTickingChunkFuture()
|
||||
.getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK).orElse(null);
|
||||
levelChunk = ((Optional<LevelChunk>) ((Either) chunkHolder
|
||||
.getTickingChunkFuture() // method is not present with new paper chunk system
|
||||
.getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left())
|
||||
.orElse(null);
|
||||
}
|
||||
if (levelChunk == null) {
|
||||
return;
|
||||
}
|
||||
StampLockHolder lockHolder = new StampLockHolder();
|
||||
NMSAdapter.beginChunkPacketSend(nmsWorld.getWorld().getName(), pair, lockHolder);
|
||||
if (lockHolder.chunkLock == null) {
|
||||
return;
|
||||
}
|
||||
MinecraftServer.getServer().execute(() -> {
|
||||
ClientboundLevelChunkWithLightPacket packet;
|
||||
if (PaperLib.isPaper()) {
|
||||
packet = new ClientboundLevelChunkWithLightPacket(
|
||||
levelChunk,
|
||||
nmsWorld.getChunkSource().getLightEngine(),
|
||||
null,
|
||||
null,
|
||||
false // last false is to not bother with x-ray
|
||||
);
|
||||
} else {
|
||||
// deprecated on paper - deprecation suppressed
|
||||
packet = new ClientboundLevelChunkWithLightPacket(
|
||||
levelChunk,
|
||||
nmsWorld.getChunkSource().getLightEngine(),
|
||||
null,
|
||||
null
|
||||
);
|
||||
try {
|
||||
ClientboundLevelChunkWithLightPacket packet;
|
||||
if (PaperLib.isPaper()) {
|
||||
packet = new ClientboundLevelChunkWithLightPacket(
|
||||
levelChunk,
|
||||
nmsWorld.getChunkSource().getLightEngine(),
|
||||
null,
|
||||
null,
|
||||
false // last false is to not bother with x-ray
|
||||
);
|
||||
} else {
|
||||
// deprecated on paper - deprecation suppressed
|
||||
packet = new ClientboundLevelChunkWithLightPacket(
|
||||
levelChunk,
|
||||
nmsWorld.getChunkSource().getLightEngine(),
|
||||
null,
|
||||
null
|
||||
);
|
||||
}
|
||||
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
|
||||
} finally {
|
||||
NMSAdapter.endChunkPacketSend(nmsWorld.getWorld().getName(), pair, lockHolder);
|
||||
}
|
||||
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
|
||||
|
||||
import com.fastasyncworldedit.bukkit.adapter.StarlightRelighter;
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.math.IntPair;
|
||||
import com.fastasyncworldedit.core.queue.IQueueExtent;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
@ -67,7 +68,7 @@ public class PaperweightStarlightRelighter extends StarlightRelighter<ServerLeve
|
||||
int x = pos.x;
|
||||
int z = pos.z;
|
||||
if (delay) { // we still need to send the block changes of that chunk
|
||||
PaperweightPlatformAdapter.sendChunk(pos, serverLevel, x, z);
|
||||
PaperweightPlatformAdapter.sendChunk(new IntPair(x, z), serverLevel, x, z);
|
||||
}
|
||||
serverLevel.getChunkSource().removeTicketAtLevel(FAWE_TICKET, pos, LIGHT_LEVEL, Unit.INSTANCE);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType;
|
||||
import com.fastasyncworldedit.core.math.BitArrayUnstretched;
|
||||
import com.fastasyncworldedit.core.math.IntPair;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||
import com.fastasyncworldedit.core.queue.IChunkSet;
|
||||
@ -107,6 +108,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
private final ServerLevel serverLevel;
|
||||
private final int chunkX;
|
||||
private final int chunkZ;
|
||||
private final IntPair chunkPos;
|
||||
private final int minHeight;
|
||||
private final int maxHeight;
|
||||
private final int minSectionPosition;
|
||||
@ -141,6 +143,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
this.blockLight = new DataLayer[getSectionCount()];
|
||||
this.biomeRegistry = serverLevel.registryAccess().registryOrThrow(BIOME);
|
||||
this.biomeHolderIdMap = biomeRegistry.asHolderIdMap();
|
||||
this.chunkPos = new IntPair(chunkX, chunkZ);
|
||||
}
|
||||
|
||||
public int getChunkX() {
|
||||
@ -427,7 +430,8 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
throw new IllegalStateException("Attempted to call chunk GET but chunk was not call-locked.");
|
||||
}
|
||||
forceLoadSections = false;
|
||||
PaperweightGetBlocks_Copy copy = createCopy ? new PaperweightGetBlocks_Copy(levelChunk) : null;
|
||||
LevelChunk nmsChunk = ensureLoaded(serverLevel, chunkX, chunkZ);
|
||||
PaperweightGetBlocks_Copy copy = createCopy ? new PaperweightGetBlocks_Copy(nmsChunk) : null;
|
||||
if (createCopy) {
|
||||
if (copies.containsKey(copyKey)) {
|
||||
throw new IllegalStateException("Copy key already used.");
|
||||
@ -435,9 +439,6 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
copies.put(copyKey, copy);
|
||||
}
|
||||
try {
|
||||
ServerLevel nmsWorld = serverLevel;
|
||||
LevelChunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ);
|
||||
|
||||
// Remove existing tiles. Create a copy so that we can remove blocks
|
||||
Map<BlockPos, BlockEntity> chunkTiles = new HashMap<>(nmsChunk.getBlockEntities());
|
||||
List<BlockEntity> beacons = null;
|
||||
@ -509,6 +510,8 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
biomeData
|
||||
);
|
||||
if (PaperweightPlatformAdapter.setSectionAtomic(
|
||||
serverLevel.getWorld().getName(),
|
||||
chunkPos,
|
||||
levelChunkSections,
|
||||
null,
|
||||
newSection,
|
||||
@ -583,6 +586,8 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
biomeData
|
||||
);
|
||||
if (PaperweightPlatformAdapter.setSectionAtomic(
|
||||
serverLevel.getWorld().getName(),
|
||||
chunkPos,
|
||||
levelChunkSections,
|
||||
null,
|
||||
newSection,
|
||||
@ -644,7 +649,11 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
biomeRegistry,
|
||||
biomeData != null ? biomeData : (PalettedContainer<Holder<Biome>>) existingSection.getBiomes()
|
||||
);
|
||||
if (!PaperweightPlatformAdapter.setSectionAtomic(levelChunkSections, existingSection,
|
||||
if (!PaperweightPlatformAdapter.setSectionAtomic(
|
||||
serverLevel.getWorld().getName(),
|
||||
chunkPos,
|
||||
levelChunkSections,
|
||||
existingSection,
|
||||
newSection,
|
||||
getSectionIndex
|
||||
)) {
|
||||
@ -716,7 +725,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
}
|
||||
if (Settings.settings().EXPERIMENTAL.REMOVE_ENTITY_FROM_WORLD_ON_CHUNK_FAIL) {
|
||||
for (UUID uuid : entityRemoves) {
|
||||
Entity entity = nmsWorld.getEntities().get(uuid);
|
||||
Entity entity = serverLevel.getEntities().get(uuid);
|
||||
if (entity != null) {
|
||||
removeEntity(entity);
|
||||
}
|
||||
@ -755,7 +764,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
|
||||
EntityType<?> type = EntityType.byString(id).orElse(null);
|
||||
if (type != null) {
|
||||
Entity entity = type.create(nmsWorld);
|
||||
Entity entity = type.create(serverLevel);
|
||||
if (entity != null) {
|
||||
final CompoundTag tag = (CompoundTag) adapter.fromNativeLin(linTag);
|
||||
for (final String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
|
||||
@ -764,11 +773,11 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
entity.load(tag);
|
||||
entity.absMoveTo(x, y, z, yaw, pitch);
|
||||
entity.setUUID(NbtUtils.uuid(nativeTag));
|
||||
if (!nmsWorld.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM)) {
|
||||
if (!serverLevel.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM)) {
|
||||
LOGGER.warn(
|
||||
"Error creating entity of type `{}` in world `{}` at location `{},{},{}`",
|
||||
id,
|
||||
nmsWorld.getWorld().getName(),
|
||||
serverLevel.getWorld().getName(),
|
||||
x,
|
||||
y,
|
||||
z
|
||||
@ -798,11 +807,11 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
final int z = blockHash.z() + bz;
|
||||
final BlockPos pos = new BlockPos(x, y, z);
|
||||
|
||||
synchronized (nmsWorld) {
|
||||
BlockEntity tileEntity = nmsWorld.getBlockEntity(pos);
|
||||
synchronized (serverLevel) {
|
||||
BlockEntity tileEntity = serverLevel.getBlockEntity(pos);
|
||||
if (tileEntity == null || tileEntity.isRemoved()) {
|
||||
nmsWorld.removeBlockEntity(pos);
|
||||
tileEntity = nmsWorld.getBlockEntity(pos);
|
||||
serverLevel.removeBlockEntity(pos);
|
||||
tileEntity = serverLevel.getBlockEntity(pos);
|
||||
}
|
||||
if (tileEntity != null) {
|
||||
final CompoundTag tag = (CompoundTag) adapter.fromNativeLin(nativeTag.linTag());
|
||||
@ -821,7 +830,6 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
callback = null;
|
||||
} else {
|
||||
int finalMask = bitMask != 0 ? bitMask : lightUpdate ? set.getBitMask() : 0;
|
||||
boolean finalLightUpdate = lightUpdate;
|
||||
callback = () -> {
|
||||
// Set Modified
|
||||
nmsChunk.setLightCorrect(true); // Set Modified
|
||||
@ -927,7 +935,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
@Override
|
||||
public void send() {
|
||||
synchronized (sendLock) {
|
||||
PaperweightPlatformAdapter.sendChunk(this, serverLevel, chunkX, chunkZ);
|
||||
PaperweightPlatformAdapter.sendChunk(new IntPair(chunkX, chunkZ), serverLevel, chunkX, chunkZ);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,9 +8,10 @@ import com.fastasyncworldedit.bukkit.adapter.NMSAdapter;
|
||||
import com.fastasyncworldedit.core.Fawe;
|
||||
import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.math.BitArrayUnstretched;
|
||||
import com.fastasyncworldedit.core.math.IntPair;
|
||||
import com.fastasyncworldedit.core.util.MathMan;
|
||||
import com.fastasyncworldedit.core.util.ReflectionUtils;
|
||||
import com.fastasyncworldedit.core.util.TaskManager;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
||||
@ -31,7 +32,6 @@ import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.BitStorage;
|
||||
import net.minecraft.util.ExceptionCollector;
|
||||
import net.minecraft.util.SimpleBitStorage;
|
||||
import net.minecraft.util.ThreadingDetector;
|
||||
import net.minecraft.util.Unit;
|
||||
@ -76,6 +76,7 @@ import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -226,15 +227,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
}
|
||||
|
||||
static boolean setSectionAtomic(
|
||||
String worldName,
|
||||
IntPair pair,
|
||||
LevelChunkSection[] sections,
|
||||
LevelChunkSection expected,
|
||||
LevelChunkSection value,
|
||||
int layer
|
||||
) {
|
||||
if (layer >= 0 && layer < sections.length) {
|
||||
return ReflectionUtils.compareAndSet(sections, expected, value, layer);
|
||||
}
|
||||
return false;
|
||||
return NMSAdapter.setSectionAtomic(worldName, pair, sections, expected, value, layer);
|
||||
}
|
||||
|
||||
// There is no point in having a functional semaphore for paper servers.
|
||||
@ -332,7 +332,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void sendChunk(Object chunk, ServerLevel nmsWorld, int chunkX, int chunkZ) {
|
||||
public static void sendChunk(IntPair pair, ServerLevel nmsWorld, int chunkX, int chunkZ) {
|
||||
ChunkHolder chunkHolder = getPlayerChunk(nmsWorld, chunkX, chunkZ);
|
||||
if (chunkHolder == null) {
|
||||
return;
|
||||
@ -345,32 +345,43 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
.getChunkSource()
|
||||
.getChunkAtIfLoadedImmediately(chunkX, chunkZ);
|
||||
} else {
|
||||
levelChunk = chunkHolder.getTickingChunkFuture()
|
||||
.getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK).orElse(null);
|
||||
levelChunk = ((Optional<LevelChunk>) ((Either) chunkHolder
|
||||
.getTickingChunkFuture() // method is not present with new paper chunk system
|
||||
.getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left())
|
||||
.orElse(null);
|
||||
}
|
||||
if (levelChunk == null) {
|
||||
return;
|
||||
}
|
||||
StampLockHolder lockHolder = new StampLockHolder();
|
||||
NMSAdapter.beginChunkPacketSend(nmsWorld.getWorld().getName(), pair, lockHolder);
|
||||
if (lockHolder.chunkLock == null) {
|
||||
return;
|
||||
}
|
||||
MinecraftServer.getServer().execute(() -> {
|
||||
ClientboundLevelChunkWithLightPacket packet;
|
||||
if (PaperLib.isPaper()) {
|
||||
packet = new ClientboundLevelChunkWithLightPacket(
|
||||
levelChunk,
|
||||
nmsWorld.getChunkSource().getLightEngine(),
|
||||
null,
|
||||
null,
|
||||
false // last false is to not bother with x-ray
|
||||
);
|
||||
} else {
|
||||
// deprecated on paper - deprecation suppressed
|
||||
packet = new ClientboundLevelChunkWithLightPacket(
|
||||
levelChunk,
|
||||
nmsWorld.getChunkSource().getLightEngine(),
|
||||
null,
|
||||
null
|
||||
);
|
||||
try {
|
||||
ClientboundLevelChunkWithLightPacket packet;
|
||||
if (PaperLib.isPaper()) {
|
||||
packet = new ClientboundLevelChunkWithLightPacket(
|
||||
levelChunk,
|
||||
nmsWorld.getChunkSource().getLightEngine(),
|
||||
null,
|
||||
null,
|
||||
false // last false is to not bother with x-ray
|
||||
);
|
||||
} else {
|
||||
// deprecated on paper - deprecation suppressed
|
||||
packet = new ClientboundLevelChunkWithLightPacket(
|
||||
levelChunk,
|
||||
nmsWorld.getChunkSource().getLightEngine(),
|
||||
null,
|
||||
null
|
||||
);
|
||||
}
|
||||
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
|
||||
} finally {
|
||||
NMSAdapter.endChunkPacketSend(nmsWorld.getWorld().getName(), pair, lockHolder);
|
||||
}
|
||||
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1;
|
||||
|
||||
import com.fastasyncworldedit.bukkit.adapter.StarlightRelighter;
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.math.IntPair;
|
||||
import com.fastasyncworldedit.core.queue.IQueueExtent;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
@ -70,7 +71,7 @@ public class PaperweightStarlightRelighter extends StarlightRelighter<ServerLeve
|
||||
int x = pos.x;
|
||||
int z = pos.z;
|
||||
if (delay) { // we still need to send the block changes of that chunk
|
||||
PaperweightPlatformAdapter.sendChunk(pos, serverLevel, x, z);
|
||||
PaperweightPlatformAdapter.sendChunk(new IntPair(x, z), serverLevel, x, z);
|
||||
}
|
||||
serverLevel.getChunkSource().removeTicketAtLevel(FAWE_TICKET, pos, LIGHT_LEVEL, Unit.INSTANCE);
|
||||
}
|
||||
|
Reference in New Issue
Block a user