Skip to content

Commit 2c7ac3d

Browse files
authored
Merge pull request #1611 from EngineHub/feature/nbt-parsing
Add NBT Parsing for items
2 parents 0cabb82 + b7880c2 commit 2c7ac3d

File tree

67 files changed

+1433
-1339
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+1433
-1339
lines changed

buildSrc/src/main/kotlin/LibsConfig.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ fun Project.applyLibrariesConfiguration() {
2828

2929
val relocations = mapOf(
3030
"net.kyori.text" to "com.sk89q.worldedit.util.formatting.text",
31-
"net.kyori.minecraft" to "com.sk89q.worldedit.util.kyori"
31+
"net.kyori.minecraft" to "com.sk89q.worldedit.util.kyori",
32+
"net.kyori.adventure.nbt" to "com.sk89q.worldedit.util.nbt"
3233
)
3334

3435
tasks.register<ShadowJar>("jar") {

worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java

+7-5
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import com.sk89q.worldedit.util.formatting.text.adapter.bukkit.TextAdapter;
4040
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
4141
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
42+
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
4243
import com.sk89q.worldedit.world.World;
4344
import com.sk89q.worldedit.world.block.BaseBlock;
4445
import com.sk89q.worldedit.world.block.BlockStateHolder;
@@ -295,11 +296,12 @@ public <B extends BlockStateHolder<B>> void sendFakeBlock(BlockVector3 pos, B bl
295296
player.sendBlockChange(loc, player.getWorld().getBlockAt(loc).getBlockData());
296297
} else {
297298
player.sendBlockChange(loc, BukkitAdapter.adapt(block));
298-
if (block instanceof BaseBlock && ((BaseBlock) block).hasNbtData()) {
299-
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
300-
if (adapter != null) {
301-
if (block.getBlockType() == BlockTypes.STRUCTURE_BLOCK) {
302-
adapter.sendFakeNBT(player, pos, ((BaseBlock) block).getNbtData());
299+
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
300+
if (adapter != null) {
301+
if (block.getBlockType() == BlockTypes.STRUCTURE_BLOCK && block instanceof BaseBlock) {
302+
CompoundBinaryTag nbt = ((BaseBlock) block).getNbt();
303+
if (nbt != null) {
304+
adapter.sendFakeNBT(player, pos, nbt);
303305
adapter.sendFakeOP(player);
304306
}
305307
}

worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,8 @@ public com.sk89q.worldedit.entity.Entity createEntity(com.sk89q.worldedit.util.L
150150
}
151151
} catch (Exception e) {
152152
logger.warn("Corrupt entity found when creating: " + entity.getType().getId());
153-
if (entity.getNbtData() != null) {
154-
logger.warn(entity.getNbtData().toString());
153+
if (entity.getNbt() != null) {
154+
logger.warn(entity.getNbt().toString());
155155
}
156156
e.printStackTrace();
157157
return null;
@@ -463,9 +463,9 @@ public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B
463463
try {
464464
return worldNativeAccess.setBlock(position, block, sideEffects);
465465
} catch (Exception e) {
466-
if (block instanceof BaseBlock && ((BaseBlock) block).getNbtData() != null) {
466+
if (block instanceof BaseBlock && ((BaseBlock) block).getNbt() != null) {
467467
logger.warn("Tried to set a corrupt tile entity at " + position.toString()
468-
+ ": " + ((BaseBlock) block).getNbtData(), e);
468+
+ ": " + ((BaseBlock) block).getNbt(), e);
469469
} else {
470470
logger.warn("Failed to set block via adapter, falling back to generic", e);
471471
}

worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
package com.sk89q.worldedit.bukkit.adapter;
2121

22-
import com.sk89q.jnbt.CompoundTag;
2322
import com.sk89q.worldedit.blocks.BaseItem;
2423
import com.sk89q.worldedit.blocks.BaseItemStack;
2524
import com.sk89q.worldedit.entity.BaseEntity;
@@ -31,6 +30,7 @@
3130
import com.sk89q.worldedit.util.Direction;
3231
import com.sk89q.worldedit.util.SideEffect;
3332
import com.sk89q.worldedit.util.formatting.text.Component;
33+
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
3434
import com.sk89q.worldedit.world.DataFixer;
3535
import com.sk89q.worldedit.world.RegenOptions;
3636
import com.sk89q.worldedit.world.block.BaseBlock;
@@ -151,7 +151,7 @@ default void tickWatchdog() {
151151
* @param pos The position
152152
* @param nbtData The NBT Data
153153
*/
154-
void sendFakeNBT(Player player, BlockVector3 pos, CompoundTag nbtData);
154+
void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData);
155155

156156
/**
157157
* Make the client think it has operator status.
Binary file not shown.

worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/MobSpawnerBlock.java

+4
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@
3737

3838
/**
3939
* A mob spawner block.
40+
*
41+
* @deprecated WorldEdit does not handle interpreting NBT,
42+
* deprecated for removal without replacement
4043
*/
44+
@Deprecated
4145
public class MobSpawnerBlock extends BaseBlock {
4246

4347
private String mobType;

worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/SignBlock.java

+4
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@
3131

3232
/**
3333
* Represents a sign block.
34+
*
35+
* @deprecated WorldEdit does not handle interpreting NBT,
36+
* deprecated for removal without replacement
3437
*/
38+
@Deprecated
3539
public class SignBlock extends BaseBlock {
3640

3741
private String[] text;

worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/SkullBlock.java

+4
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@
3131

3232
/**
3333
* A skull block.
34+
*
35+
* @deprecated WorldEdit does not handle interpreting NBT,
36+
* deprecated for removal without replacement
3437
*/
38+
@Deprecated
3539
public class SkullBlock extends BaseBlock {
3640

3741
private String owner = ""; // notchian
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* WorldEdit, a Minecraft world manipulation toolkit
3+
* Copyright (C) sk89q <http://www.sk89q.com>
4+
* Copyright (C) WorldEdit team and contributors
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
20+
package com.sk89q.jnbt;
21+
22+
import com.google.common.collect.BiMap;
23+
import com.google.common.collect.ImmutableBiMap;
24+
import com.google.common.collect.ImmutableMap;
25+
import com.sk89q.worldedit.util.nbt.BinaryTag;
26+
import com.sk89q.worldedit.util.nbt.BinaryTagType;
27+
import com.sk89q.worldedit.util.nbt.BinaryTagTypes;
28+
29+
import java.lang.reflect.Constructor;
30+
import java.lang.reflect.InvocationTargetException;
31+
import java.util.Map;
32+
import java.util.Objects;
33+
import java.util.function.Function;
34+
35+
/**
36+
* Converts between JNBT and Adventure-NBT classes.
37+
*
38+
* @deprecated JNBT is being removed in WE8.
39+
*/
40+
@Deprecated
41+
public class AdventureNBTConverter {
42+
private static final BiMap<Class<? extends Tag>, BinaryTagType<?>> TAG_TYPES =
43+
new ImmutableBiMap.Builder<Class<? extends Tag>, BinaryTagType<?>>()
44+
.put(ByteArrayTag.class, BinaryTagTypes.BYTE_ARRAY)
45+
.put(ByteTag.class, BinaryTagTypes.BYTE)
46+
.put(CompoundTag.class, BinaryTagTypes.COMPOUND)
47+
.put(DoubleTag.class, BinaryTagTypes.DOUBLE)
48+
.put(EndTag.class, BinaryTagTypes.END)
49+
.put(FloatTag.class, BinaryTagTypes.FLOAT)
50+
.put(IntArrayTag.class, BinaryTagTypes.INT_ARRAY)
51+
.put(IntTag.class, BinaryTagTypes.INT)
52+
.put(ListTag.class, BinaryTagTypes.LIST)
53+
.put(LongArrayTag.class, BinaryTagTypes.LONG_ARRAY)
54+
.put(LongTag.class, BinaryTagTypes.LONG)
55+
.put(ShortTag.class, BinaryTagTypes.SHORT)
56+
.put(StringTag.class, BinaryTagTypes.STRING)
57+
.build();
58+
59+
private static final Map<BinaryTagType<?>, Function<BinaryTag, Tag>> CONVERSION;
60+
61+
static {
62+
ImmutableMap.Builder<BinaryTagType<?>, Function<BinaryTag, Tag>> conversion =
63+
ImmutableMap.builder();
64+
65+
for (Map.Entry<Class<? extends Tag>, BinaryTagType<?>> tag : TAG_TYPES.entrySet()) {
66+
Constructor<?>[] constructors = tag.getKey().getConstructors();
67+
for (Constructor<?> c : constructors) {
68+
if (c.getParameterCount() == 1 && BinaryTag.class.isAssignableFrom(c.getParameterTypes()[0])) {
69+
conversion.put(tag.getValue(), binaryTag -> {
70+
try {
71+
return (Tag) c.newInstance(binaryTag);
72+
} catch (InstantiationException | IllegalAccessException e) {
73+
throw new IllegalStateException(e);
74+
} catch (InvocationTargetException e) {
75+
// I assume this is always a RuntimeException since we control the ctor
76+
throw (RuntimeException) e.getCause();
77+
}
78+
});
79+
break;
80+
}
81+
}
82+
}
83+
84+
CONVERSION = conversion.build();
85+
}
86+
87+
public static BinaryTagType<?> getAdventureType(Class<? extends Tag> type) {
88+
return Objects.requireNonNull(TAG_TYPES.get(type), () -> "Missing entry for " + type);
89+
}
90+
91+
public static Class<? extends Tag> getJNBTType(BinaryTagType<?> type) {
92+
return Objects.requireNonNull(TAG_TYPES.inverse().get(type), () -> "Missing entry for " + type);
93+
}
94+
95+
private AdventureNBTConverter() {
96+
}
97+
98+
public static Tag fromAdventure(BinaryTag other) {
99+
Function<BinaryTag, Tag> conversion = CONVERSION.get(other.type());
100+
if (conversion == null) {
101+
throw new IllegalArgumentException("Can't convert other of type " + other.getClass().getCanonicalName());
102+
}
103+
return conversion.apply(other);
104+
}
105+
}

worldedit-core/src/main/java/com/sk89q/jnbt/ByteArrayTag.java

+15-14
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,19 @@
1919

2020
package com.sk89q.jnbt;
2121

22+
import com.sk89q.worldedit.util.nbt.ByteArrayBinaryTag;
23+
2224
import java.util.Locale;
2325

2426
/**
2527
* The {@code TAG_Byte_Array} tag.
28+
*
29+
* @deprecated Use {@link ByteArrayBinaryTag}.
2630
*/
31+
@Deprecated
2732
public final class ByteArrayTag extends Tag {
2833

29-
private final byte[] value;
34+
private final ByteArrayBinaryTag innerTag;
3035

3136
/**
3237
* Creates the tag with an empty name.
@@ -35,25 +40,21 @@ public final class ByteArrayTag extends Tag {
3540
*/
3641
public ByteArrayTag(byte[] value) {
3742
super();
38-
this.value = value;
43+
this.innerTag = ByteArrayBinaryTag.of(value);
44+
}
45+
46+
public ByteArrayTag(ByteArrayBinaryTag adventureTag) {
47+
super();
48+
this.innerTag = adventureTag;
3949
}
4050

4151
@Override
4252
public byte[] getValue() {
43-
return value;
53+
return innerTag.value();
4454
}
4555

4656
@Override
47-
public String toString() {
48-
StringBuilder hex = new StringBuilder();
49-
for (byte b : value) {
50-
String hexDigits = Integer.toHexString(b).toUpperCase(Locale.ROOT);
51-
if (hexDigits.length() == 1) {
52-
hex.append("0");
53-
}
54-
hex.append(hexDigits).append(" ");
55-
}
56-
return "TAG_Byte_Array(" + hex + ")";
57+
public ByteArrayBinaryTag asBinaryTag() {
58+
return innerTag;
5759
}
58-
5960
}

worldedit-core/src/main/java/com/sk89q/jnbt/ByteTag.java

+15-6
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,17 @@
1919

2020
package com.sk89q.jnbt;
2121

22+
import com.sk89q.worldedit.util.nbt.ByteBinaryTag;
23+
2224
/**
2325
* The {@code TAG_Byte} tag.
26+
*
27+
* @deprecated Use {@link ByteBinaryTag}.
2428
*/
29+
@Deprecated
2530
public final class ByteTag extends Tag {
2631

27-
private final byte value;
32+
private final ByteBinaryTag innerTag;
2833

2934
/**
3035
* Creates the tag with an empty name.
@@ -33,17 +38,21 @@ public final class ByteTag extends Tag {
3338
*/
3439
public ByteTag(byte value) {
3540
super();
36-
this.value = value;
41+
this.innerTag = ByteBinaryTag.of(value);
42+
}
43+
44+
public ByteTag(ByteBinaryTag adventureTag) {
45+
super();
46+
this.innerTag = adventureTag;
3747
}
3848

3949
@Override
4050
public Byte getValue() {
41-
return value;
51+
return innerTag.value();
4252
}
4353

4454
@Override
45-
public String toString() {
46-
return "TAG_Byte(" + value + ")";
55+
public ByteBinaryTag asBinaryTag() {
56+
return innerTag;
4757
}
48-
4958
}

0 commit comments

Comments
 (0)