diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 1de1aa8df..c223aae35 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -27,9 +27,10 @@ body: description: Which server version version you using? If your server version is not listed, it is not supported. Update to a supported version first. multiple: false options: - - '1.20.5/6' - - '1.20' - - '1.19.4' + - '1.21' + - '1.20.6' + - '1.20.4' + - '1.20.2' validations: required: true diff --git a/buildSrc/src/main/kotlin/CommonJavaConfig.kt b/buildSrc/src/main/kotlin/CommonJavaConfig.kt index 60860f7f7..d221a98d2 100644 --- a/buildSrc/src/main/kotlin/CommonJavaConfig.kt +++ b/buildSrc/src/main/kotlin/CommonJavaConfig.kt @@ -23,7 +23,7 @@ fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, banSlf4j: Boolean val disabledLint = listOf( "processing", "path", "fallthrough", "serial", "overloads", "this-escape", ) - options.release.set(17) + options.release.set(21) options.compilerArgs.addAll(listOf("-Xlint:all") + disabledLint.map { "-Xlint:-$it" }) options.isDeprecation = true options.encoding = "UTF-8" diff --git a/settings.gradle.kts b/settings.gradle.kts index de52de2f9..4e1b292c5 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,7 +2,7 @@ rootProject.name = "FastAsyncWorldEdit" include("worldedit-libs") -listOf("1_19_4", "1_20", "1_20_2", "1_20_4", "1_20_5", "1_21").forEach { +listOf("1_20_2", "1_20_4", "1_20_5", "1_21").forEach { include("worldedit-bukkit:adapters:adapter-$it") } diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_19_4/build.gradle.kts deleted file mode 100644 index e53d2497e..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/build.gradle.kts +++ /dev/null @@ -1,17 +0,0 @@ -import io.papermc.paperweight.userdev.PaperweightUserDependenciesExtension - -plugins { - java -} - -applyPaperweightAdapterConfiguration() - -repositories { - gradlePluginPortal() -} - -dependencies { - // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.19.4-R0.1-SNAPSHOT - the().paperDevBundle("1.19.4-R0.1-20230608.201059-104") - compileOnly(libs.paperlib) -} 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 deleted file mode 100644 index 87135fa86..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java +++ /dev/null @@ -1,1077 +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.bukkit.adapter.ext.fawe.v1_19_R3; - -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.common.collect.ImmutableList; -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.NBTConstants; -import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.blocks.BaseItem; -import com.sk89q.worldedit.blocks.BaseItemStack; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3.PaperweightPlatformAdapter; -import com.sk89q.worldedit.entity.BaseEntity; -import com.sk89q.worldedit.extension.platform.Watchdog; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.internal.Constants; -import com.sk89q.worldedit.internal.block.BlockStateIdAccess; -import com.sk89q.worldedit.internal.wna.WorldNativeAccess; -import com.sk89q.worldedit.math.BlockVector2; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.registry.state.BooleanProperty; -import com.sk89q.worldedit.registry.state.DirectionalProperty; -import com.sk89q.worldedit.registry.state.EnumProperty; -import com.sk89q.worldedit.registry.state.IntegerProperty; -import com.sk89q.worldedit.registry.state.Property; -import com.sk89q.worldedit.util.Direction; -import com.sk89q.worldedit.util.SideEffect; -import com.sk89q.worldedit.util.concurrency.LazyReference; -import com.sk89q.worldedit.util.formatting.text.Component; -import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; -import com.sk89q.worldedit.util.io.file.SafeFiles; -import com.sk89q.worldedit.world.DataFixer; -import com.sk89q.worldedit.world.RegenOptions; -import com.sk89q.worldedit.world.biome.BiomeCategory; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.biome.BiomeTypes; -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.block.BlockTypes; -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.HolderSet; -import net.minecraft.core.Registry; -import net.minecraft.core.registries.Registries; -import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; -import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; -import net.minecraft.resources.ResourceKey; -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.progress.ChunkProgressListener; -import net.minecraft.util.StringRepresentable; -import net.minecraft.util.thread.BlockableEventLoop; -import net.minecraft.world.Clearable; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.item.Item; -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.biome.Biome; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.StructureBlockEntity; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.DirectionProperty; -import net.minecraft.world.level.chunk.ChunkAccess; -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.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.Environment; -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.data.CraftBlockData; -import org.bukkit.craftbukkit.v1_19_R3.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_19_R3.util.CraftMagicNumbers; -import org.bukkit.entity.Player; -import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; -import org.bukkit.generator.ChunkGenerator; -import org.enginehub.linbus.common.LinTagId; -import org.enginehub.linbus.tree.LinByteArrayTag; -import org.enginehub.linbus.tree.LinByteTag; -import org.enginehub.linbus.tree.LinCompoundTag; -import org.enginehub.linbus.tree.LinDoubleTag; -import org.enginehub.linbus.tree.LinEndTag; -import org.enginehub.linbus.tree.LinFloatTag; -import org.enginehub.linbus.tree.LinIntArrayTag; -import org.enginehub.linbus.tree.LinIntTag; -import org.enginehub.linbus.tree.LinListTag; -import org.enginehub.linbus.tree.LinLongArrayTag; -import org.enginehub.linbus.tree.LinLongTag; -import org.enginehub.linbus.tree.LinShortTag; -import org.enginehub.linbus.tree.LinStringTag; -import org.enginehub.linbus.tree.LinTag; -import org.enginehub.linbus.tree.LinTagType; -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; -import java.lang.reflect.Method; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; -import java.util.OptionalInt; -import java.util.OptionalLong; -import java.util.Set; -import java.util.TreeMap; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -public final class PaperweightAdapter implements BukkitImplAdapter { - - private final Logger logger = Logger.getLogger(getClass().getCanonicalName()); - - private final Field serverWorldsField; - private final Method getChunkFutureMethod; - private final Field chunkProviderExecutorField; - private final Watchdog watchdog; - - // ------------------------------------------------------------------------ - // Code that may break between versions of Minecraft - // ------------------------------------------------------------------------ - - public PaperweightAdapter() throws NoSuchFieldException, NoSuchMethodException { - // A simple test - CraftServer.class.cast(Bukkit.getServer()); - - int dataVersion = CraftMagicNumbers.INSTANCE.getDataVersion(); - if (dataVersion != 3337) { - throw new UnsupportedClassVersionError("Not 1.19.4!"); - } - - serverWorldsField = CraftServer.class.getDeclaredField("worlds"); - serverWorldsField.setAccessible(true); - - getChunkFutureMethod = ServerChunkCache.class.getDeclaredMethod( - Refraction.pickName("getChunkFutureMainThread", "c"), - int.class, int.class, ChunkStatus.class, boolean.class - ); - getChunkFutureMethod.setAccessible(true); - - chunkProviderExecutorField = ServerChunkCache.class.getDeclaredField( - Refraction.pickName("mainThreadProcessor", "g") - ); - chunkProviderExecutorField.setAccessible(true); - - new PaperweightDataConverters(CraftMagicNumbers.INSTANCE.getDataVersion(), this).buildUnoptimized(); - - Watchdog watchdog; - try { - Class.forName("org.spigotmc.WatchdogThread"); - watchdog = new SpigotWatchdog(); - } catch (ClassNotFoundException | NoSuchFieldException e) { - try { - watchdog = new MojangWatchdog(((CraftServer) Bukkit.getServer()).getServer()); - } catch (NoSuchFieldException ex) { - watchdog = null; - } - } - this.watchdog = watchdog; - - try { - Class.forName("org.spigotmc.SpigotConfig"); - SpigotConfig.config.set("world-settings.faweregentempworld.verbose", false); - } catch (ClassNotFoundException ignored) { - } - } - - @Override - public DataFixer getDataFixer() { - return PaperweightDataConverters.INSTANCE; - } - - /** - * Read the given NBT data into the given tile entity. - * - * @param tileEntity the tile entity - * @param tag the tag - */ - static void readTagIntoTileEntity(net.minecraft.nbt.CompoundTag tag, BlockEntity tileEntity) { - tileEntity.load(tag); - tileEntity.setChanged(); - } - - /** - * Get the ID string of the given entity. - * - * @param entity the entity - * @return the entity ID - */ - private static String getEntityId(Entity entity) { - return EntityType.getKey(entity.getType()).toString(); - } - - /** - * Create an entity using the given entity ID. - * - * @param id the entity ID - * @param world the world - * @return an entity or null - */ - @Nullable - private static Entity createEntityFromId(String id, net.minecraft.world.level.Level world) { - return EntityType.byString(id).map(t -> t.create(world)).orElse(null); - } - - /** - * Write the given NBT data into the given entity. - * - * @param entity the entity - * @param tag the tag - */ - private static void readTagIntoEntity(net.minecraft.nbt.CompoundTag tag, Entity entity) { - entity.load(tag); - } - - /** - * Write the entity's NBT data to the given tag. - * - * @param entity the entity - * @param tag the tag - */ - private static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag tag) { - //FAWE start - avoid villager async catcher - PaperweightPlatformAdapter.readEntityIntoTag(entity, tag); - //FAWE end - } - - private static Block getBlockFromType(BlockType blockType) { - - return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.BLOCK).get(ResourceLocation.tryParse(blockType.id())); - } - - private static Item getItemFromType(ItemType itemType) { - return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.ITEM).get(ResourceLocation.tryParse(itemType.id())); - } - - public BiomeType adapt(Biome biome) { - var mcBiome = ((CraftServer) Bukkit.getServer()).getServer().registryAccess().registryOrThrow(Registries.BIOME).getKey(biome); - if (mcBiome == null) { - return null; - } - return BiomeType.REGISTRY.get(mcBiome.toString()); - } - - @Override - public OptionalInt getInternalBlockStateId(BlockData data) { - net.minecraft.world.level.block.state.BlockState state = ((CraftBlockData) data).getState(); - int combinedId = Block.getId(state); - return combinedId == 0 && state.getBlock() != Blocks.AIR ? OptionalInt.empty() : OptionalInt.of(combinedId); - } - - @Override - public OptionalInt getInternalBlockStateId(BlockState state) { - Block mcBlock = getBlockFromType(state.getBlockType()); - net.minecraft.world.level.block.state.BlockState newState = mcBlock.defaultBlockState(); - Map, Object> states = state.getStates(); - newState = applyProperties(mcBlock.getStateDefinition(), newState, states); - final int combinedId = Block.getId(newState); - return combinedId == 0 && state.getBlockType() != BlockTypes.AIR ? OptionalInt.empty() : OptionalInt.of(combinedId); - } - - @Override - public BlockState getBlock(Location location) { - checkNotNull(location); - - CraftWorld craftWorld = ((CraftWorld) location.getWorld()); - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - - final ServerLevel handle = craftWorld.getHandle(); - LevelChunk chunk = handle.getChunk(x >> 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; - } - - @Override - public BaseBlock getFullBlock(Location location) { - BlockState state = getBlock(location); - - CraftWorld craftWorld = ((CraftWorld) location.getWorld()); - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - - final ServerLevel handle = craftWorld.getHandle(); - LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); - final BlockPos blockPos = new BlockPos(x, y, z); - - // Read the NBT data - BlockEntity te = chunk.getBlockEntity(blockPos); - if (te != null) { - net.minecraft.nbt.CompoundTag tag = te.saveWithId(); - return state.toBaseBlock((LinCompoundTag) toNativeLin(tag)); - } - - return state.toBaseBlock(); - } - - @Override - public WorldNativeAccess createWorldNativeAccess(org.bukkit.World world) { - return new PaperweightWorldNativeAccess(this, - new WeakReference<>(((CraftWorld) world).getHandle())); - } - - private static net.minecraft.core.Direction adapt(Direction face) { - switch (face) { - case NORTH: - return net.minecraft.core.Direction.NORTH; - case SOUTH: - return net.minecraft.core.Direction.SOUTH; - case WEST: - return net.minecraft.core.Direction.WEST; - case EAST: - return net.minecraft.core.Direction.EAST; - case DOWN: - return net.minecraft.core.Direction.DOWN; - case UP: - default: - return net.minecraft.core.Direction.UP; - } - } - - @SuppressWarnings({"rawtypes", "unchecked"}) - private net.minecraft.world.level.block.state.BlockState applyProperties( - StateDefinition stateContainer, - net.minecraft.world.level.block.state.BlockState newState, - Map, Object> states - ) { - for (Map.Entry, Object> state : states.entrySet()) { - net.minecraft.world.level.block.state.properties.Property property = - stateContainer.getProperty(state.getKey().getName()); - Comparable value = (Comparable) state.getValue(); - // we may need to adapt this value, depending on the source prop - if (property instanceof DirectionProperty) { - Direction dir = (Direction) value; - value = adapt(dir); - } else if (property instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { - String enumName = (String) value; - value = ((net.minecraft.world.level.block.state.properties.EnumProperty) property) - .getValue(enumName).orElseThrow(() -> - new IllegalStateException( - "Enum property " + property.getName() + " does not contain " + enumName - ) - ); - } - - newState = newState.setValue( - (net.minecraft.world.level.block.state.properties.Property) property, - (Comparable) value - ); - } - return newState; - } - - @Override - public BaseEntity getEntity(org.bukkit.entity.Entity entity) { - checkNotNull(entity); - - CraftEntity craftEntity = ((CraftEntity) entity); - Entity mcEntity = craftEntity.getHandle(); - - // Do not allow creating of passenger entity snapshots, passengers are included in the vehicle entity - if (mcEntity.isPassenger()) { - return null; - } - - String id = getEntityId(mcEntity); - - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - readEntityIntoTag(mcEntity, tag); - return new BaseEntity( - com.sk89q.worldedit.world.entity.EntityTypes.get(id), - LazyReference.from(() -> (LinCompoundTag) toNativeLin(tag)) - ); - } - - @Nullable - @Override - public org.bukkit.entity.Entity createEntity(Location location, BaseEntity state) { - checkNotNull(location); - checkNotNull(state); - - CraftWorld craftWorld = ((CraftWorld) location.getWorld()); - ServerLevel worldServer = craftWorld.getHandle(); - - Entity createdEntity = createEntityFromId(state.getType().id(), craftWorld.getHandle()); - - if (createdEntity != null) { - LinCompoundTag nativeTag = state.getNbt(); - if (nativeTag != null) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) fromNativeLin(nativeTag); - for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { - tag.remove(name); - } - readTagIntoEntity(tag, createdEntity); - } - - createdEntity.absMoveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); - - worldServer.addFreshEntity(createdEntity, SpawnReason.CUSTOM); - return createdEntity.getBukkitEntity(); - } else { - return null; - } - } - - // This removes all unwanted tags from the main entity and all its passengers - private void removeUnwantedEntityTagsRecursively(net.minecraft.nbt.CompoundTag tag) { - for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { - tag.remove(name); - } - - // Adapted from net.minecraft.world.entity.EntityType#loadEntityRecursive - if (tag.contains("Passengers", NBTConstants.TYPE_LIST)) { - net.minecraft.nbt.ListTag nbttaglist = tag.getList("Passengers", NBTConstants.TYPE_COMPOUND); - - for (int i = 0; i < nbttaglist.size(); ++i) { - removeUnwantedEntityTagsRecursively(nbttaglist.getCompound(i)); - } - } - } - - @Override - public Component getRichBlockName(BlockType blockType) { - return TranslatableComponent.of(getBlockFromType(blockType).getDescriptionId()); - } - - @Override - public Component getRichItemName(ItemType itemType) { - return TranslatableComponent.of(getItemFromType(itemType).getDescriptionId()); - } - - @Override - public Component getRichItemName(BaseItemStack itemStack) { - return TranslatableComponent.of(CraftItemStack.asNMSCopy(BukkitAdapter.adapt(itemStack)).getDescriptionId()); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private static final LoadingCache> PROPERTY_CACHE = CacheBuilder - .newBuilder() - .build(new CacheLoader<>() { - @Override - public Property load(net.minecraft.world.level.block.state.properties.Property state) { - if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { - return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else if (state instanceof DirectionProperty) { - return new DirectionalProperty( - state.getName(), - new ArrayList<>((List) state - .getPossibleValues() - .stream() - .map(e -> Direction.valueOf(((StringRepresentable) e) - .getSerializedName() - .toUpperCase(Locale.ROOT))) - .toList()) - ); - } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { - return new EnumProperty( - state.getName(), - new ArrayList<>((List) state - .getPossibleValues() - .stream() - .map(e -> ((StringRepresentable) e).getSerializedName()) - .toList()) - ); - } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { - return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else { - throw new IllegalArgumentException("WorldEdit needs an update to support " + state - .getClass() - .getSimpleName()); - } - } - }); - - @SuppressWarnings({ "rawtypes" }) - @Override - public Map> getProperties(BlockType blockType) { - Map> properties = new TreeMap<>(); - Block block = getBlockFromType(blockType); - StateDefinition blockStateList = - block.getStateDefinition(); - for (net.minecraft.world.level.block.state.properties.Property state : blockStateList.getProperties()) { - Property property = PROPERTY_CACHE.getUnchecked(state); - properties.put(property.getName(), property); - } - return properties; - } - - @Override - public void sendFakeNBT(Player player, BlockVector3 pos, LinCompoundTag nbtData) { - ((CraftPlayer) player).getHandle().connection.send(ClientboundBlockEntityDataPacket.create( - new StructureBlockEntity( - new BlockPos(pos.x(), pos.y(), pos.z()), - Blocks.STRUCTURE_BLOCK.defaultBlockState() - ), - __ -> (net.minecraft.nbt.CompoundTag) fromNativeLin(nbtData) - )); - } - - @Override - public void sendFakeOP(Player player) { - ((CraftPlayer) player).getHandle().connection.send(new ClientboundEntityEventPacket( - ((CraftPlayer) player).getHandle(), (byte) 28 - )); - } - - @Override - public org.bukkit.inventory.ItemStack adapt(BaseItemStack item) { - ItemStack stack = new ItemStack( - DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.ITEM).get(ResourceLocation.tryParse(item.getType().id())), - item.getAmount() - ); - stack.setTag(((net.minecraft.nbt.CompoundTag) fromNative(item.getNbtData()))); - return CraftItemStack.asCraftMirror(stack); - } - - @Override - public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) { - final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); - final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount()); - weStack.setNbt(((LinCompoundTag) toNativeLin(nmsStack.getTag()))); - return weStack; - } - - private final LoadingCache fakePlayers - = CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(PaperweightFakePlayer::new)); - - @Override - public boolean simulateItemUse(org.bukkit.World world, BlockVector3 position, BaseItem item, Direction face) { - CraftWorld craftWorld = (CraftWorld) world; - ServerLevel worldServer = craftWorld.getHandle(); - ItemStack stack = CraftItemStack.asNMSCopy(BukkitAdapter.adapt(item instanceof BaseItemStack - ? ((BaseItemStack) item) : new BaseItemStack(item.getType(), item.getNbtData(), 1))); - stack.setTag((net.minecraft.nbt.CompoundTag) fromNative(item.getNbtData())); - - PaperweightFakePlayer fakePlayer; - try { - fakePlayer = fakePlayers.get(worldServer); - } catch (ExecutionException ignored) { - return false; - } - fakePlayer.setItemInHand(InteractionHand.MAIN_HAND, stack); - fakePlayer.absMoveTo(position.x(), position.y(), position.z(), - (float) face.toVector().toYaw(), (float) face.toVector().toPitch()); - - final BlockPos blockPos = new BlockPos(position.x(), position.y(), position.z()); - final Vec3 blockVec = Vec3.atLowerCornerOf(blockPos); - final net.minecraft.core.Direction enumFacing = adapt(face); - BlockHitResult rayTrace = new BlockHitResult(blockVec, enumFacing, blockPos, false); - UseOnContext context = new UseOnContext(fakePlayer, InteractionHand.MAIN_HAND, rayTrace); - InteractionResult result = stack.useOn(context, InteractionHand.MAIN_HAND); - if (result != InteractionResult.SUCCESS) { - if (worldServer.getBlockState(blockPos).use(worldServer, fakePlayer, InteractionHand.MAIN_HAND, rayTrace).consumesAction()) { - result = InteractionResult.SUCCESS; - } else { - result = stack.getItem().use(worldServer, fakePlayer, InteractionHand.MAIN_HAND).getResult(); - } - } - - return result == InteractionResult.SUCCESS; - } - - @Override - public boolean canPlaceAt(org.bukkit.World world, BlockVector3 position, BlockState blockState) { - int internalId = BlockStateIdAccess.getBlockStateId(blockState); - net.minecraft.world.level.block.state.BlockState blockData = Block.stateById(internalId); - return blockData.canSurvive(((CraftWorld) world).getHandle(), new BlockPos(position.x(), position.y(), position.z())); - } - - @Override - public boolean regenerate(org.bukkit.World bukkitWorld, Region region, Extent extent, RegenOptions options) { - try { - doRegen(bukkitWorld, region, extent, options); - } catch (Exception e) { - throw new IllegalStateException("Regen failed.", e); - } - - return true; - } - - private void doRegen(org.bukkit.World bukkitWorld, Region region, Extent extent, RegenOptions options) throws Exception { - Environment env = bukkitWorld.getEnvironment(); - ChunkGenerator gen = bukkitWorld.getGenerator(); - - Path tempDir = Files.createTempDirectory("WorldEditWorldGen"); - LevelStorageSource levelStorage = LevelStorageSource.createDefault(tempDir); - ResourceKey worldDimKey = getWorldDimKey(env); - try (LevelStorageSource.LevelStorageAccess session = levelStorage.createAccess("faweregentempworld", worldDimKey)) { - ServerLevel originalWorld = ((CraftWorld) bukkitWorld).getHandle(); - PrimaryLevelData levelProperties = (PrimaryLevelData) originalWorld.getServer() - .getWorldData().overworldData(); - WorldOptions originalOpts = levelProperties.worldGenOptions(); - - long seed = options.getSeed().orElse(originalWorld.getSeed()); - WorldOptions newOpts = options.getSeed().isPresent() - ? originalOpts.withSeed(OptionalLong.of(seed)) - : originalOpts; - - LevelSettings newWorldSettings = new LevelSettings( - "faweregentempworld", - levelProperties.settings.gameType(), - levelProperties.settings.hardcore(), - levelProperties.settings.difficulty(), - levelProperties.settings.allowCommands(), - levelProperties.settings.gameRules(), - levelProperties.settings.getDataConfiguration() - ); - - PrimaryLevelData.SpecialWorldProperty specialWorldProperty = - levelProperties.isFlatWorld() - ? PrimaryLevelData.SpecialWorldProperty.FLAT - : levelProperties.isDebugWorld() - ? PrimaryLevelData.SpecialWorldProperty.DEBUG - : PrimaryLevelData.SpecialWorldProperty.NONE; - - PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, specialWorldProperty, Lifecycle.stable()); - - ServerLevel freshWorld = new ServerLevel( - originalWorld.getServer(), - originalWorld.getServer().executor, - session, newWorldData, - originalWorld.dimension(), - new LevelStem( - originalWorld.dimensionTypeRegistration(), - originalWorld.getChunkSource().getGenerator() - ), - new NoOpWorldLoadListener(), - originalWorld.isDebug(), - seed, - ImmutableList.of(), - false, - env, - gen, - bukkitWorld.getBiomeProvider() - ); - try { - regenForWorld(region, extent, freshWorld, options); - } finally { - freshWorld.getChunkSource().close(false); - } - } finally { - try { - @SuppressWarnings("unchecked") - Map map = (Map) serverWorldsField.get(Bukkit.getServer()); - map.remove("faweregentempworld"); - } catch (IllegalAccessException ignored) { - } - SafeFiles.tryHardToDeleteDir(tempDir); - } - } - - private BiomeType adapt(ServerLevel serverWorld, Biome origBiome) { - ResourceLocation key = serverWorld.registryAccess().registryOrThrow(Registries.BIOME).getKey(origBiome); - if (key == null) { - return null; - } - return BiomeTypes.get(key.toString()); - } - - @SuppressWarnings("unchecked") - private void regenForWorld(Region region, Extent extent, ServerLevel serverWorld, RegenOptions options) throws WorldEditException { - List> chunkLoadings = submitChunkLoadTasks(region, serverWorld); - BlockableEventLoop executor; - try { - executor = (BlockableEventLoop) chunkProviderExecutorField.get(serverWorld.getChunkSource()); - } catch (IllegalAccessException e) { - throw new IllegalStateException("Couldn't get executor for chunk loading.", e); - } - executor.managedBlock(() -> { - // bail out early if a future fails - if (chunkLoadings.stream().anyMatch(ftr -> - ftr.isDone() && Futures.getUnchecked(ftr) == null - )) { - return false; - } - return chunkLoadings.stream().allMatch(CompletableFuture::isDone); - }); - Map chunks = new HashMap<>(); - for (CompletableFuture future : chunkLoadings) { - @Nullable - ChunkAccess chunk = future.getNow(null); - checkState(chunk != null, "Failed to generate a chunk, regen failed."); - chunks.put(chunk.getPos(), chunk); - } - - for (BlockVector3 vec : region) { - BlockPos pos = new BlockPos(vec.x(), vec.y(), vec.z()); - ChunkAccess chunk = chunks.get(new ChunkPos(pos)); - final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos); - int internalId = Block.getId(blockData); - BlockStateHolder state = BlockStateIdAccess.getBlockStateById(internalId); - Objects.requireNonNull(state); - BlockEntity blockEntity = chunk.getBlockEntity(pos); - if (blockEntity != null) { - net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(); - state = state.toBaseBlock((LinCompoundTag) toNativeLin(tag)); - } - extent.setBlock(vec, state.toBaseBlock()); - if (options.shouldRegenBiomes()) { - Biome origBiome = chunk.getNoiseBiome(vec.x(), vec.y(), vec.z()).value(); - BiomeType adaptedBiome = adapt(serverWorld, origBiome); - if (adaptedBiome != null) { - extent.setBiome(vec, adaptedBiome); - } - } - } - } - - @SuppressWarnings("unchecked") - private List> submitChunkLoadTasks(Region region, ServerLevel serverWorld) { - ServerChunkCache chunkManager = serverWorld.getChunkSource(); - List> chunkLoadings = new ArrayList<>(); - // Pre-gen all the chunks - for (BlockVector2 chunk : region.getChunks()) { - try { - //noinspection unchecked - chunkLoadings.add( - ((CompletableFuture>) - getChunkFutureMethod.invoke(chunkManager, chunk.x(), chunk.z(), ChunkStatus.FEATURES, true)) - .thenApply(either -> either.left().orElse(null)) - ); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new IllegalStateException("Couldn't load chunk for regen.", e); - } - } - return chunkLoadings; - } - - private ResourceKey getWorldDimKey(Environment env) { - switch (env) { - case NETHER: - return LevelStem.NETHER; - case THE_END: - return LevelStem.END; - case NORMAL: - default: - return LevelStem.OVERWORLD; - } - } - - private static final Set SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet( - SideEffect.NEIGHBORS, - SideEffect.LIGHTING, - SideEffect.VALIDATION, - SideEffect.ENTITY_AI, - SideEffect.EVENTS, - SideEffect.UPDATE - ); - - @Override - public Set getSupportedSideEffects() { - return SUPPORTED_SIDE_EFFECTS; - } - - @Override - public boolean clearContainerBlockContents(org.bukkit.World world, BlockVector3 pt) { - ServerLevel originalWorld = ((CraftWorld) world).getHandle(); - - BlockEntity entity = originalWorld.getBlockEntity(new BlockPos(pt.x(), pt.y(), pt.z())); - if (entity instanceof Clearable) { - ((Clearable) entity).clearContent(); - return true; - } - return false; - } - - @Override - public void initializeRegistries() { - DedicatedServer server = ((CraftServer) Bukkit.getServer()).getServer(); - // Biomes - for (ResourceLocation name : server.registryAccess().registryOrThrow(Registries.BIOME).keySet()) { - if (BiomeType.REGISTRY.get(name.toString()) == null) { - BiomeType.REGISTRY.register(name.toString(), new BiomeType(name.toString())); - } - } - - // BiomeCategories - Registry biomeRegistry = server.registryAccess().registryOrThrow(Registries.BIOME); - biomeRegistry.getTagNames().forEach(tagKey -> { - String key = tagKey.location().toString(); - if (BiomeCategory.REGISTRY.get(key) == null) { - BiomeCategory.REGISTRY.register(key, new BiomeCategory( - key, - () -> biomeRegistry.getTag(tagKey) - .stream() - .flatMap(HolderSet.Named::stream) - .map(Holder::value) - .map(this::adapt) - .collect(Collectors.toSet())) - ); - } - }); - } - - // ------------------------------------------------------------------------ - // Code that is less likely to break - // ------------------------------------------------------------------------ - - /** - * Converts from a non-native NMS NBT structure to a native WorldEdit NBT - * structure. - * - * @param foreign non-native NMS NBT structure - * @return native WorldEdit NBT structure - */ - @Override - public LinTag toNativeLin(net.minecraft.nbt.Tag foreign) { - if (foreign == null) { - return null; - } - if (foreign instanceof net.minecraft.nbt.CompoundTag) { - Map> values = new HashMap<>(); - Set foreignKeys = ((net.minecraft.nbt.CompoundTag) foreign).getAllKeys(); - - for (String str : foreignKeys) { - net.minecraft.nbt.Tag base = ((net.minecraft.nbt.CompoundTag) foreign).get(str); - values.put(str, toNativeLin(base)); - } - return LinCompoundTag.of(values); - } else if (foreign instanceof net.minecraft.nbt.ByteTag) { - return LinByteTag.of(((net.minecraft.nbt.ByteTag) foreign).getAsByte()); - } else if (foreign instanceof net.minecraft.nbt.ByteArrayTag) { - return LinByteArrayTag.of(((net.minecraft.nbt.ByteArrayTag) foreign).getAsByteArray()); - } else if (foreign instanceof net.minecraft.nbt.DoubleTag) { - return LinDoubleTag.of(((net.minecraft.nbt.DoubleTag) foreign).getAsDouble()); - } else if (foreign instanceof net.minecraft.nbt.FloatTag) { - return LinFloatTag.of(((net.minecraft.nbt.FloatTag) foreign).getAsFloat()); - } else if (foreign instanceof net.minecraft.nbt.IntTag) { - return LinIntTag.of(((net.minecraft.nbt.IntTag) foreign).getAsInt()); - } else if (foreign instanceof net.minecraft.nbt.IntArrayTag) { - return LinIntArrayTag.of(((net.minecraft.nbt.IntArrayTag) foreign).getAsIntArray()); - } else if (foreign instanceof net.minecraft.nbt.LongArrayTag) { - return LinLongArrayTag.of(((net.minecraft.nbt.LongArrayTag) foreign).getAsLongArray()); - } else if (foreign instanceof net.minecraft.nbt.ListTag) { - try { - return toNativeLinList((net.minecraft.nbt.ListTag) foreign); - } catch (Throwable e) { - logger.log(Level.WARNING, "Failed to convert net.minecraft.nbt.ListTag", e); - } - } else if (foreign instanceof net.minecraft.nbt.LongTag) { - return LinLongTag.of(((net.minecraft.nbt.LongTag) foreign).getAsLong()); - } else if (foreign instanceof net.minecraft.nbt.ShortTag) { - return LinShortTag.of(((net.minecraft.nbt.ShortTag) foreign).getAsShort()); - } else if (foreign instanceof net.minecraft.nbt.StringTag) { - return LinStringTag.of(foreign.getAsString()); - } else if (foreign instanceof net.minecraft.nbt.EndTag) { - return LinEndTag.instance(); - } - throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName()); - } - - /** - * Convert a foreign NBT list tag into a native WorldEdit one. - * - * @param foreign the foreign tag - * @return the converted tag - * @throws SecurityException on error - * @throws IllegalArgumentException on error - */ - private LinListTag toNativeLinList(net.minecraft.nbt.ListTag foreign) throws SecurityException, IllegalArgumentException { - LinListTag.Builder> builder = LinListTag.builder( - LinTagType.fromId(LinTagId.fromId(foreign.getElementType())) - ); - - for (net.minecraft.nbt.Tag tag : foreign) { - builder.add(toNativeLin(tag)); - } - - return builder.build(); - } - - /** - * Converts a WorldEdit-native NBT structure to a NMS structure. - * - * @param foreign structure to convert - * @return non-native structure - */ - @Override - public net.minecraft.nbt.Tag fromNativeLin(LinTag foreign) { - if (foreign == null) { - return null; - } - if (foreign instanceof LinCompoundTag compoundTag) { - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - for (var entry : compoundTag.value().entrySet()) { - tag.put(entry.getKey(), fromNativeLin(entry.getValue())); - } - return tag; - } else if (foreign instanceof LinByteTag byteTag) { - return net.minecraft.nbt.ByteTag.valueOf(byteTag.valueAsByte()); - } else if (foreign instanceof LinByteArrayTag byteArrayTag) { - return new net.minecraft.nbt.ByteArrayTag(byteArrayTag.value()); - } else if (foreign instanceof LinDoubleTag doubleTag) { - return net.minecraft.nbt.DoubleTag.valueOf(doubleTag.valueAsDouble()); - } else if (foreign instanceof LinFloatTag floatTag) { - return net.minecraft.nbt.FloatTag.valueOf(floatTag.valueAsFloat()); - } else if (foreign instanceof LinIntTag intTag) { - return net.minecraft.nbt.IntTag.valueOf(intTag.valueAsInt()); - } else if (foreign instanceof LinIntArrayTag intArrayTag) { - return new net.minecraft.nbt.IntArrayTag(intArrayTag.value()); - } else if (foreign instanceof LinLongArrayTag longArrayTag) { - return new net.minecraft.nbt.LongArrayTag(longArrayTag.value()); - } else if (foreign instanceof LinListTag listTag) { - net.minecraft.nbt.ListTag tag = new net.minecraft.nbt.ListTag(); - for (var t : listTag.value()) { - tag.add(fromNativeLin(t)); - } - return tag; - } else if (foreign instanceof LinLongTag longTag) { - return net.minecraft.nbt.LongTag.valueOf(longTag.valueAsLong()); - } else if (foreign instanceof LinShortTag shortTag) { - return net.minecraft.nbt.ShortTag.valueOf(shortTag.valueAsShort()); - } else if (foreign instanceof LinStringTag stringTag) { - return net.minecraft.nbt.StringTag.valueOf(stringTag.value()); - } else if (foreign instanceof LinEndTag) { - return net.minecraft.nbt.EndTag.INSTANCE; - } else { - throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName()); - } - } - - @Override - public boolean supportsWatchdog() { - return watchdog != null; - } - - @Override - public void tickWatchdog() { - watchdog.tick(); - } - - private class SpigotWatchdog implements Watchdog { - private final Field instanceField; - private final Field lastTickField; - - SpigotWatchdog() throws NoSuchFieldException { - Field instanceField = WatchdogThread.class.getDeclaredField("instance"); - instanceField.setAccessible(true); - this.instanceField = instanceField; - - Field lastTickField = WatchdogThread.class.getDeclaredField("lastTick"); - lastTickField.setAccessible(true); - this.lastTickField = lastTickField; - } - - @Override - public void tick() { - try { - WatchdogThread instance = (WatchdogThread) this.instanceField.get(null); - if ((long) lastTickField.get(instance) != 0) { - WatchdogThread.tick(); - } - } catch (IllegalAccessException e) { - logger.log(Level.WARNING, "Failed to tick watchdog", e); - } - } - } - - private static class MojangWatchdog implements Watchdog { - private final DedicatedServer server; - private final Field tickField; - - MojangWatchdog(DedicatedServer server) throws NoSuchFieldException { - this.server = server; - Field tickField = MinecraftServer.class.getDeclaredField( - Refraction.pickName("nextTickTime", "ah") - ); - if (tickField.getType() != long.class) { - throw new IllegalStateException("nextTickTime is not a long field, mapping is likely incorrect"); - } - tickField.setAccessible(true); - this.tickField = tickField; - } - - @Override - public void tick() { - try { - tickField.set(server, Util.getMillis()); - } catch (IllegalAccessException ignored) { - } - } - } - - private static class NoOpWorldLoadListener implements ChunkProgressListener { - @Override - public void updateSpawnPos(ChunkPos spawnPos) { - } - - @Override - public void onStatusChange(ChunkPos pos, @org.jetbrains.annotations.Nullable ChunkStatus status) { - } - - @Override - public void start() { - } - - @Override - public void stop() { - } - - @Override - public void setChunkRadius(int radius) { - } - } -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightDataConverters.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightDataConverters.java deleted file mode 100644 index 50de3467e..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightDataConverters.java +++ /dev/null @@ -1,2799 +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.bukkit.adapter.ext.fawe.v1_19_R3; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonParseException; -import com.mojang.datafixers.DSL; -import com.mojang.datafixers.DSL.TypeReference; -import com.mojang.datafixers.DataFixer; -import com.mojang.datafixers.DataFixerBuilder; -import com.mojang.datafixers.schemas.Schema; -import com.mojang.serialization.Dynamic; -import net.minecraft.core.Direction; -import net.minecraft.nbt.NbtOps; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.MutableComponent; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.GsonHelper; -import net.minecraft.util.StringUtil; -import net.minecraft.util.datafix.DataFixers; -import net.minecraft.util.datafix.fixes.References; -import net.minecraft.world.item.DyeColor; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.enginehub.linbus.tree.LinCompoundTag; - -import javax.annotation.Nullable; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Executor; -import java.util.stream.Collectors; - -/** - * Handles converting all Pre 1.13.2 data using the Legacy DataFix System (ported to 1.13.2) - * - * We register a DFU Fixer per Legacy Data Version and apply the fixes using legacy strategy - * which is safer, faster and cleaner code. - * - * The pre DFU code did not fail when the Source version was unknown. - * - * This class also provides util methods for converting compounds to wrap the update call to - * receive the source version in the compound - */ -@SuppressWarnings({ "rawtypes", "unchecked" }) -class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.worldedit.world.DataFixer { - - @SuppressWarnings("unchecked") - @Override - public T fixUp(FixType type, T original, int srcVer) { - if (type == FixTypes.CHUNK) { - return (T) fixChunk((LinCompoundTag) original, srcVer); - } else if (type == FixTypes.BLOCK_ENTITY) { - return (T) fixBlockEntity((LinCompoundTag) original, srcVer); - } else if (type == FixTypes.ENTITY) { - return (T) fixEntity((LinCompoundTag) original, srcVer); - } else if (type == FixTypes.BLOCK_STATE) { - return (T) fixBlockState((String) original, srcVer); - } else if (type == FixTypes.ITEM_TYPE) { - return (T) fixItemType((String) original, srcVer); - } else if (type == FixTypes.BIOME) { - return (T) fixBiome((String) original, srcVer); - } - return original; - } - - private LinCompoundTag fixChunk(LinCompoundTag originalChunk, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(originalChunk); - net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.CHUNK, tag, srcVer); - return (LinCompoundTag) adapter.toNativeLin(fixed); - } - - private LinCompoundTag fixBlockEntity(LinCompoundTag origTileEnt, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(origTileEnt); - net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.BLOCK_ENTITY, tag, srcVer); - return (LinCompoundTag) adapter.toNativeLin(fixed); - } - - private LinCompoundTag fixEntity(LinCompoundTag origEnt, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(origEnt); - net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.ENTITY, tag, srcVer); - return (LinCompoundTag) adapter.toNativeLin(fixed); - } - - private String fixBlockState(String blockState, int srcVer) { - net.minecraft.nbt.CompoundTag stateNBT = stateToNBT(blockState); - Dynamic dynamic = new Dynamic<>(OPS_NBT, stateNBT); - net.minecraft.nbt.CompoundTag fixed = (net.minecraft.nbt.CompoundTag) INSTANCE.fixer.update(References.BLOCK_STATE, dynamic, srcVer, DATA_VERSION).getValue(); - return nbtToState(fixed); - } - - private String nbtToState(net.minecraft.nbt.CompoundTag tagCompound) { - StringBuilder sb = new StringBuilder(); - sb.append(tagCompound.getString("Name")); - if (tagCompound.contains("Properties", 10)) { - sb.append('['); - net.minecraft.nbt.CompoundTag props = tagCompound.getCompound("Properties"); - sb.append(props.getAllKeys().stream().map(k -> k + "=" + props.getString(k).replace("\"", "")).collect(Collectors.joining(","))); - sb.append(']'); - } - return sb.toString(); - } - - private static net.minecraft.nbt.CompoundTag stateToNBT(String blockState) { - int propIdx = blockState.indexOf('['); - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - if (propIdx < 0) { - tag.putString("Name", blockState); - } else { - tag.putString("Name", blockState.substring(0, propIdx)); - net.minecraft.nbt.CompoundTag propTag = new net.minecraft.nbt.CompoundTag(); - String props = blockState.substring(propIdx + 1, blockState.length() - 1); - String[] propArr = props.split(","); - for (String pair : propArr) { - final String[] split = pair.split("="); - propTag.putString(split[0], split[1]); - } - tag.put("Properties", propTag); - } - return tag; - } - - private String fixBiome(String key, int srcVer) { - return fixName(key, srcVer, References.BIOME); - } - - private String fixItemType(String key, int srcVer) { - return fixName(key, srcVer, References.ITEM_NAME); - } - - private static String fixName(String key, int srcVer, TypeReference type) { - return INSTANCE.fixer.update(type, new Dynamic<>(OPS_NBT, net.minecraft.nbt.StringTag.valueOf(key)), srcVer, DATA_VERSION) - .getValue().getAsString(); - } - - private final PaperweightAdapter adapter; - - private static final NbtOps OPS_NBT = NbtOps.INSTANCE; - private static final int LEGACY_VERSION = 1343; - private static int DATA_VERSION; - static PaperweightDataConverters INSTANCE; - - private final Map> converters = new EnumMap<>(LegacyType.class); - private final Map> inspectors = new EnumMap<>(LegacyType.class); - - // Set on build - private DataFixer fixer; - private static final Map DFU_TO_LEGACY = new HashMap<>(); - - public enum LegacyType { - LEVEL(References.LEVEL), - PLAYER(References.PLAYER), - CHUNK(References.CHUNK), - BLOCK_ENTITY(References.BLOCK_ENTITY), - ENTITY(References.ENTITY), - ITEM_INSTANCE(References.ITEM_STACK), - OPTIONS(References.OPTIONS), - STRUCTURE(References.STRUCTURE); - - private final TypeReference type; - - LegacyType(TypeReference type) { - this.type = type; - DFU_TO_LEGACY.put(type.typeName(), this); - } - - public TypeReference getDFUType() { - return type; - } - } - - PaperweightDataConverters(int dataVersion, PaperweightAdapter adapter) { - super(dataVersion); - DATA_VERSION = dataVersion; - INSTANCE = this; - this.adapter = adapter; - registerConverters(); - registerInspectors(); - } - - - // Called after fixers are built and ready for FIXING - @Override - public DataFixer buildUnoptimized() { - return this.fixer = new WrappedDataFixer(DataFixers.getDataFixer()); - } - - @Override - public DataFixer buildOptimized(final Set requiredTypes, Executor executor) { - return buildUnoptimized(); - } - - @SuppressWarnings("unchecked") - private class WrappedDataFixer implements DataFixer { - private final DataFixer realFixer; - - WrappedDataFixer(DataFixer realFixer) { - this.realFixer = realFixer; - } - - @Override - - public Dynamic update(TypeReference type, Dynamic dynamic, int sourceVer, int targetVer) { - LegacyType legacyType = DFU_TO_LEGACY.get(type.typeName()); - if (sourceVer < LEGACY_VERSION && legacyType != null) { - net.minecraft.nbt.CompoundTag cmp = (net.minecraft.nbt.CompoundTag) dynamic.getValue(); - int desiredVersion = Math.min(targetVer, LEGACY_VERSION); - - cmp = convert(legacyType, cmp, sourceVer, desiredVersion); - sourceVer = desiredVersion; - dynamic = new Dynamic(OPS_NBT, cmp); - } - return realFixer.update(type, dynamic, sourceVer, targetVer); - } - - private net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer, int desiredVersion) { - List converters = PaperweightDataConverters.this.converters.get(type); - if (converters != null && !converters.isEmpty()) { - for (DataConverter converter : converters) { - int dataVersion = converter.getDataVersion(); - if (dataVersion > sourceVer && dataVersion <= desiredVersion) { - cmp = converter.convert(cmp); - } - } - } - - List inspectors = PaperweightDataConverters.this.inspectors.get(type); - if (inspectors != null && !inspectors.isEmpty()) { - for (DataInspector inspector : inspectors) { - cmp = inspector.inspect(cmp, sourceVer, desiredVersion); - } - } - - return cmp; - } - - @Override - public Schema getSchema(int i) { - return realFixer.getSchema(i); - } - } - - public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp) { - return convert(type.getDFUType(), cmp); - } - - public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer) { - return convert(type.getDFUType(), cmp, sourceVer); - } - - public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - return convert(type.getDFUType(), cmp, sourceVer, targetVer); - } - - public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp) { - int i = cmp.contains("DataVersion", 99) ? cmp.getInt("DataVersion") : -1; - return convert(type, cmp, i); - } - - public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp, int sourceVer) { - return convert(type, cmp, sourceVer, DATA_VERSION); - } - - public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (sourceVer >= targetVer) { - return cmp; - } - return (net.minecraft.nbt.CompoundTag) INSTANCE.fixer.update(type, new Dynamic<>(OPS_NBT, cmp), sourceVer, targetVer).getValue(); - } - - - public interface DataInspector { - net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer); - } - - public interface DataConverter { - - int getDataVersion(); - - net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp); - } - - - private void registerInspector(LegacyType type, DataInspector inspector) { - this.inspectors.computeIfAbsent(type, k -> new ArrayList<>()).add(inspector); - } - - private void registerConverter(LegacyType type, DataConverter converter) { - int version = converter.getDataVersion(); - - List list = this.converters.computeIfAbsent(type, k -> new ArrayList<>()); - if (!list.isEmpty() && list.get(list.size() - 1).getDataVersion() > version) { - for (int j = 0; j < list.size(); ++j) { - if (list.get(j).getDataVersion() > version) { - list.add(j, converter); - break; - } - } - } else { - list.add(converter); - } - } - - private void registerInspectors() { - registerEntityItemList("EntityHorseDonkey", "SaddleItem", "Items"); - registerEntityItemList("EntityHorseMule", "Items"); - registerEntityItemList("EntityMinecartChest", "Items"); - registerEntityItemList("EntityMinecartHopper", "Items"); - registerEntityItemList("EntityVillager", "Inventory"); - registerEntityItemListEquipment("EntityArmorStand"); - registerEntityItemListEquipment("EntityBat"); - registerEntityItemListEquipment("EntityBlaze"); - registerEntityItemListEquipment("EntityCaveSpider"); - registerEntityItemListEquipment("EntityChicken"); - registerEntityItemListEquipment("EntityCow"); - registerEntityItemListEquipment("EntityCreeper"); - registerEntityItemListEquipment("EntityEnderDragon"); - registerEntityItemListEquipment("EntityEnderman"); - registerEntityItemListEquipment("EntityEndermite"); - registerEntityItemListEquipment("EntityEvoker"); - registerEntityItemListEquipment("EntityGhast"); - registerEntityItemListEquipment("EntityGiantZombie"); - registerEntityItemListEquipment("EntityGuardian"); - registerEntityItemListEquipment("EntityGuardianElder"); - registerEntityItemListEquipment("EntityHorse"); - registerEntityItemListEquipment("EntityHorseDonkey"); - registerEntityItemListEquipment("EntityHorseMule"); - registerEntityItemListEquipment("EntityHorseSkeleton"); - registerEntityItemListEquipment("EntityHorseZombie"); - registerEntityItemListEquipment("EntityIronGolem"); - registerEntityItemListEquipment("EntityMagmaCube"); - registerEntityItemListEquipment("EntityMushroomCow"); - registerEntityItemListEquipment("EntityOcelot"); - registerEntityItemListEquipment("EntityPig"); - registerEntityItemListEquipment("EntityPigZombie"); - registerEntityItemListEquipment("EntityRabbit"); - registerEntityItemListEquipment("EntitySheep"); - registerEntityItemListEquipment("EntityShulker"); - registerEntityItemListEquipment("EntitySilverfish"); - registerEntityItemListEquipment("EntitySkeleton"); - registerEntityItemListEquipment("EntitySkeletonStray"); - registerEntityItemListEquipment("EntitySkeletonWither"); - registerEntityItemListEquipment("EntitySlime"); - registerEntityItemListEquipment("EntitySnowman"); - registerEntityItemListEquipment("EntitySpider"); - registerEntityItemListEquipment("EntitySquid"); - registerEntityItemListEquipment("EntityVex"); - registerEntityItemListEquipment("EntityVillager"); - registerEntityItemListEquipment("EntityVindicator"); - registerEntityItemListEquipment("EntityWitch"); - registerEntityItemListEquipment("EntityWither"); - registerEntityItemListEquipment("EntityWolf"); - registerEntityItemListEquipment("EntityZombie"); - registerEntityItemListEquipment("EntityZombieHusk"); - registerEntityItemListEquipment("EntityZombieVillager"); - registerEntityItemSingle("EntityFireworks", "FireworksItem"); - registerEntityItemSingle("EntityHorse", "ArmorItem"); - registerEntityItemSingle("EntityHorse", "SaddleItem"); - registerEntityItemSingle("EntityHorseMule", "SaddleItem"); - registerEntityItemSingle("EntityHorseSkeleton", "SaddleItem"); - registerEntityItemSingle("EntityHorseZombie", "SaddleItem"); - registerEntityItemSingle("EntityItem", "Item"); - registerEntityItemSingle("EntityItemFrame", "Item"); - registerEntityItemSingle("EntityPotion", "Potion"); - - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItem("TileEntityRecordPlayer", "RecordItem")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityBrewingStand", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityChest", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityDispenser", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityDropper", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityFurnace", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityHopper", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityShulkerBox", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorMobSpawnerMobs()); - registerInspector(LegacyType.CHUNK, new DataInspectorChunks()); - registerInspector(LegacyType.ENTITY, new DataInspectorCommandBlock()); - registerInspector(LegacyType.ENTITY, new DataInspectorEntityPassengers()); - registerInspector(LegacyType.ENTITY, new DataInspectorMobSpawnerMinecart()); - registerInspector(LegacyType.ENTITY, new DataInspectorVillagers()); - registerInspector(LegacyType.ITEM_INSTANCE, new DataInspectorBlockEntity()); - registerInspector(LegacyType.ITEM_INSTANCE, new DataInspectorEntity()); - registerInspector(LegacyType.LEVEL, new DataInspectorLevelPlayer()); - registerInspector(LegacyType.PLAYER, new DataInspectorPlayer()); - registerInspector(LegacyType.PLAYER, new DataInspectorPlayerVehicle()); - registerInspector(LegacyType.STRUCTURE, new DataInspectorStructure()); - } - - private void registerConverters() { - registerConverter(LegacyType.ENTITY, new DataConverterEquipment()); - registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterSignText()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterMaterialId()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterPotionId()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterSpawnEgg()); - registerConverter(LegacyType.ENTITY, new DataConverterMinecart()); - registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterMobSpawner()); - registerConverter(LegacyType.ENTITY, new DataConverterUUID()); - registerConverter(LegacyType.ENTITY, new DataConverterHealth()); - registerConverter(LegacyType.ENTITY, new DataConverterSaddle()); - registerConverter(LegacyType.ENTITY, new DataConverterHanging()); - registerConverter(LegacyType.ENTITY, new DataConverterDropChances()); - registerConverter(LegacyType.ENTITY, new DataConverterRiding()); - registerConverter(LegacyType.ENTITY, new DataConverterArmorStand()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterBook()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterCookedFish()); - registerConverter(LegacyType.ENTITY, new DataConverterZombie()); - registerConverter(LegacyType.OPTIONS, new DataConverterVBO()); - registerConverter(LegacyType.ENTITY, new DataConverterGuardian()); - registerConverter(LegacyType.ENTITY, new DataConverterSkeleton()); - registerConverter(LegacyType.ENTITY, new DataConverterZombieType()); - registerConverter(LegacyType.ENTITY, new DataConverterHorse()); - registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterTileEntity()); - registerConverter(LegacyType.ENTITY, new DataConverterEntity()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterBanner()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterPotionWater()); - registerConverter(LegacyType.ENTITY, new DataConverterShulker()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterShulkerBoxItem()); - registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterShulkerBoxBlock()); - registerConverter(LegacyType.OPTIONS, new DataConverterLang()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterTotem()); - registerConverter(LegacyType.CHUNK, new DataConverterBedBlock()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterBedItem()); - } - - private void registerEntityItemList(String type, String... keys) { - registerInspector(LegacyType.ENTITY, new DataInspectorItemList(type, keys)); - } - - private void registerEntityItemSingle(String type, String key) { - registerInspector(LegacyType.ENTITY, new DataInspectorItem(type, key)); - } - - private void registerEntityItemListEquipment(String type) { - registerEntityItemList(type, "ArmorItems", "HandItems"); - } - - private static final Map OLD_ID_TO_KEY_MAP = new HashMap<>(); - - static { - final Map map = OLD_ID_TO_KEY_MAP; - map.put("EntityItem", new ResourceLocation("item")); - map.put("EntityExperienceOrb", new ResourceLocation("xp_orb")); - map.put("EntityAreaEffectCloud", new ResourceLocation("area_effect_cloud")); - map.put("EntityGuardianElder", new ResourceLocation("elder_guardian")); - map.put("EntitySkeletonWither", new ResourceLocation("wither_skeleton")); - map.put("EntitySkeletonStray", new ResourceLocation("stray")); - map.put("EntityEgg", new ResourceLocation("egg")); - map.put("EntityLeash", new ResourceLocation("leash_knot")); - map.put("EntityPainting", new ResourceLocation("painting")); - map.put("EntityTippedArrow", new ResourceLocation("arrow")); - map.put("EntitySnowball", new ResourceLocation("snowball")); - map.put("EntityLargeFireball", new ResourceLocation("fireball")); - map.put("EntitySmallFireball", new ResourceLocation("small_fireball")); - map.put("EntityEnderPearl", new ResourceLocation("ender_pearl")); - map.put("EntityEnderSignal", new ResourceLocation("eye_of_ender_signal")); - map.put("EntityPotion", new ResourceLocation("potion")); - map.put("EntityThrownExpBottle", new ResourceLocation("xp_bottle")); - map.put("EntityItemFrame", new ResourceLocation("item_frame")); - map.put("EntityWitherSkull", new ResourceLocation("wither_skull")); - map.put("EntityTNTPrimed", new ResourceLocation("tnt")); - map.put("EntityFallingBlock", new ResourceLocation("falling_block")); - map.put("EntityFireworks", new ResourceLocation("fireworks_rocket")); - map.put("EntityZombieHusk", new ResourceLocation("husk")); - map.put("EntitySpectralArrow", new ResourceLocation("spectral_arrow")); - map.put("EntityShulkerBullet", new ResourceLocation("shulker_bullet")); - map.put("EntityDragonFireball", new ResourceLocation("dragon_fireball")); - map.put("EntityZombieVillager", new ResourceLocation("zombie_villager")); - map.put("EntityHorseSkeleton", new ResourceLocation("skeleton_horse")); - map.put("EntityHorseZombie", new ResourceLocation("zombie_horse")); - map.put("EntityArmorStand", new ResourceLocation("armor_stand")); - map.put("EntityHorseDonkey", new ResourceLocation("donkey")); - map.put("EntityHorseMule", new ResourceLocation("mule")); - map.put("EntityEvokerFangs", new ResourceLocation("evocation_fangs")); - map.put("EntityEvoker", new ResourceLocation("evocation_illager")); - map.put("EntityVex", new ResourceLocation("vex")); - map.put("EntityVindicator", new ResourceLocation("vindication_illager")); - map.put("EntityIllagerIllusioner", new ResourceLocation("illusion_illager")); - map.put("EntityMinecartCommandBlock", new ResourceLocation("commandblock_minecart")); - map.put("EntityBoat", new ResourceLocation("boat")); - map.put("EntityMinecartRideable", new ResourceLocation("minecart")); - map.put("EntityMinecartChest", new ResourceLocation("chest_minecart")); - map.put("EntityMinecartFurnace", new ResourceLocation("furnace_minecart")); - map.put("EntityMinecartTNT", new ResourceLocation("tnt_minecart")); - map.put("EntityMinecartHopper", new ResourceLocation("hopper_minecart")); - map.put("EntityMinecartMobSpawner", new ResourceLocation("spawner_minecart")); - map.put("EntityCreeper", new ResourceLocation("creeper")); - map.put("EntitySkeleton", new ResourceLocation("skeleton")); - map.put("EntitySpider", new ResourceLocation("spider")); - map.put("EntityGiantZombie", new ResourceLocation("giant")); - map.put("EntityZombie", new ResourceLocation("zombie")); - map.put("EntitySlime", new ResourceLocation("slime")); - map.put("EntityGhast", new ResourceLocation("ghast")); - map.put("EntityPigZombie", new ResourceLocation("zombie_pigman")); - map.put("EntityEnderman", new ResourceLocation("enderman")); - map.put("EntityCaveSpider", new ResourceLocation("cave_spider")); - map.put("EntitySilverfish", new ResourceLocation("silverfish")); - map.put("EntityBlaze", new ResourceLocation("blaze")); - map.put("EntityMagmaCube", new ResourceLocation("magma_cube")); - map.put("EntityEnderDragon", new ResourceLocation("ender_dragon")); - map.put("EntityWither", new ResourceLocation("wither")); - map.put("EntityBat", new ResourceLocation("bat")); - map.put("EntityWitch", new ResourceLocation("witch")); - map.put("EntityEndermite", new ResourceLocation("endermite")); - map.put("EntityGuardian", new ResourceLocation("guardian")); - map.put("EntityShulker", new ResourceLocation("shulker")); - map.put("EntityPig", new ResourceLocation("pig")); - map.put("EntitySheep", new ResourceLocation("sheep")); - map.put("EntityCow", new ResourceLocation("cow")); - map.put("EntityChicken", new ResourceLocation("chicken")); - map.put("EntitySquid", new ResourceLocation("squid")); - map.put("EntityWolf", new ResourceLocation("wolf")); - map.put("EntityMushroomCow", new ResourceLocation("mooshroom")); - map.put("EntitySnowman", new ResourceLocation("snowman")); - map.put("EntityOcelot", new ResourceLocation("ocelot")); - map.put("EntityIronGolem", new ResourceLocation("villager_golem")); - map.put("EntityHorse", new ResourceLocation("horse")); - map.put("EntityRabbit", new ResourceLocation("rabbit")); - map.put("EntityPolarBear", new ResourceLocation("polar_bear")); - map.put("EntityLlama", new ResourceLocation("llama")); - map.put("EntityLlamaSpit", new ResourceLocation("llama_spit")); - map.put("EntityParrot", new ResourceLocation("parrot")); - map.put("EntityVillager", new ResourceLocation("villager")); - map.put("EntityEnderCrystal", new ResourceLocation("ender_crystal")); - map.put("TileEntityFurnace", new ResourceLocation("furnace")); - map.put("TileEntityChest", new ResourceLocation("chest")); - map.put("TileEntityEnderChest", new ResourceLocation("ender_chest")); - map.put("TileEntityRecordPlayer", new ResourceLocation("jukebox")); - map.put("TileEntityDispenser", new ResourceLocation("dispenser")); - map.put("TileEntityDropper", new ResourceLocation("dropper")); - map.put("TileEntitySign", new ResourceLocation("sign")); - map.put("TileEntityMobSpawner", new ResourceLocation("mob_spawner")); - map.put("TileEntityNote", new ResourceLocation("noteblock")); - map.put("TileEntityPiston", new ResourceLocation("piston")); - map.put("TileEntityBrewingStand", new ResourceLocation("brewing_stand")); - map.put("TileEntityEnchantTable", new ResourceLocation("enchanting_table")); - map.put("TileEntityEnderPortal", new ResourceLocation("end_portal")); - map.put("TileEntityBeacon", new ResourceLocation("beacon")); - map.put("TileEntitySkull", new ResourceLocation("skull")); - map.put("TileEntityLightDetector", new ResourceLocation("daylight_detector")); - map.put("TileEntityHopper", new ResourceLocation("hopper")); - map.put("TileEntityComparator", new ResourceLocation("comparator")); - map.put("TileEntityFlowerPot", new ResourceLocation("flower_pot")); - map.put("TileEntityBanner", new ResourceLocation("banner")); - map.put("TileEntityStructure", new ResourceLocation("structure_block")); - map.put("TileEntityEndGateway", new ResourceLocation("end_gateway")); - map.put("TileEntityCommand", new ResourceLocation("command_block")); - map.put("TileEntityShulkerBox", new ResourceLocation("shulker_box")); - map.put("TileEntityBed", new ResourceLocation("bed")); - } - - private static ResourceLocation getKey(String type) { - final ResourceLocation key = OLD_ID_TO_KEY_MAP.get(type); - if (key == null) { - throw new IllegalArgumentException("Unknown mapping for " + type); - } - return key; - } - - private static void convertCompound(LegacyType type, net.minecraft.nbt.CompoundTag cmp, String key, int sourceVer, int targetVer) { - cmp.put(key, convert(type, cmp.getCompound(key), sourceVer, targetVer)); - } - - private static void convertItem(net.minecraft.nbt.CompoundTag nbttagcompound, String key, int sourceVer, int targetVer) { - if (nbttagcompound.contains(key, 10)) { - convertCompound(LegacyType.ITEM_INSTANCE, nbttagcompound, key, sourceVer, targetVer); - } - } - - private static void convertItems(net.minecraft.nbt.CompoundTag nbttagcompound, String key, int sourceVer, int targetVer) { - if (nbttagcompound.contains(key, 9)) { - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound.getList(key, 10); - - for (int j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set(j, convert(LegacyType.ITEM_INSTANCE, nbttaglist.getCompound(j), sourceVer, targetVer)); - } - } - - } - - private static class DataConverterEquipment implements DataConverter { - - DataConverterEquipment() { - } - - public int getDataVersion() { - return 100; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - net.minecraft.nbt.ListTag nbttaglist = cmp.getList("Equipment", 10); - net.minecraft.nbt.ListTag nbttaglist1; - - if (!nbttaglist.isEmpty() && !cmp.contains("HandItems", 10)) { - nbttaglist1 = new net.minecraft.nbt.ListTag(); - nbttaglist1.add(nbttaglist.get(0)); - nbttaglist1.add(new net.minecraft.nbt.CompoundTag()); - cmp.put("HandItems", nbttaglist1); - } - - if (nbttaglist.size() > 1 && !cmp.contains("ArmorItem", 10)) { - nbttaglist1 = new net.minecraft.nbt.ListTag(); - nbttaglist1.add(nbttaglist.get(1)); - nbttaglist1.add(nbttaglist.get(2)); - nbttaglist1.add(nbttaglist.get(3)); - nbttaglist1.add(nbttaglist.get(4)); - cmp.put("ArmorItems", nbttaglist1); - } - - cmp.remove("Equipment"); - if (cmp.contains("DropChances", 9)) { - nbttaglist1 = cmp.getList("DropChances", 5); - net.minecraft.nbt.ListTag nbttaglist2; - - if (!cmp.contains("HandDropChances", 10)) { - nbttaglist2 = new net.minecraft.nbt.ListTag(); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(0))); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(0.0F)); - cmp.put("HandDropChances", nbttaglist2); - } - - if (!cmp.contains("ArmorDropChances", 10)) { - nbttaglist2 = new net.minecraft.nbt.ListTag(); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(1))); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(2))); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(3))); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(4))); - cmp.put("ArmorDropChances", nbttaglist2); - } - - cmp.remove("DropChances"); - } - - return cmp; - } - } - - private static class DataInspectorBlockEntity implements DataInspector { - - private static final Map b = Maps.newHashMap(); - private static final Map c = Maps.newHashMap(); - - DataInspectorBlockEntity() { - } - - @Nullable - private static String convertEntityId(int i, String s) { - String key = new ResourceLocation(s).toString(); - if (i < 515 && DataInspectorBlockEntity.b.containsKey(key)) { - return DataInspectorBlockEntity.b.get(key); - } else { - return DataInspectorBlockEntity.c.get(key); - } - } - - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (!cmp.contains("tag", 10)) { - return cmp; - } else { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("BlockEntityTag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag"); - String s = cmp.getString("id"); - String s1 = convertEntityId(sourceVer, s); - boolean flag; - - if (s1 == null) { - // CraftBukkit - Remove unnecessary warning (occurs when deserializing a Shulker Box item) - // DataInspectorBlockEntity.a.warn("Unable to resolve BlockEntity for ItemInstance: {}", s); - flag = false; - } else { - flag = !nbttagcompound2.contains("id"); - nbttagcompound2.putString("id", s1); - } - - convert(LegacyType.BLOCK_ENTITY, nbttagcompound2, sourceVer, targetVer); - if (flag) { - nbttagcompound2.remove("id"); - } - } - - return cmp; - } - } - - static { - Map map = DataInspectorBlockEntity.b; - - map.put("minecraft:furnace", "Furnace"); - map.put("minecraft:lit_furnace", "Furnace"); - map.put("minecraft:chest", "Chest"); - map.put("minecraft:trapped_chest", "Chest"); - map.put("minecraft:ender_chest", "EnderChest"); - map.put("minecraft:jukebox", "RecordPlayer"); - map.put("minecraft:dispenser", "Trap"); - map.put("minecraft:dropper", "Dropper"); - map.put("minecraft:sign", "Sign"); - map.put("minecraft:mob_spawner", "MobSpawner"); - map.put("minecraft:noteblock", "Music"); - map.put("minecraft:brewing_stand", "Cauldron"); - map.put("minecraft:enhanting_table", "EnchantTable"); - map.put("minecraft:command_block", "CommandBlock"); - map.put("minecraft:beacon", "Beacon"); - map.put("minecraft:skull", "Skull"); - map.put("minecraft:daylight_detector", "DLDetector"); - map.put("minecraft:hopper", "Hopper"); - map.put("minecraft:banner", "Banner"); - map.put("minecraft:flower_pot", "FlowerPot"); - map.put("minecraft:repeating_command_block", "CommandBlock"); - map.put("minecraft:chain_command_block", "CommandBlock"); - map.put("minecraft:standing_sign", "Sign"); - map.put("minecraft:wall_sign", "Sign"); - map.put("minecraft:piston_head", "Piston"); - map.put("minecraft:daylight_detector_inverted", "DLDetector"); - map.put("minecraft:unpowered_comparator", "Comparator"); - map.put("minecraft:powered_comparator", "Comparator"); - map.put("minecraft:wall_banner", "Banner"); - map.put("minecraft:standing_banner", "Banner"); - map.put("minecraft:structure_block", "Structure"); - map.put("minecraft:end_portal", "Airportal"); - map.put("minecraft:end_gateway", "EndGateway"); - map.put("minecraft:shield", "Shield"); - map = DataInspectorBlockEntity.c; - map.put("minecraft:furnace", "minecraft:furnace"); - map.put("minecraft:lit_furnace", "minecraft:furnace"); - map.put("minecraft:chest", "minecraft:chest"); - map.put("minecraft:trapped_chest", "minecraft:chest"); - map.put("minecraft:ender_chest", "minecraft:enderchest"); - map.put("minecraft:jukebox", "minecraft:jukebox"); - map.put("minecraft:dispenser", "minecraft:dispenser"); - map.put("minecraft:dropper", "minecraft:dropper"); - map.put("minecraft:sign", "minecraft:sign"); - map.put("minecraft:mob_spawner", "minecraft:mob_spawner"); - map.put("minecraft:noteblock", "minecraft:noteblock"); - map.put("minecraft:brewing_stand", "minecraft:brewing_stand"); - map.put("minecraft:enhanting_table", "minecraft:enchanting_table"); - map.put("minecraft:command_block", "minecraft:command_block"); - map.put("minecraft:beacon", "minecraft:beacon"); - map.put("minecraft:skull", "minecraft:skull"); - map.put("minecraft:daylight_detector", "minecraft:daylight_detector"); - map.put("minecraft:hopper", "minecraft:hopper"); - map.put("minecraft:banner", "minecraft:banner"); - map.put("minecraft:flower_pot", "minecraft:flower_pot"); - map.put("minecraft:repeating_command_block", "minecraft:command_block"); - map.put("minecraft:chain_command_block", "minecraft:command_block"); - map.put("minecraft:shulker_box", "minecraft:shulker_box"); - map.put("minecraft:white_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:orange_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:magenta_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:light_blue_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:yellow_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:lime_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:pink_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:gray_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:silver_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:cyan_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:purple_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:blue_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:brown_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:green_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:red_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:black_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:bed", "minecraft:bed"); - map.put("minecraft:standing_sign", "minecraft:sign"); - map.put("minecraft:wall_sign", "minecraft:sign"); - map.put("minecraft:piston_head", "minecraft:piston"); - map.put("minecraft:daylight_detector_inverted", "minecraft:daylight_detector"); - map.put("minecraft:unpowered_comparator", "minecraft:comparator"); - map.put("minecraft:powered_comparator", "minecraft:comparator"); - map.put("minecraft:wall_banner", "minecraft:banner"); - map.put("minecraft:standing_banner", "minecraft:banner"); - map.put("minecraft:structure_block", "minecraft:structure_block"); - map.put("minecraft:end_portal", "minecraft:end_portal"); - map.put("minecraft:end_gateway", "minecraft:end_gateway"); - map.put("minecraft:shield", "minecraft:shield"); - } - } - - private static class DataInspectorEntity implements DataInspector { - - DataInspectorEntity() { - } - - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("EntityTag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("EntityTag"); - String s = cmp.getString("id"); - String s1; - - if ("minecraft:armor_stand".equals(s)) { - s1 = sourceVer < 515 ? "ArmorStand" : "minecraft:armor_stand"; - } else { - if (!"minecraft:spawn_egg".equals(s)) { - return cmp; - } - - s1 = nbttagcompound2.getString("id"); - } - - boolean flag; - - flag = !nbttagcompound2.contains("id", 8); - nbttagcompound2.putString("id", s1); - - convert(LegacyType.ENTITY, nbttagcompound2, sourceVer, targetVer); - if (flag) { - nbttagcompound2.remove("id"); - } - } - - return cmp; - } - } - - - private abstract static class DataInspectorTagged implements DataInspector { - - private final ResourceLocation key; - - DataInspectorTagged(String type) { - this.key = getKey(type); - } - - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (this.key.equals(new ResourceLocation(cmp.getString("id")))) { - cmp = this.inspectChecked(cmp, sourceVer, targetVer); - } - - return cmp; - } - - abstract net.minecraft.nbt.CompoundTag inspectChecked(net.minecraft.nbt.CompoundTag nbttagcompound, int sourceVer, int targetVer); - } - - private static class DataInspectorItemList extends DataInspectorTagged { - - private final String[] keys; - - DataInspectorItemList(String oclass, String... astring) { - super(oclass); - this.keys = astring; - } - - net.minecraft.nbt.CompoundTag inspectChecked(net.minecraft.nbt.CompoundTag nbttagcompound, int sourceVer, int targetVer) { - for (String s : this.keys) { - PaperweightDataConverters.convertItems(nbttagcompound, s, sourceVer, targetVer); - } - - return nbttagcompound; - } - } - - private static class DataInspectorItem extends DataInspectorTagged { - - private final String[] keys; - - DataInspectorItem(String oclass, String... astring) { - super(oclass); - this.keys = astring; - } - - net.minecraft.nbt.CompoundTag inspectChecked(net.minecraft.nbt.CompoundTag nbttagcompound, int sourceVer, int targetVer) { - for (String key : this.keys) { - PaperweightDataConverters.convertItem(nbttagcompound, key, sourceVer, targetVer); - } - - return nbttagcompound; - } - } - - private static class DataConverterMaterialId implements DataConverter { - - private static final String[] materials = new String[2268]; - - DataConverterMaterialId() { - } - - public int getDataVersion() { - return 102; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (cmp.contains("id", 99)) { - short short0 = cmp.getShort("id"); - - if (short0 > 0 && short0 < materials.length && materials[short0] != null) { - cmp.putString("id", materials[short0]); - } - } - - return cmp; - } - - static { - materials[1] = "minecraft:stone"; - materials[2] = "minecraft:grass"; - materials[3] = "minecraft:dirt"; - materials[4] = "minecraft:cobblestone"; - materials[5] = "minecraft:planks"; - materials[6] = "minecraft:sapling"; - materials[7] = "minecraft:bedrock"; - materials[8] = "minecraft:flowing_water"; - materials[9] = "minecraft:water"; - materials[10] = "minecraft:flowing_lava"; - materials[11] = "minecraft:lava"; - materials[12] = "minecraft:sand"; - materials[13] = "minecraft:gravel"; - materials[14] = "minecraft:gold_ore"; - materials[15] = "minecraft:iron_ore"; - materials[16] = "minecraft:coal_ore"; - materials[17] = "minecraft:log"; - materials[18] = "minecraft:leaves"; - materials[19] = "minecraft:sponge"; - materials[20] = "minecraft:glass"; - materials[21] = "minecraft:lapis_ore"; - materials[22] = "minecraft:lapis_block"; - materials[23] = "minecraft:dispenser"; - materials[24] = "minecraft:sandstone"; - materials[25] = "minecraft:noteblock"; - materials[27] = "minecraft:golden_rail"; - materials[28] = "minecraft:detector_rail"; - materials[29] = "minecraft:sticky_piston"; - materials[30] = "minecraft:web"; - materials[31] = "minecraft:tallgrass"; - materials[32] = "minecraft:deadbush"; - materials[33] = "minecraft:piston"; - materials[35] = "minecraft:wool"; - materials[37] = "minecraft:yellow_flower"; - materials[38] = "minecraft:red_flower"; - materials[39] = "minecraft:brown_mushroom"; - materials[40] = "minecraft:red_mushroom"; - materials[41] = "minecraft:gold_block"; - materials[42] = "minecraft:iron_block"; - materials[43] = "minecraft:double_stone_slab"; - materials[44] = "minecraft:stone_slab"; - materials[45] = "minecraft:brick_block"; - materials[46] = "minecraft:tnt"; - materials[47] = "minecraft:bookshelf"; - materials[48] = "minecraft:mossy_cobblestone"; - materials[49] = "minecraft:obsidian"; - materials[50] = "minecraft:torch"; - materials[51] = "minecraft:fire"; - materials[52] = "minecraft:mob_spawner"; - materials[53] = "minecraft:oak_stairs"; - materials[54] = "minecraft:chest"; - materials[56] = "minecraft:diamond_ore"; - materials[57] = "minecraft:diamond_block"; - materials[58] = "minecraft:crafting_table"; - materials[60] = "minecraft:farmland"; - materials[61] = "minecraft:furnace"; - materials[62] = "minecraft:lit_furnace"; - materials[65] = "minecraft:ladder"; - materials[66] = "minecraft:rail"; - materials[67] = "minecraft:stone_stairs"; - materials[69] = "minecraft:lever"; - materials[70] = "minecraft:stone_pressure_plate"; - materials[72] = "minecraft:wooden_pressure_plate"; - materials[73] = "minecraft:redstone_ore"; - materials[76] = "minecraft:redstone_torch"; - materials[77] = "minecraft:stone_button"; - materials[78] = "minecraft:snow_layer"; - materials[79] = "minecraft:ice"; - materials[80] = "minecraft:snow"; - materials[81] = "minecraft:cactus"; - materials[82] = "minecraft:clay"; - materials[84] = "minecraft:jukebox"; - materials[85] = "minecraft:fence"; - materials[86] = "minecraft:pumpkin"; - materials[87] = "minecraft:netherrack"; - materials[88] = "minecraft:soul_sand"; - materials[89] = "minecraft:glowstone"; - materials[90] = "minecraft:portal"; - materials[91] = "minecraft:lit_pumpkin"; - materials[95] = "minecraft:stained_glass"; - materials[96] = "minecraft:trapdoor"; - materials[97] = "minecraft:monster_egg"; - materials[98] = "minecraft:stonebrick"; - materials[99] = "minecraft:brown_mushroom_block"; - materials[100] = "minecraft:red_mushroom_block"; - materials[101] = "minecraft:iron_bars"; - materials[102] = "minecraft:glass_pane"; - materials[103] = "minecraft:melon_block"; - materials[106] = "minecraft:vine"; - materials[107] = "minecraft:fence_gate"; - materials[108] = "minecraft:brick_stairs"; - materials[109] = "minecraft:stone_brick_stairs"; - materials[110] = "minecraft:mycelium"; - materials[111] = "minecraft:waterlily"; - materials[112] = "minecraft:nether_brick"; - materials[113] = "minecraft:nether_brick_fence"; - materials[114] = "minecraft:nether_brick_stairs"; - materials[116] = "minecraft:enchanting_table"; - materials[119] = "minecraft:end_portal"; - materials[120] = "minecraft:end_portal_frame"; - materials[121] = "minecraft:end_stone"; - materials[122] = "minecraft:dragon_egg"; - materials[123] = "minecraft:redstone_lamp"; - materials[125] = "minecraft:double_wooden_slab"; - materials[126] = "minecraft:wooden_slab"; - materials[127] = "minecraft:cocoa"; - materials[128] = "minecraft:sandstone_stairs"; - materials[129] = "minecraft:emerald_ore"; - materials[130] = "minecraft:ender_chest"; - materials[131] = "minecraft:tripwire_hook"; - materials[133] = "minecraft:emerald_block"; - materials[134] = "minecraft:spruce_stairs"; - materials[135] = "minecraft:birch_stairs"; - materials[136] = "minecraft:jungle_stairs"; - materials[137] = "minecraft:command_block"; - materials[138] = "minecraft:beacon"; - materials[139] = "minecraft:cobblestone_wall"; - materials[141] = "minecraft:carrots"; - materials[142] = "minecraft:potatoes"; - materials[143] = "minecraft:wooden_button"; - materials[145] = "minecraft:anvil"; - materials[146] = "minecraft:trapped_chest"; - materials[147] = "minecraft:light_weighted_pressure_plate"; - materials[148] = "minecraft:heavy_weighted_pressure_plate"; - materials[151] = "minecraft:daylight_detector"; - materials[152] = "minecraft:redstone_block"; - materials[153] = "minecraft:quartz_ore"; - materials[154] = "minecraft:hopper"; - materials[155] = "minecraft:quartz_block"; - materials[156] = "minecraft:quartz_stairs"; - materials[157] = "minecraft:activator_rail"; - materials[158] = "minecraft:dropper"; - materials[159] = "minecraft:stained_hardened_clay"; - materials[160] = "minecraft:stained_glass_pane"; - materials[161] = "minecraft:leaves2"; - materials[162] = "minecraft:log2"; - materials[163] = "minecraft:acacia_stairs"; - materials[164] = "minecraft:dark_oak_stairs"; - materials[170] = "minecraft:hay_block"; - materials[171] = "minecraft:carpet"; - materials[172] = "minecraft:hardened_clay"; - materials[173] = "minecraft:coal_block"; - materials[174] = "minecraft:packed_ice"; - materials[175] = "minecraft:double_plant"; - materials[256] = "minecraft:iron_shovel"; - materials[257] = "minecraft:iron_pickaxe"; - materials[258] = "minecraft:iron_axe"; - materials[259] = "minecraft:flint_and_steel"; - materials[260] = "minecraft:apple"; - materials[261] = "minecraft:bow"; - materials[262] = "minecraft:arrow"; - materials[263] = "minecraft:coal"; - materials[264] = "minecraft:diamond"; - materials[265] = "minecraft:iron_ingot"; - materials[266] = "minecraft:gold_ingot"; - materials[267] = "minecraft:iron_sword"; - materials[268] = "minecraft:wooden_sword"; - materials[269] = "minecraft:wooden_shovel"; - materials[270] = "minecraft:wooden_pickaxe"; - materials[271] = "minecraft:wooden_axe"; - materials[272] = "minecraft:stone_sword"; - materials[273] = "minecraft:stone_shovel"; - materials[274] = "minecraft:stone_pickaxe"; - materials[275] = "minecraft:stone_axe"; - materials[276] = "minecraft:diamond_sword"; - materials[277] = "minecraft:diamond_shovel"; - materials[278] = "minecraft:diamond_pickaxe"; - materials[279] = "minecraft:diamond_axe"; - materials[280] = "minecraft:stick"; - materials[281] = "minecraft:bowl"; - materials[282] = "minecraft:mushroom_stew"; - materials[283] = "minecraft:golden_sword"; - materials[284] = "minecraft:golden_shovel"; - materials[285] = "minecraft:golden_pickaxe"; - materials[286] = "minecraft:golden_axe"; - materials[287] = "minecraft:string"; - materials[288] = "minecraft:feather"; - materials[289] = "minecraft:gunpowder"; - materials[290] = "minecraft:wooden_hoe"; - materials[291] = "minecraft:stone_hoe"; - materials[292] = "minecraft:iron_hoe"; - materials[293] = "minecraft:diamond_hoe"; - materials[294] = "minecraft:golden_hoe"; - materials[295] = "minecraft:wheat_seeds"; - materials[296] = "minecraft:wheat"; - materials[297] = "minecraft:bread"; - materials[298] = "minecraft:leather_helmet"; - materials[299] = "minecraft:leather_chestplate"; - materials[300] = "minecraft:leather_leggings"; - materials[301] = "minecraft:leather_boots"; - materials[302] = "minecraft:chainmail_helmet"; - materials[303] = "minecraft:chainmail_chestplate"; - materials[304] = "minecraft:chainmail_leggings"; - materials[305] = "minecraft:chainmail_boots"; - materials[306] = "minecraft:iron_helmet"; - materials[307] = "minecraft:iron_chestplate"; - materials[308] = "minecraft:iron_leggings"; - materials[309] = "minecraft:iron_boots"; - materials[310] = "minecraft:diamond_helmet"; - materials[311] = "minecraft:diamond_chestplate"; - materials[312] = "minecraft:diamond_leggings"; - materials[313] = "minecraft:diamond_boots"; - materials[314] = "minecraft:golden_helmet"; - materials[315] = "minecraft:golden_chestplate"; - materials[316] = "minecraft:golden_leggings"; - materials[317] = "minecraft:golden_boots"; - materials[318] = "minecraft:flint"; - materials[319] = "minecraft:porkchop"; - materials[320] = "minecraft:cooked_porkchop"; - materials[321] = "minecraft:painting"; - materials[322] = "minecraft:golden_apple"; - materials[323] = "minecraft:sign"; - materials[324] = "minecraft:wooden_door"; - materials[325] = "minecraft:bucket"; - materials[326] = "minecraft:water_bucket"; - materials[327] = "minecraft:lava_bucket"; - materials[328] = "minecraft:minecart"; - materials[329] = "minecraft:saddle"; - materials[330] = "minecraft:iron_door"; - materials[331] = "minecraft:redstone"; - materials[332] = "minecraft:snowball"; - materials[333] = "minecraft:boat"; - materials[334] = "minecraft:leather"; - materials[335] = "minecraft:milk_bucket"; - materials[336] = "minecraft:brick"; - materials[337] = "minecraft:clay_ball"; - materials[338] = "minecraft:reeds"; - materials[339] = "minecraft:paper"; - materials[340] = "minecraft:book"; - materials[341] = "minecraft:slime_ball"; - materials[342] = "minecraft:chest_minecart"; - materials[343] = "minecraft:furnace_minecart"; - materials[344] = "minecraft:egg"; - materials[345] = "minecraft:compass"; - materials[346] = "minecraft:fishing_rod"; - materials[347] = "minecraft:clock"; - materials[348] = "minecraft:glowstone_dust"; - materials[349] = "minecraft:fish"; - materials[350] = "minecraft:cooked_fish"; // Paper - cooked_fished -> cooked_fish - materials[351] = "minecraft:dye"; - materials[352] = "minecraft:bone"; - materials[353] = "minecraft:sugar"; - materials[354] = "minecraft:cake"; - materials[355] = "minecraft:bed"; - materials[356] = "minecraft:repeater"; - materials[357] = "minecraft:cookie"; - materials[358] = "minecraft:filled_map"; - materials[359] = "minecraft:shears"; - materials[360] = "minecraft:melon"; - materials[361] = "minecraft:pumpkin_seeds"; - materials[362] = "minecraft:melon_seeds"; - materials[363] = "minecraft:beef"; - materials[364] = "minecraft:cooked_beef"; - materials[365] = "minecraft:chicken"; - materials[366] = "minecraft:cooked_chicken"; - materials[367] = "minecraft:rotten_flesh"; - materials[368] = "minecraft:ender_pearl"; - materials[369] = "minecraft:blaze_rod"; - materials[370] = "minecraft:ghast_tear"; - materials[371] = "minecraft:gold_nugget"; - materials[372] = "minecraft:nether_wart"; - materials[373] = "minecraft:potion"; - materials[374] = "minecraft:glass_bottle"; - materials[375] = "minecraft:spider_eye"; - materials[376] = "minecraft:fermented_spider_eye"; - materials[377] = "minecraft:blaze_powder"; - materials[378] = "minecraft:magma_cream"; - materials[379] = "minecraft:brewing_stand"; - materials[380] = "minecraft:cauldron"; - materials[381] = "minecraft:ender_eye"; - materials[382] = "minecraft:speckled_melon"; - materials[383] = "minecraft:spawn_egg"; - materials[384] = "minecraft:experience_bottle"; - materials[385] = "minecraft:fire_charge"; - materials[386] = "minecraft:writable_book"; - materials[387] = "minecraft:written_book"; - materials[388] = "minecraft:emerald"; - materials[389] = "minecraft:item_frame"; - materials[390] = "minecraft:flower_pot"; - materials[391] = "minecraft:carrot"; - materials[392] = "minecraft:potato"; - materials[393] = "minecraft:baked_potato"; - materials[394] = "minecraft:poisonous_potato"; - materials[395] = "minecraft:map"; - materials[396] = "minecraft:golden_carrot"; - materials[397] = "minecraft:skull"; - materials[398] = "minecraft:carrot_on_a_stick"; - materials[399] = "minecraft:nether_star"; - materials[400] = "minecraft:pumpkin_pie"; - materials[401] = "minecraft:fireworks"; - materials[402] = "minecraft:firework_charge"; - materials[403] = "minecraft:enchanted_book"; - materials[404] = "minecraft:comparator"; - materials[405] = "minecraft:netherbrick"; - materials[406] = "minecraft:quartz"; - materials[407] = "minecraft:tnt_minecart"; - materials[408] = "minecraft:hopper_minecart"; - materials[417] = "minecraft:iron_horse_armor"; - materials[418] = "minecraft:golden_horse_armor"; - materials[419] = "minecraft:diamond_horse_armor"; - materials[420] = "minecraft:lead"; - materials[421] = "minecraft:name_tag"; - materials[422] = "minecraft:command_block_minecart"; - materials[2256] = "minecraft:record_13"; - materials[2257] = "minecraft:record_cat"; - materials[2258] = "minecraft:record_blocks"; - materials[2259] = "minecraft:record_chirp"; - materials[2260] = "minecraft:record_far"; - materials[2261] = "minecraft:record_mall"; - materials[2262] = "minecraft:record_mellohi"; - materials[2263] = "minecraft:record_stal"; - materials[2264] = "minecraft:record_strad"; - materials[2265] = "minecraft:record_ward"; - materials[2266] = "minecraft:record_11"; - materials[2267] = "minecraft:record_wait"; - // Paper start - materials[409] = "minecraft:prismarine_shard"; - materials[410] = "minecraft:prismarine_crystals"; - materials[411] = "minecraft:rabbit"; - materials[412] = "minecraft:cooked_rabbit"; - materials[413] = "minecraft:rabbit_stew"; - materials[414] = "minecraft:rabbit_foot"; - materials[415] = "minecraft:rabbit_hide"; - materials[416] = "minecraft:armor_stand"; - materials[423] = "minecraft:mutton"; - materials[424] = "minecraft:cooked_mutton"; - materials[425] = "minecraft:banner"; - materials[426] = "minecraft:end_crystal"; - materials[427] = "minecraft:spruce_door"; - materials[428] = "minecraft:birch_door"; - materials[429] = "minecraft:jungle_door"; - materials[430] = "minecraft:acacia_door"; - materials[431] = "minecraft:dark_oak_door"; - materials[432] = "minecraft:chorus_fruit"; - materials[433] = "minecraft:chorus_fruit_popped"; - materials[434] = "minecraft:beetroot"; - materials[435] = "minecraft:beetroot_seeds"; - materials[436] = "minecraft:beetroot_soup"; - materials[437] = "minecraft:dragon_breath"; - materials[438] = "minecraft:splash_potion"; - materials[439] = "minecraft:spectral_arrow"; - materials[440] = "minecraft:tipped_arrow"; - materials[441] = "minecraft:lingering_potion"; - materials[442] = "minecraft:shield"; - materials[443] = "minecraft:elytra"; - materials[444] = "minecraft:spruce_boat"; - materials[445] = "minecraft:birch_boat"; - materials[446] = "minecraft:jungle_boat"; - materials[447] = "minecraft:acacia_boat"; - materials[448] = "minecraft:dark_oak_boat"; - materials[449] = "minecraft:totem_of_undying"; - materials[450] = "minecraft:shulker_shell"; - materials[452] = "minecraft:iron_nugget"; - materials[453] = "minecraft:knowledge_book"; - // Paper end - } - } - - private static class DataConverterArmorStand implements DataConverter { - - DataConverterArmorStand() { - } - - public int getDataVersion() { - return 147; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("ArmorStand".equals(cmp.getString("id")) && cmp.getBoolean("Silent") && !cmp.getBoolean("Marker")) { - cmp.remove("Silent"); - } - - return cmp; - } - } - - private static class DataConverterBanner implements DataConverter { - - DataConverterBanner() { - } - - public int getDataVersion() { - return 804; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:banner".equals(cmp.getString("id")) && cmp.contains("tag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("BlockEntityTag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag"); - - if (nbttagcompound2.contains("Base", 99)) { - cmp.putShort("Damage", (short) (nbttagcompound2.getShort("Base") & 15)); - if (nbttagcompound1.contains("display", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound3 = nbttagcompound1.getCompound("display"); - - if (nbttagcompound3.contains("Lore", 9)) { - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound3.getList("Lore", 8); - - if (nbttaglist.size() == 1 && "(+NBT)".equals(nbttaglist.getString(0))) { - return cmp; - } - } - } - - nbttagcompound2.remove("Base"); - if (nbttagcompound2.isEmpty()) { - nbttagcompound1.remove("BlockEntityTag"); - } - - if (nbttagcompound1.isEmpty()) { - cmp.remove("tag"); - } - } - } - } - - return cmp; - } - } - - private static class DataConverterPotionId implements DataConverter { - - private static final String[] potions = new String[128]; - - DataConverterPotionId() { - } - - public int getDataVersion() { - return 102; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:potion".equals(cmp.getString("id"))) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - short short0 = cmp.getShort("Damage"); - - if (!nbttagcompound1.contains("Potion", 8)) { - String s = DataConverterPotionId.potions[short0 & 127]; - - nbttagcompound1.putString("Potion", s == null ? "minecraft:water" : s); - cmp.put("tag", nbttagcompound1); - if ((short0 & 16384) == 16384) { - cmp.putString("id", "minecraft:splash_potion"); - } - } - - if (short0 != 0) { - cmp.putShort("Damage", (short) 0); - } - } - - return cmp; - } - - static { - DataConverterPotionId.potions[0] = "minecraft:water"; - DataConverterPotionId.potions[1] = "minecraft:regeneration"; - DataConverterPotionId.potions[2] = "minecraft:swiftness"; - DataConverterPotionId.potions[3] = "minecraft:fire_resistance"; - DataConverterPotionId.potions[4] = "minecraft:poison"; - DataConverterPotionId.potions[5] = "minecraft:healing"; - DataConverterPotionId.potions[6] = "minecraft:night_vision"; - DataConverterPotionId.potions[7] = null; - DataConverterPotionId.potions[8] = "minecraft:weakness"; - DataConverterPotionId.potions[9] = "minecraft:strength"; - DataConverterPotionId.potions[10] = "minecraft:slowness"; - DataConverterPotionId.potions[11] = "minecraft:leaping"; - DataConverterPotionId.potions[12] = "minecraft:harming"; - DataConverterPotionId.potions[13] = "minecraft:water_breathing"; - DataConverterPotionId.potions[14] = "minecraft:invisibility"; - DataConverterPotionId.potions[15] = null; - DataConverterPotionId.potions[16] = "minecraft:awkward"; - DataConverterPotionId.potions[17] = "minecraft:regeneration"; - DataConverterPotionId.potions[18] = "minecraft:swiftness"; - DataConverterPotionId.potions[19] = "minecraft:fire_resistance"; - DataConverterPotionId.potions[20] = "minecraft:poison"; - DataConverterPotionId.potions[21] = "minecraft:healing"; - DataConverterPotionId.potions[22] = "minecraft:night_vision"; - DataConverterPotionId.potions[23] = null; - DataConverterPotionId.potions[24] = "minecraft:weakness"; - DataConverterPotionId.potions[25] = "minecraft:strength"; - DataConverterPotionId.potions[26] = "minecraft:slowness"; - DataConverterPotionId.potions[27] = "minecraft:leaping"; - DataConverterPotionId.potions[28] = "minecraft:harming"; - DataConverterPotionId.potions[29] = "minecraft:water_breathing"; - DataConverterPotionId.potions[30] = "minecraft:invisibility"; - DataConverterPotionId.potions[31] = null; - DataConverterPotionId.potions[32] = "minecraft:thick"; - DataConverterPotionId.potions[33] = "minecraft:strong_regeneration"; - DataConverterPotionId.potions[34] = "minecraft:strong_swiftness"; - DataConverterPotionId.potions[35] = "minecraft:fire_resistance"; - DataConverterPotionId.potions[36] = "minecraft:strong_poison"; - DataConverterPotionId.potions[37] = "minecraft:strong_healing"; - DataConverterPotionId.potions[38] = "minecraft:night_vision"; - DataConverterPotionId.potions[39] = null; - DataConverterPotionId.potions[40] = "minecraft:weakness"; - DataConverterPotionId.potions[41] = "minecraft:strong_strength"; - DataConverterPotionId.potions[42] = "minecraft:slowness"; - DataConverterPotionId.potions[43] = "minecraft:strong_leaping"; - DataConverterPotionId.potions[44] = "minecraft:strong_harming"; - DataConverterPotionId.potions[45] = "minecraft:water_breathing"; - DataConverterPotionId.potions[46] = "minecraft:invisibility"; - DataConverterPotionId.potions[47] = null; - DataConverterPotionId.potions[48] = null; - DataConverterPotionId.potions[49] = "minecraft:strong_regeneration"; - DataConverterPotionId.potions[50] = "minecraft:strong_swiftness"; - DataConverterPotionId.potions[51] = "minecraft:fire_resistance"; - DataConverterPotionId.potions[52] = "minecraft:strong_poison"; - DataConverterPotionId.potions[53] = "minecraft:strong_healing"; - DataConverterPotionId.potions[54] = "minecraft:night_vision"; - DataConverterPotionId.potions[55] = null; - DataConverterPotionId.potions[56] = "minecraft:weakness"; - DataConverterPotionId.potions[57] = "minecraft:strong_strength"; - DataConverterPotionId.potions[58] = "minecraft:slowness"; - DataConverterPotionId.potions[59] = "minecraft:strong_leaping"; - DataConverterPotionId.potions[60] = "minecraft:strong_harming"; - DataConverterPotionId.potions[61] = "minecraft:water_breathing"; - DataConverterPotionId.potions[62] = "minecraft:invisibility"; - DataConverterPotionId.potions[63] = null; - DataConverterPotionId.potions[64] = "minecraft:mundane"; - DataConverterPotionId.potions[65] = "minecraft:long_regeneration"; - DataConverterPotionId.potions[66] = "minecraft:long_swiftness"; - DataConverterPotionId.potions[67] = "minecraft:long_fire_resistance"; - DataConverterPotionId.potions[68] = "minecraft:long_poison"; - DataConverterPotionId.potions[69] = "minecraft:healing"; - DataConverterPotionId.potions[70] = "minecraft:long_night_vision"; - DataConverterPotionId.potions[71] = null; - DataConverterPotionId.potions[72] = "minecraft:long_weakness"; - DataConverterPotionId.potions[73] = "minecraft:long_strength"; - DataConverterPotionId.potions[74] = "minecraft:long_slowness"; - DataConverterPotionId.potions[75] = "minecraft:long_leaping"; - DataConverterPotionId.potions[76] = "minecraft:harming"; - DataConverterPotionId.potions[77] = "minecraft:long_water_breathing"; - DataConverterPotionId.potions[78] = "minecraft:long_invisibility"; - DataConverterPotionId.potions[79] = null; - DataConverterPotionId.potions[80] = "minecraft:awkward"; - DataConverterPotionId.potions[81] = "minecraft:long_regeneration"; - DataConverterPotionId.potions[82] = "minecraft:long_swiftness"; - DataConverterPotionId.potions[83] = "minecraft:long_fire_resistance"; - DataConverterPotionId.potions[84] = "minecraft:long_poison"; - DataConverterPotionId.potions[85] = "minecraft:healing"; - DataConverterPotionId.potions[86] = "minecraft:long_night_vision"; - DataConverterPotionId.potions[87] = null; - DataConverterPotionId.potions[88] = "minecraft:long_weakness"; - DataConverterPotionId.potions[89] = "minecraft:long_strength"; - DataConverterPotionId.potions[90] = "minecraft:long_slowness"; - DataConverterPotionId.potions[91] = "minecraft:long_leaping"; - DataConverterPotionId.potions[92] = "minecraft:harming"; - DataConverterPotionId.potions[93] = "minecraft:long_water_breathing"; - DataConverterPotionId.potions[94] = "minecraft:long_invisibility"; - DataConverterPotionId.potions[95] = null; - DataConverterPotionId.potions[96] = "minecraft:thick"; - DataConverterPotionId.potions[97] = "minecraft:regeneration"; - DataConverterPotionId.potions[98] = "minecraft:swiftness"; - DataConverterPotionId.potions[99] = "minecraft:long_fire_resistance"; - DataConverterPotionId.potions[100] = "minecraft:poison"; - DataConverterPotionId.potions[101] = "minecraft:strong_healing"; - DataConverterPotionId.potions[102] = "minecraft:long_night_vision"; - DataConverterPotionId.potions[103] = null; - DataConverterPotionId.potions[104] = "minecraft:long_weakness"; - DataConverterPotionId.potions[105] = "minecraft:strength"; - DataConverterPotionId.potions[106] = "minecraft:long_slowness"; - DataConverterPotionId.potions[107] = "minecraft:leaping"; - DataConverterPotionId.potions[108] = "minecraft:strong_harming"; - DataConverterPotionId.potions[109] = "minecraft:long_water_breathing"; - DataConverterPotionId.potions[110] = "minecraft:long_invisibility"; - DataConverterPotionId.potions[111] = null; - DataConverterPotionId.potions[112] = null; - DataConverterPotionId.potions[113] = "minecraft:regeneration"; - DataConverterPotionId.potions[114] = "minecraft:swiftness"; - DataConverterPotionId.potions[115] = "minecraft:long_fire_resistance"; - DataConverterPotionId.potions[116] = "minecraft:poison"; - DataConverterPotionId.potions[117] = "minecraft:strong_healing"; - DataConverterPotionId.potions[118] = "minecraft:long_night_vision"; - DataConverterPotionId.potions[119] = null; - DataConverterPotionId.potions[120] = "minecraft:long_weakness"; - DataConverterPotionId.potions[121] = "minecraft:strength"; - DataConverterPotionId.potions[122] = "minecraft:long_slowness"; - DataConverterPotionId.potions[123] = "minecraft:leaping"; - DataConverterPotionId.potions[124] = "minecraft:strong_harming"; - DataConverterPotionId.potions[125] = "minecraft:long_water_breathing"; - DataConverterPotionId.potions[126] = "minecraft:long_invisibility"; - DataConverterPotionId.potions[127] = null; - } - } - - private static class DataConverterSpawnEgg implements DataConverter { - - private static final String[] eggs = new String[256]; - - DataConverterSpawnEgg() { - } - - public int getDataVersion() { - return 105; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:spawn_egg".equals(cmp.getString("id"))) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("EntityTag"); - short short0 = cmp.getShort("Damage"); - - if (!nbttagcompound2.contains("id", 8)) { - String s = DataConverterSpawnEgg.eggs[short0 & 255]; - - if (s != null) { - nbttagcompound2.putString("id", s); - nbttagcompound1.put("EntityTag", nbttagcompound2); - cmp.put("tag", nbttagcompound1); - } - } - - if (short0 != 0) { - cmp.putShort("Damage", (short) 0); - } - } - - return cmp; - } - - static { - - DataConverterSpawnEgg.eggs[1] = "Item"; - DataConverterSpawnEgg.eggs[2] = "XPOrb"; - DataConverterSpawnEgg.eggs[7] = "ThrownEgg"; - DataConverterSpawnEgg.eggs[8] = "LeashKnot"; - DataConverterSpawnEgg.eggs[9] = "Painting"; - DataConverterSpawnEgg.eggs[10] = "Arrow"; - DataConverterSpawnEgg.eggs[11] = "Snowball"; - DataConverterSpawnEgg.eggs[12] = "Fireball"; - DataConverterSpawnEgg.eggs[13] = "SmallFireball"; - DataConverterSpawnEgg.eggs[14] = "ThrownEnderpearl"; - DataConverterSpawnEgg.eggs[15] = "EyeOfEnderSignal"; - DataConverterSpawnEgg.eggs[16] = "ThrownPotion"; - DataConverterSpawnEgg.eggs[17] = "ThrownExpBottle"; - DataConverterSpawnEgg.eggs[18] = "ItemFrame"; - DataConverterSpawnEgg.eggs[19] = "WitherSkull"; - DataConverterSpawnEgg.eggs[20] = "PrimedTnt"; - DataConverterSpawnEgg.eggs[21] = "FallingSand"; - DataConverterSpawnEgg.eggs[22] = "FireworksRocketEntity"; - DataConverterSpawnEgg.eggs[23] = "TippedArrow"; - DataConverterSpawnEgg.eggs[24] = "SpectralArrow"; - DataConverterSpawnEgg.eggs[25] = "ShulkerBullet"; - DataConverterSpawnEgg.eggs[26] = "DragonFireball"; - DataConverterSpawnEgg.eggs[30] = "ArmorStand"; - DataConverterSpawnEgg.eggs[41] = "Boat"; - DataConverterSpawnEgg.eggs[42] = "MinecartRideable"; - DataConverterSpawnEgg.eggs[43] = "MinecartChest"; - DataConverterSpawnEgg.eggs[44] = "MinecartFurnace"; - DataConverterSpawnEgg.eggs[45] = "MinecartTNT"; - DataConverterSpawnEgg.eggs[46] = "MinecartHopper"; - DataConverterSpawnEgg.eggs[47] = "MinecartSpawner"; - DataConverterSpawnEgg.eggs[40] = "MinecartCommandBlock"; - DataConverterSpawnEgg.eggs[48] = "Mob"; - DataConverterSpawnEgg.eggs[49] = "Monster"; - DataConverterSpawnEgg.eggs[50] = "Creeper"; - DataConverterSpawnEgg.eggs[51] = "Skeleton"; - DataConverterSpawnEgg.eggs[52] = "Spider"; - DataConverterSpawnEgg.eggs[53] = "Giant"; - DataConverterSpawnEgg.eggs[54] = "Zombie"; - DataConverterSpawnEgg.eggs[55] = "Slime"; - DataConverterSpawnEgg.eggs[56] = "Ghast"; - DataConverterSpawnEgg.eggs[57] = "PigZombie"; - DataConverterSpawnEgg.eggs[58] = "Enderman"; - DataConverterSpawnEgg.eggs[59] = "CaveSpider"; - DataConverterSpawnEgg.eggs[60] = "Silverfish"; - DataConverterSpawnEgg.eggs[61] = "Blaze"; - DataConverterSpawnEgg.eggs[62] = "LavaSlime"; - DataConverterSpawnEgg.eggs[63] = "EnderDragon"; - DataConverterSpawnEgg.eggs[64] = "WitherBoss"; - DataConverterSpawnEgg.eggs[65] = "Bat"; - DataConverterSpawnEgg.eggs[66] = "Witch"; - DataConverterSpawnEgg.eggs[67] = "Endermite"; - DataConverterSpawnEgg.eggs[68] = "Guardian"; - DataConverterSpawnEgg.eggs[69] = "Shulker"; - DataConverterSpawnEgg.eggs[90] = "Pig"; - DataConverterSpawnEgg.eggs[91] = "Sheep"; - DataConverterSpawnEgg.eggs[92] = "Cow"; - DataConverterSpawnEgg.eggs[93] = "Chicken"; - DataConverterSpawnEgg.eggs[94] = "Squid"; - DataConverterSpawnEgg.eggs[95] = "Wolf"; - DataConverterSpawnEgg.eggs[96] = "MushroomCow"; - DataConverterSpawnEgg.eggs[97] = "SnowMan"; - DataConverterSpawnEgg.eggs[98] = "Ozelot"; - DataConverterSpawnEgg.eggs[99] = "VillagerGolem"; - DataConverterSpawnEgg.eggs[100] = "EntityHorse"; - DataConverterSpawnEgg.eggs[101] = "Rabbit"; - DataConverterSpawnEgg.eggs[120] = "Villager"; - DataConverterSpawnEgg.eggs[200] = "EnderCrystal"; - } - } - - private static class DataConverterMinecart implements DataConverter { - - private static final List a = Lists.newArrayList("MinecartRideable", "MinecartChest", "MinecartFurnace", "MinecartTNT", "MinecartSpawner", "MinecartHopper", "MinecartCommandBlock"); - - DataConverterMinecart() { - } - - public int getDataVersion() { - return 106; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Minecart".equals(cmp.getString("id"))) { - String s = "MinecartRideable"; - int i = cmp.getInt("Type"); - - if (i > 0 && i < DataConverterMinecart.a.size()) { - s = DataConverterMinecart.a.get(i); - } - - cmp.putString("id", s); - cmp.remove("Type"); - } - - return cmp; - } - } - - private static class DataConverterMobSpawner implements DataConverter { - - DataConverterMobSpawner() { - } - - public int getDataVersion() { - return 107; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (!"MobSpawner".equals(cmp.getString("id"))) { - return cmp; - } else { - if (cmp.contains("EntityId", 8)) { - String s = cmp.getString("EntityId"); - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("SpawnData"); - - nbttagcompound1.putString("id", s.isEmpty() ? "Pig" : s); - cmp.put("SpawnData", nbttagcompound1); - cmp.remove("EntityId"); - } - - if (cmp.contains("SpawnPotentials", 9)) { - net.minecraft.nbt.ListTag nbttaglist = cmp.getList("SpawnPotentials", 10); - - for (int i = 0; i < nbttaglist.size(); ++i) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttaglist.getCompound(i); - - if (nbttagcompound2.contains("Type", 8)) { - net.minecraft.nbt.CompoundTag nbttagcompound3 = nbttagcompound2.getCompound("Properties"); - - nbttagcompound3.putString("id", nbttagcompound2.getString("Type")); - nbttagcompound2.put("Entity", nbttagcompound3); - nbttagcompound2.remove("Type"); - nbttagcompound2.remove("Properties"); - } - } - } - - return cmp; - } - } - } - - private static class DataConverterUUID implements DataConverter { - - DataConverterUUID() { - } - - public int getDataVersion() { - return 108; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (cmp.contains("UUID", 8)) { - cmp.putUUID("UUID", UUID.fromString(cmp.getString("UUID"))); - } - - return cmp; - } - } - - private static class DataConverterHealth implements DataConverter { - - private static final Set a = Sets.newHashSet("ArmorStand", "Bat", "Blaze", "CaveSpider", "Chicken", "Cow", "Creeper", "EnderDragon", "Enderman", "Endermite", "EntityHorse", "Ghast", "Giant", "Guardian", "LavaSlime", "MushroomCow", "Ozelot", "Pig", "PigZombie", "Rabbit", "Sheep", "Shulker", "Silverfish", "Skeleton", "Slime", "SnowMan", "Spider", "Squid", "Villager", "VillagerGolem", "Witch", "WitherBoss", "Wolf", "Zombie"); - - DataConverterHealth() { - } - - public int getDataVersion() { - return 109; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (DataConverterHealth.a.contains(cmp.getString("id"))) { - float f; - - if (cmp.contains("HealF", 99)) { - f = cmp.getFloat("HealF"); - cmp.remove("HealF"); - } else { - if (!cmp.contains("Health", 99)) { - return cmp; - } - - f = cmp.getFloat("Health"); - } - - cmp.putFloat("Health", f); - } - - return cmp; - } - } - - private static class DataConverterSaddle implements DataConverter { - - DataConverterSaddle() { - } - - public int getDataVersion() { - return 110; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("EntityHorse".equals(cmp.getString("id")) && !cmp.contains("SaddleItem", 10) && cmp.getBoolean("Saddle")) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = new net.minecraft.nbt.CompoundTag(); - - nbttagcompound1.putString("id", "minecraft:saddle"); - nbttagcompound1.putByte("Count", (byte) 1); - nbttagcompound1.putShort("Damage", (short) 0); - cmp.put("SaddleItem", nbttagcompound1); - cmp.remove("Saddle"); - } - - return cmp; - } - } - - private static class DataConverterHanging implements DataConverter { - - DataConverterHanging() { - } - - public int getDataVersion() { - return 111; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = cmp.getString("id"); - boolean flag = "Painting".equals(s); - boolean flag1 = "ItemFrame".equals(s); - - if ((flag || flag1) && !cmp.contains("Facing", 99)) { - Direction enumdirection; - - if (cmp.contains("Direction", 99)) { - enumdirection = Direction.from2DDataValue(cmp.getByte("Direction")); - cmp.putInt("TileX", cmp.getInt("TileX") + enumdirection.getStepX()); - cmp.putInt("TileY", cmp.getInt("TileY") + enumdirection.getStepY()); - cmp.putInt("TileZ", cmp.getInt("TileZ") + enumdirection.getStepZ()); - cmp.remove("Direction"); - if (flag1 && cmp.contains("ItemRotation", 99)) { - cmp.putByte("ItemRotation", (byte) (cmp.getByte("ItemRotation") * 2)); - } - } else { - enumdirection = Direction.from2DDataValue(cmp.getByte("Dir")); - cmp.remove("Dir"); - } - - cmp.putByte("Facing", (byte) enumdirection.get2DDataValue()); - } - - return cmp; - } - } - - private static class DataConverterDropChances implements DataConverter { - - DataConverterDropChances() { - } - - public int getDataVersion() { - return 113; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - net.minecraft.nbt.ListTag nbttaglist; - - if (cmp.contains("HandDropChances", 9)) { - nbttaglist = cmp.getList("HandDropChances", 5); - if (nbttaglist.size() == 2 && nbttaglist.getFloat(0) == 0.0F && nbttaglist.getFloat(1) == 0.0F) { - cmp.remove("HandDropChances"); - } - } - - if (cmp.contains("ArmorDropChances", 9)) { - nbttaglist = cmp.getList("ArmorDropChances", 5); - if (nbttaglist.size() == 4 && nbttaglist.getFloat(0) == 0.0F && nbttaglist.getFloat(1) == 0.0F && nbttaglist.getFloat(2) == 0.0F && nbttaglist.getFloat(3) == 0.0F) { - cmp.remove("ArmorDropChances"); - } - } - - return cmp; - } - } - - private static class DataConverterRiding implements DataConverter { - - DataConverterRiding() { - } - - public int getDataVersion() { - return 135; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - while (cmp.contains("Riding", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = this.b(cmp); - - this.convert(cmp, nbttagcompound1); - cmp = nbttagcompound1; - } - - return cmp; - } - - protected void convert(net.minecraft.nbt.CompoundTag nbttagcompound, net.minecraft.nbt.CompoundTag nbttagcompound1) { - net.minecraft.nbt.ListTag nbttaglist = new net.minecraft.nbt.ListTag(); - - nbttaglist.add(nbttagcompound); - nbttagcompound1.put("Passengers", nbttaglist); - } - - protected net.minecraft.nbt.CompoundTag b(net.minecraft.nbt.CompoundTag nbttagcompound) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = nbttagcompound.getCompound("Riding"); - - nbttagcompound.remove("Riding"); - return nbttagcompound1; - } - } - - private static class DataConverterBook implements DataConverter { - - DataConverterBook() { - } - - public int getDataVersion() { - return 165; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:written_book".equals(cmp.getString("id"))) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("pages", 9)) { - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound1.getList("pages", 8); - - for (int i = 0; i < nbttaglist.size(); ++i) { - String s = nbttaglist.getString(i); - Component object = null; - - if (!"null".equals(s) && !StringUtil.isNullOrEmpty(s)) { - if ((s.charAt(0) != 34 || s.charAt(s.length() - 1) != 34) && (s.charAt(0) != 123 || s.charAt(s.length() - 1) != 125)) { - object = Component.literal(s); - } else { - try { - object = GsonHelper.fromJson(DataConverterSignText.a, s, Component.class, true); - if (object == null) { - object = Component.literal(""); - } - } catch (JsonParseException jsonparseexception) { - ; - } - - if (object == null) { - try { - object = Component.Serializer.fromJson(s); - } catch (JsonParseException jsonparseexception1) { - ; - } - } - - if (object == null) { - try { - object = Component.Serializer.fromJsonLenient(s); - } catch (JsonParseException jsonparseexception2) { - ; - } - } - - if (object == null) { - object = Component.literal(s); - } - } - } else { - object = Component.literal(""); - } - - nbttaglist.set(i, net.minecraft.nbt.StringTag.valueOf(Component.Serializer.toJson(object))); - } - - nbttagcompound1.put("pages", nbttaglist); - } - } - - return cmp; - } - } - - private static class DataConverterCookedFish implements DataConverter { - - private static final ResourceLocation a = new ResourceLocation("cooked_fished"); - - DataConverterCookedFish() { - } - - public int getDataVersion() { - return 502; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (cmp.contains("id", 8) && DataConverterCookedFish.a.equals(new ResourceLocation(cmp.getString("id")))) { - cmp.putString("id", "minecraft:cooked_fish"); - } - - return cmp; - } - } - - private static class DataConverterZombie implements DataConverter { - - private static final Random a = new Random(); - - DataConverterZombie() { - } - - public int getDataVersion() { - return 502; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Zombie".equals(cmp.getString("id")) && cmp.getBoolean("IsVillager")) { - if (!cmp.contains("ZombieType", 99)) { - int i = -1; - - if (cmp.contains("VillagerProfession", 99)) { - try { - i = this.convert(cmp.getInt("VillagerProfession")); - } catch (RuntimeException runtimeexception) { - ; - } - } - - if (i == -1) { - i = this.convert(DataConverterZombie.a.nextInt(6)); - } - - cmp.putInt("ZombieType", i); - } - - cmp.remove("IsVillager"); - } - - return cmp; - } - - private int convert(int i) { - return i >= 0 && i < 6 ? i : -1; - } - } - - private static class DataConverterVBO implements DataConverter { - - DataConverterVBO() { - } - - public int getDataVersion() { - return 505; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - cmp.putString("useVbo", "true"); - return cmp; - } - } - - private static class DataConverterGuardian implements DataConverter { - - DataConverterGuardian() { - } - - public int getDataVersion() { - return 700; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Guardian".equals(cmp.getString("id"))) { - if (cmp.getBoolean("Elder")) { - cmp.putString("id", "ElderGuardian"); - } - - cmp.remove("Elder"); - } - - return cmp; - } - } - - private static class DataConverterSkeleton implements DataConverter { - - DataConverterSkeleton() { - } - - public int getDataVersion() { - return 701; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = cmp.getString("id"); - - if ("Skeleton".equals(s)) { - int i = cmp.getInt("SkeletonType"); - - if (i == 1) { - cmp.putString("id", "WitherSkeleton"); - } else if (i == 2) { - cmp.putString("id", "Stray"); - } - - cmp.remove("SkeletonType"); - } - - return cmp; - } - } - - private static class DataConverterZombieType implements DataConverter { - - DataConverterZombieType() { - } - - public int getDataVersion() { - return 702; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Zombie".equals(cmp.getString("id"))) { - int i = cmp.getInt("ZombieType"); - - switch (i) { - case 0: - default: - break; - - case 1: - case 2: - case 3: - case 4: - case 5: - cmp.putString("id", "ZombieVillager"); - cmp.putInt("Profession", i - 1); - break; - - case 6: - cmp.putString("id", "Husk"); - } - - cmp.remove("ZombieType"); - } - - return cmp; - } - } - - private static class DataConverterHorse implements DataConverter { - - DataConverterHorse() { - } - - public int getDataVersion() { - return 703; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("EntityHorse".equals(cmp.getString("id"))) { - int i = cmp.getInt("Type"); - - switch (i) { - case 0: - default: - cmp.putString("id", "Horse"); - break; - - case 1: - cmp.putString("id", "Donkey"); - break; - - case 2: - cmp.putString("id", "Mule"); - break; - - case 3: - cmp.putString("id", "ZombieHorse"); - break; - - case 4: - cmp.putString("id", "SkeletonHorse"); - } - - cmp.remove("Type"); - } - - return cmp; - } - } - - private static class DataConverterTileEntity implements DataConverter { - - private static final Map a = Maps.newHashMap(); - - DataConverterTileEntity() { - } - - public int getDataVersion() { - return 704; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = DataConverterTileEntity.a.get(cmp.getString("id")); - - if (s != null) { - cmp.putString("id", s); - } - - return cmp; - } - - static { - DataConverterTileEntity.a.put("Airportal", "minecraft:end_portal"); - DataConverterTileEntity.a.put("Banner", "minecraft:banner"); - DataConverterTileEntity.a.put("Beacon", "minecraft:beacon"); - DataConverterTileEntity.a.put("Cauldron", "minecraft:brewing_stand"); - DataConverterTileEntity.a.put("Chest", "minecraft:chest"); - DataConverterTileEntity.a.put("Comparator", "minecraft:comparator"); - DataConverterTileEntity.a.put("Control", "minecraft:command_block"); - DataConverterTileEntity.a.put("DLDetector", "minecraft:daylight_detector"); - DataConverterTileEntity.a.put("Dropper", "minecraft:dropper"); - DataConverterTileEntity.a.put("EnchantTable", "minecraft:enchanting_table"); - DataConverterTileEntity.a.put("EndGateway", "minecraft:end_gateway"); - DataConverterTileEntity.a.put("EnderChest", "minecraft:ender_chest"); - DataConverterTileEntity.a.put("FlowerPot", "minecraft:flower_pot"); - DataConverterTileEntity.a.put("Furnace", "minecraft:furnace"); - DataConverterTileEntity.a.put("Hopper", "minecraft:hopper"); - DataConverterTileEntity.a.put("MobSpawner", "minecraft:mob_spawner"); - DataConverterTileEntity.a.put("Music", "minecraft:noteblock"); - DataConverterTileEntity.a.put("Piston", "minecraft:piston"); - DataConverterTileEntity.a.put("RecordPlayer", "minecraft:jukebox"); - DataConverterTileEntity.a.put("Sign", "minecraft:sign"); - DataConverterTileEntity.a.put("Skull", "minecraft:skull"); - DataConverterTileEntity.a.put("Structure", "minecraft:structure_block"); - DataConverterTileEntity.a.put("Trap", "minecraft:dispenser"); - } - } - - private static class DataConverterEntity implements DataConverter { - - private static final Map a = Maps.newHashMap(); - - DataConverterEntity() { - } - - public int getDataVersion() { - return 704; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = DataConverterEntity.a.get(cmp.getString("id")); - - if (s != null) { - cmp.putString("id", s); - } - - return cmp; - } - - static { - DataConverterEntity.a.put("AreaEffectCloud", "minecraft:area_effect_cloud"); - DataConverterEntity.a.put("ArmorStand", "minecraft:armor_stand"); - DataConverterEntity.a.put("Arrow", "minecraft:arrow"); - DataConverterEntity.a.put("Bat", "minecraft:bat"); - DataConverterEntity.a.put("Blaze", "minecraft:blaze"); - DataConverterEntity.a.put("Boat", "minecraft:boat"); - DataConverterEntity.a.put("CaveSpider", "minecraft:cave_spider"); - DataConverterEntity.a.put("Chicken", "minecraft:chicken"); - DataConverterEntity.a.put("Cow", "minecraft:cow"); - DataConverterEntity.a.put("Creeper", "minecraft:creeper"); - DataConverterEntity.a.put("Donkey", "minecraft:donkey"); - DataConverterEntity.a.put("DragonFireball", "minecraft:dragon_fireball"); - DataConverterEntity.a.put("ElderGuardian", "minecraft:elder_guardian"); - DataConverterEntity.a.put("EnderCrystal", "minecraft:ender_crystal"); - DataConverterEntity.a.put("EnderDragon", "minecraft:ender_dragon"); - DataConverterEntity.a.put("Enderman", "minecraft:enderman"); - DataConverterEntity.a.put("Endermite", "minecraft:endermite"); - DataConverterEntity.a.put("EyeOfEnderSignal", "minecraft:eye_of_ender_signal"); - DataConverterEntity.a.put("FallingSand", "minecraft:falling_block"); - DataConverterEntity.a.put("Fireball", "minecraft:fireball"); - DataConverterEntity.a.put("FireworksRocketEntity", "minecraft:fireworks_rocket"); - DataConverterEntity.a.put("Ghast", "minecraft:ghast"); - DataConverterEntity.a.put("Giant", "minecraft:giant"); - DataConverterEntity.a.put("Guardian", "minecraft:guardian"); - DataConverterEntity.a.put("Horse", "minecraft:horse"); - DataConverterEntity.a.put("Husk", "minecraft:husk"); - DataConverterEntity.a.put("Item", "minecraft:item"); - DataConverterEntity.a.put("ItemFrame", "minecraft:item_frame"); - DataConverterEntity.a.put("LavaSlime", "minecraft:magma_cube"); - DataConverterEntity.a.put("LeashKnot", "minecraft:leash_knot"); - DataConverterEntity.a.put("MinecartChest", "minecraft:chest_minecart"); - DataConverterEntity.a.put("MinecartCommandBlock", "minecraft:commandblock_minecart"); - DataConverterEntity.a.put("MinecartFurnace", "minecraft:furnace_minecart"); - DataConverterEntity.a.put("MinecartHopper", "minecraft:hopper_minecart"); - DataConverterEntity.a.put("MinecartRideable", "minecraft:minecart"); - DataConverterEntity.a.put("MinecartSpawner", "minecraft:spawner_minecart"); - DataConverterEntity.a.put("MinecartTNT", "minecraft:tnt_minecart"); - DataConverterEntity.a.put("Mule", "minecraft:mule"); - DataConverterEntity.a.put("MushroomCow", "minecraft:mooshroom"); - DataConverterEntity.a.put("Ozelot", "minecraft:ocelot"); - DataConverterEntity.a.put("Painting", "minecraft:painting"); - DataConverterEntity.a.put("Pig", "minecraft:pig"); - DataConverterEntity.a.put("PigZombie", "minecraft:zombie_pigman"); - DataConverterEntity.a.put("PolarBear", "minecraft:polar_bear"); - DataConverterEntity.a.put("PrimedTnt", "minecraft:tnt"); - DataConverterEntity.a.put("Rabbit", "minecraft:rabbit"); - DataConverterEntity.a.put("Sheep", "minecraft:sheep"); - DataConverterEntity.a.put("Shulker", "minecraft:shulker"); - DataConverterEntity.a.put("ShulkerBullet", "minecraft:shulker_bullet"); - DataConverterEntity.a.put("Silverfish", "minecraft:silverfish"); - DataConverterEntity.a.put("Skeleton", "minecraft:skeleton"); - DataConverterEntity.a.put("SkeletonHorse", "minecraft:skeleton_horse"); - DataConverterEntity.a.put("Slime", "minecraft:slime"); - DataConverterEntity.a.put("SmallFireball", "minecraft:small_fireball"); - DataConverterEntity.a.put("SnowMan", "minecraft:snowman"); - DataConverterEntity.a.put("Snowball", "minecraft:snowball"); - DataConverterEntity.a.put("SpectralArrow", "minecraft:spectral_arrow"); - DataConverterEntity.a.put("Spider", "minecraft:spider"); - DataConverterEntity.a.put("Squid", "minecraft:squid"); - DataConverterEntity.a.put("Stray", "minecraft:stray"); - DataConverterEntity.a.put("ThrownEgg", "minecraft:egg"); - DataConverterEntity.a.put("ThrownEnderpearl", "minecraft:ender_pearl"); - DataConverterEntity.a.put("ThrownExpBottle", "minecraft:xp_bottle"); - DataConverterEntity.a.put("ThrownPotion", "minecraft:potion"); - DataConverterEntity.a.put("Villager", "minecraft:villager"); - DataConverterEntity.a.put("VillagerGolem", "minecraft:villager_golem"); - DataConverterEntity.a.put("Witch", "minecraft:witch"); - DataConverterEntity.a.put("WitherBoss", "minecraft:wither"); - DataConverterEntity.a.put("WitherSkeleton", "minecraft:wither_skeleton"); - DataConverterEntity.a.put("WitherSkull", "minecraft:wither_skull"); - DataConverterEntity.a.put("Wolf", "minecraft:wolf"); - DataConverterEntity.a.put("XPOrb", "minecraft:xp_orb"); - DataConverterEntity.a.put("Zombie", "minecraft:zombie"); - DataConverterEntity.a.put("ZombieHorse", "minecraft:zombie_horse"); - DataConverterEntity.a.put("ZombieVillager", "minecraft:zombie_villager"); - } - } - - private static class DataConverterPotionWater implements DataConverter { - - DataConverterPotionWater() { - } - - public int getDataVersion() { - return 806; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = cmp.getString("id"); - - if ("minecraft:potion".equals(s) || "minecraft:splash_potion".equals(s) || "minecraft:lingering_potion".equals(s) || "minecraft:tipped_arrow".equals(s)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (!nbttagcompound1.contains("Potion", 8)) { - nbttagcompound1.putString("Potion", "minecraft:water"); - } - - if (!cmp.contains("tag", 10)) { - cmp.put("tag", nbttagcompound1); - } - } - - return cmp; - } - } - - private static class DataConverterShulker implements DataConverter { - - DataConverterShulker() { - } - - public int getDataVersion() { - return 808; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:shulker".equals(cmp.getString("id")) && !cmp.contains("Color", 99)) { - cmp.putByte("Color", (byte) 10); - } - - return cmp; - } - } - - private static class DataConverterShulkerBoxItem implements DataConverter { - - public static final String[] a = new String[] { "minecraft:white_shulker_box", "minecraft:orange_shulker_box", "minecraft:magenta_shulker_box", "minecraft:light_blue_shulker_box", "minecraft:yellow_shulker_box", "minecraft:lime_shulker_box", "minecraft:pink_shulker_box", "minecraft:gray_shulker_box", "minecraft:silver_shulker_box", "minecraft:cyan_shulker_box", "minecraft:purple_shulker_box", "minecraft:blue_shulker_box", "minecraft:brown_shulker_box", "minecraft:green_shulker_box", "minecraft:red_shulker_box", "minecraft:black_shulker_box" }; - - DataConverterShulkerBoxItem() { - } - - public int getDataVersion() { - return 813; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:shulker_box".equals(cmp.getString("id")) && cmp.contains("tag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("BlockEntityTag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag"); - - if (nbttagcompound2.getList("Items", 10).isEmpty()) { - nbttagcompound2.remove("Items"); - } - - int i = nbttagcompound2.getInt("Color"); - - nbttagcompound2.remove("Color"); - if (nbttagcompound2.isEmpty()) { - nbttagcompound1.remove("BlockEntityTag"); - } - - if (nbttagcompound1.isEmpty()) { - cmp.remove("tag"); - } - - cmp.putString("id", DataConverterShulkerBoxItem.a[i % 16]); - } - } - - return cmp; - } - } - - private static class DataConverterShulkerBoxBlock implements DataConverter { - - DataConverterShulkerBoxBlock() { - } - - public int getDataVersion() { - return 813; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:shulker".equals(cmp.getString("id"))) { - cmp.remove("Color"); - } - - return cmp; - } - } - - private static class DataConverterLang implements DataConverter { - - DataConverterLang() { - } - - public int getDataVersion() { - return 816; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (cmp.contains("lang", 8)) { - cmp.putString("lang", cmp.getString("lang").toLowerCase(Locale.ROOT)); - } - - return cmp; - } - } - - private static class DataConverterTotem implements DataConverter { - - DataConverterTotem() { - } - - public int getDataVersion() { - return 820; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:totem".equals(cmp.getString("id"))) { - cmp.putString("id", "minecraft:totem_of_undying"); - } - - return cmp; - } - } - - private static class DataConverterBedBlock implements DataConverter { - - private static final Logger a = LogManager.getLogger(PaperweightDataConverters.class); - - DataConverterBedBlock() { - } - - public int getDataVersion() { - return 1125; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - try { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("Level"); - int i = nbttagcompound1.getInt("xPos"); - int j = nbttagcompound1.getInt("zPos"); - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound1.getList("TileEntities", 10); - net.minecraft.nbt.ListTag nbttaglist1 = nbttagcompound1.getList("Sections", 10); - - for (int k = 0; k < nbttaglist1.size(); ++k) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttaglist1.getCompound(k); - byte b0 = nbttagcompound2.getByte("Y"); - byte[] abyte = nbttagcompound2.getByteArray("Blocks"); - - for (int l = 0; l < abyte.length; ++l) { - if (416 == (abyte[l] & 255) << 4) { - int i1 = l & 15; - int j1 = l >> 8 & 15; - int k1 = l >> 4 & 15; - net.minecraft.nbt.CompoundTag nbttagcompound3 = new net.minecraft.nbt.CompoundTag(); - - nbttagcompound3.putString("id", "bed"); - nbttagcompound3.putInt("x", i1 + (i << 4)); - nbttagcompound3.putInt("y", j1 + (b0 << 4)); - nbttagcompound3.putInt("z", k1 + (j << 4)); - nbttaglist.add(nbttagcompound3); - } - } - } - } catch (Exception exception) { - DataConverterBedBlock.a.warn("Unable to datafix Bed blocks, level format may be missing tags."); - } - - return cmp; - } - } - - private static class DataConverterBedItem implements DataConverter { - - DataConverterBedItem() { - } - - public int getDataVersion() { - return 1125; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:bed".equals(cmp.getString("id")) && cmp.getShort("Damage") == 0) { - cmp.putShort("Damage", (short) DyeColor.RED.getId()); - } - - return cmp; - } - } - - private static class DataConverterSignText implements DataConverter { - - public static final Gson a = new GsonBuilder().registerTypeAdapter(Component.class, new JsonDeserializer() { - MutableComponent a(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { - if (jsonelement.isJsonPrimitive()) { - return Component.literal(jsonelement.getAsString()); - } else if (jsonelement.isJsonArray()) { - JsonArray jsonarray = jsonelement.getAsJsonArray(); - MutableComponent ichatbasecomponent = null; - Iterator iterator = jsonarray.iterator(); - - while (iterator.hasNext()) { - JsonElement jsonelement1 = (JsonElement) iterator.next(); - MutableComponent ichatbasecomponent1 = this.a(jsonelement1, jsonelement1.getClass(), jsondeserializationcontext); - - if (ichatbasecomponent == null) { - ichatbasecomponent = ichatbasecomponent1; - } else { - ichatbasecomponent.append(ichatbasecomponent1); - } - } - - return ichatbasecomponent; - } else { - throw new JsonParseException("Don't know how to turn " + jsonelement + " into a Component"); - } - } - - public Object deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { - return this.a(jsonelement, type, jsondeserializationcontext); - } - }).create(); - - DataConverterSignText() { - } - - public int getDataVersion() { - return 101; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Sign".equals(cmp.getString("id"))) { - this.convert(cmp, "Text1"); - this.convert(cmp, "Text2"); - this.convert(cmp, "Text3"); - this.convert(cmp, "Text4"); - } - - return cmp; - } - - private void convert(net.minecraft.nbt.CompoundTag nbttagcompound, String s) { - String s1 = nbttagcompound.getString(s); - Component object = null; - - if (!"null".equals(s1) && !StringUtil.isNullOrEmpty(s1)) { - if ((s1.charAt(0) != 34 || s1.charAt(s1.length() - 1) != 34) && (s1.charAt(0) != 123 || s1.charAt(s1.length() - 1) != 125)) { - object = Component.literal(s1); - } else { - try { - object = GsonHelper.fromJson(DataConverterSignText.a, s1, Component.class, true); - if (object == null) { - object = Component.literal(""); - } - } catch (JsonParseException jsonparseexception) { - ; - } - - if (object == null) { - try { - object = Component.Serializer.fromJson(s1); - } catch (JsonParseException jsonparseexception1) { - ; - } - } - - if (object == null) { - try { - object = Component.Serializer.fromJsonLenient(s1); - } catch (JsonParseException jsonparseexception2) { - ; - } - } - - if (object == null) { - object = Component.literal(s1); - } - } - } else { - object = Component.literal(""); - } - - nbttagcompound.putString(s, Component.Serializer.toJson(object)); - } - } - - private static class DataInspectorPlayerVehicle implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (cmp.contains("RootVehicle", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("RootVehicle"); - - if (nbttagcompound1.contains("Entity", 10)) { - convertCompound(LegacyType.ENTITY, nbttagcompound1, "Entity", sourceVer, targetVer); - } - } - - return cmp; - } - } - - private static class DataInspectorLevelPlayer implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (cmp.contains("Player", 10)) { - convertCompound(LegacyType.PLAYER, cmp, "Player", sourceVer, targetVer); - } - - return cmp; - } - } - - private static class DataInspectorStructure implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - net.minecraft.nbt.ListTag nbttaglist; - int j; - net.minecraft.nbt.CompoundTag nbttagcompound1; - - if (cmp.contains("entities", 9)) { - nbttaglist = cmp.getList("entities", 10); - - for (j = 0; j < nbttaglist.size(); ++j) { - nbttagcompound1 = (net.minecraft.nbt.CompoundTag) nbttaglist.get(j); - if (nbttagcompound1.contains("nbt", 10)) { - convertCompound(LegacyType.ENTITY, nbttagcompound1, "nbt", sourceVer, targetVer); - } - } - } - - if (cmp.contains("blocks", 9)) { - nbttaglist = cmp.getList("blocks", 10); - - for (j = 0; j < nbttaglist.size(); ++j) { - nbttagcompound1 = (net.minecraft.nbt.CompoundTag) nbttaglist.get(j); - if (nbttagcompound1.contains("nbt", 10)) { - convertCompound(LegacyType.BLOCK_ENTITY, nbttagcompound1, "nbt", sourceVer, targetVer); - } - } - } - - return cmp; - } - } - - private static class DataInspectorChunks implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (cmp.contains("Level", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("Level"); - net.minecraft.nbt.ListTag nbttaglist; - int j; - - if (nbttagcompound1.contains("Entities", 9)) { - nbttaglist = nbttagcompound1.getList("Entities", 10); - - for (j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set(j, convert(LegacyType.ENTITY, (net.minecraft.nbt.CompoundTag) nbttaglist.get(j), sourceVer, targetVer)); - } - } - - if (nbttagcompound1.contains("TileEntities", 9)) { - nbttaglist = nbttagcompound1.getList("TileEntities", 10); - - for (j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set(j, convert(LegacyType.BLOCK_ENTITY, (net.minecraft.nbt.CompoundTag) nbttaglist.get(j), sourceVer, targetVer)); - } - } - } - - return cmp; - } - } - - private static class DataInspectorEntityPassengers implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (cmp.contains("Passengers", 9)) { - net.minecraft.nbt.ListTag nbttaglist = cmp.getList("Passengers", 10); - - for (int j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set(j, convert(LegacyType.ENTITY, nbttaglist.getCompound(j), sourceVer, targetVer)); - } - } - - return cmp; - } - } - - private static class DataInspectorPlayer implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - convertItems(cmp, "Inventory", sourceVer, targetVer); - convertItems(cmp, "EnderItems", sourceVer, targetVer); - if (cmp.contains("ShoulderEntityLeft", 10)) { - convertCompound(LegacyType.ENTITY, cmp, "ShoulderEntityLeft", sourceVer, targetVer); - } - - if (cmp.contains("ShoulderEntityRight", 10)) { - convertCompound(LegacyType.ENTITY, cmp, "ShoulderEntityRight", sourceVer, targetVer); - } - - return cmp; - } - } - - private static class DataInspectorVillagers implements DataInspector { - ResourceLocation entityVillager = getKey("EntityVillager"); - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (entityVillager.equals(new ResourceLocation(cmp.getString("id"))) && cmp.contains("Offers", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("Offers"); - - if (nbttagcompound1.contains("Recipes", 9)) { - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound1.getList("Recipes", 10); - - for (int j = 0; j < nbttaglist.size(); ++j) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttaglist.getCompound(j); - - convertItem(nbttagcompound2, "buy", sourceVer, targetVer); - convertItem(nbttagcompound2, "buyB", sourceVer, targetVer); - convertItem(nbttagcompound2, "sell", sourceVer, targetVer); - nbttaglist.set(j, nbttagcompound2); - } - } - } - - return cmp; - } - } - - private static class DataInspectorMobSpawnerMinecart implements DataInspector { - ResourceLocation entityMinecartMobSpawner = getKey("EntityMinecartMobSpawner"); - ResourceLocation tileEntityMobSpawner = getKey("TileEntityMobSpawner"); - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - String s = cmp.getString("id"); - if (entityMinecartMobSpawner.equals(new ResourceLocation(s))) { - cmp.putString("id", tileEntityMobSpawner.toString()); - convert(LegacyType.BLOCK_ENTITY, cmp, sourceVer, targetVer); - cmp.putString("id", s); - } - - return cmp; - } - } - - private static class DataInspectorMobSpawnerMobs implements DataInspector { - ResourceLocation tileEntityMobSpawner = getKey("TileEntityMobSpawner"); - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (tileEntityMobSpawner.equals(new ResourceLocation(cmp.getString("id")))) { - if (cmp.contains("SpawnPotentials", 9)) { - net.minecraft.nbt.ListTag nbttaglist = cmp.getList("SpawnPotentials", 10); - - for (int j = 0; j < nbttaglist.size(); ++j) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = nbttaglist.getCompound(j); - - convertCompound(LegacyType.ENTITY, nbttagcompound1, "Entity", sourceVer, targetVer); - } - } - - convertCompound(LegacyType.ENTITY, cmp, "SpawnData", sourceVer, targetVer); - } - - return cmp; - } - } - - private static class DataInspectorCommandBlock implements DataInspector { - ResourceLocation tileEntityCommand = getKey("TileEntityCommand"); - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (tileEntityCommand.equals(new ResourceLocation(cmp.getString("id")))) { - cmp.putString("id", "Control"); - convert(LegacyType.BLOCK_ENTITY, cmp, sourceVer, targetVer); - cmp.putString("id", "MinecartCommandBlock"); - } - - return cmp; - } - } -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightFakePlayer.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightFakePlayer.java deleted file mode 100644 index ee7d82f09..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightFakePlayer.java +++ /dev/null @@ -1,93 +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.bukkit.adapter.ext.fawe.v1_19_R3; - -import com.mojang.authlib.GameProfile; -import net.minecraft.network.chat.Component; -import net.minecraft.network.protocol.game.ServerboundClientInformationPacket; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.stats.Stat; -import net.minecraft.world.MenuProvider; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.block.entity.SignBlockEntity; -import net.minecraft.world.phys.Vec3; -import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; - -import java.util.OptionalInt; -import java.util.UUID; - -class PaperweightFakePlayer extends ServerPlayer { - private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile(UUID.nameUUIDFromBytes("worldedit".getBytes()), "[WorldEdit]"); - private static final Vec3 ORIGIN = new Vec3(0.0D, 0.0D, 0.0D); - - PaperweightFakePlayer(ServerLevel world) { - super(world.getServer(), world, FAKE_WORLDEDIT_PROFILE); - } - - @Override - public Vec3 position() { - return ORIGIN; - } - - @Override - public void tick() { - } - - @Override - public void die(DamageSource damagesource) { - } - - @Override - public Entity changeDimension(ServerLevel worldserver, TeleportCause cause) { - return this; - } - - @Override - public OptionalInt openMenu(MenuProvider factory) { - return OptionalInt.empty(); - } - - @Override - public void updateOptions(ServerboundClientInformationPacket packet) { - } - - @Override - public void displayClientMessage(Component message, boolean actionBar) { - } - - @Override - public void awardStat(Stat stat, int amount) { - } - - @Override - public void awardStat(Stat stat) { - } - - @Override - public boolean isInvulnerableTo(DamageSource damageSource) { - return true; - } - - @Override - public void openTextEdit(SignBlockEntity sign) { - } -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightWorldNativeAccess.java deleted file mode 100644 index 424422ce6..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightWorldNativeAccess.java +++ /dev/null @@ -1,196 +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.bukkit.adapter.ext.fawe.v1_19_R3; - -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.internal.block.BlockStateIdAccess; -import com.sk89q.worldedit.internal.wna.WorldNativeAccess; -import com.sk89q.worldedit.util.SideEffect; -import com.sk89q.worldedit.util.SideEffectSet; -import com.sk89q.worldedit.world.block.BlockState; -import net.minecraft.core.BlockPos; -import net.minecraft.nbt.Tag; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.chunk.LevelChunk; -import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R3.block.data.CraftBlockData; -import org.bukkit.event.block.BlockPhysicsEvent; -import org.enginehub.linbus.tree.LinCompoundTag; - -import javax.annotation.Nullable; -import java.lang.ref.WeakReference; -import java.util.Objects; - -public class PaperweightWorldNativeAccess implements WorldNativeAccess { - private static final int UPDATE = 1; - private static final int NOTIFY = 2; - - private final PaperweightAdapter adapter; - private final WeakReference world; - private SideEffectSet sideEffectSet; - - public PaperweightWorldNativeAccess(PaperweightAdapter adapter, WeakReference world) { - this.adapter = adapter; - this.world = world; - } - - private ServerLevel getWorld() { - return Objects.requireNonNull(world.get(), "The reference to the world was lost"); - } - - @Override - public void setCurrentSideEffectSet(SideEffectSet sideEffectSet) { - this.sideEffectSet = sideEffectSet; - } - - @Override - public LevelChunk getChunk(int x, int z) { - return getWorld().getChunk(x, z); - } - - @Override - public net.minecraft.world.level.block.state.BlockState toNative(BlockState state) { - int stateId = BlockStateIdAccess.getBlockStateId(state); - return BlockStateIdAccess.isValidInternalId(stateId) - ? Block.stateById(stateId) - : ((CraftBlockData) BukkitAdapter.adapt(state)).getState(); - } - - @Override - public net.minecraft.world.level.block.state.BlockState getBlockState(LevelChunk chunk, BlockPos position) { - return chunk.getBlockState(position); - } - - @Nullable - @Override - public net.minecraft.world.level.block.state.BlockState setBlockState(LevelChunk chunk, BlockPos position, net.minecraft.world.level.block.state.BlockState state) { - return chunk.setBlockState(position, state, false, this.sideEffectSet.shouldApply(SideEffect.UPDATE)); - } - - @Override - public net.minecraft.world.level.block.state.BlockState getValidBlockForPosition(net.minecraft.world.level.block.state.BlockState block, BlockPos position) { - return Block.updateFromNeighbourShapes(block, getWorld(), position); - } - - @Override - public BlockPos getPosition(int x, int y, int z) { - return new BlockPos(x, y, z); - } - - @Override - public void updateLightingForBlock(BlockPos position) { - getWorld().getChunkSource().getLightEngine().checkBlock(position); - } - - @Override - public boolean updateTileEntity(BlockPos position, LinCompoundTag tag) { - // We will assume that the tile entity was created for us - BlockEntity tileEntity = getWorld().getBlockEntity(position); - if (tileEntity == null) { - return false; - } - Tag nativeTag = adapter.fromNative(new CompoundTag(tag)); - PaperweightAdapter.readTagIntoTileEntity((net.minecraft.nbt.CompoundTag) nativeTag, tileEntity); - return true; - } - - @Override - public void notifyBlockUpdate(LevelChunk chunk, BlockPos position, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { - if (chunk.getSections()[getWorld().getSectionIndex(position.getY())] != null) { - getWorld().sendBlockUpdated(position, oldState, newState, UPDATE | NOTIFY); - } - } - - @Override - public boolean isChunkTicking(LevelChunk chunk) { - return chunk.getFullStatus().isOrAfter(ChunkHolder.FullChunkStatus.TICKING); - } - - @Override - public void markBlockChanged(LevelChunk chunk, BlockPos position) { - if (chunk.getSections()[getWorld().getSectionIndex(position.getY())] != null) { - getWorld().getChunkSource().blockChanged(position); - } - } - - @Override - public void notifyNeighbors(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { - ServerLevel world = getWorld(); - if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { - world.updateNeighborsAt(pos, oldState.getBlock()); - } else { - // When we don't want events, manually run the physics without them. - Block block = oldState.getBlock(); - fireNeighborChanged(pos, world, block, pos.west()); - fireNeighborChanged(pos, world, block, pos.east()); - fireNeighborChanged(pos, world, block, pos.below()); - fireNeighborChanged(pos, world, block, pos.above()); - fireNeighborChanged(pos, world, block, pos.north()); - fireNeighborChanged(pos, world, block, pos.south()); - } - if (newState.hasAnalogOutputSignal()) { - world.updateNeighbourForOutputSignal(pos, newState.getBlock()); - } - } - - @Override - public void updateBlock(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { - ServerLevel world = getWorld(); - newState.onPlace(world, pos, oldState, false); - } - - // Not sure why neighborChanged is deprecated - @SuppressWarnings("deprecation") - private void fireNeighborChanged(BlockPos pos, ServerLevel world, Block block, BlockPos neighborPos) { - world.getBlockState(neighborPos).neighborChanged(world, neighborPos, block, pos, false); - } - - @Override - public void updateNeighbors(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState, int recursionLimit) { - ServerLevel world = getWorld(); - // a == updateNeighbors - // b == updateDiagonalNeighbors - oldState.updateIndirectNeighbourShapes(world, pos, NOTIFY, recursionLimit); - if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { - CraftWorld craftWorld = world.getWorld(); - BlockPhysicsEvent event = new BlockPhysicsEvent(craftWorld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()), CraftBlockData.fromData(newState)); - world.getCraftServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { - return; - } - } - newState.updateNeighbourShapes(world, pos, NOTIFY, recursionLimit); - newState.updateIndirectNeighbourShapes(world, pos, NOTIFY, recursionLimit); - } - - @Override - public void onBlockStateChange(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { - getWorld().onBlockStateChange(pos, oldState, newState); - } - - @Override - public void flush() { - - } -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightBlockMaterial.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightBlockMaterial.java deleted file mode 100644 index cbd1af53d..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightBlockMaterial.java +++ /dev/null @@ -1,189 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3; - -import com.google.common.base.Suppliers; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.util.ReflectionUtil; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.world.registry.BlockMaterial; -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.EmptyBlockGetter; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.EntityBlock; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.material.PushReaction; -import org.bukkit.craftbukkit.v1_19_R3.block.data.CraftBlockData; - -public class PaperweightBlockMaterial implements BlockMaterial { - - private final Block block; - private final BlockState blockState; - private final Material material; - private final boolean isTranslucent; - private final CraftBlockData craftBlockData; - private final org.bukkit.Material craftMaterial; - private final int opacity; - private final CompoundTag tile; - - public PaperweightBlockMaterial(Block block) { - this(block, block.defaultBlockState()); - } - - public PaperweightBlockMaterial(Block block, BlockState blockState) { - this.block = block; - this.blockState = blockState; - this.material = blockState.getMaterial(); - this.craftBlockData = CraftBlockData.fromData(blockState); - this.craftMaterial = craftBlockData.getMaterial(); - BlockBehaviour.Properties blockInfo = ReflectionUtil.getField(BlockBehaviour.class, block, - Refraction.pickName("properties", "aP")); - this.isTranslucent = !(boolean) ReflectionUtil.getField(BlockBehaviour.Properties.class, blockInfo, - Refraction.pickName("canOcclude", "n") - ); - opacity = blockState.getLightBlock(EmptyBlockGetter.INSTANCE, BlockPos.ZERO); - BlockEntity tileEntity = !(block instanceof EntityBlock) ? null : ((EntityBlock) block).newBlockEntity( - BlockPos.ZERO, - blockState - ); - tile = tileEntity == null - ? null - : new PaperweightLazyCompoundTag(Suppliers.memoize(tileEntity::saveWithId)); - } - - public Block getBlock() { - return block; - } - - public BlockState getState() { - return blockState; - } - - public CraftBlockData getCraftBlockData() { - return craftBlockData; - } - - public Material getMaterial() { - return material; - } - - @Override - public boolean isAir() { - return blockState.isAir(); - } - - @Override - public boolean isFullCube() { - return craftMaterial.isOccluding(); - } - - @Override - public boolean isOpaque() { - return material.isSolidBlocking(); - } - - @Override - public boolean isPowerSource() { - return blockState.isSignalSource(); - } - - @Override - public boolean isLiquid() { - return material.isLiquid(); - } - - @Override - public boolean isSolid() { - return material.isSolid(); - } - - @Override - public float getHardness() { - return craftBlockData.getState().destroySpeed; - } - - @Override - public float getResistance() { - return block.getExplosionResistance(); - } - - @Override - public float getSlipperiness() { - return block.getFriction(); - } - - @Override - public int getLightValue() { - return blockState.getLightEmission(); - } - - @Override - public int getLightOpacity() { - return opacity; - } - - @Override - public boolean isFragileWhenPushed() { - return material.getPushReaction() == PushReaction.DESTROY; - } - - @Override - public boolean isUnpushable() { - return material.getPushReaction() == PushReaction.BLOCK; - } - - @Override - public boolean isTicksRandomly() { - return block.isRandomlyTicking(blockState); - } - - @Override - public boolean isMovementBlocker() { - return material.isSolid(); - } - - @Override - public boolean isBurnable() { - return material.isFlammable(); - } - - @Override - public boolean isToolRequired() { - // Removed in 1.16.1, this is not present in higher versions - return false; - } - - @Override - public boolean isReplacedDuringPlacement() { - return material.isReplaceable(); - } - - @Override - public boolean isTranslucent() { - return isTranslucent; - } - - @Override - public boolean hasContainer() { - return block instanceof EntityBlock; - } - - @Override - public boolean isTile() { - return block instanceof EntityBlock; - } - - @Override - public CompoundTag getDefaultTile() { - return tile; - } - - @Override - public int getMapColor() { - // rgb field - return material.getColor().col; - } - -} 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 deleted file mode 100644 index 0b90d942a..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java +++ /dev/null @@ -1,614 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3; - -import com.fastasyncworldedit.bukkit.adapter.FaweAdapter; -import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory; -import com.fastasyncworldedit.core.FaweCache; -import com.fastasyncworldedit.core.entity.LazyBaseEntity; -import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory; -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.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.blocks.BaseItemStack; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_19_R3.PaperweightAdapter; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3.regen.PaperweightRegen; -import com.sk89q.worldedit.entity.BaseEntity; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.internal.block.BlockStateIdAccess; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.internal.wna.WorldNativeAccess; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.registry.state.BooleanProperty; -import com.sk89q.worldedit.registry.state.DirectionalProperty; -import com.sk89q.worldedit.registry.state.EnumProperty; -import com.sk89q.worldedit.registry.state.IntegerProperty; -import com.sk89q.worldedit.registry.state.Property; -import com.sk89q.worldedit.util.Direction; -import com.sk89q.worldedit.util.SideEffect; -import com.sk89q.worldedit.util.SideEffectSet; -import com.sk89q.worldedit.util.formatting.text.Component; -import com.sk89q.worldedit.world.RegenOptions; -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.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.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.WritableRegistry; -import net.minecraft.core.registries.Registries; -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.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.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.LevelChunk; -import org.apache.logging.log4j.Logger; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.NamespacedKey; -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.data.CraftBlockData; -import org.bukkit.craftbukkit.v1_19_R3.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_19_R3.util.CraftNamespacedKey; -import org.bukkit.entity.Player; -import org.enginehub.linbus.tree.LinCompoundTag; -import org.enginehub.linbus.tree.LinStringTag; -import org.enginehub.linbus.tree.LinTag; - -import javax.annotation.Nullable; -import java.lang.ref.WeakReference; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; -import java.util.OptionalInt; -import java.util.Set; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static net.minecraft.core.registries.Registries.BIOME; - -public final class PaperweightFaweAdapter extends FaweAdapter { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - private static Method CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE; - - static { - try { - CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE = ChunkHolder.class.getDeclaredMethod("wasAccessibleSinceLastSave"); - } catch (NoSuchMethodException ignored) { // may not be present in newer paper versions - } - } - - private final PaperweightAdapter parent; - // ------------------------------------------------------------------------ - // Code that may break between versions of Minecraft - // ------------------------------------------------------------------------ - private final PaperweightMapChunkUtil mapUtil = new PaperweightMapChunkUtil(); - private char[] ibdToStateOrdinal = null; - private int[] ordinalToIbdID = null; - private boolean initialised = false; - private Map>> allBlockProperties = null; - - public PaperweightFaweAdapter() throws NoSuchFieldException, NoSuchMethodException { - this.parent = new PaperweightAdapter(); - } - - @Nullable - private static String getEntityId(Entity entity) { - ResourceLocation resourceLocation = net.minecraft.world.entity.EntityType.getKey(entity.getType()); - return resourceLocation == null ? null : resourceLocation.toString(); - } - - @Override - public BukkitImplAdapter getParent() { - return parent; - } - - private synchronized boolean init() { - if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) { - return false; - } - ibdToStateOrdinal = new char[BlockTypesCache.states.length]; // size - ordinalToIbdID = new int[ibdToStateOrdinal.length]; // size - for (int i = 0; i < ibdToStateOrdinal.length; i++) { - BlockState blockState = BlockTypesCache.states[i]; - PaperweightBlockMaterial material = (PaperweightBlockMaterial) blockState.getMaterial(); - int id = Block.BLOCK_STATE_REGISTRY.getId(material.getState()); - char ordinal = blockState.getOrdinalChar(); - ibdToStateOrdinal[id] = ordinal; - ordinalToIbdID[ordinal] = id; - } - Map>> properties = new HashMap<>(); - try { - for (Field field : BlockStateProperties.class.getDeclaredFields()) { - Object obj = field.get(null); - if (!(obj instanceof net.minecraft.world.level.block.state.properties.Property state)) { - continue; - } - Property property; - if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { - property = new BooleanProperty( - state.getName(), - (List) ImmutableList.copyOf(state.getPossibleValues()) - ); - } else if (state instanceof DirectionProperty) { - property = new DirectionalProperty( - state.getName(), - state - .getPossibleValues() - .stream() - .map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase())) - .collect(Collectors.toList()) - ); - } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { - property = new EnumProperty( - state.getName(), - state - .getPossibleValues() - .stream() - .map(e -> ((StringRepresentable) e).getSerializedName()) - .collect(Collectors.toList()) - ); - } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { - property = new IntegerProperty( - state.getName(), - (List) ImmutableList.copyOf(state.getPossibleValues()) - ); - } else { - throw new IllegalArgumentException("FastAsyncWorldEdit needs an update to support " + state - .getClass() - .getSimpleName()); - } - properties.compute(property.getName().toLowerCase(Locale.ROOT), (k, v) -> { - if (v == null) { - v = new ArrayList<>(Collections.singletonList(property)); - } else { - v.add(property); - } - return v; - }); - } - } catch (IllegalAccessException e) { - e.printStackTrace(); - } finally { - allBlockProperties = ImmutableMap.copyOf(properties); - } - initialised = true; - return true; - } - - @Override - public BlockMaterial getMaterial(BlockType blockType) { - Block block = getBlock(blockType); - return new PaperweightBlockMaterial(block); - } - - @Override - public synchronized BlockMaterial getMaterial(BlockState state) { - net.minecraft.world.level.block.state.BlockState blockState = ((CraftBlockData) Bukkit.createBlockData(state.getAsString())).getState(); - return new PaperweightBlockMaterial(blockState.getBlock(), blockState); - } - - public Block getBlock(BlockType blockType) { - return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.BLOCK) - .get(new ResourceLocation(blockType.getNamespace(), blockType.getResource())); - } - - @Deprecated - @Override - public BlockState getBlock(Location location) { - Preconditions.checkNotNull(location); - - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - final ServerLevel handle = getServerLevel(location.getWorld()); - LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); - final BlockPos blockPos = new BlockPos(x, y, z); - final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos); - BlockState state = adapt(blockData); - if (state == null) { - org.bukkit.block.Block bukkitBlock = location.getBlock(); - state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); - } - return state; - } - - @Override - public BaseBlock getFullBlock(final Location location) { - Preconditions.checkNotNull(location); - - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - - final ServerLevel handle = getServerLevel(location.getWorld()); - LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); - final BlockPos blockPos = new BlockPos(x, y, z); - final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos); - BlockState state = adapt(blockData); - if (state == null) { - org.bukkit.block.Block bukkitBlock = location.getBlock(); - state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); - } - if (state.getBlockType().getMaterial().hasContainer()) { - - // Read the NBT data - BlockEntity blockEntity = chunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK); - if (blockEntity != null) { - net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(); - return state.toBaseBlock((LinCompoundTag) toNativeLin(tag)); - } - } - - return state.toBaseBlock(); - } - - @Override - public Set getSupportedSideEffects() { - return SideEffectSet.defaults().getSideEffectsToApply(); - } - - @Override - public WorldNativeAccess createWorldNativeAccess(org.bukkit.World world) { - return new PaperweightFaweWorldNativeAccess(this, new WeakReference<>(getServerLevel(world))); - } - - @Override - public BaseEntity getEntity(org.bukkit.entity.Entity entity) { - Preconditions.checkNotNull(entity); - - CraftEntity craftEntity = ((CraftEntity) entity); - Entity mcEntity = craftEntity.getHandle(); - - String id = getEntityId(mcEntity); - - if (id != null) { - EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id); - Supplier saveTag = () -> { - final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag(); - PaperweightPlatformAdapter.readEntityIntoTag(mcEntity, minecraftTag); - //add Id for AbstractChangeSet to work - final LinCompoundTag tag = (LinCompoundTag) toNativeLin(minecraftTag); - final Map> tags = NbtUtils.getLinCompoundTagValues(tag); - tags.put("Id", LinStringTag.of(id)); - return LinCompoundTag.of(tags); - }; - return new LazyBaseEntity(type, saveTag); - } else { - return null; - } - } - - @Override - public Component getRichBlockName(BlockType blockType) { - return parent.getRichBlockName(blockType); - } - - @Override - public Component getRichItemName(ItemType itemType) { - return parent.getRichItemName(itemType); - } - - @Override - public Component getRichItemName(BaseItemStack itemStack) { - return parent.getRichItemName(itemStack); - } - - @Override - public OptionalInt getInternalBlockStateId(BlockState state) { - PaperweightBlockMaterial material = (PaperweightBlockMaterial) state.getMaterial(); - net.minecraft.world.level.block.state.BlockState mcState = material.getCraftBlockData().getState(); - return OptionalInt.of(Block.BLOCK_STATE_REGISTRY.getId(mcState)); - } - - @Override - public BlockState adapt(BlockData blockData) { - CraftBlockData cbd = ((CraftBlockData) blockData); - net.minecraft.world.level.block.state.BlockState ibd = cbd.getState(); - return adapt(ibd); - } - - public BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) { - return BlockTypesCache.states[adaptToChar(blockState)]; - } - - public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockState) { - int id = Block.BLOCK_STATE_REGISTRY.getId(blockState); - if (initialised) { - return ibdToStateOrdinal[id]; - } - synchronized (this) { - if (initialised) { - return ibdToStateOrdinal[id]; - } - try { - init(); - return ibdToStateOrdinal[id]; - } catch (ArrayIndexOutOfBoundsException e1) { - LOGGER.error("Attempted to convert {} with ID {} to char. ibdToStateOrdinal length: {}. Defaulting to air!", - blockState.getBlock(), Block.BLOCK_STATE_REGISTRY.getId(blockState), ibdToStateOrdinal.length, e1 - ); - return BlockTypesCache.ReservedIDs.AIR; - } - } - } - - public char ibdIDToOrdinal(int id) { - if (initialised) { - return ibdToStateOrdinal[id]; - } - synchronized (this) { - if (initialised) { - return ibdToStateOrdinal[id]; - } - init(); - return ibdToStateOrdinal[id]; - } - } - - @Override - public char[] getIbdToStateOrdinal() { - if (initialised) { - return ibdToStateOrdinal; - } - synchronized (this) { - if (initialised) { - return ibdToStateOrdinal; - } - init(); - return ibdToStateOrdinal; - } - } - - public int ordinalToIbdID(char ordinal) { - if (initialised) { - return ordinalToIbdID[ordinal]; - } - synchronized (this) { - if (initialised) { - return ordinalToIbdID[ordinal]; - } - init(); - return ordinalToIbdID[ordinal]; - } - } - - @Override - public int[] getOrdinalToIbdID() { - if (initialised) { - return ordinalToIbdID; - } - synchronized (this) { - if (initialised) { - return ordinalToIbdID; - } - init(); - return ordinalToIbdID; - } - } - - @Override - public > BlockData adapt(B state) { - PaperweightBlockMaterial material = (PaperweightBlockMaterial) state.getMaterial(); - return material.getCraftBlockData(); - } - - @Override - public void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket chunkPacket) { - ServerLevel nmsWorld = getServerLevel(world); - ChunkHolder map = PaperweightPlatformAdapter.getPlayerChunk(nmsWorld, chunkPacket.getChunkX(), chunkPacket.getChunkZ()); - if (map != null && wasAccessibleSinceLastSave(map)) { - boolean flag = false; - // PlayerChunk.d players = map.players; - Stream stream = /*players.a(new ChunkCoordIntPair(packet.getChunkX(), packet.getChunkZ()), flag) - */ Stream.empty(); - - ServerPlayer checkPlayer = player == null ? null : ((CraftPlayer) player).getHandle(); - stream.filter(entityPlayer -> checkPlayer == null || entityPlayer == checkPlayer) - .forEach(entityPlayer -> { - synchronized (chunkPacket) { - ClientboundLevelChunkWithLightPacket nmsPacket = (ClientboundLevelChunkWithLightPacket) chunkPacket.getNativePacket(); - if (nmsPacket == null) { - nmsPacket = mapUtil.create(this, chunkPacket); - chunkPacket.setNativePacket(nmsPacket); - } - try { - FaweCache.INSTANCE.CHUNK_FLAG.get().set(true); - entityPlayer.connection.send(nmsPacket); - } finally { - FaweCache.INSTANCE.CHUNK_FLAG.get().set(false); - } - } - }); - } - } - - @Override - public Map> getProperties(BlockType blockType) { - return getParent().getProperties(blockType); - } - - @Override - public boolean canPlaceAt(org.bukkit.World world, BlockVector3 blockVector3, BlockState blockState) { - int internalId = BlockStateIdAccess.getBlockStateId(blockState); - net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(internalId); - return blockState1.hasPostProcess( - getServerLevel(world), - new BlockPos(blockVector3.x(), blockVector3.y(), blockVector3.z()) - ); - } - - @Override - public org.bukkit.inventory.ItemStack adapt(BaseItemStack baseItemStack) { - ItemStack stack = new ItemStack( - DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.ITEM) - .get(ResourceLocation.tryParse(baseItemStack.getType().id())), - baseItemStack.getAmount() - ); - stack.setTag(((net.minecraft.nbt.CompoundTag) fromNative(baseItemStack.getNbtData()))); - return CraftItemStack.asCraftMirror(stack); - } - - @Override - protected void preCaptureStates(final ServerLevel serverLevel) { - serverLevel.captureTreeGeneration = true; - serverLevel.captureBlockStates = true; - } - - @Override - protected List getCapturedBlockStatesCopy(final ServerLevel serverLevel) { - return new ArrayList<>(serverLevel.capturedBlockStates.values()); - } - - @Override - protected void postCaptureBlockStates(final ServerLevel serverLevel) { - serverLevel.captureBlockStates = false; - serverLevel.captureTreeGeneration = false; - serverLevel.capturedBlockStates.clear(); - } - - @Override - protected ServerLevel getServerLevel(final World world) { - return ((CraftWorld) world).getHandle(); - } - - @Override - public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) { - final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); - final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount()); - weStack.setNbt((LinCompoundTag) toNativeLin(nmsStack.getTag())); - return weStack; - } - - @Override - public Tag toNative(net.minecraft.nbt.Tag foreign) { - return parent.toNative(foreign); - } - - @Override - public net.minecraft.nbt.Tag fromNative(Tag foreign) { - if (foreign instanceof PaperweightLazyCompoundTag) { - return ((PaperweightLazyCompoundTag) foreign).get(); - } - return parent.fromNative(foreign); - } - - @Override - public boolean regenerate(org.bukkit.World bukkitWorld, Region region, Extent target, RegenOptions options) throws Exception { - return new PaperweightRegen(bukkitWorld, region, target, options).regenerate(); - } - - @Override - public IChunkGet get(org.bukkit.World world, int chunkX, int chunkZ) { - return new PaperweightGetBlocks(world, chunkX, chunkZ); - } - - @Override - public int getInternalBiomeId(BiomeType biomeType) { - final Registry registry = MinecraftServer - .getServer() - .registryAccess() - .registryOrThrow(BIOME); - ResourceLocation resourceLocation = ResourceLocation.tryParse(biomeType.id()); - Biome biome = registry.get(resourceLocation); - return registry.getId(biome); - } - - @Override - public Iterable getRegisteredBiomes() { - WritableRegistry biomeRegistry = (WritableRegistry) ((CraftServer) Bukkit.getServer()) - .getServer() - .registryAccess() - .registryOrThrow(BIOME); - List keys = biomeRegistry.stream() - .map(biomeRegistry::getKey).filter(Objects::nonNull).toList(); - List namespacedKeys = new ArrayList<>(); - for (ResourceLocation key : keys) { - try { - namespacedKeys.add(CraftNamespacedKey.fromMinecraft(key)); - } catch (IllegalArgumentException e) { - LOGGER.error("Error converting biome key {}", key.toString(), e); - } - } - return namespacedKeys; - } - - @Override - public RelighterFactory getRelighterFactory() { - if (PaperLib.isPaper()) { - return new PaperweightStarlightRelighterFactory(); - } else { - return new NMSRelighterFactory(); - } - } - - @Override - public Map>> getAllProperties() { - if (initialised) { - return allBlockProperties; - } - synchronized (this) { - if (initialised) { - return allBlockProperties; - } - init(); - return allBlockProperties; - } - } - - @Override - public IBatchProcessor getTickingPostProcessor() { - return new PaperweightPostProcessor(); - } - - private boolean wasAccessibleSinceLastSave(ChunkHolder holder) { - if (!PaperLib.isPaper() || !PaperweightPlatformAdapter.POST_CHUNK_REWRITE) { - try { - return (boolean) CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE.invoke(holder); - } catch (IllegalAccessException | InvocationTargetException ignored) { - // fall-through - } - } - // Papers new chunk system has no related replacement - therefor we assume true. - return true; - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweWorldNativeAccess.java deleted file mode 100644 index 0c57f9ca6..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweWorldNativeAccess.java +++ /dev/null @@ -1,292 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3; - -import com.fastasyncworldedit.core.Fawe; -import com.fastasyncworldedit.core.math.IntPair; -import com.fastasyncworldedit.core.util.TaskManager; -import com.fastasyncworldedit.core.util.task.RunnableVal; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.internal.block.BlockStateIdAccess; -import com.sk89q.worldedit.internal.wna.WorldNativeAccess; -import com.sk89q.worldedit.util.SideEffect; -import com.sk89q.worldedit.util.SideEffectSet; -import com.sk89q.worldedit.world.block.BlockState; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.server.level.ServerChunkCache; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.chunk.LevelChunk; -import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R3.block.data.CraftBlockData; -import org.bukkit.event.block.BlockPhysicsEvent; -import org.enginehub.linbus.tree.LinCompoundTag; - -import javax.annotation.Nullable; -import java.lang.ref.WeakReference; -import java.util.Collections; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; - -public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess { - - private static final int UPDATE = 1; - private static final int NOTIFY = 2; - private static final Direction[] NEIGHBOUR_ORDER = { - Direction.EAST, - Direction.WEST, - Direction.DOWN, - Direction.UP, - Direction.NORTH, - Direction.SOUTH - }; - private final PaperweightFaweAdapter paperweightFaweAdapter; - private final WeakReference level; - private final AtomicInteger lastTick; - private final Set cachedChanges = new HashSet<>(); - private final Set cachedChunksToSend = new HashSet<>(); - private SideEffectSet sideEffectSet; - - public PaperweightFaweWorldNativeAccess(PaperweightFaweAdapter paperweightFaweAdapter, WeakReference level) { - this.paperweightFaweAdapter = paperweightFaweAdapter; - this.level = level; - // Use the actual tick as minecraft-defined so we don't try to force blocks into the world when the server's already lagging. - // - With the caveat that we don't want to have too many cached changed (1024) so we'd flush those at 1024 anyway. - this.lastTick = new AtomicInteger(MinecraftServer.currentTick); - } - - private Level getLevel() { - return Objects.requireNonNull(level.get(), "The reference to the world was lost"); - } - - @Override - public void setCurrentSideEffectSet(SideEffectSet sideEffectSet) { - this.sideEffectSet = sideEffectSet; - } - - @Override - public LevelChunk getChunk(int x, int z) { - return getLevel().getChunk(x, z); - } - - @Override - public net.minecraft.world.level.block.state.BlockState toNative(BlockState blockState) { - int stateId = paperweightFaweAdapter.ordinalToIbdID(blockState.getOrdinalChar()); - return BlockStateIdAccess.isValidInternalId(stateId) - ? Block.stateById(stateId) - : ((CraftBlockData) BukkitAdapter.adapt(blockState)).getState(); - } - - @Override - public net.minecraft.world.level.block.state.BlockState getBlockState(LevelChunk levelChunk, BlockPos blockPos) { - return levelChunk.getBlockState(blockPos); - } - - @Nullable - @Override - public synchronized net.minecraft.world.level.block.state.BlockState setBlockState( - LevelChunk levelChunk, BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState blockState - ) { - int currentTick = MinecraftServer.currentTick; - if (Fawe.isMainThread()) { - return levelChunk.setBlockState(blockPos, blockState, - this.sideEffectSet != null && this.sideEffectSet.shouldApply(SideEffect.UPDATE) - ); - } - // Since FAWE is.. Async we need to do it on the main thread (wooooo.. :( ) - cachedChanges.add(new CachedChange(levelChunk, blockPos, blockState)); - cachedChunksToSend.add(new IntPair(levelChunk.locX, levelChunk.locZ)); - boolean nextTick = lastTick.get() > currentTick; - if (nextTick || cachedChanges.size() >= 1024) { - if (nextTick) { - lastTick.set(currentTick); - } - flushAsync(nextTick); - } - return blockState; - } - - @Override - public net.minecraft.world.level.block.state.BlockState getValidBlockForPosition( - net.minecraft.world.level.block.state.BlockState blockState, - BlockPos blockPos - ) { - return Block.updateFromNeighbourShapes(blockState, getLevel(), blockPos); - } - - @Override - public BlockPos getPosition(int x, int y, int z) { - return new BlockPos(x, y, z); - } - - @Override - public void updateLightingForBlock(BlockPos blockPos) { - getLevel().getChunkSource().getLightEngine().checkBlock(blockPos); - } - - @Override - public boolean updateTileEntity(BlockPos blockPos, LinCompoundTag tag) { - // We will assume that the tile entity was created for us, - // though we do not do this on the other versions - BlockEntity blockEntity = getLevel().getBlockEntity(blockPos); - if (blockEntity == null) { - return false; - } - net.minecraft.nbt.Tag nativeTag = paperweightFaweAdapter.fromNativeLin(tag); - blockEntity.load((CompoundTag) nativeTag); - return true; - } - - @Override - public void notifyBlockUpdate( - LevelChunk levelChunk, BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState - ) { - if (levelChunk.getSections()[level.get().getSectionIndex(blockPos.getY())] != null) { - getLevel().sendBlockUpdated(blockPos, oldState, newState, UPDATE | NOTIFY); - } - } - - @Override - public boolean isChunkTicking(LevelChunk levelChunk) { - return levelChunk.getFullStatus().isOrAfter(ChunkHolder.FullChunkStatus.TICKING); - } - - @Override - public void markBlockChanged(LevelChunk levelChunk, BlockPos blockPos) { - if (levelChunk.getSections()[level.get().getSectionIndex(blockPos.getY())] != null) { - ((ServerChunkCache) getLevel().getChunkSource()).blockChanged(blockPos); - } - } - - @Override - public void notifyNeighbors( - BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState - ) { - Level level = getLevel(); - if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { - level.blockUpdated(blockPos, oldState.getBlock()); - } else { - // When we don't want events, manually run the physics without them. - // Un-nest neighbour updating - for (Direction direction : NEIGHBOUR_ORDER) { - BlockPos shifted = blockPos.relative(direction); - level.getBlockState(shifted).neighborChanged(level, shifted, oldState.getBlock(), blockPos, false); - } - } - if (newState.hasAnalogOutputSignal()) { - level.updateNeighbourForOutputSignal(blockPos, newState.getBlock()); - } - } - - @Override - public void updateNeighbors( - BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState, - int recursionLimit - ) { - Level level = getLevel(); - // a == updateNeighbors - // b == updateDiagonalNeighbors - oldState.updateIndirectNeighbourShapes(level, blockPos, NOTIFY, recursionLimit); - if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { - CraftWorld craftWorld = level.getWorld(); - if (craftWorld != null) { - BlockPhysicsEvent event = new BlockPhysicsEvent( - craftWorld.getBlockAt(blockPos.getX(), blockPos.getY(), blockPos.getZ()), - CraftBlockData.fromData(newState) - ); - level.getCraftServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { - return; - } - } - } - newState.triggerEvent(level, blockPos, NOTIFY, recursionLimit); - newState.updateIndirectNeighbourShapes(level, blockPos, NOTIFY, recursionLimit); - } - - @Override - public void updateBlock(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { - Level world = getLevel(); - newState.onPlace(world, pos, oldState, false); - } - - @Override - public void onBlockStateChange( - BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState - ) { - getLevel().onBlockStateChange(blockPos, oldState, newState); - } - - private synchronized void flushAsync(final boolean sendChunks) { - final Set changes = Set.copyOf(cachedChanges); - cachedChanges.clear(); - final Set toSend; - if (sendChunks) { - toSend = Set.copyOf(cachedChunksToSend); - cachedChunksToSend.clear(); - } else { - toSend = Collections.emptySet(); - } - RunnableVal runnableVal = new RunnableVal<>() { - @Override - public void run(Object value) { - changes.forEach(cc -> cc.levelChunk.setBlockState(cc.blockPos, cc.blockState, - sideEffectSet != null && sideEffectSet.shouldApply(SideEffect.UPDATE) - )); - if (!sendChunks) { - return; - } - for (IntPair chunk : toSend) { - PaperweightPlatformAdapter.sendChunk(chunk, getLevel().getWorld().getHandle(), chunk.x(), chunk.z()); - } - } - }; - TaskManager.taskManager().async(() -> TaskManager.taskManager().sync(runnableVal)); - } - - @Override - public synchronized void flush() { - RunnableVal runnableVal = new RunnableVal<>() { - @Override - public void run(Object value) { - cachedChanges.forEach(cc -> cc.levelChunk.setBlockState(cc.blockPos, cc.blockState, - sideEffectSet != null && sideEffectSet.shouldApply(SideEffect.UPDATE) - )); - for (IntPair chunk : cachedChunksToSend) { - PaperweightPlatformAdapter.sendChunk(chunk, getLevel().getWorld().getHandle(), chunk.x(), chunk.z()); - } - } - }; - if (Fawe.isMainThread()) { - runnableVal.run(); - } else { - TaskManager.taskManager().sync(runnableVal); - } - cachedChanges.clear(); - cachedChunksToSend.clear(); - } - - private record CachedChange( - LevelChunk levelChunk, - BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState blockState - ) { - - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks.java deleted file mode 100644 index c3d4388e9..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks.java +++ /dev/null @@ -1,1187 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3; - -import com.fastasyncworldedit.bukkit.adapter.BukkitGetBlocks; -import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore; -import com.fastasyncworldedit.core.Fawe; -import com.fastasyncworldedit.core.FaweCache; -import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType; -import com.fastasyncworldedit.core.math.BitArrayUnstretched; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.queue.IChunkSet; -import com.fastasyncworldedit.core.queue.implementation.QueueHandler; -import com.fastasyncworldedit.core.queue.implementation.blocks.CharGetBlocks; -import com.fastasyncworldedit.core.util.MathMan; -import com.fastasyncworldedit.core.util.collection.AdaptedMap; -import com.google.common.base.Suppliers; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.ListTag; -import com.sk89q.jnbt.StringTag; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.internal.Constants; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.biome.BiomeTypes; -import com.sk89q.worldedit.world.block.BlockTypesCache; -import io.papermc.lib.PaperLib; -import io.papermc.paper.event.block.BeaconDeactivatedEvent; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.core.IdMap; -import net.minecraft.core.Registry; -import net.minecraft.core.SectionPos; -import net.minecraft.nbt.IntTag; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.util.BitStorage; -import net.minecraft.util.ZeroBitStorage; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.level.LightLayer; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.entity.BeaconBlockEntity; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.DataLayer; -import net.minecraft.world.level.chunk.HashMapPalette; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.LevelChunkSection; -import net.minecraft.world.level.chunk.LinearPalette; -import net.minecraft.world.level.chunk.Palette; -import net.minecraft.world.level.chunk.PalettedContainer; -import net.minecraft.world.level.chunk.PalettedContainerRO; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.lighting.LevelLightEngine; -import org.apache.logging.log4j.Logger; -import org.bukkit.World; -import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R3.block.CraftBlock; -import org.bukkit.event.entity.CreatureSpawnEvent; - -import javax.annotation.Nonnull; -import java.util.AbstractSet; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Future; -import java.util.concurrent.Semaphore; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.function.Function; -import java.util.stream.Collectors; - -import static net.minecraft.core.registries.Registries.BIOME; - -public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBlocks { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - - private static final Function posNms2We = v -> BlockVector3.at(v.getX(), v.getY(), v.getZ()); - private static final Function nmsTile2We = - tileEntity -> new PaperweightLazyCompoundTag(Suppliers.memoize(tileEntity::saveWithId)); - private final PaperweightFaweAdapter adapter = ((PaperweightFaweAdapter) WorldEditPlugin - .getInstance() - .getBukkitImplAdapter()); - private final ReadWriteLock sectionLock = new ReentrantReadWriteLock(); - private final ReentrantLock callLock = new ReentrantLock(); - private final ServerLevel serverLevel; - private final int chunkX; - private final int chunkZ; - private final int minHeight; - private final int maxHeight; - private final int minSectionPosition; - private final int maxSectionPosition; - private final Registry biomeRegistry; - private final IdMap> biomeHolderIdMap; - private final ConcurrentHashMap copies = new ConcurrentHashMap<>(); - private final Object sendLock = new Object(); - private LevelChunkSection[] sections; - private LevelChunk levelChunk; - private DataLayer[] blockLight; - private DataLayer[] skyLight; - private boolean createCopy = false; - private boolean forceLoadSections = true; - private boolean lightUpdate = false; - private int copyKey = 0; - - public PaperweightGetBlocks(World world, int chunkX, int chunkZ) { - this(((CraftWorld) world).getHandle(), chunkX, chunkZ); - } - - public PaperweightGetBlocks(ServerLevel serverLevel, int chunkX, int chunkZ) { - super(serverLevel.getMinBuildHeight() >> 4, (serverLevel.getMaxBuildHeight() - 1) >> 4); - this.serverLevel = serverLevel; - this.chunkX = chunkX; - this.chunkZ = chunkZ; - this.minHeight = serverLevel.getMinBuildHeight(); - this.maxHeight = serverLevel.getMaxBuildHeight() - 1; // Minecraft max limit is exclusive. - this.minSectionPosition = minHeight >> 4; - this.maxSectionPosition = maxHeight >> 4; - this.skyLight = new DataLayer[getSectionCount()]; - this.blockLight = new DataLayer[getSectionCount()]; - this.biomeRegistry = serverLevel.registryAccess().registryOrThrow(BIOME); - this.biomeHolderIdMap = biomeRegistry.asHolderIdMap(); - } - - public int getChunkX() { - return chunkX; - } - - public int getChunkZ() { - return chunkZ; - } - - @Override - public boolean isCreateCopy() { - return createCopy; - } - - @Override - public int setCreateCopy(boolean createCopy) { - if (!callLock.isHeldByCurrentThread()) { - throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked."); - } - this.createCopy = createCopy; - // Increment regardless of whether copy will be created or not to return null from getCopy() - return ++this.copyKey; - } - - @Override - public IChunkGet getCopy(final int key) { - return copies.remove(key); - } - - @Override - public void lockCall() { - this.callLock.lock(); - } - - @Override - public void unlockCall() { - this.callLock.unlock(); - } - - @Override - public void setLightingToGet(char[][] light, int minSectionPosition, int maxSectionPosition) { - if (light != null) { - lightUpdate = true; - try { - fillLightNibble(light, LightLayer.BLOCK, minSectionPosition, maxSectionPosition); - } catch (Throwable e) { - e.printStackTrace(); - } - } - } - - @Override - public void setSkyLightingToGet(char[][] light, int minSectionPosition, int maxSectionPosition) { - if (light != null) { - lightUpdate = true; - try { - fillLightNibble(light, LightLayer.SKY, minSectionPosition, maxSectionPosition); - } catch (Throwable e) { - e.printStackTrace(); - } - } - } - - @Override - public void setHeightmapToGet(HeightMapType type, int[] data) { - // height + 1 to match server internal - BitArrayUnstretched bitArray = new BitArrayUnstretched(MathMan.log2nlz(getChunk().getHeight() + 1), 256); - bitArray.fromRaw(data); - Heightmap.Types nativeType = Heightmap.Types.valueOf(type.name()); - Heightmap heightMap = getChunk().heightmaps.get(nativeType); - heightMap.setRawData(getChunk(), nativeType, bitArray.getData()); - } - - @Override - public int getMaxY() { - return maxHeight; - } - - @Override - public int getMinY() { - return minHeight; - } - - @Override - public BiomeType getBiomeType(int x, int y, int z) { - LevelChunkSection section = getSections(false)[(y >> 4) - getMinSectionPosition()]; - Holder biomes = section.getNoiseBiome(x >> 2, (y & 15) >> 2, z >> 2); - return PaperweightPlatformAdapter.adapt(biomes, serverLevel); - } - - @Override - public void removeSectionLighting(int layer, boolean sky) { - SectionPos sectionPos = SectionPos.of(getChunk().getPos(), layer); - DataLayer dataLayer = serverLevel.getChunkSource().getLightEngine().getLayerListener(LightLayer.BLOCK).getDataLayerData( - sectionPos); - if (dataLayer != null) { - lightUpdate = true; - synchronized (dataLayer) { - byte[] bytes = dataLayer.getData(); - Arrays.fill(bytes, (byte) 0); - } - } - if (sky) { - SectionPos sectionPos1 = SectionPos.of(getChunk().getPos(), layer); - DataLayer dataLayer1 = serverLevel - .getChunkSource() - .getLightEngine() - .getLayerListener(LightLayer.SKY) - .getDataLayerData(sectionPos1); - if (dataLayer1 != null) { - lightUpdate = true; - synchronized (dataLayer1) { - byte[] bytes = dataLayer1.getData(); - Arrays.fill(bytes, (byte) 0); - } - } - } - } - - @Override - public CompoundTag getTile(int x, int y, int z) { - BlockEntity blockEntity = getChunk().getBlockEntity(new BlockPos((x & 15) + ( - chunkX << 4), y, (z & 15) + ( - chunkZ << 4))); - if (blockEntity == null) { - return null; - } - return new PaperweightLazyCompoundTag(Suppliers.memoize(blockEntity::saveWithId)); - } - - @Override - public Map getTiles() { - Map nmsTiles = getChunk().getBlockEntities(); - if (nmsTiles.isEmpty()) { - return Collections.emptyMap(); - } - return AdaptedMap.immutable(nmsTiles, posNms2We, nmsTile2We); - } - - @Override - public int getSkyLight(int x, int y, int z) { - int layer = y >> 4; - int alayer = layer - getMinSectionPosition(); - if (skyLight[alayer] == null) { - SectionPos sectionPos = SectionPos.of(getChunk().getPos(), layer); - DataLayer dataLayer = - serverLevel.getChunkSource().getLightEngine().getLayerListener(LightLayer.SKY).getDataLayerData(sectionPos); - // If the server hasn't generated the section's NibbleArray yet, it will be null - if (dataLayer == null) { - byte[] LAYER_COUNT = new byte[2048]; - // Safe enough to assume if it's not created, it's under the sky. Unlikely to be created before lighting is fixed anyway. - Arrays.fill(LAYER_COUNT, (byte) 15); - dataLayer = new DataLayer(LAYER_COUNT); - ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData( - LightLayer.BLOCK, - sectionPos, - dataLayer, - true - ); - } - skyLight[alayer] = dataLayer; - } - return skyLight[alayer].get(x & 15, y & 15, z & 15); - } - - @Override - public int getEmittedLight(int x, int y, int z) { - int layer = y >> 4; - int alayer = layer - getMinSectionPosition(); - if (blockLight[alayer] == null) { - serverLevel.getRawBrightness(new BlockPos(1, 1, 1), 5); - SectionPos sectionPos = SectionPos.of(getChunk().getPos(), layer); - DataLayer dataLayer = serverLevel - .getChunkSource() - .getLightEngine() - .getLayerListener(LightLayer.BLOCK) - .getDataLayerData(sectionPos); - // If the server hasn't generated the section's DataLayer yet, it will be null - if (dataLayer == null) { - byte[] LAYER_COUNT = new byte[2048]; - // Safe enough to assume if it's not created, it's under the sky. Unlikely to be created before lighting is fixed anyway. - Arrays.fill(LAYER_COUNT, (byte) 15); - dataLayer = new DataLayer(LAYER_COUNT); - ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData(LightLayer.BLOCK, sectionPos, - dataLayer, true - ); - } - blockLight[alayer] = dataLayer; - } - return blockLight[alayer].get(x & 15, y & 15, z & 15); - } - - @Override - public int[] getHeightMap(HeightMapType type) { - long[] longArray = getChunk().heightmaps.get(Heightmap.Types.valueOf(type.name())).getRawData(); - BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256, longArray); - return bitArray.toRaw(new int[256]); - } - - @Override - public CompoundTag getEntity(UUID uuid) { - Entity entity = serverLevel.getEntity(uuid); - if (entity != null) { - org.bukkit.entity.Entity bukkitEnt = entity.getBukkitEntity(); - return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData(); - } - for (CompoundTag tag : getEntities()) { - if (uuid.equals(tag.getUUID())) { - return tag; - } - } - return null; - } - - @Override - public Set getEntities() { - ensureLoaded(serverLevel, chunkX, chunkZ); - List entities = PaperweightPlatformAdapter.getEntities(getChunk()); - if (entities.isEmpty()) { - return Collections.emptySet(); - } - int size = entities.size(); - return new AbstractSet<>() { - @Override - public int size() { - return size; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public boolean contains(Object get) { - if (!(get instanceof CompoundTag getTag)) { - return false; - } - UUID getUUID = getTag.getUUID(); - for (Entity entity : entities) { - UUID uuid = entity.getUUID(); - if (uuid.equals(getUUID)) { - return true; - } - } - return false; - } - - @Nonnull - @Override - public Iterator iterator() { - Iterable result = entities.stream().map(input -> { - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - PaperweightPlatformAdapter.readEntityIntoTag(input, tag); - return (CompoundTag) adapter.toNative(tag); - }).collect(Collectors.toList()); - return result.iterator(); - } - }; - } - - private void removeEntity(Entity entity) { - entity.discard(); - } - - public LevelChunk ensureLoaded(ServerLevel nmsWorld, int chunkX, int chunkZ) { - return PaperweightPlatformAdapter.ensureLoaded(nmsWorld, chunkX, chunkZ); - } - - @Override - @SuppressWarnings("rawtypes") - public synchronized > T call(IChunkSet set, Runnable finalizer) { - if (!callLock.isHeldByCurrentThread()) { - throw new IllegalStateException("Attempted to call chunk GET but chunk was not call-locked."); - } - forceLoadSections = false; - PaperweightGetBlocks_Copy copy = createCopy ? new PaperweightGetBlocks_Copy(levelChunk) : null; - if (createCopy) { - if (copies.containsKey(copyKey)) { - throw new IllegalStateException("Copy key already used."); - } - copies.put(copyKey, copy); - } - try { - ServerLevel nmsWorld = serverLevel; - LevelChunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ); - - // Remove existing tiles. Create a copy so that we can remove blocks - Map chunkTiles = new HashMap<>(nmsChunk.getBlockEntities()); - List beacons = null; - if (!chunkTiles.isEmpty()) { - for (Map.Entry entry : chunkTiles.entrySet()) { - final BlockPos pos = entry.getKey(); - final int lx = pos.getX() & 15; - final int ly = pos.getY(); - final int lz = pos.getZ() & 15; - final int layer = ly >> 4; - if (!set.hasSection(layer)) { - continue; - } - - int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); - if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { - BlockEntity tile = entry.getValue(); - if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { - if (beacons == null) { - beacons = new ArrayList<>(); - } - beacons.add(tile); - PaperweightPlatformAdapter.removeBeacon(tile, nmsChunk); - continue; - } - nmsChunk.removeBlockEntity(tile.getBlockPos()); - if (createCopy) { - copy.storeTile(tile); - } - } - } - } - final BiomeType[][] biomes = set.getBiomes(); - - int bitMask = 0; - synchronized (nmsChunk) { - LevelChunkSection[] levelChunkSections = nmsChunk.getSections(); - - for (int layerNo = getMinSectionPosition(); layerNo <= getMaxSectionPosition(); layerNo++) { - - int getSectionIndex = layerNo - getMinSectionPosition(); - int setSectionIndex = layerNo - set.getMinSectionPosition(); - - if (!set.hasSection(layerNo)) { - // No blocks, but might be biomes present. Handle this lazily. - if (biomes == null) { - continue; - } - if (layerNo < set.getMinSectionPosition() || layerNo > set.getMaxSectionPosition()) { - continue; - } - if (biomes[setSectionIndex] != null) { - synchronized (super.sectionLocks[getSectionIndex]) { - LevelChunkSection existingSection = levelChunkSections[getSectionIndex]; - if (createCopy && existingSection != null) { - copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); - } - - if (existingSection == null) { - PalettedContainer> biomeData = PaperweightPlatformAdapter.getBiomePalettedContainer( - biomes[setSectionIndex], - biomeHolderIdMap - ); - LevelChunkSection newSection = PaperweightPlatformAdapter.newChunkSection( - layerNo, - new char[4096], - adapter, - biomeRegistry, - biomeData - ); - if (PaperweightPlatformAdapter.setSectionAtomic( - levelChunkSections, - null, - newSection, - getSectionIndex - )) { - updateGet(nmsChunk, levelChunkSections, newSection, new char[4096], getSectionIndex); - continue; - } else { - existingSection = levelChunkSections[getSectionIndex]; - if (existingSection == null) { - LOGGER.error("Skipping invalid null section. chunk: {}, {} layer: {}", chunkX, chunkZ, - getSectionIndex - ); - continue; - } - } - } else { - PalettedContainer> paletteBiomes = setBiomesToPalettedContainer( - biomes, - setSectionIndex, - existingSection.getBiomes() - ); - if (paletteBiomes != null) { - PaperweightPlatformAdapter.setBiomesToChunkSection(existingSection, paletteBiomes); - } - } - } - } - continue; - } - - bitMask |= 1 << getSectionIndex; - - // setArr is modified by PaperweightPlatformAdapter#newChunkSection. This is in order to write changes to - // this chunk GET when #updateGet is called. Future dords, please listen this time. - char[] tmp = set.load(layerNo); - char[] setArr = new char[tmp.length]; - System.arraycopy(tmp, 0, setArr, 0, tmp.length); - - // synchronise on internal section to avoid circular locking with a continuing edit if the chunk was - // submitted to keep loaded internal chunks to queue target size. - synchronized (super.sectionLocks[getSectionIndex]) { - - LevelChunkSection newSection; - LevelChunkSection existingSection = levelChunkSections[getSectionIndex]; - // Don't attempt to tick section whilst we're editing - if (existingSection != null) { - PaperweightPlatformAdapter.clearCounts(existingSection); - if (PaperLib.isPaper()) { - existingSection.tickingList.clear(); - } - } - - if (createCopy) { - char[] tmpLoad = loadPrivately(layerNo); - char[] copyArr = new char[4096]; - System.arraycopy(tmpLoad, 0, copyArr, 0, 4096); - copy.storeSection(getSectionIndex, copyArr); - if (biomes != null && existingSection != null) { - copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); - } - } - - if (existingSection == null) { - PalettedContainer> biomeData = biomes == null ? new PalettedContainer<>( - biomeHolderIdMap, - biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)), - PalettedContainer.Strategy.SECTION_BIOMES, - null - ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap); - newSection = PaperweightPlatformAdapter.newChunkSection( - layerNo, - setArr, - adapter, - biomeRegistry, - biomeData - ); - if (PaperweightPlatformAdapter.setSectionAtomic( - levelChunkSections, - null, - newSection, - getSectionIndex - )) { - updateGet(nmsChunk, levelChunkSections, newSection, setArr, getSectionIndex); - continue; - } else { - existingSection = levelChunkSections[getSectionIndex]; - if (existingSection == null) { - LOGGER.error("Skipping invalid null section. chunk: {}, {} layer: {}", chunkX, chunkZ, - getSectionIndex - ); - continue; - } - } - } - - //ensure that the server doesn't try to tick the chunksection while we're editing it. (Again) - PaperweightPlatformAdapter.clearCounts(existingSection); - if (PaperLib.isPaper()) { - existingSection.tickingList.clear(); - } - DelegateSemaphore lock = PaperweightPlatformAdapter.applyLock(existingSection); - - // Synchronize to prevent further acquisitions - synchronized (lock) { - lock.acquire(); // Wait until we have the lock - lock.release(); - try { - sectionLock.writeLock().lock(); - if (this.getChunk() != nmsChunk) { - this.levelChunk = nmsChunk; - this.sections = null; - this.reset(); - } else if (existingSection != getSections(false)[getSectionIndex]) { - this.sections[getSectionIndex] = existingSection; - this.reset(); - } else if (!Arrays.equals( - update(getSectionIndex, new char[4096], true), - loadPrivately(layerNo) - )) { - this.reset(layerNo); - /*} else if (lock.isModified()) { - this.reset(layerNo);*/ - } - } finally { - sectionLock.writeLock().unlock(); - } - - PalettedContainer> biomeData = setBiomesToPalettedContainer( - biomes, - setSectionIndex, - existingSection.getBiomes() - ); - - newSection = PaperweightPlatformAdapter.newChunkSection( - layerNo, - this::loadPrivately, - setArr, - adapter, - biomeRegistry, - biomeData != null ? biomeData : (PalettedContainer>) existingSection.getBiomes() - ); - if (!PaperweightPlatformAdapter.setSectionAtomic( - levelChunkSections, - existingSection, - newSection, - getSectionIndex - )) { - LOGGER.error("Skipping invalid null section. chunk: {}, {} layer: {}", chunkX, chunkZ, - getSectionIndex - ); - } else { - updateGet(nmsChunk, levelChunkSections, newSection, setArr, getSectionIndex); - } - } - } - } - - Map heightMaps = set.getHeightMaps(); - for (Map.Entry entry : heightMaps.entrySet()) { - PaperweightGetBlocks.this.setHeightmapToGet(entry.getKey(), entry.getValue()); - } - PaperweightGetBlocks.this.setLightingToGet( - set.getLight(), - set.getMinSectionPosition(), - set.getMaxSectionPosition() - ); - PaperweightGetBlocks.this.setSkyLightingToGet( - set.getSkyLight(), - set.getMinSectionPosition(), - set.getMaxSectionPosition() - ); - - Runnable[] syncTasks = null; - - int bx = chunkX << 4; - int bz = chunkZ << 4; - - // Call beacon deactivate events here synchronously - // list will be null on spigot, so this is an implicit isPaper check - if (beacons != null && !beacons.isEmpty()) { - final List finalBeacons = beacons; - - syncTasks = new Runnable[4]; - - syncTasks[3] = () -> { - for (BlockEntity beacon : finalBeacons) { - BeaconBlockEntity.playSound(beacon.getLevel(), beacon.getBlockPos(), SoundEvents.BEACON_DEACTIVATE); - new BeaconDeactivatedEvent(CraftBlock.at(beacon.getLevel(), beacon.getBlockPos())).callEvent(); - } - }; - } - - Set entityRemoves = set.getEntityRemoves(); - if (entityRemoves != null && !entityRemoves.isEmpty()) { - if (syncTasks == null) { - syncTasks = new Runnable[3]; - } - - syncTasks[2] = () -> { - Set entitiesRemoved = new HashSet<>(); - final List entities = PaperweightPlatformAdapter.getEntities(nmsChunk); - - for (Entity entity : entities) { - UUID uuid = entity.getUUID(); - if (entityRemoves.contains(uuid)) { - if (createCopy) { - copy.storeEntity(entity); - } - removeEntity(entity); - entitiesRemoved.add(uuid); - entityRemoves.remove(uuid); - } - } - if (Settings.settings().EXPERIMENTAL.REMOVE_ENTITY_FROM_WORLD_ON_CHUNK_FAIL) { - for (UUID uuid : entityRemoves) { - Entity entity = nmsWorld.getEntities().get(uuid); - if (entity != null) { - removeEntity(entity); - } - } - } - // Only save entities that were actually removed to history - set.getEntityRemoves().clear(); - set.getEntityRemoves().addAll(entitiesRemoved); - }; - } - - Set entities = set.getEntities(); - if (entities != null && !entities.isEmpty()) { - if (syncTasks == null) { - syncTasks = new Runnable[2]; - } - - syncTasks[1] = () -> { - Iterator iterator = entities.iterator(); - while (iterator.hasNext()) { - final CompoundTag nativeTag = iterator.next(); - final Map> entityTagMap = nativeTag.getValue(); - final StringTag idTag = (StringTag) entityTagMap.get("Id"); - final ListTag posTag = (ListTag) entityTagMap.get("Pos"); - final ListTag rotTag = (ListTag) entityTagMap.get("Rotation"); - if (idTag == null || posTag == null || rotTag == null) { - LOGGER.error("Unknown entity tag: {}", nativeTag); - continue; - } - final double x = posTag.getDouble(0); - final double y = posTag.getDouble(1); - final double z = posTag.getDouble(2); - final float yaw = rotTag.getFloat(0); - final float pitch = rotTag.getFloat(1); - final String id = idTag.getValue(); - - EntityType type = EntityType.byString(id).orElse(null); - if (type != null) { - Entity entity = type.create(nmsWorld); - if (entity != null) { - final net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNative( - nativeTag); - for (final String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { - tag.remove(name); - } - entity.load(tag); - entity.absMoveTo(x, y, z, yaw, pitch); - entity.setUUID(nativeTag.getUUID()); - if (!nmsWorld.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM)) { - LOGGER.warn( - "Error creating entity of type `{}` in world `{}` at location `{},{},{}`", - id, - nmsWorld.getWorld().getName(), - x, - y, - z - ); - // Unsuccessful create should not be saved to history - iterator.remove(); - } - } - } - } - }; - } - - // set tiles - Map tiles = set.getTiles(); - if (tiles != null && !tiles.isEmpty()) { - if (syncTasks == null) { - syncTasks = new Runnable[1]; - } - - syncTasks[0] = () -> { - for (final Map.Entry entry : tiles.entrySet()) { - final CompoundTag nativeTag = entry.getValue(); - final BlockVector3 blockHash = entry.getKey(); - final int x = blockHash.x() + bx; - final int y = blockHash.y(); - final int z = blockHash.z() + bz; - final BlockPos pos = new BlockPos(x, y, z); - - synchronized (nmsWorld) { - BlockEntity tileEntity = nmsWorld.getBlockEntity(pos); - if (tileEntity == null || tileEntity.isRemoved()) { - nmsWorld.removeBlockEntity(pos); - tileEntity = nmsWorld.getBlockEntity(pos); - } - if (tileEntity != null) { - final net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNative( - nativeTag); - tag.put("x", IntTag.valueOf(x)); - tag.put("y", IntTag.valueOf(y)); - tag.put("z", IntTag.valueOf(z)); - tileEntity.load(tag); - } - } - } - }; - } - - Runnable callback; - if (bitMask == 0 && biomes == null && !lightUpdate) { - callback = null; - } else { - int finalMask = bitMask != 0 ? bitMask : lightUpdate ? set.getBitMask() : 0; - boolean finalLightUpdate = lightUpdate; - callback = () -> { - // Set Modified - nmsChunk.setLightCorrect(true); // Set Modified - nmsChunk.mustNotSave = false; - nmsChunk.setUnsaved(true); - // send to player - if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalMask == 0 && biomes != null) { - this.send(); - } - if (finalizer != null) { - finalizer.run(); - } - }; - } - if (syncTasks != null) { - QueueHandler queueHandler = Fawe.instance().getQueueHandler(); - Runnable[] finalSyncTasks = syncTasks; - - // Chain the sync tasks and the callback - Callable chain = () -> { - try { - // Run the sync tasks - for (Runnable task : finalSyncTasks) { - if (task != null) { - task.run(); - } - } - if (callback == null) { - if (finalizer != null) { - queueHandler.async(finalizer, null); - } - return null; - } else { - return queueHandler.async(callback, null); - } - } catch (Throwable e) { - e.printStackTrace(); - throw e; - } - }; - //noinspection unchecked - required at compile time - return (T) (Future) queueHandler.sync(chain); - } else { - if (callback == null) { - if (finalizer != null) { - finalizer.run(); - } - } else { - callback.run(); - } - } - } - return null; - } catch (Throwable e) { - e.printStackTrace(); - return null; - } finally { - forceLoadSections = true; - } - } - - private void updateGet( - LevelChunk nmsChunk, - LevelChunkSection[] chunkSections, - LevelChunkSection section, - char[] arr, - int layer - ) { - try { - sectionLock.writeLock().lock(); - if (this.getChunk() != nmsChunk) { - this.levelChunk = nmsChunk; - this.sections = new LevelChunkSection[chunkSections.length]; - System.arraycopy(chunkSections, 0, this.sections, 0, chunkSections.length); - this.reset(); - } - if (this.sections == null) { - this.sections = new LevelChunkSection[chunkSections.length]; - System.arraycopy(chunkSections, 0, this.sections, 0, chunkSections.length); - } - if (this.sections[layer] != section) { - // Not sure why it's funky, but it's what I did in commit fda7d00747abe97d7891b80ed8bb88d97e1c70d1 and I don't want to touch it >dords - this.sections[layer] = new LevelChunkSection[]{section}.clone()[0]; - } - } finally { - sectionLock.writeLock().unlock(); - } - this.blocks[layer] = arr; - } - - private char[] loadPrivately(int layer) { - layer -= getMinSectionPosition(); - if (super.sections[layer] != null) { - synchronized (super.sectionLocks[layer]) { - if (super.sections[layer].isFull() && super.blocks[layer] != null) { - return super.blocks[layer]; - } - } - } - return PaperweightGetBlocks.this.update(layer, null, true); - } - - @Override - public void send() { - synchronized (sendLock) { - PaperweightPlatformAdapter.sendChunk(this, serverLevel, chunkX, chunkZ); - } - } - - /** - * Update a given (nullable) data array to the current data stored in the server's chunk, associated with this - * {@link PaperweightPlatformAdapter} instance. Not synchronised to the {@link PaperweightPlatformAdapter} instance as synchronisation - * is handled where necessary in the method, and should otherwise be handled correctly by this method's caller. - * - * @param layer layer index (0 may denote a negative layer in the world, e.g. at y=-32) - * @param data array to be updated/filled with data or null - * @param aggressive if the cached section array should be re-acquired. - * @return the given array to be filled with data, or a new array if null is given. - */ - @Override - @SuppressWarnings("unchecked") - public char[] update(int layer, char[] data, boolean aggressive) { - LevelChunkSection section = getSections(aggressive)[layer]; - // Section is null, return empty array - if (section == null) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - return data; - } - if (data != null && data.length != 4096) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - } - if (data == null || data == FaweCache.INSTANCE.EMPTY_CHAR_4096) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - } - Semaphore lock = PaperweightPlatformAdapter.applyLock(section); - synchronized (lock) { - // Efficiently convert ChunkSection to raw data - try { - lock.acquire(); - - final PalettedContainer blocks = section.getStates(); - final Object dataObject = PaperweightPlatformAdapter.fieldData.get(blocks); - final BitStorage bits = (BitStorage) PaperweightPlatformAdapter.fieldStorage.get(dataObject); - - if (bits instanceof ZeroBitStorage) { - Arrays.fill(data, adapter.adaptToChar(blocks.get(0, 0, 0))); // get(int) is only public on paper - return data; - } - - final Palette palette = (Palette) PaperweightPlatformAdapter.fieldPalette.get(dataObject); - - final int bitsPerEntry = bits.getBits(); - final long[] blockStates = bits.getRaw(); - - new BitArrayUnstretched(bitsPerEntry, 4096, blockStates).toRaw(data); - - int num_palette; - if (palette instanceof LinearPalette || palette instanceof HashMapPalette) { - num_palette = palette.getSize(); - } else { - // The section's palette is the global block palette. - for (int i = 0; i < 4096; i++) { - char paletteVal = data[i]; - char ordinal = adapter.ibdIDToOrdinal(paletteVal); - data[i] = ordinal; - } - return data; - } - - char[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK_CHAR.get(); - try { - if (num_palette != 1) { - for (int i = 0; i < num_palette; i++) { - char ordinal = ordinal(palette.valueFor(i), adapter); - paletteToOrdinal[i] = ordinal; - } - for (int i = 0; i < 4096; i++) { - char paletteVal = data[i]; - char val = paletteToOrdinal[paletteVal]; - if (val == Character.MAX_VALUE) { - val = ordinal(palette.valueFor(i), adapter); - paletteToOrdinal[i] = val; - } - data[i] = val; - } - } else { - char ordinal = ordinal(palette.valueFor(0), adapter); - Arrays.fill(data, ordinal); - } - } finally { - for (int i = 0; i < num_palette; i++) { - paletteToOrdinal[i] = Character.MAX_VALUE; - } - } - return data; - } catch (IllegalAccessException | InterruptedException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } finally { - lock.release(); - } - } - } - - private char ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { - if (ibd == null) { - return BlockTypesCache.ReservedIDs.AIR; - } else { - return adapter.adaptToChar(ibd); - } - } - - public LevelChunkSection[] getSections(boolean force) { - force &= forceLoadSections; - LevelChunkSection[] tmp = sections; - if (tmp == null || force) { - try { - sectionLock.writeLock().lock(); - tmp = sections; - if (tmp == null || force) { - LevelChunkSection[] chunkSections = getChunk().getSections(); - tmp = new LevelChunkSection[chunkSections.length]; - System.arraycopy(chunkSections, 0, tmp, 0, chunkSections.length); - sections = tmp; - } - } finally { - sectionLock.writeLock().unlock(); - } - } - return tmp; - } - - public LevelChunk getChunk() { - LevelChunk levelChunk = this.levelChunk; - if (levelChunk == null) { - synchronized (this) { - levelChunk = this.levelChunk; - if (levelChunk == null) { - this.levelChunk = levelChunk = ensureLoaded(this.serverLevel, chunkX, chunkZ); - } - } - } - return levelChunk; - } - - private void fillLightNibble(char[][] light, LightLayer lightLayer, int minSectionPosition, int maxSectionPosition) { - for (int Y = 0; Y <= maxSectionPosition - minSectionPosition; Y++) { - if (light[Y] == null) { - continue; - } - SectionPos sectionPos = SectionPos.of(levelChunk.getPos(), Y + minSectionPosition); - DataLayer dataLayer = serverLevel.getChunkSource().getLightEngine().getLayerListener(lightLayer).getDataLayerData( - sectionPos); - if (dataLayer == null) { - byte[] LAYER_COUNT = new byte[2048]; - Arrays.fill(LAYER_COUNT, lightLayer == LightLayer.SKY ? (byte) 15 : (byte) 0); - dataLayer = new DataLayer(LAYER_COUNT); - ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData( - lightLayer, - sectionPos, - dataLayer, - true - ); - } - synchronized (dataLayer) { - for (int x = 0; x < 16; x++) { - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - int i = y << 8 | z << 4 | x; - if (light[Y][i] < 16) { - dataLayer.set(x, y, z, light[Y][i]); - } - } - } - } - } - } - } - - private PalettedContainer> setBiomesToPalettedContainer( - final BiomeType[][] biomes, - final int sectionIndex, - final PalettedContainerRO> data - ) { - BiomeType[] sectionBiomes; - if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { - return null; - } - PalettedContainer> biomeData = data.recreate(); - for (int y = 0, index = 0; y < 4; y++) { - for (int z = 0; z < 4; z++) { - for (int x = 0; x < 4; x++, index++) { - BiomeType biomeType = sectionBiomes[index]; - if (biomeType == null) { - biomeData.set(x, y, z, data.get(x, y, z)); - } else { - biomeData.set( - x, - y, - z, - biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) - ); - } - } - } - } - return biomeData; - } - - @Override - public boolean hasSection(int layer) { - layer -= getMinSectionPosition(); - return getSections(false)[layer] != null; - } - - @Override - @SuppressWarnings("unchecked") - public synchronized boolean trim(boolean aggressive) { - skyLight = new DataLayer[getSectionCount()]; - blockLight = new DataLayer[getSectionCount()]; - if (aggressive) { - sectionLock.writeLock().lock(); - sections = null; - levelChunk = null; - sectionLock.writeLock().unlock(); - return super.trim(true); - } else if (sections == null) { - // don't bother trimming if there are no sections stored. - return true; - } else { - for (int i = getMinSectionPosition(); i <= getMaxSectionPosition(); i++) { - int layer = i - getMinSectionPosition(); - if (!hasSection(i) || !super.sections[layer].isFull()) { - continue; - } - LevelChunkSection existing = getSections(true)[layer]; - try { - final PalettedContainer blocksExisting = existing.getStates(); - - final Object dataObject = PaperweightPlatformAdapter.fieldData.get(blocksExisting); - final Palette palette = (Palette) PaperweightPlatformAdapter.fieldPalette.get( - dataObject); - int paletteSize; - - if (palette instanceof LinearPalette || palette instanceof HashMapPalette) { - paletteSize = palette.getSize(); - } else { - super.trim(false, i); - continue; - } - if (paletteSize == 1) { - //If the cached palette size is 1 then no blocks can have been changed i.e. do not need to update these chunks. - continue; - } - super.trim(false, i); - } catch (IllegalAccessException ignored) { - super.trim(false, i); - } - } - return true; - } - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks_Copy.java deleted file mode 100644 index dd1787868..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks_Copy.java +++ /dev/null @@ -1,259 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3; - -import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType; -import com.fastasyncworldedit.core.queue.IBlocks; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.queue.IChunkSet; -import com.google.common.base.Suppliers; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.math.BlockVector3; -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.BlockTypesCache; -import net.minecraft.core.Holder; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.PalettedContainer; -import net.minecraft.world.level.chunk.PalettedContainerRO; -import org.apache.logging.log4j.Logger; - -import javax.annotation.Nullable; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Future; - -public class PaperweightGetBlocks_Copy implements IChunkGet { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - - private final Map tiles = new HashMap<>(); - private final Set entities = new HashSet<>(); - private final char[][] blocks; - private final int minHeight; - private final int maxHeight; - final ServerLevel serverLevel; - final LevelChunk levelChunk; - private Holder[][] biomes = null; - - protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { - this.levelChunk = levelChunk; - this.serverLevel = levelChunk.level; - this.minHeight = serverLevel.getMinBuildHeight(); - this.maxHeight = serverLevel.getMaxBuildHeight() - 1; // Minecraft max limit is exclusive. - this.blocks = new char[getSectionCount()][]; - } - - protected void storeTile(BlockEntity blockEntity) { - tiles.put( - BlockVector3.at( - blockEntity.getBlockPos().getX(), - blockEntity.getBlockPos().getY(), - blockEntity.getBlockPos().getZ() - ), - new PaperweightLazyCompoundTag(Suppliers.memoize(blockEntity::saveWithId)) - ); - } - - @Override - public Map getTiles() { - return tiles; - } - - @Override - @Nullable - public CompoundTag getTile(int x, int y, int z) { - return tiles.get(BlockVector3.at(x, y, z)); - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - protected void storeEntity(Entity entity) { - BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); - net.minecraft.nbt.CompoundTag compoundTag = new net.minecraft.nbt.CompoundTag(); - PaperweightPlatformAdapter.readEntityIntoTag(entity, compoundTag); - entities.add((CompoundTag) adapter.toNative(compoundTag)); - } - - @Override - public Set getEntities() { - return this.entities; - } - - @Override - public CompoundTag getEntity(UUID uuid) { - for (CompoundTag tag : entities) { - if (uuid.equals(tag.getUUID())) { - return tag; - } - } - return null; - } - - @Override - public boolean isCreateCopy() { - return false; - } - - @Override - public int setCreateCopy(boolean createCopy) { - return -1; - } - - @Override - public void setLightingToGet(char[][] lighting, int minSectionPosition, int maxSectionPosition) { - } - - @Override - public void setSkyLightingToGet(char[][] lighting, int minSectionPosition, int maxSectionPosition) { - } - - @Override - public void setHeightmapToGet(HeightMapType type, int[] data) { - } - - @Override - public int getMaxY() { - return maxHeight; - } - - @Override - public int getMinY() { - return minHeight; - } - - @Override - public int getMaxSectionPosition() { - return maxHeight >> 4; - } - - @Override - public int getMinSectionPosition() { - return minHeight >> 4; - } - - @Override - public BiomeType getBiomeType(int x, int y, int z) { - Holder biome = biomes[(y >> 4) - getMinSectionPosition()][(y & 12) << 2 | (z & 12) | (x & 12) >> 2]; - return PaperweightPlatformAdapter.adapt(biome, serverLevel); - } - - @Override - public void removeSectionLighting(int layer, boolean sky) { - } - - @Override - public boolean trim(boolean aggressive, int layer) { - return false; - } - - @Override - public IBlocks reset() { - return null; - } - - @Override - public int getSectionCount() { - return serverLevel.getSectionsCount(); - } - - protected void storeSection(int layer, char[] data) { - blocks[layer] = data; - } - - protected void storeBiomes(int layer, PalettedContainerRO> biomeData) { - if (biomes == null) { - biomes = new Holder[getSectionCount()][]; - } - if (biomes[layer] == null) { - biomes[layer] = new Holder[64]; - } - if (biomeData instanceof PalettedContainer> palettedContainer) { - for (int i = 0; i < 64; i++) { - biomes[layer][i] = palettedContainer.get(i); - } - } else { - LOGGER.error( - "Cannot correctly save biomes to history. Expected class type {} but got {}", - PalettedContainer.class.getSimpleName(), - biomeData.getClass().getSimpleName() - ); - } - } - - @Override - public BaseBlock getFullBlock(int x, int y, int z) { - BlockState state = BlockTypesCache.states[get(x, y, z)]; - return state.toBaseBlock(this, x, y, z); - } - - @Override - public boolean hasSection(int layer) { - layer -= getMinSectionPosition(); - return blocks[layer] != null; - } - - @Override - public char[] load(int layer) { - layer -= getMinSectionPosition(); - if (blocks[layer] == null) { - blocks[layer] = new char[4096]; - Arrays.fill(blocks[layer], (char) BlockTypesCache.ReservedIDs.AIR); - } - return blocks[layer]; - } - - @Override - public char[] loadIfPresent(int layer) { - layer -= getMinSectionPosition(); - return blocks[layer]; - } - - @Override - public BlockState getBlock(int x, int y, int z) { - return BlockTypesCache.states[get(x, y, z)]; - } - - @Override - public int getSkyLight(int x, int y, int z) { - return 0; - } - - @Override - public int getEmittedLight(int x, int y, int z) { - return 0; - } - - @Override - public int[] getHeightMap(HeightMapType type) { - return new int[0]; - } - - @Override - public > T call(IChunkSet set, Runnable finalize) { - return null; - } - - public char get(int x, int y, int z) { - final int layer = (y >> 4) - getMinSectionPosition(); - final int index = (y & 15) << 8 | z << 4 | x; - return blocks[layer][index]; - } - - - @Override - public boolean trim(boolean aggressive) { - return false; - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightMapChunkUtil.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightMapChunkUtil.java deleted file mode 100644 index 7c7f39d9a..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightMapChunkUtil.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3; - -import com.fastasyncworldedit.bukkit.adapter.MapChunkUtil; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData; -import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; - -//TODO un-very-break-this -public class PaperweightMapChunkUtil extends MapChunkUtil { - - public PaperweightMapChunkUtil() throws NoSuchFieldException { - fieldX = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("TWO_MEGABYTES", "a")); - fieldZ = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("x", "a")); - fieldBitMask = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("z", "b")); - fieldHeightMap = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("heightmaps", "b")); - fieldChunkData = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("chunkData", "c")); - fieldBlockEntities = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("buffer", "c")); - fieldFull = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("blockEntitiesData", "d")); - fieldX.setAccessible(true); - fieldZ.setAccessible(true); - fieldBitMask.setAccessible(true); - fieldHeightMap.setAccessible(true); - fieldChunkData.setAccessible(true); - fieldBlockEntities.setAccessible(true); - fieldFull.setAccessible(true); - } - - @Override - public ClientboundLevelChunkWithLightPacket createPacket() { - // TODO ??? return new ClientboundLevelChunkPacket(); - throw new UnsupportedOperationException(); - } - -} 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 deleted file mode 100644 index aec3cfd24..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java +++ /dev/null @@ -1,748 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3; - -import com.destroystokyo.paper.util.maplist.EntityList; -import com.fastasyncworldedit.bukkit.adapter.CachedBukkitAdapter; -import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore; -import com.fastasyncworldedit.bukkit.adapter.NMSAdapter; -import com.fastasyncworldedit.core.Fawe; -import com.fastasyncworldedit.core.FaweCache; -import com.fastasyncworldedit.core.math.BitArrayUnstretched; -import com.fastasyncworldedit.core.util.MathMan; -import com.fastasyncworldedit.core.util.ReflectionUtils; -import com.fastasyncworldedit.core.util.TaskManager; -import com.mojang.datafixers.util.Either; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.biome.BiomeTypes; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockTypesCache; -import io.papermc.lib.PaperLib; -import io.papermc.paper.world.ChunkEntitySlices; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.core.IdMap; -import net.minecraft.core.Registry; -import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.server.level.ChunkMap; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.level.TicketType; -import net.minecraft.util.BitStorage; -import net.minecraft.util.ExceptionCollector; -import net.minecraft.util.SimpleBitStorage; -import net.minecraft.util.ThreadingDetector; -import net.minecraft.util.Unit; -import net.minecraft.util.ZeroBitStorage; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.npc.AbstractVillager; -import net.minecraft.world.item.trading.MerchantOffers; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.chunk.ChunkStatus; -import net.minecraft.world.level.chunk.GlobalPalette; -import net.minecraft.world.level.chunk.HashMapPalette; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.LevelChunkSection; -import net.minecraft.world.level.chunk.LinearPalette; -import net.minecraft.world.level.chunk.Palette; -import net.minecraft.world.level.chunk.PalettedContainer; -import net.minecraft.world.level.chunk.SingleValuePalette; -import net.minecraft.world.level.entity.PersistentEntitySectionManager; -import org.apache.logging.log4j.Logger; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_19_R3.CraftChunk; -import sun.misc.Unsafe; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.function.Function; - -import static net.minecraft.core.registries.Registries.BIOME; - -public final class PaperweightPlatformAdapter extends NMSAdapter { - - public static final Field fieldData; - - public static final Constructor dataConstructor; - - public static final Field fieldStorage; - public static final Field fieldPalette; - - private static final Field fieldTickingFluidCount; - private static final Field fieldTickingBlockCount; - private static final Field fieldBiomes; - - private static final MethodHandle methodGetVisibleChunk; - - private static final Field fieldThreadingDetector; - private static final Field fieldLock; - - private static final MethodHandle methodRemoveGameEventListener; - private static final MethodHandle methodremoveTickingBlockEntity; - - private static final Field fieldOffers; - private static final MerchantOffers OFFERS = new MerchantOffers(); - - private static final Field fieldRemove; - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - - static final boolean POST_CHUNK_REWRITE; - private static Method PAPER_CHUNK_GEN_ALL_ENTITIES; - private static Field LEVEL_CHUNK_ENTITIES; - private static Field SERVER_LEVEL_ENTITY_MANAGER; - - static { - final MethodHandles.Lookup lookup = MethodHandles.lookup(); - try { - fieldData = PalettedContainer.class.getDeclaredField(Refraction.pickName("data", "d")); - fieldData.setAccessible(true); - - Class dataClazz = fieldData.getType(); - dataConstructor = dataClazz.getDeclaredConstructors()[0]; - dataConstructor.setAccessible(true); - - fieldStorage = dataClazz.getDeclaredField(Refraction.pickName("storage", "b")); - fieldStorage.setAccessible(true); - fieldPalette = dataClazz.getDeclaredField(Refraction.pickName("palette", "c")); - fieldPalette.setAccessible(true); - - fieldTickingFluidCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingFluidCount", "h")); - fieldTickingFluidCount.setAccessible(true); - fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "g")); - fieldTickingBlockCount.setAccessible(true); - Field tmpFieldBiomes; - try { - // It seems to actually be biomes, but is apparently obfuscated to "j" - tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("biomes"); - } catch (NoSuchFieldException ignored) { - tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("j"); - } - fieldBiomes = tmpFieldBiomes; - fieldBiomes.setAccessible(true); - - Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( - "getVisibleChunkIfPresent", - "b" - ), long.class); - getVisibleChunkIfPresent.setAccessible(true); - methodGetVisibleChunk = lookup.unreflect(getVisibleChunkIfPresent); - - if (!PaperLib.isPaper()) { - fieldThreadingDetector = PalettedContainer.class.getDeclaredField(Refraction.pickName("threadingDetector", "f")); - fieldThreadingDetector.setAccessible(true); - fieldLock = ThreadingDetector.class.getDeclaredField(Refraction.pickName("lock", "c")); - fieldLock.setAccessible(true); - } else { - // in paper, the used methods are synchronized properly - fieldThreadingDetector = null; - fieldLock = null; - } - - Method removeGameEventListener = LevelChunk.class.getDeclaredMethod( - Refraction.pickName("removeGameEventListener", "a"), - BlockEntity.class, - ServerLevel.class - ); - removeGameEventListener.setAccessible(true); - methodRemoveGameEventListener = lookup.unreflect(removeGameEventListener); - - Method removeBlockEntityTicker = LevelChunk.class.getDeclaredMethod( - Refraction.pickName( - "removeBlockEntityTicker", - "l" - ), BlockPos.class - ); - removeBlockEntityTicker.setAccessible(true); - methodremoveTickingBlockEntity = lookup.unreflect(removeBlockEntityTicker); - - fieldRemove = BlockEntity.class.getDeclaredField(Refraction.pickName("remove", "q")); - fieldRemove.setAccessible(true); - - boolean chunkRewrite; - try { - ServerLevel.class.getDeclaredMethod("getEntityLookup"); - chunkRewrite = true; - PAPER_CHUNK_GEN_ALL_ENTITIES = ChunkEntitySlices.class.getDeclaredMethod("getAllEntities"); - PAPER_CHUNK_GEN_ALL_ENTITIES.setAccessible(true); - } catch (NoSuchMethodException ignored) { - chunkRewrite = false; - } - try { - // Paper - Pre-Chunk-Update - LEVEL_CHUNK_ENTITIES = LevelChunk.class.getDeclaredField("entities"); - LEVEL_CHUNK_ENTITIES.setAccessible(true); - } catch (NoSuchFieldException ignored) { - } - try { - // Non-Paper - SERVER_LEVEL_ENTITY_MANAGER = ServerLevel.class.getDeclaredField(Refraction.pickName("entityManager", "L")); - SERVER_LEVEL_ENTITY_MANAGER.setAccessible(true); - } catch (NoSuchFieldException ignored) { - } - POST_CHUNK_REWRITE = chunkRewrite; - - fieldOffers = AbstractVillager.class.getDeclaredField(Refraction.pickName("offers", "bT")); - fieldOffers.setAccessible(true); - } catch (RuntimeException | Error e) { - throw e; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - static boolean setSectionAtomic( - LevelChunkSection[] sections, - LevelChunkSection expected, - LevelChunkSection value, - int layer - ) { - if (layer >= 0 && layer < sections.length) { - return ReflectionUtils.compareAndSet(sections, expected, value, layer); - } - return false; - } - - // There is no point in having a functional semaphore for paper servers. - private static final ThreadLocal SEMAPHORE_THREAD_LOCAL = - ThreadLocal.withInitial(() -> new DelegateSemaphore(1, null)); - - static DelegateSemaphore applyLock(LevelChunkSection section) { - if (PaperLib.isPaper()) { - return SEMAPHORE_THREAD_LOCAL.get(); - } - try { - synchronized (section) { - PalettedContainer blocks = section.getStates(); - ThreadingDetector currentThreadingDetector = (ThreadingDetector) fieldThreadingDetector.get(blocks); - synchronized (currentThreadingDetector) { - Semaphore currentLock = (Semaphore) fieldLock.get(currentThreadingDetector); - if (currentLock instanceof DelegateSemaphore delegateSemaphore) { - return delegateSemaphore; - } - DelegateSemaphore newLock = new DelegateSemaphore(1, currentLock); - fieldLock.set(currentThreadingDetector, newLock); - return newLock; - } - } - } catch (Throwable e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - - public static LevelChunk ensureLoaded(ServerLevel serverLevel, int chunkX, int chunkZ) { - if (!PaperLib.isPaper()) { - LevelChunk nmsChunk = serverLevel.getChunkSource().getChunk(chunkX, chunkZ, false); - if (nmsChunk != null) { - return nmsChunk; - } - if (Fawe.isMainThread()) { - return serverLevel.getChunk(chunkX, chunkZ); - } - } else { - LevelChunk nmsChunk = serverLevel.getChunkSource().getChunkAtIfCachedImmediately(chunkX, chunkZ); - if (nmsChunk != null) { - addTicket(serverLevel, chunkX, chunkZ); - return nmsChunk; - } - nmsChunk = serverLevel.getChunkSource().getChunkAtIfLoadedImmediately(chunkX, chunkZ); - if (nmsChunk != null) { - addTicket(serverLevel, chunkX, chunkZ); - return nmsChunk; - } - // Avoid "async" methods from the main thread. - if (Fawe.isMainThread()) { - return serverLevel.getChunk(chunkX, chunkZ); - } - CompletableFuture future = serverLevel.getWorld().getChunkAtAsync(chunkX, chunkZ, true, true); - try { - CraftChunk chunk; - try { - chunk = (CraftChunk) future.get(10, TimeUnit.SECONDS); - } catch (TimeoutException e) { - String world = serverLevel.getWorld().getName(); - // We've already taken 10 seconds we can afford to wait a little here. - boolean loaded = TaskManager.taskManager().sync(() -> Bukkit.getWorld(world) != null); - if (loaded) { - LOGGER.warn("Chunk {},{} failed to load in 10 seconds in world {}. Retrying...", chunkX, chunkZ, world); - // Retry chunk load - chunk = (CraftChunk) serverLevel.getWorld().getChunkAtAsync(chunkX, chunkZ, true, true).get(); - } else { - throw new UnsupportedOperationException("Cannot load chunk from unloaded world " + world + "!"); - } - } - addTicket(serverLevel, chunkX, chunkZ); - return (LevelChunk) chunk.getHandle(ChunkStatus.FULL); - } catch (Throwable e) { - e.printStackTrace(); - } - } - return TaskManager.taskManager().sync(() -> serverLevel.getChunk(chunkX, chunkZ)); - } - - private static void addTicket(ServerLevel serverLevel, int chunkX, int chunkZ) { - // Ensure chunk is definitely loaded before applying a ticket - io.papermc.paper.util.MCUtil.MAIN_EXECUTOR.execute(() -> serverLevel - .getChunkSource() - .addRegionTicket(TicketType.UNLOAD_COOLDOWN, new ChunkPos(chunkX, chunkZ), 0, Unit.INSTANCE)); - } - - public static ChunkHolder getPlayerChunk(ServerLevel nmsWorld, final int chunkX, final int chunkZ) { - ChunkMap chunkMap = nmsWorld.getChunkSource().chunkMap; - try { - return (ChunkHolder) methodGetVisibleChunk.invoke(chunkMap, ChunkPos.asLong(chunkX, chunkZ)); - } catch (Throwable thr) { - throw new RuntimeException(thr); - } - } - - @SuppressWarnings("deprecation") - public static void sendChunk(Object chunk, ServerLevel nmsWorld, int chunkX, int chunkZ) { - ChunkHolder chunkHolder = getPlayerChunk(nmsWorld, chunkX, chunkZ); - if (chunkHolder == null) { - return; - } - ChunkPos coordIntPair = new ChunkPos(chunkX, chunkZ); - LevelChunk levelChunk; - if (PaperLib.isPaper()) { - // getChunkAtIfLoadedImmediately is paper only - levelChunk = nmsWorld - .getChunkSource() - .getChunkAtIfLoadedImmediately(chunkX, chunkZ); - } else { - levelChunk = ((Optional) ((Either) chunkHolder - .getTickingChunkFuture() // method is not present with new paper chunk system - .getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left()) - .orElse(null); - } - if (levelChunk == null) { - return; - } - MinecraftServer.getServer().execute(() -> { - ClientboundLevelChunkWithLightPacket packet; - if (PaperLib.isPaper()) { - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null, - true, - false // last false is to not bother with x-ray - ); - } else { - // deprecated on paper - deprecation suppressed - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null, - true - ); - } - nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet)); - }); - } - - private static List nearbyPlayers(ServerLevel serverLevel, ChunkPos coordIntPair) { - return serverLevel.getChunkSource().chunkMap.getPlayers(coordIntPair, false); - } - - /* - NMS conversion - */ - public static LevelChunkSection newChunkSection( - final int layer, - final char[] blocks, - CachedBukkitAdapter adapter, - Registry biomeRegistry, - @Nullable PalettedContainer> biomes - ) { - return newChunkSection(layer, null, blocks, adapter, biomeRegistry, biomes); - } - - public static LevelChunkSection newChunkSection( - final int layer, - final Function get, - char[] set, - CachedBukkitAdapter adapter, - Registry biomeRegistry, - @Nullable PalettedContainer> biomes - ) { - if (set == null) { - return newChunkSection(layer, biomeRegistry, biomes); - } - final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get(); - final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); - final long[] blockStates = FaweCache.INSTANCE.BLOCK_STATES.get(); - final int[] blocksCopy = FaweCache.INSTANCE.SECTION_BLOCKS.get(); - try { - int num_palette; - if (get == null) { - num_palette = createPalette(blockToPalette, paletteToBlock, blocksCopy, set, adapter, null); - } else { - num_palette = createPalette(layer, blockToPalette, paletteToBlock, blocksCopy, get, set, adapter, null); - } - - int bitsPerEntry = MathMan.log2nlz(num_palette - 1); - if (bitsPerEntry > 0 && bitsPerEntry < 5) { - bitsPerEntry = 4; - } else if (bitsPerEntry > 8) { - bitsPerEntry = MathMan.log2nlz(Block.BLOCK_STATE_REGISTRY.size() - 1); - } - - int bitsPerEntryNonZero = Math.max(bitsPerEntry, 1); // We do want to use zero sometimes - final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntryNonZero); - final int blockBitArrayEnd = MathMan.ceilZero((float) 4096 / blocksPerLong); - - if (num_palette == 1) { - for (int i = 0; i < blockBitArrayEnd; i++) { - blockStates[i] = 0; - } - } else { - final BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntryNonZero, 4096, blockStates); - bitArray.fromRaw(blocksCopy); - } - - final long[] bits = Arrays.copyOfRange(blockStates, 0, blockBitArrayEnd); - final BitStorage nmsBits; - if (bitsPerEntry == 0) { - nmsBits = new ZeroBitStorage(4096); - } else { - nmsBits = new SimpleBitStorage(bitsPerEntry, 4096, bits); - } - List palette; - if (bitsPerEntry < 9) { - palette = new ArrayList<>(); - for (int i = 0; i < num_palette; i++) { - int ordinal = paletteToBlock[i]; - blockToPalette[ordinal] = Integer.MAX_VALUE; - final BlockState state = BlockTypesCache.states[ordinal]; - palette.add(((PaperweightBlockMaterial) state.getMaterial()).getState()); - } - } else { - palette = List.of(); - } - - // Create palette with data - @SuppressWarnings("deprecation") // constructor is deprecated on paper, but needed to keep compatibility with spigot - final PalettedContainer blockStatePalettedContainer = - new PalettedContainer<>( - Block.BLOCK_STATE_REGISTRY, - PalettedContainer.Strategy.SECTION_STATES, - PalettedContainer.Strategy.SECTION_STATES.getConfiguration(Block.BLOCK_STATE_REGISTRY, bitsPerEntry), - nmsBits, - palette - ); - if (biomes == null) { - IdMap> biomeHolderIdMap = biomeRegistry.asHolderIdMap(); - biomes = new PalettedContainer<>( - biomeHolderIdMap, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId( - BiomeTypes.PLAINS)), - PalettedContainer.Strategy.SECTION_BIOMES, - null - ); - } - - return new LevelChunkSection(layer, blockStatePalettedContainer, biomes); - } catch (final Throwable e) { - throw e; - } finally { - Arrays.fill(blockToPalette, Integer.MAX_VALUE); - Arrays.fill(paletteToBlock, Integer.MAX_VALUE); - Arrays.fill(blockStates, 0); - Arrays.fill(blocksCopy, 0); - } - } - - @SuppressWarnings("deprecation") // Only deprecated in paper - private static LevelChunkSection newChunkSection( - int layer, - Registry biomeRegistry, - @Nullable PalettedContainer> biomes - ) { - if (biomes == null) { - return new LevelChunkSection(layer, biomeRegistry); - } - PalettedContainer dataPaletteBlocks = new PalettedContainer<>( - Block.BLOCK_STATE_REGISTRY, - Blocks.AIR.defaultBlockState(), - PalettedContainer.Strategy.SECTION_STATES, - null - ); - return new LevelChunkSection(layer, dataPaletteBlocks, biomes); - } - - public static void setBiomesToChunkSection(LevelChunkSection section, PalettedContainer> biomes) { - try { - fieldBiomes.set(section, biomes); - } catch (IllegalAccessException e) { - LOGGER.error("Could not set biomes to chunk section", e); - } - } - - /** - * Create a new {@link PalettedContainer}. Should only be used if no biome container existed beforehand. - */ - public static PalettedContainer> getBiomePalettedContainer( - BiomeType[] biomes, - IdMap> biomeRegistry - ) { - if (biomes == null) { - return null; - } - BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); - // Don't stream this as typically will see 1-4 biomes; stream overhead is large for the small length - Map> palette = new HashMap<>(); - for (BiomeType biomeType : new LinkedList<>(Arrays.asList(biomes))) { - Holder biome; - if (biomeType == null) { - biome = biomeRegistry.byId(adapter.getInternalBiomeId(BiomeTypes.PLAINS)); - } else { - biome = biomeRegistry.byId(adapter.getInternalBiomeId(biomeType)); - } - palette.put(biomeType, biome); - } - int biomeCount = palette.size(); - int bitsPerEntry = MathMan.log2nlz(biomeCount - 1); - Object configuration = PalettedContainer.Strategy.SECTION_STATES.getConfiguration( - new FakeIdMapBiome(biomeCount), - bitsPerEntry - ); - if (bitsPerEntry > 3) { - bitsPerEntry = MathMan.log2nlz(biomeRegistry.size() - 1); - } - PalettedContainer> biomePalettedContainer = new PalettedContainer<>( - biomeRegistry, - biomeRegistry.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)), - PalettedContainer.Strategy.SECTION_BIOMES, - null - ); - - final Palette> biomePalette; - if (bitsPerEntry == 0) { - biomePalette = new SingleValuePalette<>( - biomePalettedContainer.registry, - biomePalettedContainer, - new ArrayList<>(palette.values()) // Must be modifiable - ); - } else if (bitsPerEntry == 4) { - biomePalette = LinearPalette.create( - 4, - biomePalettedContainer.registry, - biomePalettedContainer, - new ArrayList<>(palette.values()) // Must be modifiable - ); - } else if (bitsPerEntry < 9) { - biomePalette = HashMapPalette.create( - bitsPerEntry, - biomePalettedContainer.registry, - biomePalettedContainer, - new ArrayList<>(palette.values()) // Must be modifiable - ); - } else { - biomePalette = GlobalPalette.create( - bitsPerEntry, - biomePalettedContainer.registry, - biomePalettedContainer, - null // unused - ); - } - - int bitsPerEntryNonZero = Math.max(bitsPerEntry, 1); // We do want to use zero sometimes - final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntryNonZero); - final int arrayLength = MathMan.ceilZero(64f / blocksPerLong); - - - BitStorage bitStorage = bitsPerEntry == 0 ? new ZeroBitStorage(64) : new SimpleBitStorage( - bitsPerEntry, - 64, - new long[arrayLength] - ); - - try { - Object data = dataConstructor.newInstance(configuration, bitStorage, biomePalette); - fieldData.set(biomePalettedContainer, data); - int index = 0; - for (int y = 0; y < 4; y++) { - for (int z = 0; z < 4; z++) { - for (int x = 0; x < 4; x++, index++) { - BiomeType biomeType = biomes[index]; - if (biomeType == null) { - continue; - } - Holder biome = biomeRegistry.byId(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId(biomeType)); - if (biome == null) { - continue; - } - biomePalettedContainer.set(x, y, z, biome); - } - } - } - } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - return biomePalettedContainer; - } - - public static void clearCounts(final LevelChunkSection section) throws IllegalAccessException { - fieldTickingFluidCount.setShort(section, (short) 0); - fieldTickingBlockCount.setShort(section, (short) 0); - } - - public static BiomeType adapt(Holder biome, LevelAccessor levelAccessor) { - final Registry biomeRegistry = levelAccessor.registryAccess().registryOrThrow(BIOME); - if (biomeRegistry.getKey(biome.value()) == null) { - return biomeRegistry.asHolderIdMap().getId(biome) == -1 ? BiomeTypes.OCEAN - : null; - } - return BiomeTypes.get(biome.unwrapKey().orElseThrow().location().toString()); - } - - static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) { - try { - if (levelChunk.loaded || levelChunk.level.isClientSide()) { - BlockEntity blockEntity = levelChunk.blockEntities.remove(beacon.getBlockPos()); - if (blockEntity != null) { - if (!levelChunk.level.isClientSide) { - methodRemoveGameEventListener.invoke(levelChunk, beacon, levelChunk.level); - } - fieldRemove.set(beacon, true); - } - } - methodremoveTickingBlockEntity.invoke(levelChunk, beacon.getBlockPos()); - } catch (Throwable throwable) { - throwable.printStackTrace(); - } - } - - static List getEntities(LevelChunk chunk) { - ExceptionCollector collector = new ExceptionCollector<>(); - if (PaperLib.isPaper()) { - if (POST_CHUNK_REWRITE) { - try { - //noinspection unchecked - return (List) PAPER_CHUNK_GEN_ALL_ENTITIES.invoke(chunk.level.getEntityLookup().getChunk(chunk.locX, chunk.locZ)); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException("Failed to lookup entities [POST_CHUNK_REWRITE=true]", e); - } - } - try { - EntityList entityList = (EntityList) LEVEL_CHUNK_ENTITIES.get(chunk); - return List.of(entityList.getRawData()); - } catch (IllegalAccessException e) { - collector.add(new RuntimeException("Failed to lookup entities [POST_CHUNK_REWRITE=false]", e)); - // fall through - } - } - try { - //noinspection unchecked - return ((PersistentEntitySectionManager) (SERVER_LEVEL_ENTITY_MANAGER.get(chunk.level))).getEntities(chunk.getPos()); - } catch (IllegalAccessException e) { - collector.add(new RuntimeException("Failed to lookup entities [PAPER=false]", e)); - } - collector.throwIfPresent(); - return List.of(); - } - - public static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag compoundTag) { - boolean isVillager = entity instanceof AbstractVillager && !Fawe.isMainThread(); - boolean unset = false; - if (isVillager) { - try { - if (fieldOffers.get(entity) != null) { - fieldOffers.set(entity, OFFERS); - unset = true; - } - } catch (IllegalAccessException e) { - throw new RuntimeException("Failed to set offers field to villager to avoid async catcher.", e); - } - } - entity.save(compoundTag); - if (unset) { - try { - fieldOffers.set(entity, null); - } catch (IllegalAccessException e) { - throw new RuntimeException("Failed to set offers field to null again on villager.", e); - } - } - } - - record FakeIdMapBlock(int size) implements IdMap { - - @Override - public int getId(final net.minecraft.world.level.block.state.BlockState entry) { - return 0; - } - - @Nullable - @Override - public net.minecraft.world.level.block.state.BlockState byId(final int index) { - return null; - } - - @Nonnull - @Override - public Iterator iterator() { - return Collections.emptyIterator(); - } - - } - - record FakeIdMapBiome(int size) implements IdMap { - - @Override - public int getId(final Biome entry) { - return 0; - } - - @Nullable - @Override - public Biome byId(final int index) { - return null; - } - - @Nonnull - @Override - public Iterator iterator() { - return Collections.emptyIterator(); - } - - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPostProcessor.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPostProcessor.java deleted file mode 100644 index ac10f2c0a..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPostProcessor.java +++ /dev/null @@ -1,175 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3; - -import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.extent.processor.ProcessorScope; -import com.fastasyncworldedit.core.queue.IBatchProcessor; -import com.fastasyncworldedit.core.queue.IChunk; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.queue.IChunkSet; -import com.fastasyncworldedit.core.registry.state.PropertyKey; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockTypes; -import com.sk89q.worldedit.world.block.BlockTypesCache; -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.material.Fluid; -import net.minecraft.world.level.material.Fluids; - -import javax.annotation.Nullable; - -public class PaperweightPostProcessor implements IBatchProcessor { - - @Override - public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChunkSet set) { - return set; - } - - @SuppressWarnings("deprecation") - @Override - public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final IChunkSet iChunkSet) { - boolean tickFluid = Settings.settings().EXPERIMENTAL.ALLOW_TICK_FLUIDS; - // The PostProcessor shouldn't be added, but just in case - if (!tickFluid) { - return; - } - PaperweightGetBlocks_Copy getBlocks = (PaperweightGetBlocks_Copy) iChunkGet; - layer: - for (int layer = iChunkSet.getMinSectionPosition(); layer <= iChunkSet.getMaxSectionPosition(); layer++) { - char[] set = iChunkSet.loadIfPresent(layer); - if (set == null) { - // No edit means no need to process - continue; - } - char[] get = null; - for (int i = 0; i < 4096; i++) { - char ordinal = set[i]; - char replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; - boolean fromGet = false; // Used for liquids - if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { - if (get == null) { - get = getBlocks.load(layer); - } - // If this is null, then it's because we're loading a layer in the range of 0->15, but blocks aren't - // actually being set - if (get == null) { - continue layer; - } - fromGet = true; - ordinal = replacedOrdinal = get[i]; - } - if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { - continue; - } else if (!fromGet) { // if fromGet, don't do the same again - if (get == null) { - get = getBlocks.load(layer); - } - replacedOrdinal = get[i]; - } - boolean ticking = BlockTypesCache.ticking[ordinal]; - boolean replacedWasTicking = BlockTypesCache.ticking[replacedOrdinal]; - boolean replacedWasLiquid = false; - BlockState replacedState = null; - if (!ticking) { - // If the block being replaced was not ticking, it cannot be a liquid - if (!replacedWasTicking) { - continue; - } - // If the block being replaced is not fluid, we do not need to worry - if (!(replacedWasLiquid = - (replacedState = BlockState.getFromOrdinal(replacedOrdinal)).getMaterial().isLiquid())) { - continue; - } - } - BlockState state = BlockState.getFromOrdinal(ordinal); - boolean liquid = state.getMaterial().isLiquid(); - int x = i & 15; - int y = (i >> 8) & 15; - int z = (i >> 4) & 15; - BlockPos position = new BlockPos((chunk.getX() << 4) + x, (layer << 4) + y, (chunk.getZ() << 4) + z); - if (liquid || replacedWasLiquid) { - if (liquid) { - addFluid(getBlocks.serverLevel, state, position); - continue; - } - // If the replaced fluid (is?) adjacent to water. Do not bother to check adjacent chunks(sections) as this - // may be time consuming. Chances are any fluid blocks in adjacent chunks are being replaced or will end up - // being ticked anyway. We only need it to be "hit" once. - if (!wasAdjacentToWater(get, set, i, x, y, z)) { - continue; - } - addFluid(getBlocks.serverLevel, replacedState, position); - } - } - } - } - - @Nullable - @Override - public Extent construct(final Extent child) { - throw new UnsupportedOperationException("Processing only"); - } - - @Override - public ProcessorScope getScope() { - return ProcessorScope.READING_SET_BLOCKS; - } - - private boolean wasAdjacentToWater(char[] get, char[] set, int i, int x, int y, int z) { - if (set == null || get == null) { - return false; - } - char ordinal; - char reserved = BlockTypesCache.ReservedIDs.__RESERVED__; - if (x > 0 && set[i - 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 1])] && isFluid(ordinal)) { - return true; - } - } - if (x < 15 && set[i + 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 1])] && isFluid(ordinal)) { - return true; - } - } - if (z > 0 && set[i - 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 16])] && isFluid(ordinal)) { - return true; - } - } - if (z < 15 && set[i + 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 16])] && isFluid(ordinal)) { - return true; - } - } - if (y > 0 && set[i - 256] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 256])] && isFluid(ordinal)) { - return true; - } - } - if (y < 15 && set[i + 256] != reserved) { - return BlockTypesCache.ticking[(ordinal = get[i + 256])] && isFluid(ordinal); - } - return false; - } - - @SuppressWarnings("deprecation") - private boolean isFluid(char ordinal) { - return BlockState.getFromOrdinal(ordinal).getMaterial().isLiquid(); - } - - @SuppressWarnings("deprecation") - private void addFluid(final ServerLevel serverLevel, final BlockState replacedState, final BlockPos position) { - Fluid type; - if (replacedState.getBlockType() == BlockTypes.LAVA) { - type = (int) replacedState.getState(PropertyKey.LEVEL) == 0 ? Fluids.LAVA : Fluids.FLOWING_LAVA; - } else { - type = (int) replacedState.getState(PropertyKey.LEVEL) == 0 ? Fluids.WATER : Fluids.FLOWING_WATER; - } - serverLevel.scheduleTick( - position, - type, - type.getTickDelay(serverLevel) - ); - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightStarlightRelighter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightStarlightRelighter.java deleted file mode 100644 index b1e0c5772..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightStarlightRelighter.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3; - -import com.fastasyncworldedit.bukkit.adapter.StarlightRelighter; -import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.queue.IQueueExtent; -import net.minecraft.server.level.ChunkMap; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.TicketType; -import net.minecraft.util.Unit; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.chunk.ChunkStatus; - -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.function.Consumer; -import java.util.function.IntConsumer; - -public class PaperweightStarlightRelighter extends StarlightRelighter { - - private static final TicketType FAWE_TICKET = TicketType.create("fawe_ticket", (a, b) -> 0); - private static final int LIGHT_LEVEL = ChunkMap.MAX_VIEW_DISTANCE + ChunkStatus.getDistance(ChunkStatus.LIGHT); - - public PaperweightStarlightRelighter(ServerLevel serverLevel, IQueueExtent queue) { - super(serverLevel, queue); - } - - @Override - protected ChunkPos createChunkPos(final long chunkKey) { - return new ChunkPos(chunkKey); - } - - @Override - protected long asLong(final int chunkX, final int chunkZ) { - return ChunkPos.asLong(chunkX, chunkZ); - } - - @Override - protected CompletableFuture chunkLoadFuture(final ChunkPos chunkPos) { - return serverLevel.getWorld().getChunkAtAsync(chunkPos.x, chunkPos.z) - .thenAccept(c -> serverLevel.getChunkSource().addTicketAtLevel( - FAWE_TICKET, - chunkPos, - LIGHT_LEVEL, - Unit.INSTANCE - )); - } - - protected void invokeRelight( - Set coords, - Consumer chunkCallback, - IntConsumer processCallback - ) { - try { - serverLevel.getChunkSource().getLightEngine().relight(coords, chunkCallback, processCallback); - } catch (Exception e) { - LOGGER.error("Error occurred on relighting", e); - } - } - - /* - * Allow the server to unload the chunks again. - * Also, if chunk packets are sent delayed, we need to do that here - */ - protected void postProcessChunks(Set coords) { - boolean delay = Settings.settings().LIGHTING.DELAY_PACKET_SENDING; - for (ChunkPos pos : coords) { - int x = pos.x; - int z = pos.z; - if (delay) { // we still need to send the block changes of that chunk - PaperweightPlatformAdapter.sendChunk(pos, serverLevel, x, z); - } - serverLevel.getChunkSource().removeTicketAtLevel(FAWE_TICKET, pos, LIGHT_LEVEL, Unit.INSTANCE); - } - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightStarlightRelighterFactory.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightStarlightRelighterFactory.java deleted file mode 100644 index 78c623c7a..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightStarlightRelighterFactory.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3; - -import com.fastasyncworldedit.core.extent.processor.lighting.NullRelighter; -import com.fastasyncworldedit.core.extent.processor.lighting.RelightMode; -import com.fastasyncworldedit.core.extent.processor.lighting.Relighter; -import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory; -import com.fastasyncworldedit.core.queue.IQueueExtent; -import com.sk89q.worldedit.world.World; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; - -import javax.annotation.Nonnull; - -public class PaperweightStarlightRelighterFactory implements RelighterFactory { - - @Override - public @Nonnull Relighter createRelighter(RelightMode relightMode, World world, IQueueExtent queue) { - org.bukkit.World w = Bukkit.getWorld(world.getName()); - if (w == null) { - return NullRelighter.INSTANCE; - } - return new PaperweightStarlightRelighter(((CraftWorld) w).getHandle(), queue); - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/nbt/PaperweightLazyCompoundTag.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/nbt/PaperweightLazyCompoundTag.java deleted file mode 100644 index 0026c4c67..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/nbt/PaperweightLazyCompoundTag.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3.nbt; - -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.LazyCompoundTag; -import com.sk89q.jnbt.ListTag; -import com.sk89q.jnbt.StringTag; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import net.minecraft.nbt.NumericTag; -import org.enginehub.linbus.tree.LinCompoundTag; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Supplier; - -public class PaperweightLazyCompoundTag extends LazyCompoundTag { - - private final Supplier compoundTagSupplier; - private CompoundTag compoundTag; - - public PaperweightLazyCompoundTag(Supplier compoundTagSupplier) { - super(new HashMap<>()); - this.compoundTagSupplier = compoundTagSupplier; - } - - public PaperweightLazyCompoundTag(net.minecraft.nbt.CompoundTag compoundTag) { - this(() -> compoundTag); - } - - public net.minecraft.nbt.CompoundTag get() { - return compoundTagSupplier.get(); - } - - @Override - @SuppressWarnings("unchecked") - public Map> getValue() { - if (compoundTag == null) { - compoundTag = (CompoundTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(compoundTagSupplier.get()); - } - return compoundTag.getValue(); - } - - @Override - public LinCompoundTag toLinTag() { - getValue(); - return compoundTag.toLinTag(); - } - - public boolean containsKey(String key) { - return compoundTagSupplier.get().contains(key); - } - - public byte[] getByteArray(String key) { - return compoundTagSupplier.get().getByteArray(key); - } - - public byte getByte(String key) { - return compoundTagSupplier.get().getByte(key); - } - - public double getDouble(String key) { - return compoundTagSupplier.get().getDouble(key); - } - - public double asDouble(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof NumericTag numTag) { - return numTag.getAsDouble(); - } - return 0; - } - - public float getFloat(String key) { - return compoundTagSupplier.get().getFloat(key); - } - - public int[] getIntArray(String key) { - return compoundTagSupplier.get().getIntArray(key); - } - - public int getInt(String key) { - return compoundTagSupplier.get().getInt(key); - } - - public int asInt(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof NumericTag numTag) { - return numTag.getAsInt(); - } - return 0; - } - - @SuppressWarnings("unchecked") - public List> getList(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof net.minecraft.nbt.ListTag nbtList) { - ArrayList> list = new ArrayList<>(); - for (net.minecraft.nbt.Tag elem : nbtList) { - if (elem instanceof net.minecraft.nbt.CompoundTag compoundTag) { - list.add(new PaperweightLazyCompoundTag(compoundTag)); - } else { - list.add(WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(elem)); - } - } - return list; - } - return Collections.emptyList(); - } - - @SuppressWarnings("unchecked") - public ListTag getListTag(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof net.minecraft.nbt.ListTag) { - return (ListTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(tag); - } - return new ListTag(StringTag.class, Collections.emptyList()); - } - - @SuppressWarnings("unchecked") - public > List getList(String key, Class listType) { - ListTag listTag = getListTag(key); - if (listTag.getType().equals(listType)) { - return (List) listTag.getValue(); - } else { - return Collections.emptyList(); - } - } - - public long[] getLongArray(String key) { - return compoundTagSupplier.get().getLongArray(key); - } - - public long getLong(String key) { - return compoundTagSupplier.get().getLong(key); - } - - public long asLong(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof NumericTag numTag) { - return numTag.getAsLong(); - } - return 0; - } - - public short getShort(String key) { - return compoundTagSupplier.get().getShort(key); - } - - public String getString(String key) { - return compoundTagSupplier.get().getString(key); - } - - @Override - public String toString() { - return compoundTagSupplier.get().toString(); - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/regen/PaperweightRegen.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/regen/PaperweightRegen.java deleted file mode 100644 index 17b354535..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/regen/PaperweightRegen.java +++ /dev/null @@ -1,596 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3.regen; - -import com.fastasyncworldedit.bukkit.adapter.Regenerator; -import com.fastasyncworldedit.core.Fawe; -import com.fastasyncworldedit.core.queue.IChunkCache; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.util.ReflectionUtils; -import com.fastasyncworldedit.core.util.TaskManager; -import com.google.common.collect.ImmutableList; -import com.mojang.datafixers.util.Either; -import com.mojang.serialization.Lifecycle; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3.PaperweightGetBlocks; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.util.io.file.SafeFiles; -import com.sk89q.worldedit.world.RegenOptions; -import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.core.registries.Registries; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.dedicated.DedicatedServer; -import net.minecraft.server.level.ChunkMap; -import net.minecraft.server.level.ChunkTaskPriorityQueueSorter.Message; -import net.minecraft.server.level.ServerChunkCache; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ThreadedLevelLightEngine; -import net.minecraft.server.level.progress.ChunkProgressListener; -import net.minecraft.util.thread.ProcessorHandle; -import net.minecraft.util.thread.ProcessorMailbox; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelHeightAccessor; -import net.minecraft.world.level.LevelSettings; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.biome.FixedBiomeSource; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.chunk.ChunkGeneratorStructureState; -import net.minecraft.world.level.chunk.ChunkStatus; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.ProtoChunk; -import net.minecraft.world.level.chunk.UpgradeData; -import net.minecraft.world.level.dimension.LevelStem; -import net.minecraft.world.level.levelgen.FlatLevelSource; -import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; -import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; -import net.minecraft.world.level.levelgen.WorldOptions; -import net.minecraft.world.level.levelgen.blending.BlendingData; -import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings; -import net.minecraft.world.level.levelgen.structure.placement.ConcentricRingsStructurePlacement; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager; -import net.minecraft.world.level.storage.LevelStorageSource; -import net.minecraft.world.level.storage.PrimaryLevelData; -import org.apache.logging.log4j.Logger; -import org.bukkit.Bukkit; -import org.bukkit.Chunk; -import org.bukkit.craftbukkit.v1_19_R3.CraftServer; -import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R3.generator.CustomChunkGenerator; -import org.bukkit.generator.BiomeProvider; -import org.bukkit.generator.BlockPopulator; - -import javax.annotation.Nullable; -import java.lang.reflect.Field; -import java.nio.file.Path; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.OptionalLong; -import java.util.Random; -import java.util.concurrent.CompletableFuture; -import java.util.function.BooleanSupplier; -import java.util.function.Supplier; - -import static net.minecraft.core.registries.Registries.BIOME; - -public class PaperweightRegen extends Regenerator { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - - private static final Field serverWorldsField; - private static final Field paperConfigField; - private static final Field flatBedrockField; - private static final Field generatorSettingFlatField; - private static final Field generatorSettingBaseSupplierField; - private static final Field delegateField; - private static final Field chunkSourceField; - private static final Field generatorStructureStateField; - private static final Field ringPositionsField; - private static final Field hasGeneratedPositionsField; - - //list of chunk stati in correct order without FULL - private static final Map chunkStati = new LinkedHashMap<>(); - - static { - chunkStati.put(ChunkStatus.EMPTY, Concurrency.FULL); // empty: radius -1, does nothing - chunkStati.put(ChunkStatus.STRUCTURE_STARTS, Concurrency.NONE); // structure starts: uses unsynchronized maps - chunkStati.put( - ChunkStatus.STRUCTURE_REFERENCES, - Concurrency.FULL - ); // structure refs: radius 8, but only writes to current chunk - chunkStati.put(ChunkStatus.BIOMES, Concurrency.FULL); // biomes: radius 0 - chunkStati.put(ChunkStatus.NOISE, Concurrency.RADIUS); // noise: radius 8 - chunkStati.put(ChunkStatus.SURFACE, Concurrency.NONE); // surface: radius 0, requires NONE - chunkStati.put(ChunkStatus.CARVERS, Concurrency.NONE); // carvers: radius 0, but RADIUS and FULL change results - chunkStati.put( - ChunkStatus.LIQUID_CARVERS, - Concurrency.NONE - ); // liquid carvers: radius 0, but RADIUS and FULL change results - chunkStati.put(ChunkStatus.FEATURES, Concurrency.NONE); // features: uses unsynchronized maps - chunkStati.put( - ChunkStatus.LIGHT, - Concurrency.FULL - ); // light: radius 1, but no writes to other chunks, only current chunk - chunkStati.put(ChunkStatus.SPAWN, Concurrency.FULL); // spawn: radius 0 - chunkStati.put(ChunkStatus.HEIGHTMAPS, Concurrency.FULL); // heightmaps: radius 0 - - try { - serverWorldsField = CraftServer.class.getDeclaredField("worlds"); - serverWorldsField.setAccessible(true); - - Field tmpPaperConfigField; - Field tmpFlatBedrockField; - try { //only present on paper - tmpPaperConfigField = Level.class.getDeclaredField("paperConfig"); - tmpPaperConfigField.setAccessible(true); - - tmpFlatBedrockField = tmpPaperConfigField.getType().getDeclaredField("generateFlatBedrock"); - tmpFlatBedrockField.setAccessible(true); - } catch (Exception e) { - tmpPaperConfigField = null; - tmpFlatBedrockField = null; - } - paperConfigField = tmpPaperConfigField; - flatBedrockField = tmpFlatBedrockField; - - generatorSettingBaseSupplierField = NoiseBasedChunkGenerator.class.getDeclaredField(Refraction.pickName( - "settings", "e")); - generatorSettingBaseSupplierField.setAccessible(true); - - generatorSettingFlatField = FlatLevelSource.class.getDeclaredField(Refraction.pickName("settings", "d")); - generatorSettingFlatField.setAccessible(true); - - delegateField = CustomChunkGenerator.class.getDeclaredField("delegate"); - delegateField.setAccessible(true); - - chunkSourceField = ServerLevel.class.getDeclaredField(Refraction.pickName("chunkSource", "H")); - chunkSourceField.setAccessible(true); - - generatorStructureStateField = ChunkMap.class.getDeclaredField(Refraction.pickName("chunkGeneratorState", "w")); - generatorStructureStateField.setAccessible(true); - - ringPositionsField = ChunkGeneratorStructureState.class.getDeclaredField(Refraction.pickName("ringPositions", "g")); - ringPositionsField.setAccessible(true); - - hasGeneratedPositionsField = ChunkGeneratorStructureState.class.getDeclaredField( - Refraction.pickName("hasGeneratedPositions", "h") - ); - hasGeneratedPositionsField.setAccessible(true); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - //runtime - private ServerLevel originalServerWorld; - private ServerChunkCache originalChunkProvider; - private ServerLevel freshWorld; - private ServerChunkCache freshChunkProvider; - private LevelStorageSource.LevelStorageAccess session; - private StructureTemplateManager structureTemplateManager; - private ThreadedLevelLightEngine threadedLevelLightEngine; - private ChunkGenerator chunkGenerator; - - private Path tempDir; - - private boolean generateFlatBedrock = false; - - public PaperweightRegen(org.bukkit.World originalBukkitWorld, Region region, Extent target, RegenOptions options) { - super(originalBukkitWorld, region, target, options); - } - - @Override - protected boolean prepare() { - this.originalServerWorld = ((CraftWorld) originalBukkitWorld).getHandle(); - originalChunkProvider = originalServerWorld.getChunkSource(); - - //flat bedrock? (only on paper) - if (paperConfigField != null) { - try { - generateFlatBedrock = flatBedrockField.getBoolean(paperConfigField.get(originalServerWorld)); - } catch (Exception ignored) { - } - } - - seed = options.getSeed().orElse(originalServerWorld.getSeed()); - chunkStati.forEach((s, c) -> super.chunkStatuses.put(new ChunkStatusWrap(s), c)); - - return true; - } - - @Override - @SuppressWarnings("unchecked") - protected boolean initNewWorld() throws Exception { - //world folder - tempDir = java.nio.file.Files.createTempDirectory("FastAsyncWorldEditWorldGen"); - - //prepare for world init (see upstream implementation for reference) - org.bukkit.World.Environment environment = originalBukkitWorld.getEnvironment(); - org.bukkit.generator.ChunkGenerator generator = originalBukkitWorld.getGenerator(); - LevelStorageSource levelStorageSource = LevelStorageSource.createDefault(tempDir); - ResourceKey levelStemResourceKey = getWorldDimKey(environment); - session = levelStorageSource.createAccess("faweregentempworld", levelStemResourceKey); - PrimaryLevelData originalWorldData = originalServerWorld.serverLevelData; - - MinecraftServer server = originalServerWorld.getCraftServer().getServer(); - WorldOptions originalOpts = originalWorldData.worldGenOptions(); - WorldOptions newOpts = options.getSeed().isPresent() - ? originalOpts.withSeed(OptionalLong.of(seed)) - : originalOpts; - LevelSettings newWorldSettings = new LevelSettings( - "faweregentempworld", - originalWorldData.settings.gameType(), - originalWorldData.settings.hardcore(), - originalWorldData.settings.difficulty(), - originalWorldData.settings.allowCommands(), - originalWorldData.settings.gameRules(), - originalWorldData.settings.getDataConfiguration() - ); - - PrimaryLevelData.SpecialWorldProperty specialWorldProperty = - originalWorldData.isFlatWorld() - ? PrimaryLevelData.SpecialWorldProperty.FLAT - : originalWorldData.isDebugWorld() - ? PrimaryLevelData.SpecialWorldProperty.DEBUG - : PrimaryLevelData.SpecialWorldProperty.NONE; - PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, specialWorldProperty, Lifecycle.stable()); - - BiomeProvider biomeProvider = getBiomeProvider(); - - - //init world - freshWorld = Fawe.instance().getQueueHandler().sync((Supplier) () -> new ServerLevel( - server, - server.executor, - session, - newWorldData, - originalServerWorld.dimension(), - DedicatedServer.getServer().registryAccess().registry(Registries.LEVEL_STEM).orElseThrow() - .getOrThrow(levelStemResourceKey), - new RegenNoOpWorldLoadListener(), - originalServerWorld.isDebug(), - seed, - ImmutableList.of(), - false, - environment, - generator, - biomeProvider - ) { - - private final Holder singleBiome = options.hasBiomeType() ? DedicatedServer.getServer().registryAccess() - .registryOrThrow(BIOME).asHolderIdMap().byIdOrThrow( - WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType()) - ) : null; - - @Override - public void tick(BooleanSupplier shouldKeepTicking) { //no ticking - } - - @Override - public Holder getUncachedNoiseBiome(int biomeX, int biomeY, int biomeZ) { - if (options.hasBiomeType()) { - return singleBiome; - } - return PaperweightRegen.this.chunkGenerator.getBiomeSource().getNoiseBiome( - biomeX, biomeY, biomeZ, getChunkSource().randomState().sampler() - ); - } - }).get(); - freshWorld.noSave = true; - removeWorldFromWorldsMap(); - newWorldData.checkName(originalServerWorld.serverLevelData.getLevelName()); //rename to original world name - if (paperConfigField != null) { - paperConfigField.set(freshWorld, originalServerWorld.paperConfig()); - } - - ChunkGenerator originalGenerator = originalChunkProvider.getGenerator(); - if (originalGenerator instanceof FlatLevelSource flatLevelSource) { - FlatLevelGeneratorSettings generatorSettingFlat = flatLevelSource.settings(); - chunkGenerator = new FlatLevelSource(generatorSettingFlat); - } else if (originalGenerator instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) { - Holder generatorSettingBaseSupplier = (Holder) generatorSettingBaseSupplierField.get( - originalGenerator); - BiomeSource biomeSource; - if (options.hasBiomeType()) { - - biomeSource = new FixedBiomeSource( - DedicatedServer.getServer().registryAccess() - .registryOrThrow(BIOME).asHolderIdMap().byIdOrThrow( - WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType()) - ) - ); - } else { - biomeSource = originalGenerator.getBiomeSource(); - } - chunkGenerator = new NoiseBasedChunkGenerator( - biomeSource, - generatorSettingBaseSupplier - ); - } else if (originalGenerator instanceof CustomChunkGenerator customChunkGenerator) { - chunkGenerator = customChunkGenerator.getDelegate(); - } else { - LOGGER.error("Unsupported generator type {}", originalGenerator.getClass().getName()); - return false; - } - if (generator != null) { - chunkGenerator = new CustomChunkGenerator(freshWorld, chunkGenerator, generator); - generateConcurrent = generator.isParallelCapable(); - } -// chunkGenerator.conf = freshWorld.spigotConfig; - Does not exist anymore, may need to be re-addressed - - freshChunkProvider = new ServerChunkCache( - freshWorld, - session, - server.getFixerUpper(), - server.getStructureManager(), - server.executor, - chunkGenerator, - freshWorld.spigotConfig.viewDistance, - freshWorld.spigotConfig.simulationDistance, - server.forceSynchronousWrites(), - new RegenNoOpWorldLoadListener(), - (chunkCoordIntPair, state) -> { - }, - () -> server.overworld().getDataStorage() - ) { - // redirect to LevelChunks created in #createChunks - @Override - public ChunkAccess getChunk(int x, int z, ChunkStatus chunkstatus, boolean create) { - ChunkAccess chunkAccess = getChunkAt(x, z); - if (chunkAccess == null && create) { - chunkAccess = createChunk(getProtoChunkAt(x, z)); - } - return chunkAccess; - } - }; - - if (seed == originalOpts.seed() && !options.hasBiomeType()) { - // Optimisation for needless ring position calculation when the seed and biome is the same. - ChunkGeneratorStructureState state = (ChunkGeneratorStructureState) generatorStructureStateField.get(originalChunkProvider.chunkMap); - boolean hasGeneratedPositions = hasGeneratedPositionsField.getBoolean(state); - if (hasGeneratedPositions) { - Map>> origPositions = - (Map>>) ringPositionsField.get(state); - Map>> copy = new Object2ObjectArrayMap<>( - origPositions); - ChunkGeneratorStructureState newState = (ChunkGeneratorStructureState) generatorStructureStateField.get(freshChunkProvider.chunkMap); - ringPositionsField.set(newState, copy); - hasGeneratedPositionsField.setBoolean(newState, true); - } - } - - - chunkSourceField.set(freshWorld, freshChunkProvider); - //let's start then - structureTemplateManager = server.getStructureManager(); - threadedLevelLightEngine = new NoOpLightEngine(freshChunkProvider); - - return true; - } - - @Override - protected void cleanup() { - try { - session.close(); - } catch (Exception ignored) { - } - - //shutdown chunk provider - try { - Fawe.instance().getQueueHandler().sync(() -> { - try { - freshChunkProvider.close(false); - } catch (Exception e) { - throw new RuntimeException(e); - } - }); - } catch (Exception ignored) { - } - - //remove world from server - try { - Fawe.instance().getQueueHandler().sync(this::removeWorldFromWorldsMap); - } catch (Exception ignored) { - } - - //delete directory - try { - SafeFiles.tryHardToDeleteDir(tempDir); - } catch (Exception ignored) { - } - } - - @Override - protected ProtoChunk createProtoChunk(int x, int z) { - return new FastProtoChunk(new ChunkPos(x, z), UpgradeData.EMPTY, freshWorld, - this.freshWorld.registryAccess().registryOrThrow(BIOME), null - ); - } - - @Override - protected LevelChunk createChunk(ProtoChunk protoChunk) { - return new LevelChunk( - freshWorld, - protoChunk, - null // we don't want to add entities - ); - } - - @Override - protected ChunkStatusWrap getFullChunkStatus() { - return new ChunkStatusWrap(ChunkStatus.FULL); - } - - @Override - protected List getBlockPopulators() { - return originalServerWorld.getWorld().getPopulators(); - } - - @Override - protected void populate(LevelChunk levelChunk, Random random, BlockPopulator blockPopulator) { - // BlockPopulator#populate has to be called synchronously for TileEntity access - TaskManager.taskManager().task(() -> { - final CraftWorld world = freshWorld.getWorld(); - final Chunk chunk = world.getChunkAt(levelChunk.locX, levelChunk.locZ); - blockPopulator.populate(world, random, chunk); - }); - } - - @Override - protected IChunkCache initSourceQueueCache() { - return (chunkX, chunkZ) -> new PaperweightGetBlocks(freshWorld, chunkX, chunkZ) { - @Override - public LevelChunk ensureLoaded(ServerLevel nmsWorld, int x, int z) { - return getChunkAt(x, z); - } - }; - } - - //util - @SuppressWarnings("unchecked") - private void removeWorldFromWorldsMap() { - Fawe.instance().getQueueHandler().sync(() -> { - try { - Map map = (Map) serverWorldsField.get(Bukkit.getServer()); - map.remove("faweregentempworld"); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - }); - } - - private ResourceKey getWorldDimKey(org.bukkit.World.Environment env) { - return switch (env) { - case NETHER -> LevelStem.NETHER; - case THE_END -> LevelStem.END; - default -> LevelStem.OVERWORLD; - }; - } - - private static class RegenNoOpWorldLoadListener implements ChunkProgressListener { - - private RegenNoOpWorldLoadListener() { - } - - @Override - public void updateSpawnPos(ChunkPos spawnPos) { - } - - @Override - public void onStatusChange(ChunkPos pos, @Nullable ChunkStatus status) { - } - - @Override - public void start() { - - } - - @Override - public void stop() { - } - - // TODO Paper only(?) @Override - public void setChunkRadius(int radius) { - } - - } - - private class FastProtoChunk extends ProtoChunk { - - public FastProtoChunk( - final ChunkPos pos, - final UpgradeData upgradeData, - final LevelHeightAccessor world, - final Registry biomeRegistry, - @Nullable final BlendingData blendingData - ) { - super(pos, upgradeData, world, biomeRegistry, blendingData); - } - - // avoid warning on paper - - // compatibility with spigot - - public boolean generateFlatBedrock() { - return generateFlatBedrock; - } - - // no one will ever see the entities! - @Override - public List getEntities() { - return Collections.emptyList(); - } - - } - - protected class ChunkStatusWrap extends ChunkStatusWrapper { - - private final ChunkStatus chunkStatus; - - public ChunkStatusWrap(ChunkStatus chunkStatus) { - this.chunkStatus = chunkStatus; - } - - @Override - public int requiredNeighborChunkRadius() { - return chunkStatus.getRange(); - } - - @Override - public String name() { - return chunkStatus.getName(); - } - - @Override - public CompletableFuture processChunk(List accessibleChunks) { - return chunkStatus.generate( - Runnable::run, // TODO revisit, we might profit from this somehow? - freshWorld, - chunkGenerator, - structureTemplateManager, - threadedLevelLightEngine, - c -> CompletableFuture.completedFuture(Either.left(c)), - accessibleChunks, - true - ); - } - - } - - /** - * A light engine that does nothing. As light is calculated after pasting anyway, we can avoid - * work this way. - */ - static class NoOpLightEngine extends ThreadedLevelLightEngine { - - private static final ProcessorMailbox MAILBOX = ProcessorMailbox.create(task -> { - }, "fawe-no-op"); - private static final ProcessorHandle> HANDLE = ProcessorHandle.of("fawe-no-op", m -> { - }); - - public NoOpLightEngine(final ServerChunkCache chunkProvider) { - super(chunkProvider, chunkProvider.chunkMap, false, MAILBOX, HANDLE); - } - - @Override - public CompletableFuture retainData(final ChunkAccess chunk) { - return CompletableFuture.completedFuture(chunk); - } - - @Override - public CompletableFuture lightChunk(final ChunkAccess chunk, final boolean excludeBlocks) { - return CompletableFuture.completedFuture(chunk); - } - - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20/build.gradle.kts deleted file mode 100644 index 51438592a..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/build.gradle.kts +++ /dev/null @@ -1,17 +0,0 @@ -import io.papermc.paperweight.userdev.PaperweightUserDependenciesExtension - -plugins { - java -} - -applyPaperweightAdapterConfiguration() - -repositories { - gradlePluginPortal() -} - -dependencies { - // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.1-R0.1-SNAPSHOT - the().paperDevBundle("1.20.1-R0.1-20230921.165944-178") - compileOnly(libs.paperlib) -} 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 deleted file mode 100644 index 0cecbb45b..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java +++ /dev/null @@ -1,1131 +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.bukkit.adapter.ext.fawe.v1_20_R1; - -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.common.collect.ImmutableList; -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.NBTConstants; -import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.blocks.BaseItem; -import com.sk89q.worldedit.blocks.BaseItemStack; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1.PaperweightPlatformAdapter; -import com.sk89q.worldedit.entity.BaseEntity; -import com.sk89q.worldedit.extension.platform.Watchdog; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.internal.Constants; -import com.sk89q.worldedit.internal.block.BlockStateIdAccess; -import com.sk89q.worldedit.internal.wna.WorldNativeAccess; -import com.sk89q.worldedit.math.BlockVector2; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.registry.state.BooleanProperty; -import com.sk89q.worldedit.registry.state.DirectionalProperty; -import com.sk89q.worldedit.registry.state.EnumProperty; -import com.sk89q.worldedit.registry.state.IntegerProperty; -import com.sk89q.worldedit.registry.state.Property; -import com.sk89q.worldedit.util.Direction; -import com.sk89q.worldedit.util.SideEffect; -import com.sk89q.worldedit.util.concurrency.LazyReference; -import com.sk89q.worldedit.util.formatting.text.Component; -import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; -import com.sk89q.worldedit.util.io.file.SafeFiles; -import com.sk89q.worldedit.world.DataFixer; -import com.sk89q.worldedit.world.RegenOptions; -import com.sk89q.worldedit.world.biome.BiomeCategory; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.biome.BiomeTypes; -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.block.BlockTypes; -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.HolderSet; -import net.minecraft.core.Registry; -import net.minecraft.core.registries.Registries; -import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; -import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; -import net.minecraft.resources.ResourceKey; -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.progress.ChunkProgressListener; -import net.minecraft.util.StringRepresentable; -import net.minecraft.util.thread.BlockableEventLoop; -import net.minecraft.world.Clearable; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.item.Item; -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.biome.Biome; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.StructureBlockEntity; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.DirectionProperty; -import net.minecraft.world.level.chunk.ChunkAccess; -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.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.Environment; -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.data.CraftBlockData; -import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_20_R1.util.CraftMagicNumbers; -import org.bukkit.entity.Player; -import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; -import org.bukkit.generator.ChunkGenerator; -import org.enginehub.linbus.common.LinTagId; -import org.enginehub.linbus.tree.LinByteArrayTag; -import org.enginehub.linbus.tree.LinByteTag; -import org.enginehub.linbus.tree.LinCompoundTag; -import org.enginehub.linbus.tree.LinDoubleTag; -import org.enginehub.linbus.tree.LinEndTag; -import org.enginehub.linbus.tree.LinFloatTag; -import org.enginehub.linbus.tree.LinIntArrayTag; -import org.enginehub.linbus.tree.LinIntTag; -import org.enginehub.linbus.tree.LinListTag; -import org.enginehub.linbus.tree.LinLongArrayTag; -import org.enginehub.linbus.tree.LinLongTag; -import org.enginehub.linbus.tree.LinShortTag; -import org.enginehub.linbus.tree.LinStringTag; -import org.enginehub.linbus.tree.LinTag; -import org.enginehub.linbus.tree.LinTagType; -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; -import java.lang.reflect.Method; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; -import java.util.OptionalInt; -import java.util.OptionalLong; -import java.util.Set; -import java.util.TreeMap; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -public final class PaperweightAdapter implements BukkitImplAdapter { - - private final Logger logger = Logger.getLogger(getClass().getCanonicalName()); - - private final Field serverWorldsField; - private final Method getChunkFutureMethod; - private final Field chunkProviderExecutorField; - private final Watchdog watchdog; - - // ------------------------------------------------------------------------ - // Code that may break between versions of Minecraft - // ------------------------------------------------------------------------ - - public PaperweightAdapter() throws NoSuchFieldException, NoSuchMethodException { - // A simple test - CraftServer.class.cast(Bukkit.getServer()); - - int dataVersion = CraftMagicNumbers.INSTANCE.getDataVersion(); - if (dataVersion != 3463 && dataVersion != 3465) { - throw new UnsupportedClassVersionError("Not 1.20(.1)!"); - } - - serverWorldsField = CraftServer.class.getDeclaredField("worlds"); - serverWorldsField.setAccessible(true); - - getChunkFutureMethod = ServerChunkCache.class.getDeclaredMethod( - Refraction.pickName("getChunkFutureMainThread", "c"), - int.class, int.class, ChunkStatus.class, boolean.class - ); - getChunkFutureMethod.setAccessible(true); - - chunkProviderExecutorField = ServerChunkCache.class.getDeclaredField( - Refraction.pickName("mainThreadProcessor", "g") - ); - chunkProviderExecutorField.setAccessible(true); - - new PaperweightDataConverters(CraftMagicNumbers.INSTANCE.getDataVersion(), this).buildUnoptimized(); - - Watchdog watchdog; - try { - Class.forName("org.spigotmc.WatchdogThread"); - watchdog = new SpigotWatchdog(); - } catch (ClassNotFoundException | NoSuchFieldException e) { - try { - watchdog = new MojangWatchdog(((CraftServer) Bukkit.getServer()).getServer()); - } catch (NoSuchFieldException ex) { - watchdog = null; - } - } - this.watchdog = watchdog; - - try { - Class.forName("org.spigotmc.SpigotConfig"); - SpigotConfig.config.set("world-settings.faweregentempworld.verbose", false); - } catch (ClassNotFoundException ignored) { - } - } - - @Override - public DataFixer getDataFixer() { - return PaperweightDataConverters.INSTANCE; - } - - /** - * Read the given NBT data into the given tile entity. - * - * @param tileEntity the tile entity - * @param tag the tag - */ - static void readTagIntoTileEntity(net.minecraft.nbt.CompoundTag tag, BlockEntity tileEntity) { - tileEntity.load(tag); - tileEntity.setChanged(); - } - - /** - * Get the ID string of the given entity. - * - * @param entity the entity - * @return the entity ID - */ - private static String getEntityId(Entity entity) { - return EntityType.getKey(entity.getType()).toString(); - } - - /** - * Create an entity using the given entity ID. - * - * @param id the entity ID - * @param world the world - * @return an entity or null - */ - @Nullable - private static Entity createEntityFromId(String id, net.minecraft.world.level.Level world) { - return EntityType.byString(id).map(t -> t.create(world)).orElse(null); - } - - /** - * Write the given NBT data into the given entity. - * - * @param entity the entity - * @param tag the tag - */ - private static void readTagIntoEntity(net.minecraft.nbt.CompoundTag tag, Entity entity) { - entity.load(tag); - } - - /** - * Write the entity's NBT data to the given tag. - * - * @param entity the entity - * @param tag the tag - */ - private static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag tag) { - //FAWE start - avoid villager async catcher - PaperweightPlatformAdapter.readEntityIntoTag(entity, tag); - //FAWE end - } - - private static Block getBlockFromType(BlockType blockType) { - - return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.BLOCK).get(ResourceLocation.tryParse(blockType.id())); - } - - private static Item getItemFromType(ItemType itemType) { - return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.ITEM).get(ResourceLocation.tryParse(itemType.id())); - } - - @Override - public OptionalInt getInternalBlockStateId(BlockData data) { - net.minecraft.world.level.block.state.BlockState state = ((CraftBlockData) data).getState(); - int combinedId = Block.getId(state); - return combinedId == 0 && state.getBlock() != Blocks.AIR ? OptionalInt.empty() : OptionalInt.of(combinedId); - } - - @Override - public OptionalInt getInternalBlockStateId(BlockState state) { - Block mcBlock = getBlockFromType(state.getBlockType()); - net.minecraft.world.level.block.state.BlockState newState = mcBlock.defaultBlockState(); - Map, Object> states = state.getStates(); - newState = applyProperties(mcBlock.getStateDefinition(), newState, states); - final int combinedId = Block.getId(newState); - return combinedId == 0 && state.getBlockType() != BlockTypes.AIR ? OptionalInt.empty() : OptionalInt.of(combinedId); - } - - public BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) { - int internalId = Block.getId(blockState); - BlockState state = BlockStateIdAccess.getBlockStateById(internalId); - if (state == null) { - state = BukkitAdapter.adapt(CraftBlockData.createData(blockState)); - } - - return state; - } - - public BiomeType adapt(Biome biome) { - var mcBiome = ((CraftServer) Bukkit.getServer()).getServer().registryAccess().registryOrThrow(Registries.BIOME).getKey(biome); - if (mcBiome == null) { - return null; - } - return BiomeType.REGISTRY.get(mcBiome.toString()); - } - - public net.minecraft.world.level.block.state.BlockState adapt(BlockState blockState) { - int internalId = BlockStateIdAccess.getBlockStateId(blockState); - return Block.stateById(internalId); - } - - @Override - public BlockState getBlock(Location location) { - checkNotNull(location); - - CraftWorld craftWorld = ((CraftWorld) location.getWorld()); - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - - final ServerLevel handle = craftWorld.getHandle(); - LevelChunk chunk = handle.getChunk(x >> 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; - } - - @Override - public BaseBlock getFullBlock(Location location) { - BlockState state = getBlock(location); - - CraftWorld craftWorld = ((CraftWorld) location.getWorld()); - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - - final ServerLevel handle = craftWorld.getHandle(); - LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); - final BlockPos blockPos = new BlockPos(x, y, z); - - // Read the NBT data - BlockEntity te = chunk.getBlockEntity(blockPos); - if (te != null) { - net.minecraft.nbt.CompoundTag tag = te.saveWithId(); - return state.toBaseBlock((LinCompoundTag) toNativeLin(tag)); - } - - return state.toBaseBlock(); - } -/* - @Override - public boolean hasCustomBiomeSupport() { - return true; - } -*/ - private static final HashMap> biomeTypeToNMSCache = new HashMap<>(); - private static final HashMap, BiomeType> biomeTypeFromNMSCache = new HashMap<>(); - - /* @Override - public BiomeType getBiome(Location location) { - checkNotNull(location); - - CraftWorld craftWorld = ((CraftWorld) location.getWorld()); - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - - final ServerLevel handle = craftWorld.getHandle(); - LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); - - return biomeTypeFromNMSCache.computeIfAbsent(chunk.getNoiseBiome(x >> 2, y >> 2, z >> 2), b -> BiomeType.REGISTRY.get(b.unwrapKey().get().location().toString())); - } - - @Override - public void setBiome(Location location, BiomeType biome) { - checkNotNull(location); - checkNotNull(biome); - - CraftWorld craftWorld = ((CraftWorld) location.getWorld()); - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - - final ServerLevel handle = craftWorld.getHandle(); - LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); - chunk.setBiome(x >> 2, y >> 2, z >> 2, biomeTypeToNMSCache.computeIfAbsent(biome, b -> ((CraftServer) Bukkit.getServer()).getServer().registryAccess().registryOrThrow(Registries.BIOME).getHolderOrThrow(ResourceKey.create(Registries.BIOME, new ResourceLocation(b.getId()))))); - chunk.setUnsaved(true); - }*/ - - @Override - public WorldNativeAccess createWorldNativeAccess(org.bukkit.World world) { - return new com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R1.PaperweightWorldNativeAccess(this, - new WeakReference<>(((CraftWorld) world).getHandle())); - } - - private static net.minecraft.core.Direction adapt(Direction face) { - switch (face) { - case NORTH: - return net.minecraft.core.Direction.NORTH; - case SOUTH: - return net.minecraft.core.Direction.SOUTH; - case WEST: - return net.minecraft.core.Direction.WEST; - case EAST: - return net.minecraft.core.Direction.EAST; - case DOWN: - return net.minecraft.core.Direction.DOWN; - case UP: - default: - return net.minecraft.core.Direction.UP; - } - } - - @SuppressWarnings({"rawtypes", "unchecked"}) - private net.minecraft.world.level.block.state.BlockState applyProperties( - StateDefinition stateContainer, - net.minecraft.world.level.block.state.BlockState newState, - Map, Object> states - ) { - for (Map.Entry, Object> state : states.entrySet()) { - net.minecraft.world.level.block.state.properties.Property property = - stateContainer.getProperty(state.getKey().getName()); - Comparable value = (Comparable) state.getValue(); - // we may need to adapt this value, depending on the source prop - if (property instanceof DirectionProperty) { - Direction dir = (Direction) value; - value = adapt(dir); - } else if (property instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { - String enumName = (String) value; - value = ((net.minecraft.world.level.block.state.properties.EnumProperty) property) - .getValue(enumName).orElseThrow(() -> - new IllegalStateException( - "Enum property " + property.getName() + " does not contain " + enumName - ) - ); - } - - newState = newState.setValue( - (net.minecraft.world.level.block.state.properties.Property) property, - (Comparable) value - ); - } - return newState; - } - - @Override - public BaseEntity getEntity(org.bukkit.entity.Entity entity) { - checkNotNull(entity); - - CraftEntity craftEntity = ((CraftEntity) entity); - Entity mcEntity = craftEntity.getHandle(); - - // Do not allow creating of passenger entity snapshots, passengers are included in the vehicle entity - if (mcEntity.isPassenger()) { - return null; - } - - String id = getEntityId(mcEntity); - - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - readEntityIntoTag(mcEntity, tag); - return new BaseEntity( - com.sk89q.worldedit.world.entity.EntityTypes.get(id), - LazyReference.from(() -> (LinCompoundTag) toNativeLin(tag)) - ); - } - - @Nullable - @Override - public org.bukkit.entity.Entity createEntity(Location location, BaseEntity state) { - checkNotNull(location); - checkNotNull(state); - - CraftWorld craftWorld = ((CraftWorld) location.getWorld()); - ServerLevel worldServer = craftWorld.getHandle(); - - Entity createdEntity = createEntityFromId(state.getType().id(), craftWorld.getHandle()); - - if (createdEntity != null) { - LinCompoundTag nativeTag = state.getNbt(); - if (nativeTag != null) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) fromNativeLin(nativeTag); - for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { - tag.remove(name); - } - readTagIntoEntity(tag, createdEntity); - } - - createdEntity.absMoveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); - - worldServer.addFreshEntity(createdEntity, SpawnReason.CUSTOM); - return createdEntity.getBukkitEntity(); - } else { - return null; - } - } - - // This removes all unwanted tags from the main entity and all its passengers - private void removeUnwantedEntityTagsRecursively(net.minecraft.nbt.CompoundTag tag) { - for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { - tag.remove(name); - } - - // Adapted from net.minecraft.world.entity.EntityType#loadEntityRecursive - if (tag.contains("Passengers", NBTConstants.TYPE_LIST)) { - net.minecraft.nbt.ListTag nbttaglist = tag.getList("Passengers", NBTConstants.TYPE_COMPOUND); - - for (int i = 0; i < nbttaglist.size(); ++i) { - removeUnwantedEntityTagsRecursively(nbttaglist.getCompound(i)); - } - } - } - - @Override - public Component getRichBlockName(BlockType blockType) { - return TranslatableComponent.of(getBlockFromType(blockType).getDescriptionId()); - } - - @Override - public Component getRichItemName(ItemType itemType) { - return TranslatableComponent.of(getItemFromType(itemType).getDescriptionId()); - } - - @Override - public Component getRichItemName(BaseItemStack itemStack) { - return TranslatableComponent.of(CraftItemStack.asNMSCopy(BukkitAdapter.adapt(itemStack)).getDescriptionId()); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private static final LoadingCache> PROPERTY_CACHE = CacheBuilder - .newBuilder() - .build(new CacheLoader<>() { - @Override - public Property load(net.minecraft.world.level.block.state.properties.Property state) { - if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { - return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else if (state instanceof DirectionProperty) { - return new DirectionalProperty( - state.getName(), - new ArrayList<>((List) state - .getPossibleValues() - .stream() - .map(e -> Direction.valueOf(((StringRepresentable) e) - .getSerializedName() - .toUpperCase(Locale.ROOT))) - .toList()) - ); - } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { - return new EnumProperty( - state.getName(), - new ArrayList<>((List) state - .getPossibleValues() - .stream() - .map(e -> ((StringRepresentable) e).getSerializedName()) - .toList()) - ); - } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { - return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else { - throw new IllegalArgumentException("WorldEdit needs an update to support " + state - .getClass() - .getSimpleName()); - } - } - }); - - @SuppressWarnings({ "rawtypes" }) - @Override - public Map> getProperties(BlockType blockType) { - Map> properties = new TreeMap<>(); - Block block = getBlockFromType(blockType); - StateDefinition blockStateList = - block.getStateDefinition(); - for (net.minecraft.world.level.block.state.properties.Property state : blockStateList.getProperties()) { - Property property = PROPERTY_CACHE.getUnchecked(state); - properties.put(property.getName(), property); - } - return properties; - } - - @Override - public void sendFakeNBT(Player player, BlockVector3 pos, LinCompoundTag nbtData) { - ((CraftPlayer) player).getHandle().connection.send(ClientboundBlockEntityDataPacket.create( - new StructureBlockEntity( - new BlockPos(pos.x(), pos.y(), pos.z()), - Blocks.STRUCTURE_BLOCK.defaultBlockState() - ), - __ -> (net.minecraft.nbt.CompoundTag) fromNativeLin(nbtData) - )); - } - - @Override - public void sendFakeOP(Player player) { - ((CraftPlayer) player).getHandle().connection.send(new ClientboundEntityEventPacket( - ((CraftPlayer) player).getHandle(), (byte) 28 - )); - } - - @Override - public org.bukkit.inventory.ItemStack adapt(BaseItemStack item) { - ItemStack stack = new ItemStack( - DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.ITEM).get(ResourceLocation.tryParse(item.getType().id())), - item.getAmount() - ); - stack.setTag(((net.minecraft.nbt.CompoundTag) fromNative(item.getNbtData()))); - return CraftItemStack.asCraftMirror(stack); - } - - @Override - public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) { - final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); - final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount()); - weStack.setNbt(((LinCompoundTag) toNativeLin(nmsStack.getTag()))); - return weStack; - } - - private final LoadingCache fakePlayers - = CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(PaperweightFakePlayer::new)); - - @Override - public boolean simulateItemUse(org.bukkit.World world, BlockVector3 position, BaseItem item, Direction face) { - CraftWorld craftWorld = (CraftWorld) world; - ServerLevel worldServer = craftWorld.getHandle(); - ItemStack stack = CraftItemStack.asNMSCopy(BukkitAdapter.adapt(item instanceof BaseItemStack - ? ((BaseItemStack) item) : new BaseItemStack(item.getType(), item.getNbtData(), 1))); - stack.setTag((net.minecraft.nbt.CompoundTag) fromNative(item.getNbtData())); - - PaperweightFakePlayer fakePlayer; - try { - fakePlayer = fakePlayers.get(worldServer); - } catch (ExecutionException ignored) { - return false; - } - fakePlayer.setItemInHand(InteractionHand.MAIN_HAND, stack); - fakePlayer.absMoveTo(position.x(), position.y(), position.z(), - (float) face.toVector().toYaw(), (float) face.toVector().toPitch()); - - final BlockPos blockPos = new BlockPos(position.x(), position.y(), position.z()); - final Vec3 blockVec = Vec3.atLowerCornerOf(blockPos); - final net.minecraft.core.Direction enumFacing = adapt(face); - BlockHitResult rayTrace = new BlockHitResult(blockVec, enumFacing, blockPos, false); - UseOnContext context = new UseOnContext(fakePlayer, InteractionHand.MAIN_HAND, rayTrace); - InteractionResult result = stack.useOn(context); - if (result != InteractionResult.SUCCESS) { - if (worldServer.getBlockState(blockPos).use(worldServer, fakePlayer, InteractionHand.MAIN_HAND, rayTrace).consumesAction()) { - result = InteractionResult.SUCCESS; - } else { - result = stack.getItem().use(worldServer, fakePlayer, InteractionHand.MAIN_HAND).getResult(); - } - } - - return result == InteractionResult.SUCCESS; - } - - @Override - public boolean canPlaceAt(org.bukkit.World world, BlockVector3 position, BlockState blockState) { - int internalId = BlockStateIdAccess.getBlockStateId(blockState); - net.minecraft.world.level.block.state.BlockState blockData = Block.stateById(internalId); - return blockData.canSurvive(((CraftWorld) world).getHandle(), new BlockPos(position.x(), position.y(), position.z())); - } - - @Override - public boolean regenerate(org.bukkit.World bukkitWorld, Region region, Extent extent, RegenOptions options) { - try { - doRegen(bukkitWorld, region, extent, options); - } catch (Exception e) { - throw new IllegalStateException("Regen failed.", e); - } - - return true; - } - - private void doRegen(org.bukkit.World bukkitWorld, Region region, Extent extent, RegenOptions options) throws Exception { - Environment env = bukkitWorld.getEnvironment(); - ChunkGenerator gen = bukkitWorld.getGenerator(); - - Path tempDir = Files.createTempDirectory("WorldEditWorldGen"); - LevelStorageSource levelStorage = LevelStorageSource.createDefault(tempDir); - ResourceKey worldDimKey = getWorldDimKey(env); - try (LevelStorageSource.LevelStorageAccess session = levelStorage.createAccess("faweregentempworld", worldDimKey)) { - ServerLevel originalWorld = ((CraftWorld) bukkitWorld).getHandle(); - PrimaryLevelData levelProperties = (PrimaryLevelData) originalWorld.getServer() - .getWorldData().overworldData(); - WorldOptions originalOpts = levelProperties.worldGenOptions(); - - long seed = options.getSeed().orElse(originalWorld.getSeed()); - WorldOptions newOpts = options.getSeed().isPresent() - ? originalOpts.withSeed(OptionalLong.of(seed)) - : originalOpts; - - LevelSettings newWorldSettings = new LevelSettings( - "faweregentempworld", - levelProperties.settings.gameType(), - levelProperties.settings.hardcore(), - levelProperties.settings.difficulty(), - levelProperties.settings.allowCommands(), - levelProperties.settings.gameRules(), - levelProperties.settings.getDataConfiguration() - ); - - PrimaryLevelData.SpecialWorldProperty specialWorldProperty = - levelProperties.isFlatWorld() - ? PrimaryLevelData.SpecialWorldProperty.FLAT - : levelProperties.isDebugWorld() - ? PrimaryLevelData.SpecialWorldProperty.DEBUG - : PrimaryLevelData.SpecialWorldProperty.NONE; - - PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, specialWorldProperty, Lifecycle.stable()); - - ServerLevel freshWorld = new ServerLevel( - originalWorld.getServer(), - originalWorld.getServer().executor, - session, newWorldData, - originalWorld.dimension(), - new LevelStem( - originalWorld.dimensionTypeRegistration(), - originalWorld.getChunkSource().getGenerator() - ), - new NoOpWorldLoadListener(), - originalWorld.isDebug(), - seed, - ImmutableList.of(), - false, - originalWorld.getRandomSequences(), - env, - gen, - bukkitWorld.getBiomeProvider() - ); - try { - regenForWorld(region, extent, freshWorld, options); - } finally { - freshWorld.getChunkSource().close(false); - } - } finally { - try { - @SuppressWarnings("unchecked") - Map map = (Map) serverWorldsField.get(Bukkit.getServer()); - map.remove("faweregentempworld"); - } catch (IllegalAccessException ignored) { - } - SafeFiles.tryHardToDeleteDir(tempDir); - } - } - - private BiomeType adapt(ServerLevel serverWorld, Biome origBiome) { - ResourceLocation key = serverWorld.registryAccess().registryOrThrow(Registries.BIOME).getKey(origBiome); - if (key == null) { - return null; - } - return BiomeTypes.get(key.toString()); - } - - @SuppressWarnings("unchecked") - private void regenForWorld(Region region, Extent extent, ServerLevel serverWorld, RegenOptions options) throws WorldEditException { - List> chunkLoadings = submitChunkLoadTasks(region, serverWorld); - BlockableEventLoop executor; - try { - executor = (BlockableEventLoop) chunkProviderExecutorField.get(serverWorld.getChunkSource()); - } catch (IllegalAccessException e) { - throw new IllegalStateException("Couldn't get executor for chunk loading.", e); - } - executor.managedBlock(() -> { - // bail out early if a future fails - if (chunkLoadings.stream().anyMatch(ftr -> - ftr.isDone() && Futures.getUnchecked(ftr) == null - )) { - return false; - } - return chunkLoadings.stream().allMatch(CompletableFuture::isDone); - }); - Map chunks = new HashMap<>(); - for (CompletableFuture future : chunkLoadings) { - @Nullable - ChunkAccess chunk = future.getNow(null); - checkState(chunk != null, "Failed to generate a chunk, regen failed."); - chunks.put(chunk.getPos(), chunk); - } - - for (BlockVector3 vec : region) { - BlockPos pos = new BlockPos(vec.x(), vec.y(), vec.z()); - ChunkAccess chunk = chunks.get(new ChunkPos(pos)); - final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos); - int internalId = Block.getId(blockData); - BlockStateHolder state = BlockStateIdAccess.getBlockStateById(internalId); - Objects.requireNonNull(state); - BlockEntity blockEntity = chunk.getBlockEntity(pos); - if (blockEntity != null) { - net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(); - state = state.toBaseBlock(((LinCompoundTag) toNativeLin(tag))); - } - extent.setBlock(vec, state.toBaseBlock()); - if (options.shouldRegenBiomes()) { - Biome origBiome = chunk.getNoiseBiome(vec.x(), vec.y(), vec.z()).value(); - BiomeType adaptedBiome = adapt(serverWorld, origBiome); - if (adaptedBiome != null) { - extent.setBiome(vec, adaptedBiome); - } - } - } - } - - @SuppressWarnings("unchecked") - private List> submitChunkLoadTasks(Region region, ServerLevel serverWorld) { - ServerChunkCache chunkManager = serverWorld.getChunkSource(); - List> chunkLoadings = new ArrayList<>(); - // Pre-gen all the chunks - for (BlockVector2 chunk : region.getChunks()) { - try { - //noinspection unchecked - chunkLoadings.add( - ((CompletableFuture>) - getChunkFutureMethod.invoke(chunkManager, chunk.x(), chunk.z(), ChunkStatus.FEATURES, true)) - .thenApply(either -> either.left().orElse(null)) - ); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new IllegalStateException("Couldn't load chunk for regen.", e); - } - } - return chunkLoadings; - } - - private ResourceKey getWorldDimKey(Environment env) { - switch (env) { - case NETHER: - return LevelStem.NETHER; - case THE_END: - return LevelStem.END; - case NORMAL: - default: - return LevelStem.OVERWORLD; - } - } - - private static final Set SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet( - SideEffect.NEIGHBORS, - SideEffect.LIGHTING, - SideEffect.VALIDATION, - SideEffect.ENTITY_AI, - SideEffect.EVENTS, - SideEffect.UPDATE - ); - - @Override - public Set getSupportedSideEffects() { - return SUPPORTED_SIDE_EFFECTS; - } - - @Override - public boolean clearContainerBlockContents(org.bukkit.World world, BlockVector3 pt) { - ServerLevel originalWorld = ((CraftWorld) world).getHandle(); - - BlockEntity entity = originalWorld.getBlockEntity(new BlockPos(pt.x(), pt.y(), pt.z())); - if (entity instanceof Clearable) { - ((Clearable) entity).clearContent(); - return true; - } - return false; - } - - @Override - public void initializeRegistries() { - DedicatedServer server = ((CraftServer) Bukkit.getServer()).getServer(); - // Biomes - for (ResourceLocation name : server.registryAccess().registryOrThrow(Registries.BIOME).keySet()) { - if (BiomeType.REGISTRY.get(name.toString()) == null) { - BiomeType.REGISTRY.register(name.toString(), new BiomeType(name.toString())); - } - } - - // BiomeCategories - Registry biomeRegistry = server.registryAccess().registryOrThrow(Registries.BIOME); - biomeRegistry.getTagNames().forEach(tagKey -> { - String key = tagKey.location().toString(); - if (BiomeCategory.REGISTRY.get(key) == null) { - BiomeCategory.REGISTRY.register(key, new BiomeCategory( - key, - () -> biomeRegistry.getTag(tagKey) - .stream() - .flatMap(HolderSet.Named::stream) - .map(Holder::value) - .map(this::adapt) - .collect(Collectors.toSet())) - ); - } - }); - } - // ------------------------------------------------------------------------ - // Code that is less likely to break - // ------------------------------------------------------------------------ - - /** - * Converts from a non-native NMS NBT structure to a native WorldEdit NBT - * structure. - * - * @param foreign non-native NMS NBT structure - * @return native WorldEdit NBT structure - */ - @Override - public LinTag toNativeLin(net.minecraft.nbt.Tag foreign) { - if (foreign == null) { - return null; - } - if (foreign instanceof net.minecraft.nbt.CompoundTag) { - Map> values = new HashMap<>(); - Set foreignKeys = ((net.minecraft.nbt.CompoundTag) foreign).getAllKeys(); - - for (String str : foreignKeys) { - net.minecraft.nbt.Tag base = ((net.minecraft.nbt.CompoundTag) foreign).get(str); - values.put(str, toNativeLin(base)); - } - return LinCompoundTag.of(values); - } else if (foreign instanceof net.minecraft.nbt.ByteTag) { - return LinByteTag.of(((net.minecraft.nbt.ByteTag) foreign).getAsByte()); - } else if (foreign instanceof net.minecraft.nbt.ByteArrayTag) { - return LinByteArrayTag.of(((net.minecraft.nbt.ByteArrayTag) foreign).getAsByteArray()); - } else if (foreign instanceof net.minecraft.nbt.DoubleTag) { - return LinDoubleTag.of(((net.minecraft.nbt.DoubleTag) foreign).getAsDouble()); - } else if (foreign instanceof net.minecraft.nbt.FloatTag) { - return LinFloatTag.of(((net.minecraft.nbt.FloatTag) foreign).getAsFloat()); - } else if (foreign instanceof net.minecraft.nbt.IntTag) { - return LinIntTag.of(((net.minecraft.nbt.IntTag) foreign).getAsInt()); - } else if (foreign instanceof net.minecraft.nbt.IntArrayTag) { - return LinIntArrayTag.of(((net.minecraft.nbt.IntArrayTag) foreign).getAsIntArray()); - } else if (foreign instanceof net.minecraft.nbt.LongArrayTag) { - return LinLongArrayTag.of(((net.minecraft.nbt.LongArrayTag) foreign).getAsLongArray()); - } else if (foreign instanceof net.minecraft.nbt.ListTag) { - try { - return toNativeLinList((net.minecraft.nbt.ListTag) foreign); - } catch (Throwable e) { - logger.log(Level.WARNING, "Failed to convert net.minecraft.nbt.ListTag", e); - } - } else if (foreign instanceof net.minecraft.nbt.LongTag) { - return LinLongTag.of(((net.minecraft.nbt.LongTag) foreign).getAsLong()); - } else if (foreign instanceof net.minecraft.nbt.ShortTag) { - return LinShortTag.of(((net.minecraft.nbt.ShortTag) foreign).getAsShort()); - } else if (foreign instanceof net.minecraft.nbt.StringTag) { - return LinStringTag.of(foreign.getAsString()); - } else if (foreign instanceof net.minecraft.nbt.EndTag) { - return LinEndTag.instance(); - } - throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName()); - } - - /** - * Convert a foreign NBT list tag into a native WorldEdit one. - * - * @param foreign the foreign tag - * @return the converted tag - * @throws SecurityException on error - * @throws IllegalArgumentException on error - */ - private LinListTag toNativeLinList(net.minecraft.nbt.ListTag foreign) throws SecurityException, IllegalArgumentException { - LinListTag.Builder> builder = LinListTag.builder( - LinTagType.fromId(LinTagId.fromId(foreign.getElementType())) - ); - - for (net.minecraft.nbt.Tag tag : foreign) { - builder.add(toNativeLin(tag)); - } - - return builder.build(); - } - - /** - * Converts a WorldEdit-native NBT structure to a NMS structure. - * - * @param foreign structure to convert - * @return non-native structure - */ - @Override - public net.minecraft.nbt.Tag fromNativeLin(LinTag foreign) { - if (foreign == null) { - return null; - } - if (foreign instanceof LinCompoundTag compoundTag) { - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - for (var entry : compoundTag.value().entrySet()) { - tag.put(entry.getKey(), fromNativeLin(entry.getValue())); - } - return tag; - } else if (foreign instanceof LinByteTag byteTag) { - return net.minecraft.nbt.ByteTag.valueOf(byteTag.valueAsByte()); - } else if (foreign instanceof LinByteArrayTag byteArrayTag) { - return new net.minecraft.nbt.ByteArrayTag(byteArrayTag.value()); - } else if (foreign instanceof LinDoubleTag doubleTag) { - return net.minecraft.nbt.DoubleTag.valueOf(doubleTag.valueAsDouble()); - } else if (foreign instanceof LinFloatTag floatTag) { - return net.minecraft.nbt.FloatTag.valueOf(floatTag.valueAsFloat()); - } else if (foreign instanceof LinIntTag intTag) { - return net.minecraft.nbt.IntTag.valueOf(intTag.valueAsInt()); - } else if (foreign instanceof LinIntArrayTag intArrayTag) { - return new net.minecraft.nbt.IntArrayTag(intArrayTag.value()); - } else if (foreign instanceof LinLongArrayTag longArrayTag) { - return new net.minecraft.nbt.LongArrayTag(longArrayTag.value()); - } else if (foreign instanceof LinListTag listTag) { - net.minecraft.nbt.ListTag tag = new net.minecraft.nbt.ListTag(); - for (var t : listTag.value()) { - tag.add(fromNativeLin(t)); - } - return tag; - } else if (foreign instanceof LinLongTag longTag) { - return net.minecraft.nbt.LongTag.valueOf(longTag.valueAsLong()); - } else if (foreign instanceof LinShortTag shortTag) { - return net.minecraft.nbt.ShortTag.valueOf(shortTag.valueAsShort()); - } else if (foreign instanceof LinStringTag stringTag) { - return net.minecraft.nbt.StringTag.valueOf(stringTag.value()); - } else if (foreign instanceof LinEndTag) { - return net.minecraft.nbt.EndTag.INSTANCE; - } else { - throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName()); - } - } - - @Override - public boolean supportsWatchdog() { - return watchdog != null; - } - - @Override - public void tickWatchdog() { - watchdog.tick(); - } - - private class SpigotWatchdog implements Watchdog { - private final Field instanceField; - private final Field lastTickField; - - SpigotWatchdog() throws NoSuchFieldException { - Field instanceField = WatchdogThread.class.getDeclaredField("instance"); - instanceField.setAccessible(true); - this.instanceField = instanceField; - - Field lastTickField = WatchdogThread.class.getDeclaredField("lastTick"); - lastTickField.setAccessible(true); - this.lastTickField = lastTickField; - } - - @Override - public void tick() { - try { - WatchdogThread instance = (WatchdogThread) this.instanceField.get(null); - if ((long) lastTickField.get(instance) != 0) { - WatchdogThread.tick(); - } - } catch (IllegalAccessException e) { - logger.log(Level.WARNING, "Failed to tick watchdog", e); - } - } - } - - private static class MojangWatchdog implements Watchdog { - private final DedicatedServer server; - private final Field tickField; - - MojangWatchdog(DedicatedServer server) throws NoSuchFieldException { - this.server = server; - Field tickField = MinecraftServer.class.getDeclaredField( - Refraction.pickName("nextTickTime", "ah") - ); - if (tickField.getType() != long.class) { - throw new IllegalStateException("nextTickTime is not a long field, mapping is likely incorrect"); - } - tickField.setAccessible(true); - this.tickField = tickField; - } - - @Override - public void tick() { - try { - tickField.set(server, Util.getMillis()); - } catch (IllegalAccessException ignored) { - } - } - } - - private static class NoOpWorldLoadListener implements ChunkProgressListener { - @Override - public void updateSpawnPos(ChunkPos spawnPos) { - } - - @Override - public void onStatusChange(ChunkPos pos, @org.jetbrains.annotations.Nullable ChunkStatus status) { - } - - @Override - public void start() { - } - - @Override - public void stop() { - } - - @Override - public void setChunkRadius(int radius) { - } - } -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightDataConverters.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightDataConverters.java deleted file mode 100644 index ebe674ca5..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightDataConverters.java +++ /dev/null @@ -1,2798 +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.bukkit.adapter.ext.fawe.v1_20_R1; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonParseException; -import com.mojang.datafixers.DSL; -import com.mojang.datafixers.DSL.TypeReference; -import com.mojang.datafixers.DataFixer; -import com.mojang.datafixers.DataFixerBuilder; -import com.mojang.datafixers.schemas.Schema; -import com.mojang.serialization.Dynamic; -import net.minecraft.core.Direction; -import net.minecraft.nbt.NbtOps; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.MutableComponent; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.GsonHelper; -import net.minecraft.util.StringUtil; -import net.minecraft.util.datafix.DataFixers; -import net.minecraft.util.datafix.fixes.References; -import net.minecraft.world.item.DyeColor; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.enginehub.linbus.tree.LinCompoundTag; - -import javax.annotation.Nullable; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Executor; -import java.util.stream.Collectors; - -/** - * Handles converting all Pre 1.13.2 data using the Legacy DataFix System (ported to 1.13.2) - * - * We register a DFU Fixer per Legacy Data Version and apply the fixes using legacy strategy - * which is safer, faster and cleaner code. - * - * The pre DFU code did not fail when the Source version was unknown. - * - * This class also provides util methods for converting compounds to wrap the update call to - * receive the source version in the compound - */ -@SuppressWarnings({ "rawtypes", "unchecked" }) -class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.worldedit.world.DataFixer { - - @SuppressWarnings("unchecked") - @Override - public T fixUp(FixType type, T original, int srcVer) { - if (type == FixTypes.CHUNK) { - return (T) fixChunk((LinCompoundTag) original, srcVer); - } else if (type == FixTypes.BLOCK_ENTITY) { - return (T) fixBlockEntity((LinCompoundTag) original, srcVer); - } else if (type == FixTypes.ENTITY) { - return (T) fixEntity((LinCompoundTag) original, srcVer); - } else if (type == FixTypes.BLOCK_STATE) { - return (T) fixBlockState((String) original, srcVer); - } else if (type == FixTypes.ITEM_TYPE) { - return (T) fixItemType((String) original, srcVer); - } else if (type == FixTypes.BIOME) { - return (T) fixBiome((String) original, srcVer); - } - return original; - } - - private LinCompoundTag fixChunk(LinCompoundTag originalChunk, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(originalChunk); - net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.CHUNK, tag, srcVer); - return (LinCompoundTag) adapter.toNativeLin(fixed); - } - - private LinCompoundTag fixBlockEntity(LinCompoundTag origTileEnt, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(origTileEnt); - net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.BLOCK_ENTITY, tag, srcVer); - return (LinCompoundTag) adapter.toNativeLin(fixed); - } - - private LinCompoundTag fixEntity(LinCompoundTag origEnt, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(origEnt); - net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.ENTITY, tag, srcVer); - return (LinCompoundTag) adapter.toNativeLin(fixed); - } - - private String fixBlockState(String blockState, int srcVer) { - net.minecraft.nbt.CompoundTag stateNBT = stateToNBT(blockState); - Dynamic dynamic = new Dynamic<>(OPS_NBT, stateNBT); - net.minecraft.nbt.CompoundTag fixed = (net.minecraft.nbt.CompoundTag) INSTANCE.fixer.update(References.BLOCK_STATE, dynamic, srcVer, DATA_VERSION).getValue(); - return nbtToState(fixed); - } - - private String nbtToState(net.minecraft.nbt.CompoundTag tagCompound) { - StringBuilder sb = new StringBuilder(); - sb.append(tagCompound.getString("Name")); - if (tagCompound.contains("Properties", 10)) { - sb.append('['); - net.minecraft.nbt.CompoundTag props = tagCompound.getCompound("Properties"); - sb.append(props.getAllKeys().stream().map(k -> k + "=" + props.getString(k).replace("\"", "")).collect(Collectors.joining(","))); - sb.append(']'); - } - return sb.toString(); - } - - private static net.minecraft.nbt.CompoundTag stateToNBT(String blockState) { - int propIdx = blockState.indexOf('['); - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - if (propIdx < 0) { - tag.putString("Name", blockState); - } else { - tag.putString("Name", blockState.substring(0, propIdx)); - net.minecraft.nbt.CompoundTag propTag = new net.minecraft.nbt.CompoundTag(); - String props = blockState.substring(propIdx + 1, blockState.length() - 1); - String[] propArr = props.split(","); - for (String pair : propArr) { - final String[] split = pair.split("="); - propTag.putString(split[0], split[1]); - } - tag.put("Properties", propTag); - } - return tag; - } - - private String fixBiome(String key, int srcVer) { - return fixName(key, srcVer, References.BIOME); - } - - private String fixItemType(String key, int srcVer) { - return fixName(key, srcVer, References.ITEM_NAME); - } - - private static String fixName(String key, int srcVer, TypeReference type) { - return INSTANCE.fixer.update(type, new Dynamic<>(OPS_NBT, net.minecraft.nbt.StringTag.valueOf(key)), srcVer, DATA_VERSION) - .getValue().getAsString(); - } - - private final PaperweightAdapter adapter; - - private static final NbtOps OPS_NBT = NbtOps.INSTANCE; - private static final int LEGACY_VERSION = 1343; - private static int DATA_VERSION; - static PaperweightDataConverters INSTANCE; - - private final Map> converters = new EnumMap<>(LegacyType.class); - private final Map> inspectors = new EnumMap<>(LegacyType.class); - - // Set on build - private DataFixer fixer; - private static final Map DFU_TO_LEGACY = new HashMap<>(); - - public enum LegacyType { - LEVEL(References.LEVEL), - PLAYER(References.PLAYER), - CHUNK(References.CHUNK), - BLOCK_ENTITY(References.BLOCK_ENTITY), - ENTITY(References.ENTITY), - ITEM_INSTANCE(References.ITEM_STACK), - OPTIONS(References.OPTIONS), - STRUCTURE(References.STRUCTURE); - - private final TypeReference type; - - LegacyType(TypeReference type) { - this.type = type; - DFU_TO_LEGACY.put(type.typeName(), this); - } - - public TypeReference getDFUType() { - return type; - } - } - - PaperweightDataConverters(int dataVersion, PaperweightAdapter adapter) { - super(dataVersion); - DATA_VERSION = dataVersion; - INSTANCE = this; - this.adapter = adapter; - registerConverters(); - registerInspectors(); - } - - - // Called after fixers are built and ready for FIXING - @Override - public DataFixer buildUnoptimized() { - return this.fixer = new WrappedDataFixer(DataFixers.getDataFixer()); - } - - @Override - public DataFixer buildOptimized(final Set requiredTypes, Executor executor) { - return buildUnoptimized(); - } - - @SuppressWarnings("unchecked") - private class WrappedDataFixer implements DataFixer { - private final DataFixer realFixer; - - WrappedDataFixer(DataFixer realFixer) { - this.realFixer = realFixer; - } - - @Override - public Dynamic update(TypeReference type, Dynamic dynamic, int sourceVer, int targetVer) { - LegacyType legacyType = DFU_TO_LEGACY.get(type.typeName()); - if (sourceVer < LEGACY_VERSION && legacyType != null) { - net.minecraft.nbt.CompoundTag cmp = (net.minecraft.nbt.CompoundTag) dynamic.getValue(); - int desiredVersion = Math.min(targetVer, LEGACY_VERSION); - - cmp = convert(legacyType, cmp, sourceVer, desiredVersion); - sourceVer = desiredVersion; - dynamic = new Dynamic(OPS_NBT, cmp); - } - return realFixer.update(type, dynamic, sourceVer, targetVer); - } - - private net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer, int desiredVersion) { - List converters = PaperweightDataConverters.this.converters.get(type); - if (converters != null && !converters.isEmpty()) { - for (DataConverter converter : converters) { - int dataVersion = converter.getDataVersion(); - if (dataVersion > sourceVer && dataVersion <= desiredVersion) { - cmp = converter.convert(cmp); - } - } - } - - List inspectors = PaperweightDataConverters.this.inspectors.get(type); - if (inspectors != null && !inspectors.isEmpty()) { - for (DataInspector inspector : inspectors) { - cmp = inspector.inspect(cmp, sourceVer, desiredVersion); - } - } - - return cmp; - } - - @Override - public Schema getSchema(int i) { - return realFixer.getSchema(i); - } - } - - public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp) { - return convert(type.getDFUType(), cmp); - } - - public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer) { - return convert(type.getDFUType(), cmp, sourceVer); - } - - public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - return convert(type.getDFUType(), cmp, sourceVer, targetVer); - } - - public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp) { - int i = cmp.contains("DataVersion", 99) ? cmp.getInt("DataVersion") : -1; - return convert(type, cmp, i); - } - - public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp, int sourceVer) { - return convert(type, cmp, sourceVer, DATA_VERSION); - } - - public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (sourceVer >= targetVer) { - return cmp; - } - return (net.minecraft.nbt.CompoundTag) INSTANCE.fixer.update(type, new Dynamic<>(OPS_NBT, cmp), sourceVer, targetVer).getValue(); - } - - - public interface DataInspector { - net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer); - } - - public interface DataConverter { - - int getDataVersion(); - - net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp); - } - - - private void registerInspector(LegacyType type, DataInspector inspector) { - this.inspectors.computeIfAbsent(type, k -> new ArrayList<>()).add(inspector); - } - - private void registerConverter(LegacyType type, DataConverter converter) { - int version = converter.getDataVersion(); - - List list = this.converters.computeIfAbsent(type, k -> new ArrayList<>()); - if (!list.isEmpty() && list.get(list.size() - 1).getDataVersion() > version) { - for (int j = 0; j < list.size(); ++j) { - if (list.get(j).getDataVersion() > version) { - list.add(j, converter); - break; - } - } - } else { - list.add(converter); - } - } - - private void registerInspectors() { - registerEntityItemList("EntityHorseDonkey", "SaddleItem", "Items"); - registerEntityItemList("EntityHorseMule", "Items"); - registerEntityItemList("EntityMinecartChest", "Items"); - registerEntityItemList("EntityMinecartHopper", "Items"); - registerEntityItemList("EntityVillager", "Inventory"); - registerEntityItemListEquipment("EntityArmorStand"); - registerEntityItemListEquipment("EntityBat"); - registerEntityItemListEquipment("EntityBlaze"); - registerEntityItemListEquipment("EntityCaveSpider"); - registerEntityItemListEquipment("EntityChicken"); - registerEntityItemListEquipment("EntityCow"); - registerEntityItemListEquipment("EntityCreeper"); - registerEntityItemListEquipment("EntityEnderDragon"); - registerEntityItemListEquipment("EntityEnderman"); - registerEntityItemListEquipment("EntityEndermite"); - registerEntityItemListEquipment("EntityEvoker"); - registerEntityItemListEquipment("EntityGhast"); - registerEntityItemListEquipment("EntityGiantZombie"); - registerEntityItemListEquipment("EntityGuardian"); - registerEntityItemListEquipment("EntityGuardianElder"); - registerEntityItemListEquipment("EntityHorse"); - registerEntityItemListEquipment("EntityHorseDonkey"); - registerEntityItemListEquipment("EntityHorseMule"); - registerEntityItemListEquipment("EntityHorseSkeleton"); - registerEntityItemListEquipment("EntityHorseZombie"); - registerEntityItemListEquipment("EntityIronGolem"); - registerEntityItemListEquipment("EntityMagmaCube"); - registerEntityItemListEquipment("EntityMushroomCow"); - registerEntityItemListEquipment("EntityOcelot"); - registerEntityItemListEquipment("EntityPig"); - registerEntityItemListEquipment("EntityPigZombie"); - registerEntityItemListEquipment("EntityRabbit"); - registerEntityItemListEquipment("EntitySheep"); - registerEntityItemListEquipment("EntityShulker"); - registerEntityItemListEquipment("EntitySilverfish"); - registerEntityItemListEquipment("EntitySkeleton"); - registerEntityItemListEquipment("EntitySkeletonStray"); - registerEntityItemListEquipment("EntitySkeletonWither"); - registerEntityItemListEquipment("EntitySlime"); - registerEntityItemListEquipment("EntitySnowman"); - registerEntityItemListEquipment("EntitySpider"); - registerEntityItemListEquipment("EntitySquid"); - registerEntityItemListEquipment("EntityVex"); - registerEntityItemListEquipment("EntityVillager"); - registerEntityItemListEquipment("EntityVindicator"); - registerEntityItemListEquipment("EntityWitch"); - registerEntityItemListEquipment("EntityWither"); - registerEntityItemListEquipment("EntityWolf"); - registerEntityItemListEquipment("EntityZombie"); - registerEntityItemListEquipment("EntityZombieHusk"); - registerEntityItemListEquipment("EntityZombieVillager"); - registerEntityItemSingle("EntityFireworks", "FireworksItem"); - registerEntityItemSingle("EntityHorse", "ArmorItem"); - registerEntityItemSingle("EntityHorse", "SaddleItem"); - registerEntityItemSingle("EntityHorseMule", "SaddleItem"); - registerEntityItemSingle("EntityHorseSkeleton", "SaddleItem"); - registerEntityItemSingle("EntityHorseZombie", "SaddleItem"); - registerEntityItemSingle("EntityItem", "Item"); - registerEntityItemSingle("EntityItemFrame", "Item"); - registerEntityItemSingle("EntityPotion", "Potion"); - - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItem("TileEntityRecordPlayer", "RecordItem")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityBrewingStand", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityChest", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityDispenser", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityDropper", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityFurnace", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityHopper", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityShulkerBox", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorMobSpawnerMobs()); - registerInspector(LegacyType.CHUNK, new DataInspectorChunks()); - registerInspector(LegacyType.ENTITY, new DataInspectorCommandBlock()); - registerInspector(LegacyType.ENTITY, new DataInspectorEntityPassengers()); - registerInspector(LegacyType.ENTITY, new DataInspectorMobSpawnerMinecart()); - registerInspector(LegacyType.ENTITY, new DataInspectorVillagers()); - registerInspector(LegacyType.ITEM_INSTANCE, new DataInspectorBlockEntity()); - registerInspector(LegacyType.ITEM_INSTANCE, new DataInspectorEntity()); - registerInspector(LegacyType.LEVEL, new DataInspectorLevelPlayer()); - registerInspector(LegacyType.PLAYER, new DataInspectorPlayer()); - registerInspector(LegacyType.PLAYER, new DataInspectorPlayerVehicle()); - registerInspector(LegacyType.STRUCTURE, new DataInspectorStructure()); - } - - private void registerConverters() { - registerConverter(LegacyType.ENTITY, new DataConverterEquipment()); - registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterSignText()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterMaterialId()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterPotionId()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterSpawnEgg()); - registerConverter(LegacyType.ENTITY, new DataConverterMinecart()); - registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterMobSpawner()); - registerConverter(LegacyType.ENTITY, new DataConverterUUID()); - registerConverter(LegacyType.ENTITY, new DataConverterHealth()); - registerConverter(LegacyType.ENTITY, new DataConverterSaddle()); - registerConverter(LegacyType.ENTITY, new DataConverterHanging()); - registerConverter(LegacyType.ENTITY, new DataConverterDropChances()); - registerConverter(LegacyType.ENTITY, new DataConverterRiding()); - registerConverter(LegacyType.ENTITY, new DataConverterArmorStand()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterBook()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterCookedFish()); - registerConverter(LegacyType.ENTITY, new DataConverterZombie()); - registerConverter(LegacyType.OPTIONS, new DataConverterVBO()); - registerConverter(LegacyType.ENTITY, new DataConverterGuardian()); - registerConverter(LegacyType.ENTITY, new DataConverterSkeleton()); - registerConverter(LegacyType.ENTITY, new DataConverterZombieType()); - registerConverter(LegacyType.ENTITY, new DataConverterHorse()); - registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterTileEntity()); - registerConverter(LegacyType.ENTITY, new DataConverterEntity()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterBanner()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterPotionWater()); - registerConverter(LegacyType.ENTITY, new DataConverterShulker()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterShulkerBoxItem()); - registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterShulkerBoxBlock()); - registerConverter(LegacyType.OPTIONS, new DataConverterLang()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterTotem()); - registerConverter(LegacyType.CHUNK, new DataConverterBedBlock()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterBedItem()); - } - - private void registerEntityItemList(String type, String... keys) { - registerInspector(LegacyType.ENTITY, new DataInspectorItemList(type, keys)); - } - - private void registerEntityItemSingle(String type, String key) { - registerInspector(LegacyType.ENTITY, new DataInspectorItem(type, key)); - } - - private void registerEntityItemListEquipment(String type) { - registerEntityItemList(type, "ArmorItems", "HandItems"); - } - - private static final Map OLD_ID_TO_KEY_MAP = new HashMap<>(); - - static { - final Map map = OLD_ID_TO_KEY_MAP; - map.put("EntityItem", new ResourceLocation("item")); - map.put("EntityExperienceOrb", new ResourceLocation("xp_orb")); - map.put("EntityAreaEffectCloud", new ResourceLocation("area_effect_cloud")); - map.put("EntityGuardianElder", new ResourceLocation("elder_guardian")); - map.put("EntitySkeletonWither", new ResourceLocation("wither_skeleton")); - map.put("EntitySkeletonStray", new ResourceLocation("stray")); - map.put("EntityEgg", new ResourceLocation("egg")); - map.put("EntityLeash", new ResourceLocation("leash_knot")); - map.put("EntityPainting", new ResourceLocation("painting")); - map.put("EntityTippedArrow", new ResourceLocation("arrow")); - map.put("EntitySnowball", new ResourceLocation("snowball")); - map.put("EntityLargeFireball", new ResourceLocation("fireball")); - map.put("EntitySmallFireball", new ResourceLocation("small_fireball")); - map.put("EntityEnderPearl", new ResourceLocation("ender_pearl")); - map.put("EntityEnderSignal", new ResourceLocation("eye_of_ender_signal")); - map.put("EntityPotion", new ResourceLocation("potion")); - map.put("EntityThrownExpBottle", new ResourceLocation("xp_bottle")); - map.put("EntityItemFrame", new ResourceLocation("item_frame")); - map.put("EntityWitherSkull", new ResourceLocation("wither_skull")); - map.put("EntityTNTPrimed", new ResourceLocation("tnt")); - map.put("EntityFallingBlock", new ResourceLocation("falling_block")); - map.put("EntityFireworks", new ResourceLocation("fireworks_rocket")); - map.put("EntityZombieHusk", new ResourceLocation("husk")); - map.put("EntitySpectralArrow", new ResourceLocation("spectral_arrow")); - map.put("EntityShulkerBullet", new ResourceLocation("shulker_bullet")); - map.put("EntityDragonFireball", new ResourceLocation("dragon_fireball")); - map.put("EntityZombieVillager", new ResourceLocation("zombie_villager")); - map.put("EntityHorseSkeleton", new ResourceLocation("skeleton_horse")); - map.put("EntityHorseZombie", new ResourceLocation("zombie_horse")); - map.put("EntityArmorStand", new ResourceLocation("armor_stand")); - map.put("EntityHorseDonkey", new ResourceLocation("donkey")); - map.put("EntityHorseMule", new ResourceLocation("mule")); - map.put("EntityEvokerFangs", new ResourceLocation("evocation_fangs")); - map.put("EntityEvoker", new ResourceLocation("evocation_illager")); - map.put("EntityVex", new ResourceLocation("vex")); - map.put("EntityVindicator", new ResourceLocation("vindication_illager")); - map.put("EntityIllagerIllusioner", new ResourceLocation("illusion_illager")); - map.put("EntityMinecartCommandBlock", new ResourceLocation("commandblock_minecart")); - map.put("EntityBoat", new ResourceLocation("boat")); - map.put("EntityMinecartRideable", new ResourceLocation("minecart")); - map.put("EntityMinecartChest", new ResourceLocation("chest_minecart")); - map.put("EntityMinecartFurnace", new ResourceLocation("furnace_minecart")); - map.put("EntityMinecartTNT", new ResourceLocation("tnt_minecart")); - map.put("EntityMinecartHopper", new ResourceLocation("hopper_minecart")); - map.put("EntityMinecartMobSpawner", new ResourceLocation("spawner_minecart")); - map.put("EntityCreeper", new ResourceLocation("creeper")); - map.put("EntitySkeleton", new ResourceLocation("skeleton")); - map.put("EntitySpider", new ResourceLocation("spider")); - map.put("EntityGiantZombie", new ResourceLocation("giant")); - map.put("EntityZombie", new ResourceLocation("zombie")); - map.put("EntitySlime", new ResourceLocation("slime")); - map.put("EntityGhast", new ResourceLocation("ghast")); - map.put("EntityPigZombie", new ResourceLocation("zombie_pigman")); - map.put("EntityEnderman", new ResourceLocation("enderman")); - map.put("EntityCaveSpider", new ResourceLocation("cave_spider")); - map.put("EntitySilverfish", new ResourceLocation("silverfish")); - map.put("EntityBlaze", new ResourceLocation("blaze")); - map.put("EntityMagmaCube", new ResourceLocation("magma_cube")); - map.put("EntityEnderDragon", new ResourceLocation("ender_dragon")); - map.put("EntityWither", new ResourceLocation("wither")); - map.put("EntityBat", new ResourceLocation("bat")); - map.put("EntityWitch", new ResourceLocation("witch")); - map.put("EntityEndermite", new ResourceLocation("endermite")); - map.put("EntityGuardian", new ResourceLocation("guardian")); - map.put("EntityShulker", new ResourceLocation("shulker")); - map.put("EntityPig", new ResourceLocation("pig")); - map.put("EntitySheep", new ResourceLocation("sheep")); - map.put("EntityCow", new ResourceLocation("cow")); - map.put("EntityChicken", new ResourceLocation("chicken")); - map.put("EntitySquid", new ResourceLocation("squid")); - map.put("EntityWolf", new ResourceLocation("wolf")); - map.put("EntityMushroomCow", new ResourceLocation("mooshroom")); - map.put("EntitySnowman", new ResourceLocation("snowman")); - map.put("EntityOcelot", new ResourceLocation("ocelot")); - map.put("EntityIronGolem", new ResourceLocation("villager_golem")); - map.put("EntityHorse", new ResourceLocation("horse")); - map.put("EntityRabbit", new ResourceLocation("rabbit")); - map.put("EntityPolarBear", new ResourceLocation("polar_bear")); - map.put("EntityLlama", new ResourceLocation("llama")); - map.put("EntityLlamaSpit", new ResourceLocation("llama_spit")); - map.put("EntityParrot", new ResourceLocation("parrot")); - map.put("EntityVillager", new ResourceLocation("villager")); - map.put("EntityEnderCrystal", new ResourceLocation("ender_crystal")); - map.put("TileEntityFurnace", new ResourceLocation("furnace")); - map.put("TileEntityChest", new ResourceLocation("chest")); - map.put("TileEntityEnderChest", new ResourceLocation("ender_chest")); - map.put("TileEntityRecordPlayer", new ResourceLocation("jukebox")); - map.put("TileEntityDispenser", new ResourceLocation("dispenser")); - map.put("TileEntityDropper", new ResourceLocation("dropper")); - map.put("TileEntitySign", new ResourceLocation("sign")); - map.put("TileEntityMobSpawner", new ResourceLocation("mob_spawner")); - map.put("TileEntityNote", new ResourceLocation("noteblock")); - map.put("TileEntityPiston", new ResourceLocation("piston")); - map.put("TileEntityBrewingStand", new ResourceLocation("brewing_stand")); - map.put("TileEntityEnchantTable", new ResourceLocation("enchanting_table")); - map.put("TileEntityEnderPortal", new ResourceLocation("end_portal")); - map.put("TileEntityBeacon", new ResourceLocation("beacon")); - map.put("TileEntitySkull", new ResourceLocation("skull")); - map.put("TileEntityLightDetector", new ResourceLocation("daylight_detector")); - map.put("TileEntityHopper", new ResourceLocation("hopper")); - map.put("TileEntityComparator", new ResourceLocation("comparator")); - map.put("TileEntityFlowerPot", new ResourceLocation("flower_pot")); - map.put("TileEntityBanner", new ResourceLocation("banner")); - map.put("TileEntityStructure", new ResourceLocation("structure_block")); - map.put("TileEntityEndGateway", new ResourceLocation("end_gateway")); - map.put("TileEntityCommand", new ResourceLocation("command_block")); - map.put("TileEntityShulkerBox", new ResourceLocation("shulker_box")); - map.put("TileEntityBed", new ResourceLocation("bed")); - } - - private static ResourceLocation getKey(String type) { - final ResourceLocation key = OLD_ID_TO_KEY_MAP.get(type); - if (key == null) { - throw new IllegalArgumentException("Unknown mapping for " + type); - } - return key; - } - - private static void convertCompound(LegacyType type, net.minecraft.nbt.CompoundTag cmp, String key, int sourceVer, int targetVer) { - cmp.put(key, convert(type, cmp.getCompound(key), sourceVer, targetVer)); - } - - private static void convertItem(net.minecraft.nbt.CompoundTag nbttagcompound, String key, int sourceVer, int targetVer) { - if (nbttagcompound.contains(key, 10)) { - convertCompound(LegacyType.ITEM_INSTANCE, nbttagcompound, key, sourceVer, targetVer); - } - } - - private static void convertItems(net.minecraft.nbt.CompoundTag nbttagcompound, String key, int sourceVer, int targetVer) { - if (nbttagcompound.contains(key, 9)) { - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound.getList(key, 10); - - for (int j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set(j, convert(LegacyType.ITEM_INSTANCE, nbttaglist.getCompound(j), sourceVer, targetVer)); - } - } - - } - - private static class DataConverterEquipment implements DataConverter { - - DataConverterEquipment() { - } - - public int getDataVersion() { - return 100; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - net.minecraft.nbt.ListTag nbttaglist = cmp.getList("Equipment", 10); - net.minecraft.nbt.ListTag nbttaglist1; - - if (!nbttaglist.isEmpty() && !cmp.contains("HandItems", 10)) { - nbttaglist1 = new net.minecraft.nbt.ListTag(); - nbttaglist1.add(nbttaglist.get(0)); - nbttaglist1.add(new net.minecraft.nbt.CompoundTag()); - cmp.put("HandItems", nbttaglist1); - } - - if (nbttaglist.size() > 1 && !cmp.contains("ArmorItem", 10)) { - nbttaglist1 = new net.minecraft.nbt.ListTag(); - nbttaglist1.add(nbttaglist.get(1)); - nbttaglist1.add(nbttaglist.get(2)); - nbttaglist1.add(nbttaglist.get(3)); - nbttaglist1.add(nbttaglist.get(4)); - cmp.put("ArmorItems", nbttaglist1); - } - - cmp.remove("Equipment"); - if (cmp.contains("DropChances", 9)) { - nbttaglist1 = cmp.getList("DropChances", 5); - net.minecraft.nbt.ListTag nbttaglist2; - - if (!cmp.contains("HandDropChances", 10)) { - nbttaglist2 = new net.minecraft.nbt.ListTag(); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(0))); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(0.0F)); - cmp.put("HandDropChances", nbttaglist2); - } - - if (!cmp.contains("ArmorDropChances", 10)) { - nbttaglist2 = new net.minecraft.nbt.ListTag(); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(1))); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(2))); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(3))); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(4))); - cmp.put("ArmorDropChances", nbttaglist2); - } - - cmp.remove("DropChances"); - } - - return cmp; - } - } - - private static class DataInspectorBlockEntity implements DataInspector { - - private static final Map b = Maps.newHashMap(); - private static final Map c = Maps.newHashMap(); - - DataInspectorBlockEntity() { - } - - @Nullable - private static String convertEntityId(int i, String s) { - String key = new ResourceLocation(s).toString(); - if (i < 515 && DataInspectorBlockEntity.b.containsKey(key)) { - return DataInspectorBlockEntity.b.get(key); - } else { - return DataInspectorBlockEntity.c.get(key); - } - } - - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (!cmp.contains("tag", 10)) { - return cmp; - } else { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("BlockEntityTag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag"); - String s = cmp.getString("id"); - String s1 = convertEntityId(sourceVer, s); - boolean flag; - - if (s1 == null) { - // CraftBukkit - Remove unnecessary warning (occurs when deserializing a Shulker Box item) - // DataInspectorBlockEntity.a.warn("Unable to resolve BlockEntity for ItemInstance: {}", s); - flag = false; - } else { - flag = !nbttagcompound2.contains("id"); - nbttagcompound2.putString("id", s1); - } - - convert(LegacyType.BLOCK_ENTITY, nbttagcompound2, sourceVer, targetVer); - if (flag) { - nbttagcompound2.remove("id"); - } - } - - return cmp; - } - } - - static { - Map map = DataInspectorBlockEntity.b; - - map.put("minecraft:furnace", "Furnace"); - map.put("minecraft:lit_furnace", "Furnace"); - map.put("minecraft:chest", "Chest"); - map.put("minecraft:trapped_chest", "Chest"); - map.put("minecraft:ender_chest", "EnderChest"); - map.put("minecraft:jukebox", "RecordPlayer"); - map.put("minecraft:dispenser", "Trap"); - map.put("minecraft:dropper", "Dropper"); - map.put("minecraft:sign", "Sign"); - map.put("minecraft:mob_spawner", "MobSpawner"); - map.put("minecraft:noteblock", "Music"); - map.put("minecraft:brewing_stand", "Cauldron"); - map.put("minecraft:enhanting_table", "EnchantTable"); - map.put("minecraft:command_block", "CommandBlock"); - map.put("minecraft:beacon", "Beacon"); - map.put("minecraft:skull", "Skull"); - map.put("minecraft:daylight_detector", "DLDetector"); - map.put("minecraft:hopper", "Hopper"); - map.put("minecraft:banner", "Banner"); - map.put("minecraft:flower_pot", "FlowerPot"); - map.put("minecraft:repeating_command_block", "CommandBlock"); - map.put("minecraft:chain_command_block", "CommandBlock"); - map.put("minecraft:standing_sign", "Sign"); - map.put("minecraft:wall_sign", "Sign"); - map.put("minecraft:piston_head", "Piston"); - map.put("minecraft:daylight_detector_inverted", "DLDetector"); - map.put("minecraft:unpowered_comparator", "Comparator"); - map.put("minecraft:powered_comparator", "Comparator"); - map.put("minecraft:wall_banner", "Banner"); - map.put("minecraft:standing_banner", "Banner"); - map.put("minecraft:structure_block", "Structure"); - map.put("minecraft:end_portal", "Airportal"); - map.put("minecraft:end_gateway", "EndGateway"); - map.put("minecraft:shield", "Shield"); - map = DataInspectorBlockEntity.c; - map.put("minecraft:furnace", "minecraft:furnace"); - map.put("minecraft:lit_furnace", "minecraft:furnace"); - map.put("minecraft:chest", "minecraft:chest"); - map.put("minecraft:trapped_chest", "minecraft:chest"); - map.put("minecraft:ender_chest", "minecraft:enderchest"); - map.put("minecraft:jukebox", "minecraft:jukebox"); - map.put("minecraft:dispenser", "minecraft:dispenser"); - map.put("minecraft:dropper", "minecraft:dropper"); - map.put("minecraft:sign", "minecraft:sign"); - map.put("minecraft:mob_spawner", "minecraft:mob_spawner"); - map.put("minecraft:noteblock", "minecraft:noteblock"); - map.put("minecraft:brewing_stand", "minecraft:brewing_stand"); - map.put("minecraft:enhanting_table", "minecraft:enchanting_table"); - map.put("minecraft:command_block", "minecraft:command_block"); - map.put("minecraft:beacon", "minecraft:beacon"); - map.put("minecraft:skull", "minecraft:skull"); - map.put("minecraft:daylight_detector", "minecraft:daylight_detector"); - map.put("minecraft:hopper", "minecraft:hopper"); - map.put("minecraft:banner", "minecraft:banner"); - map.put("minecraft:flower_pot", "minecraft:flower_pot"); - map.put("minecraft:repeating_command_block", "minecraft:command_block"); - map.put("minecraft:chain_command_block", "minecraft:command_block"); - map.put("minecraft:shulker_box", "minecraft:shulker_box"); - map.put("minecraft:white_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:orange_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:magenta_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:light_blue_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:yellow_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:lime_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:pink_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:gray_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:silver_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:cyan_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:purple_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:blue_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:brown_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:green_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:red_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:black_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:bed", "minecraft:bed"); - map.put("minecraft:standing_sign", "minecraft:sign"); - map.put("minecraft:wall_sign", "minecraft:sign"); - map.put("minecraft:piston_head", "minecraft:piston"); - map.put("minecraft:daylight_detector_inverted", "minecraft:daylight_detector"); - map.put("minecraft:unpowered_comparator", "minecraft:comparator"); - map.put("minecraft:powered_comparator", "minecraft:comparator"); - map.put("minecraft:wall_banner", "minecraft:banner"); - map.put("minecraft:standing_banner", "minecraft:banner"); - map.put("minecraft:structure_block", "minecraft:structure_block"); - map.put("minecraft:end_portal", "minecraft:end_portal"); - map.put("minecraft:end_gateway", "minecraft:end_gateway"); - map.put("minecraft:shield", "minecraft:shield"); - } - } - - private static class DataInspectorEntity implements DataInspector { - - DataInspectorEntity() { - } - - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("EntityTag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("EntityTag"); - String s = cmp.getString("id"); - String s1; - - if ("minecraft:armor_stand".equals(s)) { - s1 = sourceVer < 515 ? "ArmorStand" : "minecraft:armor_stand"; - } else { - if (!"minecraft:spawn_egg".equals(s)) { - return cmp; - } - - s1 = nbttagcompound2.getString("id"); - } - - boolean flag; - - flag = !nbttagcompound2.contains("id", 8); - nbttagcompound2.putString("id", s1); - - convert(LegacyType.ENTITY, nbttagcompound2, sourceVer, targetVer); - if (flag) { - nbttagcompound2.remove("id"); - } - } - - return cmp; - } - } - - - private abstract static class DataInspectorTagged implements DataInspector { - - private final ResourceLocation key; - - DataInspectorTagged(String type) { - this.key = getKey(type); - } - - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (this.key.equals(new ResourceLocation(cmp.getString("id")))) { - cmp = this.inspectChecked(cmp, sourceVer, targetVer); - } - - return cmp; - } - - abstract net.minecraft.nbt.CompoundTag inspectChecked(net.minecraft.nbt.CompoundTag nbttagcompound, int sourceVer, int targetVer); - } - - private static class DataInspectorItemList extends DataInspectorTagged { - - private final String[] keys; - - DataInspectorItemList(String oclass, String... astring) { - super(oclass); - this.keys = astring; - } - - net.minecraft.nbt.CompoundTag inspectChecked(net.minecraft.nbt.CompoundTag nbttagcompound, int sourceVer, int targetVer) { - for (String s : this.keys) { - PaperweightDataConverters.convertItems(nbttagcompound, s, sourceVer, targetVer); - } - - return nbttagcompound; - } - } - - private static class DataInspectorItem extends DataInspectorTagged { - - private final String[] keys; - - DataInspectorItem(String oclass, String... astring) { - super(oclass); - this.keys = astring; - } - - net.minecraft.nbt.CompoundTag inspectChecked(net.minecraft.nbt.CompoundTag nbttagcompound, int sourceVer, int targetVer) { - for (String key : this.keys) { - PaperweightDataConverters.convertItem(nbttagcompound, key, sourceVer, targetVer); - } - - return nbttagcompound; - } - } - - private static class DataConverterMaterialId implements DataConverter { - - private static final String[] materials = new String[2268]; - - DataConverterMaterialId() { - } - - public int getDataVersion() { - return 102; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (cmp.contains("id", 99)) { - short short0 = cmp.getShort("id"); - - if (short0 > 0 && short0 < materials.length && materials[short0] != null) { - cmp.putString("id", materials[short0]); - } - } - - return cmp; - } - - static { - materials[1] = "minecraft:stone"; - materials[2] = "minecraft:grass"; - materials[3] = "minecraft:dirt"; - materials[4] = "minecraft:cobblestone"; - materials[5] = "minecraft:planks"; - materials[6] = "minecraft:sapling"; - materials[7] = "minecraft:bedrock"; - materials[8] = "minecraft:flowing_water"; - materials[9] = "minecraft:water"; - materials[10] = "minecraft:flowing_lava"; - materials[11] = "minecraft:lava"; - materials[12] = "minecraft:sand"; - materials[13] = "minecraft:gravel"; - materials[14] = "minecraft:gold_ore"; - materials[15] = "minecraft:iron_ore"; - materials[16] = "minecraft:coal_ore"; - materials[17] = "minecraft:log"; - materials[18] = "minecraft:leaves"; - materials[19] = "minecraft:sponge"; - materials[20] = "minecraft:glass"; - materials[21] = "minecraft:lapis_ore"; - materials[22] = "minecraft:lapis_block"; - materials[23] = "minecraft:dispenser"; - materials[24] = "minecraft:sandstone"; - materials[25] = "minecraft:noteblock"; - materials[27] = "minecraft:golden_rail"; - materials[28] = "minecraft:detector_rail"; - materials[29] = "minecraft:sticky_piston"; - materials[30] = "minecraft:web"; - materials[31] = "minecraft:tallgrass"; - materials[32] = "minecraft:deadbush"; - materials[33] = "minecraft:piston"; - materials[35] = "minecraft:wool"; - materials[37] = "minecraft:yellow_flower"; - materials[38] = "minecraft:red_flower"; - materials[39] = "minecraft:brown_mushroom"; - materials[40] = "minecraft:red_mushroom"; - materials[41] = "minecraft:gold_block"; - materials[42] = "minecraft:iron_block"; - materials[43] = "minecraft:double_stone_slab"; - materials[44] = "minecraft:stone_slab"; - materials[45] = "minecraft:brick_block"; - materials[46] = "minecraft:tnt"; - materials[47] = "minecraft:bookshelf"; - materials[48] = "minecraft:mossy_cobblestone"; - materials[49] = "minecraft:obsidian"; - materials[50] = "minecraft:torch"; - materials[51] = "minecraft:fire"; - materials[52] = "minecraft:mob_spawner"; - materials[53] = "minecraft:oak_stairs"; - materials[54] = "minecraft:chest"; - materials[56] = "minecraft:diamond_ore"; - materials[57] = "minecraft:diamond_block"; - materials[58] = "minecraft:crafting_table"; - materials[60] = "minecraft:farmland"; - materials[61] = "minecraft:furnace"; - materials[62] = "minecraft:lit_furnace"; - materials[65] = "minecraft:ladder"; - materials[66] = "minecraft:rail"; - materials[67] = "minecraft:stone_stairs"; - materials[69] = "minecraft:lever"; - materials[70] = "minecraft:stone_pressure_plate"; - materials[72] = "minecraft:wooden_pressure_plate"; - materials[73] = "minecraft:redstone_ore"; - materials[76] = "minecraft:redstone_torch"; - materials[77] = "minecraft:stone_button"; - materials[78] = "minecraft:snow_layer"; - materials[79] = "minecraft:ice"; - materials[80] = "minecraft:snow"; - materials[81] = "minecraft:cactus"; - materials[82] = "minecraft:clay"; - materials[84] = "minecraft:jukebox"; - materials[85] = "minecraft:fence"; - materials[86] = "minecraft:pumpkin"; - materials[87] = "minecraft:netherrack"; - materials[88] = "minecraft:soul_sand"; - materials[89] = "minecraft:glowstone"; - materials[90] = "minecraft:portal"; - materials[91] = "minecraft:lit_pumpkin"; - materials[95] = "minecraft:stained_glass"; - materials[96] = "minecraft:trapdoor"; - materials[97] = "minecraft:monster_egg"; - materials[98] = "minecraft:stonebrick"; - materials[99] = "minecraft:brown_mushroom_block"; - materials[100] = "minecraft:red_mushroom_block"; - materials[101] = "minecraft:iron_bars"; - materials[102] = "minecraft:glass_pane"; - materials[103] = "minecraft:melon_block"; - materials[106] = "minecraft:vine"; - materials[107] = "minecraft:fence_gate"; - materials[108] = "minecraft:brick_stairs"; - materials[109] = "minecraft:stone_brick_stairs"; - materials[110] = "minecraft:mycelium"; - materials[111] = "minecraft:waterlily"; - materials[112] = "minecraft:nether_brick"; - materials[113] = "minecraft:nether_brick_fence"; - materials[114] = "minecraft:nether_brick_stairs"; - materials[116] = "minecraft:enchanting_table"; - materials[119] = "minecraft:end_portal"; - materials[120] = "minecraft:end_portal_frame"; - materials[121] = "minecraft:end_stone"; - materials[122] = "minecraft:dragon_egg"; - materials[123] = "minecraft:redstone_lamp"; - materials[125] = "minecraft:double_wooden_slab"; - materials[126] = "minecraft:wooden_slab"; - materials[127] = "minecraft:cocoa"; - materials[128] = "minecraft:sandstone_stairs"; - materials[129] = "minecraft:emerald_ore"; - materials[130] = "minecraft:ender_chest"; - materials[131] = "minecraft:tripwire_hook"; - materials[133] = "minecraft:emerald_block"; - materials[134] = "minecraft:spruce_stairs"; - materials[135] = "minecraft:birch_stairs"; - materials[136] = "minecraft:jungle_stairs"; - materials[137] = "minecraft:command_block"; - materials[138] = "minecraft:beacon"; - materials[139] = "minecraft:cobblestone_wall"; - materials[141] = "minecraft:carrots"; - materials[142] = "minecraft:potatoes"; - materials[143] = "minecraft:wooden_button"; - materials[145] = "minecraft:anvil"; - materials[146] = "minecraft:trapped_chest"; - materials[147] = "minecraft:light_weighted_pressure_plate"; - materials[148] = "minecraft:heavy_weighted_pressure_plate"; - materials[151] = "minecraft:daylight_detector"; - materials[152] = "minecraft:redstone_block"; - materials[153] = "minecraft:quartz_ore"; - materials[154] = "minecraft:hopper"; - materials[155] = "minecraft:quartz_block"; - materials[156] = "minecraft:quartz_stairs"; - materials[157] = "minecraft:activator_rail"; - materials[158] = "minecraft:dropper"; - materials[159] = "minecraft:stained_hardened_clay"; - materials[160] = "minecraft:stained_glass_pane"; - materials[161] = "minecraft:leaves2"; - materials[162] = "minecraft:log2"; - materials[163] = "minecraft:acacia_stairs"; - materials[164] = "minecraft:dark_oak_stairs"; - materials[170] = "minecraft:hay_block"; - materials[171] = "minecraft:carpet"; - materials[172] = "minecraft:hardened_clay"; - materials[173] = "minecraft:coal_block"; - materials[174] = "minecraft:packed_ice"; - materials[175] = "minecraft:double_plant"; - materials[256] = "minecraft:iron_shovel"; - materials[257] = "minecraft:iron_pickaxe"; - materials[258] = "minecraft:iron_axe"; - materials[259] = "minecraft:flint_and_steel"; - materials[260] = "minecraft:apple"; - materials[261] = "minecraft:bow"; - materials[262] = "minecraft:arrow"; - materials[263] = "minecraft:coal"; - materials[264] = "minecraft:diamond"; - materials[265] = "minecraft:iron_ingot"; - materials[266] = "minecraft:gold_ingot"; - materials[267] = "minecraft:iron_sword"; - materials[268] = "minecraft:wooden_sword"; - materials[269] = "minecraft:wooden_shovel"; - materials[270] = "minecraft:wooden_pickaxe"; - materials[271] = "minecraft:wooden_axe"; - materials[272] = "minecraft:stone_sword"; - materials[273] = "minecraft:stone_shovel"; - materials[274] = "minecraft:stone_pickaxe"; - materials[275] = "minecraft:stone_axe"; - materials[276] = "minecraft:diamond_sword"; - materials[277] = "minecraft:diamond_shovel"; - materials[278] = "minecraft:diamond_pickaxe"; - materials[279] = "minecraft:diamond_axe"; - materials[280] = "minecraft:stick"; - materials[281] = "minecraft:bowl"; - materials[282] = "minecraft:mushroom_stew"; - materials[283] = "minecraft:golden_sword"; - materials[284] = "minecraft:golden_shovel"; - materials[285] = "minecraft:golden_pickaxe"; - materials[286] = "minecraft:golden_axe"; - materials[287] = "minecraft:string"; - materials[288] = "minecraft:feather"; - materials[289] = "minecraft:gunpowder"; - materials[290] = "minecraft:wooden_hoe"; - materials[291] = "minecraft:stone_hoe"; - materials[292] = "minecraft:iron_hoe"; - materials[293] = "minecraft:diamond_hoe"; - materials[294] = "minecraft:golden_hoe"; - materials[295] = "minecraft:wheat_seeds"; - materials[296] = "minecraft:wheat"; - materials[297] = "minecraft:bread"; - materials[298] = "minecraft:leather_helmet"; - materials[299] = "minecraft:leather_chestplate"; - materials[300] = "minecraft:leather_leggings"; - materials[301] = "minecraft:leather_boots"; - materials[302] = "minecraft:chainmail_helmet"; - materials[303] = "minecraft:chainmail_chestplate"; - materials[304] = "minecraft:chainmail_leggings"; - materials[305] = "minecraft:chainmail_boots"; - materials[306] = "minecraft:iron_helmet"; - materials[307] = "minecraft:iron_chestplate"; - materials[308] = "minecraft:iron_leggings"; - materials[309] = "minecraft:iron_boots"; - materials[310] = "minecraft:diamond_helmet"; - materials[311] = "minecraft:diamond_chestplate"; - materials[312] = "minecraft:diamond_leggings"; - materials[313] = "minecraft:diamond_boots"; - materials[314] = "minecraft:golden_helmet"; - materials[315] = "minecraft:golden_chestplate"; - materials[316] = "minecraft:golden_leggings"; - materials[317] = "minecraft:golden_boots"; - materials[318] = "minecraft:flint"; - materials[319] = "minecraft:porkchop"; - materials[320] = "minecraft:cooked_porkchop"; - materials[321] = "minecraft:painting"; - materials[322] = "minecraft:golden_apple"; - materials[323] = "minecraft:sign"; - materials[324] = "minecraft:wooden_door"; - materials[325] = "minecraft:bucket"; - materials[326] = "minecraft:water_bucket"; - materials[327] = "minecraft:lava_bucket"; - materials[328] = "minecraft:minecart"; - materials[329] = "minecraft:saddle"; - materials[330] = "minecraft:iron_door"; - materials[331] = "minecraft:redstone"; - materials[332] = "minecraft:snowball"; - materials[333] = "minecraft:boat"; - materials[334] = "minecraft:leather"; - materials[335] = "minecraft:milk_bucket"; - materials[336] = "minecraft:brick"; - materials[337] = "minecraft:clay_ball"; - materials[338] = "minecraft:reeds"; - materials[339] = "minecraft:paper"; - materials[340] = "minecraft:book"; - materials[341] = "minecraft:slime_ball"; - materials[342] = "minecraft:chest_minecart"; - materials[343] = "minecraft:furnace_minecart"; - materials[344] = "minecraft:egg"; - materials[345] = "minecraft:compass"; - materials[346] = "minecraft:fishing_rod"; - materials[347] = "minecraft:clock"; - materials[348] = "minecraft:glowstone_dust"; - materials[349] = "minecraft:fish"; - materials[350] = "minecraft:cooked_fish"; // Paper - cooked_fished -> cooked_fish - materials[351] = "minecraft:dye"; - materials[352] = "minecraft:bone"; - materials[353] = "minecraft:sugar"; - materials[354] = "minecraft:cake"; - materials[355] = "minecraft:bed"; - materials[356] = "minecraft:repeater"; - materials[357] = "minecraft:cookie"; - materials[358] = "minecraft:filled_map"; - materials[359] = "minecraft:shears"; - materials[360] = "minecraft:melon"; - materials[361] = "minecraft:pumpkin_seeds"; - materials[362] = "minecraft:melon_seeds"; - materials[363] = "minecraft:beef"; - materials[364] = "minecraft:cooked_beef"; - materials[365] = "minecraft:chicken"; - materials[366] = "minecraft:cooked_chicken"; - materials[367] = "minecraft:rotten_flesh"; - materials[368] = "minecraft:ender_pearl"; - materials[369] = "minecraft:blaze_rod"; - materials[370] = "minecraft:ghast_tear"; - materials[371] = "minecraft:gold_nugget"; - materials[372] = "minecraft:nether_wart"; - materials[373] = "minecraft:potion"; - materials[374] = "minecraft:glass_bottle"; - materials[375] = "minecraft:spider_eye"; - materials[376] = "minecraft:fermented_spider_eye"; - materials[377] = "minecraft:blaze_powder"; - materials[378] = "minecraft:magma_cream"; - materials[379] = "minecraft:brewing_stand"; - materials[380] = "minecraft:cauldron"; - materials[381] = "minecraft:ender_eye"; - materials[382] = "minecraft:speckled_melon"; - materials[383] = "minecraft:spawn_egg"; - materials[384] = "minecraft:experience_bottle"; - materials[385] = "minecraft:fire_charge"; - materials[386] = "minecraft:writable_book"; - materials[387] = "minecraft:written_book"; - materials[388] = "minecraft:emerald"; - materials[389] = "minecraft:item_frame"; - materials[390] = "minecraft:flower_pot"; - materials[391] = "minecraft:carrot"; - materials[392] = "minecraft:potato"; - materials[393] = "minecraft:baked_potato"; - materials[394] = "minecraft:poisonous_potato"; - materials[395] = "minecraft:map"; - materials[396] = "minecraft:golden_carrot"; - materials[397] = "minecraft:skull"; - materials[398] = "minecraft:carrot_on_a_stick"; - materials[399] = "minecraft:nether_star"; - materials[400] = "minecraft:pumpkin_pie"; - materials[401] = "minecraft:fireworks"; - materials[402] = "minecraft:firework_charge"; - materials[403] = "minecraft:enchanted_book"; - materials[404] = "minecraft:comparator"; - materials[405] = "minecraft:netherbrick"; - materials[406] = "minecraft:quartz"; - materials[407] = "minecraft:tnt_minecart"; - materials[408] = "minecraft:hopper_minecart"; - materials[417] = "minecraft:iron_horse_armor"; - materials[418] = "minecraft:golden_horse_armor"; - materials[419] = "minecraft:diamond_horse_armor"; - materials[420] = "minecraft:lead"; - materials[421] = "minecraft:name_tag"; - materials[422] = "minecraft:command_block_minecart"; - materials[2256] = "minecraft:record_13"; - materials[2257] = "minecraft:record_cat"; - materials[2258] = "minecraft:record_blocks"; - materials[2259] = "minecraft:record_chirp"; - materials[2260] = "minecraft:record_far"; - materials[2261] = "minecraft:record_mall"; - materials[2262] = "minecraft:record_mellohi"; - materials[2263] = "minecraft:record_stal"; - materials[2264] = "minecraft:record_strad"; - materials[2265] = "minecraft:record_ward"; - materials[2266] = "minecraft:record_11"; - materials[2267] = "minecraft:record_wait"; - // Paper start - materials[409] = "minecraft:prismarine_shard"; - materials[410] = "minecraft:prismarine_crystals"; - materials[411] = "minecraft:rabbit"; - materials[412] = "minecraft:cooked_rabbit"; - materials[413] = "minecraft:rabbit_stew"; - materials[414] = "minecraft:rabbit_foot"; - materials[415] = "minecraft:rabbit_hide"; - materials[416] = "minecraft:armor_stand"; - materials[423] = "minecraft:mutton"; - materials[424] = "minecraft:cooked_mutton"; - materials[425] = "minecraft:banner"; - materials[426] = "minecraft:end_crystal"; - materials[427] = "minecraft:spruce_door"; - materials[428] = "minecraft:birch_door"; - materials[429] = "minecraft:jungle_door"; - materials[430] = "minecraft:acacia_door"; - materials[431] = "minecraft:dark_oak_door"; - materials[432] = "minecraft:chorus_fruit"; - materials[433] = "minecraft:chorus_fruit_popped"; - materials[434] = "minecraft:beetroot"; - materials[435] = "minecraft:beetroot_seeds"; - materials[436] = "minecraft:beetroot_soup"; - materials[437] = "minecraft:dragon_breath"; - materials[438] = "minecraft:splash_potion"; - materials[439] = "minecraft:spectral_arrow"; - materials[440] = "minecraft:tipped_arrow"; - materials[441] = "minecraft:lingering_potion"; - materials[442] = "minecraft:shield"; - materials[443] = "minecraft:elytra"; - materials[444] = "minecraft:spruce_boat"; - materials[445] = "minecraft:birch_boat"; - materials[446] = "minecraft:jungle_boat"; - materials[447] = "minecraft:acacia_boat"; - materials[448] = "minecraft:dark_oak_boat"; - materials[449] = "minecraft:totem_of_undying"; - materials[450] = "minecraft:shulker_shell"; - materials[452] = "minecraft:iron_nugget"; - materials[453] = "minecraft:knowledge_book"; - // Paper end - } - } - - private static class DataConverterArmorStand implements DataConverter { - - DataConverterArmorStand() { - } - - public int getDataVersion() { - return 147; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("ArmorStand".equals(cmp.getString("id")) && cmp.getBoolean("Silent") && !cmp.getBoolean("Marker")) { - cmp.remove("Silent"); - } - - return cmp; - } - } - - private static class DataConverterBanner implements DataConverter { - - DataConverterBanner() { - } - - public int getDataVersion() { - return 804; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:banner".equals(cmp.getString("id")) && cmp.contains("tag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("BlockEntityTag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag"); - - if (nbttagcompound2.contains("Base", 99)) { - cmp.putShort("Damage", (short) (nbttagcompound2.getShort("Base") & 15)); - if (nbttagcompound1.contains("display", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound3 = nbttagcompound1.getCompound("display"); - - if (nbttagcompound3.contains("Lore", 9)) { - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound3.getList("Lore", 8); - - if (nbttaglist.size() == 1 && "(+NBT)".equals(nbttaglist.getString(0))) { - return cmp; - } - } - } - - nbttagcompound2.remove("Base"); - if (nbttagcompound2.isEmpty()) { - nbttagcompound1.remove("BlockEntityTag"); - } - - if (nbttagcompound1.isEmpty()) { - cmp.remove("tag"); - } - } - } - } - - return cmp; - } - } - - private static class DataConverterPotionId implements DataConverter { - - private static final String[] potions = new String[128]; - - DataConverterPotionId() { - } - - public int getDataVersion() { - return 102; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:potion".equals(cmp.getString("id"))) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - short short0 = cmp.getShort("Damage"); - - if (!nbttagcompound1.contains("Potion", 8)) { - String s = DataConverterPotionId.potions[short0 & 127]; - - nbttagcompound1.putString("Potion", s == null ? "minecraft:water" : s); - cmp.put("tag", nbttagcompound1); - if ((short0 & 16384) == 16384) { - cmp.putString("id", "minecraft:splash_potion"); - } - } - - if (short0 != 0) { - cmp.putShort("Damage", (short) 0); - } - } - - return cmp; - } - - static { - DataConverterPotionId.potions[0] = "minecraft:water"; - DataConverterPotionId.potions[1] = "minecraft:regeneration"; - DataConverterPotionId.potions[2] = "minecraft:swiftness"; - DataConverterPotionId.potions[3] = "minecraft:fire_resistance"; - DataConverterPotionId.potions[4] = "minecraft:poison"; - DataConverterPotionId.potions[5] = "minecraft:healing"; - DataConverterPotionId.potions[6] = "minecraft:night_vision"; - DataConverterPotionId.potions[7] = null; - DataConverterPotionId.potions[8] = "minecraft:weakness"; - DataConverterPotionId.potions[9] = "minecraft:strength"; - DataConverterPotionId.potions[10] = "minecraft:slowness"; - DataConverterPotionId.potions[11] = "minecraft:leaping"; - DataConverterPotionId.potions[12] = "minecraft:harming"; - DataConverterPotionId.potions[13] = "minecraft:water_breathing"; - DataConverterPotionId.potions[14] = "minecraft:invisibility"; - DataConverterPotionId.potions[15] = null; - DataConverterPotionId.potions[16] = "minecraft:awkward"; - DataConverterPotionId.potions[17] = "minecraft:regeneration"; - DataConverterPotionId.potions[18] = "minecraft:swiftness"; - DataConverterPotionId.potions[19] = "minecraft:fire_resistance"; - DataConverterPotionId.potions[20] = "minecraft:poison"; - DataConverterPotionId.potions[21] = "minecraft:healing"; - DataConverterPotionId.potions[22] = "minecraft:night_vision"; - DataConverterPotionId.potions[23] = null; - DataConverterPotionId.potions[24] = "minecraft:weakness"; - DataConverterPotionId.potions[25] = "minecraft:strength"; - DataConverterPotionId.potions[26] = "minecraft:slowness"; - DataConverterPotionId.potions[27] = "minecraft:leaping"; - DataConverterPotionId.potions[28] = "minecraft:harming"; - DataConverterPotionId.potions[29] = "minecraft:water_breathing"; - DataConverterPotionId.potions[30] = "minecraft:invisibility"; - DataConverterPotionId.potions[31] = null; - DataConverterPotionId.potions[32] = "minecraft:thick"; - DataConverterPotionId.potions[33] = "minecraft:strong_regeneration"; - DataConverterPotionId.potions[34] = "minecraft:strong_swiftness"; - DataConverterPotionId.potions[35] = "minecraft:fire_resistance"; - DataConverterPotionId.potions[36] = "minecraft:strong_poison"; - DataConverterPotionId.potions[37] = "minecraft:strong_healing"; - DataConverterPotionId.potions[38] = "minecraft:night_vision"; - DataConverterPotionId.potions[39] = null; - DataConverterPotionId.potions[40] = "minecraft:weakness"; - DataConverterPotionId.potions[41] = "minecraft:strong_strength"; - DataConverterPotionId.potions[42] = "minecraft:slowness"; - DataConverterPotionId.potions[43] = "minecraft:strong_leaping"; - DataConverterPotionId.potions[44] = "minecraft:strong_harming"; - DataConverterPotionId.potions[45] = "minecraft:water_breathing"; - DataConverterPotionId.potions[46] = "minecraft:invisibility"; - DataConverterPotionId.potions[47] = null; - DataConverterPotionId.potions[48] = null; - DataConverterPotionId.potions[49] = "minecraft:strong_regeneration"; - DataConverterPotionId.potions[50] = "minecraft:strong_swiftness"; - DataConverterPotionId.potions[51] = "minecraft:fire_resistance"; - DataConverterPotionId.potions[52] = "minecraft:strong_poison"; - DataConverterPotionId.potions[53] = "minecraft:strong_healing"; - DataConverterPotionId.potions[54] = "minecraft:night_vision"; - DataConverterPotionId.potions[55] = null; - DataConverterPotionId.potions[56] = "minecraft:weakness"; - DataConverterPotionId.potions[57] = "minecraft:strong_strength"; - DataConverterPotionId.potions[58] = "minecraft:slowness"; - DataConverterPotionId.potions[59] = "minecraft:strong_leaping"; - DataConverterPotionId.potions[60] = "minecraft:strong_harming"; - DataConverterPotionId.potions[61] = "minecraft:water_breathing"; - DataConverterPotionId.potions[62] = "minecraft:invisibility"; - DataConverterPotionId.potions[63] = null; - DataConverterPotionId.potions[64] = "minecraft:mundane"; - DataConverterPotionId.potions[65] = "minecraft:long_regeneration"; - DataConverterPotionId.potions[66] = "minecraft:long_swiftness"; - DataConverterPotionId.potions[67] = "minecraft:long_fire_resistance"; - DataConverterPotionId.potions[68] = "minecraft:long_poison"; - DataConverterPotionId.potions[69] = "minecraft:healing"; - DataConverterPotionId.potions[70] = "minecraft:long_night_vision"; - DataConverterPotionId.potions[71] = null; - DataConverterPotionId.potions[72] = "minecraft:long_weakness"; - DataConverterPotionId.potions[73] = "minecraft:long_strength"; - DataConverterPotionId.potions[74] = "minecraft:long_slowness"; - DataConverterPotionId.potions[75] = "minecraft:long_leaping"; - DataConverterPotionId.potions[76] = "minecraft:harming"; - DataConverterPotionId.potions[77] = "minecraft:long_water_breathing"; - DataConverterPotionId.potions[78] = "minecraft:long_invisibility"; - DataConverterPotionId.potions[79] = null; - DataConverterPotionId.potions[80] = "minecraft:awkward"; - DataConverterPotionId.potions[81] = "minecraft:long_regeneration"; - DataConverterPotionId.potions[82] = "minecraft:long_swiftness"; - DataConverterPotionId.potions[83] = "minecraft:long_fire_resistance"; - DataConverterPotionId.potions[84] = "minecraft:long_poison"; - DataConverterPotionId.potions[85] = "minecraft:healing"; - DataConverterPotionId.potions[86] = "minecraft:long_night_vision"; - DataConverterPotionId.potions[87] = null; - DataConverterPotionId.potions[88] = "minecraft:long_weakness"; - DataConverterPotionId.potions[89] = "minecraft:long_strength"; - DataConverterPotionId.potions[90] = "minecraft:long_slowness"; - DataConverterPotionId.potions[91] = "minecraft:long_leaping"; - DataConverterPotionId.potions[92] = "minecraft:harming"; - DataConverterPotionId.potions[93] = "minecraft:long_water_breathing"; - DataConverterPotionId.potions[94] = "minecraft:long_invisibility"; - DataConverterPotionId.potions[95] = null; - DataConverterPotionId.potions[96] = "minecraft:thick"; - DataConverterPotionId.potions[97] = "minecraft:regeneration"; - DataConverterPotionId.potions[98] = "minecraft:swiftness"; - DataConverterPotionId.potions[99] = "minecraft:long_fire_resistance"; - DataConverterPotionId.potions[100] = "minecraft:poison"; - DataConverterPotionId.potions[101] = "minecraft:strong_healing"; - DataConverterPotionId.potions[102] = "minecraft:long_night_vision"; - DataConverterPotionId.potions[103] = null; - DataConverterPotionId.potions[104] = "minecraft:long_weakness"; - DataConverterPotionId.potions[105] = "minecraft:strength"; - DataConverterPotionId.potions[106] = "minecraft:long_slowness"; - DataConverterPotionId.potions[107] = "minecraft:leaping"; - DataConverterPotionId.potions[108] = "minecraft:strong_harming"; - DataConverterPotionId.potions[109] = "minecraft:long_water_breathing"; - DataConverterPotionId.potions[110] = "minecraft:long_invisibility"; - DataConverterPotionId.potions[111] = null; - DataConverterPotionId.potions[112] = null; - DataConverterPotionId.potions[113] = "minecraft:regeneration"; - DataConverterPotionId.potions[114] = "minecraft:swiftness"; - DataConverterPotionId.potions[115] = "minecraft:long_fire_resistance"; - DataConverterPotionId.potions[116] = "minecraft:poison"; - DataConverterPotionId.potions[117] = "minecraft:strong_healing"; - DataConverterPotionId.potions[118] = "minecraft:long_night_vision"; - DataConverterPotionId.potions[119] = null; - DataConverterPotionId.potions[120] = "minecraft:long_weakness"; - DataConverterPotionId.potions[121] = "minecraft:strength"; - DataConverterPotionId.potions[122] = "minecraft:long_slowness"; - DataConverterPotionId.potions[123] = "minecraft:leaping"; - DataConverterPotionId.potions[124] = "minecraft:strong_harming"; - DataConverterPotionId.potions[125] = "minecraft:long_water_breathing"; - DataConverterPotionId.potions[126] = "minecraft:long_invisibility"; - DataConverterPotionId.potions[127] = null; - } - } - - private static class DataConverterSpawnEgg implements DataConverter { - - private static final String[] eggs = new String[256]; - - DataConverterSpawnEgg() { - } - - public int getDataVersion() { - return 105; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:spawn_egg".equals(cmp.getString("id"))) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("EntityTag"); - short short0 = cmp.getShort("Damage"); - - if (!nbttagcompound2.contains("id", 8)) { - String s = DataConverterSpawnEgg.eggs[short0 & 255]; - - if (s != null) { - nbttagcompound2.putString("id", s); - nbttagcompound1.put("EntityTag", nbttagcompound2); - cmp.put("tag", nbttagcompound1); - } - } - - if (short0 != 0) { - cmp.putShort("Damage", (short) 0); - } - } - - return cmp; - } - - static { - - DataConverterSpawnEgg.eggs[1] = "Item"; - DataConverterSpawnEgg.eggs[2] = "XPOrb"; - DataConverterSpawnEgg.eggs[7] = "ThrownEgg"; - DataConverterSpawnEgg.eggs[8] = "LeashKnot"; - DataConverterSpawnEgg.eggs[9] = "Painting"; - DataConverterSpawnEgg.eggs[10] = "Arrow"; - DataConverterSpawnEgg.eggs[11] = "Snowball"; - DataConverterSpawnEgg.eggs[12] = "Fireball"; - DataConverterSpawnEgg.eggs[13] = "SmallFireball"; - DataConverterSpawnEgg.eggs[14] = "ThrownEnderpearl"; - DataConverterSpawnEgg.eggs[15] = "EyeOfEnderSignal"; - DataConverterSpawnEgg.eggs[16] = "ThrownPotion"; - DataConverterSpawnEgg.eggs[17] = "ThrownExpBottle"; - DataConverterSpawnEgg.eggs[18] = "ItemFrame"; - DataConverterSpawnEgg.eggs[19] = "WitherSkull"; - DataConverterSpawnEgg.eggs[20] = "PrimedTnt"; - DataConverterSpawnEgg.eggs[21] = "FallingSand"; - DataConverterSpawnEgg.eggs[22] = "FireworksRocketEntity"; - DataConverterSpawnEgg.eggs[23] = "TippedArrow"; - DataConverterSpawnEgg.eggs[24] = "SpectralArrow"; - DataConverterSpawnEgg.eggs[25] = "ShulkerBullet"; - DataConverterSpawnEgg.eggs[26] = "DragonFireball"; - DataConverterSpawnEgg.eggs[30] = "ArmorStand"; - DataConverterSpawnEgg.eggs[41] = "Boat"; - DataConverterSpawnEgg.eggs[42] = "MinecartRideable"; - DataConverterSpawnEgg.eggs[43] = "MinecartChest"; - DataConverterSpawnEgg.eggs[44] = "MinecartFurnace"; - DataConverterSpawnEgg.eggs[45] = "MinecartTNT"; - DataConverterSpawnEgg.eggs[46] = "MinecartHopper"; - DataConverterSpawnEgg.eggs[47] = "MinecartSpawner"; - DataConverterSpawnEgg.eggs[40] = "MinecartCommandBlock"; - DataConverterSpawnEgg.eggs[48] = "Mob"; - DataConverterSpawnEgg.eggs[49] = "Monster"; - DataConverterSpawnEgg.eggs[50] = "Creeper"; - DataConverterSpawnEgg.eggs[51] = "Skeleton"; - DataConverterSpawnEgg.eggs[52] = "Spider"; - DataConverterSpawnEgg.eggs[53] = "Giant"; - DataConverterSpawnEgg.eggs[54] = "Zombie"; - DataConverterSpawnEgg.eggs[55] = "Slime"; - DataConverterSpawnEgg.eggs[56] = "Ghast"; - DataConverterSpawnEgg.eggs[57] = "PigZombie"; - DataConverterSpawnEgg.eggs[58] = "Enderman"; - DataConverterSpawnEgg.eggs[59] = "CaveSpider"; - DataConverterSpawnEgg.eggs[60] = "Silverfish"; - DataConverterSpawnEgg.eggs[61] = "Blaze"; - DataConverterSpawnEgg.eggs[62] = "LavaSlime"; - DataConverterSpawnEgg.eggs[63] = "EnderDragon"; - DataConverterSpawnEgg.eggs[64] = "WitherBoss"; - DataConverterSpawnEgg.eggs[65] = "Bat"; - DataConverterSpawnEgg.eggs[66] = "Witch"; - DataConverterSpawnEgg.eggs[67] = "Endermite"; - DataConverterSpawnEgg.eggs[68] = "Guardian"; - DataConverterSpawnEgg.eggs[69] = "Shulker"; - DataConverterSpawnEgg.eggs[90] = "Pig"; - DataConverterSpawnEgg.eggs[91] = "Sheep"; - DataConverterSpawnEgg.eggs[92] = "Cow"; - DataConverterSpawnEgg.eggs[93] = "Chicken"; - DataConverterSpawnEgg.eggs[94] = "Squid"; - DataConverterSpawnEgg.eggs[95] = "Wolf"; - DataConverterSpawnEgg.eggs[96] = "MushroomCow"; - DataConverterSpawnEgg.eggs[97] = "SnowMan"; - DataConverterSpawnEgg.eggs[98] = "Ozelot"; - DataConverterSpawnEgg.eggs[99] = "VillagerGolem"; - DataConverterSpawnEgg.eggs[100] = "EntityHorse"; - DataConverterSpawnEgg.eggs[101] = "Rabbit"; - DataConverterSpawnEgg.eggs[120] = "Villager"; - DataConverterSpawnEgg.eggs[200] = "EnderCrystal"; - } - } - - private static class DataConverterMinecart implements DataConverter { - - private static final List a = Lists.newArrayList("MinecartRideable", "MinecartChest", "MinecartFurnace", "MinecartTNT", "MinecartSpawner", "MinecartHopper", "MinecartCommandBlock"); - - DataConverterMinecart() { - } - - public int getDataVersion() { - return 106; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Minecart".equals(cmp.getString("id"))) { - String s = "MinecartRideable"; - int i = cmp.getInt("Type"); - - if (i > 0 && i < DataConverterMinecart.a.size()) { - s = DataConverterMinecart.a.get(i); - } - - cmp.putString("id", s); - cmp.remove("Type"); - } - - return cmp; - } - } - - private static class DataConverterMobSpawner implements DataConverter { - - DataConverterMobSpawner() { - } - - public int getDataVersion() { - return 107; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (!"MobSpawner".equals(cmp.getString("id"))) { - return cmp; - } else { - if (cmp.contains("EntityId", 8)) { - String s = cmp.getString("EntityId"); - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("SpawnData"); - - nbttagcompound1.putString("id", s.isEmpty() ? "Pig" : s); - cmp.put("SpawnData", nbttagcompound1); - cmp.remove("EntityId"); - } - - if (cmp.contains("SpawnPotentials", 9)) { - net.minecraft.nbt.ListTag nbttaglist = cmp.getList("SpawnPotentials", 10); - - for (int i = 0; i < nbttaglist.size(); ++i) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttaglist.getCompound(i); - - if (nbttagcompound2.contains("Type", 8)) { - net.minecraft.nbt.CompoundTag nbttagcompound3 = nbttagcompound2.getCompound("Properties"); - - nbttagcompound3.putString("id", nbttagcompound2.getString("Type")); - nbttagcompound2.put("Entity", nbttagcompound3); - nbttagcompound2.remove("Type"); - nbttagcompound2.remove("Properties"); - } - } - } - - return cmp; - } - } - } - - private static class DataConverterUUID implements DataConverter { - - DataConverterUUID() { - } - - public int getDataVersion() { - return 108; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (cmp.contains("UUID", 8)) { - cmp.putUUID("UUID", UUID.fromString(cmp.getString("UUID"))); - } - - return cmp; - } - } - - private static class DataConverterHealth implements DataConverter { - - private static final Set a = Sets.newHashSet("ArmorStand", "Bat", "Blaze", "CaveSpider", "Chicken", "Cow", "Creeper", "EnderDragon", "Enderman", "Endermite", "EntityHorse", "Ghast", "Giant", "Guardian", "LavaSlime", "MushroomCow", "Ozelot", "Pig", "PigZombie", "Rabbit", "Sheep", "Shulker", "Silverfish", "Skeleton", "Slime", "SnowMan", "Spider", "Squid", "Villager", "VillagerGolem", "Witch", "WitherBoss", "Wolf", "Zombie"); - - DataConverterHealth() { - } - - public int getDataVersion() { - return 109; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (DataConverterHealth.a.contains(cmp.getString("id"))) { - float f; - - if (cmp.contains("HealF", 99)) { - f = cmp.getFloat("HealF"); - cmp.remove("HealF"); - } else { - if (!cmp.contains("Health", 99)) { - return cmp; - } - - f = cmp.getFloat("Health"); - } - - cmp.putFloat("Health", f); - } - - return cmp; - } - } - - private static class DataConverterSaddle implements DataConverter { - - DataConverterSaddle() { - } - - public int getDataVersion() { - return 110; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("EntityHorse".equals(cmp.getString("id")) && !cmp.contains("SaddleItem", 10) && cmp.getBoolean("Saddle")) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = new net.minecraft.nbt.CompoundTag(); - - nbttagcompound1.putString("id", "minecraft:saddle"); - nbttagcompound1.putByte("Count", (byte) 1); - nbttagcompound1.putShort("Damage", (short) 0); - cmp.put("SaddleItem", nbttagcompound1); - cmp.remove("Saddle"); - } - - return cmp; - } - } - - private static class DataConverterHanging implements DataConverter { - - DataConverterHanging() { - } - - public int getDataVersion() { - return 111; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = cmp.getString("id"); - boolean flag = "Painting".equals(s); - boolean flag1 = "ItemFrame".equals(s); - - if ((flag || flag1) && !cmp.contains("Facing", 99)) { - Direction enumdirection; - - if (cmp.contains("Direction", 99)) { - enumdirection = Direction.from2DDataValue(cmp.getByte("Direction")); - cmp.putInt("TileX", cmp.getInt("TileX") + enumdirection.getStepX()); - cmp.putInt("TileY", cmp.getInt("TileY") + enumdirection.getStepY()); - cmp.putInt("TileZ", cmp.getInt("TileZ") + enumdirection.getStepZ()); - cmp.remove("Direction"); - if (flag1 && cmp.contains("ItemRotation", 99)) { - cmp.putByte("ItemRotation", (byte) (cmp.getByte("ItemRotation") * 2)); - } - } else { - enumdirection = Direction.from2DDataValue(cmp.getByte("Dir")); - cmp.remove("Dir"); - } - - cmp.putByte("Facing", (byte) enumdirection.get2DDataValue()); - } - - return cmp; - } - } - - private static class DataConverterDropChances implements DataConverter { - - DataConverterDropChances() { - } - - public int getDataVersion() { - return 113; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - net.minecraft.nbt.ListTag nbttaglist; - - if (cmp.contains("HandDropChances", 9)) { - nbttaglist = cmp.getList("HandDropChances", 5); - if (nbttaglist.size() == 2 && nbttaglist.getFloat(0) == 0.0F && nbttaglist.getFloat(1) == 0.0F) { - cmp.remove("HandDropChances"); - } - } - - if (cmp.contains("ArmorDropChances", 9)) { - nbttaglist = cmp.getList("ArmorDropChances", 5); - if (nbttaglist.size() == 4 && nbttaglist.getFloat(0) == 0.0F && nbttaglist.getFloat(1) == 0.0F && nbttaglist.getFloat(2) == 0.0F && nbttaglist.getFloat(3) == 0.0F) { - cmp.remove("ArmorDropChances"); - } - } - - return cmp; - } - } - - private static class DataConverterRiding implements DataConverter { - - DataConverterRiding() { - } - - public int getDataVersion() { - return 135; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - while (cmp.contains("Riding", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = this.b(cmp); - - this.convert(cmp, nbttagcompound1); - cmp = nbttagcompound1; - } - - return cmp; - } - - protected void convert(net.minecraft.nbt.CompoundTag nbttagcompound, net.minecraft.nbt.CompoundTag nbttagcompound1) { - net.minecraft.nbt.ListTag nbttaglist = new net.minecraft.nbt.ListTag(); - - nbttaglist.add(nbttagcompound); - nbttagcompound1.put("Passengers", nbttaglist); - } - - protected net.minecraft.nbt.CompoundTag b(net.minecraft.nbt.CompoundTag nbttagcompound) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = nbttagcompound.getCompound("Riding"); - - nbttagcompound.remove("Riding"); - return nbttagcompound1; - } - } - - private static class DataConverterBook implements DataConverter { - - DataConverterBook() { - } - - public int getDataVersion() { - return 165; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:written_book".equals(cmp.getString("id"))) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("pages", 9)) { - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound1.getList("pages", 8); - - for (int i = 0; i < nbttaglist.size(); ++i) { - String s = nbttaglist.getString(i); - Component object = null; - - if (!"null".equals(s) && !StringUtil.isNullOrEmpty(s)) { - if ((s.charAt(0) != 34 || s.charAt(s.length() - 1) != 34) && (s.charAt(0) != 123 || s.charAt(s.length() - 1) != 125)) { - object = Component.literal(s); - } else { - try { - object = GsonHelper.fromJson(DataConverterSignText.a, s, Component.class, true); - if (object == null) { - object = Component.literal(""); - } - } catch (JsonParseException jsonparseexception) { - ; - } - - if (object == null) { - try { - object = Component.Serializer.fromJson(s); - } catch (JsonParseException jsonparseexception1) { - ; - } - } - - if (object == null) { - try { - object = Component.Serializer.fromJsonLenient(s); - } catch (JsonParseException jsonparseexception2) { - ; - } - } - - if (object == null) { - object = Component.literal(s); - } - } - } else { - object = Component.literal(""); - } - - nbttaglist.set(i, net.minecraft.nbt.StringTag.valueOf(Component.Serializer.toJson(object))); - } - - nbttagcompound1.put("pages", nbttaglist); - } - } - - return cmp; - } - } - - private static class DataConverterCookedFish implements DataConverter { - - private static final ResourceLocation a = new ResourceLocation("cooked_fished"); - - DataConverterCookedFish() { - } - - public int getDataVersion() { - return 502; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (cmp.contains("id", 8) && DataConverterCookedFish.a.equals(new ResourceLocation(cmp.getString("id")))) { - cmp.putString("id", "minecraft:cooked_fish"); - } - - return cmp; - } - } - - private static class DataConverterZombie implements DataConverter { - - private static final Random a = new Random(); - - DataConverterZombie() { - } - - public int getDataVersion() { - return 502; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Zombie".equals(cmp.getString("id")) && cmp.getBoolean("IsVillager")) { - if (!cmp.contains("ZombieType", 99)) { - int i = -1; - - if (cmp.contains("VillagerProfession", 99)) { - try { - i = this.convert(cmp.getInt("VillagerProfession")); - } catch (RuntimeException runtimeexception) { - ; - } - } - - if (i == -1) { - i = this.convert(DataConverterZombie.a.nextInt(6)); - } - - cmp.putInt("ZombieType", i); - } - - cmp.remove("IsVillager"); - } - - return cmp; - } - - private int convert(int i) { - return i >= 0 && i < 6 ? i : -1; - } - } - - private static class DataConverterVBO implements DataConverter { - - DataConverterVBO() { - } - - public int getDataVersion() { - return 505; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - cmp.putString("useVbo", "true"); - return cmp; - } - } - - private static class DataConverterGuardian implements DataConverter { - - DataConverterGuardian() { - } - - public int getDataVersion() { - return 700; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Guardian".equals(cmp.getString("id"))) { - if (cmp.getBoolean("Elder")) { - cmp.putString("id", "ElderGuardian"); - } - - cmp.remove("Elder"); - } - - return cmp; - } - } - - private static class DataConverterSkeleton implements DataConverter { - - DataConverterSkeleton() { - } - - public int getDataVersion() { - return 701; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = cmp.getString("id"); - - if ("Skeleton".equals(s)) { - int i = cmp.getInt("SkeletonType"); - - if (i == 1) { - cmp.putString("id", "WitherSkeleton"); - } else if (i == 2) { - cmp.putString("id", "Stray"); - } - - cmp.remove("SkeletonType"); - } - - return cmp; - } - } - - private static class DataConverterZombieType implements DataConverter { - - DataConverterZombieType() { - } - - public int getDataVersion() { - return 702; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Zombie".equals(cmp.getString("id"))) { - int i = cmp.getInt("ZombieType"); - - switch (i) { - case 0: - default: - break; - - case 1: - case 2: - case 3: - case 4: - case 5: - cmp.putString("id", "ZombieVillager"); - cmp.putInt("Profession", i - 1); - break; - - case 6: - cmp.putString("id", "Husk"); - } - - cmp.remove("ZombieType"); - } - - return cmp; - } - } - - private static class DataConverterHorse implements DataConverter { - - DataConverterHorse() { - } - - public int getDataVersion() { - return 703; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("EntityHorse".equals(cmp.getString("id"))) { - int i = cmp.getInt("Type"); - - switch (i) { - case 0: - default: - cmp.putString("id", "Horse"); - break; - - case 1: - cmp.putString("id", "Donkey"); - break; - - case 2: - cmp.putString("id", "Mule"); - break; - - case 3: - cmp.putString("id", "ZombieHorse"); - break; - - case 4: - cmp.putString("id", "SkeletonHorse"); - } - - cmp.remove("Type"); - } - - return cmp; - } - } - - private static class DataConverterTileEntity implements DataConverter { - - private static final Map a = Maps.newHashMap(); - - DataConverterTileEntity() { - } - - public int getDataVersion() { - return 704; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = DataConverterTileEntity.a.get(cmp.getString("id")); - - if (s != null) { - cmp.putString("id", s); - } - - return cmp; - } - - static { - DataConverterTileEntity.a.put("Airportal", "minecraft:end_portal"); - DataConverterTileEntity.a.put("Banner", "minecraft:banner"); - DataConverterTileEntity.a.put("Beacon", "minecraft:beacon"); - DataConverterTileEntity.a.put("Cauldron", "minecraft:brewing_stand"); - DataConverterTileEntity.a.put("Chest", "minecraft:chest"); - DataConverterTileEntity.a.put("Comparator", "minecraft:comparator"); - DataConverterTileEntity.a.put("Control", "minecraft:command_block"); - DataConverterTileEntity.a.put("DLDetector", "minecraft:daylight_detector"); - DataConverterTileEntity.a.put("Dropper", "minecraft:dropper"); - DataConverterTileEntity.a.put("EnchantTable", "minecraft:enchanting_table"); - DataConverterTileEntity.a.put("EndGateway", "minecraft:end_gateway"); - DataConverterTileEntity.a.put("EnderChest", "minecraft:ender_chest"); - DataConverterTileEntity.a.put("FlowerPot", "minecraft:flower_pot"); - DataConverterTileEntity.a.put("Furnace", "minecraft:furnace"); - DataConverterTileEntity.a.put("Hopper", "minecraft:hopper"); - DataConverterTileEntity.a.put("MobSpawner", "minecraft:mob_spawner"); - DataConverterTileEntity.a.put("Music", "minecraft:noteblock"); - DataConverterTileEntity.a.put("Piston", "minecraft:piston"); - DataConverterTileEntity.a.put("RecordPlayer", "minecraft:jukebox"); - DataConverterTileEntity.a.put("Sign", "minecraft:sign"); - DataConverterTileEntity.a.put("Skull", "minecraft:skull"); - DataConverterTileEntity.a.put("Structure", "minecraft:structure_block"); - DataConverterTileEntity.a.put("Trap", "minecraft:dispenser"); - } - } - - private static class DataConverterEntity implements DataConverter { - - private static final Map a = Maps.newHashMap(); - - DataConverterEntity() { - } - - public int getDataVersion() { - return 704; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = DataConverterEntity.a.get(cmp.getString("id")); - - if (s != null) { - cmp.putString("id", s); - } - - return cmp; - } - - static { - DataConverterEntity.a.put("AreaEffectCloud", "minecraft:area_effect_cloud"); - DataConverterEntity.a.put("ArmorStand", "minecraft:armor_stand"); - DataConverterEntity.a.put("Arrow", "minecraft:arrow"); - DataConverterEntity.a.put("Bat", "minecraft:bat"); - DataConverterEntity.a.put("Blaze", "minecraft:blaze"); - DataConverterEntity.a.put("Boat", "minecraft:boat"); - DataConverterEntity.a.put("CaveSpider", "minecraft:cave_spider"); - DataConverterEntity.a.put("Chicken", "minecraft:chicken"); - DataConverterEntity.a.put("Cow", "minecraft:cow"); - DataConverterEntity.a.put("Creeper", "minecraft:creeper"); - DataConverterEntity.a.put("Donkey", "minecraft:donkey"); - DataConverterEntity.a.put("DragonFireball", "minecraft:dragon_fireball"); - DataConverterEntity.a.put("ElderGuardian", "minecraft:elder_guardian"); - DataConverterEntity.a.put("EnderCrystal", "minecraft:ender_crystal"); - DataConverterEntity.a.put("EnderDragon", "minecraft:ender_dragon"); - DataConverterEntity.a.put("Enderman", "minecraft:enderman"); - DataConverterEntity.a.put("Endermite", "minecraft:endermite"); - DataConverterEntity.a.put("EyeOfEnderSignal", "minecraft:eye_of_ender_signal"); - DataConverterEntity.a.put("FallingSand", "minecraft:falling_block"); - DataConverterEntity.a.put("Fireball", "minecraft:fireball"); - DataConverterEntity.a.put("FireworksRocketEntity", "minecraft:fireworks_rocket"); - DataConverterEntity.a.put("Ghast", "minecraft:ghast"); - DataConverterEntity.a.put("Giant", "minecraft:giant"); - DataConverterEntity.a.put("Guardian", "minecraft:guardian"); - DataConverterEntity.a.put("Horse", "minecraft:horse"); - DataConverterEntity.a.put("Husk", "minecraft:husk"); - DataConverterEntity.a.put("Item", "minecraft:item"); - DataConverterEntity.a.put("ItemFrame", "minecraft:item_frame"); - DataConverterEntity.a.put("LavaSlime", "minecraft:magma_cube"); - DataConverterEntity.a.put("LeashKnot", "minecraft:leash_knot"); - DataConverterEntity.a.put("MinecartChest", "minecraft:chest_minecart"); - DataConverterEntity.a.put("MinecartCommandBlock", "minecraft:commandblock_minecart"); - DataConverterEntity.a.put("MinecartFurnace", "minecraft:furnace_minecart"); - DataConverterEntity.a.put("MinecartHopper", "minecraft:hopper_minecart"); - DataConverterEntity.a.put("MinecartRideable", "minecraft:minecart"); - DataConverterEntity.a.put("MinecartSpawner", "minecraft:spawner_minecart"); - DataConverterEntity.a.put("MinecartTNT", "minecraft:tnt_minecart"); - DataConverterEntity.a.put("Mule", "minecraft:mule"); - DataConverterEntity.a.put("MushroomCow", "minecraft:mooshroom"); - DataConverterEntity.a.put("Ozelot", "minecraft:ocelot"); - DataConverterEntity.a.put("Painting", "minecraft:painting"); - DataConverterEntity.a.put("Pig", "minecraft:pig"); - DataConverterEntity.a.put("PigZombie", "minecraft:zombie_pigman"); - DataConverterEntity.a.put("PolarBear", "minecraft:polar_bear"); - DataConverterEntity.a.put("PrimedTnt", "minecraft:tnt"); - DataConverterEntity.a.put("Rabbit", "minecraft:rabbit"); - DataConverterEntity.a.put("Sheep", "minecraft:sheep"); - DataConverterEntity.a.put("Shulker", "minecraft:shulker"); - DataConverterEntity.a.put("ShulkerBullet", "minecraft:shulker_bullet"); - DataConverterEntity.a.put("Silverfish", "minecraft:silverfish"); - DataConverterEntity.a.put("Skeleton", "minecraft:skeleton"); - DataConverterEntity.a.put("SkeletonHorse", "minecraft:skeleton_horse"); - DataConverterEntity.a.put("Slime", "minecraft:slime"); - DataConverterEntity.a.put("SmallFireball", "minecraft:small_fireball"); - DataConverterEntity.a.put("SnowMan", "minecraft:snowman"); - DataConverterEntity.a.put("Snowball", "minecraft:snowball"); - DataConverterEntity.a.put("SpectralArrow", "minecraft:spectral_arrow"); - DataConverterEntity.a.put("Spider", "minecraft:spider"); - DataConverterEntity.a.put("Squid", "minecraft:squid"); - DataConverterEntity.a.put("Stray", "minecraft:stray"); - DataConverterEntity.a.put("ThrownEgg", "minecraft:egg"); - DataConverterEntity.a.put("ThrownEnderpearl", "minecraft:ender_pearl"); - DataConverterEntity.a.put("ThrownExpBottle", "minecraft:xp_bottle"); - DataConverterEntity.a.put("ThrownPotion", "minecraft:potion"); - DataConverterEntity.a.put("Villager", "minecraft:villager"); - DataConverterEntity.a.put("VillagerGolem", "minecraft:villager_golem"); - DataConverterEntity.a.put("Witch", "minecraft:witch"); - DataConverterEntity.a.put("WitherBoss", "minecraft:wither"); - DataConverterEntity.a.put("WitherSkeleton", "minecraft:wither_skeleton"); - DataConverterEntity.a.put("WitherSkull", "minecraft:wither_skull"); - DataConverterEntity.a.put("Wolf", "minecraft:wolf"); - DataConverterEntity.a.put("XPOrb", "minecraft:xp_orb"); - DataConverterEntity.a.put("Zombie", "minecraft:zombie"); - DataConverterEntity.a.put("ZombieHorse", "minecraft:zombie_horse"); - DataConverterEntity.a.put("ZombieVillager", "minecraft:zombie_villager"); - } - } - - private static class DataConverterPotionWater implements DataConverter { - - DataConverterPotionWater() { - } - - public int getDataVersion() { - return 806; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = cmp.getString("id"); - - if ("minecraft:potion".equals(s) || "minecraft:splash_potion".equals(s) || "minecraft:lingering_potion".equals(s) || "minecraft:tipped_arrow".equals(s)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (!nbttagcompound1.contains("Potion", 8)) { - nbttagcompound1.putString("Potion", "minecraft:water"); - } - - if (!cmp.contains("tag", 10)) { - cmp.put("tag", nbttagcompound1); - } - } - - return cmp; - } - } - - private static class DataConverterShulker implements DataConverter { - - DataConverterShulker() { - } - - public int getDataVersion() { - return 808; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:shulker".equals(cmp.getString("id")) && !cmp.contains("Color", 99)) { - cmp.putByte("Color", (byte) 10); - } - - return cmp; - } - } - - private static class DataConverterShulkerBoxItem implements DataConverter { - - public static final String[] a = new String[] { "minecraft:white_shulker_box", "minecraft:orange_shulker_box", "minecraft:magenta_shulker_box", "minecraft:light_blue_shulker_box", "minecraft:yellow_shulker_box", "minecraft:lime_shulker_box", "minecraft:pink_shulker_box", "minecraft:gray_shulker_box", "minecraft:silver_shulker_box", "minecraft:cyan_shulker_box", "minecraft:purple_shulker_box", "minecraft:blue_shulker_box", "minecraft:brown_shulker_box", "minecraft:green_shulker_box", "minecraft:red_shulker_box", "minecraft:black_shulker_box" }; - - DataConverterShulkerBoxItem() { - } - - public int getDataVersion() { - return 813; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:shulker_box".equals(cmp.getString("id")) && cmp.contains("tag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("BlockEntityTag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag"); - - if (nbttagcompound2.getList("Items", 10).isEmpty()) { - nbttagcompound2.remove("Items"); - } - - int i = nbttagcompound2.getInt("Color"); - - nbttagcompound2.remove("Color"); - if (nbttagcompound2.isEmpty()) { - nbttagcompound1.remove("BlockEntityTag"); - } - - if (nbttagcompound1.isEmpty()) { - cmp.remove("tag"); - } - - cmp.putString("id", DataConverterShulkerBoxItem.a[i % 16]); - } - } - - return cmp; - } - } - - private static class DataConverterShulkerBoxBlock implements DataConverter { - - DataConverterShulkerBoxBlock() { - } - - public int getDataVersion() { - return 813; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:shulker".equals(cmp.getString("id"))) { - cmp.remove("Color"); - } - - return cmp; - } - } - - private static class DataConverterLang implements DataConverter { - - DataConverterLang() { - } - - public int getDataVersion() { - return 816; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (cmp.contains("lang", 8)) { - cmp.putString("lang", cmp.getString("lang").toLowerCase(Locale.ROOT)); - } - - return cmp; - } - } - - private static class DataConverterTotem implements DataConverter { - - DataConverterTotem() { - } - - public int getDataVersion() { - return 820; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:totem".equals(cmp.getString("id"))) { - cmp.putString("id", "minecraft:totem_of_undying"); - } - - return cmp; - } - } - - private static class DataConverterBedBlock implements DataConverter { - - private static final Logger a = LogManager.getLogger(PaperweightDataConverters.class); - - DataConverterBedBlock() { - } - - public int getDataVersion() { - return 1125; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - try { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("Level"); - int i = nbttagcompound1.getInt("xPos"); - int j = nbttagcompound1.getInt("zPos"); - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound1.getList("TileEntities", 10); - net.minecraft.nbt.ListTag nbttaglist1 = nbttagcompound1.getList("Sections", 10); - - for (int k = 0; k < nbttaglist1.size(); ++k) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttaglist1.getCompound(k); - byte b0 = nbttagcompound2.getByte("Y"); - byte[] abyte = nbttagcompound2.getByteArray("Blocks"); - - for (int l = 0; l < abyte.length; ++l) { - if (416 == (abyte[l] & 255) << 4) { - int i1 = l & 15; - int j1 = l >> 8 & 15; - int k1 = l >> 4 & 15; - net.minecraft.nbt.CompoundTag nbttagcompound3 = new net.minecraft.nbt.CompoundTag(); - - nbttagcompound3.putString("id", "bed"); - nbttagcompound3.putInt("x", i1 + (i << 4)); - nbttagcompound3.putInt("y", j1 + (b0 << 4)); - nbttagcompound3.putInt("z", k1 + (j << 4)); - nbttaglist.add(nbttagcompound3); - } - } - } - } catch (Exception exception) { - DataConverterBedBlock.a.warn("Unable to datafix Bed blocks, level format may be missing tags."); - } - - return cmp; - } - } - - private static class DataConverterBedItem implements DataConverter { - - DataConverterBedItem() { - } - - public int getDataVersion() { - return 1125; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:bed".equals(cmp.getString("id")) && cmp.getShort("Damage") == 0) { - cmp.putShort("Damage", (short) DyeColor.RED.getId()); - } - - return cmp; - } - } - - private static class DataConverterSignText implements DataConverter { - - public static final Gson a = new GsonBuilder().registerTypeAdapter(Component.class, new JsonDeserializer() { - MutableComponent a(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { - if (jsonelement.isJsonPrimitive()) { - return Component.literal(jsonelement.getAsString()); - } else if (jsonelement.isJsonArray()) { - JsonArray jsonarray = jsonelement.getAsJsonArray(); - MutableComponent ichatbasecomponent = null; - Iterator iterator = jsonarray.iterator(); - - while (iterator.hasNext()) { - JsonElement jsonelement1 = (JsonElement) iterator.next(); - MutableComponent ichatbasecomponent1 = this.a(jsonelement1, jsonelement1.getClass(), jsondeserializationcontext); - - if (ichatbasecomponent == null) { - ichatbasecomponent = ichatbasecomponent1; - } else { - ichatbasecomponent.append(ichatbasecomponent1); - } - } - - return ichatbasecomponent; - } else { - throw new JsonParseException("Don't know how to turn " + jsonelement + " into a Component"); - } - } - - public Object deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { - return this.a(jsonelement, type, jsondeserializationcontext); - } - }).create(); - - DataConverterSignText() { - } - - public int getDataVersion() { - return 101; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Sign".equals(cmp.getString("id"))) { - this.convert(cmp, "Text1"); - this.convert(cmp, "Text2"); - this.convert(cmp, "Text3"); - this.convert(cmp, "Text4"); - } - - return cmp; - } - - private void convert(net.minecraft.nbt.CompoundTag nbttagcompound, String s) { - String s1 = nbttagcompound.getString(s); - Component object = null; - - if (!"null".equals(s1) && !StringUtil.isNullOrEmpty(s1)) { - if ((s1.charAt(0) != 34 || s1.charAt(s1.length() - 1) != 34) && (s1.charAt(0) != 123 || s1.charAt(s1.length() - 1) != 125)) { - object = Component.literal(s1); - } else { - try { - object = GsonHelper.fromJson(DataConverterSignText.a, s1, Component.class, true); - if (object == null) { - object = Component.literal(""); - } - } catch (JsonParseException jsonparseexception) { - ; - } - - if (object == null) { - try { - object = Component.Serializer.fromJson(s1); - } catch (JsonParseException jsonparseexception1) { - ; - } - } - - if (object == null) { - try { - object = Component.Serializer.fromJsonLenient(s1); - } catch (JsonParseException jsonparseexception2) { - ; - } - } - - if (object == null) { - object = Component.literal(s1); - } - } - } else { - object = Component.literal(""); - } - - nbttagcompound.putString(s, Component.Serializer.toJson(object)); - } - } - - private static class DataInspectorPlayerVehicle implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (cmp.contains("RootVehicle", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("RootVehicle"); - - if (nbttagcompound1.contains("Entity", 10)) { - convertCompound(LegacyType.ENTITY, nbttagcompound1, "Entity", sourceVer, targetVer); - } - } - - return cmp; - } - } - - private static class DataInspectorLevelPlayer implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (cmp.contains("Player", 10)) { - convertCompound(LegacyType.PLAYER, cmp, "Player", sourceVer, targetVer); - } - - return cmp; - } - } - - private static class DataInspectorStructure implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - net.minecraft.nbt.ListTag nbttaglist; - int j; - net.minecraft.nbt.CompoundTag nbttagcompound1; - - if (cmp.contains("entities", 9)) { - nbttaglist = cmp.getList("entities", 10); - - for (j = 0; j < nbttaglist.size(); ++j) { - nbttagcompound1 = (net.minecraft.nbt.CompoundTag) nbttaglist.get(j); - if (nbttagcompound1.contains("nbt", 10)) { - convertCompound(LegacyType.ENTITY, nbttagcompound1, "nbt", sourceVer, targetVer); - } - } - } - - if (cmp.contains("blocks", 9)) { - nbttaglist = cmp.getList("blocks", 10); - - for (j = 0; j < nbttaglist.size(); ++j) { - nbttagcompound1 = (net.minecraft.nbt.CompoundTag) nbttaglist.get(j); - if (nbttagcompound1.contains("nbt", 10)) { - convertCompound(LegacyType.BLOCK_ENTITY, nbttagcompound1, "nbt", sourceVer, targetVer); - } - } - } - - return cmp; - } - } - - private static class DataInspectorChunks implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (cmp.contains("Level", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("Level"); - net.minecraft.nbt.ListTag nbttaglist; - int j; - - if (nbttagcompound1.contains("Entities", 9)) { - nbttaglist = nbttagcompound1.getList("Entities", 10); - - for (j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set(j, convert(LegacyType.ENTITY, (net.minecraft.nbt.CompoundTag) nbttaglist.get(j), sourceVer, targetVer)); - } - } - - if (nbttagcompound1.contains("TileEntities", 9)) { - nbttaglist = nbttagcompound1.getList("TileEntities", 10); - - for (j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set(j, convert(LegacyType.BLOCK_ENTITY, (net.minecraft.nbt.CompoundTag) nbttaglist.get(j), sourceVer, targetVer)); - } - } - } - - return cmp; - } - } - - private static class DataInspectorEntityPassengers implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (cmp.contains("Passengers", 9)) { - net.minecraft.nbt.ListTag nbttaglist = cmp.getList("Passengers", 10); - - for (int j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set(j, convert(LegacyType.ENTITY, nbttaglist.getCompound(j), sourceVer, targetVer)); - } - } - - return cmp; - } - } - - private static class DataInspectorPlayer implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - convertItems(cmp, "Inventory", sourceVer, targetVer); - convertItems(cmp, "EnderItems", sourceVer, targetVer); - if (cmp.contains("ShoulderEntityLeft", 10)) { - convertCompound(LegacyType.ENTITY, cmp, "ShoulderEntityLeft", sourceVer, targetVer); - } - - if (cmp.contains("ShoulderEntityRight", 10)) { - convertCompound(LegacyType.ENTITY, cmp, "ShoulderEntityRight", sourceVer, targetVer); - } - - return cmp; - } - } - - private static class DataInspectorVillagers implements DataInspector { - ResourceLocation entityVillager = getKey("EntityVillager"); - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (entityVillager.equals(new ResourceLocation(cmp.getString("id"))) && cmp.contains("Offers", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("Offers"); - - if (nbttagcompound1.contains("Recipes", 9)) { - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound1.getList("Recipes", 10); - - for (int j = 0; j < nbttaglist.size(); ++j) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttaglist.getCompound(j); - - convertItem(nbttagcompound2, "buy", sourceVer, targetVer); - convertItem(nbttagcompound2, "buyB", sourceVer, targetVer); - convertItem(nbttagcompound2, "sell", sourceVer, targetVer); - nbttaglist.set(j, nbttagcompound2); - } - } - } - - return cmp; - } - } - - private static class DataInspectorMobSpawnerMinecart implements DataInspector { - ResourceLocation entityMinecartMobSpawner = getKey("EntityMinecartMobSpawner"); - ResourceLocation tileEntityMobSpawner = getKey("TileEntityMobSpawner"); - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - String s = cmp.getString("id"); - if (entityMinecartMobSpawner.equals(new ResourceLocation(s))) { - cmp.putString("id", tileEntityMobSpawner.toString()); - convert(LegacyType.BLOCK_ENTITY, cmp, sourceVer, targetVer); - cmp.putString("id", s); - } - - return cmp; - } - } - - private static class DataInspectorMobSpawnerMobs implements DataInspector { - ResourceLocation tileEntityMobSpawner = getKey("TileEntityMobSpawner"); - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (tileEntityMobSpawner.equals(new ResourceLocation(cmp.getString("id")))) { - if (cmp.contains("SpawnPotentials", 9)) { - net.minecraft.nbt.ListTag nbttaglist = cmp.getList("SpawnPotentials", 10); - - for (int j = 0; j < nbttaglist.size(); ++j) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = nbttaglist.getCompound(j); - - convertCompound(LegacyType.ENTITY, nbttagcompound1, "Entity", sourceVer, targetVer); - } - } - - convertCompound(LegacyType.ENTITY, cmp, "SpawnData", sourceVer, targetVer); - } - - return cmp; - } - } - - private static class DataInspectorCommandBlock implements DataInspector { - ResourceLocation tileEntityCommand = getKey("TileEntityCommand"); - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (tileEntityCommand.equals(new ResourceLocation(cmp.getString("id")))) { - cmp.putString("id", "Control"); - convert(LegacyType.BLOCK_ENTITY, cmp, sourceVer, targetVer); - cmp.putString("id", "MinecartCommandBlock"); - } - - return cmp; - } - } -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightFakePlayer.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightFakePlayer.java deleted file mode 100644 index 87dca94f2..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightFakePlayer.java +++ /dev/null @@ -1,93 +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.bukkit.adapter.ext.fawe.v1_20_R1; - -import com.mojang.authlib.GameProfile; -import net.minecraft.network.chat.Component; -import net.minecraft.network.protocol.game.ServerboundClientInformationPacket; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.stats.Stat; -import net.minecraft.world.MenuProvider; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.block.entity.SignBlockEntity; -import net.minecraft.world.phys.Vec3; -import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; - -import java.util.OptionalInt; -import java.util.UUID; - -class PaperweightFakePlayer extends ServerPlayer { - private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile(UUID.nameUUIDFromBytes("worldedit".getBytes()), "[WorldEdit]"); - private static final Vec3 ORIGIN = new Vec3(0.0D, 0.0D, 0.0D); - - PaperweightFakePlayer(ServerLevel world) { - super(world.getServer(), world, FAKE_WORLDEDIT_PROFILE); - } - - @Override - public Vec3 position() { - return ORIGIN; - } - - @Override - public void tick() { - } - - @Override - public void die(DamageSource damagesource) { - } - - @Override - public Entity changeDimension(ServerLevel worldserver, TeleportCause cause) { - return this; - } - - @Override - public OptionalInt openMenu(MenuProvider factory) { - return OptionalInt.empty(); - } - - @Override - public void updateOptions(ServerboundClientInformationPacket packet) { - } - - @Override - public void displayClientMessage(Component message, boolean actionBar) { - } - - @Override - public void awardStat(Stat stat, int amount) { - } - - @Override - public void awardStat(Stat stat) { - } - - @Override - public boolean isInvulnerableTo(DamageSource damageSource) { - return true; - } - - @Override - public void openTextEdit(SignBlockEntity sign, boolean front) { - } -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightWorldNativeAccess.java deleted file mode 100644 index ffca9e50d..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightWorldNativeAccess.java +++ /dev/null @@ -1,197 +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.bukkit.adapter.ext.fawe.v1_20_R1; - -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.internal.block.BlockStateIdAccess; -import com.sk89q.worldedit.internal.wna.WorldNativeAccess; -import com.sk89q.worldedit.util.SideEffect; -import com.sk89q.worldedit.util.SideEffectSet; -import com.sk89q.worldedit.world.block.BlockState; -import net.minecraft.core.BlockPos; -import net.minecraft.nbt.Tag; -import net.minecraft.server.level.FullChunkStatus; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.chunk.LevelChunk; -import org.bukkit.craftbukkit.v1_20_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_20_R1.block.data.CraftBlockData; -import org.bukkit.event.block.BlockPhysicsEvent; -import org.enginehub.linbus.tree.LinCompoundTag; - -import javax.annotation.Nullable; -import java.lang.ref.WeakReference; -import java.util.Objects; - -public class PaperweightWorldNativeAccess implements WorldNativeAccess { - private static final int UPDATE = 1; - private static final int NOTIFY = 2; - - private final PaperweightAdapter adapter; - private final WeakReference world; - private SideEffectSet sideEffectSet; - - public PaperweightWorldNativeAccess(PaperweightAdapter adapter, WeakReference world) { - this.adapter = adapter; - this.world = world; - } - - private ServerLevel getWorld() { - return Objects.requireNonNull(world.get(), "The reference to the world was lost"); - } - - @Override - public void setCurrentSideEffectSet(SideEffectSet sideEffectSet) { - this.sideEffectSet = sideEffectSet; - } - - @Override - public LevelChunk getChunk(int x, int z) { - return getWorld().getChunk(x, z); - } - - @Override - public net.minecraft.world.level.block.state.BlockState toNative(BlockState state) { - int stateId = BlockStateIdAccess.getBlockStateId(state); - return BlockStateIdAccess.isValidInternalId(stateId) - ? Block.stateById(stateId) - : ((CraftBlockData) BukkitAdapter.adapt(state)).getState(); - } - - @Override - public net.minecraft.world.level.block.state.BlockState getBlockState(LevelChunk chunk, BlockPos position) { - return chunk.getBlockState(position); - } - - @Nullable - @Override - public net.minecraft.world.level.block.state.BlockState setBlockState(LevelChunk chunk, BlockPos position, net.minecraft.world.level.block.state.BlockState state) { - return chunk.setBlockState(position, state, false, this.sideEffectSet.shouldApply(SideEffect.UPDATE)); - } - - @Override - public net.minecraft.world.level.block.state.BlockState getValidBlockForPosition(net.minecraft.world.level.block.state.BlockState block, BlockPos position) { - return Block.updateFromNeighbourShapes(block, getWorld(), position); - } - - @Override - public BlockPos getPosition(int x, int y, int z) { - return new BlockPos(x, y, z); - } - - @Override - public void updateLightingForBlock(BlockPos position) { - getWorld().getChunkSource().getLightEngine().checkBlock(position); - } - - @Override - public boolean updateTileEntity(BlockPos position, LinCompoundTag tag) { - // We will assume that the tile entity was created for us - BlockEntity tileEntity = getWorld().getBlockEntity(position); - if (tileEntity == null) { - return false; - } - Tag nativeTag = adapter.fromNative(new CompoundTag(tag)); - PaperweightAdapter.readTagIntoTileEntity((net.minecraft.nbt.CompoundTag) nativeTag, tileEntity); - return true; - } - - @Override - public void notifyBlockUpdate(LevelChunk chunk, BlockPos position, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { - if (chunk.getSections()[getWorld().getSectionIndex(position.getY())] != null) { - getWorld().sendBlockUpdated(position, oldState, newState, UPDATE | NOTIFY); - } - } - - @Override - public boolean isChunkTicking(LevelChunk chunk) { - return chunk.getFullStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING); - } - - @Override - public void markBlockChanged(LevelChunk chunk, BlockPos position) { - if (chunk.getSections()[getWorld().getSectionIndex(position.getY())] != null) { - getWorld().getChunkSource().blockChanged(position); - } - } - - @Override - public void notifyNeighbors(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { - ServerLevel world = getWorld(); - if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { - world.updateNeighborsAt(pos, oldState.getBlock()); - } else { - // When we don't want events, manually run the physics without them. - Block block = oldState.getBlock(); - fireNeighborChanged(pos, world, block, pos.west()); - fireNeighborChanged(pos, world, block, pos.east()); - fireNeighborChanged(pos, world, block, pos.below()); - fireNeighborChanged(pos, world, block, pos.above()); - fireNeighborChanged(pos, world, block, pos.north()); - fireNeighborChanged(pos, world, block, pos.south()); - } - if (newState.hasAnalogOutputSignal()) { - world.updateNeighbourForOutputSignal(pos, newState.getBlock()); - } - } - - @Override - public void updateBlock(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { - ServerLevel world = getWorld(); - newState.onPlace(world, pos, oldState, false); - } - - // Not sure why neighborChanged is deprecated - @SuppressWarnings("deprecation") - private void fireNeighborChanged(BlockPos pos, ServerLevel world, Block block, BlockPos neighborPos) { - world.getBlockState(neighborPos).neighborChanged(world, neighborPos, block, pos, false); - } - - @Override - public void updateNeighbors(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState, int recursionLimit) { - ServerLevel world = getWorld(); - // a == updateNeighbors - // b == updateDiagonalNeighbors - oldState.updateIndirectNeighbourShapes(world, pos, NOTIFY, recursionLimit); - if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { - CraftWorld craftWorld = world.getWorld(); - BlockPhysicsEvent event = new BlockPhysicsEvent(craftWorld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()), CraftBlockData.fromData(newState)); - world.getCraftServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { - return; - } - } - newState.updateNeighbourShapes(world, pos, NOTIFY, recursionLimit); - newState.updateIndirectNeighbourShapes(world, pos, NOTIFY, recursionLimit); - } - - @Override - public void onBlockStateChange(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { - getWorld().onBlockStateChange(pos, oldState, newState); - } - - @Override - public void flush() { - - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightBlockMaterial.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightBlockMaterial.java deleted file mode 100644 index 826874f57..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightBlockMaterial.java +++ /dev/null @@ -1,185 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1; - -import com.google.common.base.Suppliers; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.util.ReflectionUtil; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.world.registry.BlockMaterial; -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.EmptyBlockGetter; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.EntityBlock; -import net.minecraft.world.level.block.LiquidBlock; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.PushReaction; -import org.bukkit.craftbukkit.v1_20_R1.block.data.CraftBlockData; - -public class PaperweightBlockMaterial implements BlockMaterial { - - private final Block block; - private final BlockState blockState; - private final boolean isTranslucent; - private final CraftBlockData craftBlockData; - private final org.bukkit.Material craftMaterial; - private final int opacity; - private final CompoundTag tile; - - public PaperweightBlockMaterial(Block block) { - this(block, block.defaultBlockState()); - } - - public PaperweightBlockMaterial(Block block, BlockState blockState) { - this.block = block; - this.blockState = blockState; - this.craftBlockData = CraftBlockData.fromData(blockState); - this.craftMaterial = craftBlockData.getMaterial(); - BlockBehaviour.Properties blockInfo = ReflectionUtil.getField(BlockBehaviour.class, block, - Refraction.pickName("properties", "aN")); - this.isTranslucent = !(boolean) ReflectionUtil.getField(BlockBehaviour.Properties.class, blockInfo, - Refraction.pickName("canOcclude", "m") - ); - opacity = blockState.getLightBlock(EmptyBlockGetter.INSTANCE, BlockPos.ZERO); - BlockEntity tileEntity = !(block instanceof EntityBlock) ? null : ((EntityBlock) block).newBlockEntity( - BlockPos.ZERO, - blockState - ); - tile = tileEntity == null - ? null - : new PaperweightLazyCompoundTag(Suppliers.memoize(tileEntity::saveWithId)); - } - - public Block getBlock() { - return block; - } - - public BlockState getState() { - return blockState; - } - - public CraftBlockData getCraftBlockData() { - return craftBlockData; - } - - @Override - public boolean isAir() { - return blockState.isAir(); - } - - @Override - public boolean isFullCube() { - return craftMaterial.isOccluding(); - } - - @Override - public boolean isOpaque() { - return blockState.isOpaque(); - } - - @Override - public boolean isPowerSource() { - return blockState.isSignalSource(); - } - - @Override - public boolean isLiquid() { - // TODO: Better check ? - return block instanceof LiquidBlock; - } - - @Override - public boolean isSolid() { - // TODO: Replace - return blockState.isSolid(); - } - - @Override - public float getHardness() { - return craftBlockData.getState().destroySpeed; - } - - @Override - public float getResistance() { - return block.getExplosionResistance(); - } - - @Override - public float getSlipperiness() { - return block.getFriction(); - } - - @Override - public int getLightValue() { - return blockState.getLightEmission(); - } - - @Override - public int getLightOpacity() { - return opacity; - } - - @Override - public boolean isFragileWhenPushed() { - return blockState.getPistonPushReaction() == PushReaction.DESTROY; - } - - @Override - public boolean isUnpushable() { - return blockState.getPistonPushReaction() == PushReaction.BLOCK; - } - - @Override - public boolean isTicksRandomly() { - return block.isRandomlyTicking(blockState); - } - - @Override - public boolean isMovementBlocker() { - return craftMaterial.isSolid(); - } - - @Override - public boolean isBurnable() { - return craftMaterial.isBurnable(); - } - - @Override - public boolean isToolRequired() { - // Removed in 1.16.1, this is not present in higher versions - return false; - } - - @Override - public boolean isReplacedDuringPlacement() { - return blockState.canBeReplaced(); - } - - @Override - public boolean isTranslucent() { - return isTranslucent; - } - - @Override - public boolean hasContainer() { - return block instanceof EntityBlock; - } - - @Override - public boolean isTile() { - return block instanceof EntityBlock; - } - - @Override - public CompoundTag getDefaultTile() { - return tile; - } - - @Override - public int getMapColor() { - // rgb field - return block.defaultMapColor().col; - } - -} 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 deleted file mode 100644 index 7fd24c7d9..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java +++ /dev/null @@ -1,614 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1; - -import com.fastasyncworldedit.bukkit.adapter.FaweAdapter; -import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory; -import com.fastasyncworldedit.core.FaweCache; -import com.fastasyncworldedit.core.entity.LazyBaseEntity; -import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory; -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.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.blocks.BaseItemStack; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R1.PaperweightAdapter; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1.regen.PaperweightRegen; -import com.sk89q.worldedit.entity.BaseEntity; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.internal.block.BlockStateIdAccess; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.internal.wna.WorldNativeAccess; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.registry.state.BooleanProperty; -import com.sk89q.worldedit.registry.state.DirectionalProperty; -import com.sk89q.worldedit.registry.state.EnumProperty; -import com.sk89q.worldedit.registry.state.IntegerProperty; -import com.sk89q.worldedit.registry.state.Property; -import com.sk89q.worldedit.util.Direction; -import com.sk89q.worldedit.util.SideEffect; -import com.sk89q.worldedit.util.SideEffectSet; -import com.sk89q.worldedit.util.formatting.text.Component; -import com.sk89q.worldedit.world.RegenOptions; -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.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.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.WritableRegistry; -import net.minecraft.core.registries.Registries; -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.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.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.LevelChunk; -import org.apache.logging.log4j.Logger; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.NamespacedKey; -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.data.CraftBlockData; -import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_20_R1.util.CraftNamespacedKey; -import org.bukkit.entity.Player; -import org.enginehub.linbus.tree.LinCompoundTag; -import org.enginehub.linbus.tree.LinStringTag; -import org.enginehub.linbus.tree.LinTag; - -import javax.annotation.Nullable; -import java.lang.ref.WeakReference; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; -import java.util.OptionalInt; -import java.util.Set; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static net.minecraft.core.registries.Registries.BIOME; - -public final class PaperweightFaweAdapter extends FaweAdapter { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - private static Method CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE; - - static { - try { - CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE = ChunkHolder.class.getDeclaredMethod("wasAccessibleSinceLastSave"); - } catch (NoSuchMethodException ignored) { // may not be present in newer paper versions - } - } - - private final PaperweightAdapter parent; - // ------------------------------------------------------------------------ - // Code that may break between versions of Minecraft - // ------------------------------------------------------------------------ - private final PaperweightMapChunkUtil mapUtil = new PaperweightMapChunkUtil(); - private char[] ibdToStateOrdinal = null; - private int[] ordinalToIbdID = null; - private boolean initialised = false; - private Map>> allBlockProperties = null; - - public PaperweightFaweAdapter() throws NoSuchFieldException, NoSuchMethodException { - this.parent = new PaperweightAdapter(); - } - - @Nullable - private static String getEntityId(Entity entity) { - ResourceLocation resourceLocation = net.minecraft.world.entity.EntityType.getKey(entity.getType()); - return resourceLocation == null ? null : resourceLocation.toString(); - } - - @Override - public BukkitImplAdapter getParent() { - return parent; - } - - private synchronized boolean init() { - if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) { - return false; - } - ibdToStateOrdinal = new char[BlockTypesCache.states.length]; // size - ordinalToIbdID = new int[ibdToStateOrdinal.length]; // size - for (int i = 0; i < ibdToStateOrdinal.length; i++) { - BlockState blockState = BlockTypesCache.states[i]; - PaperweightBlockMaterial material = (PaperweightBlockMaterial) blockState.getMaterial(); - int id = Block.BLOCK_STATE_REGISTRY.getId(material.getState()); - char ordinal = blockState.getOrdinalChar(); - ibdToStateOrdinal[id] = ordinal; - ordinalToIbdID[ordinal] = id; - } - Map>> properties = new HashMap<>(); - try { - for (Field field : BlockStateProperties.class.getDeclaredFields()) { - Object obj = field.get(null); - if (!(obj instanceof net.minecraft.world.level.block.state.properties.Property state)) { - continue; - } - Property property; - if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { - property = new BooleanProperty( - state.getName(), - (List) ImmutableList.copyOf(state.getPossibleValues()) - ); - } else if (state instanceof DirectionProperty) { - property = new DirectionalProperty( - state.getName(), - state - .getPossibleValues() - .stream() - .map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase())) - .collect(Collectors.toList()) - ); - } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { - property = new EnumProperty( - state.getName(), - state - .getPossibleValues() - .stream() - .map(e -> ((StringRepresentable) e).getSerializedName()) - .collect(Collectors.toList()) - ); - } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { - property = new IntegerProperty( - state.getName(), - (List) ImmutableList.copyOf(state.getPossibleValues()) - ); - } else { - throw new IllegalArgumentException("FastAsyncWorldEdit needs an update to support " + state - .getClass() - .getSimpleName()); - } - properties.compute(property.getName().toLowerCase(Locale.ROOT), (k, v) -> { - if (v == null) { - v = new ArrayList<>(Collections.singletonList(property)); - } else { - v.add(property); - } - return v; - }); - } - } catch (IllegalAccessException e) { - e.printStackTrace(); - } finally { - allBlockProperties = ImmutableMap.copyOf(properties); - } - initialised = true; - return true; - } - - @Override - public BlockMaterial getMaterial(BlockType blockType) { - Block block = getBlock(blockType); - return new PaperweightBlockMaterial(block); - } - - @Override - public synchronized BlockMaterial getMaterial(BlockState state) { - net.minecraft.world.level.block.state.BlockState blockState = ((CraftBlockData) Bukkit.createBlockData(state.getAsString())).getState(); - return new PaperweightBlockMaterial(blockState.getBlock(), blockState); - } - - public Block getBlock(BlockType blockType) { - return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.BLOCK) - .get(new ResourceLocation(blockType.getNamespace(), blockType.getResource())); - } - - @Deprecated - @Override - public BlockState getBlock(Location location) { - Preconditions.checkNotNull(location); - - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - final ServerLevel handle = getServerLevel(location.getWorld()); - LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); - final BlockPos blockPos = new BlockPos(x, y, z); - final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos); - BlockState state = adapt(blockData); - if (state == null) { - org.bukkit.block.Block bukkitBlock = location.getBlock(); - state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); - } - return state; - } - - @Override - public BaseBlock getFullBlock(final Location location) { - Preconditions.checkNotNull(location); - - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - - final ServerLevel handle = getServerLevel(location.getWorld()); - LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); - final BlockPos blockPos = new BlockPos(x, y, z); - final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos); - BlockState state = adapt(blockData); - if (state == null) { - org.bukkit.block.Block bukkitBlock = location.getBlock(); - state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); - } - if (state.getBlockType().getMaterial().hasContainer()) { - - // Read the NBT data - BlockEntity blockEntity = chunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK); - if (blockEntity != null) { - net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(); - return state.toBaseBlock((LinCompoundTag) toNativeLin(tag)); - } - } - - return state.toBaseBlock(); - } - - @Override - public Set getSupportedSideEffects() { - return SideEffectSet.defaults().getSideEffectsToApply(); - } - - @Override - public WorldNativeAccess createWorldNativeAccess(org.bukkit.World world) { - return new PaperweightFaweWorldNativeAccess(this, new WeakReference<>(getServerLevel(world))); - } - - @Override - public BaseEntity getEntity(org.bukkit.entity.Entity entity) { - Preconditions.checkNotNull(entity); - - CraftEntity craftEntity = ((CraftEntity) entity); - Entity mcEntity = craftEntity.getHandle(); - - String id = getEntityId(mcEntity); - - if (id != null) { - EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id); - Supplier saveTag = () -> { - final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag(); - PaperweightPlatformAdapter.readEntityIntoTag(mcEntity, minecraftTag); - //add Id for AbstractChangeSet to work - final LinCompoundTag tag = (LinCompoundTag) toNativeLin(minecraftTag); - final Map> tags = NbtUtils.getLinCompoundTagValues(tag); - tags.put("Id", LinStringTag.of(id)); - return LinCompoundTag.of(tags); - }; - return new LazyBaseEntity(type, saveTag); - } else { - return null; - } - } - - @Override - public Component getRichBlockName(BlockType blockType) { - return parent.getRichBlockName(blockType); - } - - @Override - public Component getRichItemName(ItemType itemType) { - return parent.getRichItemName(itemType); - } - - @Override - public Component getRichItemName(BaseItemStack itemStack) { - return parent.getRichItemName(itemStack); - } - - @Override - public OptionalInt getInternalBlockStateId(BlockState state) { - PaperweightBlockMaterial material = (PaperweightBlockMaterial) state.getMaterial(); - net.minecraft.world.level.block.state.BlockState mcState = material.getCraftBlockData().getState(); - return OptionalInt.of(Block.BLOCK_STATE_REGISTRY.getId(mcState)); - } - - @Override - public BlockState adapt(BlockData blockData) { - CraftBlockData cbd = ((CraftBlockData) blockData); - net.minecraft.world.level.block.state.BlockState ibd = cbd.getState(); - return adapt(ibd); - } - - public BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) { - return BlockTypesCache.states[adaptToChar(blockState)]; - } - - public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockState) { - int id = Block.BLOCK_STATE_REGISTRY.getId(blockState); - if (initialised) { - return ibdToStateOrdinal[id]; - } - synchronized (this) { - if (initialised) { - return ibdToStateOrdinal[id]; - } - try { - init(); - return ibdToStateOrdinal[id]; - } catch (ArrayIndexOutOfBoundsException e1) { - LOGGER.error("Attempted to convert {} with ID {} to char. ibdToStateOrdinal length: {}. Defaulting to air!", - blockState.getBlock(), Block.BLOCK_STATE_REGISTRY.getId(blockState), ibdToStateOrdinal.length, e1 - ); - return BlockTypesCache.ReservedIDs.AIR; - } - } - } - - public char ibdIDToOrdinal(int id) { - if (initialised) { - return ibdToStateOrdinal[id]; - } - synchronized (this) { - if (initialised) { - return ibdToStateOrdinal[id]; - } - init(); - return ibdToStateOrdinal[id]; - } - } - - @Override - public char[] getIbdToStateOrdinal() { - if (initialised) { - return ibdToStateOrdinal; - } - synchronized (this) { - if (initialised) { - return ibdToStateOrdinal; - } - init(); - return ibdToStateOrdinal; - } - } - - public int ordinalToIbdID(char ordinal) { - if (initialised) { - return ordinalToIbdID[ordinal]; - } - synchronized (this) { - if (initialised) { - return ordinalToIbdID[ordinal]; - } - init(); - return ordinalToIbdID[ordinal]; - } - } - - @Override - public int[] getOrdinalToIbdID() { - if (initialised) { - return ordinalToIbdID; - } - synchronized (this) { - if (initialised) { - return ordinalToIbdID; - } - init(); - return ordinalToIbdID; - } - } - - @Override - public > BlockData adapt(B state) { - PaperweightBlockMaterial material = (PaperweightBlockMaterial) state.getMaterial(); - return material.getCraftBlockData(); - } - - @Override - public void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket chunkPacket) { - ServerLevel nmsWorld = getServerLevel(world); - ChunkHolder map = PaperweightPlatformAdapter.getPlayerChunk(nmsWorld, chunkPacket.getChunkX(), chunkPacket.getChunkZ()); - if (map != null && wasAccessibleSinceLastSave(map)) { - boolean flag = false; - // PlayerChunk.d players = map.players; - Stream stream = /*players.a(new ChunkCoordIntPair(packet.getChunkX(), packet.getChunkZ()), flag) - */ Stream.empty(); - - ServerPlayer checkPlayer = player == null ? null : ((CraftPlayer) player).getHandle(); - stream.filter(entityPlayer -> checkPlayer == null || entityPlayer == checkPlayer) - .forEach(entityPlayer -> { - synchronized (chunkPacket) { - ClientboundLevelChunkWithLightPacket nmsPacket = (ClientboundLevelChunkWithLightPacket) chunkPacket.getNativePacket(); - if (nmsPacket == null) { - nmsPacket = mapUtil.create(this, chunkPacket); - chunkPacket.setNativePacket(nmsPacket); - } - try { - FaweCache.INSTANCE.CHUNK_FLAG.get().set(true); - entityPlayer.connection.send(nmsPacket); - } finally { - FaweCache.INSTANCE.CHUNK_FLAG.get().set(false); - } - } - }); - } - } - - @Override - public Map> getProperties(BlockType blockType) { - return getParent().getProperties(blockType); - } - - @Override - public boolean canPlaceAt(org.bukkit.World world, BlockVector3 blockVector3, BlockState blockState) { - int internalId = BlockStateIdAccess.getBlockStateId(blockState); - net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(internalId); - return blockState1.hasPostProcess( - getServerLevel(world), - new BlockPos(blockVector3.x(), blockVector3.y(), blockVector3.z()) - ); - } - - @Override - public org.bukkit.inventory.ItemStack adapt(BaseItemStack baseItemStack) { - ItemStack stack = new ItemStack( - DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.ITEM) - .get(ResourceLocation.tryParse(baseItemStack.getType().id())), - baseItemStack.getAmount() - ); - stack.setTag(((net.minecraft.nbt.CompoundTag) fromNative(baseItemStack.getNbtData()))); - return CraftItemStack.asCraftMirror(stack); - } - - @Override - protected void preCaptureStates(final ServerLevel serverLevel) { - serverLevel.captureTreeGeneration = true; - serverLevel.captureBlockStates = true; - } - - @Override - protected List getCapturedBlockStatesCopy(final ServerLevel serverLevel) { - return new ArrayList<>(serverLevel.capturedBlockStates.values()); - } - - @Override - protected void postCaptureBlockStates(final ServerLevel serverLevel) { - serverLevel.captureBlockStates = false; - serverLevel.captureTreeGeneration = false; - serverLevel.capturedBlockStates.clear(); - } - - @Override - protected ServerLevel getServerLevel(final World world) { - return ((CraftWorld) world).getHandle(); - } - - @Override - public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) { - final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); - final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount()); - weStack.setNbt(((LinCompoundTag) toNativeLin(nmsStack.getTag()))); - return weStack; - } - - @Override - public Tag toNative(net.minecraft.nbt.Tag foreign) { - return parent.toNative(foreign); - } - - @Override - public net.minecraft.nbt.Tag fromNative(Tag foreign) { - if (foreign instanceof PaperweightLazyCompoundTag) { - return ((PaperweightLazyCompoundTag) foreign).get(); - } - return parent.fromNative(foreign); - } - - @Override - public boolean regenerate(org.bukkit.World bukkitWorld, Region region, Extent target, RegenOptions options) throws Exception { - return new PaperweightRegen(bukkitWorld, region, target, options).regenerate(); - } - - @Override - public IChunkGet get(org.bukkit.World world, int chunkX, int chunkZ) { - return new PaperweightGetBlocks(world, chunkX, chunkZ); - } - - @Override - public int getInternalBiomeId(BiomeType biomeType) { - final Registry registry = MinecraftServer - .getServer() - .registryAccess() - .registryOrThrow(BIOME); - ResourceLocation resourceLocation = ResourceLocation.tryParse(biomeType.id()); - Biome biome = registry.get(resourceLocation); - return registry.getId(biome); - } - - @Override - public Iterable getRegisteredBiomes() { - WritableRegistry biomeRegistry = (WritableRegistry) ((CraftServer) Bukkit.getServer()) - .getServer() - .registryAccess() - .registryOrThrow(BIOME); - List keys = biomeRegistry.stream() - .map(biomeRegistry::getKey).filter(Objects::nonNull).toList(); - List namespacedKeys = new ArrayList<>(); - for (ResourceLocation key : keys) { - try { - namespacedKeys.add(CraftNamespacedKey.fromMinecraft(key)); - } catch (IllegalArgumentException e) { - LOGGER.error("Error converting biome key {}", key.toString(), e); - } - } - return namespacedKeys; - } - - @Override - public RelighterFactory getRelighterFactory() { - if (PaperLib.isPaper()) { - return new PaperweightStarlightRelighterFactory(); - } else { - return new NMSRelighterFactory(); - } - } - - @Override - public Map>> getAllProperties() { - if (initialised) { - return allBlockProperties; - } - synchronized (this) { - if (initialised) { - return allBlockProperties; - } - init(); - return allBlockProperties; - } - } - - @Override - public IBatchProcessor getTickingPostProcessor() { - return new PaperweightPostProcessor(); - } - - private boolean wasAccessibleSinceLastSave(ChunkHolder holder) { - if (!PaperLib.isPaper() || !PaperweightPlatformAdapter.POST_CHUNK_REWRITE) { - try { - return (boolean) CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE.invoke(holder); - } catch (IllegalAccessException | InvocationTargetException ignored) { - // fall-through - } - } - // Papers new chunk system has no related replacement - therefor we assume true. - return true; - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweWorldNativeAccess.java deleted file mode 100644 index b06d962a0..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweWorldNativeAccess.java +++ /dev/null @@ -1,292 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1; - -import com.fastasyncworldedit.core.Fawe; -import com.fastasyncworldedit.core.math.IntPair; -import com.fastasyncworldedit.core.util.TaskManager; -import com.fastasyncworldedit.core.util.task.RunnableVal; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.internal.block.BlockStateIdAccess; -import com.sk89q.worldedit.internal.wna.WorldNativeAccess; -import com.sk89q.worldedit.util.SideEffect; -import com.sk89q.worldedit.util.SideEffectSet; -import com.sk89q.worldedit.world.block.BlockState; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.FullChunkStatus; -import net.minecraft.server.level.ServerChunkCache; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.chunk.LevelChunk; -import org.bukkit.craftbukkit.v1_20_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_20_R1.block.data.CraftBlockData; -import org.bukkit.event.block.BlockPhysicsEvent; -import org.enginehub.linbus.tree.LinCompoundTag; - -import javax.annotation.Nullable; -import java.lang.ref.WeakReference; -import java.util.Collections; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; - -public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess { - - private static final int UPDATE = 1; - private static final int NOTIFY = 2; - private static final Direction[] NEIGHBOUR_ORDER = { - Direction.EAST, - Direction.WEST, - Direction.DOWN, - Direction.UP, - Direction.NORTH, - Direction.SOUTH - }; - private final PaperweightFaweAdapter paperweightFaweAdapter; - private final WeakReference level; - private final AtomicInteger lastTick; - private final Set cachedChanges = new HashSet<>(); - private final Set cachedChunksToSend = new HashSet<>(); - private SideEffectSet sideEffectSet; - - public PaperweightFaweWorldNativeAccess(PaperweightFaweAdapter paperweightFaweAdapter, WeakReference level) { - this.paperweightFaweAdapter = paperweightFaweAdapter; - this.level = level; - // Use the actual tick as minecraft-defined so we don't try to force blocks into the world when the server's already lagging. - // - With the caveat that we don't want to have too many cached changed (1024) so we'd flush those at 1024 anyway. - this.lastTick = new AtomicInteger(MinecraftServer.currentTick); - } - - private Level getLevel() { - return Objects.requireNonNull(level.get(), "The reference to the world was lost"); - } - - @Override - public void setCurrentSideEffectSet(SideEffectSet sideEffectSet) { - this.sideEffectSet = sideEffectSet; - } - - @Override - public LevelChunk getChunk(int x, int z) { - return getLevel().getChunk(x, z); - } - - @Override - public net.minecraft.world.level.block.state.BlockState toNative(BlockState blockState) { - int stateId = paperweightFaweAdapter.ordinalToIbdID(blockState.getOrdinalChar()); - return BlockStateIdAccess.isValidInternalId(stateId) - ? Block.stateById(stateId) - : ((CraftBlockData) BukkitAdapter.adapt(blockState)).getState(); - } - - @Override - public net.minecraft.world.level.block.state.BlockState getBlockState(LevelChunk levelChunk, BlockPos blockPos) { - return levelChunk.getBlockState(blockPos); - } - - @Nullable - @Override - public synchronized net.minecraft.world.level.block.state.BlockState setBlockState( - LevelChunk levelChunk, BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState blockState - ) { - int currentTick = MinecraftServer.currentTick; - if (Fawe.isMainThread()) { - return levelChunk.setBlockState(blockPos, blockState, - this.sideEffectSet != null && this.sideEffectSet.shouldApply(SideEffect.UPDATE) - ); - } - // Since FAWE is.. Async we need to do it on the main thread (wooooo.. :( ) - cachedChanges.add(new CachedChange(levelChunk, blockPos, blockState)); - cachedChunksToSend.add(new IntPair(levelChunk.locX, levelChunk.locZ)); - boolean nextTick = lastTick.get() > currentTick; - if (nextTick || cachedChanges.size() >= 1024) { - if (nextTick) { - lastTick.set(currentTick); - } - flushAsync(nextTick); - } - return blockState; - } - - @Override - public net.minecraft.world.level.block.state.BlockState getValidBlockForPosition( - net.minecraft.world.level.block.state.BlockState blockState, - BlockPos blockPos - ) { - return Block.updateFromNeighbourShapes(blockState, getLevel(), blockPos); - } - - @Override - public BlockPos getPosition(int x, int y, int z) { - return new BlockPos(x, y, z); - } - - @Override - public void updateLightingForBlock(BlockPos blockPos) { - getLevel().getChunkSource().getLightEngine().checkBlock(blockPos); - } - - @Override - public boolean updateTileEntity(BlockPos blockPos, LinCompoundTag tag) { - // We will assume that the tile entity was created for us, - // though we do not do this on the other versions - BlockEntity blockEntity = getLevel().getBlockEntity(blockPos); - if (blockEntity == null) { - return false; - } - net.minecraft.nbt.Tag nativeTag = paperweightFaweAdapter.fromNativeLin(tag); - blockEntity.load((CompoundTag) nativeTag); - return true; - } - - @Override - public void notifyBlockUpdate( - LevelChunk levelChunk, BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState - ) { - if (levelChunk.getSections()[level.get().getSectionIndex(blockPos.getY())] != null) { - getLevel().sendBlockUpdated(blockPos, oldState, newState, UPDATE | NOTIFY); - } - } - - @Override - public boolean isChunkTicking(LevelChunk levelChunk) { - return levelChunk.getFullStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING); - } - - @Override - public void markBlockChanged(LevelChunk levelChunk, BlockPos blockPos) { - if (levelChunk.getSections()[level.get().getSectionIndex(blockPos.getY())] != null) { - ((ServerChunkCache) getLevel().getChunkSource()).blockChanged(blockPos); - } - } - - @Override - public void notifyNeighbors( - BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState - ) { - Level level = getLevel(); - if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { - level.blockUpdated(blockPos, oldState.getBlock()); - } else { - // When we don't want events, manually run the physics without them. - // Un-nest neighbour updating - for (Direction direction : NEIGHBOUR_ORDER) { - BlockPos shifted = blockPos.relative(direction); - level.getBlockState(shifted).neighborChanged(level, shifted, oldState.getBlock(), blockPos, false); - } - } - if (newState.hasAnalogOutputSignal()) { - level.updateNeighbourForOutputSignal(blockPos, newState.getBlock()); - } - } - - @Override - public void updateNeighbors( - BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState, - int recursionLimit - ) { - Level level = getLevel(); - // a == updateNeighbors - // b == updateDiagonalNeighbors - oldState.updateIndirectNeighbourShapes(level, blockPos, NOTIFY, recursionLimit); - if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { - CraftWorld craftWorld = level.getWorld(); - if (craftWorld != null) { - BlockPhysicsEvent event = new BlockPhysicsEvent( - craftWorld.getBlockAt(blockPos.getX(), blockPos.getY(), blockPos.getZ()), - CraftBlockData.fromData(newState) - ); - level.getCraftServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { - return; - } - } - } - newState.triggerEvent(level, blockPos, NOTIFY, recursionLimit); - newState.updateIndirectNeighbourShapes(level, blockPos, NOTIFY, recursionLimit); - } - - @Override - public void updateBlock(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { - Level world = getLevel(); - newState.onPlace(world, pos, oldState, false); - } - - @Override - public void onBlockStateChange( - BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState - ) { - getLevel().onBlockStateChange(blockPos, oldState, newState); - } - - private synchronized void flushAsync(final boolean sendChunks) { - final Set changes = Set.copyOf(cachedChanges); - cachedChanges.clear(); - final Set toSend; - if (sendChunks) { - toSend = Set.copyOf(cachedChunksToSend); - cachedChunksToSend.clear(); - } else { - toSend = Collections.emptySet(); - } - RunnableVal runnableVal = new RunnableVal<>() { - @Override - public void run(Object value) { - changes.forEach(cc -> cc.levelChunk.setBlockState(cc.blockPos, cc.blockState, - sideEffectSet != null && sideEffectSet.shouldApply(SideEffect.UPDATE) - )); - if (!sendChunks) { - return; - } - for (IntPair chunk : toSend) { - PaperweightPlatformAdapter.sendChunk(chunk, getLevel().getWorld().getHandle(), chunk.x(), chunk.z()); - } - } - }; - TaskManager.taskManager().async(() -> TaskManager.taskManager().sync(runnableVal)); - } - - @Override - public synchronized void flush() { - RunnableVal runnableVal = new RunnableVal<>() { - @Override - public void run(Object value) { - cachedChanges.forEach(cc -> cc.levelChunk.setBlockState(cc.blockPos, cc.blockState, - sideEffectSet != null && sideEffectSet.shouldApply(SideEffect.UPDATE) - )); - for (IntPair chunk : cachedChunksToSend) { - PaperweightPlatformAdapter.sendChunk(chunk, getLevel().getWorld().getHandle(), chunk.x(), chunk.z()); - } - } - }; - if (Fawe.isMainThread()) { - runnableVal.run(); - } else { - TaskManager.taskManager().sync(runnableVal); - } - cachedChanges.clear(); - cachedChunksToSend.clear(); - } - - private record CachedChange( - LevelChunk levelChunk, - BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState blockState - ) { - - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks.java deleted file mode 100644 index 91bcf0e92..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks.java +++ /dev/null @@ -1,1184 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1; - -import com.fastasyncworldedit.bukkit.adapter.BukkitGetBlocks; -import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore; -import com.fastasyncworldedit.core.Fawe; -import com.fastasyncworldedit.core.FaweCache; -import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType; -import com.fastasyncworldedit.core.math.BitArrayUnstretched; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.queue.IChunkSet; -import com.fastasyncworldedit.core.queue.implementation.QueueHandler; -import com.fastasyncworldedit.core.queue.implementation.blocks.CharGetBlocks; -import com.fastasyncworldedit.core.util.MathMan; -import com.fastasyncworldedit.core.util.collection.AdaptedMap; -import com.google.common.base.Suppliers; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.ListTag; -import com.sk89q.jnbt.StringTag; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.internal.Constants; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.biome.BiomeTypes; -import com.sk89q.worldedit.world.block.BlockTypesCache; -import io.papermc.lib.PaperLib; -import io.papermc.paper.event.block.BeaconDeactivatedEvent; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.core.IdMap; -import net.minecraft.core.Registry; -import net.minecraft.core.SectionPos; -import net.minecraft.nbt.IntTag; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.util.BitStorage; -import net.minecraft.util.ZeroBitStorage; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.level.LightLayer; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.entity.BeaconBlockEntity; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.DataLayer; -import net.minecraft.world.level.chunk.HashMapPalette; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.LevelChunkSection; -import net.minecraft.world.level.chunk.LinearPalette; -import net.minecraft.world.level.chunk.Palette; -import net.minecraft.world.level.chunk.PalettedContainer; -import net.minecraft.world.level.chunk.PalettedContainerRO; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.lighting.LevelLightEngine; -import org.apache.logging.log4j.Logger; -import org.bukkit.World; -import org.bukkit.craftbukkit.v1_20_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_20_R1.block.CraftBlock; -import org.bukkit.event.entity.CreatureSpawnEvent; - -import javax.annotation.Nonnull; -import java.util.AbstractSet; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Future; -import java.util.concurrent.Semaphore; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.function.Function; -import java.util.stream.Collectors; - -import static net.minecraft.core.registries.Registries.BIOME; - -public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBlocks { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - - private static final Function posNms2We = v -> BlockVector3.at(v.getX(), v.getY(), v.getZ()); - private static final Function nmsTile2We = - tileEntity -> new PaperweightLazyCompoundTag(Suppliers.memoize(tileEntity::saveWithId)); - private final PaperweightFaweAdapter adapter = ((PaperweightFaweAdapter) WorldEditPlugin - .getInstance() - .getBukkitImplAdapter()); - private final ReadWriteLock sectionLock = new ReentrantReadWriteLock(); - private final ReentrantLock callLock = new ReentrantLock(); - private final ServerLevel serverLevel; - private final int chunkX; - private final int chunkZ; - private final int minHeight; - private final int maxHeight; - private final int minSectionPosition; - private final int maxSectionPosition; - private final Registry biomeRegistry; - private final IdMap> biomeHolderIdMap; - private final ConcurrentHashMap copies = new ConcurrentHashMap<>(); - private final Object sendLock = new Object(); - private LevelChunkSection[] sections; - private LevelChunk levelChunk; - private DataLayer[] blockLight; - private DataLayer[] skyLight; - private boolean createCopy = false; - private boolean forceLoadSections = true; - private boolean lightUpdate = false; - private int copyKey = 0; - - public PaperweightGetBlocks(World world, int chunkX, int chunkZ) { - this(((CraftWorld) world).getHandle(), chunkX, chunkZ); - } - - public PaperweightGetBlocks(ServerLevel serverLevel, int chunkX, int chunkZ) { - super(serverLevel.getMinBuildHeight() >> 4, (serverLevel.getMaxBuildHeight() - 1) >> 4); - this.serverLevel = serverLevel; - this.chunkX = chunkX; - this.chunkZ = chunkZ; - this.minHeight = serverLevel.getMinBuildHeight(); - this.maxHeight = serverLevel.getMaxBuildHeight() - 1; // Minecraft max limit is exclusive. - this.minSectionPosition = minHeight >> 4; - this.maxSectionPosition = maxHeight >> 4; - this.skyLight = new DataLayer[getSectionCount()]; - this.blockLight = new DataLayer[getSectionCount()]; - this.biomeRegistry = serverLevel.registryAccess().registryOrThrow(BIOME); - this.biomeHolderIdMap = biomeRegistry.asHolderIdMap(); - } - - public int getChunkX() { - return chunkX; - } - - public int getChunkZ() { - return chunkZ; - } - - @Override - public boolean isCreateCopy() { - return createCopy; - } - - @Override - public int setCreateCopy(boolean createCopy) { - if (!callLock.isHeldByCurrentThread()) { - throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked."); - } - this.createCopy = createCopy; - // Increment regardless of whether copy will be created or not to return null from getCopy() - return ++this.copyKey; - } - - @Override - public IChunkGet getCopy(final int key) { - return copies.remove(key); - } - - @Override - public void lockCall() { - this.callLock.lock(); - } - - @Override - public void unlockCall() { - this.callLock.unlock(); - } - - @Override - public void setLightingToGet(char[][] light, int minSectionPosition, int maxSectionPosition) { - if (light != null) { - lightUpdate = true; - try { - fillLightNibble(light, LightLayer.BLOCK, minSectionPosition, maxSectionPosition); - } catch (Throwable e) { - e.printStackTrace(); - } - } - } - - @Override - public void setSkyLightingToGet(char[][] light, int minSectionPosition, int maxSectionPosition) { - if (light != null) { - lightUpdate = true; - try { - fillLightNibble(light, LightLayer.SKY, minSectionPosition, maxSectionPosition); - } catch (Throwable e) { - e.printStackTrace(); - } - } - } - - @Override - public void setHeightmapToGet(HeightMapType type, int[] data) { - // height + 1 to match server internal - BitArrayUnstretched bitArray = new BitArrayUnstretched(MathMan.log2nlz(getChunk().getHeight() + 1), 256); - bitArray.fromRaw(data); - Heightmap.Types nativeType = Heightmap.Types.valueOf(type.name()); - Heightmap heightMap = getChunk().heightmaps.get(nativeType); - heightMap.setRawData(getChunk(), nativeType, bitArray.getData()); - } - - @Override - public int getMaxY() { - return maxHeight; - } - - @Override - public int getMinY() { - return minHeight; - } - - @Override - public BiomeType getBiomeType(int x, int y, int z) { - LevelChunkSection section = getSections(false)[(y >> 4) - getMinSectionPosition()]; - Holder biomes = section.getNoiseBiome(x >> 2, (y & 15) >> 2, z >> 2); - return PaperweightPlatformAdapter.adapt(biomes, serverLevel); - } - - @Override - public void removeSectionLighting(int layer, boolean sky) { - SectionPos sectionPos = SectionPos.of(getChunk().getPos(), layer); - DataLayer dataLayer = serverLevel.getChunkSource().getLightEngine().getLayerListener(LightLayer.BLOCK).getDataLayerData( - sectionPos); - if (dataLayer != null) { - lightUpdate = true; - synchronized (dataLayer) { - byte[] bytes = dataLayer.getData(); - Arrays.fill(bytes, (byte) 0); - } - } - if (sky) { - SectionPos sectionPos1 = SectionPos.of(getChunk().getPos(), layer); - DataLayer dataLayer1 = serverLevel - .getChunkSource() - .getLightEngine() - .getLayerListener(LightLayer.SKY) - .getDataLayerData(sectionPos1); - if (dataLayer1 != null) { - lightUpdate = true; - synchronized (dataLayer1) { - byte[] bytes = dataLayer1.getData(); - Arrays.fill(bytes, (byte) 0); - } - } - } - } - - @Override - public CompoundTag getTile(int x, int y, int z) { - BlockEntity blockEntity = getChunk().getBlockEntity(new BlockPos((x & 15) + ( - chunkX << 4), y, (z & 15) + ( - chunkZ << 4))); - if (blockEntity == null) { - return null; - } - return new PaperweightLazyCompoundTag(Suppliers.memoize(blockEntity::saveWithId)); - } - - @Override - public Map getTiles() { - Map nmsTiles = getChunk().getBlockEntities(); - if (nmsTiles.isEmpty()) { - return Collections.emptyMap(); - } - return AdaptedMap.immutable(nmsTiles, posNms2We, nmsTile2We); - } - - @Override - public int getSkyLight(int x, int y, int z) { - int layer = y >> 4; - int alayer = layer - getMinSectionPosition(); - if (skyLight[alayer] == null) { - SectionPos sectionPos = SectionPos.of(getChunk().getPos(), layer); - DataLayer dataLayer = - serverLevel.getChunkSource().getLightEngine().getLayerListener(LightLayer.SKY).getDataLayerData(sectionPos); - // If the server hasn't generated the section's NibbleArray yet, it will be null - if (dataLayer == null) { - byte[] LAYER_COUNT = new byte[2048]; - // Safe enough to assume if it's not created, it's under the sky. Unlikely to be created before lighting is fixed anyway. - Arrays.fill(LAYER_COUNT, (byte) 15); - dataLayer = new DataLayer(LAYER_COUNT); - ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData( - LightLayer.BLOCK, - sectionPos, - dataLayer - ); - } - skyLight[alayer] = dataLayer; - } - return skyLight[alayer].get(x & 15, y & 15, z & 15); - } - - @Override - public int getEmittedLight(int x, int y, int z) { - int layer = y >> 4; - int alayer = layer - getMinSectionPosition(); - if (blockLight[alayer] == null) { - serverLevel.getRawBrightness(new BlockPos(1, 1, 1), 5); - SectionPos sectionPos = SectionPos.of(getChunk().getPos(), layer); - DataLayer dataLayer = serverLevel - .getChunkSource() - .getLightEngine() - .getLayerListener(LightLayer.BLOCK) - .getDataLayerData(sectionPos); - // If the server hasn't generated the section's DataLayer yet, it will be null - if (dataLayer == null) { - byte[] LAYER_COUNT = new byte[2048]; - // Safe enough to assume if it's not created, it's under the sky. Unlikely to be created before lighting is fixed anyway. - Arrays.fill(LAYER_COUNT, (byte) 15); - dataLayer = new DataLayer(LAYER_COUNT); - ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData(LightLayer.BLOCK, sectionPos, - dataLayer - ); - } - blockLight[alayer] = dataLayer; - } - return blockLight[alayer].get(x & 15, y & 15, z & 15); - } - - @Override - public int[] getHeightMap(HeightMapType type) { - long[] longArray = getChunk().heightmaps.get(Heightmap.Types.valueOf(type.name())).getRawData(); - BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256, longArray); - return bitArray.toRaw(new int[256]); - } - - @Override - public CompoundTag getEntity(UUID uuid) { - Entity entity = serverLevel.getEntity(uuid); - if (entity != null) { - org.bukkit.entity.Entity bukkitEnt = entity.getBukkitEntity(); - return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData(); - } - for (CompoundTag tag : getEntities()) { - if (uuid.equals(tag.getUUID())) { - return tag; - } - } - return null; - } - - @Override - public Set getEntities() { - ensureLoaded(serverLevel, chunkX, chunkZ); - List entities = PaperweightPlatformAdapter.getEntities(getChunk()); - if (entities.isEmpty()) { - return Collections.emptySet(); - } - int size = entities.size(); - return new AbstractSet<>() { - @Override - public int size() { - return size; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public boolean contains(Object get) { - if (!(get instanceof CompoundTag getTag)) { - return false; - } - UUID getUUID = getTag.getUUID(); - for (Entity entity : entities) { - UUID uuid = entity.getUUID(); - if (uuid.equals(getUUID)) { - return true; - } - } - return false; - } - - @Nonnull - @Override - public Iterator iterator() { - Iterable result = entities.stream().map(input -> { - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - PaperweightPlatformAdapter.readEntityIntoTag(input, tag); - return (CompoundTag) adapter.toNative(tag); - }).collect(Collectors.toList()); - return result.iterator(); - } - }; - } - - private void removeEntity(Entity entity) { - entity.discard(); - } - - public LevelChunk ensureLoaded(ServerLevel nmsWorld, int chunkX, int chunkZ) { - return PaperweightPlatformAdapter.ensureLoaded(nmsWorld, chunkX, chunkZ); - } - - @Override - @SuppressWarnings("rawtypes") - public synchronized > T call(IChunkSet set, Runnable finalizer) { - if (!callLock.isHeldByCurrentThread()) { - throw new IllegalStateException("Attempted to call chunk GET but chunk was not call-locked."); - } - forceLoadSections = false; - PaperweightGetBlocks_Copy copy = createCopy ? new PaperweightGetBlocks_Copy(levelChunk) : null; - if (createCopy) { - if (copies.containsKey(copyKey)) { - throw new IllegalStateException("Copy key already used."); - } - copies.put(copyKey, copy); - } - try { - ServerLevel nmsWorld = serverLevel; - LevelChunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ); - - // Remove existing tiles. Create a copy so that we can remove blocks - Map chunkTiles = new HashMap<>(nmsChunk.getBlockEntities()); - List beacons = null; - if (!chunkTiles.isEmpty()) { - for (Map.Entry entry : chunkTiles.entrySet()) { - final BlockPos pos = entry.getKey(); - final int lx = pos.getX() & 15; - final int ly = pos.getY(); - final int lz = pos.getZ() & 15; - final int layer = ly >> 4; - if (!set.hasSection(layer)) { - continue; - } - - int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); - if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { - BlockEntity tile = entry.getValue(); - if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { - if (beacons == null) { - beacons = new ArrayList<>(); - } - beacons.add(tile); - PaperweightPlatformAdapter.removeBeacon(tile, nmsChunk); - continue; - } - nmsChunk.removeBlockEntity(tile.getBlockPos()); - if (createCopy) { - copy.storeTile(tile); - } - } - } - } - final BiomeType[][] biomes = set.getBiomes(); - - int bitMask = 0; - synchronized (nmsChunk) { - LevelChunkSection[] levelChunkSections = nmsChunk.getSections(); - - for (int layerNo = getMinSectionPosition(); layerNo <= getMaxSectionPosition(); layerNo++) { - - int getSectionIndex = layerNo - getMinSectionPosition(); - int setSectionIndex = layerNo - set.getMinSectionPosition(); - - if (!set.hasSection(layerNo)) { - // No blocks, but might be biomes present. Handle this lazily. - if (biomes == null) { - continue; - } - if (layerNo < set.getMinSectionPosition() || layerNo > set.getMaxSectionPosition()) { - continue; - } - if (biomes[setSectionIndex] != null) { - synchronized (super.sectionLocks[getSectionIndex]) { - LevelChunkSection existingSection = levelChunkSections[getSectionIndex]; - if (createCopy && existingSection != null) { - copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); - } - - if (existingSection == null) { - PalettedContainer> biomeData = PaperweightPlatformAdapter.getBiomePalettedContainer( - biomes[setSectionIndex], - biomeHolderIdMap - ); - LevelChunkSection newSection = PaperweightPlatformAdapter.newChunkSection( - layerNo, - new char[4096], - adapter, - biomeRegistry, - biomeData - ); - if (PaperweightPlatformAdapter.setSectionAtomic( - levelChunkSections, - null, - newSection, - getSectionIndex - )) { - updateGet(nmsChunk, levelChunkSections, newSection, new char[4096], getSectionIndex); - continue; - } else { - existingSection = levelChunkSections[getSectionIndex]; - if (existingSection == null) { - LOGGER.error("Skipping invalid null section. chunk: {}, {} layer: {}", chunkX, chunkZ, - getSectionIndex - ); - continue; - } - } - } else { - PalettedContainer> paletteBiomes = setBiomesToPalettedContainer( - biomes, - setSectionIndex, - existingSection.getBiomes() - ); - if (paletteBiomes != null) { - PaperweightPlatformAdapter.setBiomesToChunkSection(existingSection, paletteBiomes); - } - } - } - } - continue; - } - - bitMask |= 1 << getSectionIndex; - - // setArr is modified by PaperweightPlatformAdapter#newChunkSection. This is in order to write changes to - // this chunk GET when #updateGet is called. Future dords, please listen this time. - char[] tmp = set.load(layerNo); - char[] setArr = new char[tmp.length]; - System.arraycopy(tmp, 0, setArr, 0, tmp.length); - - // synchronise on internal section to avoid circular locking with a continuing edit if the chunk was - // submitted to keep loaded internal chunks to queue target size. - synchronized (super.sectionLocks[getSectionIndex]) { - - LevelChunkSection newSection; - LevelChunkSection existingSection = levelChunkSections[getSectionIndex]; - // Don't attempt to tick section whilst we're editing - if (existingSection != null) { - PaperweightPlatformAdapter.clearCounts(existingSection); - if (PaperLib.isPaper()) { - existingSection.tickingList.clear(); - } - } - - if (createCopy) { - char[] tmpLoad = loadPrivately(layerNo); - char[] copyArr = new char[4096]; - System.arraycopy(tmpLoad, 0, copyArr, 0, 4096); - copy.storeSection(getSectionIndex, copyArr); - if (biomes != null && existingSection != null) { - copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); - } - } - - if (existingSection == null) { - PalettedContainer> biomeData = biomes == null ? new PalettedContainer<>( - biomeHolderIdMap, - biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)), - PalettedContainer.Strategy.SECTION_BIOMES - ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap); - newSection = PaperweightPlatformAdapter.newChunkSection( - layerNo, - setArr, - adapter, - biomeRegistry, - biomeData - ); - if (PaperweightPlatformAdapter.setSectionAtomic( - levelChunkSections, - null, - newSection, - getSectionIndex - )) { - updateGet(nmsChunk, levelChunkSections, newSection, setArr, getSectionIndex); - continue; - } else { - existingSection = levelChunkSections[getSectionIndex]; - if (existingSection == null) { - LOGGER.error("Skipping invalid null section. chunk: {}, {} layer: {}", chunkX, chunkZ, - getSectionIndex - ); - continue; - } - } - } - - //ensure that the server doesn't try to tick the chunksection while we're editing it. (Again) - PaperweightPlatformAdapter.clearCounts(existingSection); - if (PaperLib.isPaper()) { - existingSection.tickingList.clear(); - } - DelegateSemaphore lock = PaperweightPlatformAdapter.applyLock(existingSection); - - // Synchronize to prevent further acquisitions - synchronized (lock) { - lock.acquire(); // Wait until we have the lock - lock.release(); - try { - sectionLock.writeLock().lock(); - if (this.getChunk() != nmsChunk) { - this.levelChunk = nmsChunk; - this.sections = null; - this.reset(); - } else if (existingSection != getSections(false)[getSectionIndex]) { - this.sections[getSectionIndex] = existingSection; - this.reset(); - } else if (!Arrays.equals( - update(getSectionIndex, new char[4096], true), - loadPrivately(layerNo) - )) { - this.reset(layerNo); - /*} else if (lock.isModified()) { - this.reset(layerNo);*/ - } - } finally { - sectionLock.writeLock().unlock(); - } - - PalettedContainer> biomeData = setBiomesToPalettedContainer( - biomes, - setSectionIndex, - existingSection.getBiomes() - ); - - newSection = PaperweightPlatformAdapter.newChunkSection( - layerNo, - this::loadPrivately, - setArr, - adapter, - biomeRegistry, - biomeData != null ? biomeData : (PalettedContainer>) existingSection.getBiomes() - ); - if (!PaperweightPlatformAdapter.setSectionAtomic( - levelChunkSections, - existingSection, - newSection, - getSectionIndex - )) { - LOGGER.error("Skipping invalid null section. chunk: {}, {} layer: {}", chunkX, chunkZ, - getSectionIndex - ); - } else { - updateGet(nmsChunk, levelChunkSections, newSection, setArr, getSectionIndex); - } - } - } - } - - Map heightMaps = set.getHeightMaps(); - for (Map.Entry entry : heightMaps.entrySet()) { - PaperweightGetBlocks.this.setHeightmapToGet(entry.getKey(), entry.getValue()); - } - PaperweightGetBlocks.this.setLightingToGet( - set.getLight(), - set.getMinSectionPosition(), - set.getMaxSectionPosition() - ); - PaperweightGetBlocks.this.setSkyLightingToGet( - set.getSkyLight(), - set.getMinSectionPosition(), - set.getMaxSectionPosition() - ); - - Runnable[] syncTasks = null; - - int bx = chunkX << 4; - int bz = chunkZ << 4; - - // Call beacon deactivate events here synchronously - // list will be null on spigot, so this is an implicit isPaper check - if (beacons != null && !beacons.isEmpty()) { - final List finalBeacons = beacons; - - syncTasks = new Runnable[4]; - - syncTasks[3] = () -> { - for (BlockEntity beacon : finalBeacons) { - BeaconBlockEntity.playSound(beacon.getLevel(), beacon.getBlockPos(), SoundEvents.BEACON_DEACTIVATE); - new BeaconDeactivatedEvent(CraftBlock.at(beacon.getLevel(), beacon.getBlockPos())).callEvent(); - } - }; - } - - Set entityRemoves = set.getEntityRemoves(); - if (entityRemoves != null && !entityRemoves.isEmpty()) { - if (syncTasks == null) { - syncTasks = new Runnable[3]; - } - - syncTasks[2] = () -> { - Set entitiesRemoved = new HashSet<>(); - final List entities = PaperweightPlatformAdapter.getEntities(nmsChunk); - - for (Entity entity : entities) { - UUID uuid = entity.getUUID(); - if (entityRemoves.contains(uuid)) { - if (createCopy) { - copy.storeEntity(entity); - } - removeEntity(entity); - entitiesRemoved.add(uuid); - entityRemoves.remove(uuid); - } - } - if (Settings.settings().EXPERIMENTAL.REMOVE_ENTITY_FROM_WORLD_ON_CHUNK_FAIL) { - for (UUID uuid : entityRemoves) { - Entity entity = nmsWorld.getEntities().get(uuid); - if (entity != null) { - removeEntity(entity); - } - } - } - // Only save entities that were actually removed to history - set.getEntityRemoves().clear(); - set.getEntityRemoves().addAll(entitiesRemoved); - }; - } - - Set entities = set.getEntities(); - if (entities != null && !entities.isEmpty()) { - if (syncTasks == null) { - syncTasks = new Runnable[2]; - } - - syncTasks[1] = () -> { - Iterator iterator = entities.iterator(); - while (iterator.hasNext()) { - final CompoundTag nativeTag = iterator.next(); - final Map> entityTagMap = nativeTag.getValue(); - final StringTag idTag = (StringTag) entityTagMap.get("Id"); - final ListTag posTag = (ListTag) entityTagMap.get("Pos"); - final ListTag rotTag = (ListTag) entityTagMap.get("Rotation"); - if (idTag == null || posTag == null || rotTag == null) { - LOGGER.error("Unknown entity tag: {}", nativeTag); - continue; - } - final double x = posTag.getDouble(0); - final double y = posTag.getDouble(1); - final double z = posTag.getDouble(2); - final float yaw = rotTag.getFloat(0); - final float pitch = rotTag.getFloat(1); - final String id = idTag.getValue(); - - EntityType type = EntityType.byString(id).orElse(null); - if (type != null) { - Entity entity = type.create(nmsWorld); - if (entity != null) { - final net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNative( - nativeTag); - for (final String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { - tag.remove(name); - } - entity.load(tag); - entity.absMoveTo(x, y, z, yaw, pitch); - entity.setUUID(nativeTag.getUUID()); - if (!nmsWorld.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM)) { - LOGGER.warn( - "Error creating entity of type `{}` in world `{}` at location `{},{},{}`", - id, - nmsWorld.getWorld().getName(), - x, - y, - z - ); - // Unsuccessful create should not be saved to history - iterator.remove(); - } - } - } - } - }; - } - - // set tiles - Map tiles = set.getTiles(); - if (tiles != null && !tiles.isEmpty()) { - if (syncTasks == null) { - syncTasks = new Runnable[1]; - } - - syncTasks[0] = () -> { - for (final Map.Entry entry : tiles.entrySet()) { - final CompoundTag nativeTag = entry.getValue(); - final BlockVector3 blockHash = entry.getKey(); - final int x = blockHash.x() + bx; - final int y = blockHash.y(); - final int z = blockHash.z() + bz; - final BlockPos pos = new BlockPos(x, y, z); - - synchronized (nmsWorld) { - BlockEntity tileEntity = nmsWorld.getBlockEntity(pos); - if (tileEntity == null || tileEntity.isRemoved()) { - nmsWorld.removeBlockEntity(pos); - tileEntity = nmsWorld.getBlockEntity(pos); - } - if (tileEntity != null) { - final net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNative( - nativeTag); - tag.put("x", IntTag.valueOf(x)); - tag.put("y", IntTag.valueOf(y)); - tag.put("z", IntTag.valueOf(z)); - tileEntity.load(tag); - } - } - } - }; - } - - Runnable callback; - if (bitMask == 0 && biomes == null && !lightUpdate) { - callback = null; - } else { - int finalMask = bitMask != 0 ? bitMask : lightUpdate ? set.getBitMask() : 0; - boolean finalLightUpdate = lightUpdate; - callback = () -> { - // Set Modified - nmsChunk.setLightCorrect(true); // Set Modified - nmsChunk.mustNotSave = false; - nmsChunk.setUnsaved(true); - // send to player - if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalMask == 0 && biomes != null) { - this.send(); - } - if (finalizer != null) { - finalizer.run(); - } - }; - } - if (syncTasks != null) { - QueueHandler queueHandler = Fawe.instance().getQueueHandler(); - Runnable[] finalSyncTasks = syncTasks; - - // Chain the sync tasks and the callback - Callable chain = () -> { - try { - // Run the sync tasks - for (Runnable task : finalSyncTasks) { - if (task != null) { - task.run(); - } - } - if (callback == null) { - if (finalizer != null) { - queueHandler.async(finalizer, null); - } - return null; - } else { - return queueHandler.async(callback, null); - } - } catch (Throwable e) { - e.printStackTrace(); - throw e; - } - }; - //noinspection unchecked - required at compile time - return (T) (Future) queueHandler.sync(chain); - } else { - if (callback == null) { - if (finalizer != null) { - finalizer.run(); - } - } else { - callback.run(); - } - } - } - return null; - } catch (Throwable e) { - e.printStackTrace(); - return null; - } finally { - forceLoadSections = true; - } - } - - private void updateGet( - LevelChunk nmsChunk, - LevelChunkSection[] chunkSections, - LevelChunkSection section, - char[] arr, - int layer - ) { - try { - sectionLock.writeLock().lock(); - if (this.getChunk() != nmsChunk) { - this.levelChunk = nmsChunk; - this.sections = new LevelChunkSection[chunkSections.length]; - System.arraycopy(chunkSections, 0, this.sections, 0, chunkSections.length); - this.reset(); - } - if (this.sections == null) { - this.sections = new LevelChunkSection[chunkSections.length]; - System.arraycopy(chunkSections, 0, this.sections, 0, chunkSections.length); - } - if (this.sections[layer] != section) { - // Not sure why it's funky, but it's what I did in commit fda7d00747abe97d7891b80ed8bb88d97e1c70d1 and I don't want to touch it >dords - this.sections[layer] = new LevelChunkSection[]{section}.clone()[0]; - } - } finally { - sectionLock.writeLock().unlock(); - } - this.blocks[layer] = arr; - } - - private char[] loadPrivately(int layer) { - layer -= getMinSectionPosition(); - if (super.sections[layer] != null) { - synchronized (super.sectionLocks[layer]) { - if (super.sections[layer].isFull() && super.blocks[layer] != null) { - return super.blocks[layer]; - } - } - } - return PaperweightGetBlocks.this.update(layer, null, true); - } - - @Override - public void send() { - synchronized (sendLock) { - PaperweightPlatformAdapter.sendChunk(this, serverLevel, chunkX, chunkZ); - } - } - - /** - * Update a given (nullable) data array to the current data stored in the server's chunk, associated with this - * {@link PaperweightPlatformAdapter} instance. Not synchronised to the {@link PaperweightPlatformAdapter} instance as synchronisation - * is handled where necessary in the method, and should otherwise be handled correctly by this method's caller. - * - * @param layer layer index (0 may denote a negative layer in the world, e.g. at y=-32) - * @param data array to be updated/filled with data or null - * @param aggressive if the cached section array should be re-acquired. - * @return the given array to be filled with data, or a new array if null is given. - */ - @Override - @SuppressWarnings("unchecked") - public char[] update(int layer, char[] data, boolean aggressive) { - LevelChunkSection section = getSections(aggressive)[layer]; - // Section is null, return empty array - if (section == null) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - return data; - } - if (data != null && data.length != 4096) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - } - if (data == null || data == FaweCache.INSTANCE.EMPTY_CHAR_4096) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - } - Semaphore lock = PaperweightPlatformAdapter.applyLock(section); - synchronized (lock) { - // Efficiently convert ChunkSection to raw data - try { - lock.acquire(); - - final PalettedContainer blocks = section.getStates(); - final Object dataObject = PaperweightPlatformAdapter.fieldData.get(blocks); - final BitStorage bits = (BitStorage) PaperweightPlatformAdapter.fieldStorage.get(dataObject); - - if (bits instanceof ZeroBitStorage) { - Arrays.fill(data, adapter.adaptToChar(blocks.get(0, 0, 0))); // get(int) is only public on paper - return data; - } - - final Palette palette = (Palette) PaperweightPlatformAdapter.fieldPalette.get(dataObject); - - final int bitsPerEntry = bits.getBits(); - final long[] blockStates = bits.getRaw(); - - new BitArrayUnstretched(bitsPerEntry, 4096, blockStates).toRaw(data); - - int num_palette; - if (palette instanceof LinearPalette || palette instanceof HashMapPalette) { - num_palette = palette.getSize(); - } else { - // The section's palette is the global block palette. - for (int i = 0; i < 4096; i++) { - char paletteVal = data[i]; - char ordinal = adapter.ibdIDToOrdinal(paletteVal); - data[i] = ordinal; - } - return data; - } - - char[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK_CHAR.get(); - try { - if (num_palette != 1) { - for (int i = 0; i < num_palette; i++) { - char ordinal = ordinal(palette.valueFor(i), adapter); - paletteToOrdinal[i] = ordinal; - } - for (int i = 0; i < 4096; i++) { - char paletteVal = data[i]; - char val = paletteToOrdinal[paletteVal]; - if (val == Character.MAX_VALUE) { - val = ordinal(palette.valueFor(i), adapter); - paletteToOrdinal[i] = val; - } - data[i] = val; - } - } else { - char ordinal = ordinal(palette.valueFor(0), adapter); - Arrays.fill(data, ordinal); - } - } finally { - for (int i = 0; i < num_palette; i++) { - paletteToOrdinal[i] = Character.MAX_VALUE; - } - } - return data; - } catch (IllegalAccessException | InterruptedException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } finally { - lock.release(); - } - } - } - - private char ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { - if (ibd == null) { - return BlockTypesCache.ReservedIDs.AIR; - } else { - return adapter.adaptToChar(ibd); - } - } - - public LevelChunkSection[] getSections(boolean force) { - force &= forceLoadSections; - LevelChunkSection[] tmp = sections; - if (tmp == null || force) { - try { - sectionLock.writeLock().lock(); - tmp = sections; - if (tmp == null || force) { - LevelChunkSection[] chunkSections = getChunk().getSections(); - tmp = new LevelChunkSection[chunkSections.length]; - System.arraycopy(chunkSections, 0, tmp, 0, chunkSections.length); - sections = tmp; - } - } finally { - sectionLock.writeLock().unlock(); - } - } - return tmp; - } - - public LevelChunk getChunk() { - LevelChunk levelChunk = this.levelChunk; - if (levelChunk == null) { - synchronized (this) { - levelChunk = this.levelChunk; - if (levelChunk == null) { - this.levelChunk = levelChunk = ensureLoaded(this.serverLevel, chunkX, chunkZ); - } - } - } - return levelChunk; - } - - private void fillLightNibble(char[][] light, LightLayer lightLayer, int minSectionPosition, int maxSectionPosition) { - for (int Y = 0; Y <= maxSectionPosition - minSectionPosition; Y++) { - if (light[Y] == null) { - continue; - } - SectionPos sectionPos = SectionPos.of(levelChunk.getPos(), Y + minSectionPosition); - DataLayer dataLayer = serverLevel.getChunkSource().getLightEngine().getLayerListener(lightLayer).getDataLayerData( - sectionPos); - if (dataLayer == null) { - byte[] LAYER_COUNT = new byte[2048]; - Arrays.fill(LAYER_COUNT, lightLayer == LightLayer.SKY ? (byte) 15 : (byte) 0); - dataLayer = new DataLayer(LAYER_COUNT); - ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData( - lightLayer, - sectionPos, - dataLayer - ); - } - synchronized (dataLayer) { - for (int x = 0; x < 16; x++) { - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - int i = y << 8 | z << 4 | x; - if (light[Y][i] < 16) { - dataLayer.set(x, y, z, light[Y][i]); - } - } - } - } - } - } - } - - private PalettedContainer> setBiomesToPalettedContainer( - final BiomeType[][] biomes, - final int sectionIndex, - final PalettedContainerRO> data - ) { - BiomeType[] sectionBiomes; - if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { - return null; - } - PalettedContainer> biomeData = data.recreate(); - for (int y = 0, index = 0; y < 4; y++) { - for (int z = 0; z < 4; z++) { - for (int x = 0; x < 4; x++, index++) { - BiomeType biomeType = sectionBiomes[index]; - if (biomeType == null) { - biomeData.set(x, y, z, data.get(x, y, z)); - } else { - biomeData.set( - x, - y, - z, - biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) - ); - } - } - } - } - return biomeData; - } - - @Override - public boolean hasSection(int layer) { - layer -= getMinSectionPosition(); - return getSections(false)[layer] != null; - } - - @Override - @SuppressWarnings("unchecked") - public synchronized boolean trim(boolean aggressive) { - skyLight = new DataLayer[getSectionCount()]; - blockLight = new DataLayer[getSectionCount()]; - if (aggressive) { - sectionLock.writeLock().lock(); - sections = null; - levelChunk = null; - sectionLock.writeLock().unlock(); - return super.trim(true); - } else if (sections == null) { - // don't bother trimming if there are no sections stored. - return true; - } else { - for (int i = getMinSectionPosition(); i <= getMaxSectionPosition(); i++) { - int layer = i - getMinSectionPosition(); - if (!hasSection(i) || !super.sections[layer].isFull()) { - continue; - } - LevelChunkSection existing = getSections(true)[layer]; - try { - final PalettedContainer blocksExisting = existing.getStates(); - - final Object dataObject = PaperweightPlatformAdapter.fieldData.get(blocksExisting); - final Palette palette = (Palette) PaperweightPlatformAdapter.fieldPalette.get( - dataObject); - int paletteSize; - - if (palette instanceof LinearPalette || palette instanceof HashMapPalette) { - paletteSize = palette.getSize(); - } else { - super.trim(false, i); - continue; - } - if (paletteSize == 1) { - //If the cached palette size is 1 then no blocks can have been changed i.e. do not need to update these chunks. - continue; - } - super.trim(false, i); - } catch (IllegalAccessException ignored) { - super.trim(false, i); - } - } - return true; - } - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks_Copy.java deleted file mode 100644 index d2412b98f..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks_Copy.java +++ /dev/null @@ -1,259 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1; - -import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType; -import com.fastasyncworldedit.core.queue.IBlocks; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.queue.IChunkSet; -import com.google.common.base.Suppliers; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.math.BlockVector3; -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.BlockTypesCache; -import net.minecraft.core.Holder; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.PalettedContainer; -import net.minecraft.world.level.chunk.PalettedContainerRO; -import org.apache.logging.log4j.Logger; - -import javax.annotation.Nullable; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Future; - -public class PaperweightGetBlocks_Copy implements IChunkGet { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - - private final Map tiles = new HashMap<>(); - private final Set entities = new HashSet<>(); - private final char[][] blocks; - private final int minHeight; - private final int maxHeight; - final ServerLevel serverLevel; - final LevelChunk levelChunk; - private Holder[][] biomes = null; - - protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { - this.levelChunk = levelChunk; - this.serverLevel = levelChunk.level; - this.minHeight = serverLevel.getMinBuildHeight(); - this.maxHeight = serverLevel.getMaxBuildHeight() - 1; // Minecraft max limit is exclusive. - this.blocks = new char[getSectionCount()][]; - } - - protected void storeTile(BlockEntity blockEntity) { - tiles.put( - BlockVector3.at( - blockEntity.getBlockPos().getX(), - blockEntity.getBlockPos().getY(), - blockEntity.getBlockPos().getZ() - ), - new PaperweightLazyCompoundTag(Suppliers.memoize(blockEntity::saveWithId)) - ); - } - - @Override - public Map getTiles() { - return tiles; - } - - @Override - @Nullable - public CompoundTag getTile(int x, int y, int z) { - return tiles.get(BlockVector3.at(x, y, z)); - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - protected void storeEntity(Entity entity) { - BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); - net.minecraft.nbt.CompoundTag compoundTag = new net.minecraft.nbt.CompoundTag(); - PaperweightPlatformAdapter.readEntityIntoTag(entity, compoundTag); - entities.add((CompoundTag) adapter.toNative(compoundTag)); - } - - @Override - public Set getEntities() { - return this.entities; - } - - @Override - public CompoundTag getEntity(UUID uuid) { - for (CompoundTag tag : entities) { - if (uuid.equals(tag.getUUID())) { - return tag; - } - } - return null; - } - - @Override - public boolean isCreateCopy() { - return false; - } - - @Override - public int setCreateCopy(boolean createCopy) { - return -1; - } - - @Override - public void setLightingToGet(char[][] lighting, int minSectionPosition, int maxSectionPosition) { - } - - @Override - public void setSkyLightingToGet(char[][] lighting, int minSectionPosition, int maxSectionPosition) { - } - - @Override - public void setHeightmapToGet(HeightMapType type, int[] data) { - } - - @Override - public int getMaxY() { - return maxHeight; - } - - @Override - public int getMinY() { - return minHeight; - } - - @Override - public int getMaxSectionPosition() { - return maxHeight >> 4; - } - - @Override - public int getMinSectionPosition() { - return minHeight >> 4; - } - - @Override - public BiomeType getBiomeType(int x, int y, int z) { - Holder biome = biomes[(y >> 4) - getMinSectionPosition()][(y & 12) << 2 | (z & 12) | (x & 12) >> 2]; - return PaperweightPlatformAdapter.adapt(biome, serverLevel); - } - - @Override - public void removeSectionLighting(int layer, boolean sky) { - } - - @Override - public boolean trim(boolean aggressive, int layer) { - return false; - } - - @Override - public IBlocks reset() { - return null; - } - - @Override - public int getSectionCount() { - return serverLevel.getSectionsCount(); - } - - protected void storeSection(int layer, char[] data) { - blocks[layer] = data; - } - - protected void storeBiomes(int layer, PalettedContainerRO> biomeData) { - if (biomes == null) { - biomes = new Holder[getSectionCount()][]; - } - if (biomes[layer] == null) { - biomes[layer] = new Holder[64]; - } - if (biomeData instanceof PalettedContainer> palettedContainer) { - for (int i = 0; i < 64; i++) { - biomes[layer][i] = palettedContainer.get(i); - } - } else { - LOGGER.error( - "Cannot correctly save biomes to history. Expected class type {} but got {}", - PalettedContainer.class.getSimpleName(), - biomeData.getClass().getSimpleName() - ); - } - } - - @Override - public BaseBlock getFullBlock(int x, int y, int z) { - BlockState state = BlockTypesCache.states[get(x, y, z)]; - return state.toBaseBlock(this, x, y, z); - } - - @Override - public boolean hasSection(int layer) { - layer -= getMinSectionPosition(); - return blocks[layer] != null; - } - - @Override - public char[] load(int layer) { - layer -= getMinSectionPosition(); - if (blocks[layer] == null) { - blocks[layer] = new char[4096]; - Arrays.fill(blocks[layer], (char) BlockTypesCache.ReservedIDs.AIR); - } - return blocks[layer]; - } - - @Override - public char[] loadIfPresent(int layer) { - layer -= getMinSectionPosition(); - return blocks[layer]; - } - - @Override - public BlockState getBlock(int x, int y, int z) { - return BlockTypesCache.states[get(x, y, z)]; - } - - @Override - public int getSkyLight(int x, int y, int z) { - return 0; - } - - @Override - public int getEmittedLight(int x, int y, int z) { - return 0; - } - - @Override - public int[] getHeightMap(HeightMapType type) { - return new int[0]; - } - - @Override - public > T call(IChunkSet set, Runnable finalize) { - return null; - } - - public char get(int x, int y, int z) { - final int layer = (y >> 4) - getMinSectionPosition(); - final int index = (y & 15) << 8 | z << 4 | x; - return blocks[layer][index]; - } - - - @Override - public boolean trim(boolean aggressive) { - return false; - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightMapChunkUtil.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightMapChunkUtil.java deleted file mode 100644 index 62f5d4e03..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightMapChunkUtil.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1; - -import com.fastasyncworldedit.bukkit.adapter.MapChunkUtil; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData; -import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; - -//TODO un-very-break-this -public class PaperweightMapChunkUtil extends MapChunkUtil { - - public PaperweightMapChunkUtil() throws NoSuchFieldException { - fieldX = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("TWO_MEGABYTES", "a")); - fieldZ = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("x", "a")); - fieldBitMask = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("z", "b")); - fieldHeightMap = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("heightmaps", "b")); - fieldChunkData = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("chunkData", "c")); - fieldBlockEntities = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("buffer", "c")); - fieldFull = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("blockEntitiesData", "d")); - fieldX.setAccessible(true); - fieldZ.setAccessible(true); - fieldBitMask.setAccessible(true); - fieldHeightMap.setAccessible(true); - fieldChunkData.setAccessible(true); - fieldBlockEntities.setAccessible(true); - fieldFull.setAccessible(true); - } - - @Override - public ClientboundLevelChunkWithLightPacket createPacket() { - // TODO ??? return new ClientboundLevelChunkPacket(); - throw new UnsupportedOperationException(); - } - -} 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 deleted file mode 100644 index 05c0b58f9..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPlatformAdapter.java +++ /dev/null @@ -1,764 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1; - -import com.destroystokyo.paper.util.maplist.EntityList; -import com.fastasyncworldedit.bukkit.adapter.CachedBukkitAdapter; -import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore; -import com.fastasyncworldedit.bukkit.adapter.NMSAdapter; -import com.fastasyncworldedit.core.Fawe; -import com.fastasyncworldedit.core.FaweCache; -import com.fastasyncworldedit.core.math.BitArrayUnstretched; -import com.fastasyncworldedit.core.util.MathMan; -import com.fastasyncworldedit.core.util.ReflectionUtils; -import com.fastasyncworldedit.core.util.TaskManager; -import com.mojang.datafixers.util.Either; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.biome.BiomeTypes; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockTypesCache; -import io.papermc.lib.PaperLib; -import io.papermc.paper.world.ChunkEntitySlices; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.core.IdMap; -import net.minecraft.core.Registry; -import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.server.level.ChunkMap; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.level.TicketType; -import net.minecraft.util.BitStorage; -import net.minecraft.util.ExceptionCollector; -import net.minecraft.util.SimpleBitStorage; -import net.minecraft.util.ThreadingDetector; -import net.minecraft.util.Unit; -import net.minecraft.util.ZeroBitStorage; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.npc.AbstractVillager; -import net.minecraft.world.entity.npc.Villager; -import net.minecraft.world.item.trading.MerchantOffers; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkStatus; -import net.minecraft.world.level.chunk.GlobalPalette; -import net.minecraft.world.level.chunk.HashMapPalette; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.LevelChunkSection; -import net.minecraft.world.level.chunk.LinearPalette; -import net.minecraft.world.level.chunk.Palette; -import net.minecraft.world.level.chunk.PalettedContainer; -import net.minecraft.world.level.chunk.SingleValuePalette; -import net.minecraft.world.level.entity.PersistentEntitySectionManager; -import org.apache.logging.log4j.Logger; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_20_R1.CraftChunk; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.function.Function; - -import static java.lang.invoke.MethodType.methodType; -import static net.minecraft.core.registries.Registries.BIOME; - -public final class PaperweightPlatformAdapter extends NMSAdapter { - - public static final Field fieldData; - - public static final Constructor dataConstructor; - - public static final Field fieldStorage; - public static final Field fieldPalette; - - private static final Field fieldTickingFluidCount; - private static final Field fieldTickingBlockCount; - - private static final MethodHandle methodGetVisibleChunk; - - private static final Field fieldThreadingDetector; - private static final Field fieldLock; - - private static final MethodHandle methodRemoveGameEventListener; - private static final MethodHandle methodremoveTickingBlockEntity; - private static final Field fieldBiomes; - - private static final Field fieldOffers; - private static final MerchantOffers OFFERS = new MerchantOffers(); - - /* - * This is a workaround for the changes from https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/commits/1fddefce1cdce44010927b888432bf70c0e88cde#src/main/java/org/bukkit/craftbukkit/CraftChunk.java - * and is only needed to support 1.19.4 versions before *and* after this change. - */ - private static final MethodHandle CRAFT_CHUNK_GET_HANDLE; - - private static final Field fieldRemove; - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - - static final boolean POST_CHUNK_REWRITE; - private static Method PAPER_CHUNK_GEN_ALL_ENTITIES; - private static Field LEVEL_CHUNK_ENTITIES; - private static Field SERVER_LEVEL_ENTITY_MANAGER; - - static { - final MethodHandles.Lookup lookup = MethodHandles.lookup(); - try { - fieldData = PalettedContainer.class.getDeclaredField(Refraction.pickName("data", "d")); - fieldData.setAccessible(true); - - Class dataClazz = fieldData.getType(); - dataConstructor = dataClazz.getDeclaredConstructors()[0]; - dataConstructor.setAccessible(true); - - fieldStorage = dataClazz.getDeclaredField(Refraction.pickName("storage", "b")); - fieldStorage.setAccessible(true); - fieldPalette = dataClazz.getDeclaredField(Refraction.pickName("palette", "c")); - fieldPalette.setAccessible(true); - - fieldTickingFluidCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingFluidCount", "g")); - fieldTickingFluidCount.setAccessible(true); - fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f")); - fieldTickingBlockCount.setAccessible(true); - Field tmpFieldBiomes; - try { - // It seems to actually be biomes, but is apparently obfuscated to "i" - tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("biomes"); - } catch (NoSuchFieldException ignored) { - tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("i"); - } - fieldBiomes = tmpFieldBiomes; - fieldBiomes.setAccessible(true); - - Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( - "getVisibleChunkIfPresent", - "b" - ), long.class); - getVisibleChunkIfPresent.setAccessible(true); - methodGetVisibleChunk = lookup.unreflect(getVisibleChunkIfPresent); - - if (!PaperLib.isPaper()) { - fieldThreadingDetector = PalettedContainer.class.getDeclaredField(Refraction.pickName("threadingDetector", "f")); - fieldThreadingDetector.setAccessible(true); - fieldLock = ThreadingDetector.class.getDeclaredField(Refraction.pickName("lock", "c")); - fieldLock.setAccessible(true); - } else { - // in paper, the used methods are synchronized properly - fieldThreadingDetector = null; - fieldLock = null; - } - - Method removeGameEventListener = LevelChunk.class.getDeclaredMethod( - Refraction.pickName("removeGameEventListener", "a"), - BlockEntity.class, - ServerLevel.class - ); - removeGameEventListener.setAccessible(true); - methodRemoveGameEventListener = lookup.unreflect(removeGameEventListener); - - Method removeBlockEntityTicker = LevelChunk.class.getDeclaredMethod( - Refraction.pickName( - "removeBlockEntityTicker", - "l" - ), BlockPos.class - ); - removeBlockEntityTicker.setAccessible(true); - methodremoveTickingBlockEntity = lookup.unreflect(removeBlockEntityTicker); - - fieldRemove = BlockEntity.class.getDeclaredField(Refraction.pickName("remove", "q")); - fieldRemove.setAccessible(true); - - boolean chunkRewrite; - try { - ServerLevel.class.getDeclaredMethod("getEntityLookup"); - chunkRewrite = true; - PAPER_CHUNK_GEN_ALL_ENTITIES = ChunkEntitySlices.class.getDeclaredMethod("getAllEntities"); - PAPER_CHUNK_GEN_ALL_ENTITIES.setAccessible(true); - } catch (NoSuchMethodException ignored) { - chunkRewrite = false; - } - try { - // Paper - Pre-Chunk-Update - LEVEL_CHUNK_ENTITIES = LevelChunk.class.getDeclaredField("entities"); - LEVEL_CHUNK_ENTITIES.setAccessible(true); - } catch (NoSuchFieldException ignored) { - } - try { - // Non-Paper - SERVER_LEVEL_ENTITY_MANAGER = ServerLevel.class.getDeclaredField(Refraction.pickName("entityManager", "M")); - SERVER_LEVEL_ENTITY_MANAGER.setAccessible(true); - } catch (NoSuchFieldException ignored) { - } - POST_CHUNK_REWRITE = chunkRewrite; - - fieldOffers = AbstractVillager.class.getDeclaredField(Refraction.pickName("offers", "bU")); - fieldOffers.setAccessible(true); - } catch (RuntimeException | Error e) { - throw e; - } catch (Exception e) { - throw new RuntimeException(e); - } - MethodHandle craftChunkGetHandle; - final MethodType type = methodType(LevelChunk.class); - try { - craftChunkGetHandle = lookup.findVirtual(CraftChunk.class, "getHandle", type); - } catch (NoSuchMethodException | IllegalAccessException e) { - try { - final MethodType newType = methodType(ChunkAccess.class, ChunkStatus.class); - craftChunkGetHandle = lookup.findVirtual(CraftChunk.class, "getHandle", newType); - craftChunkGetHandle = MethodHandles.insertArguments(craftChunkGetHandle, 1, ChunkStatus.FULL); - } catch (NoSuchMethodException | IllegalAccessException ex) { - throw new RuntimeException(ex); - } - } - CRAFT_CHUNK_GET_HANDLE = craftChunkGetHandle; - } - - static boolean setSectionAtomic( - LevelChunkSection[] sections, - LevelChunkSection expected, - LevelChunkSection value, - int layer - ) { - if (layer >= 0 && layer < sections.length) { - return ReflectionUtils.compareAndSet(sections, expected, value, layer); - } - return false; - } - - // There is no point in having a functional semaphore for paper servers. - private static final ThreadLocal SEMAPHORE_THREAD_LOCAL = - ThreadLocal.withInitial(() -> new DelegateSemaphore(1, null)); - - static DelegateSemaphore applyLock(LevelChunkSection section) { - if (PaperLib.isPaper()) { - return SEMAPHORE_THREAD_LOCAL.get(); - } - try { - synchronized (section) { - PalettedContainer blocks = section.getStates(); - ThreadingDetector currentThreadingDetector = (ThreadingDetector) fieldThreadingDetector.get(blocks); - synchronized (currentThreadingDetector) { - Semaphore currentLock = (Semaphore) fieldLock.get(currentThreadingDetector); - if (currentLock instanceof DelegateSemaphore delegateSemaphore) { - return delegateSemaphore; - } - DelegateSemaphore newLock = new DelegateSemaphore(1, currentLock); - fieldLock.set(currentThreadingDetector, newLock); - return newLock; - } - } - } catch (Throwable e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - - public static LevelChunk ensureLoaded(ServerLevel serverLevel, int chunkX, int chunkZ) { - if (!PaperLib.isPaper()) { - LevelChunk nmsChunk = serverLevel.getChunkSource().getChunk(chunkX, chunkZ, false); - if (nmsChunk != null) { - return nmsChunk; - } - if (Fawe.isMainThread()) { - return serverLevel.getChunk(chunkX, chunkZ); - } - } else { - LevelChunk nmsChunk = serverLevel.getChunkSource().getChunkAtIfCachedImmediately(chunkX, chunkZ); - if (nmsChunk != null) { - addTicket(serverLevel, chunkX, chunkZ); - return nmsChunk; - } - nmsChunk = serverLevel.getChunkSource().getChunkAtIfLoadedImmediately(chunkX, chunkZ); - if (nmsChunk != null) { - addTicket(serverLevel, chunkX, chunkZ); - return nmsChunk; - } - // Avoid "async" methods from the main thread. - if (Fawe.isMainThread()) { - return serverLevel.getChunk(chunkX, chunkZ); - } - CompletableFuture future = serverLevel.getWorld().getChunkAtAsync(chunkX, chunkZ, true, true); - try { - CraftChunk chunk; - try { - chunk = (CraftChunk) future.get(10, TimeUnit.SECONDS); - } catch (TimeoutException e) { - String world = serverLevel.getWorld().getName(); - // We've already taken 10 seconds we can afford to wait a little here. - boolean loaded = TaskManager.taskManager().sync(() -> Bukkit.getWorld(world) != null); - if (loaded) { - LOGGER.warn("Chunk {},{} failed to load in 10 seconds in world {}. Retrying...", chunkX, chunkZ, world); - // Retry chunk load - chunk = (CraftChunk) serverLevel.getWorld().getChunkAtAsync(chunkX, chunkZ, true, true).get(); - } else { - throw new UnsupportedOperationException("Cannot load chunk from unloaded world " + world + "!"); - } - } - addTicket(serverLevel, chunkX, chunkZ); - return (LevelChunk) CRAFT_CHUNK_GET_HANDLE.invoke(chunk); - } catch (Throwable e) { - e.printStackTrace(); - } - } - return TaskManager.taskManager().sync(() -> serverLevel.getChunk(chunkX, chunkZ)); - } - - private static void addTicket(ServerLevel serverLevel, int chunkX, int chunkZ) { - // Ensure chunk is definitely loaded before applying a ticket - io.papermc.paper.util.MCUtil.MAIN_EXECUTOR.execute(() -> serverLevel - .getChunkSource() - .addRegionTicket(TicketType.UNLOAD_COOLDOWN, new ChunkPos(chunkX, chunkZ), 0, Unit.INSTANCE)); - } - - public static ChunkHolder getPlayerChunk(ServerLevel nmsWorld, final int chunkX, final int chunkZ) { - ChunkMap chunkMap = nmsWorld.getChunkSource().chunkMap; - try { - return (ChunkHolder) methodGetVisibleChunk.invoke(chunkMap, ChunkPos.asLong(chunkX, chunkZ)); - } catch (Throwable thr) { - throw new RuntimeException(thr); - } - } - - @SuppressWarnings("deprecation") - public static void sendChunk(Object chunk, ServerLevel nmsWorld, int chunkX, int chunkZ) { - ChunkHolder chunkHolder = getPlayerChunk(nmsWorld, chunkX, chunkZ); - if (chunkHolder == null) { - return; - } - ChunkPos coordIntPair = new ChunkPos(chunkX, chunkZ); - LevelChunk levelChunk; - if (PaperLib.isPaper()) { - // getChunkAtIfLoadedImmediately is paper only - levelChunk = nmsWorld - .getChunkSource() - .getChunkAtIfLoadedImmediately(chunkX, chunkZ); - } else { - levelChunk = ((Optional) ((Either) chunkHolder - .getTickingChunkFuture() // method is not present with new paper chunk system - .getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left()) - .orElse(null); - } - if (levelChunk == null) { - return; - } - MinecraftServer.getServer().execute(() -> { - ClientboundLevelChunkWithLightPacket packet; - if (PaperLib.isPaper()) { - synchronized (chunk) { - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null, - false // last false is to not bother with x-ray - ); - } - } else { - synchronized (chunk) { - // deprecated on paper - deprecation suppressed - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null - ); - } - } - nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet)); - }); - } - - private static List nearbyPlayers(ServerLevel serverLevel, ChunkPos coordIntPair) { - return serverLevel.getChunkSource().chunkMap.getPlayers(coordIntPair, false); - } - - /* - NMS conversion - */ - public static LevelChunkSection newChunkSection( - final int layer, - final char[] blocks, - CachedBukkitAdapter adapter, - Registry biomeRegistry, - @Nullable PalettedContainer> biomes - ) { - return newChunkSection(layer, null, blocks, adapter, biomeRegistry, biomes); - } - - public static LevelChunkSection newChunkSection( - final int layer, - final Function get, - char[] set, - CachedBukkitAdapter adapter, - Registry biomeRegistry, - @Nullable PalettedContainer> biomes - ) { - if (set == null) { - return newChunkSection(biomeRegistry, biomes); - } - final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get(); - final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); - final long[] blockStates = FaweCache.INSTANCE.BLOCK_STATES.get(); - final int[] blocksCopy = FaweCache.INSTANCE.SECTION_BLOCKS.get(); - try { - int num_palette; - if (get == null) { - num_palette = createPalette(blockToPalette, paletteToBlock, blocksCopy, set, adapter, null); - } else { - num_palette = createPalette(layer, blockToPalette, paletteToBlock, blocksCopy, get, set, adapter, null); - } - - int bitsPerEntry = MathMan.log2nlz(num_palette - 1); - if (bitsPerEntry > 0 && bitsPerEntry < 5) { - bitsPerEntry = 4; - } else if (bitsPerEntry > 8) { - bitsPerEntry = MathMan.log2nlz(Block.BLOCK_STATE_REGISTRY.size() - 1); - } - - int bitsPerEntryNonZero = Math.max(bitsPerEntry, 1); // We do want to use zero sometimes - final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntryNonZero); - final int blockBitArrayEnd = MathMan.ceilZero((float) 4096 / blocksPerLong); - - if (num_palette == 1) { - for (int i = 0; i < blockBitArrayEnd; i++) { - blockStates[i] = 0; - } - } else { - final BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntryNonZero, 4096, blockStates); - bitArray.fromRaw(blocksCopy); - } - - final long[] bits = Arrays.copyOfRange(blockStates, 0, blockBitArrayEnd); - final BitStorage nmsBits; - if (bitsPerEntry == 0) { - nmsBits = new ZeroBitStorage(4096); - } else { - nmsBits = new SimpleBitStorage(bitsPerEntry, 4096, bits); - } - List palette; - if (bitsPerEntry < 9) { - palette = new ArrayList<>(); - for (int i = 0; i < num_palette; i++) { - int ordinal = paletteToBlock[i]; - blockToPalette[ordinal] = Integer.MAX_VALUE; - final BlockState state = BlockTypesCache.states[ordinal]; - palette.add(((PaperweightBlockMaterial) state.getMaterial()).getState()); - } - } else { - palette = List.of(); - } - - // Create palette with data - @SuppressWarnings("deprecation") // constructor is deprecated on paper, but needed to keep compatibility with spigot - final PalettedContainer blockStatePalettedContainer = - new PalettedContainer<>( - Block.BLOCK_STATE_REGISTRY, - PalettedContainer.Strategy.SECTION_STATES, - PalettedContainer.Strategy.SECTION_STATES.getConfiguration(Block.BLOCK_STATE_REGISTRY, bitsPerEntry), - nmsBits, - palette - ); - if (biomes == null) { - IdMap> biomeHolderIdMap = biomeRegistry.asHolderIdMap(); - biomes = new PalettedContainer<>( - biomeHolderIdMap, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId( - BiomeTypes.PLAINS)), - PalettedContainer.Strategy.SECTION_BIOMES - ); - } - - return new LevelChunkSection(blockStatePalettedContainer, biomes); - } catch (final Throwable e) { - throw e; - } finally { - Arrays.fill(blockToPalette, Integer.MAX_VALUE); - Arrays.fill(paletteToBlock, Integer.MAX_VALUE); - Arrays.fill(blockStates, 0); - Arrays.fill(blocksCopy, 0); - } - } - - @SuppressWarnings("deprecation") // Only deprecated in paper - private static LevelChunkSection newChunkSection( - Registry biomeRegistry, - @Nullable PalettedContainer> biomes - ) { - if (biomes == null) { - return new LevelChunkSection(biomeRegistry); - } - PalettedContainer dataPaletteBlocks = new PalettedContainer<>( - Block.BLOCK_STATE_REGISTRY, - Blocks.AIR.defaultBlockState(), - PalettedContainer.Strategy.SECTION_STATES - ); - return new LevelChunkSection(dataPaletteBlocks, biomes); - } - - public static void setBiomesToChunkSection(LevelChunkSection section, PalettedContainer> biomes) { - try { - fieldBiomes.set(section, biomes); - } catch (IllegalAccessException e) { - LOGGER.error("Could not set biomes to chunk section", e); - } - } - - /** - * Create a new {@link PalettedContainer}. Should only be used if no biome container existed beforehand. - */ - public static PalettedContainer> getBiomePalettedContainer( - BiomeType[] biomes, - IdMap> biomeRegistry - ) { - if (biomes == null) { - return null; - } - BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); - // Don't stream this as typically will see 1-4 biomes; stream overhead is large for the small length - Map> palette = new HashMap<>(); - for (BiomeType biomeType : new LinkedList<>(Arrays.asList(biomes))) { - Holder biome; - if (biomeType == null) { - biome = biomeRegistry.byId(adapter.getInternalBiomeId(BiomeTypes.PLAINS)); - } else { - biome = biomeRegistry.byId(adapter.getInternalBiomeId(biomeType)); - } - palette.put(biomeType, biome); - } - int biomeCount = palette.size(); - int bitsPerEntry = MathMan.log2nlz(biomeCount - 1); - Object configuration = PalettedContainer.Strategy.SECTION_STATES.getConfiguration( - new FakeIdMapBiome(biomeCount), - bitsPerEntry - ); - if (bitsPerEntry > 3) { - bitsPerEntry = MathMan.log2nlz(biomeRegistry.size() - 1); - } - PalettedContainer> biomePalettedContainer = new PalettedContainer<>( - biomeRegistry, - biomeRegistry.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)), - PalettedContainer.Strategy.SECTION_BIOMES - ); - - final Palette> biomePalette; - if (bitsPerEntry == 0) { - biomePalette = new SingleValuePalette<>( - biomePalettedContainer.registry, - biomePalettedContainer, - new ArrayList<>(palette.values()) // Must be modifiable - ); - } else if (bitsPerEntry == 4) { - biomePalette = LinearPalette.create( - 4, - biomePalettedContainer.registry, - biomePalettedContainer, - new ArrayList<>(palette.values()) // Must be modifiable - ); - } else if (bitsPerEntry < 9) { - biomePalette = HashMapPalette.create( - bitsPerEntry, - biomePalettedContainer.registry, - biomePalettedContainer, - new ArrayList<>(palette.values()) // Must be modifiable - ); - } else { - biomePalette = GlobalPalette.create( - bitsPerEntry, - biomePalettedContainer.registry, - biomePalettedContainer, - null // unused - ); - } - - int bitsPerEntryNonZero = Math.max(bitsPerEntry, 1); // We do want to use zero sometimes - final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntryNonZero); - final int arrayLength = MathMan.ceilZero(64f / blocksPerLong); - - - BitStorage bitStorage = bitsPerEntry == 0 ? new ZeroBitStorage(64) : new SimpleBitStorage( - bitsPerEntry, - 64, - new long[arrayLength] - ); - - try { - Object data = dataConstructor.newInstance(configuration, bitStorage, biomePalette); - fieldData.set(biomePalettedContainer, data); - int index = 0; - for (int y = 0; y < 4; y++) { - for (int z = 0; z < 4; z++) { - for (int x = 0; x < 4; x++, index++) { - BiomeType biomeType = biomes[index]; - if (biomeType == null) { - continue; - } - Holder biome = biomeRegistry.byId(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId(biomeType)); - if (biome == null) { - continue; - } - biomePalettedContainer.set(x, y, z, biome); - } - } - } - } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - return biomePalettedContainer; - } - - public static void clearCounts(final LevelChunkSection section) throws IllegalAccessException { - fieldTickingFluidCount.setShort(section, (short) 0); - fieldTickingBlockCount.setShort(section, (short) 0); - } - - public static BiomeType adapt(Holder biome, LevelAccessor levelAccessor) { - final Registry biomeRegistry = levelAccessor.registryAccess().registryOrThrow(BIOME); - if (biomeRegistry.getKey(biome.value()) == null) { - return biomeRegistry.asHolderIdMap().getId(biome) == -1 ? BiomeTypes.OCEAN - : null; - } - return BiomeTypes.get(biome.unwrapKey().orElseThrow().location().toString()); - } - - static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) { - try { - if (levelChunk.loaded || levelChunk.level.isClientSide()) { - BlockEntity blockEntity = levelChunk.blockEntities.remove(beacon.getBlockPos()); - if (blockEntity != null) { - if (!levelChunk.level.isClientSide) { - methodRemoveGameEventListener.invoke(levelChunk, beacon, levelChunk.level); - } - fieldRemove.set(beacon, true); - } - } - methodremoveTickingBlockEntity.invoke(levelChunk, beacon.getBlockPos()); - } catch (Throwable throwable) { - throwable.printStackTrace(); - } - } - - static List getEntities(LevelChunk chunk) { - ExceptionCollector collector = new ExceptionCollector<>(); - if (PaperLib.isPaper()) { - if (POST_CHUNK_REWRITE) { - try { - //noinspection unchecked - return (List) PAPER_CHUNK_GEN_ALL_ENTITIES.invoke(chunk.level.getEntityLookup().getChunk(chunk.locX, chunk.locZ)); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException("Failed to lookup entities [POST_CHUNK_REWRITE=true]", e); - } - } - try { - EntityList entityList = (EntityList) LEVEL_CHUNK_ENTITIES.get(chunk); - return List.of(entityList.getRawData()); - } catch (IllegalAccessException e) { - collector.add(new RuntimeException("Failed to lookup entities [POST_CHUNK_REWRITE=false]", e)); - // fall through - } - } - try { - //noinspection unchecked - return ((PersistentEntitySectionManager) (SERVER_LEVEL_ENTITY_MANAGER.get(chunk.level))).getEntities(chunk.getPos()); - } catch (IllegalAccessException e) { - collector.add(new RuntimeException("Failed to lookup entities [PAPER=false]", e)); - } - collector.throwIfPresent(); - return List.of(); - } - - public static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag compoundTag) { - boolean unset = false; - if (entity instanceof Villager villager && !Fawe.isMainThread()) { - try { - if (fieldOffers.get(entity) == null) { - villager.setOffers(OFFERS); - unset = true; - } - } catch (IllegalAccessException e) { - throw new RuntimeException("Failed to set offers field to villager to avoid async catcher.", e); - } - } - entity.save(compoundTag); - if (unset) { - ((Villager) entity).setOffers(null); - } - } - - record FakeIdMapBlock(int size) implements IdMap { - - @Override - public int getId(final net.minecraft.world.level.block.state.BlockState entry) { - return 0; - } - - @Nullable - @Override - public net.minecraft.world.level.block.state.BlockState byId(final int index) { - return null; - } - - @Nonnull - @Override - public Iterator iterator() { - return Collections.emptyIterator(); - } - - } - - record FakeIdMapBiome(int size) implements IdMap { - - @Override - public int getId(final Biome entry) { - return 0; - } - - @Nullable - @Override - public Biome byId(final int index) { - return null; - } - - @Nonnull - @Override - public Iterator iterator() { - return Collections.emptyIterator(); - } - - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPostProcessor.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPostProcessor.java deleted file mode 100644 index 0c4bcff85..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPostProcessor.java +++ /dev/null @@ -1,175 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1; - -import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.extent.processor.ProcessorScope; -import com.fastasyncworldedit.core.queue.IBatchProcessor; -import com.fastasyncworldedit.core.queue.IChunk; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.queue.IChunkSet; -import com.fastasyncworldedit.core.registry.state.PropertyKey; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockTypes; -import com.sk89q.worldedit.world.block.BlockTypesCache; -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.material.Fluid; -import net.minecraft.world.level.material.Fluids; - -import javax.annotation.Nullable; - -public class PaperweightPostProcessor implements IBatchProcessor { - - @Override - public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChunkSet set) { - return set; - } - - @SuppressWarnings("deprecation") - @Override - public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final IChunkSet iChunkSet) { - boolean tickFluid = Settings.settings().EXPERIMENTAL.ALLOW_TICK_FLUIDS; - // The PostProcessor shouldn't be added, but just in case - if (!tickFluid) { - return; - } - PaperweightGetBlocks_Copy getBlocks = (PaperweightGetBlocks_Copy) iChunkGet; - layer: - for (int layer = iChunkSet.getMinSectionPosition(); layer <= iChunkSet.getMaxSectionPosition(); layer++) { - char[] set = iChunkSet.loadIfPresent(layer); - if (set == null) { - // No edit means no need to process - continue; - } - char[] get = null; - for (int i = 0; i < 4096; i++) { - char ordinal = set[i]; - char replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; - boolean fromGet = false; // Used for liquids - if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { - if (get == null) { - get = getBlocks.load(layer); - } - // If this is null, then it's because we're loading a layer in the range of 0->15, but blocks aren't - // actually being set - if (get == null) { - continue layer; - } - fromGet = true; - ordinal = replacedOrdinal = get[i]; - } - if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { - continue; - } else if (!fromGet) { // if fromGet, don't do the same again - if (get == null) { - get = getBlocks.load(layer); - } - replacedOrdinal = get[i]; - } - boolean ticking = BlockTypesCache.ticking[ordinal]; - boolean replacedWasTicking = BlockTypesCache.ticking[replacedOrdinal]; - boolean replacedWasLiquid = false; - BlockState replacedState = null; - if (!ticking) { - // If the block being replaced was not ticking, it cannot be a liquid - if (!replacedWasTicking) { - continue; - } - // If the block being replaced is not fluid, we do not need to worry - if (!(replacedWasLiquid = - (replacedState = BlockState.getFromOrdinal(replacedOrdinal)).getMaterial().isLiquid())) { - continue; - } - } - BlockState state = BlockState.getFromOrdinal(ordinal); - boolean liquid = state.getMaterial().isLiquid(); - int x = i & 15; - int y = (i >> 8) & 15; - int z = (i >> 4) & 15; - BlockPos position = new BlockPos((chunk.getX() << 4) + x, (layer << 4) + y, (chunk.getZ() << 4) + z); - if (liquid || replacedWasLiquid) { - if (liquid) { - addFluid(getBlocks.serverLevel, state, position); - continue; - } - // If the replaced fluid (is?) adjacent to water. Do not bother to check adjacent chunks(sections) as this - // may be time consuming. Chances are any fluid blocks in adjacent chunks are being replaced or will end up - // being ticked anyway. We only need it to be "hit" once. - if (!wasAdjacentToWater(get, set, i, x, y, z)) { - continue; - } - addFluid(getBlocks.serverLevel, replacedState, position); - } - } - } - } - - @Nullable - @Override - public Extent construct(final Extent child) { - throw new UnsupportedOperationException("Processing only"); - } - - @Override - public ProcessorScope getScope() { - return ProcessorScope.READING_SET_BLOCKS; - } - - private boolean wasAdjacentToWater(char[] get, char[] set, int i, int x, int y, int z) { - if (set == null || get == null) { - return false; - } - char ordinal; - char reserved = BlockTypesCache.ReservedIDs.__RESERVED__; - if (x > 0 && set[i - 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 1])] && isFluid(ordinal)) { - return true; - } - } - if (x < 15 && set[i + 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 1])] && isFluid(ordinal)) { - return true; - } - } - if (z > 0 && set[i - 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 16])] && isFluid(ordinal)) { - return true; - } - } - if (z < 15 && set[i + 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 16])] && isFluid(ordinal)) { - return true; - } - } - if (y > 0 && set[i - 256] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 256])] && isFluid(ordinal)) { - return true; - } - } - if (y < 15 && set[i + 256] != reserved) { - return BlockTypesCache.ticking[(ordinal = get[i + 256])] && isFluid(ordinal); - } - return false; - } - - @SuppressWarnings("deprecation") - private boolean isFluid(char ordinal) { - return BlockState.getFromOrdinal(ordinal).getMaterial().isLiquid(); - } - - @SuppressWarnings("deprecation") - private void addFluid(final ServerLevel serverLevel, final BlockState replacedState, final BlockPos position) { - Fluid type; - if (replacedState.getBlockType() == BlockTypes.LAVA) { - type = (int) replacedState.getState(PropertyKey.LEVEL) == 0 ? Fluids.LAVA : Fluids.FLOWING_LAVA; - } else { - type = (int) replacedState.getState(PropertyKey.LEVEL) == 0 ? Fluids.WATER : Fluids.FLOWING_WATER; - } - serverLevel.scheduleTick( - position, - type, - type.getTickDelay(serverLevel) - ); - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightStarlightRelighter.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightStarlightRelighter.java deleted file mode 100644 index 7de83af21..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightStarlightRelighter.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1; - -import com.fastasyncworldedit.bukkit.adapter.StarlightRelighter; -import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.queue.IQueueExtent; -import net.minecraft.server.level.ChunkMap; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.TicketType; -import net.minecraft.util.Unit; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.chunk.ChunkStatus; - -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.function.Consumer; -import java.util.function.IntConsumer; - -public class PaperweightStarlightRelighter extends StarlightRelighter { - - private static final TicketType FAWE_TICKET = TicketType.create("fawe_ticket", (a, b) -> 0); - private static final int LIGHT_LEVEL = ChunkMap.MAX_VIEW_DISTANCE + ChunkStatus.getDistance(ChunkStatus.LIGHT); - - public PaperweightStarlightRelighter(ServerLevel serverLevel, IQueueExtent queue) { - super(serverLevel, queue); - } - - @Override - protected ChunkPos createChunkPos(final long chunkKey) { - return new ChunkPos(chunkKey); - } - - @Override - protected long asLong(final int chunkX, final int chunkZ) { - return ChunkPos.asLong(chunkX, chunkZ); - } - - @Override - protected CompletableFuture chunkLoadFuture(final ChunkPos chunkPos) { - return serverLevel.getWorld().getChunkAtAsync(chunkPos.x, chunkPos.z) - .thenAccept(c -> serverLevel.getChunkSource().addTicketAtLevel( - FAWE_TICKET, - chunkPos, - LIGHT_LEVEL, - Unit.INSTANCE - )); - } - - protected void invokeRelight( - Set coords, - Consumer chunkCallback, - IntConsumer processCallback - ) { - try { - serverLevel.getChunkSource().getLightEngine().relight(coords, chunkCallback, processCallback); - } catch (Exception e) { - LOGGER.error("Error occurred on relighting", e); - } - } - - /* - * Allow the server to unload the chunks again. - * Also, if chunk packets are sent delayed, we need to do that here - */ - protected void postProcessChunks(Set coords) { - boolean delay = Settings.settings().LIGHTING.DELAY_PACKET_SENDING; - for (ChunkPos pos : coords) { - int x = pos.x; - int z = pos.z; - if (delay) { // we still need to send the block changes of that chunk - PaperweightPlatformAdapter.sendChunk(pos, serverLevel, x, z); - } - serverLevel.getChunkSource().removeTicketAtLevel(FAWE_TICKET, pos, LIGHT_LEVEL, Unit.INSTANCE); - } - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightStarlightRelighterFactory.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightStarlightRelighterFactory.java deleted file mode 100644 index 83509a2bb..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightStarlightRelighterFactory.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1; - -import com.fastasyncworldedit.core.extent.processor.lighting.NullRelighter; -import com.fastasyncworldedit.core.extent.processor.lighting.RelightMode; -import com.fastasyncworldedit.core.extent.processor.lighting.Relighter; -import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory; -import com.fastasyncworldedit.core.queue.IQueueExtent; -import com.sk89q.worldedit.world.World; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_20_R1.CraftWorld; - -import javax.annotation.Nonnull; - -public class PaperweightStarlightRelighterFactory implements RelighterFactory { - - @Override - public @Nonnull Relighter createRelighter(RelightMode relightMode, World world, IQueueExtent queue) { - org.bukkit.World w = Bukkit.getWorld(world.getName()); - if (w == null) { - return NullRelighter.INSTANCE; - } - return new PaperweightStarlightRelighter(((CraftWorld) w).getHandle(), queue); - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/nbt/PaperweightLazyCompoundTag.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/nbt/PaperweightLazyCompoundTag.java deleted file mode 100644 index f2a694a2f..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/nbt/PaperweightLazyCompoundTag.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1.nbt; - -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.LazyCompoundTag; -import com.sk89q.jnbt.ListTag; -import com.sk89q.jnbt.StringTag; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import net.minecraft.nbt.NumericTag; -import org.enginehub.linbus.tree.LinCompoundTag; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Supplier; - -public class PaperweightLazyCompoundTag extends LazyCompoundTag { - - private final Supplier compoundTagSupplier; - private CompoundTag compoundTag; - - public PaperweightLazyCompoundTag(Supplier compoundTagSupplier) { - super(new HashMap<>()); - this.compoundTagSupplier = compoundTagSupplier; - } - - public PaperweightLazyCompoundTag(net.minecraft.nbt.CompoundTag compoundTag) { - this(() -> compoundTag); - } - - public net.minecraft.nbt.CompoundTag get() { - return compoundTagSupplier.get(); - } - - @Override - @SuppressWarnings("unchecked") - public Map> getValue() { - if (compoundTag == null) { - compoundTag = (CompoundTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(compoundTagSupplier.get()); - } - return compoundTag.getValue(); - } - - @Override - public LinCompoundTag toLinTag() { - getValue(); - return compoundTag.toLinTag(); - } - - public boolean containsKey(String key) { - return compoundTagSupplier.get().contains(key); - } - - public byte[] getByteArray(String key) { - return compoundTagSupplier.get().getByteArray(key); - } - - public byte getByte(String key) { - return compoundTagSupplier.get().getByte(key); - } - - public double getDouble(String key) { - return compoundTagSupplier.get().getDouble(key); - } - - public double asDouble(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof NumericTag numTag) { - return numTag.getAsDouble(); - } - return 0; - } - - public float getFloat(String key) { - return compoundTagSupplier.get().getFloat(key); - } - - public int[] getIntArray(String key) { - return compoundTagSupplier.get().getIntArray(key); - } - - public int getInt(String key) { - return compoundTagSupplier.get().getInt(key); - } - - public int asInt(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof NumericTag numTag) { - return numTag.getAsInt(); - } - return 0; - } - - @SuppressWarnings("unchecked") - public List> getList(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof net.minecraft.nbt.ListTag nbtList) { - ArrayList> list = new ArrayList<>(); - for (net.minecraft.nbt.Tag elem : nbtList) { - if (elem instanceof net.minecraft.nbt.CompoundTag compoundTag) { - list.add(new PaperweightLazyCompoundTag(compoundTag)); - } else { - list.add(WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(elem)); - } - } - return list; - } - return Collections.emptyList(); - } - - @SuppressWarnings("unchecked") - public ListTag getListTag(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof net.minecraft.nbt.ListTag) { - return (ListTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(tag); - } - return new ListTag(StringTag.class, Collections.emptyList()); - } - - @SuppressWarnings("unchecked") - public > List getList(String key, Class listType) { - ListTag listTag = getListTag(key); - if (listTag.getType().equals(listType)) { - return (List) listTag.getValue(); - } else { - return Collections.emptyList(); - } - } - - public long[] getLongArray(String key) { - return compoundTagSupplier.get().getLongArray(key); - } - - public long getLong(String key) { - return compoundTagSupplier.get().getLong(key); - } - - public long asLong(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof NumericTag numTag) { - return numTag.getAsLong(); - } - return 0; - } - - public short getShort(String key) { - return compoundTagSupplier.get().getShort(key); - } - - public String getString(String key) { - return compoundTagSupplier.get().getString(key); - } - - @Override - public String toString() { - return compoundTagSupplier.get().toString(); - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/regen/PaperweightRegen.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/regen/PaperweightRegen.java deleted file mode 100644 index 99e001837..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/regen/PaperweightRegen.java +++ /dev/null @@ -1,591 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1.regen; - -import com.fastasyncworldedit.bukkit.adapter.Regenerator; -import com.fastasyncworldedit.core.Fawe; -import com.fastasyncworldedit.core.queue.IChunkCache; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.util.ReflectionUtils; -import com.fastasyncworldedit.core.util.TaskManager; -import com.google.common.collect.ImmutableList; -import com.mojang.datafixers.util.Either; -import com.mojang.serialization.Lifecycle; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1.PaperweightGetBlocks; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.util.io.file.SafeFiles; -import com.sk89q.worldedit.world.RegenOptions; -import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.core.registries.Registries; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.dedicated.DedicatedServer; -import net.minecraft.server.level.ChunkMap; -import net.minecraft.server.level.ChunkTaskPriorityQueueSorter.Message; -import net.minecraft.server.level.ServerChunkCache; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ThreadedLevelLightEngine; -import net.minecraft.server.level.progress.ChunkProgressListener; -import net.minecraft.util.thread.ProcessorHandle; -import net.minecraft.util.thread.ProcessorMailbox; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelHeightAccessor; -import net.minecraft.world.level.LevelSettings; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.biome.FixedBiomeSource; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.chunk.ChunkGeneratorStructureState; -import net.minecraft.world.level.chunk.ChunkStatus; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.ProtoChunk; -import net.minecraft.world.level.chunk.UpgradeData; -import net.minecraft.world.level.dimension.LevelStem; -import net.minecraft.world.level.levelgen.FlatLevelSource; -import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; -import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; -import net.minecraft.world.level.levelgen.WorldOptions; -import net.minecraft.world.level.levelgen.blending.BlendingData; -import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings; -import net.minecraft.world.level.levelgen.structure.placement.ConcentricRingsStructurePlacement; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager; -import net.minecraft.world.level.storage.LevelStorageSource; -import net.minecraft.world.level.storage.PrimaryLevelData; -import org.apache.logging.log4j.Logger; -import org.bukkit.Bukkit; -import org.bukkit.Chunk; -import org.bukkit.craftbukkit.v1_20_R1.CraftServer; -import org.bukkit.craftbukkit.v1_20_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_20_R1.generator.CustomChunkGenerator; -import org.bukkit.generator.BiomeProvider; -import org.bukkit.generator.BlockPopulator; - -import javax.annotation.Nullable; -import java.lang.reflect.Field; -import java.nio.file.Path; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.OptionalLong; -import java.util.Random; -import java.util.concurrent.CompletableFuture; -import java.util.function.BooleanSupplier; -import java.util.function.Supplier; - -import static net.minecraft.core.registries.Registries.BIOME; - -public class PaperweightRegen extends Regenerator { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - - private static final Field serverWorldsField; - private static final Field paperConfigField; - private static final Field flatBedrockField; - private static final Field generatorSettingFlatField; - private static final Field generatorSettingBaseSupplierField; - private static final Field delegateField; - private static final Field chunkSourceField; - private static final Field generatorStructureStateField; - private static final Field ringPositionsField; - private static final Field hasGeneratedPositionsField; - - //list of chunk stati in correct order without FULL - private static final Map chunkStati = new LinkedHashMap<>(); - - static { - chunkStati.put(ChunkStatus.EMPTY, Concurrency.FULL); // empty: radius -1, does nothing - chunkStati.put(ChunkStatus.STRUCTURE_STARTS, Concurrency.NONE); // structure starts: uses unsynchronized maps - chunkStati.put( - ChunkStatus.STRUCTURE_REFERENCES, - Concurrency.FULL - ); // structure refs: radius 8, but only writes to current chunk - chunkStati.put(ChunkStatus.BIOMES, Concurrency.FULL); // biomes: radius 0 - chunkStati.put(ChunkStatus.NOISE, Concurrency.RADIUS); // noise: radius 8 - chunkStati.put(ChunkStatus.SURFACE, Concurrency.NONE); // surface: radius 0, requires NONE - chunkStati.put(ChunkStatus.CARVERS, Concurrency.NONE); // carvers: radius 0, but RADIUS and FULL change results - /*chunkStati.put( - ChunkStatus.LIQUID_CARVERS, - Concurrency.NONE - ); // liquid carvers: radius 0, but RADIUS and FULL change results*/ - chunkStati.put(ChunkStatus.FEATURES, Concurrency.NONE); // features: uses unsynchronized maps - chunkStati.put( - ChunkStatus.LIGHT, - Concurrency.FULL - ); // light: radius 1, but no writes to other chunks, only current chunk - chunkStati.put(ChunkStatus.SPAWN, Concurrency.FULL); // spawn: radius 0 - // chunkStati.put(ChunkStatus.HEIGHTMAPS, Concurrency.FULL); // heightmaps: radius 0 - - try { - serverWorldsField = CraftServer.class.getDeclaredField("worlds"); - serverWorldsField.setAccessible(true); - - Field tmpPaperConfigField; - Field tmpFlatBedrockField; - try { //only present on paper - tmpPaperConfigField = Level.class.getDeclaredField("paperConfig"); - tmpPaperConfigField.setAccessible(true); - - tmpFlatBedrockField = tmpPaperConfigField.getType().getDeclaredField("generateFlatBedrock"); - tmpFlatBedrockField.setAccessible(true); - } catch (Exception e) { - tmpPaperConfigField = null; - tmpFlatBedrockField = null; - } - paperConfigField = tmpPaperConfigField; - flatBedrockField = tmpFlatBedrockField; - - generatorSettingBaseSupplierField = NoiseBasedChunkGenerator.class.getDeclaredField(Refraction.pickName( - "settings", "e")); - generatorSettingBaseSupplierField.setAccessible(true); - - generatorSettingFlatField = FlatLevelSource.class.getDeclaredField(Refraction.pickName("settings", "d")); - generatorSettingFlatField.setAccessible(true); - - delegateField = CustomChunkGenerator.class.getDeclaredField("delegate"); - delegateField.setAccessible(true); - - chunkSourceField = ServerLevel.class.getDeclaredField(Refraction.pickName("chunkSource", "I")); - chunkSourceField.setAccessible(true); - - generatorStructureStateField = ChunkMap.class.getDeclaredField(Refraction.pickName("chunkGeneratorState", "v")); - generatorStructureStateField.setAccessible(true); - - ringPositionsField = ChunkGeneratorStructureState.class.getDeclaredField(Refraction.pickName("ringPositions", "g")); - ringPositionsField.setAccessible(true); - - hasGeneratedPositionsField = ChunkGeneratorStructureState.class.getDeclaredField( - Refraction.pickName("hasGeneratedPositions", "h") - ); - hasGeneratedPositionsField.setAccessible(true); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - //runtime - private ServerLevel originalServerWorld; - private ServerChunkCache originalChunkProvider; - private ServerLevel freshWorld; - private ServerChunkCache freshChunkProvider; - private LevelStorageSource.LevelStorageAccess session; - private StructureTemplateManager structureTemplateManager; - private ThreadedLevelLightEngine threadedLevelLightEngine; - private ChunkGenerator chunkGenerator; - - private Path tempDir; - - private boolean generateFlatBedrock = false; - - public PaperweightRegen(org.bukkit.World originalBukkitWorld, Region region, Extent target, RegenOptions options) { - super(originalBukkitWorld, region, target, options); - } - - @Override - protected boolean prepare() { - this.originalServerWorld = ((CraftWorld) originalBukkitWorld).getHandle(); - originalChunkProvider = originalServerWorld.getChunkSource(); - - //flat bedrock? (only on paper) - if (paperConfigField != null) { - try { - generateFlatBedrock = flatBedrockField.getBoolean(paperConfigField.get(originalServerWorld)); - } catch (Exception ignored) { - } - } - - seed = options.getSeed().orElse(originalServerWorld.getSeed()); - chunkStati.forEach((s, c) -> super.chunkStatuses.put(new ChunkStatusWrap(s), c)); - - return true; - } - - @Override - @SuppressWarnings("unchecked") - protected boolean initNewWorld() throws Exception { - //world folder - tempDir = java.nio.file.Files.createTempDirectory("FastAsyncWorldEditWorldGen"); - - //prepare for world init (see upstream implementation for reference) - org.bukkit.World.Environment environment = originalBukkitWorld.getEnvironment(); - org.bukkit.generator.ChunkGenerator generator = originalBukkitWorld.getGenerator(); - LevelStorageSource levelStorageSource = LevelStorageSource.createDefault(tempDir); - ResourceKey levelStemResourceKey = getWorldDimKey(environment); - session = levelStorageSource.createAccess("faweregentempworld", levelStemResourceKey); - PrimaryLevelData originalWorldData = originalServerWorld.serverLevelData; - - MinecraftServer server = originalServerWorld.getCraftServer().getServer(); - WorldOptions originalOpts = originalWorldData.worldGenOptions(); - WorldOptions newOpts = options.getSeed().isPresent() - ? originalOpts.withSeed(OptionalLong.of(seed)) - : originalOpts; - LevelSettings newWorldSettings = new LevelSettings( - "faweregentempworld", - originalWorldData.settings.gameType(), - originalWorldData.settings.hardcore(), - originalWorldData.settings.difficulty(), - originalWorldData.settings.allowCommands(), - originalWorldData.settings.gameRules(), - originalWorldData.settings.getDataConfiguration() - ); - - PrimaryLevelData.SpecialWorldProperty specialWorldProperty = - originalWorldData.isFlatWorld() - ? PrimaryLevelData.SpecialWorldProperty.FLAT - : originalWorldData.isDebugWorld() - ? PrimaryLevelData.SpecialWorldProperty.DEBUG - : PrimaryLevelData.SpecialWorldProperty.NONE; - PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, specialWorldProperty, Lifecycle.stable()); - - BiomeProvider biomeProvider = getBiomeProvider(); - - - //init world - freshWorld = Fawe.instance().getQueueHandler().sync((Supplier) () -> new ServerLevel( - server, - server.executor, - session, - newWorldData, - originalServerWorld.dimension(), - DedicatedServer.getServer().registryAccess().registry(Registries.LEVEL_STEM).orElseThrow() - .getOrThrow(levelStemResourceKey), - new RegenNoOpWorldLoadListener(), - originalServerWorld.isDebug(), - seed, - ImmutableList.of(), - false, - originalServerWorld.getRandomSequences(), - environment, - generator, - biomeProvider - ) { - - private final Holder singleBiome = options.hasBiomeType() ? DedicatedServer.getServer().registryAccess() - .registryOrThrow(BIOME).asHolderIdMap().byIdOrThrow( - WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType()) - ) : null; - - @Override - public void tick(BooleanSupplier shouldKeepTicking) { //no ticking - } - - @Override - public Holder getUncachedNoiseBiome(int biomeX, int biomeY, int biomeZ) { - if (options.hasBiomeType()) { - return singleBiome; - } - return PaperweightRegen.this.chunkGenerator.getBiomeSource().getNoiseBiome( - biomeX, biomeY, biomeZ, getChunkSource().randomState().sampler() - ); - } - }).get(); - freshWorld.noSave = true; - removeWorldFromWorldsMap(); - newWorldData.checkName(originalServerWorld.serverLevelData.getLevelName()); //rename to original world name - if (paperConfigField != null) { - paperConfigField.set(freshWorld, originalServerWorld.paperConfig()); - } - - ChunkGenerator originalGenerator = originalChunkProvider.getGenerator(); - if (originalGenerator instanceof FlatLevelSource flatLevelSource) { - FlatLevelGeneratorSettings generatorSettingFlat = flatLevelSource.settings(); - chunkGenerator = new FlatLevelSource(generatorSettingFlat); - } else if (originalGenerator instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) { - Holder generatorSettingBaseSupplier = (Holder) generatorSettingBaseSupplierField.get( - originalGenerator); - BiomeSource biomeSource; - if (options.hasBiomeType()) { - - biomeSource = new FixedBiomeSource( - DedicatedServer.getServer().registryAccess() - .registryOrThrow(BIOME).asHolderIdMap().byIdOrThrow( - WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType()) - ) - ); - } else { - biomeSource = originalGenerator.getBiomeSource(); - } - chunkGenerator = new NoiseBasedChunkGenerator( - biomeSource, - generatorSettingBaseSupplier - ); - } else if (originalGenerator instanceof CustomChunkGenerator customChunkGenerator) { - chunkGenerator = customChunkGenerator.getDelegate(); - } else { - LOGGER.error("Unsupported generator type {}", originalGenerator.getClass().getName()); - return false; - } - if (generator != null) { - chunkGenerator = new CustomChunkGenerator(freshWorld, chunkGenerator, generator); - generateConcurrent = generator.isParallelCapable(); - } -// chunkGenerator.conf = freshWorld.spigotConfig; - Does not exist anymore, may need to be re-addressed - - freshChunkProvider = new ServerChunkCache( - freshWorld, - session, - server.getFixerUpper(), - server.getStructureManager(), - server.executor, - chunkGenerator, - freshWorld.spigotConfig.viewDistance, - freshWorld.spigotConfig.simulationDistance, - server.forceSynchronousWrites(), - new RegenNoOpWorldLoadListener(), - (chunkCoordIntPair, state) -> { - }, - () -> server.overworld().getDataStorage() - ) { - // redirect to LevelChunks created in #createChunks - @Override - public ChunkAccess getChunk(int x, int z, ChunkStatus chunkstatus, boolean create) { - ChunkAccess chunkAccess = getChunkAt(x, z); - if (chunkAccess == null && create) { - chunkAccess = createChunk(getProtoChunkAt(x, z)); - } - return chunkAccess; - } - }; - - if (seed == originalOpts.seed() && !options.hasBiomeType()) { - // Optimisation for needless ring position calculation when the seed and biome is the same. - ChunkGeneratorStructureState state = (ChunkGeneratorStructureState) generatorStructureStateField.get(originalChunkProvider.chunkMap); - boolean hasGeneratedPositions = hasGeneratedPositionsField.getBoolean(state); - if (hasGeneratedPositions) { - Map>> origPositions = - (Map>>) ringPositionsField.get(state); - Map>> copy = new Object2ObjectArrayMap<>( - origPositions); - ChunkGeneratorStructureState newState = (ChunkGeneratorStructureState) generatorStructureStateField.get(freshChunkProvider.chunkMap); - ringPositionsField.set(newState, copy); - hasGeneratedPositionsField.setBoolean(newState, true); - } - } - - - chunkSourceField.set(freshWorld, freshChunkProvider); - //let's start then - structureTemplateManager = server.getStructureManager(); - threadedLevelLightEngine = new NoOpLightEngine(freshChunkProvider); - - return true; - } - - @Override - protected void cleanup() { - try { - session.close(); - } catch (Exception ignored) { - } - - //shutdown chunk provider - try { - Fawe.instance().getQueueHandler().sync(() -> { - try { - freshChunkProvider.close(false); - } catch (Exception e) { - throw new RuntimeException(e); - } - }); - } catch (Exception ignored) { - } - - //remove world from server - try { - Fawe.instance().getQueueHandler().sync(this::removeWorldFromWorldsMap); - } catch (Exception ignored) { - } - - //delete directory - try { - SafeFiles.tryHardToDeleteDir(tempDir); - } catch (Exception ignored) { - } - } - - @Override - protected ProtoChunk createProtoChunk(int x, int z) { - return new FastProtoChunk(new ChunkPos(x, z), UpgradeData.EMPTY, freshWorld, - this.freshWorld.registryAccess().registryOrThrow(BIOME), null - ); - } - - @Override - protected LevelChunk createChunk(ProtoChunk protoChunk) { - return new LevelChunk( - freshWorld, - protoChunk, - null // we don't want to add entities - ); - } - - @Override - protected ChunkStatusWrap getFullChunkStatus() { - return new ChunkStatusWrap(ChunkStatus.FULL); - } - - @Override - protected List getBlockPopulators() { - return originalServerWorld.getWorld().getPopulators(); - } - - @Override - protected void populate(LevelChunk levelChunk, Random random, BlockPopulator blockPopulator) { - // BlockPopulator#populate has to be called synchronously for TileEntity access - TaskManager.taskManager().task(() -> { - final CraftWorld world = freshWorld.getWorld(); - final Chunk chunk = world.getChunkAt(levelChunk.locX, levelChunk.locZ); - blockPopulator.populate(world, random, chunk); - }); - } - - @Override - protected IChunkCache initSourceQueueCache() { - return (chunkX, chunkZ) -> new PaperweightGetBlocks(freshWorld, chunkX, chunkZ) { - @Override - public LevelChunk ensureLoaded(ServerLevel nmsWorld, int x, int z) { - return getChunkAt(x, z); - } - }; - } - - //util - @SuppressWarnings("unchecked") - private void removeWorldFromWorldsMap() { - Fawe.instance().getQueueHandler().sync(() -> { - try { - Map map = (Map) serverWorldsField.get(Bukkit.getServer()); - map.remove("faweregentempworld"); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - }); - } - - private ResourceKey getWorldDimKey(org.bukkit.World.Environment env) { - return switch (env) { - case NETHER -> LevelStem.NETHER; - case THE_END -> LevelStem.END; - default -> LevelStem.OVERWORLD; - }; - } - - private static class RegenNoOpWorldLoadListener implements ChunkProgressListener { - - private RegenNoOpWorldLoadListener() { - } - - @Override - public void updateSpawnPos(ChunkPos spawnPos) { - } - - @Override - public void onStatusChange(ChunkPos pos, @Nullable ChunkStatus status) { - } - - @Override - public void start() { - - } - - @Override - public void stop() { - } - - // TODO Paper only(?) @Override - public void setChunkRadius(int radius) { - } - - } - - private class FastProtoChunk extends ProtoChunk { - - public FastProtoChunk( - final ChunkPos pos, - final UpgradeData upgradeData, - final LevelHeightAccessor world, - final Registry biomeRegistry, - @Nullable final BlendingData blendingData - ) { - super(pos, upgradeData, world, biomeRegistry, blendingData); - } - - // avoid warning on paper - - // compatibility with spigot - - public boolean generateFlatBedrock() { - return generateFlatBedrock; - } - - // no one will ever see the entities! - @Override - public List getEntities() { - return Collections.emptyList(); - } - - } - - protected class ChunkStatusWrap extends ChunkStatusWrapper { - - private final ChunkStatus chunkStatus; - - public ChunkStatusWrap(ChunkStatus chunkStatus) { - this.chunkStatus = chunkStatus; - } - - @Override - public int requiredNeighborChunkRadius() { - return chunkStatus.getRange(); - } - - @Override - public String name() { - return chunkStatus.toString(); - } - - @Override - public CompletableFuture processChunk(List accessibleChunks) { - return chunkStatus.generate( - Runnable::run, // TODO revisit, we might profit from this somehow? - freshWorld, - chunkGenerator, - structureTemplateManager, - threadedLevelLightEngine, - c -> CompletableFuture.completedFuture(Either.left(c)), - accessibleChunks - ); - } - - } - - /** - * A light engine that does nothing. As light is calculated after pasting anyway, we can avoid - * work this way. - */ - static class NoOpLightEngine extends ThreadedLevelLightEngine { - - private static final ProcessorMailbox MAILBOX = ProcessorMailbox.create(task -> { - }, "fawe-no-op"); - private static final ProcessorHandle> HANDLE = ProcessorHandle.of("fawe-no-op", m -> { - }); - - public NoOpLightEngine(final ServerChunkCache chunkProvider) { - super(chunkProvider, chunkProvider.chunkMap, false, MAILBOX, HANDLE); - } - - @Override - public CompletableFuture lightChunk(final ChunkAccess chunk, final boolean excludeBlocks) { - return CompletableFuture.completedFuture(chunk); - } - - } - -}