Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add NBT Parsing for items #1611

Merged
merged 10 commits into from
Feb 15, 2021
Merged
3 changes: 2 additions & 1 deletion buildSrc/src/main/kotlin/LibsConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ fun Project.applyLibrariesConfiguration() {

val relocations = mapOf(
"net.kyori.text" to "com.sk89q.worldedit.util.formatting.text",
"net.kyori.minecraft" to "com.sk89q.worldedit.util.kyori"
"net.kyori.minecraft" to "com.sk89q.worldedit.util.kyori",
"net.kyori.adventure.nbt" to "com.sk89q.worldedit.util.nbt"
)

tasks.register<ShadowJar>("jar") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import com.sk89q.worldedit.util.formatting.text.adapter.bukkit.TextAdapter;
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockStateHolder;
Expand Down Expand Up @@ -295,11 +296,12 @@ public <B extends BlockStateHolder<B>> void sendFakeBlock(BlockVector3 pos, B bl
player.sendBlockChange(loc, player.getWorld().getBlockAt(loc).getBlockData());
} else {
player.sendBlockChange(loc, BukkitAdapter.adapt(block));
if (block instanceof BaseBlock && ((BaseBlock) block).hasNbtData()) {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
if (block.getBlockType() == BlockTypes.STRUCTURE_BLOCK) {
adapter.sendFakeNBT(player, pos, ((BaseBlock) block).getNbtData());
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
if (block.getBlockType() == BlockTypes.STRUCTURE_BLOCK && block instanceof BaseBlock) {
CompoundBinaryTag nbt = ((BaseBlock) block).getNbt();
if (nbt != null) {
adapter.sendFakeNBT(player, pos, nbt);
adapter.sendFakeOP(player);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ public com.sk89q.worldedit.entity.Entity createEntity(com.sk89q.worldedit.util.L
}
} catch (Exception e) {
logger.warn("Corrupt entity found when creating: " + entity.getType().getId());
if (entity.getNbtData() != null) {
logger.warn(entity.getNbtData().toString());
if (entity.getNbt() != null) {
logger.warn(entity.getNbt().toString());
}
e.printStackTrace();
return null;
Expand Down Expand Up @@ -457,9 +457,9 @@ public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B
try {
return worldNativeAccess.setBlock(position, block, sideEffects);
} catch (Exception e) {
if (block instanceof BaseBlock && ((BaseBlock) block).getNbtData() != null) {
if (block instanceof BaseBlock && ((BaseBlock) block).getNbt() != null) {
logger.warn("Tried to set a corrupt tile entity at " + position.toString()
+ ": " + ((BaseBlock) block).getNbtData(), e);
+ ": " + ((BaseBlock) block).getNbt(), e);
} else {
logger.warn("Failed to set block via adapter, falling back to generic", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

package com.sk89q.worldedit.bukkit.adapter;

import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.entity.BaseEntity;
Expand All @@ -31,6 +30,7 @@
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.SideEffect;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
import com.sk89q.worldedit.world.DataFixer;
import com.sk89q.worldedit.world.RegenOptions;
import com.sk89q.worldedit.world.block.BaseBlock;
Expand Down Expand Up @@ -151,7 +151,7 @@ default void tickWatchdog() {
* @param pos The position
* @param nbtData The NBT Data
*/
void sendFakeNBT(Player player, BlockVector3 pos, CompoundTag nbtData);
void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData);

/**
* Make the client think it has operator status.
Expand Down
Binary file modified worldedit-bukkit/src/main/resources/worldedit-adapters.jar
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@

/**
* A mob spawner block.
*
* @deprecated WorldEdit does not handle interpreting NBT,
* deprecated for removal without replacement
*/
@Deprecated
public class MobSpawnerBlock extends BaseBlock {

private String mobType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@

/**
* Represents a sign block.
*
* @deprecated WorldEdit does not handle interpreting NBT,
* deprecated for removal without replacement
*/
@Deprecated
public class SignBlock extends BaseBlock {

private String[] text;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@

/**
* A skull block.
*
* @deprecated WorldEdit does not handle interpreting NBT,
* deprecated for removal without replacement
*/
@Deprecated
public class SkullBlock extends BaseBlock {

private String owner = ""; // notchian
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package com.sk89q.jnbt;

import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableMap;
import com.sk89q.worldedit.util.nbt.BinaryTag;
import com.sk89q.worldedit.util.nbt.BinaryTagType;
import com.sk89q.worldedit.util.nbt.BinaryTagTypes;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;

/**
* Converts between JNBT and Adventure-NBT classes.
*
* @deprecated JNBT is being removed in WE8.
*/
@Deprecated
public class AdventureNBTConverter {
private static final BiMap<Class<? extends Tag>, BinaryTagType<?>> TAG_TYPES =
new ImmutableBiMap.Builder<Class<? extends Tag>, BinaryTagType<?>>()
.put(ByteArrayTag.class, BinaryTagTypes.BYTE_ARRAY)
.put(ByteTag.class, BinaryTagTypes.BYTE)
.put(CompoundTag.class, BinaryTagTypes.COMPOUND)
.put(DoubleTag.class, BinaryTagTypes.DOUBLE)
.put(EndTag.class, BinaryTagTypes.END)
.put(FloatTag.class, BinaryTagTypes.FLOAT)
.put(IntArrayTag.class, BinaryTagTypes.INT_ARRAY)
.put(IntTag.class, BinaryTagTypes.INT)
.put(ListTag.class, BinaryTagTypes.LIST)
.put(LongArrayTag.class, BinaryTagTypes.LONG_ARRAY)
.put(LongTag.class, BinaryTagTypes.LONG)
.put(ShortTag.class, BinaryTagTypes.SHORT)
.put(StringTag.class, BinaryTagTypes.STRING)
.build();

private static final Map<BinaryTagType<?>, Function<BinaryTag, Tag>> CONVERSION;

static {
ImmutableMap.Builder<BinaryTagType<?>, Function<BinaryTag, Tag>> conversion =
ImmutableMap.builder();

for (Map.Entry<Class<? extends Tag>, BinaryTagType<?>> tag : TAG_TYPES.entrySet()) {
Constructor<?>[] constructors = tag.getKey().getConstructors();
for (Constructor<?> c : constructors) {
if (c.getParameterCount() == 1 && BinaryTag.class.isAssignableFrom(c.getParameterTypes()[0])) {
conversion.put(tag.getValue(), binaryTag -> {
try {
return (Tag) c.newInstance(binaryTag);
} catch (InstantiationException | IllegalAccessException e) {
throw new IllegalStateException(e);
} catch (InvocationTargetException e) {
// I assume this is always a RuntimeException since we control the ctor
throw (RuntimeException) e.getCause();
}
});
break;
}
}
}

CONVERSION = conversion.build();
}

public static BinaryTagType<?> getAdventureType(Class<? extends Tag> type) {
return Objects.requireNonNull(TAG_TYPES.get(type), () -> "Missing entry for " + type);
}

public static Class<? extends Tag> getJNBTType(BinaryTagType<?> type) {
return Objects.requireNonNull(TAG_TYPES.inverse().get(type), () -> "Missing entry for " + type);
}

private AdventureNBTConverter() {
}

public static Tag fromAdventure(BinaryTag other) {
Function<BinaryTag, Tag> conversion = CONVERSION.get(other.type());
if (conversion == null) {
throw new IllegalArgumentException("Can't convert other of type " + other.getClass().getCanonicalName());
}
return conversion.apply(other);
}
}
29 changes: 15 additions & 14 deletions worldedit-core/src/main/java/com/sk89q/jnbt/ByteArrayTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,19 @@

package com.sk89q.jnbt;

import com.sk89q.worldedit.util.nbt.ByteArrayBinaryTag;

import java.util.Locale;

/**
* The {@code TAG_Byte_Array} tag.
*
* @deprecated Use {@link ByteArrayBinaryTag}.
*/
@Deprecated
public final class ByteArrayTag extends Tag {

private final byte[] value;
private final ByteArrayBinaryTag innerTag;

/**
* Creates the tag with an empty name.
Expand All @@ -35,25 +40,21 @@ public final class ByteArrayTag extends Tag {
*/
public ByteArrayTag(byte[] value) {
super();
this.value = value;
this.innerTag = ByteArrayBinaryTag.of(value);
}

public ByteArrayTag(ByteArrayBinaryTag adventureTag) {
super();
this.innerTag = adventureTag;
}

@Override
public byte[] getValue() {
return value;
return innerTag.value();
}

@Override
public String toString() {
StringBuilder hex = new StringBuilder();
for (byte b : value) {
String hexDigits = Integer.toHexString(b).toUpperCase(Locale.ROOT);
if (hexDigits.length() == 1) {
hex.append("0");
}
hex.append(hexDigits).append(" ");
}
return "TAG_Byte_Array(" + hex + ")";
public ByteArrayBinaryTag asBinaryTag() {
return innerTag;
}

}
21 changes: 15 additions & 6 deletions worldedit-core/src/main/java/com/sk89q/jnbt/ByteTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,17 @@

package com.sk89q.jnbt;

import com.sk89q.worldedit.util.nbt.ByteBinaryTag;

/**
* The {@code TAG_Byte} tag.
*
* @deprecated Use {@link ByteBinaryTag}.
*/
@Deprecated
public final class ByteTag extends Tag {

private final byte value;
private final ByteBinaryTag innerTag;

/**
* Creates the tag with an empty name.
Expand All @@ -33,17 +38,21 @@ public final class ByteTag extends Tag {
*/
public ByteTag(byte value) {
super();
this.value = value;
this.innerTag = ByteBinaryTag.of(value);
}

public ByteTag(ByteBinaryTag adventureTag) {
super();
this.innerTag = adventureTag;
}

@Override
public Byte getValue() {
return value;
return innerTag.value();
}

@Override
public String toString() {
return "TAG_Byte(" + value + ")";
public ByteBinaryTag asBinaryTag() {
return innerTag;
}

}
Loading