3
0
Mirror von https://github.com/IntellectualSites/FastAsyncWorldEdit.git synchronisiert 2024-11-19 17:30:08 +01:00

Merge branch 'main' into feat/improved-entity-operations

Dieser Commit ist enthalten in:
Jordan 2023-10-14 20:34:28 +01:00 committet von GitHub
Commit 2a45fcde38
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 4AEE18F83AFDEB23
33 geänderte Dateien mit 222 neuen und 73 gelöschten Zeilen

Datei anzeigen

@ -34,7 +34,7 @@ logger.lifecycle("""
*******************************************
""")
var rootVersion by extra("2.8.1")
var rootVersion by extra("2.8.2")
var snapshot by extra("SNAPSHOT")
var revision: String by extra("")
var buildNumber by extra("")

Datei anzeigen

@ -241,8 +241,9 @@ fun Project.applyLibrariesConfiguration() {
scm {
url.set("https://github.com/IntellectualSites/FastAsyncWorldEdit")
connection.set("scm:https://IntellectualSites@github.com/IntellectualSites/FastAsyncWorldEdit.git")
developerConnection.set("scm:git://github.com/IntellectualSites/FastAsyncWorldEdit.git")
connection.set("scm:git:https://github.com/IntellectualSites/FastAsyncWorldEdit.git")
developerConnection.set("scm:git:git@github.com:IntellectualSites/FastAsyncWorldEdit.git")
tag.set("${project.version}")
}
issueManagement {

Datei anzeigen

@ -87,23 +87,27 @@ fun Project.applyPlatformAndCoreConfiguration() {
name.set("Alexander Brandes")
email.set("contact(at)notmyfault.dev")
organization.set("IntellectualSites")
organizationUrl.set("https://github.com/IntellectualSites")
}
developer {
id.set("SirYwell")
name.set("Hannes Greule")
organization.set("IntellectualSites")
organizationUrl.set("https://github.com/IntellectualSites")
}
developer {
id.set("dordsor21")
name.set("dordsor21")
organization.set("IntellectualSites")
organizationUrl.set("https://github.com/IntellectualSites")
}
}
scm {
url.set("https://github.com/IntellectualSites/FastAsyncWorldEdit")
connection.set("scm:https://IntellectualSites@github.com/IntellectualSites/FastAsyncWorldEdit.git")
developerConnection.set("scm:git://github.com/IntellectualSites/FastAsyncWorldEdit.git")
connection.set("scm:git:https://github.com/IntellectualSites/FastAsyncWorldEdit.git")
developerConnection.set("scm:git:git@github.com:IntellectualSites/FastAsyncWorldEdit.git")
tag.set("${project.version}")
}
issueManagement{

Datei anzeigen

@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT"
griefprevention = "16.18.1"
griefdefender = "2.1.0-SNAPSHOT"
residence = "4.5._13.1"
towny = "0.99.5.20"
towny = "0.99.6.0"
plotsquared = "7.0.0"
# Third party
@ -23,9 +23,9 @@ sparsebitset = "1.3"
parallelgzip = "1.0.5"
adventure = "4.14.0"
adventure-bukkit = "4.3.1"
checkerqual = "3.38.0"
checkerqual = "3.39.0"
truezip = "6.8.4"
auto-value = "1.10.2"
auto-value = "1.10.4"
findbugs = "3.0.2"
rhino-runtime = "1.7.14"
zstd-jni = "1.4.8-1" # Not latest as it can be difficult to obtain latest ZSTD libs
@ -46,7 +46,7 @@ text = "3.0.4"
piston = "0.5.7"
# Tests
mockito = "5.5.0"
mockito = "5.6.0"
# Gradle plugins
pluginyml = "0.6.0"

Datei anzeigen

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

14
gradlew vendored
Datei anzeigen

@ -145,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
@ -153,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@ -202,11 +202,11 @@ fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \

Datei anzeigen

@ -38,6 +38,7 @@ import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.Refraction;
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2.PaperweightFaweAdapter;
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2.PaperweightPlatformAdapter;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.extension.platform.Watchdog;
import com.sk89q.worldedit.extent.Extent;
@ -288,7 +289,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
* @param tag the tag
*/
private static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag tag) {
entity.save(tag);
//FAWE start - avoid villager async catcher
PaperweightPlatformAdapter.readEntityIntoTag(entity, tag);
//FAWE end
}
private static Block getBlockFromType(BlockType blockType) {

Datei anzeigen

@ -135,10 +135,6 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
return resourceLocation == null ? null : resourceLocation.toString();
}
private static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag compoundTag) {
entity.save(compoundTag);
}
@Override
public BukkitImplAdapter<net.minecraft.nbt.Tag> getParent() {
return parent;
@ -367,7 +363,7 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id);
Supplier<CompoundBinaryTag> saveTag = () -> {
final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag();
readEntityIntoTag(mcEntity, minecraftTag);
PaperweightPlatformAdapter.readEntityIntoTag(mcEntity, minecraftTag);
//add Id for AbstractChangeSet to work
final CompoundBinaryTag tag = (CompoundBinaryTag) toNativeBinary(minecraftTag);
final Map<String, BinaryTag> tags = NbtUtils.getCompoundBinaryTagValues(tag);

Datei anzeigen

@ -378,7 +378,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
public Iterator<CompoundTag> iterator() {
Iterable<CompoundTag> result = entities.stream().map(input -> {
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
input.save(tag);
PaperweightPlatformAdapter.readEntityIntoTag(input, tag);
return (CompoundTag) adapter.toNative(tag);
}).collect(Collectors.toList());
return result.iterator();
@ -445,7 +445,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
@SuppressWarnings("rawtypes")
public synchronized <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
forceLoadSections = false;
copy = createCopy ? new PaperweightGetBlocks_Copy(levelChunk) : null;
copy = createCopy ? new PaperweightGetBlocks_Copy(getChunk()) : null;
try {
ServerLevel nmsWorld = serverLevel;
LevelChunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ);

Datei anzeigen

@ -78,7 +78,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
protected void storeEntity(Entity entity) {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
net.minecraft.nbt.CompoundTag compoundTag = new net.minecraft.nbt.CompoundTag();
entity.save(compoundTag);
PaperweightPlatformAdapter.readEntityIntoTag(entity, compoundTag);
entities.add((CompoundTag) adapter.toNative(compoundTag));
}

Datei anzeigen

@ -34,6 +34,8 @@ import net.minecraft.server.level.TicketType;
import net.minecraft.util.BitStorage;
import net.minecraft.util.Unit;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.npc.AbstractVillager;
import net.minecraft.world.item.trading.MerchantOffers;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.biome.Biome;
@ -90,6 +92,9 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
private static final Field fieldGameEventDispatcherSections;
private static final MethodHandle methodremoveBlockEntityTicker;
private static final Field fieldOffers;
private static final MerchantOffers OFFERS = new MerchantOffers();
private static final Field fieldRemove;
private static final Logger LOGGER = LogManagerCompat.getLogger();
@ -145,6 +150,9 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
fieldRemove = BlockEntity.class.getDeclaredField(Refraction.pickName("remove", "p"));
fieldRemove.setAccessible(true);
fieldOffers = AbstractVillager.class.getDeclaredField(Refraction.pickName("offers", "bU"));
fieldOffers.setAccessible(true);
} catch (RuntimeException e) {
throw e;
} catch (Throwable rethrow) {
@ -492,4 +500,27 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
return chunk.level.entityManager.getEntities(chunk.getPos());
}
public static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag compoundTag) {
boolean isVillager = entity instanceof AbstractVillager && !Fawe.isMainThread();
boolean unset = false;
if (isVillager) {
try {
if (fieldOffers.get(entity) != null) {
fieldOffers.set(entity, OFFERS);
unset = true;
}
} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to set offers field to villager to avoid async catcher.", e);
}
}
entity.save(compoundTag);
if (unset) {
try {
fieldOffers.set(entity, null);
} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to set offers field to null again on villager.", e);
}
}
}
}

Datei anzeigen

@ -34,6 +34,7 @@ import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.Refraction;
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.PaperweightPlatformAdapter;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.extension.platform.Watchdog;
import com.sk89q.worldedit.extent.Extent;
@ -270,7 +271,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
* @param tag the tag
*/
private static void readTagIntoEntity(net.minecraft.nbt.CompoundTag tag, Entity entity) {
entity.load(tag);
//FAWE start - avoid villager async catcher
PaperweightPlatformAdapter.readEntityIntoTag(entity, tag);
//FAWE end
}
/**

Datei anzeigen

@ -136,10 +136,6 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
return resourceLocation == null ? null : resourceLocation.toString();
}
private static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag compoundTag) {
entity.save(compoundTag);
}
@Override
public BukkitImplAdapter<net.minecraft.nbt.Tag> getParent() {
return parent;
@ -360,7 +356,7 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id);
Supplier<CompoundBinaryTag> saveTag = () -> {
final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag();
readEntityIntoTag(mcEntity, minecraftTag);
PaperweightPlatformAdapter.readEntityIntoTag(mcEntity, minecraftTag);
//add Id for AbstractChangeSet to work
final CompoundBinaryTag tag = (CompoundBinaryTag) toNativeBinary(minecraftTag);
final Map<String, BinaryTag> tags = NbtUtils.getCompoundBinaryTagValues(tag);

Datei anzeigen

@ -369,7 +369,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
public Iterator<CompoundTag> iterator() {
Iterable<CompoundTag> result = entities.stream().map(input -> {
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
input.save(tag);
PaperweightPlatformAdapter.readEntityIntoTag(input, tag);
return (CompoundTag) adapter.toNative(tag);
}).collect(Collectors.toList());
return result.iterator();
@ -434,7 +434,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
@SuppressWarnings("rawtypes")
public synchronized <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
forceLoadSections = false;
copy = createCopy ? new PaperweightGetBlocks_Copy(levelChunk) : null;
copy = createCopy ? new PaperweightGetBlocks_Copy(getChunk()) : null;
try {
ServerLevel nmsWorld = serverLevel;
LevelChunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ);

Datei anzeigen

@ -80,7 +80,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
protected void storeEntity(Entity entity) {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
net.minecraft.nbt.CompoundTag compoundTag = new net.minecraft.nbt.CompoundTag();
entity.save(compoundTag);
PaperweightPlatformAdapter.readEntityIntoTag(entity, compoundTag);
entities.add((CompoundTag) adapter.toNative(compoundTag));
}

Datei anzeigen

@ -35,6 +35,8 @@ import net.minecraft.util.ThreadingDetector;
import net.minecraft.util.Unit;
import net.minecraft.util.ZeroBitStorage;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.npc.AbstractVillager;
import net.minecraft.world.item.trading.MerchantOffers;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.biome.Biome;
@ -98,6 +100,9 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
private static final MethodHandle methodRemoveGameEventListener;
private static final MethodHandle methodremoveTickingBlockEntity;
private static final Field fieldOffers;
private static final MerchantOffers OFFERS = new MerchantOffers();
private static final Field fieldRemove;
private static final Logger LOGGER = LogManagerCompat.getLogger();
@ -158,6 +163,9 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
fieldRemove = BlockEntity.class.getDeclaredField(Refraction.pickName("remove", "p"));
fieldRemove.setAccessible(true);
fieldOffers = AbstractVillager.class.getDeclaredField(Refraction.pickName("offers", "bW"));
fieldOffers.setAccessible(true);
} catch (RuntimeException e) {
throw e;
} catch (Throwable rethrow) {
@ -571,7 +579,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
return BiomeTypes.get(biome.unwrapKey().orElseThrow().location().toString());
}
@SuppressWarnings("unchecked")
static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) {
try {
// Do the method ourselves to avoid trying to reflect generic method parameters
@ -595,6 +602,29 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
return chunk.level.entityManager.getEntities(chunk.getPos());
}
public static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag compoundTag) {
boolean isVillager = entity instanceof AbstractVillager && !Fawe.isMainThread();
boolean unset = false;
if (isVillager) {
try {
if (fieldOffers.get(entity) != null) {
fieldOffers.set(entity, OFFERS);
unset = true;
}
} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to set offers field to villager to avoid async catcher.", e);
}
}
entity.save(compoundTag);
if (unset) {
try {
fieldOffers.set(entity, null);
} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to set offers field to null again on villager.", e);
}
}
}
record FakeIdMapBlock(int size) implements IdMap<net.minecraft.world.level.block.state.BlockState> {
@Override

Datei anzeigen

@ -35,6 +35,7 @@ import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.Refraction;
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3.PaperweightPlatformAdapter;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.extension.platform.Watchdog;
import com.sk89q.worldedit.extent.Extent;
@ -276,7 +277,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
* @param tag the tag
*/
private static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag tag) {
entity.save(tag);
//FAWE start - avoid villager async catcher
PaperweightPlatformAdapter.readEntityIntoTag(entity, tag);
//FAWE end
}
private static Block getBlockFromType(BlockType blockType) {

Datei anzeigen

@ -144,10 +144,6 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
return resourceLocation == null ? null : resourceLocation.toString();
}
private static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag compoundTag) {
entity.save(compoundTag);
}
@Override
public BukkitImplAdapter<net.minecraft.nbt.Tag> getParent() {
return parent;
@ -321,7 +317,7 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id);
Supplier<CompoundBinaryTag> saveTag = () -> {
final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag();
readEntityIntoTag(mcEntity, minecraftTag);
PaperweightPlatformAdapter.readEntityIntoTag(mcEntity, minecraftTag);
//add Id for AbstractChangeSet to work
final CompoundBinaryTag tag = (CompoundBinaryTag) toNativeBinary(minecraftTag);
final Map<String, BinaryTag> tags = NbtUtils.getCompoundBinaryTagValues(tag);

Datei anzeigen

@ -372,7 +372,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
public Iterator<CompoundTag> iterator() {
Iterable<CompoundTag> result = entities.stream().map(input -> {
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
input.save(tag);
PaperweightPlatformAdapter.readEntityIntoTag(input, tag);
return (CompoundTag) adapter.toNative(tag);
}).collect(Collectors.toList());
return result.iterator();
@ -437,7 +437,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
@SuppressWarnings("rawtypes")
public synchronized <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
forceLoadSections = false;
copy = createCopy ? new PaperweightGetBlocks_Copy(levelChunk) : null;
copy = createCopy ? new PaperweightGetBlocks_Copy(getChunk()) : null;
try {
ServerLevel nmsWorld = serverLevel;
LevelChunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ);

Datei anzeigen

@ -84,7 +84,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
protected void storeEntity(Entity entity) {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
net.minecraft.nbt.CompoundTag compoundTag = new net.minecraft.nbt.CompoundTag();
entity.save(compoundTag);
PaperweightPlatformAdapter.readEntityIntoTag(entity, compoundTag);
entities.add((CompoundTag) adapter.toNative(compoundTag));
}

Datei anzeigen

@ -38,6 +38,8 @@ import net.minecraft.util.ThreadingDetector;
import net.minecraft.util.Unit;
import net.minecraft.util.ZeroBitStorage;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.npc.AbstractVillager;
import net.minecraft.world.item.trading.MerchantOffers;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.biome.Biome;
@ -105,6 +107,9 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
private static final MethodHandle methodRemoveGameEventListener;
private static final MethodHandle methodremoveTickingBlockEntity;
private static final Field fieldOffers;
private static final MerchantOffers OFFERS = new MerchantOffers();
private static final Field fieldRemove;
private static final Logger LOGGER = LogManagerCompat.getLogger();
@ -196,6 +201,9 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
} catch (NoSuchFieldException ignored) {
}
POST_CHUNK_REWRITE = chunkRewrite;
fieldOffers = AbstractVillager.class.getDeclaredField(Refraction.pickName("offers", "bT"));
fieldOffers.setAccessible(true);
} catch (RuntimeException | Error e) {
throw e;
} catch (Exception e) {
@ -656,6 +664,29 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
return List.of();
}
public static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag compoundTag) {
boolean isVillager = entity instanceof AbstractVillager && !Fawe.isMainThread();
boolean unset = false;
if (isVillager) {
try {
if (fieldOffers.get(entity) != null) {
fieldOffers.set(entity, OFFERS);
unset = true;
}
} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to set offers field to villager to avoid async catcher.", e);
}
}
entity.save(compoundTag);
if (unset) {
try {
fieldOffers.set(entity, null);
} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to set offers field to null again on villager.", e);
}
}
}
record FakeIdMapBlock(int size) implements IdMap<net.minecraft.world.level.block.state.BlockState> {
@Override

Datei anzeigen

@ -27,7 +27,6 @@ import com.google.common.collect.Sets;
import com.google.common.util.concurrent.Futures;
import com.mojang.datafixers.util.Either;
import com.mojang.serialization.Lifecycle;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.NBTConstants;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseItem;
@ -35,6 +34,7 @@ import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.Refraction;
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1.PaperweightPlatformAdapter;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.extension.platform.Watchdog;
import com.sk89q.worldedit.extent.Extent;
@ -138,6 +138,7 @@ import org.bukkit.generator.ChunkGenerator;
import org.spigotmc.SpigotConfig;
import org.spigotmc.WatchdogThread;
import javax.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
@ -159,7 +160,6 @@ import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
@ -277,7 +277,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
* @param tag the tag
*/
private static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag tag) {
entity.save(tag);
//FAWE start - avoid villager async catcher
PaperweightPlatformAdapter.readEntityIntoTag(entity, tag);
//FAWE end
}
private static Block getBlockFromType(BlockType blockType) {

Datei anzeigen

@ -144,10 +144,6 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
return resourceLocation == null ? null : resourceLocation.toString();
}
private static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag compoundTag) {
entity.save(compoundTag);
}
@Override
public BukkitImplAdapter<net.minecraft.nbt.Tag> getParent() {
return parent;
@ -321,7 +317,7 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id);
Supplier<CompoundBinaryTag> saveTag = () -> {
final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag();
readEntityIntoTag(mcEntity, minecraftTag);
PaperweightPlatformAdapter.readEntityIntoTag(mcEntity, minecraftTag);
//add Id for AbstractChangeSet to work
final CompoundBinaryTag tag = (CompoundBinaryTag) toNativeBinary(minecraftTag);
final Map<String, BinaryTag> tags = NbtUtils.getCompoundBinaryTagValues(tag);

Datei anzeigen

@ -30,7 +30,11 @@ import com.sk89q.worldedit.world.biome.BiomeTypes;
import com.sk89q.worldedit.world.block.BlockTypesCache;
import io.papermc.lib.PaperLib;
import io.papermc.paper.event.block.BeaconDeactivatedEvent;
import net.minecraft.core.*;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.IdMap;
import net.minecraft.core.Registry;
import net.minecraft.core.SectionPos;
import net.minecraft.nbt.IntTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvents;
@ -43,7 +47,14 @@ import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.entity.BeaconBlockEntity;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.*;
import net.minecraft.world.level.chunk.DataLayer;
import net.minecraft.world.level.chunk.HashMapPalette;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.chunk.LinearPalette;
import net.minecraft.world.level.chunk.Palette;
import net.minecraft.world.level.chunk.PalettedContainer;
import net.minecraft.world.level.chunk.PalettedContainerRO;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.lighting.LevelLightEngine;
import org.apache.logging.log4j.Logger;
@ -54,7 +65,17 @@ import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.event.entity.CreatureSpawnEvent;
import javax.annotation.Nonnull;
import java.util.*;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.Semaphore;
@ -350,7 +371,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
public Iterator<CompoundTag> iterator() {
Iterable<CompoundTag> result = entities.stream().map(input -> {
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
input.save(tag);
PaperweightPlatformAdapter.readEntityIntoTag(input, tag);
return (CompoundTag) adapter.toNative(tag);
}).collect(Collectors.toList());
return result.iterator();
@ -415,7 +436,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
@SuppressWarnings("rawtypes")
public synchronized <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
forceLoadSections = false;
copy = createCopy ? new PaperweightGetBlocks_Copy(levelChunk) : null;
copy = createCopy ? new PaperweightGetBlocks_Copy(getChunk()) : null;
try {
ServerLevel nmsWorld = serverLevel;
LevelChunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ);

Datei anzeigen

@ -84,7 +84,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
protected void storeEntity(Entity entity) {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
net.minecraft.nbt.CompoundTag compoundTag = new net.minecraft.nbt.CompoundTag();
entity.save(compoundTag);
PaperweightPlatformAdapter.readEntityIntoTag(entity, compoundTag);
entities.add((CompoundTag) adapter.toNative(compoundTag));
}

Datei anzeigen

@ -38,6 +38,9 @@ import net.minecraft.util.ThreadingDetector;
import net.minecraft.util.Unit;
import net.minecraft.util.ZeroBitStorage;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.npc.AbstractVillager;
import net.minecraft.world.entity.npc.Villager;
import net.minecraft.world.item.trading.MerchantOffers;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.biome.Biome;
@ -108,6 +111,9 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
private static final MethodHandle methodRemoveGameEventListener;
private static final MethodHandle methodremoveTickingBlockEntity;
private static final Field fieldOffers;
private static final MerchantOffers OFFERS = new MerchantOffers();
/*
* This is a workaround for the changes from https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/commits/1fddefce1cdce44010927b888432bf70c0e88cde#src/main/java/org/bukkit/craftbukkit/CraftChunk.java
* and is only needed to support 1.19.4 versions before *and* after this change.
@ -205,6 +211,9 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
} catch (NoSuchFieldException ignored) {
}
POST_CHUNK_REWRITE = chunkRewrite;
fieldOffers = AbstractVillager.class.getDeclaredField(Refraction.pickName("offers", "bU"));
fieldOffers.setAccessible(true);
} catch (RuntimeException | Error e) {
throw e;
} catch (Exception e) {
@ -674,6 +683,24 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
return List.of();
}
public static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag compoundTag) {
boolean unset = false;
if (entity instanceof Villager villager && !Fawe.isMainThread()) {
try {
if (fieldOffers.get(entity) == null) {
villager.setOffers(OFFERS);
unset = true;
}
} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to set offers field to villager to avoid async catcher.", e);
}
}
entity.save(compoundTag);
if (unset) {
((Villager) entity).setOffers(null);
}
}
record FakeIdMapBlock(int size) implements IdMap<net.minecraft.world.level.block.state.BlockState> {
@Override

Datei anzeigen

@ -12,6 +12,6 @@ repositories {
dependencies {
// https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/
the<PaperweightUserDependenciesExtension>().paperDevBundle("1.20.2-R0.1-20230929.031919-14")
the<PaperweightUserDependenciesExtension>().paperDevBundle("1.20.2-R0.1-20231008.101509-26")
compileOnly(libs.paperlib)
}

Datei anzeigen

@ -74,7 +74,12 @@ public class InspectBrush extends BrushTool {
return false;
}
try {
BlockVector3 target = getTarget(player, rightClick).toBlockPoint();
Vector3 targetVector = getTarget(player, rightClick);
if (targetVector == null) {
player.print(Caption.of("worldedit.tool.no-block"));
return true;
}
BlockVector3 target = targetVector.toBlockPoint();
final int x = target.getBlockX();
final int y = target.getBlockY();
final int z = target.getBlockZ();

Datei anzeigen

@ -12,8 +12,6 @@ import com.sk89q.worldedit.world.block.BlockTypesCache;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
public class HeightmapProcessor implements IBatchProcessor {
@ -25,7 +23,7 @@ public class HeightmapProcessor implements IBatchProcessor {
static {
Arrays.fill(COMPLETE, true);
Arrays.fill(AIR_LAYER, (char) 1);
Arrays.fill(AIR_LAYER, (char) BlockTypesCache.ReservedIDs.AIR);
}
private final int minY;

Datei anzeigen

@ -179,14 +179,14 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
for (int z = 0; z < 16; z++) {
int zz = z + bz;
for (int x = 0; x < 16; x++, index++) {
int xx = bx + x;
int from = blocksGet[index];
if (from == BlockTypesCache.ReservedIDs.__RESERVED__) {
from = BlockTypesCache.ReservedIDs.AIR;
}
final int combinedFrom = from;
final int combinedTo = blocksSet[index];
if (combinedTo != BlockTypesCache.ReservedIDs.__RESERVED__) {
int xx = bx + x;
int from = blocksGet[index];
if (from == BlockTypesCache.ReservedIDs.__RESERVED__) {
from = BlockTypesCache.ReservedIDs.AIR;
}
final int combinedFrom = from;
add(xx, yy, zz, combinedFrom, combinedTo);
}
}

Datei anzeigen

@ -257,7 +257,8 @@ public class ExtentEntityCopy implements EntityFunction {
//FAWE start
if (hasRotation) {
ListTag orgrot = state.getNbtData().getListTag("Rotation");
Vector3 orgDirection = new Location(source, 0, 0, 0, orgrot.getFloat(0), orgrot.getFloat(1)).getDirection();
// source extent may be null: use non-nullable destination instead since this is just a conversion into a vector.
Vector3 orgDirection = new Location(destination, 0, 0, 0, orgrot.getFloat(0), orgrot.getFloat(1)).getDirection();
Vector3 newDirection = transform.apply(orgDirection).subtract(transform.apply(Vector3.ZERO)).normalize();
builder.put(
"Rotation",
@ -276,7 +277,8 @@ public class ExtentEntityCopy implements EntityFunction {
CompoundTagBuilder builder = tag.createBuilder();
ListTag orgrot = state.getNbtData().getListTag("Rotation");
Vector3 orgDirection = new Location(source, 0, 0, 0, orgrot.getFloat(0), orgrot.getFloat(1)).getDirection();
// source extent may be null: use non-nullable destination instead since this is just a conversion into a vector.
Vector3 orgDirection = new Location(destination, 0, 0, 0, orgrot.getFloat(0), orgrot.getFloat(1)).getDirection();
Vector3 newDirection = transform.apply(orgDirection).subtract(transform.apply(Vector3.ZERO)).normalize();
builder.put(
"Rotation",

Datei anzeigen

@ -500,6 +500,10 @@ public class ForwardExtentCopy implements Operation {
}
affectedBlocks += blockCopy.getAffected();
if (copyingBiomes) {
// We know biomes will have happened unless something else has gone wrong. Just calculate it.
affectedBiomeCols += source.fullySupports3DBiomes() ? (getAffected() >> 2) : (region.getWidth() * region.getLength());
}
//FAWE end
return null;
}

Datei anzeigen

@ -28,7 +28,7 @@ dependencies {
})
api("org.apache.logging.log4j:log4j-api")
api("org.bstats:bstats-sponge:1.7")
testImplementation("org.mockito:mockito-core:5.5.0")
testImplementation("org.mockito:mockito-core:5.6.0")
}
<<<<<<< HEAD