Skip to content

Commit cb3dd89

Browse files
committed
Implement more data hashing
1 parent 5689389 commit cb3dd89

File tree

9 files changed

+144
-37
lines changed

9 files changed

+144
-37
lines changed

api/src/main/java/com/viaversion/viaversion/api/minecraft/PaintingVariant.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323
package com.viaversion.viaversion.api.minecraft;
2424

2525
import com.viaversion.nbt.tag.Tag;
26+
import com.viaversion.viaversion.api.minecraft.codec.Ops;
2627
import com.viaversion.viaversion.api.type.Types;
2728
import com.viaversion.viaversion.api.type.types.misc.HolderType;
29+
import com.viaversion.viaversion.util.Key;
2830
import io.netty.buffer.ByteBuf;
2931
import org.checkerframework.checker.nullness.qual.Nullable;
3032

@@ -69,5 +71,16 @@ public void writeDirect(final ByteBuf buffer, final PaintingVariant variant) {
6971
Types.OPTIONAL_TAG.write(buffer, variant.title());
7072
Types.OPTIONAL_TAG.write(buffer, variant.author());
7173
}
74+
75+
@Override
76+
public void writeDirect(final Ops ops, final PaintingVariant value) {
77+
// Unused, cannot be direct despite having a direct network codec
78+
ops.writeMap(map -> map
79+
.write("width", Types.INT, value.width())
80+
.write("height", Types.INT, value.height())
81+
.write("asset_id", Types.RESOURCE_LOCATION, Key.of(value.assetId()))
82+
.writeOptional("title", Types.TAG, value.title())
83+
.writeOptional("author", Types.TAG, value.author()));
84+
}
7285
};
7386
}

api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Consumable1_21_2.java

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,17 @@
2323
package com.viaversion.viaversion.api.minecraft.item.data;
2424

2525
import com.viaversion.viaversion.api.connection.UserConnection;
26+
import com.viaversion.viaversion.api.data.MappingData;
2627
import com.viaversion.viaversion.api.minecraft.Holder;
28+
import com.viaversion.viaversion.api.minecraft.HolderSet;
2729
import com.viaversion.viaversion.api.minecraft.SoundEvent;
30+
import com.viaversion.viaversion.api.minecraft.codec.Ops;
2831
import com.viaversion.viaversion.api.protocol.Protocol;
2932
import com.viaversion.viaversion.api.type.Type;
3033
import com.viaversion.viaversion.api.type.Types;
3134
import com.viaversion.viaversion.api.type.types.ArrayType;
35+
import com.viaversion.viaversion.api.type.types.misc.HolderSetType;
36+
import com.viaversion.viaversion.api.type.types.misc.HolderType;
3237
import com.viaversion.viaversion.util.Copyable;
3338
import com.viaversion.viaversion.util.Rewritable;
3439
import io.netty.buffer.ByteBuf;
@@ -37,12 +42,51 @@ public record Consumable1_21_2(float consumeSeconds, int animationType, Holder<S
3742
boolean hasConsumeParticles,
3843
ConsumeEffect<?>[] consumeEffects) implements Copyable, Rewritable {
3944

45+
private static final HolderSetType REMOVE_EFFECTS_TYPE = new HolderSetType() {
46+
@Override
47+
public void write(final Ops ops, final HolderSet value) {
48+
ops.writeMap(map -> map.write("effects", new HolderSetType(EnumTypes.MOB_EFFECT), value));
49+
}
50+
};
51+
private static final Type<Float> TELEPORT_RANDOMLY_TYPE = new Type<>(Float.class) {
52+
@Override
53+
public void write(final ByteBuf buffer, final Float value) {
54+
Types.FLOAT.writePrimitive(buffer, value);
55+
}
56+
57+
@Override
58+
public Float read(final ByteBuf buffer) {
59+
return Types.FLOAT.readPrimitive(buffer);
60+
}
61+
62+
@Override
63+
public void write(final Ops ops, final Float value) {
64+
ops.writeMap(map -> map.write("diameter", Types.FLOAT, 16F));
65+
}
66+
};
67+
private static final HolderType<SoundEvent> PLAY_SOUND_TYPE = new HolderType<>(MappingData.MappingType.SOUND) {
68+
@Override
69+
public SoundEvent readDirect(final ByteBuf buffer) {
70+
return Types.SOUND_EVENT.readDirect(buffer);
71+
}
72+
73+
@Override
74+
public void writeDirect(final ByteBuf buffer, final SoundEvent value) {
75+
Types.SOUND_EVENT.writeDirect(buffer, value);
76+
}
77+
78+
@Override
79+
public void write(final Ops ops, final Holder<SoundEvent> value) {
80+
ops.writeMap(map -> map.write("sound", Types.SOUND_EVENT, value));
81+
}
82+
};
83+
4084
public static final Type<?>[] EFFECT_TYPES = {
4185
ApplyStatusEffects.TYPE,
42-
Types.HOLDER_SET, // remove effects
86+
REMOVE_EFFECTS_TYPE,
4387
Types.EMPTY, // clear all effects
44-
Types.FLOAT, // teleport randomly
45-
Types.SOUND_EVENT // play sound
88+
TELEPORT_RANDOMLY_TYPE,
89+
PLAY_SOUND_TYPE
4690
};
4791

4892
public static final Type<Consumable1_21_2> TYPE = new Type<>(Consumable1_21_2.class) {
@@ -64,6 +108,17 @@ public void write(final ByteBuf buffer, final Consumable1_21_2 value) {
64108
buffer.writeBoolean(value.hasConsumeParticles);
65109
ConsumeEffect.ARRAY_TYPE.write(buffer, value.consumeEffects);
66110
}
111+
112+
@Override
113+
public void write(final Ops ops, final Consumable1_21_2 value) {
114+
final Holder<SoundEvent> defaultSound = Holder.of(ops.context().registryAccess().id(MappingData.MappingType.SOUND, "entity.generic.eat"));
115+
ops.writeMap(map -> map
116+
.writeOptional("consume_seconds", Types.FLOAT, value.consumeSeconds, 1.6F)
117+
.writeOptional("animation", EnumTypes.ITEM_USE_ANIMATION, value.animationType, 1)
118+
.writeOptional("sound", Types.SOUND_EVENT, value.sound, defaultSound)
119+
.writeOptional("has_consume_particles", Types.BOOLEAN, value.hasConsumeParticles, true)
120+
.writeOptional("consume_effects", ConsumeEffect.ARRAY_TYPE, value.consumeEffects, new ConsumeEffect<?>[0]));
121+
}
67122
};
68123

69124
public record ConsumeEffect<T>(int id, Type<T> type, T value) {
@@ -83,6 +138,17 @@ public void write(final ByteBuf buffer, final ConsumeEffect<?> value) {
83138
Types.VAR_INT.writePrimitive(buffer, value.id);
84139
value.writeValue(buffer);
85140
}
141+
142+
@Override
143+
public void write(final Ops ops, final ConsumeEffect<?> value) {
144+
writeGeneric(ops, value);
145+
}
146+
147+
private <E> void writeGeneric(final Ops ops, final ConsumeEffect<E> value) {
148+
ops.writeMap(map -> map
149+
.write("type", EnumTypes.CONSUME_EFFECT, value.id)
150+
.writeInlinedMap(value.type, value.value));
151+
}
86152
};
87153
public static final Type<ConsumeEffect<?>[]> ARRAY_TYPE = new ArrayType<>(TYPE);
88154

@@ -111,6 +177,13 @@ public void write(final ByteBuf buffer, final ApplyStatusEffects value) {
111177
PotionEffect.ARRAY_TYPE.write(buffer, value.effects);
112178
buffer.writeFloat(value.probability);
113179
}
180+
181+
@Override
182+
public void write(final Ops ops, final ApplyStatusEffects value) {
183+
ops.writeMap(map -> map
184+
.write("effects", PotionEffect.ARRAY_TYPE, value.effects)
185+
.writeOptional("probability", Types.FLOAT, value.probability, 1F));
186+
}
114187
};
115188
}
116189

api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/DeathProtection.java

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,18 @@
2222
*/
2323
package com.viaversion.viaversion.api.minecraft.item.data;
2424

25+
import com.viaversion.viaversion.api.minecraft.codec.Ops;
2526
import com.viaversion.viaversion.api.minecraft.item.data.Consumable1_21_2.ConsumeEffect;
27+
import com.viaversion.viaversion.api.type.TransformingType;
2628
import com.viaversion.viaversion.api.type.Type;
2729
import com.viaversion.viaversion.util.Copyable;
28-
import io.netty.buffer.ByteBuf;
2930

3031
public record DeathProtection(ConsumeEffect<?>[] deathEffects) implements Copyable {
3132

32-
public static final Type<DeathProtection> TYPE = new Type<>(DeathProtection.class) {
33+
public static final Type<DeathProtection> TYPE = new TransformingType<>(ConsumeEffect.ARRAY_TYPE, DeathProtection.class, DeathProtection::new, DeathProtection::deathEffects) {
3334
@Override
34-
public DeathProtection read(final ByteBuf buffer) {
35-
final ConsumeEffect<?>[] deathEffects = ConsumeEffect.ARRAY_TYPE.read(buffer);
36-
return new DeathProtection(deathEffects);
37-
}
38-
39-
@Override
40-
public void write(final ByteBuf buffer, final DeathProtection value) {
41-
ConsumeEffect.ARRAY_TYPE.write(buffer, value.deathEffects);
35+
public void write(final Ops ops, final DeathProtection value) {
36+
ops.writeMap(map -> map.write("death_effects", ConsumeEffect.ARRAY_TYPE, value.deathEffects));
4237
}
4338
};
4439

api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/EnumTypes.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import com.viaversion.viaversion.api.type.types.EnumType.Fallback;
2727
import com.viaversion.viaversion.api.type.types.FakeEnumType;
2828
import com.viaversion.viaversion.api.type.types.misc.RegistryValueType;
29+
import com.viaversion.viaversion.util.Key;
2930
import java.util.List;
3031

3132
import static com.viaversion.viaversion.api.type.types.FakeEnumType.Entry.of;
@@ -45,10 +46,12 @@ public final class EnumTypes {
4546
public static final EnumType LLAMA_VARIANT = new EnumType(Fallback.CLAMP, "creamy", "white", "brown", "gray");
4647
public static final EnumType AXOLOTL_VARIANT = new EnumType("lucy", "wild", "gold", "cyan", "blue");
4748
public static final EnumType EQUIPMENT_SLOT = new EnumType("mainhand", "feet", "legs", "chest", "head", "offhand", "body", "saddle");
49+
public static final EnumType ITEM_USE_ANIMATION = new EnumType("none", "eat", "drink", "block", "bow", "trident", "crossbow", "spyglass", "toot_horn", "brush", "bundle", "spear");
4850
// Enums with non-ordinal ids
4951
public static final FakeEnumType RABBIT_VARIANT = new FakeEnumType(List.of("brown", "white", "black", "white_splotched", "gold", "salt"), of(99, "evil"));
5052
// Pretty much enums, but with a resource location
51-
public static final RegistryValueType VILLAGER_TYPE = new RegistryValueType("desert", "jungle", "plains", "savanna", "snow", "swamp", "taiga");
52-
public static final RegistryValueType POTION = new RegistryValueType("water", "mundane", "thick", "awkward", "night_vision", "long_night_vision", "invisibility", "long_invisibility", "leaping", "long_leaping", "strong_leaping", "fire_resistance", "long_fire_resistance", "swiftness", "long_swiftness", "strong_swiftness", "slowness", "long_slowness", "strong_slowness", "turtle_master", "long_turtle_master", "strong_turtle_master", "water_breathing", "long_water_breathing", "healing", "strong_healing", "harming", "strong_harming", "poison", "long_poison", "strong_poison", "regeneration", "long_regeneration", "strong_regeneration", "strength", "long_strength", "strong_strength", "weakness", "long_weakness", "luck", "slow_falling", "long_slow_falling", "wind_charged", "weaving", "oozing", "infested");
53-
public static final RegistryValueType MOB_EFFECT = new RegistryValueType("speed", "slowness", "haste", "mining_fatigue", "strength", "instant_health", "instant_damage", "jump_boost", "nausea", "regeneration", "resistance", "fire_resistance", "water_breathing", "invisibility", "blindness", "night_vision", "hunger", "weakness", "poison", "wither", "health_boost", "absorption", "saturation", "glowing", "levitation", "luck", "unluck", "slow_falling", "conduit_power", "dolphins_grace", "bad_omen", "hero_of_the_village", "darkness", "trial_omen", "raid_omen", "wind_charged", "weaving", "oozing", "infested");
53+
public static final RegistryValueType VILLAGER_TYPE = new RegistryValueType(Key.of("villager_type"), "desert", "jungle", "plains", "savanna", "snow", "swamp", "taiga");
54+
public static final RegistryValueType POTION = new RegistryValueType(Key.of("potion"), "water", "mundane", "thick", "awkward", "night_vision", "long_night_vision", "invisibility", "long_invisibility", "leaping", "long_leaping", "strong_leaping", "fire_resistance", "long_fire_resistance", "swiftness", "long_swiftness", "strong_swiftness", "slowness", "long_slowness", "strong_slowness", "turtle_master", "long_turtle_master", "strong_turtle_master", "water_breathing", "long_water_breathing", "healing", "strong_healing", "harming", "strong_harming", "poison", "long_poison", "strong_poison", "regeneration", "long_regeneration", "strong_regeneration", "strength", "long_strength", "strong_strength", "weakness", "long_weakness", "luck", "slow_falling", "long_slow_falling", "wind_charged", "weaving", "oozing", "infested");
55+
public static final RegistryValueType MOB_EFFECT = new RegistryValueType(Key.of("mob_effect"), "speed", "slowness", "haste", "mining_fatigue", "strength", "instant_health", "instant_damage", "jump_boost", "nausea", "regeneration", "resistance", "fire_resistance", "water_breathing", "invisibility", "blindness", "night_vision", "hunger", "weakness", "poison", "wither", "health_boost", "absorption", "saturation", "glowing", "levitation", "luck", "unluck", "slow_falling", "conduit_power", "dolphins_grace", "bad_omen", "hero_of_the_village", "darkness", "trial_omen", "raid_omen", "wind_charged", "weaving", "oozing", "infested");
56+
public static final RegistryValueType CONSUME_EFFECT = new RegistryValueType(Key.of("consume_effect_type"), "apply_effects", "remove_effects", "clear_all_effects", "teleport_randomly", "play_sound");
5457
}

api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/JukeboxPlayable.java

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,14 @@
2727
import com.viaversion.viaversion.api.minecraft.EitherHolder;
2828
import com.viaversion.viaversion.api.minecraft.Holder;
2929
import com.viaversion.viaversion.api.minecraft.SoundEvent;
30+
import com.viaversion.viaversion.api.minecraft.codec.Ops;
3031
import com.viaversion.viaversion.api.protocol.Protocol;
32+
import com.viaversion.viaversion.api.type.TransformingType;
3133
import com.viaversion.viaversion.api.type.Type;
3234
import com.viaversion.viaversion.api.type.Types;
3335
import com.viaversion.viaversion.api.type.types.misc.EitherHolderType;
3436
import com.viaversion.viaversion.api.type.types.misc.HolderType;
37+
import com.viaversion.viaversion.util.Key;
3538
import com.viaversion.viaversion.util.Rewritable;
3639
import io.netty.buffer.ByteBuf;
3740

@@ -48,9 +51,9 @@ public JukeboxPlayable(final String resourceKey, final boolean showInTooltip) {
4851
public static final Type<JukeboxPlayable> TYPE1_21 = new Type<>(JukeboxPlayable.class) {
4952
@Override
5053
public JukeboxPlayable read(final ByteBuf buffer) {
51-
final EitherHolder<JukeboxSong> position = EitherHolderType.read(buffer, JukeboxSong.TYPE);
54+
final EitherHolder<JukeboxSong> song = EitherHolderType.read(buffer, JukeboxSong.TYPE);
5255
final boolean showInTooltip = buffer.readBoolean();
53-
return new JukeboxPlayable(position, showInTooltip);
56+
return new JukeboxPlayable(song, showInTooltip);
5457
}
5558

5659
@Override
@@ -59,18 +62,10 @@ public void write(final ByteBuf buffer, final JukeboxPlayable value) {
5962
buffer.writeBoolean(value.showInTooltip);
6063
}
6164
};
62-
public static final Type<JukeboxPlayable> TYPE1_21_5 = new Type<>(JukeboxPlayable.class) {
63-
@Override
64-
public JukeboxPlayable read(final ByteBuf buffer) {
65-
final EitherHolder<JukeboxSong> position = EitherHolderType.read(buffer, JukeboxSong.TYPE);
66-
return new JukeboxPlayable(position, true);
67-
}
68-
69-
@Override
70-
public void write(final ByteBuf buffer, final JukeboxPlayable value) {
71-
EitherHolderType.write(buffer, value.song, JukeboxSong.TYPE);
72-
}
73-
};
65+
public static final Type<JukeboxPlayable> TYPE1_21_5 = TransformingType.of(
66+
new EitherHolderType<>(JukeboxSong.TYPE), JukeboxPlayable.class,
67+
song -> new JukeboxPlayable(song, true), JukeboxPlayable::song
68+
);
7469

7570
@Override
7671
public JukeboxPlayable rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
@@ -107,6 +102,21 @@ public void writeDirect(final ByteBuf buffer, final JukeboxSong value) {
107102
buffer.writeFloat(value.lengthInSeconds);
108103
Types.VAR_INT.writePrimitive(buffer, value.comparatorOutput);
109104
}
105+
106+
@Override
107+
public void writeDirect(final Ops ops, final JukeboxSong value) {
108+
// Unused, cannot be direct despite having a direct network codec
109+
ops.writeMap(map -> map
110+
.write("sound_event", Types.SOUND_EVENT, value.soundEvent)
111+
.write("description", Types.TAG, value.description)
112+
.write("length_in_seconds", Types.FLOAT, value.lengthInSeconds)
113+
.write("comparator_output", Types.INT, value.comparatorOutput));
114+
}
115+
116+
@Override
117+
protected Key identifier(final Ops ops, final int id) {
118+
return ops.context().registryAccess().registryKey("jukebox_song", id);
119+
}
110120
};
111121

112122
@Override

api/src/main/java/com/viaversion/viaversion/api/type/types/misc/HolderSetType.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,11 @@ public void write(final Ops ops, final HolderSet value) {
103103
private Key key(final Ops ops, final int id) {
104104
if (registryKey instanceof final MappingData.MappingType mappingType) {
105105
return ops.context().registryAccess().key(mappingType, id);
106+
} else if (registryKey instanceof final RegistryValueType registryValueType) {
107+
return Key.of(registryValueType.byId(id));
108+
} else {
109+
return ops.context().registryAccess().registryKey(registryKey.key().toString(), id);
106110
}
107-
return ops.context().registryAccess().registryKey(registryKey.key().toString(), id);
108111
}
109112

110113
public static final class OptionalHolderSetType extends OptionalType<HolderSet> {

api/src/main/java/com/viaversion/viaversion/api/type/types/misc/HolderType.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public void write(final Ops ops, final Holder<T> value) {
7878
}
7979

8080
protected Key identifier(final Ops ops, final int id) {
81-
Preconditions.checkArgument(mappingType != null, "Mapping type is not defined for this HolderType");
81+
Preconditions.checkArgument(mappingType != null, "Mapping type is not defined for this HolderType: " + getClass().getName());
8282
return ops.context().registryAccess().key(mappingType, id);
8383
}
8484

api/src/main/java/com/viaversion/viaversion/api/type/types/misc/RegistryValueType.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,19 @@
2222
*/
2323
package com.viaversion.viaversion.api.type.types.misc;
2424

25+
import com.viaversion.viaversion.api.minecraft.RegistryKey;
2526
import com.viaversion.viaversion.api.minecraft.codec.Ops;
2627
import com.viaversion.viaversion.api.type.Types;
2728
import com.viaversion.viaversion.api.type.types.VarIntType;
2829
import com.viaversion.viaversion.util.Key;
2930

30-
public final class RegistryValueType extends VarIntType {
31+
public final class RegistryValueType extends VarIntType implements RegistryKey {
3132

33+
private final Key key;
3234
private final String[] names;
3335

34-
public RegistryValueType(final String... names) {
36+
public RegistryValueType(final Key key, final String... names) {
37+
this.key = key;
3538
this.names = names;
3639
for (int i = 0; i < names.length; i++) {
3740
names[i] = Key.namespaced(names[i]);
@@ -46,4 +49,13 @@ public void write(final Ops ops, final Integer value) {
4649
public String[] names() {
4750
return names;
4851
}
52+
53+
public String byId(final int id) {
54+
return names[id];
55+
}
56+
57+
@Override
58+
public Key key() {
59+
return key;
60+
}
4961
}

common/src/main/java/com/viaversion/viaversion/codec/CodecRegistryContext.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ public record CodecRegistryContext(Protocol<?, ?, ?, ?> protocol, RegistryAccess
3030

3131
// Generally from hardcoded, but highly variable client data
3232
private static final Set<StructuredDataKey<?>> NOT_IMPLEMENTED = new ReferenceOpenHashSet<>(List.of(
33-
StructuredDataKey.CONSUMABLE1_21_2, StructuredDataKey.JUKEBOX_PLAYABLE1_21_5,
34-
StructuredDataKey.DEATH_PROTECTION, StructuredDataKey.PAINTING_VARIANT
3533
));
3634

3735
public CodecRegistryContext(final Protocol<?, ?, ?, ?> protocol, final RegistryAccess registryAccess, final boolean mapped) {
@@ -47,6 +45,6 @@ public boolean isSupported(final StructuredDataKey<?> key) {
4745
}
4846

4947
final VersionedTypesHolder types = mapped ? protocol.mappedTypes() : protocol.types();
50-
return !NOT_IMPLEMENTED.contains(key) && types.structuredDataKeys().supportsOps(key);
48+
return (NOT_IMPLEMENTED.isEmpty() || !NOT_IMPLEMENTED.contains(key)) && types.structuredDataKeys().supportsOps(key);
5149
}
5250
}

0 commit comments

Comments
 (0)