mirror of
https://github.com/PaperMC/Paper.git
synced 2026-11-04 08:52:01 -05:00
Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c5eb0790f1 | ||
|
|
6d5b910ff0 | ||
|
|
c5a2736aaa | ||
|
|
3837e9a79e | ||
|
|
1fdbce138a |
No files matched your search
@@ -118,6 +118,7 @@ public net.minecraft.stats.ServerRecipeBook known
|
||||
public net.minecraft.tags.TagEntry id
|
||||
public net.minecraft.tags.TagEntry required
|
||||
public net.minecraft.tags.TagEntry tag
|
||||
public net.minecraft.util.AbstractListBuilder
|
||||
public net.minecraft.util.Util onThreadException(Ljava/lang/Thread;Ljava/lang/Throwable;)V
|
||||
public net.minecraft.util.datafix.fixes.BlockStateData register(ILcom/mojang/serialization/Dynamic;[Lcom/mojang/serialization/Dynamic;)V
|
||||
public net.minecraft.util.datafix.fixes.ItemIdFix ITEM_NAMES
|
||||
|
||||
@@ -86,7 +86,7 @@ dependencies {
|
||||
testImplementation("org.junit.jupiter:junit-jupiter:5.12.2")
|
||||
testImplementation("org.hamcrest:hamcrest:2.2")
|
||||
testImplementation("org.mockito:mockito-core:5.14.1")
|
||||
testImplementation("org.ow2.asm:asm-tree:9.8")
|
||||
testImplementation("org.ow2.asm:asm-tree:9.9.1")
|
||||
mockitoAgent("org.mockito:mockito-core:5.14.1") { isTransitive = false } // configure mockito agent that is needed in newer java versions
|
||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ dependencies {
|
||||
}
|
||||
implementation("io.netty:netty-codec-haproxy:4.2.7.Final") // Add support for proxy protocol
|
||||
implementation("org.apache.logging.log4j:log4j-iostreams:2.24.1")
|
||||
implementation("org.ow2.asm:asm-commons:9.8")
|
||||
implementation("org.ow2.asm:asm-commons:9.9.1")
|
||||
implementation("org.spongepowered:configurate-yaml:4.2.0")
|
||||
|
||||
// Deps that were previously in the API but have now been moved here for backwards compat, eventually to be removed
|
||||
@@ -169,7 +169,7 @@ dependencies {
|
||||
testImplementation("org.hamcrest:hamcrest:2.2")
|
||||
testImplementation("org.mockito:mockito-core:5.14.1")
|
||||
mockitoAgent("org.mockito:mockito-core:5.14.1") { isTransitive = false } // Configure mockito agent that is needed in newer java versions
|
||||
testImplementation("org.ow2.asm:asm-tree:9.8")
|
||||
testImplementation("org.ow2.asm:asm-tree:9.9.1")
|
||||
testImplementation("org.junit-pioneer:junit-pioneer:2.2.0") // CartesianTest
|
||||
|
||||
implementation("net.neoforged:srgutils:1.0.9") // Mappings handling
|
||||
|
||||
@@ -521,10 +521,10 @@ index 34ef15867759ebc7296256a6d5ec286eb3a5f895..d3d97b0b6ff6312f1deb0bb8b1beef8b
|
||||
movement = this.maybeBackOffFromEdge(movement, type);
|
||||
Vec3 vec3 = this.collide(movement);
|
||||
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||
index 5b6020de0848458f5576113e690b5a6435f35d05..6f49b5e5888a6296b929e465a5ef87dc49bd4516 100644
|
||||
index 56c29f6407256f471156d309fd81bb0256fff756..07b3d08d9c2f9e978379de5a6b846a828029e2fa 100644
|
||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3330,6 +3330,14 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
@@ -3331,6 +3331,14 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
protected void playAttackSound() {
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Wed, 8 Apr 2026 18:25:47 -0400
|
||||
Subject: [PATCH] Fix Comparator State Issues
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/ComparatorBlock.java b/net/minecraft/world/level/block/ComparatorBlock.java
|
||||
index 578e7c8dc601f53cf2a068685c6901bfaf47e763..7e87d56cd42f27c115b575b9acf2ce9ac0953af8 100644
|
||||
--- a/net/minecraft/world/level/block/ComparatorBlock.java
|
||||
+++ b/net/minecraft/world/level/block/ComparatorBlock.java
|
||||
@@ -136,7 +136,7 @@ public class ComparatorBlock extends DiodeBlock implements EntityBlock {
|
||||
float f = state.getValue(MODE) == ComparatorMode.SUBTRACT ? 0.55F : 0.5F;
|
||||
level.playSound(player, pos, SoundEvents.COMPARATOR_CLICK, SoundSource.BLOCKS, 0.3F, f);
|
||||
level.setBlock(pos, state, Block.UPDATE_CLIENTS);
|
||||
- this.refreshOutputState(level, pos, state);
|
||||
+ if (level.getBlockState(pos).is(this)) { this.refreshOutputState(level, pos, state); } // Paper
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/block/DiodeBlock.java b/net/minecraft/world/level/block/DiodeBlock.java
|
||||
index 02ffb5569e2405d86b3a4a695dd17c9372169ff7..a750e2d7f6c5ac7561c8b06870e022b07875c587 100644
|
||||
--- a/net/minecraft/world/level/block/DiodeBlock.java
|
||||
+++ b/net/minecraft/world/level/block/DiodeBlock.java
|
||||
@@ -92,6 +92,7 @@ public abstract class DiodeBlock extends HorizontalDirectionalBlock {
|
||||
|
||||
@Override
|
||||
protected void neighborChanged(BlockState state, Level level, BlockPos pos, Block neighborBlock, @Nullable Orientation orientation, boolean movedByPiston) {
|
||||
+ if (!level.getBlockState(pos).is(this)) return; // Paper
|
||||
if (state.canSurvive(level, pos)) {
|
||||
this.checkTickOnNeighbor(level, pos, state);
|
||||
} else {
|
||||
@@ -0,0 +1,18 @@
|
||||
--- a/net/minecraft/nbt/NbtAccounter.java
|
||||
+++ b/net/minecraft/nbt/NbtAccounter.java
|
||||
@@ -48,6 +_,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Track codec depth
|
||||
+ public void pushDepth(final int depth) {
|
||||
+ if (this.depth + depth >= this.maxDepth) {
|
||||
+ throw new NbtAccounterException("Tried to read NBT tag with too high complexity, depth > " + this.maxDepth);
|
||||
+ } else {
|
||||
+ this.depth += depth;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Track codec depth
|
||||
public void pushDepth() {
|
||||
if (this.depth >= this.maxDepth) {
|
||||
throw new NbtAccounterException("Tried to read NBT tag with too high complexity, depth > " + this.maxDepth);
|
||||
@@ -0,0 +1,17 @@
|
||||
--- a/net/minecraft/network/RegistryFriendlyByteBuf.java
|
||||
+++ b/net/minecraft/network/RegistryFriendlyByteBuf.java
|
||||
@@ -11,6 +_,14 @@
|
||||
super(source);
|
||||
this.registryAccess = registryAccess;
|
||||
}
|
||||
+ // Paper start - Track codec depth
|
||||
+ public RegistryFriendlyByteBuf(final ByteBuf source, final RegistryFriendlyByteBuf parent) {
|
||||
+ super(source);
|
||||
+ this.registryAccess = parent.registryAccess;
|
||||
+ this.trackCodecDepth = parent.trackCodecDepth;
|
||||
+ this.codecDepth = parent.codecDepth;
|
||||
+ }
|
||||
+ // Paper end - Track codec depth
|
||||
|
||||
public RegistryAccess registryAccess() {
|
||||
return this.registryAccess;
|
||||
@@ -1,5 +1,20 @@
|
||||
--- a/net/minecraft/network/codec/ByteBufCodecs.java
|
||||
+++ b/net/minecraft/network/codec/ByteBufCodecs.java
|
||||
@@ -334,7 +_,13 @@
|
||||
return new StreamCodec<ByteBuf, Tag>() {
|
||||
@Override
|
||||
public Tag decode(ByteBuf buffer) {
|
||||
- Tag nbt = FriendlyByteBuf.readNbt(buffer, accounter.get());
|
||||
+ // Paper start - Track codec depth
|
||||
+ final NbtAccounter acc = accounter.get();
|
||||
+ if (buffer instanceof FriendlyByteBuf friendlyByteBuf && friendlyByteBuf.trackCodecDepth) {
|
||||
+ acc.pushDepth(friendlyByteBuf.codecDepth * 3);
|
||||
+ }
|
||||
+ Tag nbt = FriendlyByteBuf.readNbt(buffer, acc);
|
||||
+ // Paper end - Track codec depth
|
||||
if (nbt == null) {
|
||||
throw new DecoderException("Expected non-null compound tag");
|
||||
} else {
|
||||
@@ -418,6 +_,48 @@
|
||||
};
|
||||
}
|
||||
@@ -49,3 +64,12 @@
|
||||
static <B extends ByteBuf, V> StreamCodec<B, Optional<V>> optional(final StreamCodec<? super B, V> codec) {
|
||||
return new StreamCodec<B, Optional<V>>() {
|
||||
@Override
|
||||
@@ -592,7 +_,7 @@
|
||||
}
|
||||
|
||||
static <V> StreamCodec.CodecOperation<RegistryFriendlyByteBuf, V, V> registryFriendlyLengthPrefixed(int length) {
|
||||
- return lengthPrefixed(length, (registryFriendlyByteBuf, byteBuf) -> new RegistryFriendlyByteBuf(byteBuf, registryFriendlyByteBuf.registryAccess()));
|
||||
+ return lengthPrefixed(length, (registryFriendlyByteBuf, byteBuf) -> new RegistryFriendlyByteBuf(byteBuf, registryFriendlyByteBuf)); // Paper - Track codec depth
|
||||
}
|
||||
|
||||
static <T> StreamCodec<ByteBuf, T> idMapper(final IntFunction<T> idLookup, final ToIntFunction<T> idGetter) {
|
||||
@@ -1051,7 +1051,7 @@
|
||||
int i = (this.getEffect(MobEffects.RESISTANCE).getAmplifier() + 1) * 5;
|
||||
int i1 = 25 - i;
|
||||
float f = damageAmount * i1;
|
||||
@@ -1863,24 +_,201 @@
|
||||
@@ -1863,24 +_,202 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1151,16 +1151,17 @@
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (damageSource.getEntity() instanceof net.minecraft.world.entity.player.Player) {
|
||||
+ if (damageSource.getEntity() instanceof net.minecraft.world.entity.player.Player attackingPlayer) {
|
||||
+ // Paper start - PlayerAttackEntityCooldownResetEvent
|
||||
+ //((net.minecraft.world.entity.player.Player) damagesource.getEntity()).resetOnlyAttackStrengthTicker(); // Moved from Player in order to make the cooldown reset get called after the damage event is fired
|
||||
+ if (damageSource.getEntity() instanceof ServerPlayer) {
|
||||
+ ServerPlayer player = (ServerPlayer) damageSource.getEntity();
|
||||
+ if (new com.destroystokyo.paper.event.player.PlayerAttackEntityCooldownResetEvent(player.getBukkitEntity(), this.getBukkitEntity(), player.getAttackStrengthScale(0F)).callEvent()) {
|
||||
+ player.resetOnlyAttackStrengthTicker();
|
||||
+ if (!attackingPlayer.isUsingItem() || !attackingPlayer.getUseItem().has(DataComponents.KINETIC_WEAPON)) { // Paper - Preserve vanilla spear charge cooldown
|
||||
+ if (attackingPlayer instanceof ServerPlayer player) {
|
||||
+ if (new com.destroystokyo.paper.event.player.PlayerAttackEntityCooldownResetEvent(player.getBukkitEntity(), this.getBukkitEntity(), player.getAttackStrengthScale(0F)).callEvent()) {
|
||||
+ player.resetOnlyAttackStrengthTicker();
|
||||
+ }
|
||||
+ } else {
|
||||
+ attackingPlayer.resetOnlyAttackStrengthTicker();
|
||||
+ }
|
||||
+ } else {
|
||||
+ ((net.minecraft.world.entity.player.Player) damageSource.getEntity()).resetOnlyAttackStrengthTicker();
|
||||
+ }
|
||||
+ // Paper end - PlayerAttackEntityCooldownResetEvent
|
||||
+ }
|
||||
|
||||
@@ -23,6 +23,15 @@
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -219,7 +_,7 @@
|
||||
public ItemStack decode(RegistryFriendlyByteBuf buffer) {
|
||||
ItemStack itemStack = codec.decode(buffer);
|
||||
if (!itemStack.isEmpty()) {
|
||||
- RegistryOps<Unit> registryOps = buffer.registryAccess().createSerializationContext(NullOps.INSTANCE);
|
||||
+ RegistryOps<io.papermc.paper.util.CountingOps.Value> registryOps = buffer.registryAccess().createSerializationContext(io.papermc.paper.util.CountingOps.INSTANCE); // Paper - Track codec depth
|
||||
ItemStack.CODEC.encodeStart(registryOps, itemStack).getOrThrow(DecoderException::new);
|
||||
}
|
||||
|
||||
@@ -371,10 +_,166 @@
|
||||
return InteractionResult.PASS;
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,308 @@
|
||||
package io.papermc.paper.util;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import com.mojang.serialization.DataResult;
|
||||
import com.mojang.serialization.DynamicOps;
|
||||
import com.mojang.serialization.ListBuilder;
|
||||
import com.mojang.serialization.MapLike;
|
||||
import com.mojang.serialization.RecordBuilder;
|
||||
import com.mojang.serialization.RecordBuilder.AbstractUniversalBuilder;
|
||||
import io.netty.handler.codec.DecoderException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.util.AbstractListBuilder;
|
||||
|
||||
public final class CountingOps implements DynamicOps<CountingOps.Value> {
|
||||
public static final CountingOps INSTANCE = new CountingOps(Tag.MAX_DEPTH);
|
||||
|
||||
private final int maxDepth;
|
||||
|
||||
public CountingOps(final int maxDepth) {
|
||||
this.maxDepth = maxDepth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> U convertTo(final DynamicOps<U> outOps, final Value input) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value empty() {
|
||||
return Value.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value emptyMap() {
|
||||
return this.container(Value.Kind.MAP, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value emptyList() {
|
||||
return this.container(Value.Kind.LIST, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value createNumeric(final Number value) {
|
||||
return Value.PRIMITIVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value createString(final String value) {
|
||||
return Value.PRIMITIVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataResult<Number> getNumberValue(final Value input) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataResult<String> getStringValue(final Value input) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataResult<Value> mergeToList(final Value input, final Value value) {
|
||||
final Accumulator accumulator = new Accumulator();
|
||||
if (input.kind == Value.Kind.LIST) {
|
||||
accumulator.acceptDepth(input.depth - 1);
|
||||
} else if (input.kind != Value.Kind.EMPTY) {
|
||||
accumulator.accept(input);
|
||||
}
|
||||
accumulator.accept(value);
|
||||
return DataResult.success(this.container(Value.Kind.LIST, accumulator));
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataResult<Value> mergeToList(final Value input, final List<Value> values) {
|
||||
final Accumulator accumulator = new Accumulator();
|
||||
if (input.kind == Value.Kind.LIST) {
|
||||
accumulator.acceptDepth(input.depth - 1);
|
||||
} else if (input.kind != Value.Kind.EMPTY) {
|
||||
accumulator.accept(input);
|
||||
}
|
||||
values.forEach(accumulator::accept);
|
||||
return DataResult.success(this.container(Value.Kind.LIST, accumulator));
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataResult<Value> mergeToMap(final Value input, final Value key, final Value value) {
|
||||
final Accumulator accumulator = new Accumulator();
|
||||
if (input.kind == Value.Kind.MAP) {
|
||||
accumulator.acceptDepth(input.depth - 1);
|
||||
} else if (input.kind != Value.Kind.EMPTY) {
|
||||
accumulator.accept(input);
|
||||
}
|
||||
accumulator.accept(value);
|
||||
return DataResult.success(this.container(Value.Kind.MAP, accumulator));
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataResult<Value> mergeToMap(final Value input, final Map<Value, Value> values) {
|
||||
final Accumulator accumulator = new Accumulator();
|
||||
if (input.kind == Value.Kind.MAP) {
|
||||
accumulator.acceptDepth(input.depth - 1);
|
||||
} else if (input.kind != Value.Kind.EMPTY) {
|
||||
accumulator.accept(input);
|
||||
}
|
||||
values.forEach((key, value) -> {
|
||||
accumulator.accept(value);
|
||||
});
|
||||
return DataResult.success(this.container(Value.Kind.MAP, accumulator));
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataResult<Value> mergeToMap(final Value input, final MapLike<Value> values) {
|
||||
final Accumulator accumulator = new Accumulator();
|
||||
if (input.kind == Value.Kind.MAP) {
|
||||
accumulator.acceptDepth(input.depth - 1);
|
||||
} else if (input.kind != Value.Kind.EMPTY) {
|
||||
accumulator.accept(input);
|
||||
}
|
||||
values.entries().forEach(entry -> {
|
||||
accumulator.accept(entry.getSecond());
|
||||
});
|
||||
return DataResult.success(this.container(Value.Kind.MAP, accumulator));
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataResult<Stream<Pair<Value, Value>>> getMapValues(final Value input) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataResult<Stream<Value>> getStream(final Value input) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value createMap(final Stream<Pair<Value, Value>> map) {
|
||||
final Accumulator accumulator = new Accumulator();
|
||||
map.forEach(entry -> accumulator.accept(entry.getSecond()));
|
||||
return this.container(Value.Kind.MAP, accumulator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value createMap(final Map<Value, Value> map) {
|
||||
final Accumulator accumulator = new Accumulator();
|
||||
map.forEach((key, value) -> {
|
||||
accumulator.accept(value);
|
||||
});
|
||||
return this.container(Value.Kind.MAP, accumulator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value createList(final Stream<Value> input) {
|
||||
final Accumulator accumulator = new Accumulator();
|
||||
input.forEach(accumulator::accept);
|
||||
return this.container(Value.Kind.LIST, accumulator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value createByteList(final ByteBuffer input) {
|
||||
return Value.PRIMITIVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value createIntList(final IntStream input) {
|
||||
return Value.PRIMITIVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value createLongList(final LongStream input) {
|
||||
return Value.PRIMITIVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value remove(final Value input, final String key) {
|
||||
return input;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecordBuilder<Value> mapBuilder() {
|
||||
return new MapBuilder(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListBuilder<Value> listBuilder() {
|
||||
return new CountingListBuilder(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Counting";
|
||||
}
|
||||
|
||||
private Value container(final Value.Kind kind, final Accumulator accumulator) {
|
||||
return this.container(kind, accumulator.maxDepth);
|
||||
}
|
||||
|
||||
private Value container(final Value.Kind kind, final int childDepth) {
|
||||
final int depth = childDepth + 1;
|
||||
if (depth > this.maxDepth) {
|
||||
throw new DecoderException("NBT depth exceeded: " + depth + " > " + this.maxDepth);
|
||||
}
|
||||
return new Value(kind, depth);
|
||||
}
|
||||
|
||||
private static final class Accumulator {
|
||||
private int maxDepth;
|
||||
|
||||
private void accept(final Value value) {
|
||||
this.acceptDepth(value.depth);
|
||||
}
|
||||
|
||||
private void acceptDepth(final int depth) {
|
||||
this.maxDepth = Math.max(this.maxDepth, depth);
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Value {
|
||||
private static final Value EMPTY = new Value(Kind.EMPTY, 0);
|
||||
private static final Value PRIMITIVE = new Value(Kind.PRIMITIVE, 0);
|
||||
|
||||
private final Kind kind;
|
||||
private final int depth;
|
||||
|
||||
private Value(final Kind kind, final int depth) {
|
||||
this.kind = kind;
|
||||
this.depth = depth;
|
||||
}
|
||||
|
||||
public int depth() {
|
||||
return this.depth;
|
||||
}
|
||||
|
||||
private enum Kind {
|
||||
EMPTY,
|
||||
PRIMITIVE,
|
||||
LIST,
|
||||
MAP
|
||||
}
|
||||
}
|
||||
|
||||
private static final class CountingListBuilder extends AbstractListBuilder<Value, Accumulator> {
|
||||
private final CountingOps ops;
|
||||
|
||||
private CountingListBuilder(final CountingOps ops) {
|
||||
super(ops);
|
||||
this.ops = ops;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Accumulator initBuilder() {
|
||||
return new Accumulator();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Accumulator append(final Accumulator builder, final Value value) {
|
||||
builder.accept(value);
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataResult<Value> build(final Accumulator builder, final Value prefix) {
|
||||
if (prefix.kind == Value.Kind.LIST) {
|
||||
builder.acceptDepth(prefix.depth - 1);
|
||||
} else if (prefix.kind != Value.Kind.EMPTY) {
|
||||
builder.accept(prefix);
|
||||
}
|
||||
return DataResult.success(this.ops.container(Value.Kind.LIST, builder));
|
||||
}
|
||||
}
|
||||
|
||||
private static final class MapBuilder extends AbstractUniversalBuilder<Value, Accumulator> {
|
||||
private final CountingOps ops;
|
||||
|
||||
private MapBuilder(final CountingOps ops) {
|
||||
super(ops);
|
||||
this.ops = ops;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Accumulator initBuilder() {
|
||||
return new Accumulator();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Accumulator append(final Value key, final Value value, final Accumulator builder) {
|
||||
builder.accept(value);
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataResult<Value> build(final Accumulator builder, final Value prefix) {
|
||||
if (prefix.kind == Value.Kind.MAP) {
|
||||
builder.acceptDepth(prefix.depth - 1);
|
||||
} else if (prefix.kind != Value.Kind.EMPTY) {
|
||||
builder.accept(prefix);
|
||||
}
|
||||
return DataResult.success(this.ops.container(Value.Kind.MAP, builder));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user