From 9de9bb3498123753585b70c51ff91d15e76b9e7e Mon Sep 17 00:00:00 2001 From: Maddy Miller Date: Fri, 10 Mar 2023 21:39:24 +1000 Subject: [PATCH 01/12] Add a feature generator and allow undoing of feature placement (https://github.com/EngineHub/WorldEdit/pull/2239) * Add a feature generator and allow undoing of feature placement [WIP] Apply changes to Forge as well Use proper translatable components * Add a brush version of the feature command Use Java proxy classes * Add for Bukkit (only 1.19.3 for now) Clean up the proxies to use a switch Checkstyle is grumpy Add the obfuscated versions Remove debug text Fix missed "destroyBlock" deobfuscated proxy function * checkstyle --- .../ext/fawe/v1_20_R1/PaperweightAdapter.java | 50 ++++++-- .../PaperweightServerLevelDelegateProxy.java | 121 ++++++++++++++++++ .../sk89q/worldedit/bukkit/BukkitWorld.java | 11 ++ .../bukkit/adapter/BukkitImplAdapter.java | 15 +++ .../worldedit/command/BrushCommands.java | 20 +++ .../worldedit/command/GenerationCommands.java | 18 +++ .../command/argument/RegistryConverter.java | 4 +- .../factory/FeatureGeneratorFactory.java | 44 +++++++ .../function/generator/FeatureGenerator.java | 52 ++++++++ .../java/com/sk89q/worldedit/world/World.java | 13 ++ .../generation/ConfiguredFeatureType.java | 43 +++++++ .../src/main/resources/lang/strings.json | 2 + .../FabricServerLevelDelegateProxy.java | 117 +++++++++++++++++ .../ForgeServerLevelDelegateProxy.java | 117 +++++++++++++++++ 14 files changed, 617 insertions(+), 10 deletions(-) create mode 100644 worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightServerLevelDelegateProxy.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/command/factory/FeatureGeneratorFactory.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/FeatureGenerator.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/ConfiguredFeatureType.java create mode 100644 worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricServerLevelDelegateProxy.java create mode 100644 worldedit-forge/src/main/java/com/sk89q/worldedit/forge/internal/ForgeServerLevelDelegateProxy.java diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java index b40c12b1a..ebe54c629 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java @@ -28,6 +28,7 @@ import com.google.common.util.concurrent.Futures; import com.mojang.datafixers.util.Either; import com.mojang.serialization.Lifecycle; import com.sk89q.jnbt.NBTConstants; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItemStack; @@ -78,6 +79,7 @@ import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; +import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; import com.sk89q.worldedit.world.item.ItemType; import net.minecraft.Util; import net.minecraft.core.BlockPos; @@ -93,6 +95,7 @@ import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.progress.ChunkProgressListener; +import net.minecraft.util.RandomSource; import net.minecraft.util.StringRepresentable; import net.minecraft.util.thread.BlockableEventLoop; import net.minecraft.world.Clearable; @@ -105,6 +108,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.LevelSettings; +import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; @@ -117,12 +121,14 @@ import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.dimension.LevelStem; import net.minecraft.world.level.levelgen.WorldOptions; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.PrimaryLevelData; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.World; import org.bukkit.World.Environment; import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.v1_20_R1.CraftServer; @@ -173,6 +179,8 @@ public final class PaperweightAdapter implements BukkitImplAdapter> 4, z >> 4); final BlockPos blockPos = new BlockPos(x, y, z); final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos); - int internalId = Block.getId(blockData); - BlockState state = BlockStateIdAccess.getBlockStateById(internalId); - if (state == null) { - org.bukkit.block.Block bukkitBlock = location.getBlock(); - state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); - } - - return state; + return adapt(blockData); } @Override @@ -865,7 +881,23 @@ public final class PaperweightAdapter implements BukkitImplAdapter k = originalWorld.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(ResourceLocation.tryParse(type.getId())); + ServerChunkCache chunkManager = originalWorld.getChunkSource(); + WorldGenLevel proxyLevel = PaperweightServerLevelDelegateProxy.newInstance(session, originalWorld, this); + return k != null && k.place(proxyLevel, chunkManager.getGenerator(), random, new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ())); + } // ------------------------------------------------------------------------ // Code that is less likely to break diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightServerLevelDelegateProxy.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightServerLevelDelegateProxy.java new file mode 100644 index 000000000..23d4aa821 --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightServerLevelDelegateProxy.java @@ -0,0 +1,121 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R1; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.world.block.BlockTypes; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +public class PaperweightServerLevelDelegateProxy implements InvocationHandler { + + private final EditSession editSession; + private final ServerLevel serverLevel; + private final PaperweightAdapter adapter; + + private PaperweightServerLevelDelegateProxy(EditSession editSession, ServerLevel serverLevel, PaperweightAdapter adapter) { + this.editSession = editSession; + this.serverLevel = serverLevel; + this.adapter = adapter; + } + + public static WorldGenLevel newInstance(EditSession editSession, ServerLevel serverLevel, PaperweightAdapter adapter) { + return (WorldGenLevel) Proxy.newProxyInstance( + serverLevel.getClass().getClassLoader(), + serverLevel.getClass().getInterfaces(), + new PaperweightServerLevelDelegateProxy(editSession, serverLevel, adapter) + ); + } + + @Nullable + private BlockEntity getBlockEntity(BlockPos blockPos) { + BlockEntity tileEntity = this.serverLevel.getChunkAt(blockPos).getBlockEntity(blockPos); + if (tileEntity == null) { + return null; + } + BlockEntity newEntity = tileEntity.getType().create(blockPos, getBlockState(blockPos)); + newEntity.load((CompoundTag) adapter.fromNativeBinary(this.editSession.getFullBlock(BlockVector3.at(blockPos.getX(), + blockPos.getY(), blockPos.getZ())).getNbtReference().getValue())); + + return newEntity; + } + + private BlockState getBlockState(BlockPos blockPos) { + return adapter.adapt(this.editSession.getBlock(BlockVector3.at(blockPos.getX(), blockPos.getY(), blockPos.getZ()))); + } + + private boolean setBlock(BlockPos blockPos, BlockState blockState) { + try { + return editSession.setBlock(BlockVector3.at(blockPos.getX(), blockPos.getY(), blockPos.getZ()), adapter.adapt(blockState)); + } catch (MaxChangedBlocksException e) { + throw new RuntimeException(e); + } + } + + private boolean removeBlock(BlockPos blockPos, boolean bl) { + try { + return editSession.setBlock(BlockVector3.at(blockPos.getX(), blockPos.getY(), blockPos.getZ()), BlockTypes.AIR.getDefaultState()); + } catch (MaxChangedBlocksException e) { + throw new RuntimeException(e); + } + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + switch (method.getName()) { + case "a_", "getBlockState" -> { + if (args.length == 1 && args[0] instanceof BlockPos blockPos) { + // getBlockState + return getBlockState(blockPos); + } + } + case "c_", "getBlockEntity" -> { + if (args.length == 1 && args[0] instanceof BlockPos blockPos) { + // getBlockEntity + return getBlockEntity(blockPos); + } + } + case "a", "setBlock", "removeBlock", "destroyBlock" -> { + if (args.length >= 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof BlockState blockState) { + // setBlock + return setBlock(blockPos, blockState); + } else if (args.length >= 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof Boolean bl) { + // removeBlock (and also matches destroyBlock) + return removeBlock(blockPos, bl); + } + } + default -> { } + } + + return method.invoke(this.serverLevel, args); + } + +} diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index a9ba45afe..29da94026 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -54,6 +54,7 @@ import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; +import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; import com.sk89q.worldedit.world.weather.WeatherType; import com.sk89q.worldedit.world.weather.WeatherTypes; import io.papermc.lib.PaperLib; @@ -519,6 +520,16 @@ public class BukkitWorld extends AbstractWorld { return true; } + @Override + public boolean generateFeature(ConfiguredFeatureType type, EditSession editSession, BlockVector3 position) { + BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); + if (adapter != null) { + return adapter.generateFeature(type, getWorld(), editSession, position); + } + // No adapter, we can't generate this. + return false; + } + private static volatile boolean hasWarnedImplError = false; @Override diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java index a34494ce5..f1bce3a52 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java @@ -29,6 +29,7 @@ import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.implementation.packet.ChunkPacket; import com.sk89q.jnbt.AdventureNBTConverter; import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.bukkit.BukkitAdapter; @@ -49,6 +50,7 @@ import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockType; +import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.registry.BlockMaterial; import org.bukkit.Keyed; @@ -280,6 +282,19 @@ public interface BukkitImplAdapter extends IBukkitAdapter { throw new UnsupportedOperationException("This adapter does not support clearing block contents."); } + /** + * Generates a Minecraft feature at the given location. + * + * @param feature The feature + * @param world The world + * @param session The EditSession + * @param pt The location + * @return If it succeeded + */ + default boolean generateFeature(ConfiguredFeatureType feature, World world, EditSession session, BlockVector3 pt) { + throw new UnsupportedOperationException("This adapter does not support generating features."); + } + //FAWE start default BlockMaterial getMaterial(BlockType blockType) { return getMaterial(blockType.getDefaultState()); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java index 76cb60c64..c0c1f77a0 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java @@ -66,6 +66,7 @@ import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.command.argument.Arguments; +import com.sk89q.worldedit.command.factory.FeatureGeneratorFactory; import com.sk89q.worldedit.command.factory.ReplaceFactory; import com.sk89q.worldedit.command.factory.TreeGeneratorFactory; import com.sk89q.worldedit.command.tool.BrushTool; @@ -116,6 +117,7 @@ import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; import org.anarres.parallelgzip.ParallelGZIPOutputStream; +import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; import org.enginehub.piston.annotation.Command; import org.enginehub.piston.annotation.CommandContainer; import org.enginehub.piston.annotation.param.Arg; @@ -1458,6 +1460,24 @@ public class BrushCommands { set(context, new ButcherBrush(flags), "worldedit.brush.butcher").setSize(radius); } + @Command( + name = "feature", + desc = "Feature brush, paints Minecraft generation features" + ) + @CommandPermissions("worldedit.brush.feature") + public void feature(Player player, LocalSession localSession, + @Arg(desc = "The shape of the region") + RegionFactory shape, + @Arg(desc = "The size of the brush", def = "5") + double radius, + @Arg(desc = "The density of the brush", def = "5") + double density, + @Arg(desc = "The type of feature to use") + ConfiguredFeatureType type) throws WorldEditException { + setOperationBasedBrush(player, localSession, radius, + new Paint(new FeatureGeneratorFactory(type), density / 100), shape, "worldedit.brush.feature"); + } + //FAWE start public BrushSettings process(Player player, Arguments arguments, BrushSettings settings) throws WorldEditException { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java index dbd698b24..5129f2dd1 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java @@ -56,6 +56,7 @@ import com.sk89q.worldedit.util.TreeGenerator.TreeType; import com.sk89q.worldedit.util.formatting.text.TextComponent; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BlockType; +import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; import org.enginehub.piston.annotation.Command; import org.enginehub.piston.annotation.CommandContainer; import org.enginehub.piston.annotation.param.Arg; @@ -345,6 +346,23 @@ public class GenerationCommands { return affected; } + @Command( + name = "/feature", + desc = "Generate Minecraft features" + ) + @CommandPermissions("worldedit.generation.feature") + @Logging(POSITION) + public int feature(Actor actor, LocalSession session, EditSession editSession, + @Arg(desc = "The feature") + ConfiguredFeatureType feature) throws WorldEditException { + if (editSession.getWorld().generateFeature(feature, editSession, session.getPlacementPosition(actor))) { + actor.printInfo(Caption.of("worldedit.feature.created")); + } else { + actor.printError(Caption.of("worldedit.feature.failed")); + } + return 0; + } + @Command( name = "/hpyramid", desc = "Generate a hollow pyramid" diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/RegistryConverter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/RegistryConverter.java index 271c0aa07..9ed38c642 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/RegistryConverter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/RegistryConverter.java @@ -32,6 +32,7 @@ import com.sk89q.worldedit.world.entity.EntityType; import com.sk89q.worldedit.world.fluid.FluidCategory; import com.sk89q.worldedit.world.fluid.FluidType; import com.sk89q.worldedit.world.gamemode.GameMode; +import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; import com.sk89q.worldedit.world.item.ItemCategory; import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.weather.WeatherType; @@ -62,7 +63,8 @@ public final class RegistryConverter implements ArgumentConvert FluidType.class, FluidCategory.class, GameMode.class, - WeatherType.class + WeatherType.class, + ConfiguredFeatureType.class ) .stream() .map(c -> (Class) c) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/factory/FeatureGeneratorFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/factory/FeatureGeneratorFactory.java new file mode 100644 index 000000000..6434f016b --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/factory/FeatureGeneratorFactory.java @@ -0,0 +1,44 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.command.factory; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.function.Contextual; +import com.sk89q.worldedit.function.EditContext; +import com.sk89q.worldedit.function.generator.FeatureGenerator; +import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; + +public final class FeatureGeneratorFactory implements Contextual { + private final ConfiguredFeatureType type; + + public FeatureGeneratorFactory(ConfiguredFeatureType type) { + this.type = type; + } + + @Override + public FeatureGenerator createFromContext(EditContext input) { + return new FeatureGenerator((EditSession) input.getDestination(), type); + } + + @Override + public String toString() { + return "feature of type " + type; + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/FeatureGenerator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/FeatureGenerator.java new file mode 100644 index 000000000..6c49138db --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/FeatureGenerator.java @@ -0,0 +1,52 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.function.generator; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.function.RegionFunction; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; + +/** + * Generates forests by searching for the ground starting from the given upper Y + * coordinate for every column given. + */ +public class FeatureGenerator implements RegionFunction { + + private final ConfiguredFeatureType featureType; + private final EditSession editSession; + + /** + * Create a new instance. + * + * @param editSession the edit session + * @param featureType the feature type + */ + public FeatureGenerator(EditSession editSession, ConfiguredFeatureType featureType) { + this.editSession = editSession; + this.featureType = featureType; + } + + @Override + public boolean apply(BlockVector3 position) throws WorldEditException { + return editSession.getWorld().generateFeature(featureType, editSession, position); + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java index 79822a934..176b22299 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java @@ -46,6 +46,7 @@ import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; +import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; import com.sk89q.worldedit.world.weather.WeatherType; import javax.annotation.Nullable; @@ -311,6 +312,18 @@ public interface World extends Extent, Keyed, IChunkCache { boolean generateTree(TreeGenerator.TreeType type, EditSession editSession, BlockVector3 position) throws MaxChangedBlocksException; + /** + * Generate a feature at the given position. + * + * @param type The feature type + * @param editSession The {@link EditSession} + * @param position The position + * @return True if the generation was successful + */ + default boolean generateFeature(ConfiguredFeatureType type, EditSession editSession, BlockVector3 position) { + return false; + } + /** * Load the chunk at the given position if it isn't loaded. * diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/ConfiguredFeatureType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/ConfiguredFeatureType.java new file mode 100644 index 000000000..56888acd9 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/ConfiguredFeatureType.java @@ -0,0 +1,43 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.world.generation; + +import com.sk89q.worldedit.registry.Keyed; +import com.sk89q.worldedit.registry.NamespacedRegistry; + +public class ConfiguredFeatureType implements Keyed { + public static final NamespacedRegistry REGISTRY = new NamespacedRegistry<>("configured feature type"); + + private final String id; + + public ConfiguredFeatureType(String id) { + this.id = id; + } + + @Override + public String getId() { + return this.id; + } + + @Override + public String toString() { + return this.id; + } +} diff --git a/worldedit-core/src/main/resources/lang/strings.json b/worldedit-core/src/main/resources/lang/strings.json index 5e922cdae..21359defd 100644 --- a/worldedit-core/src/main/resources/lang/strings.json +++ b/worldedit-core/src/main/resources/lang/strings.json @@ -498,6 +498,8 @@ "worldedit.sphere.created": "{0} blocks have been created.", "worldedit.forestgen.created": "{0} trees created.", "worldedit.pumpkins.created": "{0} pumpkin patches created.", + "worldedit.feature.created": "Feature created.", + "worldedit.feature.failed": "Failed to generate feature. Is it a valid spot for it?", "worldedit.pyramid.created": "{0} blocks have been created.", "worldedit.generate.created": "{0} blocks have been created.", "worldedit.generatebiome.changed": "{0} biomes affected.", diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricServerLevelDelegateProxy.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricServerLevelDelegateProxy.java new file mode 100644 index 000000000..07ee8d81c --- /dev/null +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricServerLevelDelegateProxy.java @@ -0,0 +1,117 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.fabric.internal; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.fabric.FabricAdapter; +import com.sk89q.worldedit.world.block.BlockTypes; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Arrays; + +public class FabricServerLevelDelegateProxy implements InvocationHandler { + + private final EditSession editSession; + private final ServerLevel serverLevel; + + private FabricServerLevelDelegateProxy(EditSession editSession, ServerLevel serverLevel) { + this.editSession = editSession; + this.serverLevel = serverLevel; + } + + public static WorldGenLevel newInstance(EditSession editSession, ServerLevel serverLevel) { + return (WorldGenLevel) Proxy.newProxyInstance( + serverLevel.getClass().getClassLoader(), + serverLevel.getClass().getInterfaces(), + new FabricServerLevelDelegateProxy(editSession, serverLevel) + ); + } + + @Nullable + private BlockEntity getBlockEntity(BlockPos blockPos) { + BlockEntity tileEntity = this.serverLevel.getChunkAt(blockPos).getBlockEntity(blockPos); + if (tileEntity == null) { + return null; + } + BlockEntity newEntity = tileEntity.getType().create(blockPos, getBlockState(blockPos)); + newEntity.load(NBTConverter.toNative(this.editSession.getFullBlock(FabricAdapter.adapt(blockPos)).getNbtReference().getValue())); + + return newEntity; + } + + private BlockState getBlockState(BlockPos blockPos) { + return FabricAdapter.adapt(this.editSession.getBlock(FabricAdapter.adapt(blockPos))); + } + + private boolean setBlock(BlockPos blockPos, BlockState blockState) { + try { + return editSession.setBlock(FabricAdapter.adapt(blockPos), FabricAdapter.adapt(blockState)); + } catch (MaxChangedBlocksException e) { + throw new RuntimeException(e); + } + } + + private boolean removeBlock(BlockPos blockPos, boolean bl) { + try { + return editSession.setBlock(FabricAdapter.adapt(blockPos), BlockTypes.AIR.getDefaultState()); + } catch (MaxChangedBlocksException e) { + throw new RuntimeException(e); + } + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + switch (method.getName()) { + case "getBlockState", "method_8320" -> { + if (args.length == 1 && args[0] instanceof BlockPos blockPos) { + return getBlockState(blockPos); + } + } + case "getBlockEntity", "method_8321" -> { + if (args.length == 1 && args[0] instanceof BlockPos blockPos) { + return getBlockEntity(blockPos); + } + } + case "setBlock", "method_8652" -> { + if (args.length >= 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof BlockState blockState) { + return setBlock(blockPos, blockState); + } + } + case "removeBlock", "destroyBlock", "method_8650", "method_8651" -> { + if (args.length >= 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof Boolean bl) { + return removeBlock(blockPos, bl); + } + } + default -> { } + } + + return method.invoke(this.serverLevel, args); + } + +} diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/internal/ForgeServerLevelDelegateProxy.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/internal/ForgeServerLevelDelegateProxy.java new file mode 100644 index 000000000..ff9e64d4e --- /dev/null +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/internal/ForgeServerLevelDelegateProxy.java @@ -0,0 +1,117 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.forge.internal; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.forge.ForgeAdapter; +import com.sk89q.worldedit.world.block.BlockTypes; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Arrays; + +public class ForgeServerLevelDelegateProxy implements InvocationHandler { + + private final EditSession editSession; + private final ServerLevel serverLevel; + + private ForgeServerLevelDelegateProxy(EditSession editSession, ServerLevel serverLevel) { + this.editSession = editSession; + this.serverLevel = serverLevel; + } + + public static WorldGenLevel newInstance(EditSession editSession, ServerLevel serverLevel) { + return (WorldGenLevel) Proxy.newProxyInstance( + serverLevel.getClass().getClassLoader(), + serverLevel.getClass().getInterfaces(), + new ForgeServerLevelDelegateProxy(editSession, serverLevel) + ); + } + + @Nullable + private BlockEntity getBlockEntity(BlockPos blockPos) { + BlockEntity tileEntity = this.serverLevel.getChunkAt(blockPos).getBlockEntity(blockPos); + if (tileEntity == null) { + return null; + } + BlockEntity newEntity = tileEntity.getType().create(blockPos, getBlockState(blockPos)); + newEntity.load(NBTConverter.toNative(this.editSession.getFullBlock(ForgeAdapter.adapt(blockPos)).getNbtReference().getValue())); + + return newEntity; + } + + private BlockState getBlockState(BlockPos blockPos) { + return ForgeAdapter.adapt(this.editSession.getBlock(ForgeAdapter.adapt(blockPos))); + } + + private boolean setBlock(BlockPos blockPos, BlockState blockState) { + try { + return editSession.setBlock(ForgeAdapter.adapt(blockPos), ForgeAdapter.adapt(blockState)); + } catch (MaxChangedBlocksException e) { + throw new RuntimeException(e); + } + } + + private boolean removeBlock(BlockPos blockPos, boolean bl) { + try { + return editSession.setBlock(ForgeAdapter.adapt(blockPos), BlockTypes.AIR.getDefaultState()); + } catch (MaxChangedBlocksException e) { + throw new RuntimeException(e); + } + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + switch (method.getName()) { + case "getBlockState", "m_8055_" -> { + if (args.length == 1 && args[0] instanceof BlockPos blockPos) { + return getBlockState(blockPos); + } + } + case "getBlockEntity", "m_7702_" -> { + if (args.length == 1 && args[0] instanceof BlockPos blockPos) { + return getBlockEntity(blockPos); + } + } + case "setBlock", "m_7731_" -> { + if (args.length >= 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof BlockState blockState) { + return setBlock(blockPos, blockState); + } + } + case "removeBlock", "destroyBlock", "m_7471_", "m_7740_" -> { + if (args.length >= 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof Boolean bl) { + return removeBlock(blockPos, bl); + } + } + default -> { } + } + + return method.invoke(this.serverLevel, args); + } + +} From f2f01eb443c9c02a3b5e144aedb531346fa38c93 Mon Sep 17 00:00:00 2001 From: Madeline Miller Date: Sun, 9 Apr 2023 18:18:23 +1000 Subject: [PATCH 02/12] Add structure generator command (cherry picked from commit 5ca80395a35100c2d7686ad8839baaa57f8db07c) --- .../ext/fawe/v1_20_R1/PaperweightAdapter.java | 35 +++++++++++++++ .../sk89q/worldedit/bukkit/BukkitWorld.java | 11 +++++ .../bukkit/adapter/BukkitImplAdapter.java | 14 ++++++ .../worldedit/command/GenerationCommands.java | 18 ++++++++ .../command/argument/RegistryConverter.java | 4 +- .../java/com/sk89q/worldedit/world/World.java | 5 +++ .../world/generation/StructureType.java | 43 +++++++++++++++++++ .../src/main/resources/lang/strings.json | 2 + 8 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/StructureType.java diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java index ebe54c629..ff8b6bdf7 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java @@ -80,10 +80,12 @@ import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; +import com.sk89q.worldedit.world.generation.StructureType; import com.sk89q.worldedit.world.item.ItemType; import net.minecraft.Util; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; +import net.minecraft.core.SectionPos; import net.minecraft.core.registries.Registries; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; @@ -122,6 +124,9 @@ import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.dimension.LevelStem; import net.minecraft.world.level.levelgen.WorldOptions; import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.level.levelgen.structure.Structure; +import net.minecraft.world.level.levelgen.structure.StructureStart; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.PrimaryLevelData; import net.minecraft.world.phys.BlockHitResult; @@ -888,6 +893,13 @@ public final class PaperweightAdapter implements BukkitImplAdapter true); + + if (!structureStart.isValid()) { + return false; + } else { + BoundingBox boundingBox = structureStart.getBoundingBox(); + ChunkPos min = new ChunkPos(SectionPos.blockToSectionCoord(boundingBox.minX()), SectionPos.blockToSectionCoord(boundingBox.minZ())); + ChunkPos max = new ChunkPos(SectionPos.blockToSectionCoord(boundingBox.maxX()), SectionPos.blockToSectionCoord(boundingBox.maxZ())); + ChunkPos.rangeClosed(min, max).forEach((chunkPosx) -> structureStart.placeInChunk(proxyLevel, originalWorld.structureManager(), chunkManager.getGenerator(), originalWorld.getRandom(), new BoundingBox(chunkPosx.getMinBlockX(), originalWorld.getMinBuildHeight(), chunkPosx.getMinBlockZ(), chunkPosx.getMaxBlockX(), originalWorld.getMaxBuildHeight(), chunkPosx.getMaxBlockZ()), chunkPosx)); + return true; + } + } + // ------------------------------------------------------------------------ // Code that is less likely to break // ------------------------------------------------------------------------ diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index 29da94026..f6b3853fc 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -55,6 +55,7 @@ import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; +import com.sk89q.worldedit.world.generation.StructureType; import com.sk89q.worldedit.world.weather.WeatherType; import com.sk89q.worldedit.world.weather.WeatherTypes; import io.papermc.lib.PaperLib; @@ -530,6 +531,16 @@ public class BukkitWorld extends AbstractWorld { return false; } + @Override + public boolean generateStructure(StructureType type, EditSession editSession, BlockVector3 position) { + BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); + if (adapter != null) { + return adapter.generateStructure(type, getWorld(), editSession, position); + } + // No adapter, we can't generate this. + return false; + } + private static volatile boolean hasWarnedImplError = false; @Override diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java index f1bce3a52..f27d2eb4c 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java @@ -51,6 +51,7 @@ import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; +import com.sk89q.worldedit.world.generation.StructureType; import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.registry.BlockMaterial; import org.bukkit.Keyed; @@ -295,6 +296,19 @@ public interface BukkitImplAdapter extends IBukkitAdapter { throw new UnsupportedOperationException("This adapter does not support generating features."); } + /** + * Generates a Minecraft structure at the given location. + * + * @param feature The feature + * @param world The world + * @param session The EditSession + * @param pt The location + * @return If it succeeded + */ + default boolean generateStructure(StructureType feature, World world, EditSession session, BlockVector3 pt) { + throw new UnsupportedOperationException("This adapter does not support generating features."); + } + //FAWE start default BlockMaterial getMaterial(BlockType blockType) { return getMaterial(blockType.getDefaultState()); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java index 5129f2dd1..1ae9f10ce 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java @@ -57,6 +57,7 @@ import com.sk89q.worldedit.util.formatting.text.TextComponent; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; +import com.sk89q.worldedit.world.generation.StructureType; import org.enginehub.piston.annotation.Command; import org.enginehub.piston.annotation.CommandContainer; import org.enginehub.piston.annotation.param.Arg; @@ -363,6 +364,23 @@ public class GenerationCommands { return 0; } + @Command( + name = "/structure", + desc = "Generate Minecraft structures" + ) + @CommandPermissions("worldedit.generation.structure") + @Logging(POSITION) + public int structure(Actor actor, LocalSession session, EditSession editSession, + @Arg(desc = "The structure") + StructureType feature) throws WorldEditException { + if (editSession.getWorld().generateStructure(feature, editSession, session.getPlacementPosition(actor))) { + actor.printInfo(Caption.of("worldedit.structure.created")); + } else { + actor.printError(Caption.of("worldedit.structure.failed")); + } + return 0; + } + @Command( name = "/hpyramid", desc = "Generate a hollow pyramid" diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/RegistryConverter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/RegistryConverter.java index 9ed38c642..c9b69cc30 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/RegistryConverter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/RegistryConverter.java @@ -33,6 +33,7 @@ import com.sk89q.worldedit.world.fluid.FluidCategory; import com.sk89q.worldedit.world.fluid.FluidType; import com.sk89q.worldedit.world.gamemode.GameMode; import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; +import com.sk89q.worldedit.world.generation.StructureType; import com.sk89q.worldedit.world.item.ItemCategory; import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.weather.WeatherType; @@ -64,7 +65,8 @@ public final class RegistryConverter implements ArgumentConvert FluidCategory.class, GameMode.class, WeatherType.class, - ConfiguredFeatureType.class + ConfiguredFeatureType.class, + StructureType.class ) .stream() .map(c -> (Class) c) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java index 176b22299..ebcaf6008 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java @@ -47,6 +47,7 @@ import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; +import com.sk89q.worldedit.world.generation.StructureType; import com.sk89q.worldedit.world.weather.WeatherType; import javax.annotation.Nullable; @@ -312,6 +313,10 @@ public interface World extends Extent, Keyed, IChunkCache { boolean generateTree(TreeGenerator.TreeType type, EditSession editSession, BlockVector3 position) throws MaxChangedBlocksException; + default boolean generateStructure(StructureType type, EditSession editSession, BlockVector3 position) { + return false; + } + /** * Generate a feature at the given position. * diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/StructureType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/StructureType.java new file mode 100644 index 000000000..e4e8aaebb --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/StructureType.java @@ -0,0 +1,43 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.world.generation; + +import com.sk89q.worldedit.registry.Keyed; +import com.sk89q.worldedit.registry.NamespacedRegistry; + +public class StructureType implements Keyed { + public static final NamespacedRegistry REGISTRY = new NamespacedRegistry<>("structure type"); + + private final String id; + + public StructureType(String id) { + this.id = id; + } + + @Override + public String getId() { + return this.id; + } + + @Override + public String toString() { + return this.id; + } +} diff --git a/worldedit-core/src/main/resources/lang/strings.json b/worldedit-core/src/main/resources/lang/strings.json index 21359defd..1e34364e2 100644 --- a/worldedit-core/src/main/resources/lang/strings.json +++ b/worldedit-core/src/main/resources/lang/strings.json @@ -503,6 +503,8 @@ "worldedit.pyramid.created": "{0} blocks have been created.", "worldedit.generate.created": "{0} blocks have been created.", "worldedit.generatebiome.changed": "{0} biomes affected.", + "worldedit.structure.created": "Structure created.", + "worldedit.structure.failed": "Failed to generate structure. Is it a valid spot for it?", "worldedit.reload.config": "Configuration reloaded!", "worldedit.report.written": "FAWE report written to {0}", "worldedit.report.error": "Failed to write report: {0}", From 594527f356bbd0081129f4e124b087ab03ee4cd2 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Tue, 24 Oct 2023 17:32:55 +0100 Subject: [PATCH 03/12] FAWE-inate --- .../FaweBlockStateListPopulator.java | 93 +++++++++ .../v1_17_R1_2/PaperweightFaweAdapter.java | 173 +++++++++++++++++ .../v1_18_R2/FaweBlockStateListPopulator.java | 100 ++++++++++ .../fawe/v1_18_R2/PaperweightFaweAdapter.java | 170 +++++++++++++++++ .../v1_19_R3/FaweBlockStateListPopulator.java | 106 +++++++++++ .../fawe/v1_19_R3/PaperweightFaweAdapter.java | 170 +++++++++++++++++ .../PaperweightServerLevelDelegateProxy.java | 2 +- .../v1_20_R1/FaweBlockStateListPopulator.java | 106 +++++++++++ .../fawe/v1_20_R1/PaperweightFaweAdapter.java | 171 +++++++++++++++++ .../ext/fawe/v1_20_R2/PaperweightAdapter.java | 15 ++ .../PaperweightServerLevelDelegateProxy.java | 121 ++++++++++++ .../v1_20_R2/FaweBlockStateListPopulator.java | 132 +++++++++++++ .../fawe/v1_20_R2/PaperweightFaweAdapter.java | 179 ++++++++++++++++++ .../bukkit/adapter/IBukkitAdapter.java | 8 + .../worldedit/bukkit/WorldEditPlugin.java | 3 +- .../factory/StructureGeneratorFactory.java | 46 +++++ .../core/command/tool/FeaturePlacer.java | 77 ++++++++ .../core/command/tool/StructurePlacer.java | 77 ++++++++ .../generator/StructureGenerator.java | 30 +++ .../core/wrappers/WorldWrapper.java | 23 ++- .../java/com/sk89q/worldedit/EditSession.java | 26 +++ .../worldedit/command/BrushCommands.java | 22 ++- .../worldedit/command/GenerationCommands.java | 41 ++-- .../sk89q/worldedit/command/ToolCommands.java | 34 ++++ .../java/com/sk89q/worldedit/world/World.java | 12 +- .../generation/ConfiguredFeatureType.java | 15 ++ .../world/generation/StructureType.java | 15 ++ .../src/main/resources/lang/strings.json | 8 +- 28 files changed, 1948 insertions(+), 27 deletions(-) create mode 100644 worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/FaweBlockStateListPopulator.java create mode 100644 worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/FaweBlockStateListPopulator.java create mode 100644 worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/FaweBlockStateListPopulator.java create mode 100644 worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/FaweBlockStateListPopulator.java create mode 100644 worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightServerLevelDelegateProxy.java create mode 100644 worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/FaweBlockStateListPopulator.java create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/command/factory/StructureGeneratorFactory.java create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/FeaturePlacer.java create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/StructurePlacer.java create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/StructureGenerator.java diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/FaweBlockStateListPopulator.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/FaweBlockStateListPopulator.java new file mode 100644 index 000000000..acd4823c5 --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/FaweBlockStateListPopulator.java @@ -0,0 +1,93 @@ +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeManager; +import net.minecraft.world.level.border.WorldBorder; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkSource; +import net.minecraft.world.level.chunk.ChunkStatus; +import net.minecraft.world.level.lighting.LevelLightEngine; +import net.minecraft.world.level.material.FluidState; +import org.bukkit.craftbukkit.v1_17_R1.util.BlockStateListPopulator; +import org.jetbrains.annotations.Nullable; + +public class FaweBlockStateListPopulator extends BlockStateListPopulator { + + private final ServerLevel world; + + public FaweBlockStateListPopulator(ServerLevel world) { + super(world); + this.world = world; + } + + @Override + public long getSeed() { + return world.getSeed(); + } + + @Override + public ServerLevel getLevel() { + return world.getLevel(); + } + + @Override + public MinecraftServer getServer() { + return world.getServer(); + } + + @Override + public ChunkSource getChunkSource() { + return world.getChunkSource(); + } + + @Override + public ChunkAccess getChunk(final int chunkX, final int chunkZ, final ChunkStatus leastStatus, final boolean create) { + return world.getChunk(chunkX, chunkZ, leastStatus, create); + } + + @Override + public BiomeManager getBiomeManager() { + return world.getBiomeManager(); + } + + @Override + public Biome getUncachedNoiseBiome(final int biomeX, final int biomeY, final int biomeZ) { + return world.getUncachedNoiseBiome(biomeX, biomeY, biomeZ); + } + + @Override + public int getSeaLevel() { + return world.getSeaLevel(); + } + + @Override + public float getShade(final Direction direction, final boolean shaded) { + return world.getShade(direction, shaded); + } + + @Override + public LevelLightEngine getLightEngine() { + return world.getLightEngine(); + } + + @Nullable + @Override + public ChunkAccess getChunkIfLoadedImmediately(final int x, final int z) { + return world.getChunkIfLoadedImmediately(x, z); + } + + @Override + public FluidState getFluidIfLoaded(final BlockPos blockposition) { + return world.getFluidIfLoaded(blockposition); + } + + @Override + public WorldBorder getWorldBorder() { + return world.getWorldBorder(); + } + +} diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightFaweAdapter.java index 2029be6f9..273d43590 100644 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightFaweAdapter.java @@ -14,6 +14,7 @@ import com.fastasyncworldedit.core.util.TaskManager; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.blocks.BaseItemStack; @@ -53,35 +54,48 @@ import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypesCache; import com.sk89q.worldedit.world.entity.EntityType; +import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; +import com.sk89q.worldedit.world.generation.StructureType; import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.registry.BlockMaterial; import net.minecraft.core.BlockPos; import net.minecraft.core.Registry; +import net.minecraft.core.SectionPos; import net.minecraft.core.WritableRegistry; import net.minecraft.nbt.IntTag; import net.minecraft.network.protocol.game.ClientboundLevelChunkPacket; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; +import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.level.ChunkHolder; +import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.util.StringRepresentable; import net.minecraft.world.entity.Entity; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.Level; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; +import net.minecraft.world.level.levelgen.feature.configurations.StructureFeatureConfiguration; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.level.levelgen.structure.StructureStart; import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.TreeType; +import org.bukkit.World; import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.v1_17_R1.CraftChunk; import org.bukkit.craftbukkit.v1_17_R1.CraftServer; @@ -105,6 +119,7 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.OptionalInt; +import java.util.Random; import java.util.Set; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -589,6 +604,164 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements return true; } + @Override + public boolean generateFeature(ConfiguredFeatureType feature, World world, EditSession editSession, BlockVector3 pt) { + ServerLevel serverLevel = ((CraftWorld) world).getHandle(); + ChunkGenerator generator = serverLevel.getMinecraftWorld().getChunkSource().getGenerator(); + FaweBlockStateListPopulator populator = new FaweBlockStateListPopulator(serverLevel); + ConfiguredFeature configuredFeature = serverLevel + .registryAccess() + .registryOrThrow(Registry.CONFIGURED_FEATURE_REGISTRY) + .get(ResourceLocation.tryParse(feature.getId())); + + Map placed = TaskManager.taskManager().sync(() -> { + serverLevel.captureTreeGeneration = true; + serverLevel.captureBlockStates = true; + try { + if (!configuredFeature.place( + populator, + generator, + serverLevel.random, + new BlockPos(pt.getX(), pt.getY(), pt.getZ()) + )) { + return null; + } + return populator.getList().stream().collect(Collectors.toMap(CraftBlockState::getPosition, + craftBlockState -> craftBlockState + )); + } finally { + serverLevel.captureBlockStates = false; + serverLevel.captureTreeGeneration = false; + serverLevel.capturedBlockStates.clear(); + } + }); + + return placeFeatureIntoSession(editSession, populator, placed); + //FAWE end + } + + @Override + public boolean generateStructure(StructureType type, World world, EditSession editSession, BlockVector3 pt) { + ServerLevel serverLevel = ((CraftWorld) world).getHandle(); + ConfiguredStructureFeature k = serverLevel + .registryAccess() + .registryOrThrow(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY) + .get(ResourceLocation.tryParse(type.getId())); + if (k == null) { + return false; + } + + ServerChunkCache chunkManager = serverLevel.getChunkSource(); + + BlockPos pos = new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()); + ChunkPos chunkPos = new ChunkPos(pos); + + //FAWE start + FaweBlockStateListPopulator populator = new FaweBlockStateListPopulator(serverLevel); + Map placed = TaskManager.taskManager().sync(() -> { + serverLevel.captureTreeGeneration = true; + serverLevel.captureBlockStates = true; + try { + StructureStart structureStart = k.generate( + serverLevel.registryAccess(), + chunkManager.getGenerator(), + chunkManager.getGenerator().getBiomeSource(), + serverLevel.getStructureManager(), + serverLevel.getSeed(), + chunkPos, + serverLevel.getBiome(pos), + 0, + (StructureFeatureConfiguration) k.config, + serverLevel + ); + if (!structureStart.isValid()) { + return null; + } else { + BoundingBox boundingBox = structureStart.getBoundingBox(); + ChunkPos min = new ChunkPos( + SectionPos.blockToSectionCoord(boundingBox.minX()), + SectionPos.blockToSectionCoord(boundingBox.minZ()) + ); + ChunkPos max = new ChunkPos( + SectionPos.blockToSectionCoord(boundingBox.maxX()), + SectionPos.blockToSectionCoord(boundingBox.maxZ()) + ); + ChunkPos.rangeClosed(min, max).forEach((chunkPosx) -> structureStart.placeInChunk( + serverLevel, + serverLevel.structureFeatureManager(), + chunkManager.getGenerator(), + serverLevel.getRandom(), + new BoundingBox( + chunkPosx.getMinBlockX(), + serverLevel.getMinBuildHeight(), + chunkPosx.getMinBlockZ(), + chunkPosx.getMaxBlockX(), + serverLevel.getMaxBuildHeight(), + chunkPosx.getMaxBlockZ() + ), + chunkPosx + )); + return populator.getList().stream().collect(Collectors.toMap( + CraftBlockState::getPosition, + craftBlockState -> craftBlockState + )); + } + } finally { + serverLevel.captureBlockStates = false; + serverLevel.captureTreeGeneration = false; + serverLevel.capturedBlockStates.clear(); + } + }); + + return placeFeatureIntoSession(editSession, populator, placed); + //FAWE end + } + + private boolean placeFeatureIntoSession( + final EditSession editSession, + final FaweBlockStateListPopulator populator, + final Map placed + ) { + if (placed == null || placed.isEmpty()) { + return false; + } + + for (Map.Entry entry : placed.entrySet()) { + CraftBlockState craftBlockState = entry.getValue(); + if (entry.getValue() == null) { + continue; + } + BlockPos pos = entry.getKey(); + editSession.setBlock(pos.getX(), pos.getY(), pos.getZ(), BukkitAdapter.adapt(craftBlockState.getBlockData())); + BlockEntity blockEntity = populator.getBlockEntity(pos); + if (blockEntity != null) { + net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); + blockEntity.save(tag); + editSession.setTile(pos.getX(), pos.getY(), pos.getZ(), (CompoundTag) toNative(tag)); + } + } + return true; + } + + @Override + public void setupFeatures() { + DedicatedServer server = ((CraftServer) Bukkit.getServer()).getServer(); + + // Features + for (ResourceLocation name : server.registryAccess().registryOrThrow(Registry.CONFIGURED_FEATURE_REGISTRY).keySet()) { + if (ConfiguredFeatureType.REGISTRY.get(name.toString()) == null) { + ConfiguredFeatureType.REGISTRY.register(name.toString(), new ConfiguredFeatureType(name.toString())); + } + } + + // Structures + for (ResourceLocation name : server.registryAccess().registryOrThrow(Registry.STRUCTURE_FEATURE_REGISTRY).keySet()) { + if (StructureType.REGISTRY.get(name.toString()) == null) { + StructureType.REGISTRY.register(name.toString(), new StructureType(name.toString())); + } + } + } + @Override public List getEntities(org.bukkit.World world) { // Quickly add each entity to a list copy. diff --git a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/FaweBlockStateListPopulator.java b/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/FaweBlockStateListPopulator.java new file mode 100644 index 000000000..43e99c245 --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/FaweBlockStateListPopulator.java @@ -0,0 +1,100 @@ +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Holder; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeManager; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.border.WorldBorder; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkSource; +import net.minecraft.world.level.chunk.ChunkStatus; +import net.minecraft.world.level.lighting.LevelLightEngine; +import net.minecraft.world.level.material.FluidState; +import org.bukkit.craftbukkit.v1_18_R2.util.BlockStateListPopulator; +import org.jetbrains.annotations.Nullable; + +public class FaweBlockStateListPopulator extends BlockStateListPopulator { + + private final ServerLevel world; + + public FaweBlockStateListPopulator(ServerLevel world) { + super(world); + this.world = world; + } + + @Override + public long getSeed() { + return world.getSeed(); + } + + @Override + public ServerLevel getLevel() { + return world.getLevel(); + } + + @Override + public MinecraftServer getServer() { + return world.getServer(); + } + + @Override + public ChunkSource getChunkSource() { + return world.getChunkSource(); + } + + @Override + public ChunkAccess getChunk(final int chunkX, final int chunkZ, final ChunkStatus leastStatus, final boolean create) { + return world.getChunk(chunkX, chunkZ, leastStatus, create); + } + + @Override + public BiomeManager getBiomeManager() { + return world.getBiomeManager(); + } + + @Override + public Holder getUncachedNoiseBiome(final int biomeX, final int biomeY, final int biomeZ) { + return world.getUncachedNoiseBiome(biomeX, biomeY, biomeZ); + } + + @Override + public int getSeaLevel() { + return world.getSeaLevel(); + } + + @Override + public float getShade(final Direction direction, final boolean shaded) { + return world.getShade(direction, shaded); + } + + @Override + public LevelLightEngine getLightEngine() { + return world.getLightEngine(); + } + + @Nullable + @Override + public ChunkAccess getChunkIfLoadedImmediately(final int x, final int z) { + return world.getChunkIfLoadedImmediately(x, z); + } + + @Override + public BlockState getBlockStateIfLoaded(final BlockPos blockposition) { + return world.getBlockStateIfLoaded(blockposition); + } + + @Override + public FluidState getFluidIfLoaded(final BlockPos blockposition) { + return world.getFluidIfLoaded(blockposition); + } + + @Override + public WorldBorder getWorldBorder() { + return world.getWorldBorder(); + } + +} diff --git a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightFaweAdapter.java index 49125529d..adfc5537e 100644 --- a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightFaweAdapter.java @@ -14,6 +14,7 @@ import com.fastasyncworldedit.core.util.TaskManager; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.blocks.BaseItemStack; @@ -53,36 +54,48 @@ import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypesCache; import com.sk89q.worldedit.world.entity.EntityType; +import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; +import com.sk89q.worldedit.world.generation.StructureType; import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.registry.BlockMaterial; import io.papermc.lib.PaperLib; import net.minecraft.core.BlockPos; import net.minecraft.core.Registry; +import net.minecraft.core.SectionPos; import net.minecraft.core.WritableRegistry; import net.minecraft.nbt.IntTag; import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; +import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.level.ChunkHolder; +import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.util.StringRepresentable; import net.minecraft.world.entity.Entity; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.Level; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.level.levelgen.structure.StructureStart; import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.TreeType; +import org.bukkit.World; import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.v1_18_R2.CraftChunk; import org.bukkit.craftbukkit.v1_18_R2.CraftServer; @@ -581,6 +594,163 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements return true; } + @Override + public boolean generateFeature(ConfiguredFeatureType feature, World world, EditSession editSession, BlockVector3 pt) { + ServerLevel serverLevel = ((CraftWorld) world).getHandle(); + ChunkGenerator generator = serverLevel.getMinecraftWorld().getChunkSource().getGenerator(); + + Registry> registry = serverLevel + .registryAccess() + .registryOrThrow(Registry.CONFIGURED_FEATURE_REGISTRY); + ConfiguredFeature configuredFeature = registry.get(ResourceLocation.tryParse(feature.getId())); + FaweBlockStateListPopulator populator = new FaweBlockStateListPopulator(serverLevel); + + Map placed = TaskManager.taskManager().sync(() -> { + serverLevel.captureTreeGeneration = true; + serverLevel.captureBlockStates = true; + try { + if (!configuredFeature.place( + populator, + generator, + serverLevel.random, + new BlockPos(pt.getX(), pt.getY(), pt.getZ()) + )) { + return null; + } + return populator.getList().stream().collect(Collectors.toMap( + CraftBlockState::getPosition, + craftBlockState -> craftBlockState + )); + } finally { + serverLevel.captureBlockStates = false; + serverLevel.captureTreeGeneration = false; + serverLevel.capturedBlockStates.clear(); + } + }); + + return placeFeatureIntoSession(editSession, populator, placed); + //FAWE end + } + + @Override + public boolean generateStructure(StructureType type, World world, EditSession editSession, BlockVector3 pt) { + ServerLevel serverLevel = ((CraftWorld) world).getHandle(); + ConfiguredStructureFeature k = serverLevel + .registryAccess() + .registryOrThrow(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY) + .get(ResourceLocation.tryParse(type.getId())); + if (k == null) { + return false; + } + + ServerChunkCache chunkManager = serverLevel.getChunkSource(); + + ChunkPos chunkPos = new ChunkPos(new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ())); + + //FAWE start + FaweBlockStateListPopulator populator = new FaweBlockStateListPopulator(serverLevel); + Map placed = TaskManager.taskManager().sync(() -> { + serverLevel.captureTreeGeneration = true; + serverLevel.captureBlockStates = true; + try { + StructureStart structureStart = k.generate( + serverLevel.registryAccess(), + chunkManager.getGenerator(), + chunkManager.getGenerator().getBiomeSource(), + serverLevel.getStructureManager(), + serverLevel.getSeed(), + chunkPos, + 0, + serverLevel, + biome -> true + ); + if (!structureStart.isValid()) { + return null; + } else { + BoundingBox boundingBox = structureStart.getBoundingBox(); + ChunkPos min = new ChunkPos( + SectionPos.blockToSectionCoord(boundingBox.minX()), + SectionPos.blockToSectionCoord(boundingBox.minZ()) + ); + ChunkPos max = new ChunkPos( + SectionPos.blockToSectionCoord(boundingBox.maxX()), + SectionPos.blockToSectionCoord(boundingBox.maxZ()) + ); + ChunkPos.rangeClosed(min, max).forEach((chunkPosx) -> structureStart.placeInChunk( + serverLevel, + serverLevel.structureFeatureManager(), + chunkManager.getGenerator(), + serverLevel.getRandom(), + new BoundingBox( + chunkPosx.getMinBlockX(), + serverLevel.getMinBuildHeight(), + chunkPosx.getMinBlockZ(), + chunkPosx.getMaxBlockX(), + serverLevel.getMaxBuildHeight(), + chunkPosx.getMaxBlockZ() + ), + chunkPosx + )); + return populator.getList().stream().collect(Collectors.toMap( + CraftBlockState::getPosition, + craftBlockState -> craftBlockState + )); + } + } finally { + serverLevel.captureBlockStates = false; + serverLevel.captureTreeGeneration = false; + serverLevel.capturedBlockStates.clear(); + } + }); + + return placeFeatureIntoSession(editSession, populator, placed); + //FAWE end + } + + private boolean placeFeatureIntoSession( + final EditSession editSession, + final FaweBlockStateListPopulator populator, + final Map placed + ) { + if (placed == null || placed.isEmpty()) { + return false; + } + + for (Map.Entry entry : placed.entrySet()) { + CraftBlockState craftBlockState = entry.getValue(); + if (entry.getValue() == null) { + continue; + } + BlockPos pos = entry.getKey(); + editSession.setBlock(pos.getX(), pos.getY(), pos.getZ(), BukkitAdapter.adapt(craftBlockState.getBlockData())); + BlockEntity blockEntity = populator.getBlockEntity(pos); + if (blockEntity != null) { + net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(); + editSession.setTile(pos.getX(), pos.getY(), pos.getZ(), (CompoundTag) toNative(tag)); + } + } + return true; + } + + @Override + public void setupFeatures() { + DedicatedServer server = ((CraftServer) Bukkit.getServer()).getServer(); + + // Features + for (ResourceLocation name : server.registryAccess().registryOrThrow(Registry.CONFIGURED_FEATURE_REGISTRY).keySet()) { + if (ConfiguredFeatureType.REGISTRY.get(name.toString()) == null) { + ConfiguredFeatureType.REGISTRY.register(name.toString(), new ConfiguredFeatureType(name.toString())); + } + } + + // Structures + for (ResourceLocation name : server.registryAccess().registryOrThrow(Registry.STRUCTURE_FEATURE_REGISTRY).keySet()) { + if (StructureType.REGISTRY.get(name.toString()) == null) { + StructureType.REGISTRY.register(name.toString(), new StructureType(name.toString())); + } + } + } + @Override public List getEntities(org.bukkit.World world) { // Quickly add each entity to a list copy. diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/FaweBlockStateListPopulator.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/FaweBlockStateListPopulator.java new file mode 100644 index 000000000..1e9eef179 --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/FaweBlockStateListPopulator.java @@ -0,0 +1,106 @@ +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Holder; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.flag.FeatureFlagSet; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeManager; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.border.WorldBorder; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkSource; +import net.minecraft.world.level.chunk.ChunkStatus; +import net.minecraft.world.level.lighting.LevelLightEngine; +import net.minecraft.world.level.material.FluidState; +import org.bukkit.craftbukkit.v1_19_R3.util.BlockStateListPopulator; +import org.jetbrains.annotations.Nullable; + +public class FaweBlockStateListPopulator extends BlockStateListPopulator { + + private final ServerLevel world; + + public FaweBlockStateListPopulator(ServerLevel world) { + super(world); + this.world = world; + } + + @Override + public long getSeed() { + return world.getSeed(); + } + + @Override + public ServerLevel getLevel() { + return world.getLevel(); + } + + @Override + public MinecraftServer getServer() { + return world.getServer(); + } + + @Override + public ChunkSource getChunkSource() { + return world.getChunkSource(); + } + + @Override + public ChunkAccess getChunk(final int chunkX, final int chunkZ, final ChunkStatus leastStatus, final boolean create) { + return world.getChunk(chunkX, chunkZ, leastStatus, create); + } + + @Override + public BiomeManager getBiomeManager() { + return world.getBiomeManager(); + } + + @Override + public Holder getUncachedNoiseBiome(final int biomeX, final int biomeY, final int biomeZ) { + return world.getUncachedNoiseBiome(biomeX, biomeY, biomeZ); + } + + @Override + public int getSeaLevel() { + return world.getSeaLevel(); + } + + @Override + public FeatureFlagSet enabledFeatures() { + return world.enabledFeatures(); + } + + @Override + public float getShade(final Direction direction, final boolean shaded) { + return world.getShade(direction, shaded); + } + + @Override + public LevelLightEngine getLightEngine() { + return world.getLightEngine(); + } + + @Nullable + @Override + public ChunkAccess getChunkIfLoadedImmediately(final int x, final int z) { + return world.getChunkIfLoadedImmediately(x, z); + } + + @Override + public BlockState getBlockStateIfLoaded(final BlockPos blockposition) { + return world.getBlockStateIfLoaded(blockposition); + } + + @Override + public FluidState getFluidIfLoaded(final BlockPos blockposition) { + return world.getFluidIfLoaded(blockposition); + } + + @Override + public WorldBorder getWorldBorder() { + return world.getWorldBorder(); + } + +} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java index 82aba5fb6..488913a0a 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java @@ -14,6 +14,7 @@ import com.fastasyncworldedit.core.util.TaskManager; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.blocks.BaseItemStack; @@ -51,11 +52,14 @@ import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypesCache; import com.sk89q.worldedit.world.entity.EntityType; +import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; +import com.sk89q.worldedit.world.generation.StructureType; import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.registry.BlockMaterial; import io.papermc.lib.PaperLib; import net.minecraft.core.BlockPos; import net.minecraft.core.Registry; +import net.minecraft.core.SectionPos; import net.minecraft.core.WritableRegistry; import net.minecraft.core.registries.Registries; import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; @@ -63,23 +67,31 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.level.ChunkHolder; +import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.util.StringRepresentable; import net.minecraft.world.entity.Entity; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.level.levelgen.structure.Structure; +import net.minecraft.world.level.levelgen.structure.StructureStart; import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.TreeType; +import org.bukkit.World; import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.v1_19_R3.CraftServer; import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; @@ -544,6 +556,164 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements return true; } + @Override + public boolean generateFeature(ConfiguredFeatureType feature, World world, EditSession editSession, BlockVector3 pt) { + ServerLevel serverLevel = ((CraftWorld) world).getHandle(); + ChunkGenerator generator = serverLevel.getMinecraftWorld().getChunkSource().getGenerator(); + + ConfiguredFeature configuredFeature = serverLevel + .registryAccess() + .registryOrThrow(Registries.CONFIGURED_FEATURE) + .get(ResourceLocation.tryParse(feature.getId())); + FaweBlockStateListPopulator populator = new FaweBlockStateListPopulator(serverLevel); + + Map placed = TaskManager.taskManager().sync(() -> { + serverLevel.captureTreeGeneration = true; + serverLevel.captureBlockStates = true; + try { + if (!configuredFeature.place( + populator, + generator, + serverLevel.random, + new BlockPos(pt.getX(), pt.getY(), pt.getZ()) + )) { + return null; + } + return populator.getList().stream().collect(Collectors.toMap( + CraftBlockState::getPosition, + craftBlockState -> craftBlockState + )); + } finally { + serverLevel.captureBlockStates = false; + serverLevel.captureTreeGeneration = false; + serverLevel.capturedBlockStates.clear(); + } + }); + + return placeFeatureIntoSession(editSession, populator, placed); + //FAWE end + } + + @Override + public boolean generateStructure(StructureType type, World world, EditSession editSession, BlockVector3 pt) { + ServerLevel serverLevel = ((CraftWorld) world).getHandle(); + Structure k = serverLevel + .registryAccess() + .registryOrThrow(Registries.STRUCTURE) + .get(ResourceLocation.tryParse(type.getId())); + if (k == null) { + return false; + } + + ServerChunkCache chunkManager = serverLevel.getChunkSource(); + + ChunkPos chunkPos = new ChunkPos(new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ())); + + //FAWE start + FaweBlockStateListPopulator populator = new FaweBlockStateListPopulator(serverLevel); + Map placed = TaskManager.taskManager().sync(() -> { + serverLevel.captureTreeGeneration = true; + serverLevel.captureBlockStates = true; + try { + StructureStart structureStart = k.generate( + serverLevel.registryAccess(), + chunkManager.getGenerator(), + chunkManager.getGenerator().getBiomeSource(), + chunkManager.randomState(), + serverLevel.getStructureManager(), + serverLevel.getSeed(), + chunkPos, + 0, + serverLevel, + biome -> true + ); + if (!structureStart.isValid()) { + return null; + } else { + BoundingBox boundingBox = structureStart.getBoundingBox(); + ChunkPos min = new ChunkPos( + SectionPos.blockToSectionCoord(boundingBox.minX()), + SectionPos.blockToSectionCoord(boundingBox.minZ()) + ); + ChunkPos max = new ChunkPos( + SectionPos.blockToSectionCoord(boundingBox.maxX()), + SectionPos.blockToSectionCoord(boundingBox.maxZ()) + ); + ChunkPos.rangeClosed(min, max).forEach((chunkPosx) -> structureStart.placeInChunk( + serverLevel, + serverLevel.structureManager(), + chunkManager.getGenerator(), + serverLevel.getRandom(), + new BoundingBox( + chunkPosx.getMinBlockX(), + serverLevel.getMinBuildHeight(), + chunkPosx.getMinBlockZ(), + chunkPosx.getMaxBlockX(), + serverLevel.getMaxBuildHeight(), + chunkPosx.getMaxBlockZ() + ), + chunkPosx + )); + return populator.getList().stream().collect(Collectors.toMap( + CraftBlockState::getPosition, + craftBlockState -> craftBlockState + )); + } + } finally { + serverLevel.captureBlockStates = false; + serverLevel.captureTreeGeneration = false; + serverLevel.capturedBlockStates.clear(); + } + }); + + return placeFeatureIntoSession(editSession, populator, placed); + //FAWE end + } + + private boolean placeFeatureIntoSession( + final EditSession editSession, + final FaweBlockStateListPopulator populator, + final Map placed + ) { + if (placed == null || placed.isEmpty()) { + return false; + } + + for (Map.Entry entry : placed.entrySet()) { + CraftBlockState craftBlockState = entry.getValue(); + if (entry.getValue() == null) { + continue; + } + BlockPos pos = entry.getKey(); + editSession.setBlock(pos.getX(), pos.getY(), pos.getZ(), BukkitAdapter.adapt(craftBlockState.getBlockData())); + BlockEntity blockEntity = populator.getBlockEntity(pos); + if (blockEntity != null) { + net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(); + editSession.setTile(pos.getX(), pos.getY(), pos.getZ(), (CompoundTag) toNative(tag)); + } + } + return true; + } + + @Override + public void setupFeatures() { + DedicatedServer server = ((CraftServer) Bukkit.getServer()).getServer(); + + // Features + for (ResourceLocation name : server.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).keySet()) { + if (ConfiguredFeatureType.REGISTRY.get(name.toString()) == null) { + ConfiguredFeatureType.REGISTRY.register(name.toString(), new ConfiguredFeatureType(name.toString())); + } + } + + // Structures + for (ResourceLocation name : server.registryAccess().registryOrThrow(Registries.STRUCTURE).keySet()) { + if (StructureType.REGISTRY.get(name.toString()) == null) { + StructureType.REGISTRY.register(name.toString(), new StructureType(name.toString())); + } + } + } + @Override public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) { final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightServerLevelDelegateProxy.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightServerLevelDelegateProxy.java index 23d4aa821..17b10a2d4 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightServerLevelDelegateProxy.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightServerLevelDelegateProxy.java @@ -35,7 +35,7 @@ import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; -public class PaperweightServerLevelDelegateProxy implements InvocationHandler { +public class PaperweightServerLevelDelegateProxy implements InvocationHandler { private final EditSession editSession; private final ServerLevel serverLevel; diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/FaweBlockStateListPopulator.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/FaweBlockStateListPopulator.java new file mode 100644 index 000000000..9989ed781 --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/FaweBlockStateListPopulator.java @@ -0,0 +1,106 @@ +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Holder; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.flag.FeatureFlagSet; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeManager; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.border.WorldBorder; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkSource; +import net.minecraft.world.level.chunk.ChunkStatus; +import net.minecraft.world.level.lighting.LevelLightEngine; +import net.minecraft.world.level.material.FluidState; +import org.bukkit.craftbukkit.v1_20_R1.util.BlockStateListPopulator; +import org.jetbrains.annotations.Nullable; + +public class FaweBlockStateListPopulator extends BlockStateListPopulator { + + private final ServerLevel world; + + public FaweBlockStateListPopulator(ServerLevel world) { + super(world); + this.world = world; + } + + @Override + public long getSeed() { + return world.getSeed(); + } + + @Override + public ServerLevel getLevel() { + return world.getLevel(); + } + + @Override + public MinecraftServer getServer() { + return world.getServer(); + } + + @Override + public ChunkSource getChunkSource() { + return world.getChunkSource(); + } + + @Override + public ChunkAccess getChunk(final int chunkX, final int chunkZ, final ChunkStatus leastStatus, final boolean create) { + return world.getChunk(chunkX, chunkZ, leastStatus, create); + } + + @Override + public BiomeManager getBiomeManager() { + return world.getBiomeManager(); + } + + @Override + public Holder getUncachedNoiseBiome(final int biomeX, final int biomeY, final int biomeZ) { + return world.getUncachedNoiseBiome(biomeX, biomeY, biomeZ); + } + + @Override + public int getSeaLevel() { + return world.getSeaLevel(); + } + + @Override + public FeatureFlagSet enabledFeatures() { + return world.enabledFeatures(); + } + + @Override + public float getShade(final Direction direction, final boolean shaded) { + return world.getShade(direction, shaded); + } + + @Override + public LevelLightEngine getLightEngine() { + return world.getLightEngine(); + } + + @Nullable + @Override + public ChunkAccess getChunkIfLoadedImmediately(final int x, final int z) { + return world.getChunkIfLoadedImmediately(x, z); + } + + @Override + public BlockState getBlockStateIfLoaded(final BlockPos blockposition) { + return world.getBlockStateIfLoaded(blockposition); + } + + @Override + public FluidState getFluidIfLoaded(final BlockPos blockposition) { + return world.getFluidIfLoaded(blockposition); + } + + @Override + public WorldBorder getWorldBorder() { + return world.getWorldBorder(); + } + +} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java index aad40c611..5310e51d1 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java @@ -14,6 +14,7 @@ import com.fastasyncworldedit.core.util.TaskManager; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.blocks.BaseItemStack; @@ -51,11 +52,14 @@ import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypesCache; import com.sk89q.worldedit.world.entity.EntityType; +import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; +import com.sk89q.worldedit.world.generation.StructureType; import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.registry.BlockMaterial; import io.papermc.lib.PaperLib; import net.minecraft.core.BlockPos; import net.minecraft.core.Registry; +import net.minecraft.core.SectionPos; import net.minecraft.core.WritableRegistry; import net.minecraft.core.registries.Registries; import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; @@ -63,23 +67,31 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.level.ChunkHolder; +import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.util.StringRepresentable; import net.minecraft.world.entity.Entity; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.level.levelgen.structure.Structure; +import net.minecraft.world.level.levelgen.structure.StructureStart; import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.TreeType; +import org.bukkit.World; import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.v1_20_R1.CraftServer; import org.bukkit.craftbukkit.v1_20_R1.CraftWorld; @@ -544,6 +556,165 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements return true; } + @Override + public boolean generateFeature(ConfiguredFeatureType feature, World world, EditSession editSession, BlockVector3 pt) { + //FAWE start + ServerLevel serverLevel = ((CraftWorld) world).getHandle(); + ChunkGenerator generator = serverLevel.getMinecraftWorld().getChunkSource().getGenerator(); + + ConfiguredFeature configuredFeature = serverLevel + .registryAccess() + .registryOrThrow(Registries.CONFIGURED_FEATURE) + .get(ResourceLocation.tryParse(feature.getId())); + FaweBlockStateListPopulator populator = new FaweBlockStateListPopulator(serverLevel); + + Map placed = TaskManager.taskManager().sync(() -> { + serverLevel.captureTreeGeneration = true; + serverLevel.captureBlockStates = true; + try { + if (!configuredFeature.place( + populator, + generator, + serverLevel.random, + new BlockPos(pt.getX(), pt.getY(), pt.getZ()) + )) { + return null; + } + return populator.getList().stream().collect(Collectors.toMap( + CraftBlockState::getPosition, + craftBlockState -> craftBlockState + )); + } finally { + serverLevel.captureBlockStates = false; + serverLevel.captureTreeGeneration = false; + serverLevel.capturedBlockStates.clear(); + } + }); + + return placeFeatureIntoSession(editSession, populator, placed); + //FAWE end + } + + @Override + public boolean generateStructure(StructureType type, World world, EditSession editSession, BlockVector3 pt) { + ServerLevel serverLevel = ((CraftWorld) world).getHandle(); + Structure k = serverLevel + .registryAccess() + .registryOrThrow(Registries.STRUCTURE) + .get(ResourceLocation.tryParse(type.getId())); + if (k == null) { + return false; + } + + ServerChunkCache chunkManager = serverLevel.getChunkSource(); + + ChunkPos chunkPos = new ChunkPos(new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ())); + + //FAWE start + FaweBlockStateListPopulator populator = new FaweBlockStateListPopulator(serverLevel); + Map placed = TaskManager.taskManager().sync(() -> { + serverLevel.captureTreeGeneration = true; + serverLevel.captureBlockStates = true; + try { + StructureStart structureStart = k.generate( + serverLevel.registryAccess(), + chunkManager.getGenerator(), + chunkManager.getGenerator().getBiomeSource(), + chunkManager.randomState(), + serverLevel.getStructureManager(), + serverLevel.getSeed(), + chunkPos, + 0, + serverLevel, + biome -> true + ); + if (!structureStart.isValid()) { + return null; + } else { + BoundingBox boundingBox = structureStart.getBoundingBox(); + ChunkPos min = new ChunkPos( + SectionPos.blockToSectionCoord(boundingBox.minX()), + SectionPos.blockToSectionCoord(boundingBox.minZ()) + ); + ChunkPos max = new ChunkPos( + SectionPos.blockToSectionCoord(boundingBox.maxX()), + SectionPos.blockToSectionCoord(boundingBox.maxZ()) + ); + ChunkPos.rangeClosed(min, max).forEach((chunkPosx) -> structureStart.placeInChunk( + serverLevel, + serverLevel.structureManager(), + chunkManager.getGenerator(), + serverLevel.getRandom(), + new BoundingBox( + chunkPosx.getMinBlockX(), + serverLevel.getMinBuildHeight(), + chunkPosx.getMinBlockZ(), + chunkPosx.getMaxBlockX(), + serverLevel.getMaxBuildHeight(), + chunkPosx.getMaxBlockZ() + ), + chunkPosx + )); + return populator.getList().stream().collect(Collectors.toMap( + CraftBlockState::getPosition, + craftBlockState -> craftBlockState + )); + } + } finally { + serverLevel.captureBlockStates = false; + serverLevel.captureTreeGeneration = false; + serverLevel.capturedBlockStates.clear(); + } + }); + + return placeFeatureIntoSession(editSession, populator, placed); + //FAWE end + } + + private boolean placeFeatureIntoSession( + final EditSession editSession, + final FaweBlockStateListPopulator populator, + final Map placed + ) { + if (placed == null || placed.isEmpty()) { + return false; + } + + for (Map.Entry entry : placed.entrySet()) { + CraftBlockState craftBlockState = entry.getValue(); + if (entry.getValue() == null) { + continue; + } + BlockPos pos = entry.getKey(); + editSession.setBlock(pos.getX(), pos.getY(), pos.getZ(), BukkitAdapter.adapt(craftBlockState.getBlockData())); + BlockEntity blockEntity = populator.getBlockEntity(pos); + if (blockEntity != null) { + net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(); + editSession.setTile(pos.getX(), pos.getY(), pos.getZ(), (CompoundTag) toNative(tag)); + } + } + return true; + } + + @Override + public void setupFeatures() { + DedicatedServer server = ((CraftServer) Bukkit.getServer()).getServer(); + + // Features + for (ResourceLocation name : server.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).keySet()) { + if (ConfiguredFeatureType.REGISTRY.get(name.toString()) == null) { + ConfiguredFeatureType.REGISTRY.register(name.toString(), new ConfiguredFeatureType(name.toString())); + } + } + + // Structures + for (ResourceLocation name : server.registryAccess().registryOrThrow(Registries.STRUCTURE).keySet()) { + if (StructureType.REGISTRY.get(name.toString()) == null) { + StructureType.REGISTRY.register(name.toString(), new StructureType(name.toString())); + } + } + } + @Override public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) { final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java index b73e6d06e..31f4736e0 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java @@ -305,6 +305,21 @@ public final class PaperweightAdapter implements BukkitImplAdapter + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R2; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.world.block.BlockTypes; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +public class PaperweightServerLevelDelegateProxy implements InvocationHandler { + + private final EditSession editSession; + private final ServerLevel serverLevel; + private final PaperweightAdapter adapter; + + private PaperweightServerLevelDelegateProxy(EditSession editSession, ServerLevel serverLevel, PaperweightAdapter adapter) { + this.editSession = editSession; + this.serverLevel = serverLevel; + this.adapter = adapter; + } + + public static WorldGenLevel newInstance(EditSession editSession, ServerLevel serverLevel, PaperweightAdapter adapter) { + return (WorldGenLevel) Proxy.newProxyInstance( + serverLevel.getClass().getClassLoader(), + serverLevel.getClass().getInterfaces(), + new PaperweightServerLevelDelegateProxy(editSession, serverLevel, adapter) + ); + } + + @Nullable + private BlockEntity getBlockEntity(BlockPos blockPos) { + BlockEntity tileEntity = this.serverLevel.getChunkAt(blockPos).getBlockEntity(blockPos); + if (tileEntity == null) { + return null; + } + BlockEntity newEntity = tileEntity.getType().create(blockPos, getBlockState(blockPos)); + newEntity.load((CompoundTag) adapter.fromNativeBinary(this.editSession.getFullBlock(BlockVector3.at(blockPos.getX(), + blockPos.getY(), blockPos.getZ())).getNbtReference().getValue())); + + return newEntity; + } + + private BlockState getBlockState(BlockPos blockPos) { + return adapter.adapt(this.editSession.getBlock(BlockVector3.at(blockPos.getX(), blockPos.getY(), blockPos.getZ()))); + } + + private boolean setBlock(BlockPos blockPos, BlockState blockState) { + try { + return editSession.setBlock(BlockVector3.at(blockPos.getX(), blockPos.getY(), blockPos.getZ()), adapter.adapt(blockState)); + } catch (MaxChangedBlocksException e) { + throw new RuntimeException(e); + } + } + + private boolean removeBlock(BlockPos blockPos, boolean bl) { + try { + return editSession.setBlock(BlockVector3.at(blockPos.getX(), blockPos.getY(), blockPos.getZ()), BlockTypes.AIR.getDefaultState()); + } catch (MaxChangedBlocksException e) { + throw new RuntimeException(e); + } + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + switch (method.getName()) { + case "a_", "getBlockState" -> { + if (args.length == 1 && args[0] instanceof BlockPos blockPos) { + // getBlockState + return getBlockState(blockPos); + } + } + case "c_", "getBlockEntity" -> { + if (args.length == 1 && args[0] instanceof BlockPos blockPos) { + // getBlockEntity + return getBlockEntity(blockPos); + } + } + case "a", "setBlock", "removeBlock", "destroyBlock" -> { + if (args.length >= 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof BlockState blockState) { + // setBlock + return setBlock(blockPos, blockState); + } else if (args.length >= 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof Boolean bl) { + // removeBlock (and also matches destroyBlock) + return removeBlock(blockPos, bl); + } + } + default -> { } + } + + return method.invoke(this.serverLevel, args); + } + +} diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/FaweBlockStateListPopulator.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/FaweBlockStateListPopulator.java new file mode 100644 index 000000000..a802a2e7a --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/FaweBlockStateListPopulator.java @@ -0,0 +1,132 @@ +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R2; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Holder; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.flag.FeatureFlagSet; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeManager; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.border.WorldBorder; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkSource; +import net.minecraft.world.level.chunk.ChunkStatus; +import net.minecraft.world.level.lighting.LevelLightEngine; +import net.minecraft.world.level.material.FluidState; +import org.bukkit.craftbukkit.v1_20_R2.util.BlockStateListPopulator; +import org.jetbrains.annotations.Nullable; + +public class FaweBlockStateListPopulator extends BlockStateListPopulator { + + private final ServerLevel world; + + public FaweBlockStateListPopulator(ServerLevel world) { + super(world); + this.world = world; + } + + @Override + public long getSeed() { + return world.getSeed(); + } + + @Override + public ServerLevel getLevel() { + return world.getLevel(); + } + + @Override + public MinecraftServer getServer() { + return world.getServer(); + } + + @Override + public ChunkSource getChunkSource() { + return world.getChunkSource(); + } + + @Override + public ChunkAccess getChunk(final int chunkX, final int chunkZ, final ChunkStatus leastStatus, final boolean create) { + return world.getChunk(chunkX, chunkZ, leastStatus, create); + } + + @Override + public BiomeManager getBiomeManager() { + return world.getBiomeManager(); + } + + @Override + public Holder getUncachedNoiseBiome(final int biomeX, final int biomeY, final int biomeZ) { + return world.getUncachedNoiseBiome(biomeX, biomeY, biomeZ); + } + + @Override + public int getSeaLevel() { + return world.getSeaLevel(); + } + + @Override + public FeatureFlagSet enabledFeatures() { + return world.enabledFeatures(); + } + + @Override + public float getShade(final Direction direction, final boolean shaded) { + return world.getShade(direction, shaded); + } + + @Override + public LevelLightEngine getLightEngine() { + return world.getLightEngine(); + } + + @Nullable + @Override + public ChunkAccess getChunkIfLoadedImmediately(final int x, final int z) { + return world.getChunkIfLoadedImmediately(x, z); + } + + @Override + public BlockState getBlockStateIfLoaded(final BlockPos blockposition) { + return world.getBlockStateIfLoaded(blockposition); + } + + @Override + public FluidState getFluidIfLoaded(final BlockPos blockposition) { + return world.getFluidIfLoaded(blockposition); + } + + @Override + public WorldBorder getWorldBorder() { + return world.getWorldBorder(); + } + + @Override + public boolean setBlock(final BlockPos pos, final BlockState state, final int flags, final int maxUpdateDepth) { + return world.setBlock(pos, state, flags, maxUpdateDepth); + } + + @Override + public boolean removeBlock(final BlockPos pos, final boolean move) { + return world.removeBlock(pos, move); + } + + @Override + public boolean destroyBlock(final BlockPos pos, final boolean drop, final Entity breakingEntity, final int maxUpdateDepth) { + return world.destroyBlock(pos, drop, breakingEntity, maxUpdateDepth); + } + + @Override + public BlockState getBlockState(final BlockPos pos) { + return world.getBlockState(pos); + } + + @Override + public boolean setBlock(final BlockPos pos, final BlockState state, final int flags) { + return world.setBlock(pos, state, flags); + } + +} diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java index 48bc935cb..d1bc6b0cf 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java @@ -14,12 +14,14 @@ import com.fastasyncworldedit.core.util.TaskManager; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitWorld; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; +import com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R2.PaperweightServerLevelDelegateProxy; import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R2.nbt.PaperweightLazyCompoundTag; import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R2.regen.PaperweightRegen; import com.sk89q.worldedit.entity.BaseEntity; @@ -50,11 +52,14 @@ import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypesCache; import com.sk89q.worldedit.world.entity.EntityType; +import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; +import com.sk89q.worldedit.world.generation.StructureType; import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.registry.BlockMaterial; import io.papermc.lib.PaperLib; import net.minecraft.core.BlockPos; import net.minecraft.core.Registry; +import net.minecraft.core.SectionPos; import net.minecraft.core.WritableRegistry; import net.minecraft.core.registries.Registries; import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; @@ -62,23 +67,32 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.level.ChunkHolder; +import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.util.StringRepresentable; import net.minecraft.world.entity.Entity; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.level.levelgen.structure.Structure; +import net.minecraft.world.level.levelgen.structure.StructureStart; import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.TreeType; +import org.bukkit.World; import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.v1_20_R2.CraftServer; import org.bukkit.craftbukkit.v1_20_R2.CraftWorld; @@ -89,6 +103,7 @@ import org.bukkit.craftbukkit.v1_20_R2.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack; import org.bukkit.craftbukkit.v1_20_R2.util.CraftNamespacedKey; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; import java.lang.ref.WeakReference; @@ -96,6 +111,7 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -104,6 +120,7 @@ import java.util.Map; import java.util.Objects; import java.util.OptionalInt; import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -547,6 +564,168 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements return true; } + @Override + public boolean generateFeature(ConfiguredFeatureType feature, World world, EditSession editSession, BlockVector3 pt) { + //FAWE start + ServerLevel serverLevel = ((CraftWorld) world).getHandle(); + ChunkGenerator generator = serverLevel.getMinecraftWorld().getChunkSource().getGenerator(); + + ConfiguredFeature configuredFeature = serverLevel + .registryAccess() + .registryOrThrow(Registries.CONFIGURED_FEATURE) + .get(ResourceLocation.tryParse(feature.getId())); + FaweBlockStateListPopulator populator = new FaweBlockStateListPopulator(serverLevel); + + Map placed = TaskManager.taskManager().sync(() -> { + serverLevel.captureTreeGeneration = true; + serverLevel.captureBlockStates = true; + try { + if (!configuredFeature.place( + populator, + generator, + serverLevel.random, + new BlockPos(pt.getX(), pt.getY(), pt.getZ()) + )) { + return null; + } + return populator.getList().stream().collect(Collectors.toMap( + CraftBlockState::getPosition, + craftBlockState -> craftBlockState + )); + } finally { + serverLevel.captureBlockStates = false; + serverLevel.captureTreeGeneration = false; + serverLevel.capturedBlockStates.clear(); + } + }); + + return placeFeatureIntoSession(editSession, populator, placed); + //FAWE end + } + + @Override + public boolean generateStructure(StructureType type, World world, EditSession editSession, BlockVector3 pt) { + ServerLevel serverLevel = ((CraftWorld) world).getHandle(); + Structure k = serverLevel + .registryAccess() + .registryOrThrow(Registries.STRUCTURE) + .get(ResourceLocation.tryParse(type.getId())); + if (k == null) { + return false; + } + + ServerChunkCache chunkManager = serverLevel.getChunkSource(); + + ChunkPos chunkPos = new ChunkPos(new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ())); + + //FAWE start + FaweBlockStateListPopulator populator = new FaweBlockStateListPopulator(serverLevel); + Map placed = TaskManager.taskManager().sync(() -> { + serverLevel.captureTreeGeneration = true; + serverLevel.captureBlockStates = true; + try { + StructureStart structureStart = k.generate( + serverLevel.registryAccess(), + chunkManager.getGenerator(), + chunkManager.getGenerator().getBiomeSource(), + chunkManager.randomState(), + serverLevel.getStructureManager(), + serverLevel.getSeed(), + chunkPos, + 0, + populator, + biome -> true + ); + if (!structureStart.isValid()) { + return null; + } else { + BoundingBox boundingBox = structureStart.getBoundingBox(); + ChunkPos min = new ChunkPos( + SectionPos.blockToSectionCoord(boundingBox.minX()), + SectionPos.blockToSectionCoord(boundingBox.minZ()) + ); + ChunkPos max = new ChunkPos( + SectionPos.blockToSectionCoord(boundingBox.maxX()), + SectionPos.blockToSectionCoord(boundingBox.maxZ()) + ); + ChunkPos.rangeClosed(min, max).forEach((chunkPosx) -> structureStart.placeInChunk( + populator, + serverLevel.structureManager(), + chunkManager.getGenerator(), + serverLevel.getRandom(), + new BoundingBox( + chunkPosx.getMinBlockX(), + serverLevel.getMinBuildHeight(), + chunkPosx.getMinBlockZ(), + chunkPosx.getMaxBlockX(), + serverLevel.getMaxBuildHeight(), + chunkPosx.getMaxBlockZ() + ), + chunkPosx + )); + Map placedBlocks = populator.getList().stream().collect(Collectors.toMap( + CraftBlockState::getPosition, + craftBlockState -> craftBlockState + )); + placedBlocks.putAll(serverLevel.capturedBlockStates); + return placedBlocks; + } + } finally { + serverLevel.captureBlockStates = false; + serverLevel.captureTreeGeneration = false; + serverLevel.capturedBlockStates.clear(); + } + }); + + return placeFeatureIntoSession(editSession, populator, placed); + //FAWE end + } + + private boolean placeFeatureIntoSession( + final EditSession editSession, + final FaweBlockStateListPopulator populator, + final Map placed + ) { + if (placed == null || placed.isEmpty()) { + return false; + } + + for (Map.Entry entry : placed.entrySet()) { + CraftBlockState craftBlockState = entry.getValue(); + if (entry.getValue() == null) { + continue; + } + BlockPos pos = entry.getKey(); + editSession.setBlock(pos.getX(), pos.getY(), pos.getZ(), BukkitAdapter.adapt(craftBlockState.getBlockData())); + BlockEntity blockEntity = populator.getBlockEntity(pos); + if (blockEntity != null) { + net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(); + editSession.setTile(pos.getX(), pos.getY(), pos.getZ(), (CompoundTag) toNative(tag)); + } + } + return true; + } + + @Override + public void setupFeatures() { + DedicatedServer server = ((CraftServer) Bukkit.getServer()).getServer(); + + // Features + for (ResourceLocation name : server.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).keySet()) { + if (ConfiguredFeatureType.REGISTRY.get(name.toString()) == null) { + ConfiguredFeatureType.REGISTRY.register(name.toString(), new ConfiguredFeatureType(name.toString())); + } + } + + // Structures + for (ResourceLocation name : server.registryAccess().registryOrThrow(Registries.STRUCTURE).keySet()) { + if (StructureType.REGISTRY.get(name.toString()) == null) { + StructureType.REGISTRY.register(name.toString(), new StructureType(name.toString())); + } + } + } + + @Override public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) { final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IBukkitAdapter.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IBukkitAdapter.java index 29162b607..4e2e6e8d5 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IBukkitAdapter.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IBukkitAdapter.java @@ -392,4 +392,12 @@ public interface IBukkitAdapter { return TaskManager.taskManager().sync(world::getEntities); } + /** + * Import Minecraft internal features into FAWE. Should be executed after worlds loading (in order to capture datapacks) + * + * @since TODO + */ + default void setupFeatures() { + } + } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java index e881416c5..84f769edb 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java @@ -21,8 +21,8 @@ package com.sk89q.worldedit.bukkit; import com.fastasyncworldedit.bukkit.BukkitPermissionAttachmentManager; import com.fastasyncworldedit.bukkit.FaweBukkit; -import com.fastasyncworldedit.core.util.UpdateNotification; import com.fastasyncworldedit.core.Fawe; +import com.fastasyncworldedit.core.util.UpdateNotification; import com.fastasyncworldedit.core.util.WEManager; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; @@ -247,6 +247,7 @@ public class WorldEditPlugin extends JavaPlugin { setupTags(); setupBiomes(false); // FAWE - load biomes later. Initialize biomes twice to allow for the registry to be present for // plugins requiring WE biomes during startup, as well as allowing custom biomes loaded later on to be present in WE. + ((BukkitImplAdapter) adapter.value().get()).setupFeatures(); WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent(platform)); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/factory/StructureGeneratorFactory.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/factory/StructureGeneratorFactory.java new file mode 100644 index 000000000..3a74f14a0 --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/factory/StructureGeneratorFactory.java @@ -0,0 +1,46 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.fastasyncworldedit.core.command.factory; + +import com.fastasyncworldedit.core.function.generator.StructureGenerator; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.function.Contextual; +import com.sk89q.worldedit.function.EditContext; +import com.sk89q.worldedit.world.generation.StructureType; + +public final class StructureGeneratorFactory implements Contextual { + + private final StructureType type; + + public StructureGeneratorFactory(StructureType type) { + this.type = type; + } + + @Override + public StructureGenerator createFromContext(EditContext input) { + return new StructureGenerator((EditSession) input.getDestination(), type); + } + + @Override + public String toString() { + return "structure of type " + type; + } + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/FeaturePlacer.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/FeaturePlacer.java new file mode 100644 index 000000000..ae47acada --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/FeaturePlacer.java @@ -0,0 +1,77 @@ +package com.fastasyncworldedit.core.command.tool; + +import com.fastasyncworldedit.core.configuration.Caption; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalConfiguration; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.command.tool.BlockTool; +import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.extension.platform.Actor; +import com.sk89q.worldedit.extension.platform.Platform; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.util.Direction; +import com.sk89q.worldedit.util.Location; +import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; + +import javax.annotation.Nullable; + +/** + * Places a feature + * + * @since TODO + */ +public class FeaturePlacer implements BlockTool { + + private final ConfiguredFeatureType feature; + + /** + * New instance + * + * @since TODO + */ + public FeaturePlacer(ConfiguredFeatureType feature) { + this.feature = feature; + } + + @Override + public boolean canUse(Actor player) { + return player.hasPermission("worldedit.tool.feature"); + } + + @Override + public boolean actPrimary( + Platform server, + LocalConfiguration config, + Player player, + LocalSession session, + Location clicked, + @Nullable Direction face + ) { + + try (EditSession editSession = session.createEditSession(player)) { + try { + boolean successful = false; + + final BlockVector3 pos = clicked.toVector().add().toBlockPoint(); + for (int i = 0; i < 10; i++) { + if (feature.place(editSession, pos)) { + successful = true; + break; + } + } + + if (!successful) { + player.print(Caption.of("worldedit.tool.feature.failed")); + } + } catch (MaxChangedBlocksException e) { + player.print(Caption.of("worldedit.tool.max-block-changes")); + } finally { + session.remember(editSession); + } + } + + return true; + } + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/StructurePlacer.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/StructurePlacer.java new file mode 100644 index 000000000..99720f65d --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/StructurePlacer.java @@ -0,0 +1,77 @@ +package com.fastasyncworldedit.core.command.tool; + +import com.fastasyncworldedit.core.configuration.Caption; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalConfiguration; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.command.tool.BlockTool; +import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.extension.platform.Actor; +import com.sk89q.worldedit.extension.platform.Platform; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.util.Direction; +import com.sk89q.worldedit.util.Location; +import com.sk89q.worldedit.world.generation.StructureType; + +import javax.annotation.Nullable; + +/** + * Places a feature + * + * @since TODO + */ +public class StructurePlacer implements BlockTool { + + private final StructureType structure; + + /** + * New instance + * + * @since TODO + */ + public StructurePlacer(StructureType structure) { + this.structure = structure; + } + + @Override + public boolean canUse(Actor player) { + return player.hasPermission("worldedit.tool.feature"); + } + + @Override + public boolean actPrimary( + Platform server, + LocalConfiguration config, + Player player, + LocalSession session, + Location clicked, + @Nullable Direction face + ) { + + try (EditSession editSession = session.createEditSession(player)) { + try { + boolean successful = false; + + final BlockVector3 pos = clicked.toVector().add().toBlockPoint(); + for (int i = 0; i < 10; i++) { + if (structure.place(editSession, pos)) { + successful = true; + break; + } + } + + if (!successful) { + player.print(Caption.of("worldedit.tool.feature.failed")); + } + } catch (MaxChangedBlocksException e) { + player.print(Caption.of("worldedit.tool.max-block-changes")); + } finally { + session.remember(editSession); + } + } + + return true; + } + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/StructureGenerator.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/StructureGenerator.java new file mode 100644 index 000000000..537a6c83b --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/StructureGenerator.java @@ -0,0 +1,30 @@ +package com.fastasyncworldedit.core.function.generator; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.function.RegionFunction; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.world.generation.StructureType; + +public class StructureGenerator implements RegionFunction { + + private final StructureType structureType; + private final EditSession editSession; + + /** + * Create a new instance. + * + * @param editSession the edit session + * @param structureType the structure type + */ + public StructureGenerator(EditSession editSession, StructureType structureType) { + this.editSession = editSession; + this.structureType = structureType; + } + + @Override + public boolean apply(BlockVector3 position) throws WorldEditException { + return editSession.getWorld().generateStructure(structureType, editSession, position); + } + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/wrappers/WorldWrapper.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/wrappers/WorldWrapper.java index 05616a414..3189d7a31 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/wrappers/WorldWrapper.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/wrappers/WorldWrapper.java @@ -36,6 +36,8 @@ import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; +import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; +import com.sk89q.worldedit.world.generation.StructureType; import com.sk89q.worldedit.world.weather.WeatherType; import javax.annotation.Nullable; @@ -132,12 +134,10 @@ public class WorldWrapper extends AbstractWorld { return parent.playEffect(position, type, data); } - //FAWE start - allow block break effect of non-legacy blocks @Override public boolean playBlockBreakEffect(Vector3 position, BlockType type) { return parent.playBlockBreakEffect(position, type); } - //FAWE end @Override public boolean queueBlockBreakEffect(Platform server, BlockVector3 position, BlockType blockType, double priority) { @@ -206,12 +206,10 @@ public class WorldWrapper extends AbstractWorld { return parent.getName(); } - //FAWE start - allow history to read an unloaded world's name @Override public String getNameUnsafe() { return parent.getNameUnsafe(); } - //FAWE end @Override public > boolean setBlock(BlockVector3 position, B block, boolean notifyAndLight) throws @@ -261,12 +259,15 @@ public class WorldWrapper extends AbstractWorld { }); } - //FAWE start @Override public Collection getBlockDrops(final BlockVector3 position) { return TaskManager.taskManager().sync(() -> parent.getBlockDrops(position)); } - //FAWE end + + @Override + public boolean canPlaceAt(final BlockVector3 position, final BlockState blockState) { + return parent.canPlaceAt(position, blockState); + } @Override public boolean regenerate(Region region, EditSession session) { @@ -288,6 +289,16 @@ public class WorldWrapper extends AbstractWorld { } } + @Override + public boolean generateStructure(final StructureType type, final EditSession editSession, final BlockVector3 position) { + return parent.generateStructure(type, editSession, position); + } + + @Override + public boolean generateFeature(final ConfiguredFeatureType type, final EditSession editSession, final BlockVector3 position) { + return parent.generateFeature(type, editSession, position); + } + @Override public BlockVector3 getSpawnPosition() { return parent.getSpawnPosition(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java index ecf859896..f9b71dc6d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -147,6 +147,8 @@ import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; +import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; +import com.sk89q.worldedit.world.generation.StructureType; import com.sk89q.worldedit.world.registry.LegacyMapper; import org.apache.logging.log4j.Logger; @@ -4017,5 +4019,29 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { } return changes; } + + /** + * Generate a feature into this EditSession + * + * @param feature feature to generate + * @param position position to generate at + * @return blocks affected + */ + public int generateFeature(ConfiguredFeatureType feature, BlockVector3 position) { + feature.place(this, position); + return changes; + } + + /** + * Generate a structure into this EditSession + * + * @param structure structure to generate + * @param position position to generate at + * @return blocks affected + */ + public int generateStructure(StructureType structure, BlockVector3 position) { + structure.place(this, position); + return changes; + } //FAWE end } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java index c0c1f77a0..cd564d0ff 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java @@ -20,6 +20,7 @@ package com.sk89q.worldedit.command; import com.fastasyncworldedit.core.Fawe; +import com.fastasyncworldedit.core.command.factory.StructureGeneratorFactory; import com.fastasyncworldedit.core.command.tool.brush.BlendBall; import com.fastasyncworldedit.core.command.tool.brush.BlobBrush; import com.fastasyncworldedit.core.command.tool.brush.BrushSettings; @@ -116,8 +117,9 @@ import com.sk89q.worldedit.util.formatting.text.event.ClickEvent; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; -import org.anarres.parallelgzip.ParallelGZIPOutputStream; import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; +import com.sk89q.worldedit.world.generation.StructureType; +import org.anarres.parallelgzip.ParallelGZIPOutputStream; import org.enginehub.piston.annotation.Command; import org.enginehub.piston.annotation.CommandContainer; import org.enginehub.piston.annotation.param.Arg; @@ -1479,6 +1481,24 @@ public class BrushCommands { } //FAWE start + @Command( + name = "structure", + desc = "Structure brush, paints Minecraft generation structures" + ) + @CommandPermissions("worldedit.brush.feature") + public void structure(Player player, LocalSession localSession, + @Arg(desc = "The shape of the region") + RegionFactory shape, + @Arg(desc = "The size of the brush", def = "5") + double radius, + @Arg(desc = "The density of the brush", def = "5") + double density, + @Arg(desc = "The type of feature to use") + StructureType type) throws WorldEditException { + setOperationBasedBrush(player, localSession, radius, + new Paint(new StructureGeneratorFactory(type), density / 100), shape, "worldedit.brush.structure"); + } + public BrushSettings process(Player player, Arguments arguments, BrushSettings settings) throws WorldEditException { LocalSession session = worldEdit.getSessionManager().get(player); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java index 1ae9f10ce..e311250ad 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java @@ -64,7 +64,7 @@ import org.enginehub.piston.annotation.param.Arg; import org.enginehub.piston.annotation.param.Switch; import org.jetbrains.annotations.Range; -import java.awt.RenderingHints; +import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.net.URISyntaxException; @@ -349,19 +349,28 @@ public class GenerationCommands { @Command( name = "/feature", + //FAWE start + aliases = {"/placefeature"}, + //FAWE end desc = "Generate Minecraft features" ) + @Logging(PLACEMENT) @CommandPermissions("worldedit.generation.feature") - @Logging(POSITION) - public int feature(Actor actor, LocalSession session, EditSession editSession, - @Arg(desc = "The feature") - ConfiguredFeatureType feature) throws WorldEditException { - if (editSession.getWorld().generateFeature(feature, editSession, session.getPlacementPosition(actor))) { - actor.printInfo(Caption.of("worldedit.feature.created")); + public int feature( + Actor actor, LocalSession session, EditSession editSession, + @Arg(desc = "Type of feature to place", def = "forest_rock") + ConfiguredFeatureType feature + ) throws WorldEditException { + //FAWE start + int affected = editSession.generateFeature(feature, session.getPlacementPosition(actor)); + + if (affected == 0) { + actor.print(Caption.of("worldedit.generate.feature.failed")); } else { - actor.printError(Caption.of("worldedit.feature.failed")); + actor.print(Caption.of("worldedit.feature.created", TextComponent.of(affected))); } - return 0; + return affected; + //FAWE end } @Command( @@ -373,12 +382,16 @@ public class GenerationCommands { public int structure(Actor actor, LocalSession session, EditSession editSession, @Arg(desc = "The structure") StructureType feature) throws WorldEditException { - if (editSession.getWorld().generateStructure(feature, editSession, session.getPlacementPosition(actor))) { - actor.printInfo(Caption.of("worldedit.structure.created")); + //FAWE start + int affected = editSession.generateStructure(feature, session.getPlacementPosition(actor)); + + if (affected > 0) { + actor.printInfo(Caption.of("worldedit.structure.created", TextComponent.of(affected))); } else { actor.printError(Caption.of("worldedit.structure.failed")); } - return 0; + return affected; + //FAWE end } @Command( @@ -750,7 +763,7 @@ public class GenerationCommands { ) @Logging(PLACEMENT) @CommandPermissions("worldedit.generation.blob") - public int blobBrush( + public int blob( Actor actor, LocalSession session, EditSession editSession, @Arg(desc = "Pattern") Pattern pattern, @@ -780,7 +793,7 @@ public class GenerationCommands { if (actor instanceof Player) { ((Player) actor).findFreePosition(); } - actor.print(Caption.of("worldedit.sphere.created", TextComponent.of(affected))); + actor.print(Caption.of("worldedit.blob.created", TextComponent.of(affected))); return affected; } //FAWE end diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java index 8395b2e2d..85ea94b65 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java @@ -19,6 +19,8 @@ package com.sk89q.worldedit.command; +import com.fastasyncworldedit.core.command.tool.FeaturePlacer; +import com.fastasyncworldedit.core.command.tool.StructurePlacer; import com.fastasyncworldedit.core.command.tool.brush.InspectBrush; import com.fastasyncworldedit.core.configuration.Caption; import com.google.common.collect.Collections2; @@ -56,6 +58,8 @@ import com.sk89q.worldedit.util.formatting.text.TextComponent; import com.sk89q.worldedit.util.formatting.text.event.ClickEvent; import com.sk89q.worldedit.util.formatting.text.format.TextColor; import com.sk89q.worldedit.world.block.BlockStateHolder; +import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; +import com.sk89q.worldedit.world.generation.StructureType; import org.enginehub.piston.CommandManager; import org.enginehub.piston.CommandManagerService; import org.enginehub.piston.CommandMetadata; @@ -244,6 +248,36 @@ public class ToolCommands { setTool(player, session, new TreePlanter(type), "worldedit.tool.tree.equip"); } + //FAWE start + @Command( + name = "featureplacer", + aliases = {"/featureplacer", "featuretool", "/featuretool"}, + desc = "Feature placer tool" + ) + @CommandPermissions("worldedit.tool.feature") + public void feature( + Player player, LocalSession session, + @Arg(desc = "Type of feature to place", def = "forest_rock") + ConfiguredFeatureType feature + ) throws WorldEditException { + setTool(player, session, new FeaturePlacer(feature), "worldedit.tool.feature.equip"); + } + + @Command( + name = "structureplacer", + aliases = {"/structureplacer", "structuretool", "/structuretool"}, + desc = "Structure placer tool" + ) + @CommandPermissions("worldedit.tool.structure") + public void structure( + Player player, LocalSession session, + @Arg(desc = "Type of structure to place", def = "") + StructureType feature + ) throws WorldEditException { + setTool(player, session, new StructurePlacer(feature), "worldedit.tool.structure.equip"); + } + //FAWE end + @Command( name = "stacker", desc = "Block stacker tool" diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java index ebcaf6008..925788b57 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java @@ -313,6 +313,14 @@ public interface World extends Extent, Keyed, IChunkCache { boolean generateTree(TreeGenerator.TreeType type, EditSession editSession, BlockVector3 position) throws MaxChangedBlocksException; + /** + * Generate a structure at the given position + * + * @param type The structure type + * @param editSession The {@link EditSession} + * @param position The position + * @return True if the generation was successful + */ default boolean generateStructure(StructureType type, EditSession editSession, BlockVector3 position) { return false; } @@ -320,9 +328,9 @@ public interface World extends Extent, Keyed, IChunkCache { /** * Generate a feature at the given position. * - * @param type The feature type + * @param type The feature type * @param editSession The {@link EditSession} - * @param position The position + * @param position The position * @return True if the generation was successful */ default boolean generateFeature(ConfiguredFeatureType type, EditSession editSession, BlockVector3 position) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/ConfiguredFeatureType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/ConfiguredFeatureType.java index 56888acd9..bc5126d31 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/ConfiguredFeatureType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/ConfiguredFeatureType.java @@ -19,6 +19,8 @@ package com.sk89q.worldedit.world.generation; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.registry.Keyed; import com.sk89q.worldedit.registry.NamespacedRegistry; @@ -40,4 +42,17 @@ public class ConfiguredFeatureType implements Keyed { public String toString() { return this.id; } + + //FAWE start + /** + * Place this feature into an {@link EditSession} + * + * @param extent EditSession to place into + * @param position position to use for placement + * @return true if successful + */ + public boolean place(EditSession extent, BlockVector3 position) { + return extent.getWorld().generateFeature(this, extent, position); + } + //FAWE end } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/StructureType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/StructureType.java index e4e8aaebb..0713735d7 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/StructureType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/StructureType.java @@ -19,6 +19,8 @@ package com.sk89q.worldedit.world.generation; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.registry.Keyed; import com.sk89q.worldedit.registry.NamespacedRegistry; @@ -40,4 +42,17 @@ public class StructureType implements Keyed { public String toString() { return this.id; } + + //FAWE start + /** + * Place this structure into an {@link EditSession} + * + * @param extent EditSession to place into + * @param position position to use for placement + * @return true if successful + */ + public boolean place(EditSession extent, BlockVector3 position) { + return extent.getWorld().generateStructure(this, extent, position); + } + //FAWE end } diff --git a/worldedit-core/src/main/resources/lang/strings.json b/worldedit-core/src/main/resources/lang/strings.json index 1e34364e2..4faa8b1b5 100644 --- a/worldedit-core/src/main/resources/lang/strings.json +++ b/worldedit-core/src/main/resources/lang/strings.json @@ -496,14 +496,16 @@ "worldedit.hcyl.thickness-too-large": "Thickness cannot be larger than x or z radii.", "worldedit.sphere.invalid-radius": "You must either specify 1 or 3 radius values.", "worldedit.sphere.created": "{0} blocks have been created.", + "worldedit.blob.created": "{0} blocks have been created.", + "worldedit.feature.created": "Feature created, {0} blocks placed.", + "worldedit.generate.feature.failed": "This feature cannot go here. Ensure the area meets the requirements.", "worldedit.forestgen.created": "{0} trees created.", "worldedit.pumpkins.created": "{0} pumpkin patches created.", - "worldedit.feature.created": "Feature created.", "worldedit.feature.failed": "Failed to generate feature. Is it a valid spot for it?", "worldedit.pyramid.created": "{0} blocks have been created.", "worldedit.generate.created": "{0} blocks have been created.", "worldedit.generatebiome.changed": "{0} biomes affected.", - "worldedit.structure.created": "Structure created.", + "worldedit.structure.created": "Structure created, {0} blocks placed.", "worldedit.structure.failed": "Failed to generate structure. Is it a valid spot for it?", "worldedit.reload.config": "Configuration reloaded!", "worldedit.report.written": "FAWE report written to {0}", @@ -542,6 +544,8 @@ "worldedit.tool.deltree.not-floating": "That's not a floating tree.", "worldedit.tool.tree.equip": "Tree tool bound to {0}.", "worldedit.tool.tree.obstructed": "A tree can't go there.", + "worldedit.tool.feature.equip": "Feature placer tool bound to {0}.", + "worldedit.tool.feature.obstructed": "This feature cannot go there. Ensure the area meets the requirements.", "worldedit.tool.info.equip": "Info tool bound to {0}.", "worldedit.tool.inspect.equip": "Inspect tool bound to {0}.", "worldedit.tool.info.blockstate.hover": "Block state", From 5a39197e3e1c92a8dc657bec9bd701e925e50fcc Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Tue, 24 Oct 2023 17:46:40 +0100 Subject: [PATCH 04/12] cleanup --- .../ext/fawe/v1_20_R2/PaperweightAdapter.java | 2 +- .../fawe/v1_20_R2/PaperweightFaweAdapter.java | 5 - .../bukkit/adapter/BukkitImplAdapter.java | 4 + .../core/command/tool/StructurePlacer.java | 2 +- .../generator/StructureGenerator.java | 7 ++ .../java/com/sk89q/worldedit/EditSession.java | 4 + .../function/generator/FeatureGenerator.java | 7 +- .../java/com/sk89q/worldedit/world/World.java | 4 + .../FabricServerLevelDelegateProxy.java | 117 ------------------ .../ForgeServerLevelDelegateProxy.java | 117 ------------------ 10 files changed, 26 insertions(+), 243 deletions(-) delete mode 100644 worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricServerLevelDelegateProxy.java delete mode 100644 worldedit-forge/src/main/java/com/sk89q/worldedit/forge/internal/ForgeServerLevelDelegateProxy.java diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java index 31f4736e0..fcdc144e9 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java @@ -137,6 +137,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; @@ -158,7 +159,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; diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java index d1bc6b0cf..d949cf430 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java @@ -21,7 +21,6 @@ import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitWorld; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R2.PaperweightServerLevelDelegateProxy; import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R2.nbt.PaperweightLazyCompoundTag; import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R2.regen.PaperweightRegen; import com.sk89q.worldedit.entity.BaseEntity; @@ -74,7 +73,6 @@ import net.minecraft.util.StringRepresentable; import net.minecraft.world.entity.Entity; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; @@ -103,7 +101,6 @@ import org.bukkit.craftbukkit.v1_20_R2.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack; import org.bukkit.craftbukkit.v1_20_R2.util.CraftNamespacedKey; import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; import java.lang.ref.WeakReference; @@ -111,7 +108,6 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -120,7 +116,6 @@ import java.util.Map; import java.util.Objects; import java.util.OptionalInt; import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java index f27d2eb4c..aa2f5529f 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java @@ -291,6 +291,8 @@ public interface BukkitImplAdapter extends IBukkitAdapter { * @param session The EditSession * @param pt The location * @return If it succeeded + * + * @since TODO */ default boolean generateFeature(ConfiguredFeatureType feature, World world, EditSession session, BlockVector3 pt) { throw new UnsupportedOperationException("This adapter does not support generating features."); @@ -304,6 +306,8 @@ public interface BukkitImplAdapter extends IBukkitAdapter { * @param session The EditSession * @param pt The location * @return If it succeeded + * + * @since TODO */ default boolean generateStructure(StructureType feature, World world, EditSession session, BlockVector3 pt) { throw new UnsupportedOperationException("This adapter does not support generating features."); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/StructurePlacer.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/StructurePlacer.java index 99720f65d..798e74aea 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/StructurePlacer.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/StructurePlacer.java @@ -17,7 +17,7 @@ import com.sk89q.worldedit.world.generation.StructureType; import javax.annotation.Nullable; /** - * Places a feature + * Places a structure * * @since TODO */ diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/StructureGenerator.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/StructureGenerator.java index 537a6c83b..c99677126 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/StructureGenerator.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/StructureGenerator.java @@ -6,6 +6,11 @@ import com.sk89q.worldedit.function.RegionFunction; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.generation.StructureType; +/** + * Generate a structure at the given location + * + * @since TODO + */ public class StructureGenerator implements RegionFunction { private final StructureType structureType; @@ -16,6 +21,8 @@ public class StructureGenerator implements RegionFunction { * * @param editSession the edit session * @param structureType the structure type + * + * @since TODO */ public StructureGenerator(EditSession editSession, StructureType structureType) { this.editSession = editSession; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java index f9b71dc6d..36c4e62df 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -4026,6 +4026,8 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { * @param feature feature to generate * @param position position to generate at * @return blocks affected + * + * @since TODO */ public int generateFeature(ConfiguredFeatureType feature, BlockVector3 position) { feature.place(this, position); @@ -4038,6 +4040,8 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { * @param structure structure to generate * @param position position to generate at * @return blocks affected + * + * @since TODO */ public int generateStructure(StructureType structure, BlockVector3 position) { structure.place(this, position); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/FeatureGenerator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/FeatureGenerator.java index 6c49138db..f01a588db 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/FeatureGenerator.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/FeatureGenerator.java @@ -26,8 +26,9 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; /** - * Generates forests by searching for the ground starting from the given upper Y - * coordinate for every column given. + * Generate a feature at the given location + * + * @since TODO */ public class FeatureGenerator implements RegionFunction { @@ -39,6 +40,8 @@ public class FeatureGenerator implements RegionFunction { * * @param editSession the edit session * @param featureType the feature type + * + * @since TODO */ public FeatureGenerator(EditSession editSession, ConfiguredFeatureType featureType) { this.editSession = editSession; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java index 925788b57..221c0de8d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java @@ -320,6 +320,8 @@ public interface World extends Extent, Keyed, IChunkCache { * @param editSession The {@link EditSession} * @param position The position * @return True if the generation was successful + * + * @since TODO */ default boolean generateStructure(StructureType type, EditSession editSession, BlockVector3 position) { return false; @@ -332,6 +334,8 @@ public interface World extends Extent, Keyed, IChunkCache { * @param editSession The {@link EditSession} * @param position The position * @return True if the generation was successful + * + * @since TODO */ default boolean generateFeature(ConfiguredFeatureType type, EditSession editSession, BlockVector3 position) { return false; diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricServerLevelDelegateProxy.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricServerLevelDelegateProxy.java deleted file mode 100644 index 07ee8d81c..000000000 --- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricServerLevelDelegateProxy.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.fabric.internal; - -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.MaxChangedBlocksException; -import com.sk89q.worldedit.fabric.FabricAdapter; -import com.sk89q.worldedit.world.block.BlockTypes; -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import org.jetbrains.annotations.Nullable; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.Arrays; - -public class FabricServerLevelDelegateProxy implements InvocationHandler { - - private final EditSession editSession; - private final ServerLevel serverLevel; - - private FabricServerLevelDelegateProxy(EditSession editSession, ServerLevel serverLevel) { - this.editSession = editSession; - this.serverLevel = serverLevel; - } - - public static WorldGenLevel newInstance(EditSession editSession, ServerLevel serverLevel) { - return (WorldGenLevel) Proxy.newProxyInstance( - serverLevel.getClass().getClassLoader(), - serverLevel.getClass().getInterfaces(), - new FabricServerLevelDelegateProxy(editSession, serverLevel) - ); - } - - @Nullable - private BlockEntity getBlockEntity(BlockPos blockPos) { - BlockEntity tileEntity = this.serverLevel.getChunkAt(blockPos).getBlockEntity(blockPos); - if (tileEntity == null) { - return null; - } - BlockEntity newEntity = tileEntity.getType().create(blockPos, getBlockState(blockPos)); - newEntity.load(NBTConverter.toNative(this.editSession.getFullBlock(FabricAdapter.adapt(blockPos)).getNbtReference().getValue())); - - return newEntity; - } - - private BlockState getBlockState(BlockPos blockPos) { - return FabricAdapter.adapt(this.editSession.getBlock(FabricAdapter.adapt(blockPos))); - } - - private boolean setBlock(BlockPos blockPos, BlockState blockState) { - try { - return editSession.setBlock(FabricAdapter.adapt(blockPos), FabricAdapter.adapt(blockState)); - } catch (MaxChangedBlocksException e) { - throw new RuntimeException(e); - } - } - - private boolean removeBlock(BlockPos blockPos, boolean bl) { - try { - return editSession.setBlock(FabricAdapter.adapt(blockPos), BlockTypes.AIR.getDefaultState()); - } catch (MaxChangedBlocksException e) { - throw new RuntimeException(e); - } - } - - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - switch (method.getName()) { - case "getBlockState", "method_8320" -> { - if (args.length == 1 && args[0] instanceof BlockPos blockPos) { - return getBlockState(blockPos); - } - } - case "getBlockEntity", "method_8321" -> { - if (args.length == 1 && args[0] instanceof BlockPos blockPos) { - return getBlockEntity(blockPos); - } - } - case "setBlock", "method_8652" -> { - if (args.length >= 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof BlockState blockState) { - return setBlock(blockPos, blockState); - } - } - case "removeBlock", "destroyBlock", "method_8650", "method_8651" -> { - if (args.length >= 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof Boolean bl) { - return removeBlock(blockPos, bl); - } - } - default -> { } - } - - return method.invoke(this.serverLevel, args); - } - -} diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/internal/ForgeServerLevelDelegateProxy.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/internal/ForgeServerLevelDelegateProxy.java deleted file mode 100644 index ff9e64d4e..000000000 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/internal/ForgeServerLevelDelegateProxy.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.forge.internal; - -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.MaxChangedBlocksException; -import com.sk89q.worldedit.forge.ForgeAdapter; -import com.sk89q.worldedit.world.block.BlockTypes; -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import org.jetbrains.annotations.Nullable; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.Arrays; - -public class ForgeServerLevelDelegateProxy implements InvocationHandler { - - private final EditSession editSession; - private final ServerLevel serverLevel; - - private ForgeServerLevelDelegateProxy(EditSession editSession, ServerLevel serverLevel) { - this.editSession = editSession; - this.serverLevel = serverLevel; - } - - public static WorldGenLevel newInstance(EditSession editSession, ServerLevel serverLevel) { - return (WorldGenLevel) Proxy.newProxyInstance( - serverLevel.getClass().getClassLoader(), - serverLevel.getClass().getInterfaces(), - new ForgeServerLevelDelegateProxy(editSession, serverLevel) - ); - } - - @Nullable - private BlockEntity getBlockEntity(BlockPos blockPos) { - BlockEntity tileEntity = this.serverLevel.getChunkAt(blockPos).getBlockEntity(blockPos); - if (tileEntity == null) { - return null; - } - BlockEntity newEntity = tileEntity.getType().create(blockPos, getBlockState(blockPos)); - newEntity.load(NBTConverter.toNative(this.editSession.getFullBlock(ForgeAdapter.adapt(blockPos)).getNbtReference().getValue())); - - return newEntity; - } - - private BlockState getBlockState(BlockPos blockPos) { - return ForgeAdapter.adapt(this.editSession.getBlock(ForgeAdapter.adapt(blockPos))); - } - - private boolean setBlock(BlockPos blockPos, BlockState blockState) { - try { - return editSession.setBlock(ForgeAdapter.adapt(blockPos), ForgeAdapter.adapt(blockState)); - } catch (MaxChangedBlocksException e) { - throw new RuntimeException(e); - } - } - - private boolean removeBlock(BlockPos blockPos, boolean bl) { - try { - return editSession.setBlock(ForgeAdapter.adapt(blockPos), BlockTypes.AIR.getDefaultState()); - } catch (MaxChangedBlocksException e) { - throw new RuntimeException(e); - } - } - - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - switch (method.getName()) { - case "getBlockState", "m_8055_" -> { - if (args.length == 1 && args[0] instanceof BlockPos blockPos) { - return getBlockState(blockPos); - } - } - case "getBlockEntity", "m_7702_" -> { - if (args.length == 1 && args[0] instanceof BlockPos blockPos) { - return getBlockEntity(blockPos); - } - } - case "setBlock", "m_7731_" -> { - if (args.length >= 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof BlockState blockState) { - return setBlock(blockPos, blockState); - } - } - case "removeBlock", "destroyBlock", "m_7471_", "m_7740_" -> { - if (args.length >= 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof Boolean bl) { - return removeBlock(blockPos, bl); - } - } - default -> { } - } - - return method.invoke(this.serverLevel, args); - } - -} From c7f359a794fb1a33f34c2b6d9123b920a76b2b09 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Tue, 21 Nov 2023 18:14:16 +0000 Subject: [PATCH 05/12] fix merge issues --- .../adapter/impl/fawe/v1_17_R1_2/PaperweightFaweAdapter.java | 4 +++- .../adapter/impl/fawe/v1_18_R2/PaperweightFaweAdapter.java | 3 +++ .../adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java | 3 +++ .../adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java | 3 +++ .../adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java | 3 +++ 5 files changed, 15 insertions(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightFaweAdapter.java index da736f64e..2d019a007 100644 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightFaweAdapter.java @@ -9,11 +9,13 @@ import com.fastasyncworldedit.core.queue.IBatchProcessor; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.implementation.packet.ChunkPacket; import com.fastasyncworldedit.core.util.NbtUtils; +import com.fastasyncworldedit.core.util.TaskManager; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.blocks.TileEntityBlock; import com.sk89q.worldedit.bukkit.BukkitAdapter; @@ -93,6 +95,7 @@ import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.v1_17_R1.CraftChunk; import org.bukkit.craftbukkit.v1_17_R1.CraftServer; import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_17_R1.block.CraftBlockState; import org.bukkit.craftbukkit.v1_17_R1.block.data.CraftBlockData; import org.bukkit.craftbukkit.v1_17_R1.entity.CraftEntity; import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer; @@ -111,7 +114,6 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.OptionalInt; -import java.util.Random; import java.util.Set; import java.util.function.Supplier; import java.util.stream.Collectors; diff --git a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightFaweAdapter.java index 83c37b919..7b344b86e 100644 --- a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightFaweAdapter.java @@ -9,11 +9,13 @@ import com.fastasyncworldedit.core.queue.IBatchProcessor; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.implementation.packet.ChunkPacket; import com.fastasyncworldedit.core.util.NbtUtils; +import com.fastasyncworldedit.core.util.TaskManager; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.blocks.TileEntityBlock; import com.sk89q.worldedit.bukkit.BukkitAdapter; @@ -93,6 +95,7 @@ import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.v1_18_R2.CraftChunk; import org.bukkit.craftbukkit.v1_18_R2.CraftServer; import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; +import org.bukkit.craftbukkit.v1_18_R2.block.CraftBlockState; import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData; import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity; import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer; diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java index 2d918faff..3e81b3d4a 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java @@ -9,11 +9,13 @@ import com.fastasyncworldedit.core.queue.IBatchProcessor; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.implementation.packet.ChunkPacket; import com.fastasyncworldedit.core.util.NbtUtils; +import com.fastasyncworldedit.core.util.TaskManager; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; @@ -88,6 +90,7 @@ import org.bukkit.World; import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.v1_19_R3.CraftServer; import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; +import org.bukkit.craftbukkit.v1_19_R3.block.CraftBlockState; import org.bukkit.craftbukkit.v1_19_R3.block.data.CraftBlockData; import org.bukkit.craftbukkit.v1_19_R3.entity.CraftEntity; import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer; diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java index 475bcee10..f3d317dbb 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java @@ -9,11 +9,13 @@ import com.fastasyncworldedit.core.queue.IBatchProcessor; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.implementation.packet.ChunkPacket; import com.fastasyncworldedit.core.util.NbtUtils; +import com.fastasyncworldedit.core.util.TaskManager; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; @@ -88,6 +90,7 @@ import org.bukkit.World; import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.v1_20_R1.CraftServer; import org.bukkit.craftbukkit.v1_20_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_20_R1.block.CraftBlockState; import org.bukkit.craftbukkit.v1_20_R1.block.data.CraftBlockData; import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity; import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer; diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java index 2137fe99f..030599141 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java @@ -9,11 +9,13 @@ import com.fastasyncworldedit.core.queue.IBatchProcessor; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.implementation.packet.ChunkPacket; import com.fastasyncworldedit.core.util.NbtUtils; +import com.fastasyncworldedit.core.util.TaskManager; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; @@ -87,6 +89,7 @@ import org.bukkit.World; import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.v1_20_R2.CraftServer; import org.bukkit.craftbukkit.v1_20_R2.CraftWorld; +import org.bukkit.craftbukkit.v1_20_R2.block.CraftBlockState; import org.bukkit.craftbukkit.v1_20_R2.block.data.CraftBlockData; import org.bukkit.craftbukkit.v1_20_R2.entity.CraftEntity; import org.bukkit.craftbukkit.v1_20_R2.entity.CraftPlayer; From fee6c4d79c0aba1aa528d97eb4a1107b4d8f7a86 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Thu, 23 Nov 2023 18:20:09 +0000 Subject: [PATCH 06/12] bring more in line with upstream --- .../ext/fawe/v1_19_R3/PaperweightAdapter.java | 87 +++++++++- .../PaperweightServerLevelDelegateProxy.java | 162 ++++++++++++++++++ .../ext/fawe/v1_20_R2/PaperweightAdapter.java | 69 ++++++++ .../bukkit/adapter/BukkitImplAdapter.java | 7 + 4 files changed, 323 insertions(+), 2 deletions(-) create mode 100644 worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightServerLevelDelegateProxy.java diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java index 22c5a07b2..b0b5afa76 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java @@ -27,8 +27,8 @@ 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.EditSession; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItemStack; @@ -72,6 +72,7 @@ import com.sk89q.worldedit.util.nbt.ShortBinaryTag; import com.sk89q.worldedit.util.nbt.StringBinaryTag; import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.RegenOptions; +import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeTypes; import com.sk89q.worldedit.world.block.BaseBlock; @@ -79,9 +80,12 @@ import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; +import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; +import com.sk89q.worldedit.world.generation.StructureType; import com.sk89q.worldedit.world.item.ItemType; import net.minecraft.Util; import net.minecraft.core.BlockPos; +import net.minecraft.core.SectionPos; import net.minecraft.core.registries.Registries; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; @@ -93,6 +97,7 @@ import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.progress.ChunkProgressListener; +import net.minecraft.util.RandomSource; import net.minecraft.util.StringRepresentable; import net.minecraft.util.thread.BlockableEventLoop; import net.minecraft.world.Clearable; @@ -105,6 +110,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.LevelSettings; +import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; @@ -117,6 +123,10 @@ import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.dimension.LevelStem; import net.minecraft.world.level.levelgen.WorldOptions; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.level.levelgen.structure.Structure; +import net.minecraft.world.level.levelgen.structure.StructureStart; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.PrimaryLevelData; import net.minecraft.world.phys.BlockHitResult; @@ -138,6 +148,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 +170,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; @@ -173,6 +183,8 @@ public final class PaperweightAdapter implements BukkitImplAdapter k = originalWorld.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(ResourceLocation.tryParse(type.getId())); + ServerChunkCache chunkManager = originalWorld.getChunkSource(); + WorldGenLevel proxyLevel = PaperweightServerLevelDelegateProxy.newInstance(session, originalWorld, this); + return k != null && k.place(proxyLevel, chunkManager.getGenerator(), random, new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ())); + } + + public boolean generateStructure(StructureType type, World world, EditSession session, BlockVector3 pt) { + ServerLevel originalWorld = ((CraftWorld) world).getHandle(); + Structure k = originalWorld.registryAccess().registryOrThrow(Registries.STRUCTURE).get(ResourceLocation.tryParse(type.getId())); + if (k == null) { + return false; + } + + ServerChunkCache chunkManager = originalWorld.getChunkSource(); + WorldGenLevel proxyLevel = PaperweightServerLevelDelegateProxy.newInstance(session, originalWorld, this); + ChunkPos chunkPos = new ChunkPos(new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ())); + StructureStart structureStart = k.generate(originalWorld.registryAccess(), chunkManager.getGenerator(), chunkManager.getGenerator().getBiomeSource(), chunkManager.randomState(), originalWorld.getStructureManager(), originalWorld.getSeed(), chunkPos, 0, proxyLevel, biome -> true); + + if (!structureStart.isValid()) { + return false; + } else { + BoundingBox boundingBox = structureStart.getBoundingBox(); + ChunkPos min = new ChunkPos(SectionPos.blockToSectionCoord(boundingBox.minX()), SectionPos.blockToSectionCoord(boundingBox.minZ())); + ChunkPos max = new ChunkPos(SectionPos.blockToSectionCoord(boundingBox.maxX()), SectionPos.blockToSectionCoord(boundingBox.maxZ())); + ChunkPos.rangeClosed(min, max).forEach((chunkPosx) -> structureStart.placeInChunk(proxyLevel, originalWorld.structureManager(), chunkManager.getGenerator(), originalWorld.getRandom(), new BoundingBox(chunkPosx.getMinBlockX(), originalWorld.getMinBuildHeight(), chunkPosx.getMinBlockZ(), chunkPosx.getMaxBlockX(), originalWorld.getMaxBuildHeight(), chunkPosx.getMaxBlockZ()), chunkPosx)); + return true; + } + } + // ------------------------------------------------------------------------ // Code that is less likely to break // ------------------------------------------------------------------------ diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightServerLevelDelegateProxy.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightServerLevelDelegateProxy.java new file mode 100644 index 000000000..fb6732eef --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightServerLevelDelegateProxy.java @@ -0,0 +1,162 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_19_R3; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.util.Location; +import com.sk89q.worldedit.world.block.BlockTypes; +import com.sk89q.worldedit.world.entity.EntityTypes; +import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +public class PaperweightServerLevelDelegateProxy implements InvocationHandler { + + private final EditSession editSession; + private final ServerLevel serverLevel; + private final PaperweightAdapter adapter; + + private PaperweightServerLevelDelegateProxy(EditSession editSession, ServerLevel serverLevel, PaperweightAdapter adapter) { + this.editSession = editSession; + this.serverLevel = serverLevel; + this.adapter = adapter; + } + + public static WorldGenLevel newInstance(EditSession editSession, ServerLevel serverLevel, PaperweightAdapter adapter) { + return (WorldGenLevel) Proxy.newProxyInstance( + serverLevel.getClass().getClassLoader(), + serverLevel.getClass().getInterfaces(), + new PaperweightServerLevelDelegateProxy(editSession, serverLevel, adapter) + ); + } + + @Nullable + private BlockEntity getBlockEntity(BlockPos blockPos) { + BlockEntity tileEntity = this.serverLevel.getChunkAt(blockPos).getBlockEntity(blockPos); + if (tileEntity == null) { + return null; + } + BlockEntity newEntity = tileEntity.getType().create(blockPos, getBlockState(blockPos)); + newEntity.load((CompoundTag) adapter.fromNativeBinary(this.editSession.getFullBlock(BlockVector3.at( + blockPos.getX(), + blockPos.getY(), + blockPos.getZ() + )).getNbtReference().getValue())); + + return newEntity; + } + + private BlockState getBlockState(BlockPos blockPos) { + return adapter.adapt(this.editSession.getBlock(BlockVector3.at(blockPos.getX(), blockPos.getY(), blockPos.getZ()))); + } + + private boolean setBlock(BlockPos blockPos, BlockState blockState) { + try { + return editSession.setBlock( + BlockVector3.at(blockPos.getX(), blockPos.getY(), blockPos.getZ()), + adapter.adapt(blockState) + ); + } catch (MaxChangedBlocksException e) { + throw new RuntimeException(e); + } + } + + private boolean removeBlock(BlockPos blockPos, boolean bl) { + try { + return editSession.setBlock( + BlockVector3.at(blockPos.getX(), blockPos.getY(), blockPos.getZ()), + BlockTypes.AIR.getDefaultState() + ); + } catch (MaxChangedBlocksException e) { + throw new RuntimeException(e); + } + } + + private boolean addEntity(Entity entity) { + Vec3 pos = entity.getPosition(0.0f); + Location location = new Location(BukkitAdapter.adapt(serverLevel.getWorld()), pos.x(), pos.y(), pos.z()); + + ResourceLocation id = serverLevel.registryAccess().registryOrThrow(Registries.ENTITY_TYPE).getKey(entity.getType()); + CompoundTag tag = new CompoundTag(); + entity.saveWithoutId(tag); + BaseEntity baseEntity = new BaseEntity( + EntityTypes.get(id.toString()), + (com.sk89q.jnbt.CompoundTag) adapter.toNative(tag) + ); + + return editSession.createEntity(location, baseEntity) != null; + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + switch (method.getName()) { + case "a_", "getBlockState", "addFreshEntityWithPassengers" -> { + if (args.length == 1 && args[0] instanceof BlockPos blockPos) { + // getBlockState + return getBlockState(blockPos); + } else if (args.length >= 1 && args[0] instanceof Entity entity) { + // addFreshEntityWithPassengers + return addEntity(entity); + } + } + case "c_", "getBlockEntity" -> { + if (args.length == 1 && args[0] instanceof BlockPos blockPos) { + // getBlockEntity + return getBlockEntity(blockPos); + } + } + case "a", "setBlock", "removeBlock", "destroyBlock" -> { + if (args.length >= 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof BlockState blockState) { + // setBlock + return setBlock(blockPos, blockState); + } else if (args.length >= 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof Boolean bl) { + // removeBlock (and also matches destroyBlock) + return removeBlock(blockPos, bl); + } + } + case "j", "addEntity" -> { + if (args.length >= 1 && args[0] instanceof Entity entity) { + return addEntity(entity); + } + } + default -> { + } + } + + return method.invoke(this.serverLevel, args); + } + +} diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java index fcdc144e9..b6712cb40 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java @@ -28,6 +28,7 @@ import com.google.common.util.concurrent.Futures; import com.mojang.datafixers.util.Either; import com.mojang.serialization.Lifecycle; import com.sk89q.jnbt.NBTConstants; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItemStack; @@ -70,6 +71,7 @@ import com.sk89q.worldedit.util.nbt.ShortBinaryTag; import com.sk89q.worldedit.util.nbt.StringBinaryTag; import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.RegenOptions; +import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeTypes; import com.sk89q.worldedit.world.block.BaseBlock; @@ -77,10 +79,13 @@ import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; +import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; +import com.sk89q.worldedit.world.generation.StructureType; import com.sk89q.worldedit.world.item.ItemType; import net.minecraft.Util; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; +import net.minecraft.core.SectionPos; import net.minecraft.core.registries.Registries; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; @@ -92,6 +97,7 @@ import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.progress.ChunkProgressListener; +import net.minecraft.util.RandomSource; import net.minecraft.util.StringRepresentable; import net.minecraft.util.thread.BlockableEventLoop; import net.minecraft.world.Clearable; @@ -104,6 +110,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.LevelSettings; +import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; @@ -116,6 +123,10 @@ import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.dimension.LevelStem; import net.minecraft.world.level.levelgen.WorldOptions; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.level.levelgen.structure.Structure; +import net.minecraft.world.level.levelgen.structure.StructureStart; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.PrimaryLevelData; import net.minecraft.world.phys.BlockHitResult; @@ -172,6 +183,8 @@ public final class PaperweightAdapter implements BukkitImplAdapter k = originalWorld.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(ResourceLocation.tryParse(type.getId())); + ServerChunkCache chunkManager = originalWorld.getChunkSource(); + WorldGenLevel proxyLevel = PaperweightServerLevelDelegateProxy.newInstance(session, originalWorld, this); + return k != null && k.place(proxyLevel, chunkManager.getGenerator(), random, new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ())); + } + + public boolean generateStructure(StructureType type, World world, EditSession session, BlockVector3 pt) { + ServerLevel originalWorld = ((CraftWorld) world).getHandle(); + Structure k = originalWorld.registryAccess().registryOrThrow(Registries.STRUCTURE).get(ResourceLocation.tryParse(type.getId())); + if (k == null) { + return false; + } + + ServerChunkCache chunkManager = originalWorld.getChunkSource(); + WorldGenLevel proxyLevel = PaperweightServerLevelDelegateProxy.newInstance(session, originalWorld, this); + ChunkPos chunkPos = new ChunkPos(new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ())); + StructureStart structureStart = k.generate(originalWorld.registryAccess(), chunkManager.getGenerator(), chunkManager.getGenerator().getBiomeSource(), chunkManager.randomState(), originalWorld.getStructureManager(), originalWorld.getSeed(), chunkPos, 0, proxyLevel, biome -> true); + + if (!structureStart.isValid()) { + return false; + } else { + BoundingBox boundingBox = structureStart.getBoundingBox(); + ChunkPos min = new ChunkPos(SectionPos.blockToSectionCoord(boundingBox.minX()), SectionPos.blockToSectionCoord(boundingBox.minZ())); + ChunkPos max = new ChunkPos(SectionPos.blockToSectionCoord(boundingBox.maxX()), SectionPos.blockToSectionCoord(boundingBox.maxZ())); + ChunkPos.rangeClosed(min, max).forEach((chunkPosx) -> structureStart.placeInChunk(proxyLevel, originalWorld.structureManager(), chunkManager.getGenerator(), originalWorld.getRandom(), new BoundingBox(chunkPosx.getMinBlockX(), originalWorld.getMinBuildHeight(), chunkPosx.getMinBlockZ(), chunkPosx.getMaxBlockX(), originalWorld.getMaxBuildHeight(), chunkPosx.getMaxBlockZ()), chunkPosx)); + return true; + } + } + // ------------------------------------------------------------------------ // Code that is less likely to break // ------------------------------------------------------------------------ diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java index aa2f5529f..009c7a99d 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java @@ -313,6 +313,13 @@ public interface BukkitImplAdapter extends IBukkitAdapter { throw new UnsupportedOperationException("This adapter does not support generating features."); } + /** + * Initialize registries that require NMS access. + */ + default void initializeRegistries() { + + } + //FAWE start default BlockMaterial getMaterial(BlockType blockType) { return getMaterial(blockType.getDefaultState()); From 324dfa889a189ce8918cac648a1deaf4af746465 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Tue, 12 Dec 2023 17:28:36 +0000 Subject: [PATCH 07/12] Update 1.20.3/4 adapters --- .../fawe/v1_20_R2/PaperweightFaweAdapter.java | 1 - .../ext.fawe/v1_20_R3/PaperweightAdapter.java | 85 +++++++++ .../PaperweightServerLevelDelegateProxy.java | 121 ++++++++++++ .../v1_20_R3/FaweBlockStateListPopulator.java | 132 +++++++++++++ .../fawe/v1_20_R3/PaperweightFaweAdapter.java | 175 ++++++++++++++++++ 5 files changed, 513 insertions(+), 1 deletion(-) create mode 100644 worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightServerLevelDelegateProxy.java create mode 100644 worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/FaweBlockStateListPopulator.java diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java index 030599141..b62807fc7 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java @@ -688,7 +688,6 @@ public final class PaperweightFaweAdapter extends FaweAdapter k = originalWorld.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(ResourceLocation.tryParse(type.getId())); + ServerChunkCache chunkManager = originalWorld.getChunkSource(); + WorldGenLevel proxyLevel = PaperweightServerLevelDelegateProxy.newInstance(session, originalWorld, this); + return k != null && k.place(proxyLevel, chunkManager.getGenerator(), random, new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ())); + } + + public boolean generateStructure(StructureType type, World world, EditSession session, BlockVector3 pt) { + ServerLevel originalWorld = ((CraftWorld) world).getHandle(); + Structure k = originalWorld.registryAccess().registryOrThrow(Registries.STRUCTURE).get(ResourceLocation.tryParse(type.getId())); + if (k == null) { + return false; + } + + ServerChunkCache chunkManager = originalWorld.getChunkSource(); + WorldGenLevel proxyLevel = PaperweightServerLevelDelegateProxy.newInstance(session, originalWorld, this); + ChunkPos chunkPos = new ChunkPos(new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ())); + StructureStart structureStart = k.generate(originalWorld.registryAccess(), chunkManager.getGenerator(), chunkManager.getGenerator().getBiomeSource(), chunkManager.randomState(), originalWorld.getStructureManager(), originalWorld.getSeed(), chunkPos, 0, proxyLevel, biome -> true); + + if (!structureStart.isValid()) { + return false; + } else { + BoundingBox boundingBox = structureStart.getBoundingBox(); + ChunkPos min = new ChunkPos(SectionPos.blockToSectionCoord(boundingBox.minX()), SectionPos.blockToSectionCoord(boundingBox.minZ())); + ChunkPos max = new ChunkPos(SectionPos.blockToSectionCoord(boundingBox.maxX()), SectionPos.blockToSectionCoord(boundingBox.maxZ())); + ChunkPos.rangeClosed(min, max).forEach((chunkPosx) -> structureStart.placeInChunk(proxyLevel, originalWorld.structureManager(), chunkManager.getGenerator(), originalWorld.getRandom(), new BoundingBox(chunkPosx.getMinBlockX(), originalWorld.getMinBuildHeight(), chunkPosx.getMinBlockZ(), chunkPosx.getMaxBlockX(), originalWorld.getMaxBuildHeight(), chunkPosx.getMaxBlockZ()), chunkPosx)); + return true; + } + } + + // ------------------------------------------------------------------------ // Code that is less likely to break // ------------------------------------------------------------------------ diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightServerLevelDelegateProxy.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightServerLevelDelegateProxy.java new file mode 100644 index 000000000..d73e8900f --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightServerLevelDelegateProxy.java @@ -0,0 +1,121 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R3; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.world.block.BlockTypes; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +public class PaperweightServerLevelDelegateProxy implements InvocationHandler { + + private final EditSession editSession; + private final ServerLevel serverLevel; + private final PaperweightAdapter adapter; + + private PaperweightServerLevelDelegateProxy(EditSession editSession, ServerLevel serverLevel, PaperweightAdapter adapter) { + this.editSession = editSession; + this.serverLevel = serverLevel; + this.adapter = adapter; + } + + public static WorldGenLevel newInstance(EditSession editSession, ServerLevel serverLevel, PaperweightAdapter adapter) { + return (WorldGenLevel) Proxy.newProxyInstance( + serverLevel.getClass().getClassLoader(), + serverLevel.getClass().getInterfaces(), + new PaperweightServerLevelDelegateProxy(editSession, serverLevel, adapter) + ); + } + + @Nullable + private BlockEntity getBlockEntity(BlockPos blockPos) { + BlockEntity tileEntity = this.serverLevel.getChunkAt(blockPos).getBlockEntity(blockPos); + if (tileEntity == null) { + return null; + } + BlockEntity newEntity = tileEntity.getType().create(blockPos, getBlockState(blockPos)); + newEntity.load((CompoundTag) adapter.fromNativeBinary(this.editSession.getFullBlock(BlockVector3.at(blockPos.getX(), + blockPos.getY(), blockPos.getZ())).getNbtReference().getValue())); + + return newEntity; + } + + private BlockState getBlockState(BlockPos blockPos) { + return adapter.adapt(this.editSession.getBlock(BlockVector3.at(blockPos.getX(), blockPos.getY(), blockPos.getZ()))); + } + + private boolean setBlock(BlockPos blockPos, BlockState blockState) { + try { + return editSession.setBlock(BlockVector3.at(blockPos.getX(), blockPos.getY(), blockPos.getZ()), adapter.adapt(blockState)); + } catch (MaxChangedBlocksException e) { + throw new RuntimeException(e); + } + } + + private boolean removeBlock(BlockPos blockPos, boolean bl) { + try { + return editSession.setBlock(BlockVector3.at(blockPos.getX(), blockPos.getY(), blockPos.getZ()), BlockTypes.AIR.getDefaultState()); + } catch (MaxChangedBlocksException e) { + throw new RuntimeException(e); + } + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + switch (method.getName()) { + case "a_", "getBlockState" -> { + if (args.length == 1 && args[0] instanceof BlockPos blockPos) { + // getBlockState + return getBlockState(blockPos); + } + } + case "c_", "getBlockEntity" -> { + if (args.length == 1 && args[0] instanceof BlockPos blockPos) { + // getBlockEntity + return getBlockEntity(blockPos); + } + } + case "a", "setBlock", "removeBlock", "destroyBlock" -> { + if (args.length >= 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof BlockState blockState) { + // setBlock + return setBlock(blockPos, blockState); + } else if (args.length >= 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof Boolean bl) { + // removeBlock (and also matches destroyBlock) + return removeBlock(blockPos, bl); + } + } + default -> { } + } + + return method.invoke(this.serverLevel, args); + } + +} diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/FaweBlockStateListPopulator.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/FaweBlockStateListPopulator.java new file mode 100644 index 000000000..6b9050fed --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/FaweBlockStateListPopulator.java @@ -0,0 +1,132 @@ +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R3; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Holder; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.flag.FeatureFlagSet; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeManager; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.border.WorldBorder; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkSource; +import net.minecraft.world.level.chunk.ChunkStatus; +import net.minecraft.world.level.lighting.LevelLightEngine; +import net.minecraft.world.level.material.FluidState; +import org.bukkit.craftbukkit.v1_20_R3.util.BlockStateListPopulator; +import org.jetbrains.annotations.Nullable; + +public class FaweBlockStateListPopulator extends BlockStateListPopulator { + + private final ServerLevel world; + + public FaweBlockStateListPopulator(ServerLevel world) { + super(world); + this.world = world; + } + + @Override + public long getSeed() { + return world.getSeed(); + } + + @Override + public ServerLevel getLevel() { + return world.getLevel(); + } + + @Override + public MinecraftServer getServer() { + return world.getServer(); + } + + @Override + public ChunkSource getChunkSource() { + return world.getChunkSource(); + } + + @Override + public ChunkAccess getChunk(final int chunkX, final int chunkZ, final ChunkStatus leastStatus, final boolean create) { + return world.getChunk(chunkX, chunkZ, leastStatus, create); + } + + @Override + public BiomeManager getBiomeManager() { + return world.getBiomeManager(); + } + + @Override + public Holder getUncachedNoiseBiome(final int biomeX, final int biomeY, final int biomeZ) { + return world.getUncachedNoiseBiome(biomeX, biomeY, biomeZ); + } + + @Override + public int getSeaLevel() { + return world.getSeaLevel(); + } + + @Override + public FeatureFlagSet enabledFeatures() { + return world.enabledFeatures(); + } + + @Override + public float getShade(final Direction direction, final boolean shaded) { + return world.getShade(direction, shaded); + } + + @Override + public LevelLightEngine getLightEngine() { + return world.getLightEngine(); + } + + @Nullable + @Override + public ChunkAccess getChunkIfLoadedImmediately(final int x, final int z) { + return world.getChunkIfLoadedImmediately(x, z); + } + + @Override + public BlockState getBlockStateIfLoaded(final BlockPos blockposition) { + return world.getBlockStateIfLoaded(blockposition); + } + + @Override + public FluidState getFluidIfLoaded(final BlockPos blockposition) { + return world.getFluidIfLoaded(blockposition); + } + + @Override + public WorldBorder getWorldBorder() { + return world.getWorldBorder(); + } + + @Override + public boolean setBlock(final BlockPos pos, final BlockState state, final int flags, final int maxUpdateDepth) { + return world.setBlock(pos, state, flags, maxUpdateDepth); + } + + @Override + public boolean removeBlock(final BlockPos pos, final boolean move) { + return world.removeBlock(pos, move); + } + + @Override + public boolean destroyBlock(final BlockPos pos, final boolean drop, final Entity breakingEntity, final int maxUpdateDepth) { + return world.destroyBlock(pos, drop, breakingEntity, maxUpdateDepth); + } + + @Override + public BlockState getBlockState(final BlockPos pos) { + return world.getBlockState(pos); + } + + @Override + public boolean setBlock(final BlockPos pos, final BlockState state, final int flags) { + return world.setBlock(pos, state, flags); + } + +} diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightFaweAdapter.java index 4414719b8..2493f0c0d 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightFaweAdapter.java @@ -9,10 +9,13 @@ import com.fastasyncworldedit.core.queue.IBatchProcessor; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.implementation.packet.ChunkPacket; import com.fastasyncworldedit.core.util.NbtUtils; +import com.fastasyncworldedit.core.util.TaskManager; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; @@ -45,11 +48,14 @@ import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypesCache; import com.sk89q.worldedit.world.entity.EntityType; +import com.sk89q.worldedit.world.generation.ConfiguredFeatureType; +import com.sk89q.worldedit.world.generation.StructureType; import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.registry.BlockMaterial; import io.papermc.lib.PaperLib; import net.minecraft.core.BlockPos; import net.minecraft.core.Registry; +import net.minecraft.core.SectionPos; import net.minecraft.core.WritableRegistry; import net.minecraft.core.registries.Registries; import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; @@ -57,17 +63,24 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.level.ChunkHolder; +import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.util.StringRepresentable; import net.minecraft.world.entity.Entity; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.level.levelgen.structure.Structure; +import net.minecraft.world.level.levelgen.structure.StructureStart; import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -76,6 +89,7 @@ import org.bukkit.World; import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.v1_20_R3.CraftServer; import org.bukkit.craftbukkit.v1_20_R3.CraftWorld; +import org.bukkit.craftbukkit.v1_20_R3.block.CraftBlockState; import org.bukkit.craftbukkit.v1_20_R3.block.data.CraftBlockData; import org.bukkit.craftbukkit.v1_20_R3.entity.CraftEntity; import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer; @@ -513,6 +527,167 @@ public final class PaperweightFaweAdapter extends FaweAdapter configuredFeature = serverLevel + .registryAccess() + .registryOrThrow(Registries.CONFIGURED_FEATURE) + .get(ResourceLocation.tryParse(feature.getId())); + FaweBlockStateListPopulator populator = new FaweBlockStateListPopulator(serverLevel); + + Map placed = TaskManager.taskManager().sync(() -> { + serverLevel.captureTreeGeneration = true; + serverLevel.captureBlockStates = true; + try { + if (!configuredFeature.place( + populator, + generator, + serverLevel.random, + new BlockPos(pt.getX(), pt.getY(), pt.getZ()) + )) { + return null; + } + return populator.getList().stream().collect(Collectors.toMap( + CraftBlockState::getPosition, + craftBlockState -> craftBlockState + )); + } finally { + serverLevel.captureBlockStates = false; + serverLevel.captureTreeGeneration = false; + serverLevel.capturedBlockStates.clear(); + } + }); + + return placeFeatureIntoSession(editSession, populator, placed); + //FAWE end + } + + @Override + public boolean generateStructure(StructureType type, World world, EditSession editSession, BlockVector3 pt) { + ServerLevel serverLevel = ((CraftWorld) world).getHandle(); + Structure k = serverLevel + .registryAccess() + .registryOrThrow(Registries.STRUCTURE) + .get(ResourceLocation.tryParse(type.getId())); + if (k == null) { + return false; + } + + ServerChunkCache chunkManager = serverLevel.getChunkSource(); + + ChunkPos chunkPos = new ChunkPos(new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ())); + + //FAWE start + FaweBlockStateListPopulator populator = new FaweBlockStateListPopulator(serverLevel); + Map placed = TaskManager.taskManager().sync(() -> { + serverLevel.captureTreeGeneration = true; + serverLevel.captureBlockStates = true; + try { + StructureStart structureStart = k.generate( + serverLevel.registryAccess(), + chunkManager.getGenerator(), + chunkManager.getGenerator().getBiomeSource(), + chunkManager.randomState(), + serverLevel.getStructureManager(), + serverLevel.getSeed(), + chunkPos, + 0, + populator, + biome -> true + ); + if (!structureStart.isValid()) { + return null; + } else { + BoundingBox boundingBox = structureStart.getBoundingBox(); + ChunkPos min = new ChunkPos( + SectionPos.blockToSectionCoord(boundingBox.minX()), + SectionPos.blockToSectionCoord(boundingBox.minZ()) + ); + ChunkPos max = new ChunkPos( + SectionPos.blockToSectionCoord(boundingBox.maxX()), + SectionPos.blockToSectionCoord(boundingBox.maxZ()) + ); + ChunkPos.rangeClosed(min, max).forEach((chunkPosx) -> structureStart.placeInChunk( + populator, + serverLevel.structureManager(), + chunkManager.getGenerator(), + serverLevel.getRandom(), + new BoundingBox( + chunkPosx.getMinBlockX(), + serverLevel.getMinBuildHeight(), + chunkPosx.getMinBlockZ(), + chunkPosx.getMaxBlockX(), + serverLevel.getMaxBuildHeight(), + chunkPosx.getMaxBlockZ() + ), + chunkPosx + )); + Map placedBlocks = populator.getList().stream().collect(Collectors.toMap( + CraftBlockState::getPosition, + craftBlockState -> craftBlockState + )); + placedBlocks.putAll(serverLevel.capturedBlockStates); + return placedBlocks; + } + } finally { + serverLevel.captureBlockStates = false; + serverLevel.captureTreeGeneration = false; + serverLevel.capturedBlockStates.clear(); + } + }); + + return placeFeatureIntoSession(editSession, populator, placed); + //FAWE end + } + + private boolean placeFeatureIntoSession( + final EditSession editSession, + final FaweBlockStateListPopulator populator, + final Map placed + ) { + if (placed == null || placed.isEmpty()) { + return false; + } + + for (Map.Entry entry : placed.entrySet()) { + CraftBlockState craftBlockState = entry.getValue(); + if (entry.getValue() == null) { + continue; + } + BlockPos pos = entry.getKey(); + editSession.setBlock(pos.getX(), pos.getY(), pos.getZ(), BukkitAdapter.adapt(craftBlockState.getBlockData())); + BlockEntity blockEntity = populator.getBlockEntity(pos); + if (blockEntity != null) { + net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(); + editSession.setTile(pos.getX(), pos.getY(), pos.getZ(), (CompoundTag) toNative(tag)); + } + } + return true; + } + + @Override + public void setupFeatures() { + DedicatedServer server = ((CraftServer) Bukkit.getServer()).getServer(); + + // Features + for (ResourceLocation name : server.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).keySet()) { + if (ConfiguredFeatureType.REGISTRY.get(name.toString()) == null) { + ConfiguredFeatureType.REGISTRY.register(name.toString(), new ConfiguredFeatureType(name.toString())); + } + } + + // Structures + for (ResourceLocation name : server.registryAccess().registryOrThrow(Registries.STRUCTURE).keySet()) { + if (StructureType.REGISTRY.get(name.toString()) == null) { + StructureType.REGISTRY.register(name.toString(), new StructureType(name.toString())); + } + } + } + @Override public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) { final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); From 2e9e78d7e8958069e2a79e29bbe4e5597ea594a3 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Thu, 28 Mar 2024 12:44:28 +0000 Subject: [PATCH 08/12] fix ext.fawe -> ext/fawe --- .../{ext.fawe => ext/fawe}/v1_20_R3/PaperweightAdapter.java | 0 .../fawe}/v1_20_R3/PaperweightDataConverters.java | 0 .../{ext.fawe => ext/fawe}/v1_20_R3/PaperweightFakePlayer.java | 0 .../fawe}/v1_20_R3/PaperweightServerLevelDelegateProxy.java | 0 .../fawe}/v1_20_R3/PaperweightWorldNativeAccess.java | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/{ext.fawe => ext/fawe}/v1_20_R3/PaperweightAdapter.java (100%) rename worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/{ext.fawe => ext/fawe}/v1_20_R3/PaperweightDataConverters.java (100%) rename worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/{ext.fawe => ext/fawe}/v1_20_R3/PaperweightFakePlayer.java (100%) rename worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/{ext.fawe => ext/fawe}/v1_20_R3/PaperweightServerLevelDelegateProxy.java (100%) rename worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/{ext.fawe => ext/fawe}/v1_20_R3/PaperweightWorldNativeAccess.java (100%) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightAdapter.java similarity index 100% rename from worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightAdapter.java rename to worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightAdapter.java diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightDataConverters.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightDataConverters.java similarity index 100% rename from worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightDataConverters.java rename to worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightDataConverters.java diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightFakePlayer.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightFakePlayer.java similarity index 100% rename from worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightFakePlayer.java rename to worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightFakePlayer.java diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightServerLevelDelegateProxy.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightServerLevelDelegateProxy.java similarity index 100% rename from worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightServerLevelDelegateProxy.java rename to worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightServerLevelDelegateProxy.java diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightWorldNativeAccess.java similarity index 100% rename from worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightWorldNativeAccess.java rename to worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightWorldNativeAccess.java From ef9c2c0bd3e75586a87b7efbf127de3443b3b17e Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Fri, 31 May 2024 18:15:56 +0100 Subject: [PATCH 09/12] Address vector deprecations --- .../bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java | 4 ++-- .../adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java | 4 ++-- .../bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java | 4 ++-- .../adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java | 4 ++-- .../bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java | 4 ++-- .../adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java | 4 ++-- .../bukkit/adapter/ext/fawe/v1_20_R3/PaperweightAdapter.java | 4 ++-- .../adapter/impl/fawe/v1_20_R3/PaperweightFaweAdapter.java | 4 ++-- .../adapter/impl/fawe/v1_20_R4/PaperweightFaweAdapter.java | 4 ++-- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java index b092048d3..bbe9f4a3d 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java @@ -862,7 +862,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter k = originalWorld.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(ResourceLocation.tryParse(type.getId())); ServerChunkCache chunkManager = originalWorld.getChunkSource(); WorldGenLevel proxyLevel = PaperweightServerLevelDelegateProxy.newInstance(session, originalWorld, this); - return k != null && k.place(proxyLevel, chunkManager.getGenerator(), random, new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ())); + return k != null && k.place(proxyLevel, chunkManager.getGenerator(), random, new BlockPos(pt.x(), pt.y(), pt.z())); } public boolean generateStructure(StructureType type, World world, EditSession session, BlockVector3 pt) { @@ -874,7 +874,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter true); if (!structureStart.isValid()) { diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java index 8c208f1ed..c10a7378e 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java @@ -543,7 +543,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter k = originalWorld.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(ResourceLocation.tryParse(type.getId())); ServerChunkCache chunkManager = originalWorld.getChunkSource(); WorldGenLevel proxyLevel = PaperweightServerLevelDelegateProxy.newInstance(session, originalWorld, this); - return k != null && k.place(proxyLevel, chunkManager.getGenerator(), random, new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ())); + return k != null && k.place(proxyLevel, chunkManager.getGenerator(), random, new BlockPos(pt.x(), pt.y(), pt.z())); } public boolean generateStructure(StructureType type, World world, EditSession session, BlockVector3 pt) { @@ -920,7 +920,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter true); if (!structureStart.isValid()) { diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java index 815a59fa2..7bdcc1b76 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java @@ -544,7 +544,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter k = originalWorld.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(ResourceLocation.tryParse(type.getId())); ServerChunkCache chunkManager = originalWorld.getChunkSource(); WorldGenLevel proxyLevel = PaperweightServerLevelDelegateProxy.newInstance(session, originalWorld, this); - return k != null && k.place(proxyLevel, chunkManager.getGenerator(), random, new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ())); + return k != null && k.place(proxyLevel, chunkManager.getGenerator(), random, new BlockPos(pt.x(), pt.y(), pt.z())); } public boolean generateStructure(StructureType type, World world, EditSession session, BlockVector3 pt) { @@ -875,7 +875,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter true); if (!structureStart.isValid()) { diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java index 0667dee3f..6454ac8ee 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java @@ -547,7 +547,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter k = originalWorld.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(ResourceLocation.tryParse(type.getId())); ServerChunkCache chunkManager = originalWorld.getChunkSource(); WorldGenLevel proxyLevel = PaperweightServerLevelDelegateProxy.newInstance(session, originalWorld, this); - return k != null && k.place(proxyLevel, chunkManager.getGenerator(), random, new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ())); + return k != null && k.place(proxyLevel, chunkManager.getGenerator(), random, new BlockPos(pt.x(), pt.y(), pt.z())); } public boolean generateStructure(StructureType type, World world, EditSession session, BlockVector3 pt) { @@ -875,7 +875,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter true); if (!structureStart.isValid()) { diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightFaweAdapter.java index c15337b76..6e5e0999f 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightFaweAdapter.java @@ -547,7 +547,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter Date: Fri, 7 Jun 2024 19:14:23 +0100 Subject: [PATCH 10/12] Upstream changes, use correct list of cached block changes --- .../ext/fawe/v1_19_R3/PaperweightAdapter.java | 12 ++--- .../v1_19_R3/FaweBlockStateListPopulator.java | 42 ++++++++++++++++ .../fawe/v1_19_R3/PaperweightFaweAdapter.java | 13 ++--- .../v1_19_R3/PaperweightPlatformAdapter.java | 14 +++++- .../ext/fawe/v1_20_R1/PaperweightAdapter.java | 12 ++--- .../v1_20_R1/FaweBlockStateListPopulator.java | 42 ++++++++++++++++ .../fawe/v1_20_R1/PaperweightFaweAdapter.java | 13 ++--- .../v1_20_R1/PaperweightPlatformAdapter.java | 14 +++++- .../ext/fawe/v1_20_R2/PaperweightAdapter.java | 12 ++--- .../v1_20_R2/FaweBlockStateListPopulator.java | 18 ++++++- .../fawe/v1_20_R2/PaperweightFaweAdapter.java | 13 ++--- .../v1_20_R2/PaperweightPlatformAdapter.java | 14 +++++- .../ext/fawe/v1_20_R3/PaperweightAdapter.java | 14 +++--- .../v1_20_R3/FaweBlockStateListPopulator.java | 18 ++++++- .../fawe/v1_20_R3/PaperweightFaweAdapter.java | 15 +++--- .../v1_20_R3/PaperweightPlatformAdapter.java | 13 +++++ .../ext.fawe/v1_20_R4/PaperweightAdapter.java | 10 ++-- .../v1_20_R4/FaweBlockStateListPopulator.java | 50 +++++++++++++++++++ .../fawe/v1_20_R4/PaperweightFaweAdapter.java | 17 +++---- .../v1_20_R4/PaperweightPlatformAdapter.java | 15 +++++- .../bukkit/adapter/IBukkitAdapter.java | 12 ++--- .../worldedit/bukkit/BukkitBiomeRegistry.java | 2 +- .../sk89q/worldedit/bukkit/BukkitPlayer.java | 4 +- .../bukkit/BukkitServerInterface.java | 2 +- .../sk89q/worldedit/bukkit/BukkitWorld.java | 2 +- .../sk89q/worldedit/cli/CLIBlockRegistry.java | 2 +- .../com/sk89q/worldedit/cli/CLIPlatform.java | 2 +- .../cli/schematic/ClipboardWorld.java | 2 +- .../core/extent/DisallowedBlocksExtent.java | 4 +- .../core/extent/HistoryExtent.java | 4 +- .../clipboard/io/FastSchematicWriter.java | 4 +- .../io/schematic/MinecraftStructure.java | 4 +- .../processor/lighting/NMSRelighter.java | 22 ++++---- .../core/function/generator/CavesGen.java | 4 +- .../core/function/mask/ABlockMask.java | 2 +- .../core/function/mask/BlockMaskBuilder.java | 6 +-- .../function/pattern/TypeSwapPattern.java | 2 +- .../core/util/MainUtil.java | 2 +- .../core/util/TextureUtil.java | 6 +-- .../sk89q/worldedit/LocalConfiguration.java | 4 +- .../com/sk89q/worldedit/LocalSession.java | 4 +- .../com/sk89q/worldedit/blocks/BaseItem.java | 2 +- .../worldedit/command/BiomeCommands.java | 4 +- .../worldedit/command/GeneralCommands.java | 4 +- .../worldedit/command/SelectionCommands.java | 2 +- .../command/argument/WorldConverter.java | 4 +- .../command/tool/BlockDataCyler.java | 2 +- .../factory/parser/DefaultBlockParser.java | 50 +++++++++---------- .../pattern/BlockCategoryPatternParser.java | 2 +- .../extension/platform/Platform.java | 3 +- .../worldedit/extent/clipboard/Clipboard.java | 2 +- .../clipboard/io/SpongeSchematicWriter.java | 4 +- .../FlowerPotCompatibilityHandler.java | 2 +- .../Pre13HangingCompatibilityHandler.java | 2 +- .../transform/BlockTransformExtent.java | 2 +- .../function/block/SnowSimulator.java | 4 +- .../internal/cui/ServerCUIHandler.java | 2 +- .../sk89q/worldedit/registry/Category.java | 4 +- .../com/sk89q/worldedit/registry/Keyed.java | 2 +- .../util/PropertiesConfiguration.java | 4 +- .../com/sk89q/worldedit/world/NullWorld.java | 2 +- .../java/com/sk89q/worldedit/world/World.java | 2 +- .../worldedit/world/biome/BiomeType.java | 4 +- .../worldedit/world/biome/BiomeTypes.java | 2 +- .../worldedit/world/block/BlockState.java | 2 +- .../world/block/BlockStateHolder.java | 4 +- .../worldedit/world/block/BlockType.java | 14 +++--- .../worldedit/world/block/BlockTypes.java | 4 +- .../worldedit/world/chunk/AnvilChunk13.java | 2 +- .../worldedit/world/chunk/AnvilChunk17.java | 2 +- .../worldedit/world/chunk/AnvilChunk18.java | 2 +- .../worldedit/world/entity/EntityType.java | 6 +-- .../world/fluid/FluidCategories.java | 2 +- .../worldedit/world/fluid/FluidType.java | 4 +- .../worldedit/world/fluid/FluidTypes.java | 2 +- .../worldedit/world/gamemode/GameMode.java | 6 +-- .../worldedit/world/gamemode/GameModes.java | 2 +- .../generation/ConfiguredFeatureType.java | 15 ++---- .../world/generation/StructureType.java | 15 ++---- .../sk89q/worldedit/world/item/ItemType.java | 6 +-- .../world/registry/BundledBlockRegistry.java | 8 +-- .../world/registry/BundledItemRegistry.java | 8 +-- .../world/registry/CategoryRegistry.java | 2 +- .../world/registry/NullBiomeRegistry.java | 2 +- .../worldedit/world/weather/WeatherType.java | 6 +-- .../worldedit/world/weather/WeatherTypes.java | 2 +- 86 files changed, 443 insertions(+), 251 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java index bbe9f4a3d..7e177984a 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java @@ -296,11 +296,11 @@ public final class PaperweightAdapter implements BukkitImplAdapter k = originalWorld.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(ResourceLocation.tryParse(type.getId())); + ConfiguredFeature k = originalWorld.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(ResourceLocation.tryParse(type.id())); ServerChunkCache chunkManager = originalWorld.getChunkSource(); WorldGenLevel proxyLevel = PaperweightServerLevelDelegateProxy.newInstance(session, originalWorld, this); return k != null && k.place(proxyLevel, chunkManager.getGenerator(), random, new BlockPos(pt.x(), pt.y(), pt.z())); @@ -867,7 +867,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter configuredFeature = serverLevel .registryAccess() .registryOrThrow(Registries.CONFIGURED_FEATURE) - .get(ResourceLocation.tryParse(feature.getId())); + .get(ResourceLocation.tryParse(feature.id())); FaweBlockStateListPopulator populator = new FaweBlockStateListPopulator(serverLevel); Map placed = TaskManager.taskManager().sync(() -> { @@ -547,10 +547,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter craftBlockState - )); + return new HashMap<>(populator.getLevel().capturedBlockStates); } finally { serverLevel.captureBlockStates = false; serverLevel.captureTreeGeneration = false; @@ -568,7 +565,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter getStatePropertiesCodec( + net.minecraft.world.level.block.state.BlockState state + ) throws IllegalAccessException { + return (MapCodec) fieldPropertiesCodec.get(state); + } + record FakeIdMapBlock(int size) implements IdMap { @Override diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java index 522f1cffa..3f48a05cd 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java @@ -297,11 +297,11 @@ public final class PaperweightAdapter implements BukkitImplAdapter k = originalWorld.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(ResourceLocation.tryParse(type.getId())); + ConfiguredFeature k = originalWorld.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(ResourceLocation.tryParse(type.id())); ServerChunkCache chunkManager = originalWorld.getChunkSource(); WorldGenLevel proxyLevel = PaperweightServerLevelDelegateProxy.newInstance(session, originalWorld, this); return k != null && k.place(proxyLevel, chunkManager.getGenerator(), random, new BlockPos(pt.x(), pt.y(), pt.z())); @@ -913,7 +913,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter configuredFeature = serverLevel .registryAccess() .registryOrThrow(Registries.CONFIGURED_FEATURE) - .get(ResourceLocation.tryParse(feature.getId())); + .get(ResourceLocation.tryParse(feature.id())); FaweBlockStateListPopulator populator = new FaweBlockStateListPopulator(serverLevel); Map placed = TaskManager.taskManager().sync(() -> { @@ -548,10 +548,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter craftBlockState - )); + return new HashMap<>(populator.getLevel().capturedBlockStates); } finally { serverLevel.captureBlockStates = false; serverLevel.captureTreeGeneration = false; @@ -569,7 +566,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter getStatePropertiesCodec( + net.minecraft.world.level.block.state.BlockState state + ) throws IllegalAccessException { + return (MapCodec) fieldPropertiesCodec.get(state); + } + record FakeIdMapBlock(int size) implements IdMap { @Override diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java index 73be8ccf7..b649a7b3a 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java @@ -294,11 +294,11 @@ public final class PaperweightAdapter implements BukkitImplAdapter k = originalWorld.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(ResourceLocation.tryParse(type.getId())); + ConfiguredFeature k = originalWorld.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(ResourceLocation.tryParse(type.id())); ServerChunkCache chunkManager = originalWorld.getChunkSource(); WorldGenLevel proxyLevel = PaperweightServerLevelDelegateProxy.newInstance(session, originalWorld, this); return k != null && k.place(proxyLevel, chunkManager.getGenerator(), random, new BlockPos(pt.x(), pt.y(), pt.z())); @@ -868,7 +868,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter configuredFeature = serverLevel .registryAccess() .registryOrThrow(Registries.CONFIGURED_FEATURE) - .get(ResourceLocation.tryParse(feature.getId())); + .get(ResourceLocation.tryParse(feature.id())); FaweBlockStateListPopulator populator = new FaweBlockStateListPopulator(serverLevel); Map placed = TaskManager.taskManager().sync(() -> { @@ -551,10 +551,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter craftBlockState - )); + return new HashMap<>(populator.getLevel().capturedBlockStates); } finally { serverLevel.captureBlockStates = false; serverLevel.captureTreeGeneration = false; @@ -572,7 +569,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter getStatePropertiesCodec( + net.minecraft.world.level.block.state.BlockState state + ) throws IllegalAccessException { + return (MapCodec) fieldPropertiesCodec.get(state); + } + record FakeIdMapBlock(int size) implements IdMap { @Override diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightAdapter.java index 605f7428e..bf7f72e93 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightAdapter.java @@ -148,6 +148,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; @@ -169,7 +170,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; @@ -294,11 +294,11 @@ public final class PaperweightAdapter implements BukkitImplAdapter k = originalWorld.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(ResourceLocation.tryParse(type.getId())); + ConfiguredFeature k = originalWorld.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(ResourceLocation.tryParse(type.id())); ServerChunkCache chunkManager = originalWorld.getChunkSource(); WorldGenLevel proxyLevel = PaperweightServerLevelDelegateProxy.newInstance(session, originalWorld, this); return k != null && k.place(proxyLevel, chunkManager.getGenerator(), random, new BlockPos(pt.x(), pt.y(), pt.z())); @@ -868,7 +868,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter configuredFeature = serverLevel .registryAccess() .registryOrThrow(Registries.CONFIGURED_FEATURE) - .get(ResourceLocation.tryParse(feature.getId())); + .get(ResourceLocation.tryParse(feature.id())); FaweBlockStateListPopulator populator = new FaweBlockStateListPopulator(serverLevel); Map placed = TaskManager.taskManager().sync(() -> { @@ -549,19 +549,16 @@ public final class PaperweightFaweAdapter extends FaweAdapter craftBlockState - )); + return new HashMap<>(populator.getLevel().capturedBlockStates); } finally { serverLevel.captureBlockStates = false; serverLevel.captureTreeGeneration = false; serverLevel.capturedBlockStates.clear(); } }); - return placeFeatureIntoSession(editSession, populator, placed); //FAWE end } @@ -572,7 +569,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter getStatePropertiesCodec( + net.minecraft.world.level.block.state.BlockState state + ) throws IllegalAccessException { + return (MapCodec) fieldPropertiesCodec.get(state); + } + record FakeIdMapBlock(int size) implements IdMap { @Override diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java index 8218ec892..dcafe36e5 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java @@ -142,6 +142,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; @@ -163,7 +164,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; @@ -291,12 +291,12 @@ public final class PaperweightAdapter implements BukkitImplAdapter, Comparable>) state.getValues(), + PaperweightPlatformAdapter.getStatePropertiesCodec(state) + ) { + @Override + public boolean is(Block block) { + return true; + } + }; + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return state; + } + + @Override + public boolean setBlock(final BlockPos pos, final BlockState state, final int flags) { + return world.setBlock(pos, state, flags); + } + } diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightFaweAdapter.java index cb952aec4..f79c737b6 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightFaweAdapter.java @@ -13,8 +13,8 @@ import com.fastasyncworldedit.core.util.TaskManager; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.sk89q.jnbt.CompoundTag; import com.mojang.serialization.Codec; +import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.blocks.BaseItemStack; @@ -57,8 +57,8 @@ import com.sk89q.worldedit.world.registry.BlockMaterial; import io.papermc.lib.PaperLib; import net.minecraft.core.BlockPos; import net.minecraft.core.Registry; -import net.minecraft.core.SectionPos; import net.minecraft.core.RegistryAccess; +import net.minecraft.core.SectionPos; import net.minecraft.core.WritableRegistry; import net.minecraft.core.component.DataComponentPatch; import net.minecraft.core.registries.Registries; @@ -505,7 +505,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter configuredFeature = serverLevel .registryAccess() .registryOrThrow(Registries.CONFIGURED_FEATURE) - .get(ResourceLocation.tryParse(feature.getId())); + .get(ResourceLocation.tryParse(feature.id())); FaweBlockStateListPopulator populator = new FaweBlockStateListPopulator(serverLevel); Map placed = TaskManager.taskManager().sync(() -> { @@ -565,10 +565,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter craftBlockState - )); + return new HashMap<>(populator.getLevel().capturedBlockStates); } finally { serverLevel.captureBlockStates = false; serverLevel.captureTreeGeneration = false; @@ -586,7 +583,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter getStatePropertiesCodec( + net.minecraft.world.level.block.state.BlockState state + ) throws IllegalAccessException { + return (MapCodec) fieldPropertiesCodec.get(state); + } + record FakeIdMapBlock(int size) implements IdMap { @Override diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IBukkitAdapter.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IBukkitAdapter.java index 81fad5ccd..b8abff0ec 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IBukkitAdapter.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IBukkitAdapter.java @@ -166,10 +166,10 @@ public interface IBukkitAdapter { */ default Material adapt(ItemType itemType) { checkNotNull(itemType); - if (!itemType.getId().startsWith("minecraft:")) { + if (!itemType.id().startsWith("minecraft:")) { throw new IllegalArgumentException("Bukkit only supports Minecraft items"); } - return Material.getMaterial(itemType.getId().substring(10).toUpperCase(Locale.ROOT)); + return Material.getMaterial(itemType.id().substring(10).toUpperCase(Locale.ROOT)); } /** @@ -180,10 +180,10 @@ public interface IBukkitAdapter { */ default Material adapt(BlockType blockType) { checkNotNull(blockType); - if (!blockType.getId().startsWith("minecraft:")) { + if (!blockType.id().startsWith("minecraft:")) { throw new IllegalArgumentException("Bukkit only supports Minecraft blocks"); } - String id = blockType.getId().substring(10).toUpperCase(Locale.ROOT); + String id = blockType.id().substring(10).toUpperCase(Locale.ROOT); return Material.getMaterial(id); } @@ -293,11 +293,11 @@ public interface IBukkitAdapter { } default Biome adapt(BiomeType biomeType) { - if (!biomeType.getId().startsWith("minecraft:")) { + if (!biomeType.id().startsWith("minecraft:")) { throw new IllegalArgumentException("Bukkit only supports vanilla biomes"); } try { - return Biome.valueOf(biomeType.getId().substring(10).toUpperCase(Locale.ROOT)); + return Biome.valueOf(biomeType.id().substring(10).toUpperCase(Locale.ROOT)); } catch (IllegalArgumentException e) { return null; } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBiomeRegistry.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBiomeRegistry.java index f78e1ae6a..087834f9b 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBiomeRegistry.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBiomeRegistry.java @@ -40,7 +40,7 @@ class BukkitBiomeRegistry implements BiomeRegistry { @Override public Component getRichName(BiomeType biomeType) { return TranslatableComponent.of( - TranslationManager.makeTranslationKey("biome", biomeType.getId()) + TranslationManager.makeTranslationKey("biome", biomeType.id()) ); } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java index 8a0081484..44918557e 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java @@ -162,7 +162,7 @@ public class BukkitPlayer extends AbstractPlayerActor { final PlayerInventory inv = player.getInventory(); ItemStack newItem = BukkitAdapter.adapt(itemStack); TaskManager.taskManager().sync(() -> { - if (itemStack.getType().getId().equalsIgnoreCase(WorldEdit.getInstance().getConfiguration().wandItem)) { + if (itemStack.getType().id().equalsIgnoreCase(WorldEdit.getInstance().getConfiguration().wandItem)) { inv.remove(newItem); } final ItemStack item = player.getInventory().getItemInMainHand(); @@ -267,7 +267,7 @@ public class BukkitPlayer extends AbstractPlayerActor { @Override public void setGameMode(GameMode gameMode) { - player.setGameMode(org.bukkit.GameMode.valueOf(gameMode.getId().toUpperCase(Locale.ROOT))); + player.setGameMode(org.bukkit.GameMode.valueOf(gameMode.id().toUpperCase(Locale.ROOT))); } @Override diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java index 3bf09481e..01d84e8ef 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java @@ -230,7 +230,7 @@ public class BukkitServerInterface extends AbstractPlatform implements MultiUser //FAWE start @Override - public String getId() { + public String id() { return "intellectualsites:bukkit"; } //FAWE end diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index f2ef3e63c..8f4602169 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -226,7 +226,7 @@ public class BukkitWorld extends AbstractWorld { //FAWE end @Override - public String getId() { + public String id() { return getWorld().getName().replace(" ", "_").toLowerCase(Locale.ROOT); } diff --git a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIBlockRegistry.java b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIBlockRegistry.java index 1fdb97ae6..01ad15c1e 100644 --- a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIBlockRegistry.java +++ b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIBlockRegistry.java @@ -68,7 +68,7 @@ public class CLIBlockRegistry extends BundledBlockRegistry { @Override public Map> getProperties(BlockType blockType) { Map properties = - CLIWorldEdit.inst.getFileRegistries().getDataFile().blocks.get(blockType.getId()).properties; + CLIWorldEdit.inst.getFileRegistries().getDataFile().blocks.get(blockType.id()).properties; Maps.EntryTransformer> entryTransform = (key, value) -> createProperty(value.type, key, value.values); return ImmutableMap.copyOf(Maps.transformEntries(properties, entryTransform)); diff --git a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIPlatform.java b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIPlatform.java index e9a397b73..4895a2922 100644 --- a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIPlatform.java +++ b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIPlatform.java @@ -115,7 +115,7 @@ class CLIPlatform extends AbstractPlatform { @Override public World matchWorld(World world) { return this.worlds.stream() - .filter(w -> w.getId().equals(world.getId())) + .filter(w -> w.id().equals(world.id())) .findAny() .orElse(null); } diff --git a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java index a8190234c..e0b4c64f2 100644 --- a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java +++ b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java @@ -85,7 +85,7 @@ public class ClipboardWorld extends AbstractWorld implements Clipboard, CLIWorld //FAWE end @Override - public String getId() { + public String id() { return getName().replace(" ", "_").toLowerCase(Locale.ROOT); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/DisallowedBlocksExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/DisallowedBlocksExtent.java index f1c523ce3..11f15131f 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/DisallowedBlocksExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/DisallowedBlocksExtent.java @@ -101,7 +101,7 @@ public class DisallowedBlocksExtent extends AbstractDelegateExtent implements IB @SuppressWarnings("unchecked") private > B checkBlock(B block) { if (blockedBlocks != null) { - if (blockedBlocks.contains(block.getBlockType().getId())) { + if (blockedBlocks.contains(block.getBlockType().id())) { return (B) (block instanceof BlockState ? RESERVED : RESERVED.toBaseBlock()); // set to reserved/empty } } @@ -140,7 +140,7 @@ public class DisallowedBlocksExtent extends AbstractDelegateExtent implements IB } BlockState state = BlockTypesCache.states[block]; if (blockedBlocks != null) { - if (blockedBlocks.contains(state.getBlockType().getId())) { + if (blockedBlocks.contains(state.getBlockType().id())) { blocks[i] = BlockTypesCache.ReservedIDs.__RESERVED__; continue; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/HistoryExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/HistoryExtent.java index d85594215..daad170da 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/HistoryExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/HistoryExtent.java @@ -110,7 +110,7 @@ public class HistoryExtent extends AbstractDelegateExtent { @Override public boolean setBiome(BlockVector3 position, BiomeType newBiome) { BiomeType oldBiome = this.getBiome(position); - if (!oldBiome.getId().equals(newBiome.getId())) { + if (!oldBiome.id().equals(newBiome.id())) { this.changeSet.addBiomeChange(position.x(), position.y(), position.z(), oldBiome, newBiome); return getExtent().setBiome(position, newBiome); } else { @@ -121,7 +121,7 @@ public class HistoryExtent extends AbstractDelegateExtent { @Override public boolean setBiome(int x, int y, int z, BiomeType newBiome) { BiomeType oldBiome = this.getBiome(mutable.setComponents(x, y, z)); - if (!oldBiome.getId().equals(newBiome.getId())) { + if (!oldBiome.id().equals(newBiome.id())) { this.changeSet.addBiomeChange(x, y, z, oldBiome, newBiome); return getExtent().setBiome(x, y, z, newBiome); } else { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java index 5218b1c1e..65a4a0e86 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java @@ -237,7 +237,7 @@ public class FastSchematicWriter implements ClipboardWriter { if (!brokenEntities) { loc = loc.setPosition(loc.add(min.toVector3())); } - values.put("Id", new StringTag(state.getType().getId())); + values.put("Id", new StringTag(state.getType().id())); values.put("Pos", writeVector(loc)); values.put("Rotation", writeRotation(entity.getLocation())); @@ -297,7 +297,7 @@ public class FastSchematicWriter implements ClipboardWriter { for (int i = 0; i < paletteList.size(); i++) { int ordinal = paletteList.get(i); BiomeType state = BiomeTypes.get(ordinal); - out12.writeNamedTag(state.getId(), i); + out12.writeNamedTag(state.id(), i); } }); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java index d52d74b5a..0779418df 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java @@ -183,7 +183,7 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter { indexes.put(combined, (Integer) palette.size()); HashMap paletteEntry = new HashMap<>(); - paletteEntry.put("Name", type.getId()); + paletteEntry.put("Name", type.id()); if (block.getInternalId() != type.getInternalId()) { Map properties = null; for (AbstractProperty property : (List>) type.getProperties()) { @@ -239,7 +239,7 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter { Map nbtMap = nbt.getValue(); // Replace rotation data nbtMap.put("Rotation", writeRotation(entity.getLocation())); - nbtMap.put("id", new StringTag(state.getType().getId())); + nbtMap.put("id", new StringTag(state.getType().id())); Map entityMap = FaweCache.INSTANCE.asMap("pos", pos, "blockPos", blockPos, "nbt", nbt); entities.add(entityMap); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/lighting/NMSRelighter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/lighting/NMSRelighter.java index dbe717e49..2ad473130 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/lighting/NMSRelighter.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/lighting/NMSRelighter.java @@ -346,7 +346,7 @@ public class NMSRelighter implements Relighter { } int lightLevel = iChunk.getEmittedLight(node.x() & 15, node.y(), node.z() & 15); BlockState state = this.queue.getBlock(node.x(), node.y(), node.z()); - String id = state.getBlockType().getId().toLowerCase(Locale.ROOT); + String id = state.getBlockType().id().toLowerCase(Locale.ROOT); if (lightLevel <= 1) { continue; } @@ -396,7 +396,7 @@ public class NMSRelighter implements Relighter { if (!(checkStairEast(state) && isStairOrTrueTop(state, top) && isSlabOrTrueValue(state, top ? "top" : "bottom"))) { break east; } - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { this.computeSpreadBlockLight(x + 1, y, z, currentLight, queue, visited); break east; } @@ -449,7 +449,7 @@ public class NMSRelighter implements Relighter { if (!(checkStairWest(state) && isStairOrTrueTop(state, top) && isSlabOrTrueValue(state, top ? "top" : "bottom"))) { break west; } - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { this.computeSpreadBlockLight(x - 1, y, z, currentLight, queue, visited); break west; } @@ -502,7 +502,7 @@ public class NMSRelighter implements Relighter { if (!(checkStairSouth(state) && isStairOrTrueTop(state, top) && isSlabOrTrueValue(state, top ? "top" : "bottom"))) { break south; } - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { this.computeSpreadBlockLight(x, y, z + 1, currentLight, queue, visited); break south; } @@ -555,7 +555,7 @@ public class NMSRelighter implements Relighter { if (!(checkStairNorth(state) && isStairOrTrueTop(state, top) && isSlabOrTrueValue(state, top ? "top" : "bottom"))) { break north; } - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { this.computeSpreadBlockLight(x, y, z - 1, currentLight, queue, visited); break north; } @@ -707,7 +707,7 @@ public class NMSRelighter implements Relighter { } private boolean checkStairNorth(BlockState state) { - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { return true; } Direction direction = getStairDir(state); @@ -725,7 +725,7 @@ public class NMSRelighter implements Relighter { } private boolean checkStairSouth(BlockState state) { - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { return true; } Direction direction = getStairDir(state); @@ -743,7 +743,7 @@ public class NMSRelighter implements Relighter { } private boolean checkStairEast(BlockState state) { - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { return true; } Direction direction = getStairDir(state); @@ -761,7 +761,7 @@ public class NMSRelighter implements Relighter { } private boolean checkStairWest(BlockState state) { - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { return true; } Direction direction = getStairDir(state); @@ -787,11 +787,11 @@ public class NMSRelighter implements Relighter { } private boolean isStairOrTrueTop(BlockState state, boolean top) { - return !state.getBlockType().getId().contains("stair") || state.getState(stairHalf).equals("top") == top; + return !state.getBlockType().id().contains("stair") || state.getState(stairHalf).equals("top") == top; } private boolean isSlabOrTrueValue(BlockState state, String value) { - return !state.getBlockType().getId().contains("slab") || state.getState(slabHalf).equals(value); + return !state.getBlockType().id().contains("slab") || state.getState(slabHalf).equals(value); } private void computeRemoveBlockLight( diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/CavesGen.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/CavesGen.java index b9a403f27..7e4b61514 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/CavesGen.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/CavesGen.java @@ -236,7 +236,7 @@ public class CavesGen extends GenBase { BlockState material = chunk.getBlock(bx + local_x, local_y, bz + local_z); BlockState materialAbove = chunk.getBlock(bx + local_x, local_y + 1, bz + local_z); BlockType blockType = material.getBlockType(); - switch (blockType.getId()) { + switch (blockType.id()) { case "minecraft:mycelium", "minecraft:grass_block" -> grassFound = true; } if (this.isSuitableBlock(material, materialAbove)) { @@ -277,7 +277,7 @@ public class CavesGen extends GenBase { } protected boolean isSuitableBlock(BlockStateHolder material, BlockStateHolder materialAbove) { - return switch (material.getBlockType().getId()) { + return switch (material.getBlockType().id()) { case "minecraft:air", "minecraft:cave_air", "minecraft:void_air", "minecraft:water", "minecraft:lava", "minecraft:bedrock" -> false; default -> true; }; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ABlockMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ABlockMask.java index 1f0b88bfa..7fdebdded 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ABlockMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ABlockMask.java @@ -40,7 +40,7 @@ public abstract class ABlockMask extends AbstractExtentMask { List all = type.getAllStates(); hasAll = all.stream().map(this::test).reduce(true, (a, b) -> a && b); if (hasAll) { - strings.add(type.getId()); + strings.add(type.id()); } else { for (BlockState state : all) { if (test(state)) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/BlockMaskBuilder.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/BlockMaskBuilder.java index 2471ff262..baef7f767 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/BlockMaskBuilder.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/BlockMaskBuilder.java @@ -183,7 +183,7 @@ public class BlockMaskBuilder { builders = new ArrayList<>(); Pattern pattern = Pattern.compile("(minecraft:)?" + regex); for (BlockType type : BlockTypesCache.values) { - if (pattern.matcher(type.getId()).find()) { + if (pattern.matcher(type.id()).find()) { blockTypeList.add(type); builders.add(new FuzzyStateAllowingBuilder(type)); add(type); @@ -284,7 +284,7 @@ public class BlockMaskBuilder { } else { boolean success = false; for (BlockType myType : BlockTypesCache.values) { - if (myType.getId().matches("(minecraft:)?" + input)) { + if (myType.id().matches("(minecraft:)?" + input)) { add(myType); success = true; } @@ -571,7 +571,7 @@ public class BlockMaskBuilder { throw new IllegalArgumentException(String.format( "Property %s cannot be applied to block type %s", property.getName(), - type.getId() + type.id() )); } masked.computeIfAbsent(property, k -> new ArrayList<>()).add(index); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/TypeSwapPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/TypeSwapPattern.java index efc122b5d..d222833a7 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/TypeSwapPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/TypeSwapPattern.java @@ -79,7 +79,7 @@ public class TypeSwapPattern extends AbstractExtentPattern { } private BlockState getNewBlock(BlockState existing) { - String oldId = existing.getBlockType().getId(); + String oldId = existing.getBlockType().id(); String newId = oldId; if (inputPattern != null) { newId = inputPattern.matcher(oldId).replaceAll(outputString); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java index 117ab8fab..7d7d5d642 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java @@ -444,7 +444,7 @@ public class MainUtil { @Nonnull public static CompoundTag setEntityInfo(@Nonnull CompoundTag tag, @Nonnull Entity entity) { Map map = new HashMap<>(tag.getValue()); - map.put("Id", new StringTag(entity.getState().getType().getId())); + map.put("Id", new StringTag(entity.getState().getType().id())); ListTag pos = (ListTag) map.get("Pos"); if (pos != null) { Location loc = entity.getLocation(); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java index f6f896f56..7c4e7137b 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java @@ -929,10 +929,10 @@ public class TextureUtil implements TextureHolder { }.getType(); for (BlockType blockType : BlockTypesCache.values) { - if (!blockType.getMaterial().isFullCube() || blockType.getId().toLowerCase().contains("shulker")) { + if (!blockType.getMaterial().isFullCube() || blockType.id().toLowerCase().contains("shulker")) { continue; } - switch (blockType.getId().toLowerCase(Locale.ROOT)) { + switch (blockType.id().toLowerCase(Locale.ROOT)) { case "slime_block": case "honey_block": case "mob_spawner": @@ -940,7 +940,7 @@ public class TextureUtil implements TextureHolder { continue; } int combined = blockType.getInternalId(); - String id = blockType.getId(); + String id = blockType.id(); String[] split = id.split(":", 2); String name = split.length == 1 ? id : split[1]; String nameSpace = split.length == 1 ? "" : split[0]; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java index 7e2ba4549..1301c5bb3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java @@ -196,7 +196,7 @@ public abstract class LocalConfiguration { BlockTypes.BEDROCK FAWE end*/ ); - return blockTypes.stream().filter(Objects::nonNull).map(BlockType::getId).toArray(String[]::new); + return blockTypes.stream().filter(Objects::nonNull).map(BlockType::id).toArray(String[]::new); } /** @@ -277,7 +277,7 @@ public abstract class LocalConfiguration { id = Integer.parseInt(splitter[0]); data = Byte.parseByte(splitter[1]); } - item = LegacyMapper.getInstance().getItemFromLegacy(id, data).getId(); + item = LegacyMapper.getInstance().getItemFromLegacy(id, data).id(); } catch (Throwable ignored) { } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java index 5a5fa654e..79a72c279 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -1879,7 +1879,7 @@ public class LocalSession implements TextureHolder { * @return item id of wand item, or {@code null} */ public String getWandItem() { - return wandItem.getId(); + return wandItem.id(); } /** @@ -1888,7 +1888,7 @@ public class LocalSession implements TextureHolder { * @return item id of nav wand item, or {@code null} */ public String getNavWandItem() { - return navWandItem.getId(); + return navWandItem.id(); } /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java b/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java index 1dab627c7..dedc3757a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java @@ -128,7 +128,7 @@ public class BaseItem implements NbtValued { } } - return getType().getId() + nbtString; + return getType().id() + nbtString; } //FAWE end } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java index 0b2bd576d..a60968da1 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java @@ -98,7 +98,7 @@ public class BiomeCommands { PaginationBox paginationBox = PaginationBox.fromComponents("Available Biomes", "/biomelist -p %page%", BiomeType.REGISTRY.values().stream() .map(biomeType -> TextComponent.builder() - .append(biomeType.getId()) + .append(biomeType.id()) .append(" (") .append(biomeRegistry.getRichName(biomeType)) .append(")") @@ -166,7 +166,7 @@ public class BiomeCommands { List components = biomes.stream().map(biome -> biomeRegistry.getRichName(biome).hoverEvent( - HoverEvent.showText(TextComponent.of(biome.getId())) + HoverEvent.showText(TextComponent.of(biome.id())) ) ).collect(Collectors.toList()); actor.print(Caption.of(messageKey, TextUtils.join(components, TextComponent.of(", ")))); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java index 0cf5b1a78..3b271a1ec 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java @@ -349,7 +349,7 @@ public class GeneralCommands { if (world == null) { actor.print(Caption.of("worldedit.world.remove")); } else { - actor.print(Caption.of("worldedit.world.set", TextComponent.of(world.getId()))); + actor.print(Caption.of("worldedit.world.set", TextComponent.of(world.id()))); } } @@ -641,7 +641,7 @@ public class GeneralCommands { if (itemsOnly && searchType.hasBlockType()) { continue; } - final String id = searchType.getId(); + final String id = searchType.id(); if (id.contains(idMatch)) { Component name = searchType.getRichName(); results.put(id, TextComponent.builder() diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java index d8e0943dc..6c4a099dd 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java @@ -832,7 +832,7 @@ public class SelectionCommands { toolTip = TextComponent.of(state.getAsString()); blockName = blockName.append(TextComponent.of("*")); } else { - toolTip = TextComponent.of(blockType.getId()); + toolTip = TextComponent.of(blockType.id()); } blockName = blockName.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, toolTip)); line.append(blockName); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/WorldConverter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/WorldConverter.java index fd043d440..54492497a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/WorldConverter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/WorldConverter.java @@ -65,7 +65,7 @@ public class WorldConverter implements ArgumentConverter { @Override public List getSuggestions(String input, InjectedValueAccess context) { return getWorlds() - .map(World::getId) + .map(World::id) .filter(world -> world.startsWith(input)) .collect(Collectors.toList()); } @@ -73,7 +73,7 @@ public class WorldConverter implements ArgumentConverter { @Override public ConversionResult convert(String s, InjectedValueAccess injectedValueAccess) { World result = getWorlds() - .filter(world -> world.getId().equals(s)) + .filter(world -> world.id().equals(s)) .findAny().orElse(null); return result == null ? FailedConversion.from(new IllegalArgumentException( diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java index b9a2ee888..2d35b2226 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java @@ -66,7 +66,7 @@ public class BlockDataCyler implements DoubleActionBlockTool { if (!config.allowedDataCycleBlocks.isEmpty() && !player.hasPermission("worldedit.override.data-cycler") - && !config.allowedDataCycleBlocks.contains(block.getBlockType().getId())) { + && !config.allowedDataCycleBlocks.contains(block.getBlockType().id())) { player.print(Caption.of("worldedit.tool.data-cycler.block-not-permitted")); return true; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java index 969216896..03cfb51e3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java @@ -135,42 +135,42 @@ public class DefaultBlockParser extends InputParser { private String woolMapper(String string) { switch (string.toLowerCase(Locale.ROOT)) { case "white": - return BlockTypes.WHITE_WOOL.getId(); + return BlockTypes.WHITE_WOOL.id(); case "black": - return BlockTypes.BLACK_WOOL.getId(); + return BlockTypes.BLACK_WOOL.id(); case "blue": - return BlockTypes.BLUE_WOOL.getId(); + return BlockTypes.BLUE_WOOL.id(); case "brown": - return BlockTypes.BROWN_WOOL.getId(); + return BlockTypes.BROWN_WOOL.id(); case "cyan": - return BlockTypes.CYAN_WOOL.getId(); + return BlockTypes.CYAN_WOOL.id(); case "gray": case "grey": - return BlockTypes.GRAY_WOOL.getId(); + return BlockTypes.GRAY_WOOL.id(); case "green": - return BlockTypes.GREEN_WOOL.getId(); + return BlockTypes.GREEN_WOOL.id(); case "light_blue": case "lightblue": - return BlockTypes.LIGHT_BLUE_WOOL.getId(); + return BlockTypes.LIGHT_BLUE_WOOL.id(); case "light_gray": case "light_grey": case "lightgray": case "lightgrey": - return BlockTypes.LIGHT_GRAY_WOOL.getId(); + return BlockTypes.LIGHT_GRAY_WOOL.id(); case "lime": - return BlockTypes.LIME_WOOL.getId(); + return BlockTypes.LIME_WOOL.id(); case "magenta": - return BlockTypes.MAGENTA_WOOL.getId(); + return BlockTypes.MAGENTA_WOOL.id(); case "orange": - return BlockTypes.ORANGE_WOOL.getId(); + return BlockTypes.ORANGE_WOOL.id(); case "pink": - return BlockTypes.PINK_WOOL.getId(); + return BlockTypes.PINK_WOOL.id(); case "purple": - return BlockTypes.PURPLE_WOOL.getId(); + return BlockTypes.PURPLE_WOOL.id(); case "yellow": - return BlockTypes.YELLOW_WOOL.getId(); + return BlockTypes.YELLOW_WOOL.id(); case "red": - return BlockTypes.RED_WOOL.getId(); + return BlockTypes.RED_WOOL.id(); default: return string; } @@ -194,7 +194,7 @@ public class DefaultBlockParser extends InputParser { if (input.indexOf('[') == -1 && input.indexOf(']') == -1) { continue; } - if (!type.getId().equalsIgnoreCase(input.substring(0, input.indexOf('[')))) { + if (!type.id().equalsIgnoreCase(input.substring(0, input.indexOf('[')))) { continue; } String[] properties = input.substring(input.indexOf('[') + 1, input.indexOf(']')).split(","); @@ -249,10 +249,10 @@ public class DefaultBlockParser extends InputParser { throw new NoMatchException(Caption.of( "worldedit.error.parser.unknown-property", TextComponent.of(parts[0]), - TextComponent.of(type.getId()) + TextComponent.of(type.id()) )); } else { - WorldEdit.logger.debug("Unknown property " + parts[0] + " for block " + type.getId()); + WorldEdit.logger.debug("Unknown property " + parts[0] + " for block " + type.id()); } return Maps.newHashMap(); } @@ -516,20 +516,20 @@ public class DefaultBlockParser extends InputParser { //FAWE start - per-limit disallowed blocks if (actor != null) { if (!actor.hasPermission("worldedit.anyblock") - && worldEdit.getConfiguration().disallowedBlocks.contains(blockType.getId().toLowerCase(Locale.ROOT))) { + && worldEdit.getConfiguration().disallowedBlocks.contains(blockType.id().toLowerCase(Locale.ROOT))) { throw new DisallowedUsageException(Caption.of( "worldedit.error.disallowed-block", - TextComponent.of(blockType.getId()) + TextComponent.of(blockType.id()) )); } FaweLimit limit = actor.getLimit(); if (!limit.isUnlimited()) { // No need to account for blocked states/properties as it will simply return false in the equality check // during contains. - if (limit.DISALLOWED_BLOCKS.contains(blockType.getId().toLowerCase(Locale.ROOT))) { + if (limit.DISALLOWED_BLOCKS.contains(blockType.id().toLowerCase(Locale.ROOT))) { throw new DisallowedUsageException(Caption.of( "fawe.error.limit.disallowed-block", - TextComponent.of(blockType.getId()) + TextComponent.of(blockType.id()) )); } } @@ -559,14 +559,14 @@ public class DefaultBlockParser extends InputParser { if (ent == null) { throw new NoMatchException(Caption.of("worldedit.error.unknown-entity", TextComponent.of(mobName))); } - mobName = ent.getId(); + mobName = ent.id(); if (!worldEdit.getPlatformManager().queryCapability(Capability.USER_COMMANDS).isValidMobType(mobName)) { throw new NoMatchException(Caption.of("worldedit.error.unknown-mob", TextComponent.of(mobName))); } return validate(context, new MobSpawnerBlock(state, mobName)); } else { //noinspection ConstantConditions - return validate(context, new MobSpawnerBlock(state, EntityTypes.PIG.getId())); + return validate(context, new MobSpawnerBlock(state, EntityTypes.PIG.id())); } } else if (blockType == BlockTypes.PLAYER_HEAD || blockType == BlockTypes.PLAYER_WALL_HEAD) { // allow setting type/player/rotation diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/BlockCategoryPatternParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/BlockCategoryPatternParser.java index 36d83eb37..089f2d861 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/BlockCategoryPatternParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/BlockCategoryPatternParser.java @@ -71,7 +71,7 @@ public class BlockCategoryPatternParser extends InputParser implements Set blocks = category.getAll(); if (blocks.isEmpty()) { - throw new InputParseException(Caption.of("worldedit.error.empty-tag", TextComponent.of(category.getId()))); + throw new InputParseException(Caption.of("worldedit.error.empty-tag", TextComponent.of(category.id()))); } if (anyState) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java index f20f3ce9b..0361ea3ce 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java @@ -23,7 +23,6 @@ import com.fastasyncworldedit.core.extent.processor.lighting.Relighter; import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory; import com.fastasyncworldedit.core.queue.IBatchProcessor; import com.sk89q.worldedit.LocalConfiguration; -import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.internal.util.NonAbstractForCompatibility; import com.sk89q.worldedit.registry.Keyed; @@ -233,7 +232,7 @@ public interface Platform extends Keyed { */ @NonAbstractForCompatibility(delegateName = "getPlatformName", delegateParams = {}) @Override - default String getId() { + default String id() { return "legacy:" + getPlatformName().toLowerCase(Locale.ROOT).replaceAll("[^a-z_.-]", "_"); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java index d52fd1056..ef60bd919 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java @@ -407,7 +407,7 @@ public interface Clipboard extends Extent, Iterable, Closeable, Fl if (pasteEntities) { for (Entity entity : this.getEntities()) { // skip players on pasting schematic - if (entity.getState() != null && entity.getState().getType().getId() + if (entity.getState() != null && entity.getState().getType().id() .equals("minecraft:player")) { continue; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java index 24860dd3c..dc313b259 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java @@ -223,7 +223,7 @@ public class SpongeSchematicWriter implements ClipboardWriter { BlockVector3 pt = BlockVector3.at(x0, min.y(), z0); BiomeType biome = clipboard.getBiome(pt); - String biomeKey = biome.getId(); + String biomeKey = biome.id(); int biomeId; if (palette.containsKey(biomeKey)) { biomeId = palette.get(biomeKey); @@ -262,7 +262,7 @@ public class SpongeSchematicWriter implements ClipboardWriter { values.putAll(rawData.getValue()); } values.remove("id"); - values.put("Id", new StringTag(state.getType().getId())); + values.put("Id", new StringTag(state.getType().id())); final Location location = e.getLocation(); values.put("Pos", writeVector(location.toVector())); values.put("Rotation", writeRotation(location)); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/FlowerPotCompatibilityHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/FlowerPotCompatibilityHandler.java index 974000762..95d2fb091 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/FlowerPotCompatibilityHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/FlowerPotCompatibilityHandler.java @@ -84,7 +84,7 @@ public class FlowerPotCompatibilityHandler implements NBTCompatibilityHandler { } else { BlockState plantedWithData = LegacyMapper.getInstance().getBlockFromLegacy(newId, data); if (plantedWithData != null) { - plantedName = plantedWithData.getBlockType().getId().substring(10); // remove "minecraft:" + plantedName = plantedWithData.getBlockType().id().substring(10); // remove "minecraft:" } } if (plantedName != null) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/Pre13HangingCompatibilityHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/Pre13HangingCompatibilityHandler.java index 25457042c..346f5f29e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/Pre13HangingCompatibilityHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/Pre13HangingCompatibilityHandler.java @@ -29,7 +29,7 @@ public class Pre13HangingCompatibilityHandler implements EntityNBTCompatibilityH @Override public boolean isAffectedEntity(EntityType type, CompoundTag tag) { - if (!type.getId().startsWith("minecraft:")) { + if (!type.id().startsWith("minecraft:")) { return false; } boolean hasLegacyDirection = tag.containsKey("Dir") || tag.containsKey("Direction"); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java index d9effa512..5f434cf9b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java @@ -441,7 +441,7 @@ public class BlockTransformExtent extends ResettableExtent { if (Settings.settings().ENABLED_COMPONENTS.DEBUG) { LOGGER.warn(String.format( "Index outside direction array length found for block:{%s} property:{%s}", - state.getBlockType().getId(), + state.getBlockType().id(), property.getName() )); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java index 4027220b2..962fb3c7d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java @@ -116,7 +116,7 @@ public class SnowSimulator implements LayerFunction { if (!above.getBlockType().getMaterial().isAir() && (!stack || above.getBlockType() != BlockTypes.SNOW)) { return false; //FAWE start - } else if (!block.getBlockType().getId().toLowerCase(Locale.ROOT).contains("ice") && this.extent.getEmittedLight( + } else if (!block.getBlockType().id().toLowerCase(Locale.ROOT).contains("ice") && this.extent.getEmittedLight( abovePosition) > 10) { return false; } else if (!block.getBlockType().getMaterial().isFullCube()) { @@ -132,7 +132,7 @@ public class SnowSimulator implements LayerFunction { return false; } //FAWE end - } else if (!block.getBlockType().getId().toLowerCase(Locale.ROOT).contains("ice") && block + } else if (!block.getBlockType().id().toLowerCase(Locale.ROOT).contains("ice") && block .getBlockType() .getMaterial() .isTranslucent()) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java index 8cc91f969..c30f6fa4d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java @@ -165,7 +165,7 @@ public class ServerCUIHandler { structureTag.putString("mode", "SAVE"); structureTag.putByte("ignoreEntities", (byte) 1); structureTag.putByte("showboundingbox", (byte) 1); - structureTag.putString("id", BlockTypes.STRUCTURE_BLOCK.getId()); + structureTag.putString("id", BlockTypes.STRUCTURE_BLOCK.id()); return BlockTypes.STRUCTURE_BLOCK.getDefaultState().toBaseBlock(structureTag.build()); //FAWE end diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Category.java b/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Category.java index fc8a5e895..e24143ce2 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Category.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Category.java @@ -36,7 +36,7 @@ public abstract class Category implements RegistryItem { this.id = id; } - public final String getId() { + public final String id() { return this.id; } @@ -81,7 +81,7 @@ public abstract class Category implements RegistryItem { @Override public String toString() { - return getId(); + return id(); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Keyed.java b/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Keyed.java index e892ba1f1..cf80a94de 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Keyed.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Keyed.java @@ -29,6 +29,6 @@ public interface Keyed { * * @return an id */ - String getId(); + String id(); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java index 3804be8d3..378ce08c8 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java @@ -114,7 +114,7 @@ public class PropertiesConfiguration extends LocalConfiguration { registerHelp = getBool("register-help", registerHelp); wandItem = getString("wand-item", wandItem).toLowerCase(Locale.ROOT); try { - wandItem = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(wandItem)).getId(); + wandItem = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(wandItem)).id(); } catch (Throwable ignored) { } superPickaxeDrop = getBool("super-pickaxe-drop-items", superPickaxeDrop); @@ -124,7 +124,7 @@ public class PropertiesConfiguration extends LocalConfiguration { useInventoryCreativeOverride = getBool("use-inventory-creative-override", useInventoryCreativeOverride); navigationWand = getString("nav-wand-item", navigationWand).toLowerCase(Locale.ROOT); try { - navigationWand = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(navigationWand)).getId(); + navigationWand = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(navigationWand)).id(); } catch (Throwable ignored) { } navigationWandMaxDistance = getInt("nav-wand-distance", navigationWandMaxDistance); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java index ccf8d8535..0e962d746 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java @@ -78,7 +78,7 @@ public class NullWorld extends AbstractWorld { //FAWE end @Override - public String getId() { + public String id() { return "null"; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java index 221c0de8d..7c4f9c12e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java @@ -449,7 +449,7 @@ public interface World extends Extent, Keyed, IChunkCache { } @Override - default String getId() { + default String id() { return getName().replace(" ", "_").toLowerCase(Locale.ROOT); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java index e8501da69..21d56c3ea 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java @@ -68,13 +68,13 @@ public class BiomeType implements RegistryItem, Keyed, BiomePattern { * @return The id */ @Override - public String getId() { + public String id() { return this.id; } @Override public String toString() { - return getId(); + return id(); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeTypes.java index 6fe08a295..e8a5e144a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeTypes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeTypes.java @@ -291,7 +291,7 @@ public final class BiomeTypes { } public static BiomeType register(final BiomeType biome) { - return BiomeType.REGISTRY.register(biome.getId(), biome); + return BiomeType.REGISTRY.register(biome.id(), biome); } public static BiomeType getLegacy(int legacyId) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java index 5059c737a..713204843 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java @@ -154,7 +154,7 @@ public class BlockState implements BlockStateHolder, Pattern { String input = key.toString(); throw new SuggestInputParseException(Caption.of("fawe.error.invalid-block-type", TextComponent.of(input)), () -> Stream.of( BlockTypesCache.values) - .map(BlockType::getId) + .map(BlockType::id) .filter(id -> StringMan.blockStateMatches(input, id)) .sorted(StringMan.blockStateComparator(input)) .collect(Collectors.toList()) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockStateHolder.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockStateHolder.java index 5f6667a13..e40482302 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockStateHolder.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockStateHolder.java @@ -204,14 +204,14 @@ public interface BlockStateHolder> extends TileEnt default String getAsString() { if (getStates().isEmpty()) { - return this.getBlockType().getId(); + return this.getBlockType().id(); } else { String properties = getStates().entrySet().stream() .map(entry -> entry.getKey().getName() + "=" + entry.getValue().toString().toLowerCase(Locale.ROOT)) .collect(Collectors.joining(",")); - return this.getBlockType().getId() + "[" + properties + "]"; + return this.getBlockType().id() + "[" + properties + "]"; } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java index a2e58a97c..d8b0ae046 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java @@ -124,7 +124,7 @@ public class BlockType implements Keyed, Pattern { * @return The id */ @Override - public String getId() { + public String id() { return this.id; } @@ -135,13 +135,13 @@ public class BlockType implements Keyed, Pattern { //FAWE start public String getNamespace() { - String id = getId(); + String id = id(); int i = id.indexOf(':'); return i == -1 ? "minecraft" : id.substring(0, i); } public String getResource() { - String id = getId(); + String id = id(); return id.substring(id.indexOf(':') + 1); } //FAWE end @@ -156,7 +156,7 @@ public class BlockType implements Keyed, Pattern { public String getName() { String name = this.name.getValue(); if (name == null || name.isEmpty()) { - return getId(); + return id(); } return name; } @@ -180,7 +180,7 @@ public class BlockType implements Keyed, Pattern { LOGGER.error( "Attempted to load blockstate with id {} of type {} outside of state ordinals length. Using default state.", propertyId, - getId() + id() ); return settings.defaultState; } @@ -189,7 +189,7 @@ public class BlockType implements Keyed, Pattern { LOGGER.error( "Attempted to load blockstate with ordinal {} of type {} outside of states length. Using default state. Using default state.", ordinal, - getId() + id() ); return settings.defaultState; } @@ -405,7 +405,7 @@ public class BlockType implements Keyed, Pattern { @Override public String toString() { - return getId(); + return id(); } //FAWE start diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java index 0206cdf92..2667d44f9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java @@ -2235,8 +2235,8 @@ public final class BlockTypes { throw new SuggestInputParseException(Caption.of("fawe.error.invalid-block-type", TextComponent.of(input)), () -> Stream.of( BlockTypesCache.values) - .filter(b -> StringMan.blockStateMatches(inputLower, b.getId())) - .map(BlockType::getId) + .filter(b -> StringMan.blockStateMatches(inputLower, b.id())) + .map(BlockType::id) .sorted(StringMan.blockStateComparator(inputLower)) .collect(Collectors.toList()) ); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java index 31bb7606c..a8c2d63c2 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java @@ -125,7 +125,7 @@ public class AnvilChunk13 implements Chunk { } catch (IllegalArgumentException e) { throw new InvalidFormatException("Invalid block state for " + blockState .getBlockType() - .getId() + ", " + property.getName() + ": " + value); + .id() + ", " + property.getName() + ": " + value); } } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk17.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk17.java index 6d366c295..3789f9a79 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk17.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk17.java @@ -133,7 +133,7 @@ public class AnvilChunk17 implements Chunk { } catch (IllegalArgumentException e) { throw new InvalidFormatException("Invalid block state for " + blockState .getBlockType() - .getId() + ", " + property.getName() + ": " + value); + .id() + ", " + property.getName() + ": " + value); } } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java index 4fa50629e..1e36938c4 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java @@ -146,7 +146,7 @@ public class AnvilChunk18 implements Chunk { } catch (IllegalArgumentException e) { throw new InvalidFormatException("Invalid block state for " + blockState .getBlockType() - .getId() + ", " + property.getName() + ": " + value); + .id() + ", " + property.getName() + ": " + value); } } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityType.java index 5a530c8a6..3f6736c1b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityType.java @@ -40,7 +40,7 @@ public class EntityType implements RegistryItem, Keyed { } @Override - public String getId() { + public String id() { return this.id; } @@ -64,12 +64,12 @@ public class EntityType implements RegistryItem, Keyed { * @return The name, or ID */ public String getName() { - return getId(); + return id(); } @Override public String toString() { - return getId(); + return id(); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidCategories.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidCategories.java index 2788fdebe..79569156e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidCategories.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidCategories.java @@ -37,7 +37,7 @@ public final class FluidCategories { } public static FluidCategory register(final FluidCategory tag) { - return FluidCategory.REGISTRY.register(tag.getId(), tag); + return FluidCategory.REGISTRY.register(tag.id(), tag); } @Nullable diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidType.java index d62d13b51..b86782b18 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidType.java @@ -45,7 +45,7 @@ public class FluidType implements RegistryItem, Keyed { * @return The id */ @Override - public String getId() { + public String id() { return this.id; } @@ -67,7 +67,7 @@ public class FluidType implements RegistryItem, Keyed { @Override public String toString() { - return getId(); + return id(); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidTypes.java index 18c43d8c8..dd5b0270e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidTypes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidTypes.java @@ -40,7 +40,7 @@ public final class FluidTypes { } public static FluidType register(final FluidType fluid) { - return FluidType.REGISTRY.register(fluid.getId(), fluid); + return FluidType.REGISTRY.register(fluid.id(), fluid); } @Nullable diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/gamemode/GameMode.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/gamemode/GameMode.java index 312caa3b5..c9adc42f4 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/gamemode/GameMode.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/gamemode/GameMode.java @@ -33,7 +33,7 @@ public class GameMode implements Keyed { } @Override - public String getId() { + public String id() { return this.id; } @@ -43,12 +43,12 @@ public class GameMode implements Keyed { * @return The name, or ID */ public String getName() { - return getId(); + return id(); } @Override public String toString() { - return getId(); + return id(); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/gamemode/GameModes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/gamemode/GameModes.java index ce87f9ce7..b6d151ba8 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/gamemode/GameModes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/gamemode/GameModes.java @@ -36,7 +36,7 @@ public final class GameModes { } public static GameMode register(final GameMode gameMode) { - return GameMode.REGISTRY.register(gameMode.getId(), gameMode); + return GameMode.REGISTRY.register(gameMode.id(), gameMode); } @Nullable diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/ConfiguredFeatureType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/ConfiguredFeatureType.java index bc5126d31..48c61a01c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/ConfiguredFeatureType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/ConfiguredFeatureType.java @@ -24,26 +24,17 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.registry.Keyed; import com.sk89q.worldedit.registry.NamespacedRegistry; -public class ConfiguredFeatureType implements Keyed { +public record ConfiguredFeatureType(String id) implements Keyed { + public static final NamespacedRegistry REGISTRY = new NamespacedRegistry<>("configured feature type"); - private final String id; - - public ConfiguredFeatureType(String id) { - this.id = id; - } - - @Override - public String getId() { - return this.id; - } - @Override public String toString() { return this.id; } //FAWE start + /** * Place this feature into an {@link EditSession} * diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/StructureType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/StructureType.java index 0713735d7..06fef05f8 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/StructureType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/generation/StructureType.java @@ -24,26 +24,17 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.registry.Keyed; import com.sk89q.worldedit.registry.NamespacedRegistry; -public class StructureType implements Keyed { +public record StructureType(String id) implements Keyed { + public static final NamespacedRegistry REGISTRY = new NamespacedRegistry<>("structure type"); - private final String id; - - public StructureType(String id) { - this.id = id; - } - - @Override - public String getId() { - return this.id; - } - @Override public String toString() { return this.id; } //FAWE start + /** * Place this structure into an {@link EditSession} * diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemType.java index 5dc7f9277..e7a72b3c9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemType.java @@ -49,7 +49,7 @@ public class ItemType implements RegistryItem, Keyed { .getRegistries().getItemRegistry().getName(this), "" ); - return name.isEmpty() ? getId() : name; + return name.isEmpty() ? id() : name; }); @SuppressWarnings("this-escape") private transient final LazyReference richName = LazyReference.from(() -> @@ -76,7 +76,7 @@ public class ItemType implements RegistryItem, Keyed { } @Override - public String getId() { + public String id() { return this.id; } @@ -153,7 +153,7 @@ public class ItemType implements RegistryItem, Keyed { @Override public String toString() { - return getId(); + return id(); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledBlockRegistry.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledBlockRegistry.java index 3f7181397..11663a4f1 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledBlockRegistry.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledBlockRegistry.java @@ -41,7 +41,7 @@ public class BundledBlockRegistry implements BlockRegistry { @Override public Component getRichName(BlockType blockType) { - BundledBlockData.BlockEntry blockEntry = BundledBlockData.getInstance().findById(blockType.getId()); + BundledBlockData.BlockEntry blockEntry = BundledBlockData.getInstance().findById(blockType.id()); if (blockEntry != null) { // This is more likely to be "right", but not translated // Some vanilla MC blocks have overrides so we need this name here @@ -50,7 +50,7 @@ public class BundledBlockRegistry implements BlockRegistry { return TextComponent.of(blockEntry.localizedName); } return Caption.of( - TranslationManager.makeTranslationKey("block", blockType.getId()) + TranslationManager.makeTranslationKey("block", blockType.id()) ); } @@ -60,14 +60,14 @@ public class BundledBlockRegistry implements BlockRegistry { // dumb_intellij.jpg - Ok?? @SuppressWarnings("deprecation") public String getName(BlockType blockType) { - BundledBlockData.BlockEntry blockEntry = BundledBlockData.getInstance().findById(blockType.getId()); + BundledBlockData.BlockEntry blockEntry = BundledBlockData.getInstance().findById(blockType.id()); return blockEntry != null ? blockEntry.localizedName : null; } @Nullable @Override public BlockMaterial getMaterial(BlockType blockType) { - return new PassthroughBlockMaterial(BundledBlockData.getInstance().getMaterialById(blockType.getId())); + return new PassthroughBlockMaterial(BundledBlockData.getInstance().getMaterialById(blockType.id())); } @Nullable diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledItemRegistry.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledItemRegistry.java index 2e1d42121..53a707821 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledItemRegistry.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledItemRegistry.java @@ -34,7 +34,7 @@ import javax.annotation.Nullable; public class BundledItemRegistry implements ItemRegistry { private BundledItemData.ItemEntry getEntryById(ItemType itemType) { - return BundledItemData.getInstance().findById(itemType.getId()); + return BundledItemData.getInstance().findById(itemType.id()); } @Override @@ -48,7 +48,7 @@ public class BundledItemRegistry implements ItemRegistry { return TextComponent.of(itemEntry.localizedName); } return Caption.of( - TranslationManager.makeTranslationKey("item", itemType.getId()) + TranslationManager.makeTranslationKey("item", itemType.id()) ); } @@ -62,7 +62,7 @@ public class BundledItemRegistry implements ItemRegistry { if (itemEntry != null) { String localized = itemEntry.localizedName; if (localized.equals("Air")) { - String id = itemType.getId(); + String id = itemType.id(); int c = id.indexOf(':'); return c < 0 ? id : id.substring(c + 1); } @@ -74,7 +74,7 @@ public class BundledItemRegistry implements ItemRegistry { @Nullable @Override public ItemMaterial getMaterial(ItemType itemType) { - return new PassthroughItemMaterial(BundledItemData.getInstance().getMaterialById(itemType.getId())); + return new PassthroughItemMaterial(BundledItemData.getInstance().getMaterialById(itemType.id())); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/CategoryRegistry.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/CategoryRegistry.java index c52c507b9..dade2d193 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/CategoryRegistry.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/CategoryRegistry.java @@ -38,7 +38,7 @@ public interface CategoryRegistry { Set getCategorisedByName(String category); default Set getAll(final Category category) { - return getCategorisedByName(category.getId()); + return getCategorisedByName(category.id()); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/NullBiomeRegistry.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/NullBiomeRegistry.java index 346c94477..19fdd3b88 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/NullBiomeRegistry.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/NullBiomeRegistry.java @@ -41,7 +41,7 @@ public class NullBiomeRegistry implements BiomeRegistry { @Override public Component getRichName(BiomeType biomeType) { return Caption.of( - TranslationManager.makeTranslationKey("biome", biomeType.getId()) + TranslationManager.makeTranslationKey("biome", biomeType.id()) ); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/weather/WeatherType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/weather/WeatherType.java index ea78ee112..24044fa05 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/weather/WeatherType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/weather/WeatherType.java @@ -33,7 +33,7 @@ public class WeatherType implements Keyed { } @Override - public String getId() { + public String id() { return this.id; } @@ -43,12 +43,12 @@ public class WeatherType implements Keyed { * @return The name, or ID */ public String getName() { - return getId(); + return id(); } @Override public String toString() { - return getId(); + return id(); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/weather/WeatherTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/weather/WeatherTypes.java index 404e8d6da..458f17f25 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/weather/WeatherTypes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/weather/WeatherTypes.java @@ -35,7 +35,7 @@ public final class WeatherTypes { } public static WeatherType register(WeatherType weather) { - return WeatherType.REGISTRY.register(weather.getId(), weather); + return WeatherType.REGISTRY.register(weather.id(), weather); } @Nullable From ba30e5a197f33e4050043acba5461bb6fdc8f2f2 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Fri, 7 Jun 2024 20:51:45 +0100 Subject: [PATCH 11/12] Undo Minecraft has a lot of different methods between private and public to determine if structures can be placed. We cannot possibly cover all of them whilst also ensuring issues do not arise with generic "true"s --- .../v1_19_R3/FaweBlockStateListPopulator.java | 18 +---------------- .../fawe/v1_19_R3/PaperweightFaweAdapter.java | 7 ++++++- .../v1_19_R3/PaperweightPlatformAdapter.java | 7 ------- .../v1_20_R1/FaweBlockStateListPopulator.java | 18 +---------------- .../fawe/v1_20_R1/PaperweightFaweAdapter.java | 7 ++++++- .../v1_20_R1/PaperweightPlatformAdapter.java | 7 ------- .../v1_20_R2/FaweBlockStateListPopulator.java | 18 +---------------- .../fawe/v1_20_R2/PaperweightFaweAdapter.java | 7 ++++++- .../v1_20_R2/PaperweightPlatformAdapter.java | 7 ------- .../v1_20_R3/FaweBlockStateListPopulator.java | 18 +---------------- .../fawe/v1_20_R3/PaperweightFaweAdapter.java | 8 +++++++- .../v1_20_R3/PaperweightPlatformAdapter.java | 7 ------- .../v1_20_R4/FaweBlockStateListPopulator.java | 20 +------------------ .../fawe/v1_20_R4/PaperweightFaweAdapter.java | 7 ++++++- .../v1_20_R4/PaperweightPlatformAdapter.java | 7 ------- 15 files changed, 36 insertions(+), 127 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/FaweBlockStateListPopulator.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/FaweBlockStateListPopulator.java index df68c0c2b..0d420da32 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/FaweBlockStateListPopulator.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/FaweBlockStateListPopulator.java @@ -9,7 +9,6 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.flag.FeatureFlagSet; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.BiomeManager; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.border.WorldBorder; import net.minecraft.world.level.chunk.ChunkAccess; @@ -122,22 +121,7 @@ public class FaweBlockStateListPopulator extends BlockStateListPopulator { @Override public BlockState getBlockState(final BlockPos pos) { - BlockState state = world.getBlockState(pos); - try { - state = new BlockState( - state.getBlock(), - state.getValues(), - PaperweightPlatformAdapter.getStatePropertiesCodec(state) - ) { - @Override - public boolean is(Block block) { - return true; - } - }; - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - return state; + return world.getBlockState(pos); } @Override diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java index ba5659bb6..0dd534ce6 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java @@ -547,7 +547,12 @@ public final class PaperweightFaweAdapter extends FaweAdapter(populator.getLevel().capturedBlockStates); + Map placedBlocks = populator.getList().stream().collect(Collectors.toMap( + CraftBlockState::getPosition, + craftBlockState -> craftBlockState + )); + placedBlocks.putAll(serverLevel.capturedBlockStates); + return placedBlocks; } finally { serverLevel.captureBlockStates = false; serverLevel.captureTreeGeneration = false; diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java index 5e020847f..e11908f2a 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java @@ -11,7 +11,6 @@ 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.mojang.serialization.MapCodec; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.Refraction; @@ -693,12 +692,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { } } - public static MapCodec getStatePropertiesCodec( - net.minecraft.world.level.block.state.BlockState state - ) throws IllegalAccessException { - return (MapCodec) fieldPropertiesCodec.get(state); - } - record FakeIdMapBlock(int size) implements IdMap { @Override diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/FaweBlockStateListPopulator.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/FaweBlockStateListPopulator.java index c6934c9dc..c1ae434df 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/FaweBlockStateListPopulator.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/FaweBlockStateListPopulator.java @@ -9,7 +9,6 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.flag.FeatureFlagSet; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.BiomeManager; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.border.WorldBorder; import net.minecraft.world.level.chunk.ChunkAccess; @@ -122,22 +121,7 @@ public class FaweBlockStateListPopulator extends BlockStateListPopulator { @Override public BlockState getBlockState(final BlockPos pos) { - BlockState state = world.getBlockState(pos); - try { - state = new BlockState( - state.getBlock(), - state.getValues(), - PaperweightPlatformAdapter.getStatePropertiesCodec(state) - ) { - @Override - public boolean is(Block block) { - return true; - } - }; - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - return state; + return world.getBlockState(pos); } @Override diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java index 7620b7126..b60d8a185 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java @@ -548,7 +548,12 @@ public final class PaperweightFaweAdapter extends FaweAdapter(populator.getLevel().capturedBlockStates); + Map placedBlocks = populator.getList().stream().collect(Collectors.toMap( + CraftBlockState::getPosition, + craftBlockState -> craftBlockState + )); + placedBlocks.putAll(serverLevel.capturedBlockStates); + return placedBlocks; } finally { serverLevel.captureBlockStates = false; serverLevel.captureTreeGeneration = false; diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPlatformAdapter.java index 53364fcd9..5b23831c7 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPlatformAdapter.java @@ -11,7 +11,6 @@ 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.mojang.serialization.MapCodec; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.Refraction; @@ -707,12 +706,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { } } - public static MapCodec getStatePropertiesCodec( - net.minecraft.world.level.block.state.BlockState state - ) throws IllegalAccessException { - return (MapCodec) fieldPropertiesCodec.get(state); - } - record FakeIdMapBlock(int size) implements IdMap { @Override diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/FaweBlockStateListPopulator.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/FaweBlockStateListPopulator.java index c0233adee..a802a2e7a 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/FaweBlockStateListPopulator.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/FaweBlockStateListPopulator.java @@ -9,7 +9,6 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.flag.FeatureFlagSet; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.BiomeManager; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.border.WorldBorder; import net.minecraft.world.level.chunk.ChunkAccess; @@ -122,22 +121,7 @@ public class FaweBlockStateListPopulator extends BlockStateListPopulator { @Override public BlockState getBlockState(final BlockPos pos) { - BlockState state = world.getBlockState(pos); - try { - state = new BlockState( - state.getBlock(), - state.getValues(), - PaperweightPlatformAdapter.getStatePropertiesCodec(state) - ) { - @Override - public boolean is(Block block) { - return true; - } - }; - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - return state; + return world.getBlockState(pos); } @Override diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java index bbb5447b1..14eabcdf7 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java @@ -551,7 +551,12 @@ public final class PaperweightFaweAdapter extends FaweAdapter(populator.getLevel().capturedBlockStates); + Map placedBlocks = populator.getList().stream().collect(Collectors.toMap( + CraftBlockState::getPosition, + craftBlockState -> craftBlockState + )); + placedBlocks.putAll(serverLevel.capturedBlockStates); + return placedBlocks; } finally { serverLevel.captureBlockStates = false; serverLevel.captureTreeGeneration = false; diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java index 098e922c7..7c397d2b4 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java @@ -11,7 +11,6 @@ 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.mojang.serialization.MapCodec; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.Refraction; @@ -680,12 +679,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { return List.of(); } - public static MapCodec getStatePropertiesCodec( - net.minecraft.world.level.block.state.BlockState state - ) throws IllegalAccessException { - return (MapCodec) fieldPropertiesCodec.get(state); - } - record FakeIdMapBlock(int size) implements IdMap { @Override diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/FaweBlockStateListPopulator.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/FaweBlockStateListPopulator.java index c05144d92..6b9050fed 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/FaweBlockStateListPopulator.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/FaweBlockStateListPopulator.java @@ -9,7 +9,6 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.flag.FeatureFlagSet; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.BiomeManager; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.border.WorldBorder; import net.minecraft.world.level.chunk.ChunkAccess; @@ -122,22 +121,7 @@ public class FaweBlockStateListPopulator extends BlockStateListPopulator { @Override public BlockState getBlockState(final BlockPos pos) { - BlockState state = world.getBlockState(pos); - try { - state = new BlockState( - state.getBlock(), - state.getValues(), - PaperweightPlatformAdapter.getStatePropertiesCodec(state) - ) { - @Override - public boolean is(Block block) { - return true; - } - }; - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - return state; + return world.getBlockState(pos); } @Override diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightFaweAdapter.java index 7fe9e0b43..8a2d5b1b0 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightFaweAdapter.java @@ -552,7 +552,12 @@ public final class PaperweightFaweAdapter extends FaweAdapter(populator.getLevel().capturedBlockStates); + Map placedBlocks = populator.getList().stream().collect(Collectors.toMap( + CraftBlockState::getPosition, + craftBlockState -> craftBlockState + )); + placedBlocks.putAll(serverLevel.capturedBlockStates); + return placedBlocks; } finally { serverLevel.captureBlockStates = false; serverLevel.captureTreeGeneration = false; @@ -596,6 +601,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter true ); + if (!structureStart.isValid()) { return null; } else { diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java index 57c95c440..6bb902c17 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java @@ -11,7 +11,6 @@ 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.mojang.serialization.MapCodec; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.Refraction; @@ -680,12 +679,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { return List.of(); } - public static MapCodec getStatePropertiesCodec( - net.minecraft.world.level.block.state.BlockState state - ) throws IllegalAccessException { - return (MapCodec) fieldPropertiesCodec.get(state); - } - record FakeIdMapBlock(int size) implements IdMap { @Override diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/FaweBlockStateListPopulator.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/FaweBlockStateListPopulator.java index d9cf01e9f..9a1e20c71 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/FaweBlockStateListPopulator.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/FaweBlockStateListPopulator.java @@ -1,6 +1,5 @@ package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4; -import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Holder; @@ -10,9 +9,7 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.flag.FeatureFlagSet; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.BiomeManager; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.Property; import net.minecraft.world.level.border.WorldBorder; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkSource; @@ -124,22 +121,7 @@ public class FaweBlockStateListPopulator extends BlockStateListPopulator { @Override public BlockState getBlockState(final BlockPos pos) { - BlockState state = world.getBlockState(pos); - try { - state = new BlockState( - state.getBlock(), - (Reference2ObjectArrayMap, Comparable>) state.getValues(), - PaperweightPlatformAdapter.getStatePropertiesCodec(state) - ) { - @Override - public boolean is(Block block) { - return true; - } - }; - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - return state; + return world.getBlockState(pos); } @Override diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightFaweAdapter.java index f79c737b6..3a4d933c6 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightFaweAdapter.java @@ -565,7 +565,12 @@ public final class PaperweightFaweAdapter extends FaweAdapter(populator.getLevel().capturedBlockStates); + Map placedBlocks = populator.getList().stream().collect(Collectors.toMap( + CraftBlockState::getPosition, + craftBlockState -> craftBlockState + )); + placedBlocks.putAll(serverLevel.capturedBlockStates); + return placedBlocks; } finally { serverLevel.captureBlockStates = false; serverLevel.captureTreeGeneration = false; diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java index 62339d62d..d1fe4f935 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java @@ -10,7 +10,6 @@ import com.fastasyncworldedit.core.math.BitArrayUnstretched; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.ReflectionUtils; import com.fastasyncworldedit.core.util.TaskManager; -import com.mojang.serialization.MapCodec; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.Refraction; @@ -676,12 +675,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { return List.of(); } - public static MapCodec getStatePropertiesCodec( - net.minecraft.world.level.block.state.BlockState state - ) throws IllegalAccessException { - return (MapCodec) fieldPropertiesCodec.get(state); - } - record FakeIdMapBlock(int size) implements IdMap { @Override From ca8ac019468c7eef259e2658602e16037f05badb Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Wed, 12 Jun 2024 16:02:41 +0100 Subject: [PATCH 12/12] Cleanup --- .../sk89q/worldedit/world/biome/BiomeType.java | 15 +++++++++++++-- .../sk89q/worldedit/world/entity/EntityType.java | 11 ++++++++++- .../sk89q/worldedit/world/fluid/FluidType.java | 14 ++++++++++++-- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java index 35bd9f58b..6be1d3a3d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java @@ -43,6 +43,17 @@ public class BiomeType implements RegistryItem, Keyed, BiomePattern { this.id = id; } + /** + * Gets the ID of this biome. + * + * @return The id + * @since TODO + */ + @Override + public String id() { + return this.id; + } + public int getLegacyId() { return legacyId; } @@ -64,12 +75,12 @@ public class BiomeType implements RegistryItem, Keyed, BiomePattern { /** * Gets the ID of this biome. * - * @return The id + * @return the id * @deprecated use {@link #id()} */ @Deprecated(forRemoval = true, since = "TODO") @Override - public String id() { + public String getId() { return this.id; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityType.java index a71404c85..1faf3bc4c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityType.java @@ -46,11 +46,20 @@ public class EntityType implements RegistryItem, Keyed { * * @return the id * @since TODO + */ + public String id() { + return this.id; + } + + /** + * Gets the id of this entity type. + * + * @return the id * @deprecated use {@link #id()} */ @Deprecated(forRemoval = true, since = "TODO") @Override - public String id() { + public String getId() { return this.id; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidType.java index 418eaf06a..36517a2b0 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidType.java @@ -40,15 +40,25 @@ public class FluidType implements RegistryItem, Keyed { } /** - * Gets the ID of this block. + * Gets the ID of this fluid. * * @return The id * @since TODO + */ + @Override + public String id() { + return this.id; + } + + /** + * Gets the ID of this fluid. + * + * @return the id * @deprecated use {@link #id()} */ @Deprecated(forRemoval = true, since = "TODO") @Override - public String id() { + public String getId() { return this.id; }