mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-30 19:24:04 +00:00
fix: set villager offers temporarily to save NBT without sending event (#2357)
This commit is contained in:
@@ -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) {
|
||||
|
@@ -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);
|
||||
|
@@ -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();
|
||||
@@ -389,7 +389,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);
|
||||
|
@@ -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));
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user