Drop codec spam fix (Fixes #5936)

having spoken to mojang about this the general issue is data which shouldn't
have been saved in the first place, so if we lose this data it's not really
an issue, bar being annoying spammy. if the spam gets on your nerves, shamefully,
all you can really do is forceUpgrade to get the conversions of the way.

Dropping as this breaks other aspects of the server and bar being spammy
seems to have no other real negative outcomes
This commit is contained in:
Shane Freeder 2021-06-26 12:56:06 +01:00
parent f800d80c45
commit 65c6d7f38f

View File

@ -1,208 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sat, 19 Jun 2021 10:54:52 -0700
Subject: [PATCH] Fix Codec log spam
Mojang did NOT add dataconverters for world gen configurations
that they CHANGED. So, the codec fails to parse old data.
This fixes two instances:
- IntProvider is new and Mojang did not account for old data.
Thankfully, only ColumnPlace needed to be special cased.
- TreeConfiguration had changes. Thankfully, they were
only renames for one value and thankfully defaults could
be provided for two new values (WITHOUT changing behavior).
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/MCUtil.java
+++ b/src/main/java/net/minecraft/server/MCUtil.java
@@ -0,0 +0,0 @@ public final class MCUtil {
public static int getTicketLevelFor(net.minecraft.world.level.chunk.ChunkStatus status) {
return net.minecraft.server.level.ChunkMap.MAX_VIEW_DISTANCE + net.minecraft.world.level.chunk.ChunkStatus.getDistance(status);
}
+
+ public static <A> com.mojang.serialization.MapCodec<A> fieldWithFallbacks(com.mojang.serialization.Codec<A> codec, String name, String ...fallback) {
+ return com.mojang.serialization.MapCodec.of(
+ new com.mojang.serialization.codecs.FieldEncoder<>(name, codec),
+ new FieldFallbackDecoder<>(name, java.util.Arrays.asList(fallback), codec),
+ () -> "FieldFallback[" + name + ": " + codec.toString() + "]"
+ );
+ }
+
+ // This is likely a common occurrence, sadly
+ public static final class FieldFallbackDecoder<A> extends com.mojang.serialization.MapDecoder.Implementation<A> {
+ protected final String name;
+ protected final List<String> fallback;
+ private final com.mojang.serialization.Decoder<A> elementCodec;
+
+ public FieldFallbackDecoder(final String name, final List<String> fallback, final com.mojang.serialization.Decoder<A> elementCodec) {
+ this.name = name;
+ this.fallback = fallback;
+ this.elementCodec = elementCodec;
+ }
+
+ @Override
+ public <T> com.mojang.serialization.DataResult<A> decode(final com.mojang.serialization.DynamicOps<T> ops, final com.mojang.serialization.MapLike<T> input) {
+ T value = input.get(name);
+ if (value == null) {
+ for (String fall : fallback) {
+ value = input.get(fall);
+ if (value != null) {
+ break;
+ }
+ }
+ if (value == null) {
+ return com.mojang.serialization.DataResult.error("No key " + name + " in " + input);
+ }
+ }
+ return elementCodec.parse(ops, value);
+ }
+
+ @Override
+ public <T> java.util.stream.Stream<T> keys(final com.mojang.serialization.DynamicOps<T> ops) {
+ return java.util.stream.Stream.of(ops.createString(name));
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ final FieldFallbackDecoder<?> that = (FieldFallbackDecoder<?>)o;
+ return java.util.Objects.equals(name, that.name) && java.util.Objects.equals(elementCodec, that.elementCodec)
+ && java.util.Objects.equals(fallback, that.fallback);
+ }
+
+ @Override
+ public int hashCode() {
+ return java.util.Objects.hash(name, fallback, elementCodec);
+ }
+
+ @Override
+ public String toString() {
+ return "FieldDecoder[" + name + ": " + elementCodec + ']';
+ }
+ }
}
diff --git a/src/main/java/net/minecraft/util/valueproviders/IntProvider.java b/src/main/java/net/minecraft/util/valueproviders/IntProvider.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/util/valueproviders/IntProvider.java
+++ b/src/main/java/net/minecraft/util/valueproviders/IntProvider.java
@@ -0,0 +0,0 @@ import net.minecraft.core.Registry;
public abstract class IntProvider {
private static final Codec<Either<Integer, IntProvider>> CONSTANT_OR_DISPATCH_CODEC = Codec.either(Codec.INT, Registry.INT_PROVIDER_TYPES.dispatch(IntProvider::getType, IntProviderType::codec));
- public static final Codec<IntProvider> CODEC = CONSTANT_OR_DISPATCH_CODEC.xmap((either) -> {
+ public static final Codec<IntProvider> CODEC_REAL = CONSTANT_OR_DISPATCH_CODEC.xmap((either) -> { // Paper - used by CODEC below
return either.map(ConstantInt::of, (intProvider) -> {
return intProvider;
});
}, (intProvider) -> {
return intProvider.getType() == IntProviderType.CONSTANT ? Either.left(((ConstantInt)intProvider).getValue()) : Either.right(intProvider);
});
+ // Paper start
+ public static final Codec<IntProvider> CODEC = new Codec<>() {
+ @Override
+ public <T> DataResult<com.mojang.datafixers.util.Pair<IntProvider, T>> decode(com.mojang.serialization.DynamicOps<T> ops, T input) {
+ /*
+ UniformInt:
+ count -> { (old format)
+ base, spread
+ } -> {UniformInt} { (new format & type)
+ base, base + spread
+ } */
+
+
+ if (ops.get(input, "base").result().isPresent() && ops.get(input, "spread").result().isPresent()) {
+ // detected old format
+ int base = ops.getNumberValue(ops.get(input, "base").result().get()).result().get().intValue();
+ int spread = ops.getNumberValue(ops.get(input, "spread").result().get()).result().get().intValue();
+ return DataResult.success(new com.mojang.datafixers.util.Pair<>(UniformInt.of(base, base + spread), input));
+ }
+
+ // not old format, forward to real codec
+ return CODEC_REAL.decode(ops, input);
+ }
+
+ @Override
+ public <T> DataResult<T> encode(IntProvider input, com.mojang.serialization.DynamicOps<T> ops, T prefix) {
+ // forward to real codec
+ return CODEC_REAL.encode(input, ops, prefix);
+ }
+ };
+ // Paper end
public static final Codec<IntProvider> NON_NEGATIVE_CODEC = codec(0, Integer.MAX_VALUE);
public static final Codec<IntProvider> POSITIVE_CODEC = codec(1, Integer.MAX_VALUE);
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/blockplacers/ColumnPlacer.java b/src/main/java/net/minecraft/world/level/levelgen/feature/blockplacers/ColumnPlacer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/blockplacers/ColumnPlacer.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/blockplacers/ColumnPlacer.java
@@ -0,0 +0,0 @@ import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.state.BlockState;
public class ColumnPlacer extends BlockPlacer {
- public static final Codec<ColumnPlacer> CODEC = RecordCodecBuilder.create((instance) -> {
+ public static final Codec<ColumnPlacer> CODEC_REAL = RecordCodecBuilder.create((instance) -> { // Paper - used by CODEC below
return instance.group(IntProvider.NON_NEGATIVE_CODEC.fieldOf("size").forGetter((columnPlacer) -> {
return columnPlacer.size;
})).apply(instance, ColumnPlacer::new);
});
+ // Paper start
+ public static final Codec<ColumnPlacer> CODEC = new Codec<>() {
+ @Override
+ public <T> com.mojang.serialization.DataResult<com.mojang.datafixers.util.Pair<ColumnPlacer, T>> decode(com.mojang.serialization.DynamicOps<T> ops, T input) {
+ /*
+ Old format:
+ min_size, extra_size -> BiasedToBottomInt(min_size, min_size + extra_size) to place @ root.size
+ */
+ if (ops.get(input, "min_size").result().isPresent() && ops.get(input, "extra_size").result().isPresent()) {
+ // detected old format
+ int min_size = ops.getNumberValue(ops.get(input, "min_size").result().get()).result().get().intValue();
+ int extra_size = ops.getNumberValue(ops.get(input, "extra_size").result().get()).result().get().intValue();
+ return com.mojang.serialization.DataResult.success(
+ new com.mojang.datafixers.util.Pair<>(new ColumnPlacer(net.minecraft.util.valueproviders.BiasedToBottomInt.of(
+ min_size, min_size + extra_size
+ )), input)
+ );
+ }
+
+ // not old format, forward to real codec
+ return CODEC_REAL.decode(ops, input);
+ }
+
+ @Override
+ public <T> com.mojang.serialization.DataResult<T> encode(ColumnPlacer input, com.mojang.serialization.DynamicOps<T> ops, T prefix) {
+ // forward to real codec
+ return CODEC_REAL.encode(input, ops, prefix);
+ }
+ };
+ // Paper end
private final IntProvider size;
public ColumnPlacer(IntProvider size) {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/configurations/TreeConfiguration.java b/src/main/java/net/minecraft/world/level/levelgen/feature/configurations/TreeConfiguration.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/configurations/TreeConfiguration.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/configurations/TreeConfiguration.java
@@ -0,0 +0,0 @@ public class TreeConfiguration implements FeatureConfiguration {
return treeConfiguration.trunkProvider;
}), TrunkPlacer.CODEC.fieldOf("trunk_placer").forGetter((treeConfiguration) -> {
return treeConfiguration.trunkPlacer;
- }), BlockStateProvider.CODEC.fieldOf("foliage_provider").forGetter((treeConfiguration) -> {
+ }), net.minecraft.server.MCUtil.fieldWithFallbacks(BlockStateProvider.CODEC, "foliage_provider", "leaves_provider").forGetter((treeConfiguration) -> { // Paper - provide fallback for rename
return treeConfiguration.foliageProvider;
- }), BlockStateProvider.CODEC.fieldOf("sapling_provider").forGetter((treeConfiguration) -> {
+ }), BlockStateProvider.CODEC.optionalFieldOf("sapling_provider", new SimpleStateProvider(Blocks.OAK_SAPLING.defaultBlockState())).forGetter((treeConfiguration) -> { // Paper - provide default - it looks like for now this is OK because it's just used to check canSurvive. Same check happens in 1.16.5 for the default we provide - so it should retain behavior...
return treeConfiguration.saplingProvider;
}), FoliagePlacer.CODEC.fieldOf("foliage_placer").forGetter((treeConfiguration) -> {
return treeConfiguration.foliagePlacer;
- }), BlockStateProvider.CODEC.fieldOf("dirt_provider").forGetter((treeConfiguration) -> {
+ }), BlockStateProvider.CODEC.optionalFieldOf("dirt_provider", new SimpleStateProvider(Blocks.DIRT.defaultBlockState())).forGetter((treeConfiguration) -> { // Paper - provide defaults, old data DOES NOT have this key (thankfully ALL OLD DATA used DIRT)
return treeConfiguration.dirtProvider;
}), FeatureSize.CODEC.fieldOf("minimum_size").forGetter((treeConfiguration) -> {
return treeConfiguration.minimumSize;