mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-06-12 04:23:54 +00:00
Make 1.18 to be effectively in a usable state (#1452)
* Update swathes of easy-to-update-sort-of-code. - Untested - Should compile but NMF broken something - Several todos: - biome history//better support (move to biome sections in core) - regen (haha lol no thanks, someone else can do that) - probably actually do the palette stuff that probably won't work in PaperweightPlatformAdapter * ci: Provide basic Jenkinsfile for ghprb pipeline * build: Update paperweight * upstream: Update Upstream de6fa17 Add getBrush helper for use with instanceof pattern matching (1926) * FAWE will now load on startup * it....works? * Begin to allow biome edits (and fix biomes reverting to plains upon editing blocks) * Add new blocks/block properties * Only create biome palette if supplies is null * Fix biome operations * Finally get removing BlockID done (major version change allows it) * refactor!: Drop PlotSquared v4 Fawe 2.0.0 and newer requires Java 17, PlotSquared v4 supports 1.13 and 1.14, Fawe wont work on these versions nevertheless and refuses to load due Java version incompatiblities with older versions. Newer versions can use PlotSquared v6. * docs: Update readme * Added and removed some comments * Added and removed some comments * refactor: Rename worldedit configuration * build: Re-add 1.17 module This the a very nasty commit * chore: Implement missing methods * build: Update paperweight * upstream: Update upstream 6df194e Remove finalize, use a Cleaner instead (1943) 9843a4f Fix snapshots in 1.18 (1959) * ci: Escape workflows * build: Update paperweight to 1.18.1 * build: Update Paster * Fix compilation * Bump to 1.18.1 * Do both 1.18 and 1.18.1 Co-authored-by: Alex <mc.cache@web.de> * Fix single-block lookups * Reserve ordinals 0 through 3 for air/"reserved" * Create block palette data with values * Fix classpath for testing for starlight * Correctly use block rather than sky light layer [not used in paper] Co-authored-by: NotMyFault <mc.cache@web.de> Co-authored-by: Matt <4009945+MattBDev@users.noreply.github.com>
This commit is contained in:
@ -15,19 +15,49 @@ plugins {
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven {
|
||||
name = "PaperMC"
|
||||
url = uri("https://papermc.io/repo/repository/maven-public/")
|
||||
}
|
||||
maven {
|
||||
name = "Athion"
|
||||
url = uri("https://ci.athion.net/plugin/repository/tools/")
|
||||
content {
|
||||
includeModule("io.papermc", "paperlib")
|
||||
includeModule("io.papermc", "paper-server")
|
||||
}
|
||||
}
|
||||
maven {
|
||||
name = "OSS Sonatype Snapshots"
|
||||
url = uri("https://oss.sonatype.org/content/repositories/snapshots/")
|
||||
}
|
||||
maven {
|
||||
name = "Mojang"
|
||||
url = uri("https://libraries.minecraft.net/")
|
||||
}
|
||||
}
|
||||
|
||||
artifacts {
|
||||
add("default", file("./src/main/resources/worldedit-adapter-1.17.1.jar"))
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly(libs.paperlib)
|
||||
java {
|
||||
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
|
||||
}
|
||||
|
||||
configurations.all {
|
||||
attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17)
|
||||
}
|
||||
|
||||
|
||||
dependencies {
|
||||
compileOnly("io.papermc.paper:paper-api:1.17.1-R0.1-SNAPSHOT")
|
||||
compileOnly(project(":worldedit-bukkit"))
|
||||
compileOnly(project(":worldedit-core"))
|
||||
compileOnly("io.papermc:paper-server:1_17_r1_2")
|
||||
compileOnly(libs.paperlib)
|
||||
compileOnly("com.mojang:datafixerupper:4.0.26")
|
||||
compileOnly("com.mojang:authlib:2.3.31")
|
||||
compileOnly("com.mojang:brigadier:1.0.18")
|
||||
compileOnly("io.netty:netty-all:4.1.25.Final")
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.bukkit.adapter.ext.fawe;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
@ -35,8 +36,10 @@ 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.WorldEditPlugin;
|
||||
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2.PaperweightFaweAdapter;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.extension.platform.Watchdog;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
@ -316,9 +319,31 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
return combinedId == 0 && state.getBlockType() != BlockTypes.AIR ? OptionalInt.empty() : OptionalInt.of(combinedId);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public BaseBlock getBlock(Location location) {
|
||||
checkNotNull(location);
|
||||
public BlockState getBlock(Location location) {
|
||||
Preconditions.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 CraftBlockData blockData = chunk.getBlockState(blockPos).createCraftBlockData();
|
||||
BlockState state = BukkitAdapter.adapt(blockData);
|
||||
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();
|
||||
@ -328,19 +353,11 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
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());
|
||||
}
|
||||
|
||||
// Read the NBT data
|
||||
BlockEntity te = chunk.getBlockEntity(blockPos);
|
||||
if (te != null) {
|
||||
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
|
||||
readTileEntityIntoTag(te, tag); // Load data
|
||||
net.minecraft.nbt.CompoundTag tag = te.save(new net.minecraft.nbt.CompoundTag());
|
||||
//FAWE start - BinaryTag
|
||||
return state.toBaseBlock((CompoundBinaryTag) toNativeBinary(tag));
|
||||
//FAWE end
|
||||
@ -748,8 +765,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
BlockPos pos = new BlockPos(vec.getBlockX(), vec.getBlockY(), vec.getBlockZ());
|
||||
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);
|
||||
BlockStateHolder<?> state = ((PaperweightFaweAdapter) WorldEditPlugin
|
||||
.getInstance()
|
||||
.getBukkitImplAdapter()).adapt(blockData);
|
||||
Objects.requireNonNull(state);
|
||||
BlockEntity blockEntity = chunk.getBlockEntity(pos);
|
||||
if (blockEntity != null) {
|
||||
|
@ -230,9 +230,24 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
|
||||
return Registry.BLOCK.get(new ResourceLocation(blockType.getNamespace(), blockType.getResource()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
@Override
|
||||
public BaseBlock getBlock(Location location) {
|
||||
public BlockState getBlock(Location location) {
|
||||
Preconditions.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);
|
||||
return adapt(blockData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getFullBlock(final Location location) {
|
||||
Preconditions.checkNotNull(location);
|
||||
|
||||
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
|
||||
@ -240,18 +255,22 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
|
||||
int y = location.getBlockY();
|
||||
int z = location.getBlockZ();
|
||||
|
||||
final ServerLevel serverLevel = craftWorld.getHandle();
|
||||
LevelChunk levelChunk = serverLevel.getChunk(x >> 4, z >> 4);
|
||||
final ServerLevel handle = craftWorld.getHandle();
|
||||
LevelChunk chunk = handle.getChunk(x >> 4, z >> 4);
|
||||
final BlockPos blockPos = new BlockPos(x, y, z);
|
||||
org.bukkit.block.Block bukkitBlock = location.getBlock();
|
||||
BlockState state = BukkitAdapter.adapt(bukkitBlock.getBlockData());
|
||||
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 = levelChunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK);
|
||||
BlockEntity blockEntity = chunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK);
|
||||
if (blockEntity != null) {
|
||||
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
|
||||
blockEntity.save(tag); // readTileEntityIntoTag - load data
|
||||
//TODO 1.18 recheck logic, I may skipped loading - NMF
|
||||
net.minecraft.nbt.CompoundTag tag = blockEntity.save(new net.minecraft.nbt.CompoundTag());
|
||||
return state.toBaseBlock((CompoundTag) toNative(tag));
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ 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.block.BlockTypes;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import io.papermc.paper.event.block.BeaconDeactivatedEvent;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@ -151,7 +150,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
if (light != null) {
|
||||
lightUpdate = true;
|
||||
try {
|
||||
fillLightNibble(light, LightLayer.SKY, minSectionPosition, maxSectionPosition);
|
||||
fillLightNibble(light, LightLayer.BLOCK, minSectionPosition, maxSectionPosition);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -546,25 +545,27 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
}
|
||||
|
||||
// Biomes
|
||||
BiomeType[] biomes = set.getBiomes();
|
||||
BiomeType[][] biomes = set.getBiomes();
|
||||
if (biomes != null) {
|
||||
// set biomes
|
||||
ChunkBiomeContainer currentBiomes = nmsChunk.getBiomes();
|
||||
if (createCopy) {
|
||||
copy.storeBiomes(currentBiomes);
|
||||
}
|
||||
for (int y = 0, i = 0; y < 64; y++) {
|
||||
for (int z = 0; z < 4; z++) {
|
||||
for (int x = 0; x < 4; x++, i++) {
|
||||
final BiomeType biome = biomes[i];
|
||||
if (biome != null) {
|
||||
Biome nmsBiome =
|
||||
nmsWorld.registryAccess().ownedRegistryOrThrow(Registry.BIOME_REGISTRY).get(
|
||||
ResourceLocation.tryParse(biome.getId()));
|
||||
if (nmsBiome == null) {
|
||||
throw new NullPointerException("BiomeBase null for BiomeType " + biome.getId());
|
||||
for (int layer = 0; layer < 16; layer++) {
|
||||
for (int y = 0, i = 0; y < 4; y++) {
|
||||
for (int z = 0; z < 4; z++) {
|
||||
for (int x = 0; x < 4; x++, i++) {
|
||||
final BiomeType biome = biomes[layer][i];
|
||||
if (biome != null) {
|
||||
Biome nmsBiome =
|
||||
nmsWorld.registryAccess().ownedRegistryOrThrow(Registry.BIOME_REGISTRY).get(
|
||||
ResourceLocation.tryParse(biome.getId()));
|
||||
if (nmsBiome == null) {
|
||||
throw new NullPointerException("BiomeBase null for BiomeType " + biome.getId());
|
||||
}
|
||||
currentBiomes.setBiome(x, (layer << 2) + y, z, nmsBiome);
|
||||
}
|
||||
currentBiomes.setBiome(x, y, z, nmsBiome);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -925,7 +926,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
|
||||
private char ordinal(net.minecraft.world.level.block.state.BlockState ibd, PaperweightFaweAdapter adapter) {
|
||||
if (ibd == null) {
|
||||
return BlockTypes.AIR.getDefaultState().getOrdinalChar();
|
||||
return 1;
|
||||
} else {
|
||||
return adapter.adaptToChar(ibd);
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
paperDevBundle("1.18-rc3-R0.1-20211129.221606-5") //TODO 1.18 switch to mainline
|
||||
paperDevBundle("1.18.1-R0.1-20211218.091106-15")
|
||||
compileOnly(libs.paperlib)
|
||||
compileOnly(libs.paper)
|
||||
}
|
||||
|
@ -30,27 +30,15 @@ import com.mojang.datafixers.util.Either;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.Dynamic;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import com.sk89q.jnbt.ByteArrayTag;
|
||||
import com.sk89q.jnbt.ByteTag;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.DoubleTag;
|
||||
import com.sk89q.jnbt.EndTag;
|
||||
import com.sk89q.jnbt.FloatTag;
|
||||
import com.sk89q.jnbt.IntArrayTag;
|
||||
import com.sk89q.jnbt.IntTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.LongArrayTag;
|
||||
import com.sk89q.jnbt.LongTag;
|
||||
import com.sk89q.jnbt.NBTConstants;
|
||||
import com.sk89q.jnbt.ShortTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
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.WorldEditPlugin;
|
||||
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1.PaperweightFaweAdapter;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.extension.platform.Watchdog;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
@ -70,6 +58,20 @@ import com.sk89q.worldedit.util.SideEffect;
|
||||
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.util.nbt.BinaryTag;
|
||||
import com.sk89q.worldedit.util.nbt.ByteArrayBinaryTag;
|
||||
import com.sk89q.worldedit.util.nbt.ByteBinaryTag;
|
||||
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
||||
import com.sk89q.worldedit.util.nbt.DoubleBinaryTag;
|
||||
import com.sk89q.worldedit.util.nbt.EndBinaryTag;
|
||||
import com.sk89q.worldedit.util.nbt.FloatBinaryTag;
|
||||
import com.sk89q.worldedit.util.nbt.IntArrayBinaryTag;
|
||||
import com.sk89q.worldedit.util.nbt.IntBinaryTag;
|
||||
import com.sk89q.worldedit.util.nbt.ListBinaryTag;
|
||||
import com.sk89q.worldedit.util.nbt.LongArrayBinaryTag;
|
||||
import com.sk89q.worldedit.util.nbt.LongBinaryTag;
|
||||
import com.sk89q.worldedit.util.nbt.ShortBinaryTag;
|
||||
import com.sk89q.worldedit.util.nbt.StringBinaryTag;
|
||||
import com.sk89q.worldedit.world.DataFixer;
|
||||
import com.sk89q.worldedit.world.RegenOptions;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
@ -142,6 +144,7 @@ import org.bukkit.generator.ChunkGenerator;
|
||||
import org.spigotmc.SpigotConfig;
|
||||
import org.spigotmc.WatchdogThread;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@ -163,12 +166,11 @@ import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft.nbt.Tag> {
|
||||
|
||||
private final Logger logger = Logger.getLogger(getClass().getCanonicalName());
|
||||
|
||||
@ -186,8 +188,8 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
CraftServer.class.cast(Bukkit.getServer());
|
||||
|
||||
int dataVersion = CraftMagicNumbers.INSTANCE.getDataVersion();
|
||||
if (dataVersion != 2860) {
|
||||
throw new UnsupportedClassVersionError("Not 1.18!");
|
||||
if (dataVersion != 2860 && dataVersion != 2865) {
|
||||
throw new UnsupportedClassVersionError("Not 1.18 or 1.18.1!");
|
||||
}
|
||||
|
||||
serverWorldsField = CraftServer.class.getDeclaredField("worlds");
|
||||
@ -235,7 +237,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
* Read the given NBT data into the given tile entity.
|
||||
*
|
||||
* @param tileEntity the tile entity
|
||||
* @param tag the tag
|
||||
* @param tag the tag
|
||||
*/
|
||||
static void readTagIntoTileEntity(net.minecraft.nbt.CompoundTag tag, BlockEntity tileEntity) {
|
||||
tileEntity.load(tag);
|
||||
@ -255,7 +257,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
/**
|
||||
* Create an entity using the given entity ID.
|
||||
*
|
||||
* @param id the entity ID
|
||||
* @param id the entity ID
|
||||
* @param world the world
|
||||
* @return an entity or null
|
||||
*/
|
||||
@ -268,7 +270,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
* Write the given NBT data into the given entity.
|
||||
*
|
||||
* @param entity the entity
|
||||
* @param tag the tag
|
||||
* @param tag the tag
|
||||
*/
|
||||
private static void readTagIntoEntity(net.minecraft.nbt.CompoundTag tag, Entity entity) {
|
||||
entity.load(tag);
|
||||
@ -278,7 +280,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
* Write the entity's NBT data to the given tag.
|
||||
*
|
||||
* @param entity the entity
|
||||
* @param tag the tag
|
||||
* @param tag the tag
|
||||
*/
|
||||
private static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag tag) {
|
||||
entity.save(tag);
|
||||
@ -321,9 +323,8 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
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);
|
||||
final CraftBlockData blockData = chunk.getBlockState(blockPos).createCraftBlockData();
|
||||
BlockState state = BukkitAdapter.adapt(blockData);
|
||||
if (state == null) {
|
||||
org.bukkit.block.Block bukkitBlock = location.getBlock();
|
||||
state = BukkitAdapter.adapt(bukkitBlock.getBlockData());
|
||||
@ -349,7 +350,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
BlockEntity te = chunk.getBlockEntity(blockPos);
|
||||
if (te != null) {
|
||||
net.minecraft.nbt.CompoundTag tag = te.saveWithId();
|
||||
return state.toBaseBlock((CompoundTag) toNative(tag));
|
||||
//FAWE start - BinaryTag
|
||||
return state.toBaseBlock((CompoundBinaryTag) toNativeBinary(tag));
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
return state.toBaseBlock();
|
||||
@ -357,8 +360,10 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
|
||||
@Override
|
||||
public WorldNativeAccess<?, ?, ?> createWorldNativeAccess(org.bukkit.World world) {
|
||||
return new PaperweightWorldNativeAccess(this,
|
||||
new WeakReference<>(((CraftWorld) world).getHandle()));
|
||||
return new PaperweightWorldNativeAccess(
|
||||
this,
|
||||
new WeakReference<>(((CraftWorld) world).getHandle())
|
||||
);
|
||||
}
|
||||
|
||||
private static net.minecraft.core.Direction adapt(Direction face) {
|
||||
@ -470,7 +475,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
return TranslatableComponent.of(CraftItemStack.asNMSCopy(BukkitAdapter.adapt(itemStack)).getDescriptionId());
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@Override
|
||||
public Map<String, ? extends Property<?>> getProperties(BlockType blockType) {
|
||||
Map<String, Property<?>> properties = Maps.newTreeMap(String::compareTo);
|
||||
@ -482,11 +487,25 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) {
|
||||
property = new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues()));
|
||||
} else if (state instanceof DirectionProperty) {
|
||||
property = new DirectionalProperty(state.getName(),
|
||||
(List<Direction>) state.getPossibleValues().stream().map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase(Locale.ROOT))).collect(Collectors.toList()));
|
||||
property = new DirectionalProperty(
|
||||
state.getName(),
|
||||
(List<Direction>) state
|
||||
.getPossibleValues()
|
||||
.stream()
|
||||
.map(e -> Direction.valueOf(((StringRepresentable) e)
|
||||
.getSerializedName()
|
||||
.toUpperCase(Locale.ROOT)))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
} else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) {
|
||||
property = new EnumProperty(state.getName(),
|
||||
(List<String>) state.getPossibleValues().stream().map(e -> ((StringRepresentable) e).getSerializedName()).collect(Collectors.toList()));
|
||||
property = new EnumProperty(
|
||||
state.getName(),
|
||||
(List<String>) 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(), ImmutableList.copyOf(state.getPossibleValues()));
|
||||
} else {
|
||||
@ -499,13 +518,13 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendFakeNBT(Player player, BlockVector3 pos, CompoundTag nbtData) {
|
||||
public void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData) {
|
||||
((CraftPlayer) player).getHandle().networkManager.send(ClientboundBlockEntityDataPacket.create(
|
||||
new StructureBlockEntity(
|
||||
new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()),
|
||||
Blocks.STRUCTURE_BLOCK.defaultBlockState()
|
||||
),
|
||||
__ -> (net.minecraft.nbt.CompoundTag) fromNative(nbtData)
|
||||
__ -> (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData)
|
||||
));
|
||||
}
|
||||
|
||||
@ -550,7 +569,8 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
}
|
||||
fakePlayer.setItemInHand(InteractionHand.MAIN_HAND, stack);
|
||||
fakePlayer.absMoveTo(position.getBlockX(), position.getBlockY(), position.getBlockZ(),
|
||||
(float) face.toVector().toYaw(), (float) face.toVector().toPitch());
|
||||
(float) face.toVector().toYaw(), (float) face.toVector().toPitch()
|
||||
);
|
||||
|
||||
final BlockPos blockPos = new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ());
|
||||
final Vec3 blockVec = Vec3.atLowerCornerOf(blockPos);
|
||||
@ -559,7 +579,10 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
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()) {
|
||||
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();
|
||||
@ -573,7 +596,10 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
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.getX(), position.getY(), position.getZ()));
|
||||
return blockData.canSurvive(
|
||||
((CraftWorld) world).getHandle(),
|
||||
new BlockPos(position.getX(), position.getY(), position.getZ())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -591,7 +617,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
Environment env = bukkitWorld.getEnvironment();
|
||||
ChunkGenerator gen = bukkitWorld.getGenerator();
|
||||
|
||||
Path tempDir = Files.createTempDirectory("WorldEditWorldGen");
|
||||
Path tempDir = Files.createTempDirectory("FastAsyncWorldEditWorldGen");
|
||||
LevelStorageSource levelStorage = LevelStorageSource.createDefault(tempDir);
|
||||
ResourceKey<LevelStem> worldDimKey = getWorldDimKey(env);
|
||||
try (LevelStorageSource.LevelStorageAccess session = levelStorage.createAccess("worldeditregentempworld", worldDimKey)) {
|
||||
@ -675,7 +701,11 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Dynamic<net.minecraft.nbt.Tag> recursivelySetSeed(Dynamic<net.minecraft.nbt.Tag> dynamic, long seed, Set<Dynamic<net.minecraft.nbt.Tag>> seen) {
|
||||
private Dynamic<net.minecraft.nbt.Tag> recursivelySetSeed(
|
||||
Dynamic<net.minecraft.nbt.Tag> dynamic,
|
||||
long seed,
|
||||
Set<Dynamic<net.minecraft.nbt.Tag>> seen
|
||||
) {
|
||||
if (!seen.add(dynamic)) {
|
||||
return dynamic;
|
||||
}
|
||||
@ -699,7 +729,8 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void regenForWorld(Region region, Extent extent, ServerLevel serverWorld, RegenOptions options) throws WorldEditException {
|
||||
private void regenForWorld(Region region, Extent extent, ServerLevel serverWorld, RegenOptions options) throws
|
||||
WorldEditException {
|
||||
List<CompletableFuture<ChunkAccess>> chunkLoadings = submitChunkLoadTasks(region, serverWorld);
|
||||
BlockableEventLoop<Runnable> executor;
|
||||
try {
|
||||
@ -728,13 +759,16 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
BlockPos pos = new BlockPos(vec.getBlockX(), vec.getBlockY(), vec.getBlockZ());
|
||||
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);
|
||||
BlockStateHolder<?> state = ((PaperweightFaweAdapter) WorldEditPlugin
|
||||
.getInstance()
|
||||
.getBukkitImplAdapter()).adapt(blockData);
|
||||
Objects.requireNonNull(state);
|
||||
BlockEntity blockEntity = chunk.getBlockEntity(pos);
|
||||
if (blockEntity != null) {
|
||||
net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId();
|
||||
state = state.toBaseBlock(((CompoundTag) toNative(tag)));
|
||||
//FAWE start - BinaryTag
|
||||
state = state.toBaseBlock(((CompoundBinaryTag) toNativeBinary(tag)));
|
||||
//FAWE end
|
||||
}
|
||||
extent.setBlock(vec, state.toBaseBlock());
|
||||
if (options.shouldRegenBiomes()) {
|
||||
@ -818,48 +852,50 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
* @param foreign non-native NMS NBT structure
|
||||
* @return native WorldEdit NBT structure
|
||||
*/
|
||||
Tag toNative(net.minecraft.nbt.Tag foreign) {
|
||||
//FAWE start - BinaryTag
|
||||
@Override
|
||||
public BinaryTag toNativeBinary(net.minecraft.nbt.Tag foreign) {
|
||||
if (foreign == null) {
|
||||
return null;
|
||||
}
|
||||
if (foreign instanceof net.minecraft.nbt.CompoundTag) {
|
||||
Map<String, Tag> values = new HashMap<>();
|
||||
Map<String, BinaryTag> values = new HashMap<>();
|
||||
Set<String> 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, toNative(base));
|
||||
values.put(str, toNativeBinary(base));
|
||||
}
|
||||
return new CompoundTag(values);
|
||||
return CompoundBinaryTag.from(values);
|
||||
} else if (foreign instanceof net.minecraft.nbt.ByteTag) {
|
||||
return new ByteTag(((net.minecraft.nbt.ByteTag) foreign).getAsByte());
|
||||
return ByteBinaryTag.of(((net.minecraft.nbt.ByteTag) foreign).getAsByte());
|
||||
} else if (foreign instanceof net.minecraft.nbt.ByteArrayTag) {
|
||||
return new ByteArrayTag(((net.minecraft.nbt.ByteArrayTag) foreign).getAsByteArray());
|
||||
return ByteArrayBinaryTag.of(((net.minecraft.nbt.ByteArrayTag) foreign).getAsByteArray());
|
||||
} else if (foreign instanceof net.minecraft.nbt.DoubleTag) {
|
||||
return new DoubleTag(((net.minecraft.nbt.DoubleTag) foreign).getAsDouble());
|
||||
return DoubleBinaryTag.of(((net.minecraft.nbt.DoubleTag) foreign).getAsDouble());
|
||||
} else if (foreign instanceof net.minecraft.nbt.FloatTag) {
|
||||
return new FloatTag(((net.minecraft.nbt.FloatTag) foreign).getAsFloat());
|
||||
return FloatBinaryTag.of(((net.minecraft.nbt.FloatTag) foreign).getAsFloat());
|
||||
} else if (foreign instanceof net.minecraft.nbt.IntTag) {
|
||||
return new IntTag(((net.minecraft.nbt.IntTag) foreign).getAsInt());
|
||||
return IntBinaryTag.of(((net.minecraft.nbt.IntTag) foreign).getAsInt());
|
||||
} else if (foreign instanceof net.minecraft.nbt.IntArrayTag) {
|
||||
return new IntArrayTag(((net.minecraft.nbt.IntArrayTag) foreign).getAsIntArray());
|
||||
return IntArrayBinaryTag.of(((net.minecraft.nbt.IntArrayTag) foreign).getAsIntArray());
|
||||
} else if (foreign instanceof net.minecraft.nbt.LongArrayTag) {
|
||||
return new LongArrayTag(((net.minecraft.nbt.LongArrayTag) foreign).getAsLongArray());
|
||||
return LongArrayBinaryTag.of(((net.minecraft.nbt.LongArrayTag) foreign).getAsLongArray());
|
||||
} else if (foreign instanceof net.minecraft.nbt.ListTag) {
|
||||
try {
|
||||
return toNativeList((net.minecraft.nbt.ListTag) foreign);
|
||||
} catch (Throwable e) {
|
||||
logger.log(Level.WARNING, "Failed to convert net.minecraft.nbt.ListTag", e);
|
||||
return new ListTag(ByteTag.class, new ArrayList<ByteTag>());
|
||||
return ListBinaryTag.empty();
|
||||
}
|
||||
} else if (foreign instanceof net.minecraft.nbt.LongTag) {
|
||||
return new LongTag(((net.minecraft.nbt.LongTag) foreign).getAsLong());
|
||||
return LongBinaryTag.of(((net.minecraft.nbt.LongTag) foreign).getAsLong());
|
||||
} else if (foreign instanceof net.minecraft.nbt.ShortTag) {
|
||||
return new ShortTag(((net.minecraft.nbt.ShortTag) foreign).getAsShort());
|
||||
return ShortBinaryTag.of(((net.minecraft.nbt.ShortTag) foreign).getAsShort());
|
||||
} else if (foreign instanceof net.minecraft.nbt.StringTag) {
|
||||
return new StringTag(foreign.getAsString());
|
||||
return StringBinaryTag.of(foreign.getAsString());
|
||||
} else if (foreign instanceof net.minecraft.nbt.EndTag) {
|
||||
return new EndTag();
|
||||
return EndBinaryTag.get();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName());
|
||||
}
|
||||
@ -870,19 +906,17 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
*
|
||||
* @param foreign the foreign tag
|
||||
* @return the converted tag
|
||||
* @throws SecurityException on error
|
||||
* @throws SecurityException on error
|
||||
* @throws IllegalArgumentException on error
|
||||
*/
|
||||
private ListTag toNativeList(net.minecraft.nbt.ListTag foreign) throws SecurityException, IllegalArgumentException {
|
||||
List<Tag> values = new ArrayList<>();
|
||||
int type = foreign.getElementType();
|
||||
private ListBinaryTag toNativeList(net.minecraft.nbt.ListTag foreign) throws SecurityException, IllegalArgumentException {
|
||||
ListBinaryTag.Builder values = ListBinaryTag.builder();
|
||||
|
||||
for (net.minecraft.nbt.Tag tag : foreign) {
|
||||
values.add(toNative(tag));
|
||||
values.add(toNativeBinary(tag));
|
||||
}
|
||||
|
||||
Class<? extends Tag> cls = NBTConstants.getClassFromType(type);
|
||||
return new ListTag(cls, values);
|
||||
return values.build();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -891,50 +925,51 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
* @param foreign structure to convert
|
||||
* @return non-native structure
|
||||
*/
|
||||
net.minecraft.nbt.Tag fromNative(Tag foreign) {
|
||||
@Override
|
||||
public net.minecraft.nbt.Tag fromNativeBinary(BinaryTag foreign) {
|
||||
if (foreign == null) {
|
||||
return null;
|
||||
}
|
||||
if (foreign instanceof CompoundTag) {
|
||||
if (foreign instanceof CompoundBinaryTag) {
|
||||
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
|
||||
for (Map.Entry<String, Tag> entry : ((CompoundTag) foreign)
|
||||
.getValue().entrySet()) {
|
||||
tag.put(entry.getKey(), fromNative(entry.getValue()));
|
||||
for (String key : ((CompoundBinaryTag) foreign).keySet()) {
|
||||
tag.put(key, fromNativeBinary(((CompoundBinaryTag) foreign).get(key)));
|
||||
}
|
||||
return tag;
|
||||
} else if (foreign instanceof ByteTag) {
|
||||
return net.minecraft.nbt.ByteTag.valueOf(((ByteTag) foreign).getValue());
|
||||
} else if (foreign instanceof ByteArrayTag) {
|
||||
return new net.minecraft.nbt.ByteArrayTag(((ByteArrayTag) foreign).getValue());
|
||||
} else if (foreign instanceof DoubleTag) {
|
||||
return net.minecraft.nbt.DoubleTag.valueOf(((DoubleTag) foreign).getValue());
|
||||
} else if (foreign instanceof FloatTag) {
|
||||
return net.minecraft.nbt.FloatTag.valueOf(((FloatTag) foreign).getValue());
|
||||
} else if (foreign instanceof IntTag) {
|
||||
return net.minecraft.nbt.IntTag.valueOf(((IntTag) foreign).getValue());
|
||||
} else if (foreign instanceof IntArrayTag) {
|
||||
return new net.minecraft.nbt.IntArrayTag(((IntArrayTag) foreign).getValue());
|
||||
} else if (foreign instanceof LongArrayTag) {
|
||||
return new net.minecraft.nbt.LongArrayTag(((LongArrayTag) foreign).getValue());
|
||||
} else if (foreign instanceof ListTag) {
|
||||
} else if (foreign instanceof ByteBinaryTag) {
|
||||
return net.minecraft.nbt.ByteTag.valueOf(((ByteBinaryTag) foreign).value());
|
||||
} else if (foreign instanceof ByteArrayBinaryTag) {
|
||||
return new net.minecraft.nbt.ByteArrayTag(((ByteArrayBinaryTag) foreign).value());
|
||||
} else if (foreign instanceof DoubleBinaryTag) {
|
||||
return net.minecraft.nbt.DoubleTag.valueOf(((DoubleBinaryTag) foreign).value());
|
||||
} else if (foreign instanceof FloatBinaryTag) {
|
||||
return net.minecraft.nbt.FloatTag.valueOf(((FloatBinaryTag) foreign).value());
|
||||
} else if (foreign instanceof IntBinaryTag) {
|
||||
return net.minecraft.nbt.IntTag.valueOf(((IntBinaryTag) foreign).value());
|
||||
} else if (foreign instanceof IntArrayBinaryTag) {
|
||||
return new net.minecraft.nbt.IntArrayTag(((IntArrayBinaryTag) foreign).value());
|
||||
} else if (foreign instanceof LongArrayBinaryTag) {
|
||||
return new net.minecraft.nbt.LongArrayTag(((LongArrayBinaryTag) foreign).value());
|
||||
} else if (foreign instanceof ListBinaryTag) {
|
||||
net.minecraft.nbt.ListTag tag = new net.minecraft.nbt.ListTag();
|
||||
ListTag foreignList = (ListTag) foreign;
|
||||
for (Tag t : foreignList.getValue()) {
|
||||
tag.add(fromNative(t));
|
||||
ListBinaryTag foreignList = (ListBinaryTag) foreign;
|
||||
for (BinaryTag t : foreignList) {
|
||||
tag.add(fromNativeBinary(t));
|
||||
}
|
||||
return tag;
|
||||
} else if (foreign instanceof LongTag) {
|
||||
return net.minecraft.nbt.LongTag.valueOf(((LongTag) foreign).getValue());
|
||||
} else if (foreign instanceof ShortTag) {
|
||||
return net.minecraft.nbt.ShortTag.valueOf(((ShortTag) foreign).getValue());
|
||||
} else if (foreign instanceof StringTag) {
|
||||
return net.minecraft.nbt.StringTag.valueOf(((StringTag) foreign).getValue());
|
||||
} else if (foreign instanceof EndTag) {
|
||||
} else if (foreign instanceof LongBinaryTag) {
|
||||
return net.minecraft.nbt.LongTag.valueOf(((LongBinaryTag) foreign).value());
|
||||
} else if (foreign instanceof ShortBinaryTag) {
|
||||
return net.minecraft.nbt.ShortTag.valueOf(((ShortBinaryTag) foreign).value());
|
||||
} else if (foreign instanceof StringBinaryTag) {
|
||||
return net.minecraft.nbt.StringTag.valueOf(((StringBinaryTag) foreign).value());
|
||||
} else if (foreign instanceof EndBinaryTag) {
|
||||
return net.minecraft.nbt.EndTag.INSTANCE;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName());
|
||||
}
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
@Override
|
||||
public boolean supportsWatchdog() {
|
||||
@ -947,6 +982,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
}
|
||||
|
||||
private class SpigotWatchdog implements Watchdog {
|
||||
|
||||
private final Field instanceField;
|
||||
private final Field lastTickField;
|
||||
|
||||
@ -971,9 +1007,11 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
logger.log(Level.WARNING, "Failed to tick watchdog", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class MojangWatchdog implements Watchdog {
|
||||
|
||||
private final DedicatedServer server;
|
||||
private final Field tickField;
|
||||
|
||||
@ -993,9 +1031,11 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
} catch (IllegalAccessException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class NoOpWorldLoadListener implements ChunkProgressListener {
|
||||
|
||||
@Override
|
||||
public void updateSpawnPos(ChunkPos spawnPos) {
|
||||
}
|
||||
@ -1015,5 +1055,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter {
|
||||
@Override
|
||||
public void setChunkRadius(int radius) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ import com.mojang.datafixers.DataFixer;
|
||||
import com.mojang.datafixers.DataFixerBuilder;
|
||||
import com.mojang.datafixers.schemas.Schema;
|
||||
import com.mojang.serialization.Dynamic;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.NbtOps;
|
||||
import net.minecraft.network.chat.Component;
|
||||
@ -49,6 +49,7 @@ import net.minecraft.world.item.DyeColor;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
@ -62,31 +63,31 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Handles converting all Pre 1.13.2 data using the Legacy DataFix System (ported to 1.13.2)
|
||||
*
|
||||
* <p>
|
||||
* We register a DFU Fixer per Legacy Data Version and apply the fixes using legacy strategy
|
||||
* which is safer, faster and cleaner code.
|
||||
*
|
||||
* <p>
|
||||
* The pre DFU code did not fail when the Source version was unknown.
|
||||
*
|
||||
* <p>
|
||||
* 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" })
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.worldedit.world.DataFixer {
|
||||
|
||||
//FAWE start - BinaryTag
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> T fixUp(FixType<T> type, T original, int srcVer) {
|
||||
if (type == FixTypes.CHUNK) {
|
||||
return (T) fixChunk((CompoundTag) original, srcVer);
|
||||
return (T) fixChunk((CompoundBinaryTag) original, srcVer);
|
||||
} else if (type == FixTypes.BLOCK_ENTITY) {
|
||||
return (T) fixBlockEntity((CompoundTag) original, srcVer);
|
||||
return (T) fixBlockEntity((CompoundBinaryTag) original, srcVer);
|
||||
} else if (type == FixTypes.ENTITY) {
|
||||
return (T) fixEntity((CompoundTag) original, srcVer);
|
||||
return (T) fixEntity((CompoundBinaryTag) original, srcVer);
|
||||
} else if (type == FixTypes.BLOCK_STATE) {
|
||||
return (T) fixBlockState((String) original, srcVer);
|
||||
} else if (type == FixTypes.ITEM_TYPE) {
|
||||
@ -97,28 +98,34 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
return original;
|
||||
}
|
||||
|
||||
private CompoundTag fixChunk(CompoundTag originalChunk, int srcVer) {
|
||||
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNative(originalChunk);
|
||||
private CompoundBinaryTag fixChunk(CompoundBinaryTag originalChunk, int srcVer) {
|
||||
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeBinary(originalChunk);
|
||||
net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.CHUNK, tag, srcVer);
|
||||
return (CompoundTag) adapter.toNative(fixed);
|
||||
return (CompoundBinaryTag) adapter.toNativeBinary(fixed);
|
||||
}
|
||||
|
||||
private CompoundTag fixBlockEntity(CompoundTag origTileEnt, int srcVer) {
|
||||
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNative(origTileEnt);
|
||||
private CompoundBinaryTag fixBlockEntity(CompoundBinaryTag origTileEnt, int srcVer) {
|
||||
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeBinary(origTileEnt);
|
||||
net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.BLOCK_ENTITY, tag, srcVer);
|
||||
return (CompoundTag) adapter.toNative(fixed);
|
||||
return (CompoundBinaryTag) adapter.toNativeBinary(fixed);
|
||||
}
|
||||
|
||||
private CompoundTag fixEntity(CompoundTag origEnt, int srcVer) {
|
||||
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNative(origEnt);
|
||||
private CompoundBinaryTag fixEntity(CompoundBinaryTag origEnt, int srcVer) {
|
||||
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeBinary(origEnt);
|
||||
net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.ENTITY, tag, srcVer);
|
||||
return (CompoundTag) adapter.toNative(fixed);
|
||||
return (CompoundBinaryTag) adapter.toNativeBinary(fixed);
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
private String fixBlockState(String blockState, int srcVer) {
|
||||
net.minecraft.nbt.CompoundTag stateNBT = stateToNBT(blockState);
|
||||
Dynamic<net.minecraft.nbt.Tag> 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();
|
||||
net.minecraft.nbt.CompoundTag fixed = (net.minecraft.nbt.CompoundTag) INSTANCE.fixer.update(
|
||||
References.BLOCK_STATE,
|
||||
dynamic,
|
||||
srcVer,
|
||||
DATA_VERSION
|
||||
).getValue();
|
||||
return nbtToState(fixed);
|
||||
}
|
||||
|
||||
@ -128,7 +135,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
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(props
|
||||
.getAllKeys()
|
||||
.stream()
|
||||
.map(k -> k + "=" + props.getString(k).replace("\"", ""))
|
||||
.collect(Collectors.joining(",")));
|
||||
sb.append(']');
|
||||
}
|
||||
return sb.toString();
|
||||
@ -220,6 +231,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private class WrappedDataFixer implements DataFixer {
|
||||
|
||||
private final DataFixer realFixer;
|
||||
|
||||
WrappedDataFixer(DataFixer realFixer) {
|
||||
@ -240,7 +252,12 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
return realFixer.update(type, dynamic, sourceVer, targetVer);
|
||||
}
|
||||
|
||||
private net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer, int desiredVersion) {
|
||||
private net.minecraft.nbt.CompoundTag convert(
|
||||
LegacyType type,
|
||||
net.minecraft.nbt.CompoundTag cmp,
|
||||
int sourceVer,
|
||||
int desiredVersion
|
||||
) {
|
||||
List<DataConverter> converters = PaperweightDataConverters.this.converters.get(type);
|
||||
if (converters != null && !converters.isEmpty()) {
|
||||
for (DataConverter converter : converters) {
|
||||
@ -265,6 +282,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
public Schema getSchema(int i) {
|
||||
return realFixer.getSchema(i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp) {
|
||||
@ -275,7 +293,12 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
return convert(type.getDFUType(), cmp, sourceVer);
|
||||
}
|
||||
|
||||
public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -288,16 +311,25 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
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) {
|
||||
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();
|
||||
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 {
|
||||
@ -305,6 +337,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
int getDataVersion();
|
||||
|
||||
net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -582,7 +615,13 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
return key;
|
||||
}
|
||||
|
||||
private static void convertCompound(LegacyType type, net.minecraft.nbt.CompoundTag cmp, String key, int sourceVer, int targetVer) {
|
||||
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));
|
||||
}
|
||||
|
||||
@ -658,6 +697,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataInspectorBlockEntity implements DataInspector {
|
||||
@ -840,6 +880,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -859,7 +900,12 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
return cmp;
|
||||
}
|
||||
|
||||
abstract net.minecraft.nbt.CompoundTag inspectChecked(net.minecraft.nbt.CompoundTag nbttagcompound, int sourceVer, int targetVer);
|
||||
abstract net.minecraft.nbt.CompoundTag inspectChecked(
|
||||
net.minecraft.nbt.CompoundTag nbttagcompound,
|
||||
int sourceVer,
|
||||
int targetVer
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
private static class DataInspectorItemList extends DataInspectorTagged {
|
||||
@ -878,6 +924,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return nbttagcompound;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataInspectorItem extends DataInspectorTagged {
|
||||
@ -896,6 +943,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return nbttagcompound;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterMaterialId implements DataConverter {
|
||||
@ -1296,6 +1344,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterBanner implements DataConverter {
|
||||
@ -1342,6 +1391,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterPotionId implements DataConverter {
|
||||
@ -1619,7 +1669,15 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
private static class DataConverterMinecart implements DataConverter {
|
||||
|
||||
private static final List<String> a = Lists.newArrayList("MinecartRideable", "MinecartChest", "MinecartFurnace", "MinecartTNT", "MinecartSpawner", "MinecartHopper", "MinecartCommandBlock");
|
||||
private static final List<String> a = Lists.newArrayList(
|
||||
"MinecartRideable",
|
||||
"MinecartChest",
|
||||
"MinecartFurnace",
|
||||
"MinecartTNT",
|
||||
"MinecartSpawner",
|
||||
"MinecartHopper",
|
||||
"MinecartCommandBlock"
|
||||
);
|
||||
|
||||
DataConverterMinecart() {
|
||||
}
|
||||
@ -1643,6 +1701,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterMobSpawner implements DataConverter {
|
||||
@ -1687,6 +1746,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
return cmp;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterUUID implements DataConverter {
|
||||
@ -1705,11 +1765,47 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterHealth implements DataConverter {
|
||||
|
||||
private static final Set<String> 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");
|
||||
private static final Set<String> 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() {
|
||||
}
|
||||
@ -1738,6 +1834,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterSaddle implements DataConverter {
|
||||
@ -1762,6 +1859,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterHanging implements DataConverter {
|
||||
@ -1800,6 +1898,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterDropChances implements DataConverter {
|
||||
@ -1823,13 +1922,15 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
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) {
|
||||
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 {
|
||||
@ -1865,6 +1966,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
nbttagcompound.remove("Riding");
|
||||
return nbttagcompound1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterBook implements DataConverter {
|
||||
@ -1933,6 +2035,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterCookedFish implements DataConverter {
|
||||
@ -1953,6 +2056,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterZombie implements DataConverter {
|
||||
@ -1995,6 +2099,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
private int convert(int i) {
|
||||
return i >= 0 && i < 6 ? i : -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterVBO implements DataConverter {
|
||||
@ -2010,6 +2115,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
cmp.putString("useVbo", "true");
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterGuardian implements DataConverter {
|
||||
@ -2032,6 +2138,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterSkeleton implements DataConverter {
|
||||
@ -2060,6 +2167,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterZombieType implements DataConverter {
|
||||
@ -2098,6 +2206,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterHorse implements DataConverter {
|
||||
@ -2140,6 +2249,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterTileEntity implements DataConverter {
|
||||
@ -2302,7 +2412,8 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
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)) {
|
||||
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)) {
|
||||
@ -2316,6 +2427,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterShulker implements DataConverter {
|
||||
@ -2334,11 +2446,12 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
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" };
|
||||
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() {
|
||||
}
|
||||
@ -2375,6 +2488,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterShulkerBoxBlock implements DataConverter {
|
||||
@ -2393,6 +2507,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterLang implements DataConverter {
|
||||
@ -2411,6 +2526,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterTotem implements DataConverter {
|
||||
@ -2429,6 +2545,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterBedBlock implements DataConverter {
|
||||
@ -2476,6 +2593,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataConverterBedItem implements DataConverter {
|
||||
@ -2494,12 +2612,14 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
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 {
|
||||
MutableComponent a(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws
|
||||
JsonParseException {
|
||||
if (jsonelement.isJsonPrimitive()) {
|
||||
return new TextComponent(jsonelement.getAsString());
|
||||
} else if (jsonelement.isJsonArray()) {
|
||||
@ -2509,7 +2629,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
JsonElement jsonelement1 = (JsonElement) iterator.next();
|
||||
MutableComponent ichatbasecomponent1 = this.a(jsonelement1, jsonelement1.getClass(), jsondeserializationcontext);
|
||||
MutableComponent ichatbasecomponent1 = this.a(
|
||||
jsonelement1,
|
||||
jsonelement1.getClass(),
|
||||
jsondeserializationcontext
|
||||
);
|
||||
|
||||
if (ichatbasecomponent == null) {
|
||||
ichatbasecomponent = ichatbasecomponent1;
|
||||
@ -2524,7 +2648,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
}
|
||||
}
|
||||
|
||||
public Object deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException {
|
||||
public Object deserialize(
|
||||
JsonElement jsonelement,
|
||||
Type type,
|
||||
JsonDeserializationContext jsondeserializationcontext
|
||||
) throws JsonParseException {
|
||||
return this.a(jsonelement, type, jsondeserializationcontext);
|
||||
}
|
||||
}).create();
|
||||
@ -2590,9 +2718,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
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)) {
|
||||
@ -2605,9 +2735,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
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)) {
|
||||
@ -2616,9 +2748,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
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;
|
||||
@ -2649,9 +2783,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
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)) {
|
||||
@ -2663,7 +2799,15 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
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));
|
||||
nbttaglist.set(
|
||||
j,
|
||||
convert(
|
||||
LegacyType.ENTITY,
|
||||
(net.minecraft.nbt.CompoundTag) nbttaglist.get(j),
|
||||
sourceVer,
|
||||
targetVer
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2671,16 +2815,26 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
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));
|
||||
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)) {
|
||||
@ -2693,9 +2847,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
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);
|
||||
@ -2710,9 +2866,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataInspectorVillagers implements DataInspector {
|
||||
|
||||
ResourceLocation entityVillager = getKey("EntityVillager");
|
||||
|
||||
@Override
|
||||
@ -2736,9 +2894,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataInspectorMobSpawnerMinecart implements DataInspector {
|
||||
|
||||
ResourceLocation entityMinecartMobSpawner = getKey("EntityMinecartMobSpawner");
|
||||
ResourceLocation tileEntityMobSpawner = getKey("TileEntityMobSpawner");
|
||||
|
||||
@ -2753,9 +2913,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataInspectorMobSpawnerMobs implements DataInspector {
|
||||
|
||||
ResourceLocation tileEntityMobSpawner = getKey("TileEntityMobSpawner");
|
||||
|
||||
@Override
|
||||
@ -2776,9 +2938,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataInspectorCommandBlock implements DataInspector {
|
||||
|
||||
ResourceLocation tileEntityCommand = getKey("TileEntityCommand");
|
||||
|
||||
@Override
|
||||
@ -2791,5 +2955,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,7 +37,11 @@ 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 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) {
|
||||
@ -95,4 +99,5 @@ class PaperweightFakePlayer extends ServerPlayer {
|
||||
@Override
|
||||
public void openTextEdit(SignBlockEntity sign) {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,29 +19,29 @@
|
||||
|
||||
package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_18_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.util.nbt.CompoundBinaryTag;
|
||||
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_18_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_18_R1.block.data.CraftBlockData;
|
||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Objects;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class PaperweightWorldNativeAccess implements WorldNativeAccess<LevelChunk, net.minecraft.world.level.block.state.BlockState, BlockPos> {
|
||||
public class PaperweightWorldNativeAccess implements
|
||||
WorldNativeAccess<LevelChunk, net.minecraft.world.level.block.state.BlockState, BlockPos> {
|
||||
|
||||
private static final int UPDATE = 1;
|
||||
private static final int NOTIFY = 2;
|
||||
|
||||
@ -83,12 +83,19 @@ public class PaperweightWorldNativeAccess implements WorldNativeAccess<LevelChun
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public net.minecraft.world.level.block.state.BlockState setBlockState(LevelChunk chunk, BlockPos position, net.minecraft.world.level.block.state.BlockState state) {
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -103,19 +110,17 @@ public class PaperweightWorldNativeAccess implements WorldNativeAccess<LevelChun
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateTileEntity(BlockPos position, CompoundTag 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(tag);
|
||||
PaperweightAdapter.readTagIntoTileEntity((net.minecraft.nbt.CompoundTag) nativeTag, tileEntity);
|
||||
return true;
|
||||
public boolean updateTileEntity(final BlockPos position, final CompoundBinaryTag tag) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyBlockUpdate(LevelChunk chunk, BlockPos position, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) {
|
||||
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);
|
||||
}
|
||||
@ -134,7 +139,11 @@ public class PaperweightWorldNativeAccess implements WorldNativeAccess<LevelChun
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyNeighbors(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) {
|
||||
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());
|
||||
@ -158,14 +167,22 @@ public class PaperweightWorldNativeAccess implements WorldNativeAccess<LevelChun
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNeighbors(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState, int recursionLimit) {
|
||||
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));
|
||||
BlockPhysicsEvent event = new BlockPhysicsEvent(
|
||||
craftWorld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()),
|
||||
CraftBlockData.fromData(newState)
|
||||
);
|
||||
world.getCraftServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
@ -176,7 +193,17 @@ public class PaperweightWorldNativeAccess implements WorldNativeAccess<LevelChun
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockStateChange(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) {
|
||||
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() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -51,8 +51,7 @@ public class PaperweightBlockMaterial implements BlockMaterial {
|
||||
);
|
||||
tile = tileEntity == null
|
||||
? null
|
||||
: new PaperweightLazyCompoundTag(Suppliers.memoize(() -> tileEntity.save(new net.minecraft.nbt.CompoundTag())));
|
||||
// TODO 1.18 save -> saveAdditional
|
||||
: new PaperweightLazyCompoundTag(Suppliers.memoize(tileEntity::saveWithId));
|
||||
}
|
||||
|
||||
public Block getBlock() {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1;
|
||||
|
||||
import ca.spottedleaf.starlight.common.light.StarLightEngine;
|
||||
import com.fastasyncworldedit.bukkit.adapter.CachedBukkitAdapter;
|
||||
import com.fastasyncworldedit.bukkit.adapter.IDelegateBukkitImplAdapter;
|
||||
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
|
||||
@ -22,7 +23,6 @@ import com.sk89q.worldedit.bukkit.BukkitWorld;
|
||||
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||
import com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_18_R1.PaperweightAdapter;
|
||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1.nbt.PaperweightLazyCompoundTag;
|
||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1.regen.PaperweightRegen;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
|
||||
@ -55,7 +55,7 @@ import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.WritableRegistry;
|
||||
import net.minecraft.nbt.IntTag;
|
||||
import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData;
|
||||
import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ChunkHolder;
|
||||
@ -229,9 +229,24 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
|
||||
return Registry.BLOCK.get(new ResourceLocation(blockType.getNamespace(), blockType.getResource()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
@Override
|
||||
public BaseBlock getBlock(Location location) {
|
||||
public BlockState getBlock(Location location) {
|
||||
Preconditions.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);
|
||||
return adapt(blockData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getFullBlock(final Location location) {
|
||||
Preconditions.checkNotNull(location);
|
||||
|
||||
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
|
||||
@ -239,19 +254,21 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
|
||||
int y = location.getBlockY();
|
||||
int z = location.getBlockZ();
|
||||
|
||||
final ServerLevel serverLevel = craftWorld.getHandle();
|
||||
LevelChunk levelChunk = serverLevel.getChunk(x >> 4, z >> 4);
|
||||
final ServerLevel handle = craftWorld.getHandle();
|
||||
LevelChunk chunk = handle.getChunk(x >> 4, z >> 4);
|
||||
final BlockPos blockPos = new BlockPos(x, y, z);
|
||||
org.bukkit.block.Block bukkitBlock = location.getBlock();
|
||||
BlockState state = BukkitAdapter.adapt(bukkitBlock.getBlockData());
|
||||
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 = levelChunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK);
|
||||
BlockEntity blockEntity = chunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK);
|
||||
if (blockEntity != null) {
|
||||
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
|
||||
//TODO save -> saveAdditional
|
||||
blockEntity.save(tag); // readTileEntityIntoTag - load data
|
||||
net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId();
|
||||
return state.toBaseBlock((CompoundTag) toNative(tag));
|
||||
}
|
||||
}
|
||||
@ -305,12 +322,6 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
|
||||
if (existing == blockState) {
|
||||
return true;
|
||||
}
|
||||
if (section == null) {
|
||||
if (blockState.isAir()) {
|
||||
return true;
|
||||
}
|
||||
levelChunkSections[y4] = section = new LevelChunkSection(y4 << 4);
|
||||
}
|
||||
levelChunk.setBlockState(blockPos, blockState, false);
|
||||
}
|
||||
if (update) {
|
||||
@ -482,7 +493,7 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
|
||||
stream.filter(entityPlayer -> checkPlayer == null || entityPlayer == checkPlayer)
|
||||
.forEach(entityPlayer -> {
|
||||
synchronized (chunkPacket) {
|
||||
ClientboundLevelChunkPacketData nmsPacket = (ClientboundLevelChunkPacketData) chunkPacket.getNativePacket();
|
||||
ClientboundLevelChunkWithLightPacket nmsPacket = (ClientboundLevelChunkWithLightPacket) chunkPacket.getNativePacket();
|
||||
if (nmsPacket == null) {
|
||||
nmsPacket = mapUtil.create(this, chunkPacket);
|
||||
chunkPacket.setNativePacket(nmsPacket);
|
||||
@ -600,7 +611,8 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
|
||||
|
||||
@Override
|
||||
public boolean regenerate(org.bukkit.World bukkitWorld, Region region, Extent target, RegenOptions options) throws Exception {
|
||||
return new PaperweightRegen(bukkitWorld, region, target, options).regenerate();
|
||||
// return new PaperweightRegen(bukkitWorld, region, target, options).regenerate();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -644,7 +656,7 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
|
||||
@Override
|
||||
public RelighterFactory getRelighterFactory() {
|
||||
try {
|
||||
Class.forName("ca.spottedleaf.starlight.light.StarLightEngine");
|
||||
Class.forName("ca.spottedleaf.starlight.common.light.StarLightEngine");
|
||||
if (PaperweightStarlightRelighter.isUsable()) {
|
||||
return new PaperweightStarlightRelighterFactory();
|
||||
}
|
||||
|
@ -275,8 +275,21 @@ public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess<Level
|
||||
cachedChunksToSend.clear();
|
||||
}
|
||||
|
||||
private record CachedChange(LevelChunk levelChunk, BlockPos blockPos,
|
||||
net.minecraft.world.level.block.state.BlockState blockState) {
|
||||
private static final class CachedChange {
|
||||
|
||||
private final LevelChunk levelChunk;
|
||||
private final BlockPos blockPos;
|
||||
private final net.minecraft.world.level.block.state.BlockState blockState;
|
||||
|
||||
private CachedChange(
|
||||
LevelChunk levelChunk,
|
||||
BlockPos blockPos,
|
||||
net.minecraft.world.level.block.state.BlockState blockState
|
||||
) {
|
||||
this.levelChunk = levelChunk;
|
||||
this.blockPos = blockPos;
|
||||
this.blockState = blockState;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@ 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.block.BlockTypes;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import io.papermc.paper.event.block.BeaconDeactivatedEvent;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@ -36,14 +35,15 @@ import net.minecraft.resources.ResourceLocation;
|
||||
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.biome.Biomes;
|
||||
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.ChunkBiomeContainer;
|
||||
import net.minecraft.world.level.chunk.DataLayer;
|
||||
import net.minecraft.world.level.chunk.HashMapPalette;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
@ -60,7 +60,6 @@ import org.bukkit.craftbukkit.v1_18_R1.block.CraftBlock;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.AbstractSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -86,9 +85,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
|
||||
private static final Function<BlockPos, BlockVector3> posNms2We = v -> BlockVector3.at(v.getX(), v.getY(), v.getZ());
|
||||
private static final Function<BlockEntity, CompoundTag> nmsTile2We =
|
||||
tileEntity -> new PaperweightLazyCompoundTag(Suppliers.memoize(
|
||||
//TODO save -> saveAdditional
|
||||
() -> tileEntity.save(new net.minecraft.nbt.CompoundTag())));
|
||||
tileEntity -> new PaperweightLazyCompoundTag(Suppliers.memoize(tileEntity::saveWithId));
|
||||
private final PaperweightFaweAdapter adapter = ((PaperweightFaweAdapter) WorldEditPlugin
|
||||
.getInstance()
|
||||
.getBukkitImplAdapter());
|
||||
@ -100,6 +97,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
private final int maxHeight;
|
||||
private final int minSectionPosition;
|
||||
private final int maxSectionPosition;
|
||||
private final Registry<Biome> biomeRegistry;
|
||||
private LevelChunkSection[] sections;
|
||||
private LevelChunk levelChunk;
|
||||
private DataLayer[] blockLight;
|
||||
@ -124,6 +122,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
this.maxSectionPosition = maxHeight >> 4;
|
||||
this.skyLight = new DataLayer[getSectionCount()];
|
||||
this.blockLight = new DataLayer[getSectionCount()];
|
||||
this.biomeRegistry = serverLevel.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY);
|
||||
}
|
||||
|
||||
public int getChunkX() {
|
||||
@ -154,7 +153,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
if (light != null) {
|
||||
lightUpdate = true;
|
||||
try {
|
||||
fillLightNibble(light, LightLayer.SKY, minSectionPosition, maxSectionPosition);
|
||||
fillLightNibble(light, LightLayer.BLOCK, minSectionPosition, maxSectionPosition);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -194,19 +193,9 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
|
||||
@Override
|
||||
public BiomeType getBiomeType(int x, int y, int z) {
|
||||
ChunkBiomeContainer index = getChunk().getBiomes();
|
||||
Biome biomes = null;
|
||||
if (y == -1) {
|
||||
for (y = serverLevel.getMinBuildHeight(); y < serverLevel.getMaxBuildHeight(); y += 4) {
|
||||
biomes = index.getNoiseBiome(x >> 2, y >> 2, z >> 2);
|
||||
if (biomes != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
biomes = index.getNoiseBiome(x >> 2, y >> 2, z >> 2);
|
||||
}
|
||||
return biomes != null ? PaperweightPlatformAdapter.adapt(biomes, serverLevel) : null;
|
||||
LevelChunkSection section = getSections(false)[(y >> 4) - getMinSectionPosition()];
|
||||
Biome biomes = section.getNoiseBiome(x >> 2, (y & 15) >> 2, z >> 2);
|
||||
return PaperweightPlatformAdapter.adapt(biomes, serverLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -217,10 +206,8 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
if (dataLayer != null) {
|
||||
lightUpdate = true;
|
||||
synchronized (dataLayer) {
|
||||
byte[] bytes = PaperLib.isPaper() ? dataLayer.getIfSet() : dataLayer.getData();
|
||||
if (!PaperLib.isPaper() || bytes != DataLayer.EMPTY_NIBBLE) {
|
||||
Arrays.fill(bytes, (byte) 0);
|
||||
}
|
||||
byte[] bytes = dataLayer.getData();
|
||||
Arrays.fill(bytes, (byte) 0);
|
||||
}
|
||||
}
|
||||
if (sky) {
|
||||
@ -233,10 +220,8 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
if (dataLayer1 != null) {
|
||||
lightUpdate = true;
|
||||
synchronized (dataLayer1) {
|
||||
byte[] bytes = PaperLib.isPaper() ? dataLayer1.getIfSet() : dataLayer1.getData();
|
||||
if (!PaperLib.isPaper() || bytes != DataLayer.EMPTY_NIBBLE) {
|
||||
Arrays.fill(bytes, (byte) 0);
|
||||
}
|
||||
byte[] bytes = dataLayer1.getData();
|
||||
Arrays.fill(bytes, (byte) 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -251,7 +236,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
if (blockEntity == null) {
|
||||
return null;
|
||||
}
|
||||
return new PaperweightLazyCompoundTag(Suppliers.memoize(() -> blockEntity.save(new net.minecraft.nbt.CompoundTag())));
|
||||
return new PaperweightLazyCompoundTag(Suppliers.memoize(blockEntity::saveWithId));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -450,18 +435,67 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
}
|
||||
}
|
||||
}
|
||||
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().copy());
|
||||
}
|
||||
|
||||
if (existingSection == null) {
|
||||
PalettedContainer<Biome> biomeData = PaperweightPlatformAdapter.getBiomePalettedContainer(
|
||||
biomes[setSectionIndex],
|
||||
biomeRegistry
|
||||
);
|
||||
LevelChunkSection newSection = PaperweightPlatformAdapter.newChunkSection(
|
||||
layerNo,
|
||||
new char[4096],
|
||||
fastmode,
|
||||
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<Biome> biomeData = existingSection.getBiomes();
|
||||
setBiomesToPalettedContainer(biomes[setSectionIndex], biomeData);
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
int layer = layerNo - getMinSectionPosition();
|
||||
|
||||
bitMask |= 1 << layer;
|
||||
bitMask |= 1 << getSectionIndex;
|
||||
|
||||
char[] tmp = set.load(layerNo);
|
||||
char[] setArr = new char[4096];
|
||||
@ -469,26 +503,44 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
|
||||
// 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[layer]) {
|
||||
synchronized (super.sectionLocks[getSectionIndex]) {
|
||||
|
||||
LevelChunkSection newSection;
|
||||
LevelChunkSection existingSection = levelChunkSections[getSectionIndex];
|
||||
|
||||
if (createCopy) {
|
||||
char[] tmpLoad = loadPrivately(layerNo);
|
||||
char[] copyArr = new char[4096];
|
||||
System.arraycopy(tmpLoad, 0, copyArr, 0, 4096);
|
||||
copy.storeSection(layer, copyArr);
|
||||
copy.storeSection(getSectionIndex, copyArr);
|
||||
if (biomes != null && existingSection != null) {
|
||||
copy.storeBiomes(getSectionIndex, existingSection.getBiomes().copy());
|
||||
}
|
||||
}
|
||||
|
||||
LevelChunkSection newSection;
|
||||
LevelChunkSection existingSection = levelChunkSections[layer];
|
||||
if (existingSection == null) {
|
||||
newSection = PaperweightPlatformAdapter.newChunkSection(layerNo, setArr, fastmode, adapter);
|
||||
if (PaperweightPlatformAdapter.setSectionAtomic(levelChunkSections, null, newSection, layer)) {
|
||||
updateGet(nmsChunk, levelChunkSections, newSection, setArr, layer);
|
||||
PalettedContainer<Biome> biomeData = biomes == null ? new PalettedContainer<>(
|
||||
biomeRegistry,
|
||||
biomeRegistry.getOrThrow(Biomes.PLAINS),
|
||||
PalettedContainer.Strategy.SECTION_BIOMES,
|
||||
null
|
||||
) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeRegistry);
|
||||
newSection = PaperweightPlatformAdapter.newChunkSection(
|
||||
layerNo,
|
||||
setArr,
|
||||
fastmode,
|
||||
adapter,
|
||||
biomeRegistry,
|
||||
biomeData
|
||||
);
|
||||
if (PaperweightPlatformAdapter.setSectionAtomic(levelChunkSections, null, newSection, getSectionIndex)) {
|
||||
updateGet(nmsChunk, levelChunkSections, newSection, setArr, getSectionIndex);
|
||||
continue;
|
||||
} else {
|
||||
existingSection = levelChunkSections[layer];
|
||||
existingSection = levelChunkSections[getSectionIndex];
|
||||
if (existingSection == null) {
|
||||
LOGGER.error("Skipping invalid null section. chunk: {}, {} layer: {}", chunkX, chunkZ,
|
||||
+layer
|
||||
getSectionIndex
|
||||
);
|
||||
continue;
|
||||
}
|
||||
@ -507,10 +559,10 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
this.levelChunk = nmsChunk;
|
||||
this.sections = null;
|
||||
this.reset();
|
||||
} else if (existingSection != getSections(false)[layer]) {
|
||||
this.sections[layer] = existingSection;
|
||||
} else if (existingSection != getSections(false)[getSectionIndex]) {
|
||||
this.sections[getSectionIndex] = existingSection;
|
||||
this.reset();
|
||||
} else if (!Arrays.equals(update(layer, new char[4096], true), loadPrivately(layerNo))) {
|
||||
} else if (!Arrays.equals(update(getSectionIndex, new char[4096], true), loadPrivately(layerNo))) {
|
||||
this.reset(layerNo);
|
||||
/*} else if (lock.isModified()) {
|
||||
this.reset(layerNo);*/
|
||||
@ -518,51 +570,34 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
} finally {
|
||||
sectionLock.writeLock().unlock();
|
||||
}
|
||||
|
||||
PalettedContainer<Biome> biomeData = existingSection.getBiomes();
|
||||
|
||||
if (biomes != null && biomes[setSectionIndex] != null) {
|
||||
setBiomesToPalettedContainer(biomes[setSectionIndex], biomeData);
|
||||
}
|
||||
|
||||
newSection =
|
||||
PaperweightPlatformAdapter.newChunkSection(
|
||||
layerNo,
|
||||
this::loadPrivately,
|
||||
setArr,
|
||||
fastmode,
|
||||
adapter
|
||||
adapter,
|
||||
biomeRegistry,
|
||||
biomeData
|
||||
);
|
||||
if (!PaperweightPlatformAdapter.setSectionAtomic(
|
||||
levelChunkSections,
|
||||
existingSection,
|
||||
newSection,
|
||||
layer
|
||||
getSectionIndex
|
||||
)) {
|
||||
LOGGER.error("Skipping invalid null section. chunk: {}, {} layer: {}", chunkX, chunkZ,
|
||||
+layer
|
||||
getSectionIndex
|
||||
);
|
||||
} else {
|
||||
updateGet(nmsChunk, levelChunkSections, newSection, setArr, layer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Biomes
|
||||
BiomeType[] biomes = set.getBiomes();
|
||||
if (biomes != null) {
|
||||
// set biomes
|
||||
ChunkBiomeContainer currentBiomes = nmsChunk.getBiomes();
|
||||
if (createCopy) {
|
||||
copy.storeBiomes(currentBiomes);
|
||||
}
|
||||
for (int y = 0, i = 0; y < 64; y++) {
|
||||
for (int z = 0; z < 4; z++) {
|
||||
for (int x = 0; x < 4; x++, i++) {
|
||||
final BiomeType biome = biomes[i];
|
||||
if (biome != null) {
|
||||
Biome nmsBiome =
|
||||
nmsWorld.registryAccess().ownedRegistryOrThrow(Registry.BIOME_REGISTRY).get(
|
||||
ResourceLocation.tryParse(biome.getId()));
|
||||
if (nmsBiome == null) {
|
||||
throw new NullPointerException("BiomeBase null for BiomeType " + biome.getId());
|
||||
}
|
||||
currentBiomes.setBiome(x, y, z, nmsBiome);
|
||||
}
|
||||
updateGet(nmsChunk, levelChunkSections, newSection, setArr, getSectionIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -665,7 +700,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
}
|
||||
entity.load(tag);
|
||||
entity.absMoveTo(x, y, z, yaw, pitch);
|
||||
nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM);
|
||||
nmsWorld.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -718,7 +753,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
// Set Modified
|
||||
nmsChunk.setLightCorrect(true); // Set Modified
|
||||
nmsChunk.mustNotSave = false;
|
||||
nmsChunk.isUnsaved(); // TODO 1.18 revisit
|
||||
nmsChunk.setUnsaved(true);
|
||||
// send to player
|
||||
if (Settings.IMP.LIGHTING.MODE == 0 || !Settings.IMP.LIGHTING.DELAY_PACKET_SENDING) {
|
||||
this.send(finalMask, finalLightUpdate);
|
||||
@ -857,10 +892,17 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
lock.acquire();
|
||||
|
||||
final PalettedContainer<net.minecraft.world.level.block.state.BlockState> blocks = section.getStates();
|
||||
final BitStorage bits = (BitStorage) PaperweightPlatformAdapter.fieldStorage.get(blocks);
|
||||
final Palette<BlockState> palette = (Palette<BlockState>) PaperweightPlatformAdapter.fieldPalette.get(blocks);
|
||||
final Object dataObject = PaperweightPlatformAdapter.fieldData.get(blocks);
|
||||
final BitStorage bits = (BitStorage) PaperweightPlatformAdapter.fieldStorage.get(dataObject);
|
||||
|
||||
final int bitsPerEntry = (int) PaperweightPlatformAdapter.fieldBitsPerEntry.get(bits);
|
||||
if (bits instanceof ZeroBitStorage) {
|
||||
Arrays.fill(data, (char) 0);
|
||||
return data;
|
||||
}
|
||||
|
||||
final Palette<BlockState> palette = (Palette<BlockState>) PaperweightPlatformAdapter.fieldPalette.get(dataObject);
|
||||
|
||||
final int bitsPerEntry = bits.getBits();
|
||||
final long[] blockStates = bits.getRaw();
|
||||
|
||||
new BitArrayUnstretched(bitsPerEntry, 4096, blockStates).toRaw(data);
|
||||
@ -924,7 +966,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
|
||||
private char ordinal(net.minecraft.world.level.block.state.BlockState ibd, PaperweightFaweAdapter adapter) {
|
||||
if (ibd == null) {
|
||||
return BlockTypes.AIR.getDefaultState().getOrdinalChar();
|
||||
return 1;
|
||||
} else {
|
||||
return adapter.adaptToChar(ibd);
|
||||
}
|
||||
@ -999,6 +1041,32 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
}
|
||||
}
|
||||
|
||||
private void setBiomesToPalettedContainer(
|
||||
final BiomeType[] biomes,
|
||||
PalettedContainer<Biome> data
|
||||
) {
|
||||
int index = 0;
|
||||
if (biomes == null) {
|
||||
return;
|
||||
}
|
||||
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;
|
||||
}
|
||||
data.set(
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
biomeRegistry.get(ResourceLocation.tryParse(biomeType.getId()))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSection(int layer) {
|
||||
layer -= getMinSectionPosition();
|
||||
@ -1028,8 +1096,10 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
try {
|
||||
final PalettedContainer<net.minecraft.world.level.block.state.BlockState> blocksExisting = existing.getStates();
|
||||
|
||||
final Object dataObject = PaperweightPlatformAdapter.fieldData.get(blocksExisting);
|
||||
//TODO this field doesn't exist in 1.18
|
||||
final Palette<BlockState> palette = (Palette<BlockState>) PaperweightPlatformAdapter.fieldPalette.get(
|
||||
blocksExisting);
|
||||
dataObject);
|
||||
int paletteSize;
|
||||
|
||||
if (palette instanceof LinearPalette || palette instanceof HashMapPalette) {
|
||||
|
@ -18,7 +18,7 @@ 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.ChunkBiomeContainer;
|
||||
import net.minecraft.world.level.chunk.PalettedContainer;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
@ -36,7 +36,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
|
||||
private final int minHeight;
|
||||
private final int maxHeight;
|
||||
private final ServerLevel serverLevel;
|
||||
private ChunkBiomeContainer chunkBiomeContainer;
|
||||
private PalettedContainer<Biome>[] biomes = null;
|
||||
|
||||
protected PaperweightGetBlocks_Copy(ServerLevel world) {
|
||||
this.serverLevel = world;
|
||||
@ -52,8 +52,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
|
||||
blockEntity.getBlockPos().getY(),
|
||||
blockEntity.getBlockPos().getZ()
|
||||
),
|
||||
new PaperweightLazyCompoundTag(Suppliers.memoize(() -> blockEntity.save(new net.minecraft.nbt.CompoundTag())))
|
||||
//TODO 1.18 save -> saveAdditional
|
||||
new PaperweightLazyCompoundTag(Suppliers.memoize(blockEntity::saveWithId))
|
||||
);
|
||||
}
|
||||
|
||||
@ -142,27 +141,9 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
|
||||
return minHeight >> 4;
|
||||
}
|
||||
|
||||
protected void storeBiomes(ChunkBiomeContainer chunkBiomeContainer) {
|
||||
// The to do one line below is pre-paperweight and needs to be revised
|
||||
// TODO revisit last parameter, BiomeStorage[] *would* be more efficient
|
||||
this.chunkBiomeContainer = new ChunkBiomeContainer(chunkBiomeContainer.biomeRegistry, serverLevel,
|
||||
chunkBiomeContainer.writeBiomes()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeType getBiomeType(int x, int y, int z) {
|
||||
Biome biome = null;
|
||||
if (y == -1) {
|
||||
for (y = serverLevel.getMinBuildHeight(); y <= serverLevel.getMaxBuildHeight(); y += 4) {
|
||||
biome = this.chunkBiomeContainer.getNoiseBiome(x >> 2, y >> 2, z >> 2);
|
||||
if (biome != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
biome = this.chunkBiomeContainer.getNoiseBiome(x >> 2, y >> 2, z >> 2);
|
||||
}
|
||||
Biome biome = biomes[(y >> 4) - getMinSectionPosition()].get(x >> 2, (y & 15) >> 2, z >> 2);
|
||||
return biome != null ? PaperweightPlatformAdapter.adapt(biome, serverLevel) : null;
|
||||
}
|
||||
|
||||
@ -189,6 +170,13 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
|
||||
blocks[layer] = data;
|
||||
}
|
||||
|
||||
protected void storeBiomes(int layer, PalettedContainer<Biome> biomeData) {
|
||||
if (biomes == null) {
|
||||
biomes = new PalettedContainer[getSectionCount()];
|
||||
}
|
||||
biomes[layer] = biomeData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getFullBlock(int x, int y, int z) {
|
||||
BlockState state = BlockTypesCache.states[get(x, y, z)];
|
||||
|
@ -4,16 +4,19 @@ import com.fastasyncworldedit.bukkit.adapter.MapChunkUtil;
|
||||
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
||||
import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData;
|
||||
|
||||
public class PaperweightMapChunkUtil extends MapChunkUtil<ClientboundLevelChunkPacketData> {
|
||||
import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
|
||||
|
||||
//TODO un-very-break-this
|
||||
public class PaperweightMapChunkUtil extends MapChunkUtil<ClientboundLevelChunkWithLightPacket> {
|
||||
|
||||
public PaperweightMapChunkUtil() throws NoSuchFieldException {
|
||||
fieldX = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("TWO_MEGABYTES", "a"));
|
||||
fieldZ = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("x", "b"));
|
||||
fieldBitMask = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("z", "c"));
|
||||
fieldHeightMap = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("availableSections", "d"));
|
||||
fieldChunkData = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("biomes", "f"));
|
||||
fieldBlockEntities = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("buffer", "g"));
|
||||
fieldFull = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("blockEntitiesTags", "h"));
|
||||
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);
|
||||
@ -24,7 +27,7 @@ public class PaperweightMapChunkUtil extends MapChunkUtil<ClientboundLevelChunkP
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientboundLevelChunkPacketData createPacket() {
|
||||
public ClientboundLevelChunkWithLightPacket createPacket() {
|
||||
// TODO ??? return new ClientboundLevelChunkPacket();
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ 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.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.math.BitArrayUnstretched;
|
||||
import com.fastasyncworldedit.core.util.MathMan;
|
||||
import com.fastasyncworldedit.core.util.ReflectionUtils;
|
||||
@ -20,68 +19,84 @@ import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.IdMap;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData;
|
||||
import net.minecraft.network.protocol.game.ClientboundLightUpdatePacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
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.util.BitStorage;
|
||||
import net.minecraft.util.SimpleBitStorage;
|
||||
import net.minecraft.util.ThreadingDetector;
|
||||
import net.minecraft.util.ZeroBitStorage;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.Biomes;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.EntityBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.chunk.ChunkBiomeContainer;
|
||||
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.gameevent.GameEventDispatcher;
|
||||
import net.minecraft.world.level.gameevent.GameEventListener;
|
||||
import org.bukkit.craftbukkit.v1_18_R1.CraftChunk;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
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.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
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;
|
||||
public static final Field fieldBits;
|
||||
|
||||
public static final Field fieldBitsPerEntry;
|
||||
|
||||
public static final Field fieldTickingFluidContent;
|
||||
public static final Field fieldTickingBlockCount;
|
||||
public static final Field fieldNonEmptyBlockCount;
|
||||
|
||||
private static final Field fieldBiomes;
|
||||
|
||||
private static final MethodHandle methodGetVisibleChunk;
|
||||
|
||||
private static final int CHUNKSECTION_BASE;
|
||||
private static final int CHUNKSECTION_SHIFT;
|
||||
|
||||
private static final Field fieldThreadingDetector;
|
||||
private static final long fieldThreadingDetectorOffset;
|
||||
|
||||
private static final Field fieldLock;
|
||||
private static final long fieldLockOffset;
|
||||
|
||||
@ -92,15 +107,18 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
|
||||
static {
|
||||
try {
|
||||
fieldBits = PalettedContainer.class.getDeclaredField(Refraction.pickName("bits", "l"));
|
||||
fieldBits.setAccessible(true);
|
||||
fieldStorage = PalettedContainer.class.getDeclaredField(Refraction.pickName("storage", "c"));
|
||||
fieldStorage.setAccessible(true);
|
||||
fieldPalette = PalettedContainer.class.getDeclaredField(Refraction.pickName("palette", "k"));
|
||||
fieldPalette.setAccessible(true);
|
||||
fieldData = PalettedContainer.class.getDeclaredField(Refraction.pickName("data", "d"));
|
||||
fieldData.setAccessible(true);
|
||||
|
||||
fieldBitsPerEntry = BitStorage.class.getDeclaredField(Refraction.pickName("bits", "c"));
|
||||
fieldBitsPerEntry.setAccessible(true);
|
||||
Class<?> dataClazz = fieldData.getType();
|
||||
dataConstructor = dataClazz.getDeclaredConstructors()[0];
|
||||
dataConstructor.setAccessible(true);
|
||||
|
||||
//TODO FIXME 1.18
|
||||
fieldStorage = dataClazz.getDeclaredField(Refraction.pickName("storage", "b"));
|
||||
fieldStorage.setAccessible(true);
|
||||
fieldPalette = dataClazz.getDeclaredField(Refraction.pickName("palette", "c"));
|
||||
fieldPalette.setAccessible(true);
|
||||
|
||||
fieldTickingFluidContent = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingFluidCount", "h"));
|
||||
fieldTickingFluidContent.setAccessible(true);
|
||||
@ -109,27 +127,27 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "f"));
|
||||
fieldNonEmptyBlockCount.setAccessible(true);
|
||||
|
||||
fieldBiomes = ChunkBiomeContainer.class.getDeclaredField(Refraction.pickName("biomes", "f"));
|
||||
fieldBiomes.setAccessible(true);
|
||||
|
||||
Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName(
|
||||
"getVisibleChunkIfPresent",
|
||||
"getVisibleChunk"
|
||||
"b"
|
||||
), long.class);
|
||||
getVisibleChunkIfPresent.setAccessible(true);
|
||||
methodGetVisibleChunk = MethodHandles.lookup().unreflect(getVisibleChunkIfPresent);
|
||||
|
||||
Unsafe unsafe = ReflectionUtils.getUnsafe();
|
||||
fieldLock = PalettedContainer.class.getDeclaredField(Refraction.pickName("lock", "m"));
|
||||
fieldThreadingDetector = PalettedContainer.class.getDeclaredField(Refraction.pickName("threadingDetector", "f"));
|
||||
fieldThreadingDetectorOffset = unsafe.objectFieldOffset(fieldThreadingDetector);
|
||||
|
||||
fieldLock = ThreadingDetector.class.getDeclaredField(Refraction.pickName("lock", "c"));
|
||||
fieldLockOffset = unsafe.objectFieldOffset(fieldLock);
|
||||
|
||||
fieldGameEventDispatcherSections = LevelChunk.class.getDeclaredField(Refraction.pickName(
|
||||
"gameEventDispatcherSections", "x"));
|
||||
"gameEventDispatcherSections", "t"));
|
||||
fieldGameEventDispatcherSections.setAccessible(true);
|
||||
Method removeBlockEntityTicker = LevelChunk.class.getDeclaredMethod(
|
||||
Refraction.pickName(
|
||||
"removeBlockEntityTicker",
|
||||
"l"
|
||||
"m"
|
||||
), BlockPos.class
|
||||
);
|
||||
removeBlockEntityTicker.setAccessible(true);
|
||||
@ -166,18 +184,21 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
}
|
||||
|
||||
static DelegateSemaphore applyLock(LevelChunkSection section) {
|
||||
//todo there has to be a better way to do this. Maybe using a() in DataPaletteBlock which acquires the lock in NMS?
|
||||
try {
|
||||
synchronized (section) {
|
||||
Unsafe unsafe = ReflectionUtils.getUnsafe();
|
||||
PalettedContainer<net.minecraft.world.level.block.state.BlockState> blocks = section.getStates();
|
||||
Semaphore currentLock = (Semaphore) unsafe.getObject(blocks, fieldLockOffset);
|
||||
if (currentLock instanceof DelegateSemaphore) {
|
||||
return (DelegateSemaphore) currentLock;
|
||||
ThreadingDetector currentThreadingDetector = (ThreadingDetector) unsafe.getObject(blocks,
|
||||
fieldThreadingDetectorOffset) ;
|
||||
synchronized(currentThreadingDetector) {
|
||||
Semaphore currentLock = (Semaphore) unsafe.getObject(currentThreadingDetector, fieldLockOffset);
|
||||
if (currentLock instanceof DelegateSemaphore) {
|
||||
return (DelegateSemaphore) currentLock;
|
||||
}
|
||||
DelegateSemaphore newLock = new DelegateSemaphore(1, currentLock);
|
||||
unsafe.putObject(currentThreadingDetector, fieldLockOffset, newLock);
|
||||
return newLock;
|
||||
}
|
||||
DelegateSemaphore newLock = new DelegateSemaphore(1, currentLock);
|
||||
unsafe.putObject(blocks, fieldLockOffset, newLock);
|
||||
return newLock;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
@ -248,21 +269,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
}
|
||||
LevelChunk levelChunk = optional.get();
|
||||
TaskManager.IMP.task(() -> {
|
||||
ClientboundLevelChunkPacketData chunkPacket = new ClientboundLevelChunkPacketData(levelChunk);
|
||||
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(chunkPacket));
|
||||
if (lighting) {
|
||||
//This needs to be true otherwise Minecraft will update lighting from/at the chunk edges (bad)
|
||||
boolean trustEdges = true;
|
||||
ClientboundLightUpdatePacket packet =
|
||||
new ClientboundLightUpdatePacket(coordIntPair, nmsWorld.getChunkSource().getLightEngine(), null, null,
|
||||
trustEdges
|
||||
);
|
||||
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
|
||||
}
|
||||
ClientboundLevelChunkWithLightPacket packet =
|
||||
new ClientboundLevelChunkWithLightPacket(levelChunk, nmsWorld.getChunkSource().getLightEngine(), null, null
|
||||
, true, false); // last false is to not bother with x-ray
|
||||
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
|
||||
});
|
||||
}
|
||||
|
||||
private static Stream<ServerPlayer> nearbyPlayers(ServerLevel serverLevel, ChunkPos coordIntPair) {
|
||||
private static List<ServerPlayer> nearbyPlayers(ServerLevel serverLevel, ChunkPos coordIntPair) {
|
||||
return serverLevel.getChunkSource().chunkMap.getPlayers(coordIntPair, false);
|
||||
}
|
||||
|
||||
@ -271,17 +285,19 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
*/
|
||||
public static LevelChunkSection newChunkSection(
|
||||
final int layer, final char[] blocks, boolean fastmode,
|
||||
CachedBukkitAdapter adapter
|
||||
CachedBukkitAdapter adapter, Registry<Biome> biomeRegistry,
|
||||
@Nullable PalettedContainer<Biome> biomes
|
||||
) {
|
||||
return newChunkSection(layer, null, blocks, fastmode, adapter);
|
||||
return newChunkSection(layer, null, blocks, fastmode, adapter, biomeRegistry, biomes);
|
||||
}
|
||||
|
||||
public static LevelChunkSection newChunkSection(
|
||||
final int layer, final Function<Integer, char[]> get, char[] set,
|
||||
boolean fastmode, CachedBukkitAdapter adapter
|
||||
boolean fastmode, CachedBukkitAdapter adapter, Registry<Biome> biomeRegistry,
|
||||
@Nullable PalettedContainer<Biome> biomes
|
||||
) {
|
||||
if (set == null) {
|
||||
return newChunkSection(layer);
|
||||
return newChunkSection(layer, biomeRegistry, biomes);
|
||||
}
|
||||
final int[] blockToPalette = FaweCache.IMP.BLOCK_TO_PALETTE.get();
|
||||
final int[] paletteToBlock = FaweCache.IMP.PALETTE_TO_BLOCK.get();
|
||||
@ -302,17 +318,18 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
}
|
||||
int num_palette = num_palette_buffer[0];
|
||||
// BlockStates
|
||||
|
||||
int bitsPerEntry = MathMan.log2nlz(num_palette - 1);
|
||||
if (Settings.IMP.PROTOCOL_SUPPORT_FIX || num_palette != 1) {
|
||||
bitsPerEntry = Math.max(bitsPerEntry, 4); // Protocol support breaks <4 bits per entry
|
||||
} else {
|
||||
bitsPerEntry = Math.max(bitsPerEntry, 1); // For some reason minecraft needs 4096 bits to store 0 entries
|
||||
}
|
||||
if (bitsPerEntry > 8) {
|
||||
Object configuration =
|
||||
PalettedContainer.Strategy.SECTION_STATES.getConfiguration(new FakeIdMapBlock(num_palette), bitsPerEntry);
|
||||
if (bitsPerEntry > 0 && bitsPerEntry < 5) {
|
||||
bitsPerEntry = 4;
|
||||
} else if (bitsPerEntry > 8) {
|
||||
bitsPerEntry = MathMan.log2nlz(Block.BLOCK_STATE_REGISTRY.size() - 1);
|
||||
}
|
||||
|
||||
final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntry);
|
||||
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) {
|
||||
@ -320,55 +337,63 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
blockStates[i] = 0;
|
||||
}
|
||||
} else {
|
||||
final BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntry, 4096, blockStates);
|
||||
final BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntryNonZero, 4096, blockStates);
|
||||
bitArray.fromRaw(blocksCopy);
|
||||
}
|
||||
|
||||
LevelChunkSection levelChunkSection = newChunkSection(layer);
|
||||
// set palette & data bits
|
||||
final PalettedContainer<net.minecraft.world.level.block.state.BlockState> dataPaletteBlocks =
|
||||
levelChunkSection.getStates();
|
||||
// private DataPalette<T> h;
|
||||
// protected DataBits a;
|
||||
final long[] bits = Arrays.copyOfRange(blockStates, 0, blockBitArrayEnd);
|
||||
final BitStorage nmsBits = new BitStorage(bitsPerEntry, 4096, bits);
|
||||
final Palette<net.minecraft.world.level.block.state.BlockState> blockStatePalettedContainer;
|
||||
if (bitsPerEntry <= 4) {
|
||||
blockStatePalettedContainer = new LinearPalette<>(Block.BLOCK_STATE_REGISTRY, bitsPerEntry, dataPaletteBlocks,
|
||||
NbtUtils::readBlockState
|
||||
);
|
||||
} else if (bitsPerEntry < 9) {
|
||||
blockStatePalettedContainer = new HashMapPalette<>(
|
||||
Block.BLOCK_STATE_REGISTRY,
|
||||
bitsPerEntry,
|
||||
dataPaletteBlocks,
|
||||
NbtUtils::readBlockState,
|
||||
NbtUtils::writeBlockState
|
||||
);
|
||||
final BitStorage nmsBits;
|
||||
if (bitsPerEntry == 0) {
|
||||
nmsBits = new ZeroBitStorage(4096);
|
||||
} else {
|
||||
blockStatePalettedContainer = LevelChunkSection.GLOBAL_BLOCKSTATE_PALETTE;
|
||||
nmsBits = new SimpleBitStorage(bitsPerEntry, 4096, bits);
|
||||
}
|
||||
|
||||
// set palette if required
|
||||
final Palette<net.minecraft.world.level.block.state.BlockState> blockStatePalette;
|
||||
List<net.minecraft.world.level.block.state.BlockState> palette;
|
||||
if (bitsPerEntry < 9) {
|
||||
palette = new ArrayList<>();
|
||||
for (int i = 0; i < num_palette; i++) {
|
||||
final int ordinal = paletteToBlock[i];
|
||||
int ordinal = paletteToBlock[i];
|
||||
blockToPalette[ordinal] = Integer.MAX_VALUE;
|
||||
final BlockState state = BlockTypesCache.states[ordinal];
|
||||
final net.minecraft.world.level.block.state.BlockState blockState = ((PaperweightBlockMaterial) state.getMaterial()).getState();
|
||||
blockStatePalettedContainer.idFor(blockState);
|
||||
palette.add(((PaperweightBlockMaterial) state.getMaterial()).getState());
|
||||
}
|
||||
} else {
|
||||
palette = List.of();
|
||||
}
|
||||
|
||||
// Create palette with data
|
||||
final PalettedContainer<net.minecraft.world.level.block.state.BlockState> blockStatePalettedContainer =
|
||||
new PalettedContainer<>(
|
||||
Block.BLOCK_STATE_REGISTRY,
|
||||
PalettedContainer.Strategy.SECTION_STATES,
|
||||
PalettedContainer.Strategy.SECTION_STATES.getConfiguration(Block.BLOCK_STATE_REGISTRY, bitsPerEntry),
|
||||
nmsBits,
|
||||
palette,
|
||||
null,
|
||||
null
|
||||
);
|
||||
LevelChunkSection levelChunkSection;
|
||||
try {
|
||||
fieldStorage.set(dataPaletteBlocks, nmsBits);
|
||||
fieldPalette.set(dataPaletteBlocks, blockStatePalettedContainer);
|
||||
fieldBits.set(dataPaletteBlocks, bitsPerEntry);
|
||||
//fieldStorage.set(dataPaletteBlocks, nmsBits);
|
||||
//fieldPalette.set(dataPaletteBlocks, blockStatePalettedContainer);
|
||||
if (biomes == null) {
|
||||
biomes = new PalettedContainer<>(
|
||||
biomeRegistry,
|
||||
biomeRegistry.getOrThrow(Biomes.PLAINS),
|
||||
PalettedContainer.Strategy.SECTION_BIOMES,
|
||||
null
|
||||
);
|
||||
}
|
||||
levelChunkSection = new LevelChunkSection(layer, blockStatePalettedContainer, biomes);
|
||||
setCount(ticking_blocks.size(), 4096 - air, levelChunkSection);
|
||||
if (!fastmode) {
|
||||
ticking_blocks.forEach((pos, ordinal) -> levelChunkSection
|
||||
.setBlockState(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ(),
|
||||
Block.stateById(ordinal)
|
||||
));
|
||||
ticking_blocks.forEach((pos, ordinal) -> levelChunkSection.setBlockState(
|
||||
pos.getBlockX(),
|
||||
pos.getBlockY(),
|
||||
pos.getBlockZ(),
|
||||
Block.stateById(ordinal)
|
||||
));
|
||||
}
|
||||
} catch (final IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
@ -381,8 +406,123 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
private static LevelChunkSection newChunkSection(int layer) {
|
||||
return new LevelChunkSection(layer);
|
||||
private static LevelChunkSection newChunkSection(
|
||||
int layer, Registry<Biome> biomeRegistry,
|
||||
@Nullable PalettedContainer<Biome> biomes
|
||||
) {
|
||||
PalettedContainer<net.minecraft.world.level.block.state.BlockState> dataPaletteBlocks = new PalettedContainer<>(
|
||||
Block.BLOCK_STATE_REGISTRY,
|
||||
Blocks.AIR.defaultBlockState(),
|
||||
PalettedContainer.Strategy.SECTION_STATES,
|
||||
null
|
||||
);
|
||||
PalettedContainer<Biome> biomesPalette = biomes != null ? biomes : new PalettedContainer<>(
|
||||
biomeRegistry,
|
||||
biomeRegistry.getOrThrow(Biomes.PLAINS),
|
||||
PalettedContainer.Strategy.SECTION_BIOMES,
|
||||
null
|
||||
);
|
||||
return new LevelChunkSection(layer, dataPaletteBlocks, biomesPalette);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link PalettedContainer<Biome>}. Should only be used if no biome container existed beforehand.
|
||||
*/
|
||||
public static PalettedContainer<Biome> getBiomePalettedContainer(BiomeType[] biomes, Registry<Biome> biomeRegistry) {
|
||||
if (biomes == null) {
|
||||
return null;
|
||||
}
|
||||
// Don't stream this as typically will see 1-4 biomes; stream overhead is large for the small length
|
||||
Map<BiomeType, Biome> palette = new HashMap<>();
|
||||
for (BiomeType biomeType : new LinkedList<>(Arrays.asList(biomes))) {
|
||||
Biome biome;
|
||||
if (biomeType == null) {
|
||||
biome = biomeRegistry.getOrThrow(Biomes.PLAINS);
|
||||
} else {
|
||||
biome = biomeRegistry.get(ResourceLocation.tryParse(biomeType.getId()));
|
||||
}
|
||||
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<Biome> biomePalettedContainer = new PalettedContainer<>(
|
||||
biomeRegistry,
|
||||
biomeRegistry.getOrThrow(Biomes.PLAINS),
|
||||
PalettedContainer.Strategy.SECTION_BIOMES,
|
||||
null
|
||||
);
|
||||
|
||||
final Palette<Biome> 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;
|
||||
}
|
||||
Biome biome = biomeRegistry.get(ResourceLocation.tryParse(biomeType.getId()));
|
||||
if (biome == null) {
|
||||
continue;
|
||||
}
|
||||
biomePalettedContainer.set(x, y, z, biome);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return biomePalettedContainer;
|
||||
}
|
||||
|
||||
public static void setCount(final int tickingBlockCount, final int nonEmptyBlockCount, final LevelChunkSection section) throws
|
||||
@ -392,15 +532,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
fieldNonEmptyBlockCount.setShort(section, (short) nonEmptyBlockCount);
|
||||
}
|
||||
|
||||
public static Biome[] getBiomeArray(ChunkBiomeContainer chunkBiomeContainer) {
|
||||
try {
|
||||
return (Biome[]) fieldBiomes.get(chunkBiomeContainer);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static BiomeType adapt(Biome biome, LevelAccessor levelAccessor) {
|
||||
ResourceLocation resourceLocation = levelAccessor.registryAccess().ownedRegistryOrThrow(Registry.BIOME_REGISTRY).getKey(
|
||||
biome);
|
||||
@ -415,6 +546,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) {
|
||||
try {
|
||||
// Do the method ourselves to avoid trying to reflect generic method parameters
|
||||
// similar to removeGameEventListener
|
||||
if (levelChunk.loaded || levelChunk.level.isClientSide()) {
|
||||
BlockEntity blockEntity = levelChunk.blockEntities.remove(beacon.getBlockPos());
|
||||
if (blockEntity != null) {
|
||||
@ -446,4 +578,68 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
static class FakeIdMapBlock implements IdMap<net.minecraft.world.level.block.state.BlockState> {
|
||||
|
||||
private final int size;
|
||||
|
||||
FakeIdMapBlock(int size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Iterator<net.minecraft.world.level.block.state.BlockState> iterator() {
|
||||
return Collections.emptyIterator();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class FakeIdMapBiome implements IdMap<Biome> {
|
||||
|
||||
private final int size;
|
||||
|
||||
FakeIdMapBiome(int size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId(final Biome entry) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Biome byId(final int index) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Iterator<Biome> iterator() {
|
||||
return Collections.emptyIterator();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -94,8 +94,9 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag {
|
||||
|
||||
public List<Tag> getList(String key) {
|
||||
net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key);
|
||||
if (tag instanceof net.minecraft.nbt.ListTag nbtList) {
|
||||
if (tag instanceof net.minecraft.nbt.ListTag) {
|
||||
ArrayList<Tag> list = new ArrayList<>();
|
||||
net.minecraft.nbt.ListTag nbtList = (net.minecraft.nbt.ListTag) tag;
|
||||
for (net.minecraft.nbt.Tag elem : nbtList) {
|
||||
if (elem instanceof net.minecraft.nbt.CompoundTag) {
|
||||
list.add(new PaperweightLazyCompoundTag((net.minecraft.nbt.CompoundTag) elem));
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -102,7 +102,6 @@ dependencies {
|
||||
compileOnly(libs.protocollib) { isTransitive = false }
|
||||
compileOnly(libs.plotsquaredV6Bukkit) { isTransitive = false }
|
||||
compileOnly(libs.plotsquaredV6Core) { isTransitive = false }
|
||||
compileOnly(libs.plotsquaredV4) { isTransitive = false }
|
||||
|
||||
// Third party
|
||||
compileOnly(libs.flowmath) {
|
||||
|
@ -310,14 +310,12 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
if (plotSquared == null) {
|
||||
return;
|
||||
}
|
||||
if (plotSquared.getClass().getPackage().toString().contains("intellectualsites")) {
|
||||
WEManager.IMP.addManager(new com.fastasyncworldedit.bukkit.regions.plotsquaredv4.PlotSquaredFeature());
|
||||
LOGGER.info("Plugin 'PlotSquared' found. Using it now.");
|
||||
} else if (PlotSquared.get().getVersion().version[0] == 6) {
|
||||
if (PlotSquared.get().getVersion().version[0] == 6) {
|
||||
WEManager.IMP.addManager(new com.fastasyncworldedit.bukkit.regions.plotsquared.PlotSquaredFeature());
|
||||
LOGGER.info("Plugin 'PlotSquared' found. Using it now.");
|
||||
LOGGER.info("Plugin 'PlotSquared' v6 found. Using it now.");
|
||||
} else {
|
||||
LOGGER.error("Incompatible version of PlotSquared found. Please use PlotSquared v6.");
|
||||
LOGGER.info("https://www.spigotmc.org/resources/77506/");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ public interface IDelegateBukkitImplAdapter<T> extends BukkitImplAdapter<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
default BaseBlock getBlock(Location location) {
|
||||
default BlockState getBlock(Location location) {
|
||||
return getParent().getBlock(location);
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@ import com.fastasyncworldedit.core.FAWEPlatformAdapterImpl;
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||
import com.fastasyncworldedit.core.util.MathMan;
|
||||
import com.fastasyncworldedit.core.world.block.BlockID;
|
||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
@ -24,8 +23,8 @@ public class NMSAdapter implements FAWEPlatformAdapterImpl {
|
||||
int num_palette = 0;
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
char ordinal = set[i];
|
||||
if (ordinal == BlockID.__RESERVED__) {
|
||||
ordinal = BlockID.AIR;
|
||||
if (ordinal == 0) {
|
||||
ordinal = 1;
|
||||
}
|
||||
int palette = blockToPalette[ordinal];
|
||||
if (palette == Integer.MAX_VALUE) {
|
||||
@ -43,17 +42,17 @@ public class NMSAdapter implements FAWEPlatformAdapterImpl {
|
||||
}
|
||||
System.arraycopy(adapter.getOrdinalToIbdID(), 0, blockToPalette, 0, adapter.getOrdinalToIbdID().length);
|
||||
}
|
||||
char lastOrdinal = BlockID.__RESERVED__;
|
||||
char lastOrdinal = 0;
|
||||
boolean lastticking = false;
|
||||
boolean tick_placed = Settings.IMP.EXPERIMENTAL.ALLOW_TICK_PLACED;
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
char ordinal = set[i];
|
||||
switch (ordinal) {
|
||||
case BlockID.__RESERVED__:
|
||||
ordinal = BlockID.AIR;
|
||||
case BlockID.AIR:
|
||||
case BlockID.CAVE_AIR:
|
||||
case BlockID.VOID_AIR:
|
||||
case 0:
|
||||
ordinal = 1;
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
air++;
|
||||
break;
|
||||
default:
|
||||
@ -95,13 +94,13 @@ public class NMSAdapter implements FAWEPlatformAdapterImpl {
|
||||
char[] getArr = null;
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
char ordinal = set[i];
|
||||
if (ordinal == BlockID.__RESERVED__) {
|
||||
if (ordinal == 0) {
|
||||
if (getArr == null) {
|
||||
getArr = get.apply(layer);
|
||||
}
|
||||
ordinal = getArr[i];
|
||||
if (ordinal == BlockID.__RESERVED__) {
|
||||
ordinal = BlockID.AIR;
|
||||
if (ordinal == 0) {
|
||||
ordinal = 1;
|
||||
}
|
||||
}
|
||||
int palette = blockToPalette[ordinal];
|
||||
@ -120,24 +119,24 @@ public class NMSAdapter implements FAWEPlatformAdapterImpl {
|
||||
}
|
||||
System.arraycopy(adapter.getOrdinalToIbdID(), 0, blockToPalette, 0, adapter.getOrdinalToIbdID().length);
|
||||
}
|
||||
char lastOrdinal = BlockID.__RESERVED__;
|
||||
char lastOrdinal = 0;
|
||||
boolean lastticking = false;
|
||||
boolean tick_placed = Settings.IMP.EXPERIMENTAL.ALLOW_TICK_PLACED;
|
||||
boolean tick_existing = Settings.IMP.EXPERIMENTAL.ALLOW_TICK_EXISTING;
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
char ordinal = set[i];
|
||||
switch (ordinal) {
|
||||
case BlockID.__RESERVED__: {
|
||||
case 0: {
|
||||
if (getArr == null) {
|
||||
getArr = get.apply(layer);
|
||||
}
|
||||
ordinal = getArr[i];
|
||||
switch (ordinal) {
|
||||
case BlockID.__RESERVED__:
|
||||
ordinal = BlockID.AIR;
|
||||
case BlockID.AIR:
|
||||
case BlockID.CAVE_AIR:
|
||||
case BlockID.VOID_AIR:
|
||||
case 0:
|
||||
ordinal = 1;
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
air++;
|
||||
break;
|
||||
default:
|
||||
@ -164,9 +163,9 @@ public class NMSAdapter implements FAWEPlatformAdapterImpl {
|
||||
set[i] = ordinal;
|
||||
break;
|
||||
}
|
||||
case BlockID.AIR:
|
||||
case BlockID.CAVE_AIR:
|
||||
case BlockID.VOID_AIR:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
air++;
|
||||
break;
|
||||
}
|
||||
|
@ -4,9 +4,6 @@ import com.fastasyncworldedit.core.FaweAPI;
|
||||
import com.fastasyncworldedit.core.configuration.Caption;
|
||||
import com.fastasyncworldedit.core.regions.FaweMask;
|
||||
import com.fastasyncworldedit.core.regions.FaweMaskManager;
|
||||
import com.fastasyncworldedit.core.regions.filter.RegionFilter;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler;
|
||||
import com.plotsquared.core.PlotSquared;
|
||||
import com.plotsquared.core.configuration.Settings;
|
||||
import com.plotsquared.core.database.DBFunc;
|
||||
import com.plotsquared.core.player.PlotPlayer;
|
||||
@ -62,6 +59,15 @@ public class PlotSquaredFeature extends FaweMaskManager {
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the player is allowed to use FAWE on a PlotSquared plot.
|
||||
*
|
||||
* @param player the {@link Player}
|
||||
* @param plot the {@link Plot}
|
||||
* @param type the {@link MaskType}
|
||||
* @return {@code true} if the player is the plot owner, trusted, has the permission fawe.plotsquared.member
|
||||
* or fawe.plotsquared.admin and the NoWorldeditFlag is not set; otherwise {@code false}
|
||||
*/
|
||||
public boolean isAllowed(Player player, Plot plot, MaskType type) {
|
||||
if (plot == null) {
|
||||
return false;
|
||||
|
@ -1,172 +0,0 @@
|
||||
package com.fastasyncworldedit.bukkit.regions.plotsquaredv4;
|
||||
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.util.TaskManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Location;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.ChunkManager;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.bukkit.Bukkit.getWorld;
|
||||
|
||||
public class FaweChunkManager extends ChunkManager {
|
||||
|
||||
private final ChunkManager parent;
|
||||
|
||||
public FaweChunkManager(ChunkManager parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] countEntities(Plot plot) {
|
||||
return parent.countEntities(plot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture loadChunk(String world, BlockVector2 loc, boolean force) {
|
||||
return parent.loadChunk(world, loc, force);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unloadChunk(String world, BlockVector2 loc, boolean save) {
|
||||
parent.unloadChunk(world, loc, save);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearAllEntities(Location pos1, Location pos2) {
|
||||
parent.clearAllEntities(pos1, pos2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void swap(
|
||||
final Location pos1,
|
||||
final Location pos2,
|
||||
final Location pos3,
|
||||
final Location pos4,
|
||||
final Runnable whenDone
|
||||
) {
|
||||
if (!Settings.IMP.PLOTSQUARED_INTEGRATION.COPY_AND_SWAP) {
|
||||
parent.swap(pos1, pos2, pos3, pos4, whenDone);
|
||||
}
|
||||
TaskManager.IMP.async(() -> {
|
||||
synchronized (FaweChunkManager.class) {
|
||||
//todo because of the following code this should proably be in the Bukkit module
|
||||
World pos1World = BukkitAdapter.adapt(getWorld(pos1.getWorld()));
|
||||
World pos3World = BukkitAdapter.adapt(getWorld(pos3.getWorld()));
|
||||
EditSession sessionA = WorldEdit.getInstance().newEditSessionBuilder().world(pos1World)
|
||||
.checkMemory(false)
|
||||
.fastMode(true)
|
||||
.limitUnlimited()
|
||||
.changeSetNull()
|
||||
.build();
|
||||
EditSession sessionB = WorldEdit.getInstance().newEditSessionBuilder().world(pos3World)
|
||||
.checkMemory(false)
|
||||
.fastMode(true)
|
||||
.limitUnlimited()
|
||||
.changeSetNull()
|
||||
.build();
|
||||
CuboidRegion regionA = new CuboidRegion(
|
||||
BlockVector3.at(pos1.getX(), pos1.getY(), pos1.getZ()),
|
||||
BlockVector3.at(pos2.getX(), pos2.getY(), pos2.getZ())
|
||||
);
|
||||
CuboidRegion regionB = new CuboidRegion(
|
||||
BlockVector3.at(pos3.getX(), pos3.getY(), pos3.getZ()),
|
||||
BlockVector3.at(pos4.getX(), pos4.getY(), pos4.getZ())
|
||||
);
|
||||
ForwardExtentCopy copyA = new ForwardExtentCopy(sessionA, regionA, sessionB, regionB.getMinimumPoint());
|
||||
ForwardExtentCopy copyB = new ForwardExtentCopy(sessionB, regionB, sessionA, regionA.getMinimumPoint());
|
||||
try {
|
||||
Operations.completeLegacy(copyA);
|
||||
Operations.completeLegacy(copyB);
|
||||
sessionA.flushQueue();
|
||||
sessionB.flushQueue();
|
||||
} catch (MaxChangedBlocksException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
TaskManager.IMP.task(whenDone);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean copyRegion(final Location pos1, final Location pos2, final Location pos3, final Runnable whenDone) {
|
||||
if (!Settings.IMP.PLOTSQUARED_INTEGRATION.COPY_AND_SWAP) {
|
||||
return parent.copyRegion(pos1, pos2, pos3, whenDone);
|
||||
}
|
||||
TaskManager.IMP.async(() -> {
|
||||
synchronized (FaweChunkManager.class) {
|
||||
World pos1World = BukkitAdapter.adapt(getWorld(pos1.getWorld()));
|
||||
World pos3World = BukkitAdapter.adapt(getWorld(pos3.getWorld()));
|
||||
EditSession from = WorldEdit.getInstance().newEditSessionBuilder().world(pos1World)
|
||||
.checkMemory(false)
|
||||
.fastMode(true)
|
||||
.limitUnlimited()
|
||||
.changeSetNull()
|
||||
.build();
|
||||
EditSession to = WorldEdit.getInstance().newEditSessionBuilder().world(pos3World)
|
||||
.checkMemory(false)
|
||||
.fastMode(true)
|
||||
.limitUnlimited()
|
||||
.changeSetNull()
|
||||
.build();
|
||||
CuboidRegion region = new CuboidRegion(
|
||||
BlockVector3.at(pos1.getX(), pos1.getY(), pos1.getZ()),
|
||||
BlockVector3.at(pos2.getX(), pos2.getY(), pos2.getZ())
|
||||
);
|
||||
ForwardExtentCopy copy = new ForwardExtentCopy(
|
||||
from,
|
||||
region,
|
||||
to,
|
||||
BlockVector3.at(pos3.getX(), pos3.getY(), pos3.getZ())
|
||||
);
|
||||
try {
|
||||
Operations.completeLegacy(copy);
|
||||
to.flushQueue();
|
||||
} catch (MaxChangedBlocksException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
TaskManager.IMP.task(whenDone);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean regenerateRegion(final Location pos1, final Location pos2, boolean ignore, final Runnable whenDone) {
|
||||
TaskManager.IMP.async(() -> {
|
||||
synchronized (FaweChunkManager.class) {
|
||||
World pos1World = BukkitAdapter.adapt(getWorld(pos1.getWorld()));
|
||||
try (EditSession editSession = WorldEdit
|
||||
.getInstance()
|
||||
.newEditSessionBuilder()
|
||||
.world(pos1World)
|
||||
.checkMemory(false)
|
||||
.fastMode(true)
|
||||
.limitUnlimited()
|
||||
.changeSetNull()
|
||||
.build()) {
|
||||
CuboidRegion region = new CuboidRegion(
|
||||
BlockVector3.at(pos1.getX(), pos1.getY(), pos1.getZ()),
|
||||
BlockVector3.at(pos2.getX(), pos2.getY(), pos2.getZ())
|
||||
);
|
||||
editSession.regenerate(region);
|
||||
editSession.flushQueue();
|
||||
}
|
||||
TaskManager.IMP.task(whenDone);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,131 +0,0 @@
|
||||
package com.fastasyncworldedit.bukkit.regions.plotsquaredv4;
|
||||
|
||||
import com.fastasyncworldedit.core.Fawe;
|
||||
import com.fastasyncworldedit.core.FaweAPI;
|
||||
import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.math.MutableBlockVector3;
|
||||
import com.fastasyncworldedit.core.queue.IQueueChunk;
|
||||
import com.fastasyncworldedit.core.queue.IQueueExtent;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
|
||||
// TODO FIXME
|
||||
public class FaweLocalBlockQueue extends LocalBlockQueue {
|
||||
|
||||
public final IQueueExtent<IQueueChunk> instance;
|
||||
private final World world;
|
||||
private final BlockVector3 mutable = new MutableBlockVector3();
|
||||
|
||||
public FaweLocalBlockQueue(String worldName) {
|
||||
super(worldName);
|
||||
this.world = FaweAPI.getWorld(worldName);
|
||||
instance = Fawe.get().getQueueHandler().getQueue(world);
|
||||
Fawe.get().getQueueHandler().unCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean next() {
|
||||
if (!instance.isEmpty()) {
|
||||
instance.flush();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startSet(boolean parallel) {
|
||||
Fawe.get().getQueueHandler().startSet(parallel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endSet(boolean parallel) {
|
||||
Fawe.get().getQueueHandler().endSet(parallel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return instance.isEmpty() ? 0 : 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void optimize() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModified(long l) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getModified() {
|
||||
return instance.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(final int x, final int y, final int z, final BlockState id) {
|
||||
return instance.setBlock(x, y, z, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(int x, int y, int z, Pattern pattern) {
|
||||
mutable.setComponents(x, y, z);
|
||||
return pattern.apply(instance, mutable, mutable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(final int x, final int y, final int z, final BaseBlock id) {
|
||||
return instance.setBlock(x, y, z, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlock(int x, int y, int z) {
|
||||
return instance.getBlock(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(int x, int z, BiomeType biomeType) {
|
||||
return instance.setBiome(x, 0, z, biomeType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWorld() {
|
||||
return world.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
instance.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean enqueue() {
|
||||
boolean val = super.enqueue();
|
||||
instance.enableQueue();
|
||||
return val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshChunk(int x, int z) {
|
||||
world.refreshChunk(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fixChunkLighting(int x, int z) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void regenChunk(int x, int z) {
|
||||
instance.regenerateChunk(x, z, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setTile(int x, int y, int z, CompoundTag tag) {
|
||||
instance.setTile(x, y, z, (com.sk89q.jnbt.CompoundTag) FaweCache.IMP.asTag(tag));
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,154 +0,0 @@
|
||||
package com.fastasyncworldedit.bukkit.regions.plotsquaredv4;
|
||||
|
||||
import com.fastasyncworldedit.core.FaweAPI;
|
||||
import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.ReadOnlyClipboard;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicWriter;
|
||||
import com.fastasyncworldedit.core.jnbt.CompressedCompoundTag;
|
||||
import com.fastasyncworldedit.core.jnbt.CompressedSchematicTag;
|
||||
import com.fastasyncworldedit.core.util.IOUtil;
|
||||
import com.fastasyncworldedit.core.util.TaskManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Location;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.RunnableVal;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.NBTOutputStream;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||
import org.anarres.parallelgzip.ParallelGZIPOutputStream;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.bukkit.Bukkit.getWorld;
|
||||
|
||||
public class FaweSchematicHandler extends SchematicHandler {
|
||||
|
||||
@Override
|
||||
public boolean restoreTile(LocalBlockQueue queue, CompoundTag compoundTag, int x, int y, int z) {
|
||||
if (queue instanceof FaweLocalBlockQueue) {
|
||||
queue.setTile(x, y, z, compoundTag);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getCompoundTag(final String world, final Set<CuboidRegion> regions, final RunnableVal<CompoundTag> whenDone) {
|
||||
TaskManager.IMP.async(() -> {
|
||||
Location[] corners = MainUtil.getCorners(world, regions);
|
||||
Location pos1 = corners[0];
|
||||
Location pos2 = corners[1];
|
||||
World adaptedWorld = BukkitAdapter.adapt(getWorld(world));
|
||||
final CuboidRegion region = new CuboidRegion(
|
||||
BlockVector3.at(pos1.getX(), pos1.getY(), pos1.getZ()),
|
||||
BlockVector3.at(pos2.getX(), pos2.getY(), pos2.getZ())
|
||||
);
|
||||
final EditSession editSession = WorldEdit.getInstance().newEditSessionBuilder().world(adaptedWorld)
|
||||
.checkMemory(false)
|
||||
.fastMode(true)
|
||||
.limitUnlimited()
|
||||
.changeSetNull()
|
||||
.build();
|
||||
|
||||
ReadOnlyClipboard clipboard = ReadOnlyClipboard.of(editSession, region, false, true);
|
||||
|
||||
Clipboard holder = new BlockArrayClipboard(region, clipboard);
|
||||
|
||||
CompressedSchematicTag tag = new CompressedSchematicTag(holder);
|
||||
whenDone.run(tag);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean save(CompoundTag tag, String path) {
|
||||
if (tag == null) {
|
||||
PlotSquared.debug("&cCannot save empty tag");
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
File tmp = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), path);
|
||||
tmp.getParentFile().mkdirs();
|
||||
if (tag instanceof CompressedCompoundTag) {
|
||||
CompressedCompoundTag cTag = (CompressedCompoundTag) tag;
|
||||
if (cTag instanceof CompressedSchematicTag) {
|
||||
Clipboard clipboard = (Clipboard) cTag.getSource();
|
||||
try (OutputStream stream = new FileOutputStream(tmp); NBTOutputStream output = new NBTOutputStream(new BufferedOutputStream(
|
||||
new ParallelGZIPOutputStream(stream)))) {
|
||||
new FastSchematicWriter(output).write(clipboard);
|
||||
}
|
||||
} else {
|
||||
try (OutputStream stream = new FileOutputStream(tmp); BufferedOutputStream output = new BufferedOutputStream(
|
||||
new ParallelGZIPOutputStream(stream))) {
|
||||
LZ4BlockInputStream is = cTag.adapt(cTag.getSource());
|
||||
IOUtil.copy(is, stream);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try (OutputStream stream = new FileOutputStream(tmp); NBTOutputStream output = new NBTOutputStream(new ParallelGZIPOutputStream(
|
||||
stream))) {
|
||||
Map<String, Tag> map = tag.getValue();
|
||||
output.writeNamedTag("Schematic", map.getOrDefault("Schematic", tag));
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void upload(final CompoundTag tag, final UUID uuid, final String file, final RunnableVal<URL> whenDone) {
|
||||
if (tag == null) {
|
||||
PlotSquared.debug("&cCannot save empty tag");
|
||||
com.github.intellectualsites.plotsquared.plot.util.TaskManager.runTask(whenDone);
|
||||
return;
|
||||
}
|
||||
CompoundTag weTag = (CompoundTag) FaweCache.IMP.asTag(tag);
|
||||
if (weTag instanceof CompressedSchematicTag) {
|
||||
Clipboard clipboard = ((CompressedSchematicTag) weTag).getSource();
|
||||
URL url = FaweAPI.upload(clipboard, BuiltInClipboardFormat.SPONGE_SCHEMATIC);
|
||||
whenDone.run(url);
|
||||
return;
|
||||
}
|
||||
MainUtil.upload(uuid, file, "schem", new RunnableVal<OutputStream>() {
|
||||
@Override
|
||||
public void run(OutputStream output) {
|
||||
try {
|
||||
try (ParallelGZIPOutputStream gzip = new ParallelGZIPOutputStream(output)) {
|
||||
try (NBTOutputStream nos = new NBTOutputStream(gzip)) {
|
||||
Map<String, Tag> map = weTag.getValue();
|
||||
nos.writeNamedTag("Schematic", map.getOrDefault("Schematic", weTag));
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}, whenDone);
|
||||
}
|
||||
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
package com.fastasyncworldedit.bukkit.regions.plotsquaredv4;
|
||||
|
||||
import com.fastasyncworldedit.core.util.TaskManager;
|
||||
import com.github.intellectualsites.plotsquared.commands.CommandDeclaration;
|
||||
import com.github.intellectualsites.plotsquared.plot.commands.CommandCategory;
|
||||
import com.github.intellectualsites.plotsquared.plot.commands.RequiredType;
|
||||
import com.github.intellectualsites.plotsquared.plot.commands.SubCommand;
|
||||
import com.github.intellectualsites.plotsquared.plot.config.Captions;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.WorldUtil;
|
||||
|
||||
@CommandDeclaration(
|
||||
command = "trimchunks",
|
||||
permission = "plots.admin",
|
||||
description = "Delete unmodified portions of your plotworld",
|
||||
requiredType = RequiredType.PLAYER,
|
||||
category = CommandCategory.ADMINISTRATION)
|
||||
public class FaweTrim extends SubCommand {
|
||||
|
||||
private boolean ran = false;
|
||||
|
||||
@Override
|
||||
public boolean onCommand(final PlotPlayer plotPlayer, final String[] strings) {
|
||||
if (ran) {
|
||||
plotPlayer.sendMessage("Already running!");
|
||||
return false;
|
||||
}
|
||||
if (strings.length != 2) {
|
||||
plotPlayer.sendMessage(
|
||||
"First make a backup of your world called <world-copy> then stand in the middle of an empty plot");
|
||||
plotPlayer.sendMessage("use /plot trimall <world> <boolean-delete-unowned>");
|
||||
return false;
|
||||
}
|
||||
if (!WorldUtil.IMP.isWorld(strings[0])) {
|
||||
Captions.NOT_VALID_PLOT_WORLD.send(plotPlayer, strings[0]);
|
||||
return false;
|
||||
}
|
||||
ran = true;
|
||||
TaskManager.IMP.async(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// TODO NOT IMPLEMENTED
|
||||
// PlotTrim trim = new PlotTrim(plotPlayer, plotPlayer.getPlotAreaAbs(), strings[0], Boolean.parseBoolean(strings[1]));
|
||||
// Location loc = plotPlayer.getLocation();
|
||||
// trim.setChunk(loc.getX() >> 4, loc.getZ() >> 4);
|
||||
// trim.run();
|
||||
// plotPlayer.sendMessage("Done!");
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
ran = false;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
package com.fastasyncworldedit.bukkit.regions.plotsquaredv4;
|
||||
|
||||
import com.fastasyncworldedit.core.util.TaskManager;
|
||||
import com.github.intellectualsites.plotsquared.commands.Command;
|
||||
import com.github.intellectualsites.plotsquared.commands.CommandDeclaration;
|
||||
import com.github.intellectualsites.plotsquared.plot.commands.CommandCategory;
|
||||
import com.github.intellectualsites.plotsquared.plot.commands.MainCommand;
|
||||
import com.github.intellectualsites.plotsquared.plot.commands.RequiredType;
|
||||
import com.github.intellectualsites.plotsquared.plot.config.Captions;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.RunnableVal2;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.RunnableVal3;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.Permissions;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.StringMan;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||
import com.sk89q.worldedit.world.biome.Biomes;
|
||||
import com.sk89q.worldedit.world.registry.BiomeRegistry;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
@CommandDeclaration(
|
||||
command = "generatebiome",
|
||||
permission = "plots.generatebiome",
|
||||
category = CommandCategory.APPEARANCE,
|
||||
requiredType = RequiredType.NONE,
|
||||
description = "Generate a biome in your plot",
|
||||
aliases = {"bg", "gb"},
|
||||
usage = "/plots generatebiome <biome>"
|
||||
)
|
||||
public class PlotSetBiome extends Command {
|
||||
|
||||
public PlotSetBiome() {
|
||||
super(MainCommand.getInstance(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> execute(
|
||||
final PlotPlayer player,
|
||||
String[] args,
|
||||
RunnableVal3<Command, Runnable, Runnable> confirm,
|
||||
RunnableVal2<Command, CommandResult> whenDone
|
||||
) throws CommandException {
|
||||
final Plot plot = check(player.getCurrentPlot(), Captions.NOT_IN_PLOT);
|
||||
checkTrue(plot.isOwner(player.getUUID()) || Permissions
|
||||
.hasPermission(player, "plots.admin.command.generatebiome"), Captions.NO_PLOT_PERMS);
|
||||
if (plot.getRunning() != 0) {
|
||||
Captions.WAIT_FOR_TIMER.send(player);
|
||||
return null;
|
||||
}
|
||||
checkTrue(args.length == 1, Captions.COMMAND_SYNTAX, getUsage());
|
||||
final Set<CuboidRegion> regions = plot.getRegions();
|
||||
BiomeRegistry biomeRegistry = WorldEdit
|
||||
.getInstance()
|
||||
.getPlatformManager()
|
||||
.queryCapability(Capability.GAME_HOOKS)
|
||||
.getRegistries()
|
||||
.getBiomeRegistry();
|
||||
Collection<BiomeType> knownBiomes = BiomeTypes.values();
|
||||
final BiomeType biome = Biomes.findBiomeByName(knownBiomes, args[0], biomeRegistry);
|
||||
if (biome == null) {
|
||||
String biomes = StringMan
|
||||
.join(BiomeType.REGISTRY.values(), Captions.BLOCK_LIST_SEPARATOR.getTranslated());
|
||||
Captions.NEED_BIOME.send(player);
|
||||
MainUtil.sendMessage(player, Captions.SUBCOMMAND_SET_OPTIONS_HEADER + biomes);
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
confirm.run(this, () -> {
|
||||
if (plot.getRunning() != 0) {
|
||||
Captions.WAIT_FOR_TIMER.send(player);
|
||||
return;
|
||||
}
|
||||
plot.addRunning();
|
||||
TaskManager.IMP.async(() -> {
|
||||
EditSession session = WorldEdit.getInstance().newEditSessionBuilder().world(BukkitAdapter.adapt(Bukkit.getWorld(
|
||||
plot.getArea().worldname)))
|
||||
.checkMemory(false)
|
||||
.allowedRegionsEverywhere()
|
||||
.actor(BukkitAdapter.adapt(Bukkit.getPlayer(player.getUUID())))
|
||||
.limitUnlimited()
|
||||
.build();
|
||||
long seed = ThreadLocalRandom.current().nextLong();
|
||||
for (CuboidRegion region : regions) {
|
||||
session.regenerate(region, biome, seed);
|
||||
}
|
||||
session.flushQueue();
|
||||
plot.removeRunning();
|
||||
});
|
||||
}, null);
|
||||
|
||||
return CompletableFuture.completedFuture(true);
|
||||
}
|
||||
|
||||
}
|
@ -1,225 +0,0 @@
|
||||
package com.fastasyncworldedit.bukkit.regions.plotsquaredv4;
|
||||
|
||||
import com.fastasyncworldedit.core.FaweAPI;
|
||||
import com.fastasyncworldedit.core.configuration.Caption;
|
||||
import com.fastasyncworldedit.core.regions.FaweMask;
|
||||
import com.fastasyncworldedit.core.regions.FaweMaskManager;
|
||||
import com.fastasyncworldedit.core.regions.RegionWrapper;
|
||||
import com.github.intellectualsites.plotsquared.plot.commands.MainCommand;
|
||||
import com.github.intellectualsites.plotsquared.plot.config.Settings;
|
||||
import com.github.intellectualsites.plotsquared.plot.database.DBFunc;
|
||||
import com.github.intellectualsites.plotsquared.plot.flag.Flags;
|
||||
import com.github.intellectualsites.plotsquared.plot.listener.WEManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.ChunkManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.regions.RegionIntersection;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PlotSquaredFeature extends FaweMaskManager {
|
||||
|
||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||
|
||||
public PlotSquaredFeature() {
|
||||
super("PlotSquared");
|
||||
LOGGER.info("Optimizing PlotSquared");
|
||||
if (com.fastasyncworldedit.core.configuration.Settings.IMP.ENABLED_COMPONENTS.PLOTSQUARED_V4_HOOK) {
|
||||
Settings.Enabled_Components.WORLDEDIT_RESTRICTIONS = false;
|
||||
try {
|
||||
setupBlockQueue();
|
||||
setupSchematicHandler();
|
||||
setupChunkManager();
|
||||
} catch (Throwable ignored) {
|
||||
LOGGER.info("Please update PlotSquared: https://www.spigotmc.org/resources/77506/");
|
||||
}
|
||||
if (Settings.PLATFORM.toLowerCase(Locale.ROOT).startsWith("bukkit")) {
|
||||
new FaweTrim();
|
||||
}
|
||||
if (MainCommand.getInstance().getCommand("generatebiome") == null) {
|
||||
new PlotSetBiome();
|
||||
}
|
||||
}
|
||||
// TODO: revisit this later on
|
||||
/*
|
||||
try {
|
||||
if (Settings.Enabled_Components.WORLDS) {
|
||||
new ReplaceAll();
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
log.debug("You need to update PlotSquared to access the CFI and REPLACEALL commands");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public static String getName(UUID uuid) {
|
||||
return UUIDHandler.getName(uuid);
|
||||
}
|
||||
|
||||
private void setupBlockQueue() throws RuntimeException {
|
||||
// If it's going to fail, throw an error now rather than later
|
||||
//QueueProvider provider = QueueProvider.of(FaweLocalBlockQueue.class, null);
|
||||
//GlobalBlockQueue.IMP.setProvider(provider);
|
||||
//HybridPlotManager.REGENERATIVE_CLEAR = false;
|
||||
//log.debug(" - QueueProvider: " + FaweLocalBlockQueue.class);
|
||||
//log.debug(" - HybridPlotManager.REGENERATIVE_CLEAR: " + HybridPlotManager.REGENERATIVE_CLEAR);
|
||||
}
|
||||
|
||||
private void setupChunkManager() throws RuntimeException {
|
||||
ChunkManager.manager = new FaweChunkManager(ChunkManager.manager);
|
||||
LOGGER.info(" - ChunkManager: {}", ChunkManager.manager);
|
||||
}
|
||||
|
||||
private void setupSchematicHandler() throws RuntimeException {
|
||||
SchematicHandler.manager = new FaweSchematicHandler();
|
||||
LOGGER.info(" - SchematicHandler: {}", SchematicHandler.manager);
|
||||
}
|
||||
|
||||
public boolean isAllowed(Player player, Plot plot, MaskType type) {
|
||||
if (plot == null) {
|
||||
return false;
|
||||
}
|
||||
UUID uid = player.getUniqueId();
|
||||
if (Flags.NO_WORLDEDIT.isTrue(plot)) {
|
||||
player.print(Caption.of(
|
||||
"fawe.cancel.reason.no.region.reason",
|
||||
Caption.of("fawe.cancel.reason.no.region.plot.noworldeditflag")
|
||||
));
|
||||
return false;
|
||||
}
|
||||
if (plot.isOwner(uid) || player.hasPermission("fawe.plotsquared.admin")) {
|
||||
return true;
|
||||
}
|
||||
if (type != MaskType.MEMBER) {
|
||||
player.print(Caption.of(
|
||||
"fawe.cancel.reason.no.region.reason",
|
||||
Caption.of("fawe.cancel.reason.no.region.plot.owner.only")
|
||||
));
|
||||
return false;
|
||||
}
|
||||
if (plot.getTrusted().contains(uid) || plot.getTrusted().contains(DBFunc.EVERYONE)) {
|
||||
return true;
|
||||
}
|
||||
if (plot.getMembers().contains(uid) || plot.getMembers().contains(DBFunc.EVERYONE)) {
|
||||
if (!player.hasPermission("fawe.plotsquared.member")) {
|
||||
player.print(Caption.of(
|
||||
"fawe.cancel.reason.no.region.reason",
|
||||
Caption.of("fawe.error.no-perm", "fawe.plotsquared.member")
|
||||
));
|
||||
return false;
|
||||
}
|
||||
if (!plot.getOwners().isEmpty() && plot.getOwners().stream().anyMatch(this::playerOnline)) {
|
||||
return true;
|
||||
} else {
|
||||
player.print(Caption.of(
|
||||
"fawe.cancel.reason.no.region.reason",
|
||||
Caption.of("fawe.cancel.reason.no.region.plot.owner.offline")
|
||||
));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
player.print(Caption.of(
|
||||
"fawe.cancel.reason.no.region.reason",
|
||||
Caption.of("fawe.cancel.reason.no.region.not.added")
|
||||
));
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean playerOnline(UUID uuid) {
|
||||
if (uuid == null) {
|
||||
return false;
|
||||
}
|
||||
org.bukkit.entity.Player player = Bukkit.getPlayer(uuid);
|
||||
return player != null && player.isOnline();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweMask getMask(Player player, MaskType type) {
|
||||
final PlotPlayer pp = PlotPlayer.wrap(player.getUniqueId());
|
||||
if (pp == null) {
|
||||
return null;
|
||||
}
|
||||
final Set<CuboidRegion> regions;
|
||||
Plot plot = pp.getCurrentPlot();
|
||||
if (isAllowed(player, plot, type)) {
|
||||
regions = plot.getRegions();
|
||||
} else {
|
||||
plot = null;
|
||||
regions = WEManager.getMask(pp);
|
||||
if (regions.size() == 1) {
|
||||
CuboidRegion region = regions.iterator().next();
|
||||
if (region.getMinimumPoint().getX() == Integer.MIN_VALUE && region
|
||||
.getMaximumPoint()
|
||||
.getX() == Integer.MAX_VALUE) {
|
||||
regions.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (regions.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
PlotArea area = pp.getApplicablePlotArea();
|
||||
int min = area != null ? area.MIN_BUILD_HEIGHT : 0;
|
||||
int max = area != null ? Math.min(255, area.MAX_BUILD_HEIGHT) : 255;
|
||||
final HashSet<RegionWrapper> faweRegions = new HashSet<>();
|
||||
for (CuboidRegion current : regions) {
|
||||
faweRegions.add(new RegionWrapper(
|
||||
current.getMinimumX(),
|
||||
current.getMaximumX(),
|
||||
min,
|
||||
max,
|
||||
current.getMinimumZ(),
|
||||
current.getMaximumZ()
|
||||
));
|
||||
}
|
||||
final CuboidRegion region = regions.iterator().next();
|
||||
final BlockVector3 pos1 = BlockVector3.at(region.getMinimumX(), min, region.getMinimumZ());
|
||||
final BlockVector3 pos2 = BlockVector3.at(region.getMaximumX(), max, region.getMaximumZ());
|
||||
final Plot finalPlot = plot;
|
||||
if (Settings.Done.RESTRICT_BUILDING && Flags.DONE.isSet(finalPlot) || regions.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Region maskedRegion;
|
||||
if (regions.size() == 1) {
|
||||
maskedRegion = new CuboidRegion(pos1, pos2);
|
||||
} else {
|
||||
World world = FaweAPI.getWorld(area.worldname);
|
||||
List<Region> weRegions = regions.stream()
|
||||
.map(r -> new CuboidRegion(
|
||||
world,
|
||||
BlockVector3.at(r.getMinimumX(), r.getMinimumY(), r.getMinimumZ()),
|
||||
BlockVector3.at(r.getMaximumX(), r.getMaximumY(), r.getMaximumZ())
|
||||
))
|
||||
.collect(Collectors.toList());
|
||||
maskedRegion = new RegionIntersection(world, weRegions);
|
||||
}
|
||||
|
||||
return new FaweMask(maskedRegion) {
|
||||
@Override
|
||||
public boolean isValid(Player player, MaskType type) {
|
||||
if (Settings.Done.RESTRICT_BUILDING && Flags.DONE.isSet(finalPlot)) {
|
||||
return false;
|
||||
}
|
||||
return isAllowed(player, finalPlot, type);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -520,7 +520,7 @@ public class BukkitWorld extends AbstractWorld {
|
||||
public BaseBlock getFullBlock(BlockVector3 position) {
|
||||
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
|
||||
if (adapter != null) {
|
||||
return adapter.getBlock(BukkitAdapter.adapt(getWorld(), position));
|
||||
return adapter.getFullBlock(BukkitAdapter.adapt(getWorld(), position));
|
||||
} else {
|
||||
return getBlock(position).toBaseBlock();
|
||||
}
|
||||
|
@ -138,12 +138,12 @@ public class WorldEditPlugin extends JavaPlugin {
|
||||
platform = new BukkitServerInterface(this, getServer());
|
||||
worldEdit.getPlatformManager().register(platform);
|
||||
|
||||
//FAWE start - Rename config to config-legacy.yml TODO: Chose a better name in the future
|
||||
createDefaultConfiguration("config-legacy.yml"); // Create the default configuration file for WorldEdit, for us it's 'config-legacy.yml'
|
||||
//FAWE start - Migrate from config-legacy to worldedit-config
|
||||
migrateLegacyConfig();
|
||||
//FAWE end
|
||||
|
||||
//FAWE start - Modify WorldEdit config name
|
||||
config = new BukkitConfiguration(new YAMLProcessor(new File(getDataFolder(), "config-legacy.yml"), true), this);
|
||||
config = new BukkitConfiguration(new YAMLProcessor(new File(getDataFolder(), "worldedit-config.yml"), true), this);
|
||||
//FAWE end
|
||||
|
||||
//FAWE start - Setup permission attachments
|
||||
@ -422,6 +422,19 @@ public class WorldEditPlugin extends JavaPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
private void migrateLegacyConfig() {
|
||||
File legacy = new File(getDataFolder(), "config-legacy.yml");
|
||||
if (legacy.exists()) {
|
||||
try {
|
||||
legacy.renameTo(new File(getDataFolder(), "worldedit-config.yml"));
|
||||
LOGGER.info("Migrated config-legacy.yml to worldedit-config.yml");
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Unable to rename legacy config file", e);
|
||||
}
|
||||
}
|
||||
createDefaultConfiguration("worldedit-config.yml");
|
||||
}
|
||||
|
||||
private void copyDefaultConfig(InputStream input, File actual, String name) {
|
||||
try (FileOutputStream output = new FileOutputStream(actual)) {
|
||||
byte[] buf = new byte[8192];
|
||||
|
@ -106,7 +106,15 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
|
||||
* @param location the location
|
||||
* @return the block
|
||||
*/
|
||||
BaseBlock getBlock(Location location);
|
||||
BlockState getBlock(Location location);
|
||||
|
||||
/**
|
||||
* Get the block at the given location.
|
||||
*
|
||||
* @param location the location
|
||||
* @return the block
|
||||
*/
|
||||
BaseBlock getFullBlock(Location location);
|
||||
|
||||
/**
|
||||
* Create a {@link WorldNativeAccess} for the given world reference.
|
||||
|
@ -10,39 +10,39 @@
|
||||
# in categories, like "max-blocks-changed", are placed in the "limits"
|
||||
# category.
|
||||
# - If you want to check the format of this file before putting it
|
||||
# into WorldEdit, paste it into http://yaml-online-parser.appspot.com/
|
||||
# into WorldEdit, paste it into https://yaml-online-parser.appspot.com/
|
||||
# and see if it gives you "ERROR:".
|
||||
# - Lines starting with # are comments, so they are ignored.
|
||||
# - If you want to allow blocks, make sure to change "disallowed-blocks" to []
|
||||
#
|
||||
|
||||
limits :
|
||||
max-blocks-changed :
|
||||
limits:
|
||||
max-blocks-changed:
|
||||
# Ignored, use FAWE config limits
|
||||
default : -1
|
||||
maximum : -1
|
||||
max-polygonal-points :
|
||||
default : -1
|
||||
maximum : 20
|
||||
max-radius : -1
|
||||
max-super-pickaxe-size : 5
|
||||
max-brush-radius : 100
|
||||
butcher-radius :
|
||||
default : -1
|
||||
maximum : -1
|
||||
disallowed-blocks :
|
||||
default: -1
|
||||
maximum: -1
|
||||
max-polygonal-points:
|
||||
default: -1
|
||||
maximum: 20
|
||||
max-radius: -1
|
||||
max-super-pickaxe-size: 5
|
||||
max-brush-radius: 100
|
||||
butcher-radius:
|
||||
default: -1
|
||||
maximum: -1
|
||||
disallowed-blocks:
|
||||
- "minecraft:wheat"
|
||||
- "minecraft:fire"
|
||||
- "minecraft:redstone_wire"
|
||||
|
||||
use-inventory :
|
||||
enable : false
|
||||
allow-override : true
|
||||
creative-mode-overrides : false
|
||||
use-inventory:
|
||||
enable: false
|
||||
allow-override: true
|
||||
creative-mode-overrides: false
|
||||
|
||||
logging :
|
||||
log-commands : false
|
||||
file : worldedit.log
|
||||
logging:
|
||||
log-commands: false
|
||||
file: worldedit.log
|
||||
# The format of custom log message. This is java general format string (java.util.Formatter). Arguments are:
|
||||
# 1$ : date - a Date object representing event time of the log record.
|
||||
# 2$ : source - a string representing the caller, if available; otherwise, the logger's name.
|
||||
@ -53,44 +53,44 @@ logging :
|
||||
# For details see:
|
||||
# https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html
|
||||
# https://docs.oracle.com/javase/8/docs/api/java/util/logging/SimpleFormatter.html#format-java.util.logging.LogRecord-
|
||||
format : "[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS %4$s]: %5$s%6$s%n"
|
||||
format: "[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS %4$s]: %5$s%6$s%n"
|
||||
|
||||
super-pickaxe :
|
||||
drop-items : true
|
||||
many-drop-items : false
|
||||
super-pickaxe:
|
||||
drop-items: true
|
||||
many-drop-items: false
|
||||
|
||||
snapshots :
|
||||
directory :
|
||||
snapshots:
|
||||
directory:
|
||||
|
||||
navigation-wand :
|
||||
item : minecraft:compass
|
||||
max-distance : 100
|
||||
navigation-wand:
|
||||
item: minecraft:compass
|
||||
max-distance: 100
|
||||
|
||||
scripting :
|
||||
timeout : 3000
|
||||
dir : craftscripts
|
||||
scripting:
|
||||
timeout: 3000
|
||||
dir: craftscripts
|
||||
|
||||
saving :
|
||||
dir : schematics
|
||||
saving:
|
||||
dir: schematics
|
||||
|
||||
files :
|
||||
allow-symbolic-links : false
|
||||
files:
|
||||
allow-symbolic-links: false
|
||||
|
||||
history :
|
||||
size : 15
|
||||
expiration : 10
|
||||
history:
|
||||
size: 15
|
||||
expiration: 10
|
||||
|
||||
calculation :
|
||||
timeout : 100
|
||||
calculation:
|
||||
timeout: 100
|
||||
|
||||
debugging :
|
||||
trace-unflushed-sessions : false
|
||||
debugging:
|
||||
trace-unflushed-sessions: false
|
||||
|
||||
wand-item : minecraft:wooden_axe
|
||||
shell-save-type :
|
||||
no-double-slash : false
|
||||
no-op-permissions : false
|
||||
debug : false
|
||||
show-help-on-first-use : true
|
||||
server-side-cui : true
|
||||
command-block-support : false
|
||||
wand-item: minecraft:wooden_axe
|
||||
shell-save-type:
|
||||
no-double-slash: false
|
||||
no-op-permissions: false
|
||||
debug: false
|
||||
show-help-on-first-use: true
|
||||
server-side-cui: true
|
||||
command-block-support: false
|
@ -118,6 +118,11 @@ public class StubServer implements Server {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSimulationDistance() {
|
||||
return 12;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull
|
||||
String getIp() {
|
||||
@ -465,6 +470,11 @@ public class StubServer implements Server {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getHideOnlinePlayers() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getOnlineMode() {
|
||||
return false;
|
||||
|
Reference in New Issue
Block a user