Skip to content

Commit de6f93e

Browse files
fix: broken LinOps for entity and block NBT (#3415)
* fix: broken LinOps for entity and block NBT * fix: sign text reading
1 parent 2aedf8d commit de6f93e

File tree

2 files changed

+77
-6
lines changed

2 files changed

+77
-6
lines changed

worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/LinOps.java

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,13 @@
5454
public class LinOps implements DynamicOps<LinTag<?>> {
5555

5656
static final DynamicOps<LinTag<?>> INSTANCE = new LinOps();
57-
private static final LinTag<?> EMPTY_TAG = LinCompoundTag.of(Map.of());
5857

5958
private LinOps() {
6059
}
6160

6261
@Override
6362
public LinTag<?> empty() {
64-
return EMPTY_TAG;
63+
return LinEndTag.instance();
6564
}
6665

6766
@Override
@@ -71,7 +70,7 @@ public LinTag<?> emptyList() {
7170

7271
@Override
7372
public LinTag<?> emptyMap() {
74-
return EMPTY_TAG;
73+
return LinCompoundTag.builder().build();
7574
}
7675

7776
@Override
@@ -177,11 +176,68 @@ public DataResult<LinTag<?>> mergeToMap(final LinTag<?> map, final LinTag<?> key
177176
return DataResult.error(() -> "key is not a string: " + key, map);
178177
}
179178
if (map instanceof LinCompoundTag mapCompoundTag) {
179+
if (value == empty()) {
180+
return DataResult.success(mapCompoundTag);
181+
}
180182
return DataResult.success(mapCompoundTag.toBuilder().put(keyStringTag.value(), value).build());
181183
}
184+
if (value == empty()) {
185+
return DataResult.success(emptyMap());
186+
}
182187
return DataResult.success(LinCompoundTag.builder().put(keyStringTag.value(), value).build());
183188
}
184189

190+
@Override
191+
public DataResult<LinTag<?>> mergeToMap(final LinTag<?> map, final MapLike<LinTag<?>> values) {
192+
if (!(map instanceof LinCompoundTag) && !(map instanceof LinEndTag)) {
193+
return DataResult.error(() -> "mergeToMap called with not a map: " + map, map);
194+
}
195+
final Iterator<Pair<LinTag<?>, LinTag<?>>> iterator = values.entries().iterator();
196+
if (!iterator.hasNext()) {
197+
// if map is LinEndTag (returned by empty()) return a functional empty map
198+
return map == empty() ? DataResult.success(this.emptyMap()) : DataResult.success(map);
199+
}
200+
LinCompoundTag.Builder resultBuilder = map instanceof LinCompoundTag compoundTag ?
201+
compoundTag.toBuilder() : LinCompoundTag.builder();
202+
List<LinTag<?>> nonStringKeys = new ArrayList<>();
203+
iterator.forEachRemaining(entry -> {
204+
LinTag<?> key = entry.getFirst();
205+
if (key instanceof LinStringTag keyStringTag) {
206+
if (entry.getSecond() != empty()) {
207+
resultBuilder.put(keyStringTag.value(), entry.getSecond());
208+
}
209+
} else {
210+
nonStringKeys.add(key);
211+
}
212+
});
213+
return nonStringKeys.isEmpty() ? DataResult.success(resultBuilder.build()) :
214+
DataResult.error(() -> "some keys are not strings: " + nonStringKeys);
215+
}
216+
217+
@Override
218+
public DataResult<LinTag<?>> mergeToMap(final LinTag<?> map, final Map<LinTag<?>, LinTag<?>> values) {
219+
if (!(map instanceof LinCompoundTag) && !(map instanceof LinEndTag)) {
220+
return DataResult.error(() -> "mergeToMap called with not a map: " + map, map);
221+
}
222+
if (values.isEmpty()) {
223+
return map == empty() ? DataResult.success(this.emptyMap()) : DataResult.success(map);
224+
}
225+
LinCompoundTag.Builder resultBuilder = map instanceof LinCompoundTag compoundTag ?
226+
compoundTag.toBuilder() : LinCompoundTag.builder();
227+
List<LinTag<?>> nonStringKeys = new ArrayList<>();
228+
values.forEach((key, value) -> {
229+
if (key instanceof LinStringTag keyStringTag) {
230+
if (value != empty()) {
231+
resultBuilder.put(keyStringTag.value(), value);
232+
}
233+
} else {
234+
nonStringKeys.add(key);
235+
}
236+
});
237+
return nonStringKeys.isEmpty() ? DataResult.success(resultBuilder.build()) :
238+
DataResult.error(() -> "some keys are not strings: " + nonStringKeys);
239+
}
240+
185241
@Override
186242
public DataResult<Stream<Pair<LinTag<?>, LinTag<?>>>> getMapValues(final LinTag<?> input) {
187243
if (input instanceof LinCompoundTag tag) {
@@ -241,7 +297,7 @@ public String toString() {
241297
@Override
242298
public LinTag<?> createMap(final Stream<Pair<LinTag<?>, LinTag<?>>> map) {
243299
LinCompoundTag.Builder builder = LinCompoundTag.builder();
244-
map.forEach(pair -> {
300+
map.filter(pair -> pair.getSecond() != empty()).forEach(pair -> {
245301
if (pair.getFirst() instanceof LinStringTag key) {
246302
builder.put(key.value(), pair.getSecond());
247303
return;
@@ -309,7 +365,16 @@ public LinByteTag next() {
309365
@Override
310366
public DataResult<Consumer<Consumer<LinTag<?>>>> getList(final LinTag<?> input) {
311367
if (input instanceof LinListTag<?> tag) {
312-
return DataResult.success(consumer -> tag.value().forEach(consumer));
368+
return DataResult.success(consumer -> tag.value().forEach(entry -> {
369+
// Handling of mixed lists: NbtOps doesn't need to do that here given the net.minecraft.nbt.ListTag unwraps the
370+
// entries on insertion. LinListTag doesn't allow mixed list content, so we unwrap on read.
371+
// the only location this is used currently should be components (i.e. sign text)
372+
if (entry instanceof LinCompoundTag compoundTag && compoundTag.value().size() == 1 && compoundTag.value().containsKey("")) {
373+
consumer.accept(compoundTag.value().get(""));
374+
return;
375+
}
376+
consumer.accept(entry);
377+
}));
313378
}
314379
if (input instanceof LinByteArrayTag tag) {
315380
return DataResult.success(consumer -> {
@@ -570,7 +635,10 @@ protected LinCompoundTag.Builder initBuilder() {
570635

571636
@Override
572637
protected LinCompoundTag.Builder append(final String key, final LinTag<?> value, final LinCompoundTag.Builder builder) {
573-
return builder.put(key, value);
638+
if (value != ops().empty()) {
639+
return builder.put(key, value);
640+
}
641+
return builder;
574642
}
575643

576644
@Override

worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/LinValueOutput.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,9 @@ public boolean isEmpty() {
198198
}
199199

200200
public LinCompoundTag buildResult() {
201+
if (this.isEmpty()) {
202+
return LinCompoundTag.builder().build();
203+
}
201204
return LinCompoundTag.of(this.collector.entrySet().stream()
202205
.collect(Collectors.toMap(Map.Entry::getKey, entry -> unwrapPendingEntry(entry.getValue())))
203206
);

0 commit comments

Comments
 (0)