3
0
Mirror von https://github.com/ViaVersion/ViaVersion.git synchronisiert 2024-11-08 17:20:24 +01:00

Use mappings instead of hardcoding entity ids

Dieser Commit ist enthalten in:
Nassim Jahnke 2022-04-01 16:54:07 +02:00
Ursprung f0462085d3
Commit 1d5ae0e3e0
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 6BE3B555EBC5982B
27 geänderte Dateien mit 575 neuen und 190 gelöschten Zeilen

Datei anzeigen

@ -64,7 +64,7 @@ public interface ViaAPI<T> {
* @return API version incremented with meaningful API changes * @return API version incremented with meaningful API changes
*/ */
default int apiVersion() { default int apiVersion() {
return 11; return 12;
} }
/** /**

Datei anzeigen

@ -24,7 +24,10 @@ package com.viaversion.viaversion.api.data;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
public interface FullMappingData { /**
* Mappings containing the full string identifier mappings.
*/
public interface FullMappings {
Mappings mappings(); Mappings mappings();

Datei anzeigen

@ -26,14 +26,14 @@ import com.google.gson.JsonArray;
import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntMap;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
public class FullMappingDataBase implements FullMappingData { public class FullMappingsBase implements FullMappings {
private final Object2IntMap<String> stringToId; private final Object2IntMap<String> stringToId;
private final Object2IntMap<String> mappedStringToId; private final Object2IntMap<String> mappedStringToId;
private final String[] idToString; private final String[] idToString;
private final String[] mappedIdToString; private final String[] mappedIdToString;
private final Mappings mappings; private final Mappings mappings;
public FullMappingDataBase(final JsonArray oldMappings, final JsonArray newMappings, final Mappings mappings) { public FullMappingsBase(final JsonArray oldMappings, final JsonArray newMappings, final Mappings mappings) {
this.mappings = mappings; this.mappings = mappings;
stringToId = MappingDataLoader.arrayToMap(oldMappings); stringToId = MappingDataLoader.arrayToMap(oldMappings);
mappedStringToId = MappingDataLoader.arrayToMap(newMappings); mappedStringToId = MappingDataLoader.arrayToMap(newMappings);

Datei anzeigen

@ -0,0 +1,66 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.data;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
public class Int2IntMapMappings implements Mappings {
private final Int2IntMap mappings;
private final int mappedIds;
protected Int2IntMapMappings(final Int2IntMap mappings, final int mappedIds) {
this.mappings = mappings;
this.mappedIds = mappedIds;
mappings.defaultReturnValue(-1);
}
public static Int2IntMapMappings of(final Int2IntMap mappings, final int mappedIds) {
return new Int2IntMapMappings(mappings, mappedIds);
}
public static Int2IntMapMappings of() {
return new Int2IntMapMappings(new Int2IntOpenHashMap(), -1);
}
@Override
public int getNewId(final int id) {
return mappings.get(id);
}
@Override
public void setNewId(final int id, final int newId) {
mappings.put(id, newId);
}
@Override
public int size() {
return mappings.size();
}
@Override
public int mappedSize() {
return mappedIds;
}
}

Datei anzeigen

@ -105,7 +105,9 @@ public interface MappingData {
@Nullable Mappings getEnchantmentMappings(); @Nullable Mappings getEnchantmentMappings();
@Nullable FullMappingData getArgumentTypeMappings(); @Nullable FullMappings getEntityMappings();
@Nullable FullMappings getArgumentTypeMappings();
@Nullable Mappings getPaintingMappings(); @Nullable Mappings getPaintingMappings();
} }

Datei anzeigen

@ -44,7 +44,8 @@ public class MappingDataBase implements MappingData {
protected final String newVersion; protected final String newVersion;
protected final boolean hasDiffFile; protected final boolean hasDiffFile;
protected Int2IntBiMap itemMappings; protected Int2IntBiMap itemMappings;
protected FullMappingData argumentTypeMappings; protected FullMappings argumentTypeMappings;
protected FullMappings entityMappings;
protected ParticleMappings particleMappings; protected ParticleMappings particleMappings;
protected Mappings blockMappings; protected Mappings blockMappings;
protected Mappings blockStateMappings; protected Mappings blockStateMappings;
@ -81,11 +82,8 @@ public class MappingDataBase implements MappingData {
enchantmentMappings = loadFromArray(oldMappings, newMappings, diffmapping, "enchantments"); enchantmentMappings = loadFromArray(oldMappings, newMappings, diffmapping, "enchantments");
paintingMappings = loadFromArray(oldMappings, newMappings, diffmapping, "paintings"); paintingMappings = loadFromArray(oldMappings, newMappings, diffmapping, "paintings");
Mappings argumentTypeMappings = loadFromArray(oldMappings, newMappings, diffmapping, "argumenttypes"); entityMappings = loadFullMappings(oldMappings, newMappings, diffmapping, "entities");
if (argumentTypeMappings != null) { argumentTypeMappings = loadFullMappings(oldMappings, newMappings, diffmapping, "argumenttypes");
this.argumentTypeMappings = new FullMappingDataBase(oldMappings.getAsJsonArray("argumenttypes"),
newMappings.getAsJsonArray("argumenttypes"), argumentTypeMappings);
}
Mappings particles = loadFromArray(oldMappings, newMappings, diffmapping, "particles"); Mappings particles = loadFromArray(oldMappings, newMappings, diffmapping, "particles");
if (particles != null) { if (particles != null) {
@ -113,6 +111,11 @@ public class MappingDataBase implements MappingData {
loadExtras(oldMappings, newMappings, diffmapping); loadExtras(oldMappings, newMappings, diffmapping);
} }
protected FullMappings loadFullMappings(JsonObject oldMappings, JsonObject newMappings, @Nullable JsonObject diffMappings, String key) {
Mappings mappings = loadFromArray(oldMappings, newMappings, diffMappings, key);
return mappings != null ? new FullMappingsBase(oldMappings.getAsJsonArray(key), newMappings.getAsJsonArray(key), mappings) : null;
}
private void loadTags(RegistryType type, JsonObject object, Object2IntMap<String> typeMapping) { private void loadTags(RegistryType type, JsonObject object, Object2IntMap<String> typeMapping) {
JsonObject tags = object.getAsJsonObject(type.resourceLocation()); JsonObject tags = object.getAsJsonObject(type.resourceLocation());
List<TagData> tagsList = new ArrayList<>(tags.size()); List<TagData> tagsList = new ArrayList<>(tags.size());
@ -208,7 +211,12 @@ public class MappingDataBase implements MappingData {
} }
@Override @Override
public @Nullable FullMappingData getArgumentTypeMappings() { public @Nullable FullMappings getEntityMappings() {
return entityMappings;
}
@Override
public @Nullable FullMappings getArgumentTypeMappings() {
return argumentTypeMappings; return argumentTypeMappings;
} }

Datei anzeigen

@ -164,7 +164,7 @@ public class MappingDataLoader {
mapIdentifiers(output, oldIdentifiers, newIdentifiers, diffIdentifiers, true); mapIdentifiers(output, oldIdentifiers, newIdentifiers, diffIdentifiers, true);
} }
private static int mapIdentifierEntry(Map.Entry<String, JsonElement> entry, Object2IntMap newIdentifierMap, @Nullable JsonObject diffIdentifiers, boolean warnOnMissing) { private static int mapIdentifierEntry(Map.Entry<String, JsonElement> entry, Object2IntMap<String> newIdentifierMap, @Nullable JsonObject diffIdentifiers, boolean warnOnMissing) {
int value = newIdentifierMap.getInt(entry.getValue().getAsString()); int value = newIdentifierMap.getInt(entry.getValue().getAsString());
if (value == -1) { if (value == -1) {
// Search in diff mappings // Search in diff mappings

Datei anzeigen

@ -38,6 +38,28 @@ public interface Mappings {
*/ */
int getNewId(int id); int getNewId(int id);
/**
* Returns the mapped id from the given id, or the given default if unmapped/invalid.
*
* @param id unmapped id
* @param def fallback return value
* @return mapped id, or -1 if invalid/out of bounds
*/
default int getNewIdOrDefault(int id, int def) {
final int mappedId = getNewId(id);
return mappedId != -1 ? mappedId : def;
}
/**
* Returns whether the id has a mapping.
*
* @param id unmapped id
* @return whether the id has a mapped id
*/
default boolean contains(int id) {
return getNewId(id) != -1;
}
/** /**
* Manually maps a specific id. * Manually maps a specific id.
* *

Datei anzeigen

@ -26,7 +26,7 @@ import com.google.gson.JsonArray;
import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntList;
public class ParticleMappings extends FullMappingDataBase { public class ParticleMappings extends FullMappingsBase {
private final IntList itemParticleIds = new IntArrayList(2); private final IntList itemParticleIds = new IntArrayList(2);
private final IntList blockParticleIds = new IntArrayList(4); private final IntList blockParticleIds = new IntArrayList(4);

Datei anzeigen

@ -170,6 +170,16 @@ public class Entity1_10Types {
public EntityType getParent() { public EntityType getParent() {
return parent; return parent;
} }
@Override
public String identifier() {
throw new UnsupportedOperationException();
}
@Override
public boolean isAbstractType() {
return id != -1;
}
} }
public enum ObjectType implements com.viaversion.viaversion.api.minecraft.entities.ObjectType { public enum ObjectType implements com.viaversion.viaversion.api.minecraft.entities.ObjectType {

Datei anzeigen

@ -187,6 +187,16 @@ public class Entity1_11Types {
return parent; return parent;
} }
@Override
public String identifier() {
throw new UnsupportedOperationException();
}
@Override
public boolean isAbstractType() {
return id != -1;
}
static { static {
for (EntityType type : EntityType.values()) { for (EntityType type : EntityType.values()) {
TYPES.put(type.id, type); TYPES.put(type.id, type);

Datei anzeigen

@ -191,6 +191,16 @@ public class Entity1_12Types {
return parent; return parent;
} }
@Override
public String identifier() {
throw new UnsupportedOperationException();
}
@Override
public boolean isAbstractType() {
return id != -1;
}
static { static {
for (EntityType type : EntityType.values()) { for (EntityType type : EntityType.values()) {
TYPES.put(type.id, type); TYPES.put(type.id, type);

Datei anzeigen

@ -240,6 +240,16 @@ public class Entity1_13Types {
return parent; return parent;
} }
@Override
public String identifier() {
throw new UnsupportedOperationException();
}
@Override
public boolean isAbstractType() {
return id != -1;
}
static { static {
for (EntityType type : EntityType.values()) { for (EntityType type : EntityType.values()) {
TYPES.put(type.id, type); TYPES.put(type.id, type);

Datei anzeigen

@ -224,6 +224,16 @@ public enum Entity1_14Types implements EntityType {
return parent; return parent;
} }
@Override
public String identifier() {
throw new UnsupportedOperationException();
}
@Override
public boolean isAbstractType() {
return id != -1;
}
static { static {
TYPES = EntityTypeUtil.toOrderedArray(values()); TYPES = EntityTypeUtil.toOrderedArray(values());
} }

Datei anzeigen

@ -226,6 +226,16 @@ public enum Entity1_15Types implements EntityType {
return parent; return parent;
} }
@Override
public String identifier() {
throw new UnsupportedOperationException();
}
@Override
public boolean isAbstractType() {
return id != -1;
}
static { static {
TYPES = EntityTypeUtil.toOrderedArray(values()); TYPES = EntityTypeUtil.toOrderedArray(values());
} }

Datei anzeigen

@ -231,6 +231,16 @@ public enum Entity1_16Types implements EntityType {
return parent; return parent;
} }
@Override
public String identifier() {
throw new UnsupportedOperationException();
}
@Override
public boolean isAbstractType() {
return id != -1;
}
static { static {
TYPES = EntityTypeUtil.toOrderedArray(values()); TYPES = EntityTypeUtil.toOrderedArray(values());
} }

Datei anzeigen

@ -235,6 +235,16 @@ public enum Entity1_16_2Types implements EntityType {
return parent; return parent;
} }
@Override
public String identifier() {
throw new UnsupportedOperationException();
}
@Override
public boolean isAbstractType() {
return id != -1;
}
static { static {
TYPES = EntityTypeUtil.toOrderedArray(values()); TYPES = EntityTypeUtil.toOrderedArray(values());
} }

Datei anzeigen

@ -240,6 +240,16 @@ public enum Entity1_17Types implements EntityType {
return parent; return parent;
} }
@Override
public String identifier() {
throw new UnsupportedOperationException();
}
@Override
public boolean isAbstractType() {
return id != -1;
}
static { static {
TYPES = EntityTypeUtil.toOrderedArray(values()); TYPES = EntityTypeUtil.toOrderedArray(values());
} }

Datei anzeigen

@ -22,234 +22,262 @@
*/ */
package com.viaversion.viaversion.api.minecraft.entities; package com.viaversion.viaversion.api.minecraft.entities;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.util.EntityTypeUtil; import com.viaversion.viaversion.util.EntityTypeUtil;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.Locale;
public enum Entity1_19Types implements EntityType { public enum Entity1_19Types implements EntityType {
ENTITY(-1), ENTITY(null, null),
AREA_EFFECT_CLOUD(1, ENTITY), AREA_EFFECT_CLOUD(ENTITY),
END_CRYSTAL(21, ENTITY), END_CRYSTAL(ENTITY),
EVOKER_FANGS(26, ENTITY), EVOKER_FANGS(ENTITY),
EXPERIENCE_ORB(27, ENTITY), EXPERIENCE_ORB(ENTITY),
EYE_OF_ENDER(28, ENTITY), EYE_OF_ENDER(ENTITY),
FALLING_BLOCK(29, ENTITY), FALLING_BLOCK(ENTITY),
FIREWORK_ROCKET(30, ENTITY), FIREWORK_ROCKET(ENTITY),
ITEM(44, ENTITY), ITEM(ENTITY),
LLAMA_SPIT(50, ENTITY), LLAMA_SPIT(ENTITY),
TNT(72, ENTITY), TNT(ENTITY),
SHULKER_BULLET(79, ENTITY), SHULKER_BULLET(ENTITY),
FISHING_BOBBER(117, ENTITY), FISHING_BOBBER(ENTITY),
LIVINGENTITY(-1, ENTITY), LIVINGENTITY(ENTITY, null),
ARMOR_STAND(2, LIVINGENTITY), ARMOR_STAND(LIVINGENTITY),
MARKER(52, ENTITY), MARKER(ENTITY),
PLAYER(116, LIVINGENTITY), PLAYER(LIVINGENTITY),
ABSTRACT_INSENTIENT(-1, LIVINGENTITY), ABSTRACT_INSENTIENT(LIVINGENTITY, null),
ENDER_DRAGON(22, ABSTRACT_INSENTIENT), ENDER_DRAGON(ABSTRACT_INSENTIENT),
BEE(6, ABSTRACT_INSENTIENT), BEE(ABSTRACT_INSENTIENT),
ABSTRACT_CREATURE(-1, ABSTRACT_INSENTIENT), ABSTRACT_CREATURE(ABSTRACT_INSENTIENT, null),
ABSTRACT_AGEABLE(-1, ABSTRACT_CREATURE), ABSTRACT_AGEABLE(ABSTRACT_CREATURE, null),
VILLAGER(102, ABSTRACT_AGEABLE), VILLAGER(ABSTRACT_AGEABLE),
WANDERING_TRADER(104, ABSTRACT_AGEABLE), WANDERING_TRADER(ABSTRACT_AGEABLE),
// Animals // Animals
ABSTRACT_ANIMAL(-1, ABSTRACT_AGEABLE), ABSTRACT_ANIMAL(ABSTRACT_AGEABLE, null),
AXOLOTL(4, ABSTRACT_ANIMAL), AXOLOTL(ABSTRACT_ANIMAL),
DOLPHIN(16, ABSTRACT_INSENTIENT), DOLPHIN(ABSTRACT_INSENTIENT),
CHICKEN(12, ABSTRACT_ANIMAL), CHICKEN(ABSTRACT_ANIMAL),
COW(14, ABSTRACT_ANIMAL), COW(ABSTRACT_ANIMAL),
MOOSHROOM(61, COW), MOOSHROOM(COW),
PANDA(64, ABSTRACT_INSENTIENT), PANDA(ABSTRACT_INSENTIENT),
PIG(67, ABSTRACT_ANIMAL), PIG(ABSTRACT_ANIMAL),
POLAR_BEAR(71, ABSTRACT_ANIMAL), POLAR_BEAR(ABSTRACT_ANIMAL),
RABBIT(74, ABSTRACT_ANIMAL), RABBIT(ABSTRACT_ANIMAL),
SHEEP(77, ABSTRACT_ANIMAL), SHEEP(ABSTRACT_ANIMAL),
TURTLE(100, ABSTRACT_ANIMAL), TURTLE(ABSTRACT_ANIMAL),
FOX(31, ABSTRACT_ANIMAL), FOX(ABSTRACT_ANIMAL),
FROG(32, ABSTRACT_ANIMAL), FROG(ABSTRACT_ANIMAL),
GOAT(37, ABSTRACT_ANIMAL), GOAT(ABSTRACT_ANIMAL),
ABSTRACT_TAMEABLE_ANIMAL(-1, ABSTRACT_ANIMAL), ABSTRACT_TAMEABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(10, ABSTRACT_TAMEABLE_ANIMAL), CAT(ABSTRACT_TAMEABLE_ANIMAL),
OCELOT(62, ABSTRACT_TAMEABLE_ANIMAL), OCELOT(ABSTRACT_TAMEABLE_ANIMAL),
WOLF(110, ABSTRACT_TAMEABLE_ANIMAL), WOLF(ABSTRACT_TAMEABLE_ANIMAL),
ABSTRACT_PARROT(-1, ABSTRACT_TAMEABLE_ANIMAL), ABSTRACT_PARROT(ABSTRACT_TAMEABLE_ANIMAL, null),
PARROT(65, ABSTRACT_PARROT), PARROT(ABSTRACT_PARROT),
// Horses // Horses
ABSTRACT_HORSE(-1, ABSTRACT_ANIMAL), ABSTRACT_HORSE(ABSTRACT_ANIMAL, null),
CHESTED_HORSE(-1, ABSTRACT_HORSE), CHESTED_HORSE(ABSTRACT_HORSE, null),
DONKEY(17, CHESTED_HORSE), DONKEY(CHESTED_HORSE),
MULE(60, CHESTED_HORSE), MULE(CHESTED_HORSE),
LLAMA(49, CHESTED_HORSE), LLAMA(CHESTED_HORSE),
TRADER_LLAMA(98, CHESTED_HORSE), TRADER_LLAMA(CHESTED_HORSE),
HORSE(40, ABSTRACT_HORSE), HORSE(ABSTRACT_HORSE),
SKELETON_HORSE(82, ABSTRACT_HORSE), SKELETON_HORSE(ABSTRACT_HORSE),
ZOMBIE_HORSE(113, ABSTRACT_HORSE), ZOMBIE_HORSE(ABSTRACT_HORSE),
// Golem // Golem
ABSTRACT_GOLEM(-1, ABSTRACT_CREATURE), ABSTRACT_GOLEM(ABSTRACT_CREATURE, null),
SNOW_GOLEM(85, ABSTRACT_GOLEM), SNOW_GOLEM(ABSTRACT_GOLEM),
IRON_GOLEM(43, ABSTRACT_GOLEM), IRON_GOLEM(ABSTRACT_GOLEM),
SHULKER(78, ABSTRACT_GOLEM), SHULKER(ABSTRACT_GOLEM),
// Fish // Fish
ABSTRACT_FISHES(-1, ABSTRACT_CREATURE), ABSTRACT_FISHES(ABSTRACT_CREATURE, null),
COD(13, ABSTRACT_FISHES), COD(ABSTRACT_FISHES),
PUFFERFISH(73, ABSTRACT_FISHES), PUFFERFISH(ABSTRACT_FISHES),
SALMON(76, ABSTRACT_FISHES), SALMON(ABSTRACT_FISHES),
TROPICAL_FISH(99, ABSTRACT_FISHES), TROPICAL_FISH(ABSTRACT_FISHES),
// Monsters // Monsters
ABSTRACT_MONSTER(-1, ABSTRACT_CREATURE), ABSTRACT_MONSTER(ABSTRACT_CREATURE, null),
BLAZE(7, ABSTRACT_MONSTER), BLAZE(ABSTRACT_MONSTER),
CREEPER(15, ABSTRACT_MONSTER), CREEPER(ABSTRACT_MONSTER),
ENDERMITE(24, ABSTRACT_MONSTER), ENDERMITE(ABSTRACT_MONSTER),
ENDERMAN(23, ABSTRACT_MONSTER), ENDERMAN(ABSTRACT_MONSTER),
GIANT(34, ABSTRACT_MONSTER), GIANT(ABSTRACT_MONSTER),
SILVERFISH(80, ABSTRACT_MONSTER), SILVERFISH(ABSTRACT_MONSTER),
VEX(101, ABSTRACT_MONSTER), VEX(ABSTRACT_MONSTER),
WITCH(106, ABSTRACT_MONSTER), WITCH(ABSTRACT_MONSTER),
WITHER(107, ABSTRACT_MONSTER), WITHER(ABSTRACT_MONSTER),
RAVAGER(75, ABSTRACT_MONSTER), RAVAGER(ABSTRACT_MONSTER),
ABSTRACT_PIGLIN(-1, ABSTRACT_MONSTER), ABSTRACT_PIGLIN(ABSTRACT_MONSTER, null),
PIGLIN(68, ABSTRACT_PIGLIN), PIGLIN(ABSTRACT_PIGLIN),
PIGLIN_BRUTE(69, ABSTRACT_PIGLIN), PIGLIN_BRUTE(ABSTRACT_PIGLIN),
HOGLIN(39, ABSTRACT_ANIMAL), HOGLIN(ABSTRACT_ANIMAL),
STRIDER(91, ABSTRACT_ANIMAL), STRIDER(ABSTRACT_ANIMAL),
TADPOLE(91, ABSTRACT_FISHES), TADPOLE(ABSTRACT_FISHES),
ZOGLIN(111, ABSTRACT_MONSTER), ZOGLIN(ABSTRACT_MONSTER),
WARDEN(105, ABSTRACT_MONSTER), WARDEN(ABSTRACT_MONSTER),
// Illagers // Illagers
ABSTRACT_ILLAGER_BASE(-1, ABSTRACT_MONSTER), ABSTRACT_ILLAGER_BASE(ABSTRACT_MONSTER, null),
ABSTRACT_EVO_ILLU_ILLAGER(-1, ABSTRACT_ILLAGER_BASE), ABSTRACT_EVO_ILLU_ILLAGER(ABSTRACT_ILLAGER_BASE, null),
EVOKER(25, ABSTRACT_EVO_ILLU_ILLAGER), EVOKER(ABSTRACT_EVO_ILLU_ILLAGER),
ILLUSIONER(42, ABSTRACT_EVO_ILLU_ILLAGER), ILLUSIONER(ABSTRACT_EVO_ILLU_ILLAGER),
VINDICATOR(103, ABSTRACT_ILLAGER_BASE), VINDICATOR(ABSTRACT_ILLAGER_BASE),
PILLAGER(70, ABSTRACT_ILLAGER_BASE), PILLAGER(ABSTRACT_ILLAGER_BASE),
// Skeletons // Skeletons
ABSTRACT_SKELETON(-1, ABSTRACT_MONSTER), ABSTRACT_SKELETON(ABSTRACT_MONSTER, null),
SKELETON(81, ABSTRACT_SKELETON), SKELETON(ABSTRACT_SKELETON),
STRAY(90, ABSTRACT_SKELETON), STRAY(ABSTRACT_SKELETON),
WITHER_SKELETON(108, ABSTRACT_SKELETON), WITHER_SKELETON(ABSTRACT_SKELETON),
// Guardians // Guardians
GUARDIAN(38, ABSTRACT_MONSTER), GUARDIAN(ABSTRACT_MONSTER),
ELDER_GUARDIAN(20, GUARDIAN), ELDER_GUARDIAN(GUARDIAN),
// Spiders // Spiders
SPIDER(88, ABSTRACT_MONSTER), SPIDER(ABSTRACT_MONSTER),
CAVE_SPIDER(11, SPIDER), CAVE_SPIDER(SPIDER),
// Zombies // Zombies
ZOMBIE(112, ABSTRACT_MONSTER), ZOMBIE(ABSTRACT_MONSTER),
DROWNED(19, ZOMBIE), DROWNED(ZOMBIE),
HUSK(41, ZOMBIE), HUSK(ZOMBIE),
ZOMBIFIED_PIGLIN(115, ZOMBIE), ZOMBIFIED_PIGLIN(ZOMBIE),
ZOMBIE_VILLAGER(114, ZOMBIE), ZOMBIE_VILLAGER(ZOMBIE),
// Flying entities // Flying entities
ABSTRACT_FLYING(-1, ABSTRACT_INSENTIENT), ABSTRACT_FLYING(ABSTRACT_INSENTIENT, null),
GHAST(33, ABSTRACT_FLYING), GHAST(ABSTRACT_FLYING),
PHANTOM(66, ABSTRACT_FLYING), PHANTOM(ABSTRACT_FLYING),
ABSTRACT_AMBIENT(-1, ABSTRACT_INSENTIENT), ABSTRACT_AMBIENT(ABSTRACT_INSENTIENT, null),
BAT(5, ABSTRACT_AMBIENT), BAT(ABSTRACT_AMBIENT),
ALLAY(0, ABSTRACT_CREATURE), ALLAY(ABSTRACT_CREATURE),
ABSTRACT_WATERMOB(-1, ABSTRACT_INSENTIENT), ABSTRACT_WATERMOB(ABSTRACT_INSENTIENT, null),
SQUID(89, ABSTRACT_WATERMOB), SQUID(ABSTRACT_WATERMOB),
GLOW_SQUID(36, SQUID), GLOW_SQUID(SQUID),
// Slimes // Slimes
SLIME(83, ABSTRACT_INSENTIENT), SLIME(ABSTRACT_INSENTIENT),
MAGMA_CUBE(51, SLIME), MAGMA_CUBE(SLIME),
// Hangable objects // Hangable objects
ABSTRACT_HANGING(-1, ENTITY), ABSTRACT_HANGING(ENTITY, null),
LEASH_KNOT(47, ABSTRACT_HANGING), LEASH_KNOT(ABSTRACT_HANGING),
ITEM_FRAME(45, ABSTRACT_HANGING), ITEM_FRAME(ABSTRACT_HANGING),
GLOW_ITEM_FRAME(35, ITEM_FRAME), GLOW_ITEM_FRAME(ITEM_FRAME),
PAINTING(63, ABSTRACT_HANGING), PAINTING(ABSTRACT_HANGING),
ABSTRACT_LIGHTNING(-1, ENTITY), ABSTRACT_LIGHTNING(ENTITY, null),
LIGHTNING_BOLT(48, ABSTRACT_LIGHTNING), LIGHTNING_BOLT(ABSTRACT_LIGHTNING),
// Arrows // Arrows
ABSTRACT_ARROW(-1, ENTITY), ABSTRACT_ARROW(ENTITY, null),
ARROW(3, ABSTRACT_ARROW), ARROW(ABSTRACT_ARROW),
SPECTRAL_ARROW(87, ABSTRACT_ARROW), SPECTRAL_ARROW(ABSTRACT_ARROW),
TRIDENT(97, ABSTRACT_ARROW), TRIDENT(ABSTRACT_ARROW),
// Fireballs // Fireballs
ABSTRACT_FIREBALL(-1, ENTITY), ABSTRACT_FIREBALL(ENTITY, null),
DRAGON_FIREBALL(18, ABSTRACT_FIREBALL), DRAGON_FIREBALL(ABSTRACT_FIREBALL),
FIREBALL(46, ABSTRACT_FIREBALL), FIREBALL(ABSTRACT_FIREBALL),
SMALL_FIREBALL(84, ABSTRACT_FIREBALL), SMALL_FIREBALL(ABSTRACT_FIREBALL),
WITHER_SKULL(109, ABSTRACT_FIREBALL), WITHER_SKULL(ABSTRACT_FIREBALL),
// Projectiles // Projectiles
PROJECTILE_ABSTRACT(-1, ENTITY), PROJECTILE_ABSTRACT(ENTITY, null),
SNOWBALL(86, PROJECTILE_ABSTRACT), SNOWBALL(PROJECTILE_ABSTRACT),
ENDER_PEARL(94, PROJECTILE_ABSTRACT), ENDER_PEARL(PROJECTILE_ABSTRACT),
EGG(93, PROJECTILE_ABSTRACT), EGG(PROJECTILE_ABSTRACT),
POTION(96, PROJECTILE_ABSTRACT), POTION(PROJECTILE_ABSTRACT),
EXPERIENCE_BOTTLE(95, PROJECTILE_ABSTRACT), EXPERIENCE_BOTTLE(PROJECTILE_ABSTRACT),
// Vehicles // Vehicles
MINECART_ABSTRACT(-1, ENTITY), MINECART_ABSTRACT(ENTITY, null),
CHESTED_MINECART_ABSTRACT(-1, MINECART_ABSTRACT), CHESTED_MINECART_ABSTRACT(MINECART_ABSTRACT, null),
CHEST_MINECART(54, CHESTED_MINECART_ABSTRACT), CHEST_MINECART(CHESTED_MINECART_ABSTRACT),
HOPPER_MINECART(57, CHESTED_MINECART_ABSTRACT), HOPPER_MINECART(CHESTED_MINECART_ABSTRACT),
MINECART(53, MINECART_ABSTRACT), MINECART(MINECART_ABSTRACT),
FURNACE_MINECART(56, MINECART_ABSTRACT), FURNACE_MINECART(MINECART_ABSTRACT),
COMMAND_BLOCK_MINECART(55, MINECART_ABSTRACT), COMMAND_BLOCK_MINECART(MINECART_ABSTRACT),
TNT_MINECART(59, MINECART_ABSTRACT), TNT_MINECART(MINECART_ABSTRACT),
SPAWNER_MINECART(58, MINECART_ABSTRACT), SPAWNER_MINECART(MINECART_ABSTRACT),
BOAT(8, ENTITY), BOAT(ENTITY),
CHEST_BOAT(9, BOAT); CHEST_BOAT(BOAT);
private static final EntityType[] TYPES; private static final EntityType[] TYPES = EntityTypeUtil.createSizedArray(values());
private final int id;
private final EntityType parent; private final EntityType parent;
private final String identifier;
private int id;
Entity1_19Types(int id) { Entity1_19Types(final EntityType parent) {
this.id = id; this.parent = parent;
this.parent = null; this.identifier = "minecraft:" + name().toLowerCase(Locale.ROOT);
} }
Entity1_19Types(int id, EntityType parent) { Entity1_19Types(final EntityType parent, @Nullable final String identifier) {
this.id = id;
this.parent = parent; this.parent = parent;
this.identifier = identifier;
} }
@Override @Override
public int getId() { public int getId() {
if (id == -1) {
throw new IllegalStateException("Ids have not been initialized yet");
}
return id; return id;
} }
@Override @Override
public EntityType getParent() { public String identifier() {
Preconditions.checkArgument(identifier != null, "Called identifier method on abstract type");
return identifier;
}
@Override
public @Nullable EntityType getParent() {
return parent; return parent;
} }
static { @Override
TYPES = EntityTypeUtil.toOrderedArray(values()); public boolean isAbstractType() {
return identifier == null;
} }
public static EntityType getTypeFromId(int typeId) { public static EntityType getTypeFromId(final int typeId) {
return EntityTypeUtil.getTypeFromId(TYPES, typeId, ENTITY); return EntityTypeUtil.getTypeFromId(TYPES, typeId, ENTITY);
} }
public static void initialize(final Protocol<?, ?, ?, ?> protocol) {
for (final Entity1_19Types type : values()) {
if (type.isAbstractType()) {
continue;
}
final int id = protocol.getMappingData().getEntityMappings().mappedId(type.identifier());
Preconditions.checkArgument(id != -1, "Entity type %s has no id", type.identifier());
type.id = id;
}
EntityTypeUtil.fill(values(), TYPES);
}
} }

Datei anzeigen

@ -30,6 +30,7 @@ public interface EntityType {
* Returns the entity id. * Returns the entity id.
* *
* @return entity id * @return entity id
* @throws IllegalStateException if ids have not been loaded yet
*/ */
int getId(); int getId();
@ -47,6 +48,22 @@ public interface EntityType {
*/ */
String name(); String name();
/**
* Returns the entity's Vanilla identifier.
*
* @return entity identifier
* @throws IllegalArgumentException if {@link #isAbstractType()} returns true
*/
String identifier();
/**
* Returns whether the type does not represent an actual entity, e.g. animal or monster.
*
* @return whether the type does not represent an actual entity
*/
boolean isAbstractType();
@Deprecated/*(forRemoval = true)*/
default boolean is(EntityType... types) { default boolean is(EntityType... types) {
for (EntityType type : types) { for (EntityType type : types) {
if (this == type) { if (this == type) {

Datei anzeigen

@ -49,6 +49,9 @@ public abstract class RewriterBase<T extends Protocol> implements Rewriter<T> {
protected void registerRewrites() { protected void registerRewrites() {
} }
public void onMappingDataLoaded() {
}
@Override @Override
public T protocol() { public T protocol() {
return protocol; return protocol;

Datei anzeigen

@ -37,9 +37,9 @@ public class EntityTypeUtil {
* @param values entity types * @param values entity types
* @return ordered array with each index representing the actual entity id * @return ordered array with each index representing the actual entity id
*/ */
public static EntityType[] toOrderedArray(EntityType[] values) { public static EntityType[] toOrderedArray(final EntityType[] values) {
List<EntityType> types = new ArrayList<>(); final List<EntityType> types = new ArrayList<>();
for (EntityType type : values) { for (final EntityType type : values) {
if (type.getId() != -1) { if (type.getId() != -1) {
types.add(type); types.add(type);
} }
@ -49,6 +49,24 @@ public class EntityTypeUtil {
return types.toArray(new EntityType[0]); return types.toArray(new EntityType[0]);
} }
public static EntityType[] createSizedArray(final EntityType[] values) {
int count = 0;
for (final EntityType type : values) {
if (!type.isAbstractType()) {
count++;
}
}
return new EntityType[(int) count];
}
public static void fill(final EntityType[] values, final EntityType[] toFill) {
for (final EntityType type : values) {
if (!type.isAbstractType()) {
toFill[type.getId()] = type;
}
}
}
/** /**
* Returns the entity type from id, or the given fallback if out of bounds. * Returns the entity type from id, or the given fallback if out of bounds.
* *
@ -57,8 +75,8 @@ public class EntityTypeUtil {
* @param fallback fallback/base entity type * @param fallback fallback/base entity type
* @return entity type from id * @return entity type from id
*/ */
public static EntityType getTypeFromId(EntityType[] values, int typeId, EntityType fallback) { public static EntityType getTypeFromId(final EntityType[] values, final int typeId, final EntityType fallback) {
EntityType type; final EntityType type;
if (typeId < 0 || typeId >= values.length || (type = values[typeId]) == null) { if (typeId < 0 || typeId >= values.length || (type = values[typeId]) == null) {
Via.getPlatform().getLogger().severe("Could not find " + fallback.getClass().getSimpleName() + " type id " + typeId); Via.getPlatform().getLogger().severe("Could not find " + fallback.getClass().getSimpleName() + " type id " + typeId);
return fallback; return fallback;

Datei anzeigen

@ -69,7 +69,7 @@ public class MetadataRewriter1_11To1_10 extends EntityRewriter<Protocol1_11To1_1
} }
if (type.isOrHasParent(EntityType.ZOMBIE)) { // Zombie | Zombie Villager | Husk if (type.isOrHasParent(EntityType.ZOMBIE)) { // Zombie | Zombie Villager | Husk
if (type.is(EntityType.ZOMBIE, EntityType.HUSK) && metadata.id() == 14) { if ((type == EntityType.ZOMBIE || type == EntityType.HUSK) && metadata.id() == 14) {
metadatas.remove(metadata); metadatas.remove(metadata);
} else { } else {
if (metadata.id() == 15) { if (metadata.id() == 15) {
@ -104,7 +104,7 @@ public class MetadataRewriter1_11To1_10 extends EntityRewriter<Protocol1_11To1_1
metadatas.remove(metadata); metadatas.remove(metadata);
} }
} }
if (type.is(EntityType.DONKEY, EntityType.MULE)) { if (type == EntityType.DONKEY || type == EntityType.MULE) {
// Chested Horse // Chested Horse
if (metadata.id() == 13) { if (metadata.id() == 13) {
if ((((byte) metadata.getValue()) & 0x08) == 0x08) { if ((((byte) metadata.getValue()) & 0x08) == 0x08) {

Datei anzeigen

@ -279,6 +279,8 @@ public final class Protocol1_19To1_18_2 extends AbstractProtocol<ClientboundPack
.reader("vibration", ParticleType.Readers.VIBRATION) .reader("vibration", ParticleType.Readers.VIBRATION)
.reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE) .reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
.reader("shriek", ParticleType.Readers.SHRIEK); .reader("shriek", ParticleType.Readers.SHRIEK);
Entity1_19Types.initialize(this);
entityRewriter.onMappingDataLoaded();
} }
@Override @Override

Datei anzeigen

@ -119,7 +119,6 @@ public final class EntityPackets extends EntityRewriter<Protocol1_19To1_18_2> {
public EntityPackets(final Protocol1_19To1_18_2 protocol) { public EntityPackets(final Protocol1_19To1_18_2 protocol) {
super(protocol); super(protocol);
mapTypes(Entity1_17Types.values(), Entity1_19Types.class);
} }
@Override @Override
@ -354,6 +353,11 @@ public final class EntityPackets extends EntityRewriter<Protocol1_19To1_18_2> {
filter().type(Entity1_19Types.CAT).index(19).handler((event, meta) -> meta.setMetaType(Types1_19.META_TYPES.catVariantType)); filter().type(Entity1_19Types.CAT).index(19).handler((event, meta) -> meta.setMetaType(Types1_19.META_TYPES.catVariantType));
} }
@Override
public void onMappingDataLoaded() {
mapTypes();
}
@Override @Override
public EntityType typeFromId(final int type) { public EntityType typeFromId(final int type) {
return Entity1_19Types.getTypeFromId(type); return Entity1_19Types.getTypeFromId(type);

Datei anzeigen

@ -24,6 +24,8 @@ import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.Int2IntMapMappings;
import com.viaversion.viaversion.api.data.Mappings;
import com.viaversion.viaversion.api.data.ParticleMappings; import com.viaversion.viaversion.api.data.ParticleMappings;
import com.viaversion.viaversion.api.data.entity.DimensionData; import com.viaversion.viaversion.api.data.entity.DimensionData;
import com.viaversion.viaversion.api.data.entity.EntityTracker; import com.viaversion.viaversion.api.data.entity.EntityTracker;
@ -41,8 +43,6 @@ import com.viaversion.viaversion.api.type.types.Particle;
import com.viaversion.viaversion.rewriter.meta.MetaFilter; import com.viaversion.viaversion.rewriter.meta.MetaFilter;
import com.viaversion.viaversion.rewriter.meta.MetaHandlerEvent; import com.viaversion.viaversion.rewriter.meta.MetaHandlerEvent;
import com.viaversion.viaversion.rewriter.meta.MetaHandlerEventImpl; import com.viaversion.viaversion.rewriter.meta.MetaHandlerEventImpl;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
@ -55,7 +55,7 @@ public abstract class EntityRewriter<T extends Protocol> extends RewriterBase<T>
private static final Metadata[] EMPTY_ARRAY = new Metadata[0]; private static final Metadata[] EMPTY_ARRAY = new Metadata[0];
protected final List<MetaFilter> metadataFilters = new ArrayList<>(); protected final List<MetaFilter> metadataFilters = new ArrayList<>();
protected final boolean trackMappedType; protected final boolean trackMappedType;
protected Int2IntMap typeMappings; protected Mappings typeMappings;
protected EntityRewriter(T protocol) { protected EntityRewriter(T protocol) {
this(protocol, true); this(protocol, true);
@ -167,7 +167,7 @@ public abstract class EntityRewriter<T extends Protocol> extends RewriterBase<T>
@Override @Override
public int newEntityId(int id) { public int newEntityId(int id) {
return typeMappings != null ? typeMappings.getOrDefault(id, id) : id; return typeMappings != null ? typeMappings.getNewIdOrDefault(id, id) : id;
} }
/** /**
@ -184,10 +184,9 @@ public abstract class EntityRewriter<T extends Protocol> extends RewriterBase<T>
protected void mapEntityType(int id, int mappedId) { protected void mapEntityType(int id, int mappedId) {
if (typeMappings == null) { if (typeMappings == null) {
typeMappings = new Int2IntOpenHashMap(); typeMappings = Int2IntMapMappings.of();
typeMappings.defaultReturnValue(-1);
} }
typeMappings.put(id, mappedId); typeMappings.setNewId(id, mappedId);
} }
/** /**
@ -199,15 +198,14 @@ public abstract class EntityRewriter<T extends Protocol> extends RewriterBase<T>
*/ */
public <E extends Enum<E> & EntityType> void mapTypes(EntityType[] oldTypes, Class<E> newTypeClass) { public <E extends Enum<E> & EntityType> void mapTypes(EntityType[] oldTypes, Class<E> newTypeClass) {
if (typeMappings == null) { if (typeMappings == null) {
typeMappings = new Int2IntOpenHashMap(oldTypes.length, .99F); typeMappings = Int2IntMapMappings.of();
typeMappings.defaultReturnValue(-1);
} }
for (EntityType oldType : oldTypes) { for (EntityType oldType : oldTypes) {
try { try {
E newType = Enum.valueOf(newTypeClass, oldType.name()); E newType = Enum.valueOf(newTypeClass, oldType.name());
typeMappings.put(oldType.getId(), newType.getId()); typeMappings.setNewId(oldType.getId(), newType.getId());
} catch (IllegalArgumentException notFound) { } catch (IllegalArgumentException notFound) {
if (!typeMappings.containsKey(oldType.getId())) { if (!typeMappings.contains(oldType.getId())) {
Via.getPlatform().getLogger().warning("Could not find new entity type for " + oldType + "! " + Via.getPlatform().getLogger().warning("Could not find new entity type for " + oldType + "! " +
"Old type: " + oldType.getClass().getEnclosingClass().getSimpleName() + ", new type: " + newTypeClass.getEnclosingClass().getSimpleName()); "Old type: " + oldType.getClass().getEnclosingClass().getSimpleName() + ", new type: " + newTypeClass.getEnclosingClass().getSimpleName());
} }
@ -215,6 +213,15 @@ public abstract class EntityRewriter<T extends Protocol> extends RewriterBase<T>
} }
} }
/**
* Maps entity ids based on the protocol's mapping data.
*/
public void mapTypes() {
Preconditions.checkArgument(typeMappings == null, "Type mappings have already been set - manual type mappings should be set *after* this");
Preconditions.checkNotNull(protocol.getMappingData().getEntityMappings(), "Protocol does not have entity mappings");
typeMappings = protocol.getMappingData().getEntityMappings().mappings();
}
/** /**
* Registers a metadata handler to rewrite, item, block, and particle ids stored in metadata. * Registers a metadata handler to rewrite, item, block, and particle ids stored in metadata.
* *

Datei anzeigen

@ -23765,6 +23765,121 @@
"minecraft:mending", "minecraft:mending",
"minecraft:vanishing_curse" "minecraft:vanishing_curse"
], ],
"entities": [
"minecraft:area_effect_cloud",
"minecraft:armor_stand",
"minecraft:arrow",
"minecraft:axolotl",
"minecraft:bat",
"minecraft:bee",
"minecraft:blaze",
"minecraft:boat",
"minecraft:cat",
"minecraft:cave_spider",
"minecraft:chicken",
"minecraft:cod",
"minecraft:cow",
"minecraft:creeper",
"minecraft:dolphin",
"minecraft:donkey",
"minecraft:dragon_fireball",
"minecraft:drowned",
"minecraft:elder_guardian",
"minecraft:end_crystal",
"minecraft:ender_dragon",
"minecraft:enderman",
"minecraft:endermite",
"minecraft:evoker",
"minecraft:evoker_fangs",
"minecraft:experience_orb",
"minecraft:eye_of_ender",
"minecraft:falling_block",
"minecraft:firework_rocket",
"minecraft:fox",
"minecraft:ghast",
"minecraft:giant",
"minecraft:glow_item_frame",
"minecraft:glow_squid",
"minecraft:goat",
"minecraft:guardian",
"minecraft:hoglin",
"minecraft:horse",
"minecraft:husk",
"minecraft:illusioner",
"minecraft:iron_golem",
"minecraft:item",
"minecraft:item_frame",
"minecraft:fireball",
"minecraft:leash_knot",
"minecraft:lightning_bolt",
"minecraft:llama",
"minecraft:llama_spit",
"minecraft:magma_cube",
"minecraft:marker",
"minecraft:minecart",
"minecraft:chest_minecart",
"minecraft:command_block_minecart",
"minecraft:furnace_minecart",
"minecraft:hopper_minecart",
"minecraft:spawner_minecart",
"minecraft:tnt_minecart",
"minecraft:mule",
"minecraft:mooshroom",
"minecraft:ocelot",
"minecraft:painting",
"minecraft:panda",
"minecraft:parrot",
"minecraft:phantom",
"minecraft:pig",
"minecraft:piglin",
"minecraft:piglin_brute",
"minecraft:pillager",
"minecraft:polar_bear",
"minecraft:tnt",
"minecraft:pufferfish",
"minecraft:rabbit",
"minecraft:ravager",
"minecraft:salmon",
"minecraft:sheep",
"minecraft:shulker",
"minecraft:shulker_bullet",
"minecraft:silverfish",
"minecraft:skeleton",
"minecraft:skeleton_horse",
"minecraft:slime",
"minecraft:small_fireball",
"minecraft:snow_golem",
"minecraft:snowball",
"minecraft:spectral_arrow",
"minecraft:spider",
"minecraft:squid",
"minecraft:stray",
"minecraft:strider",
"minecraft:egg",
"minecraft:ender_pearl",
"minecraft:experience_bottle",
"minecraft:potion",
"minecraft:trident",
"minecraft:trader_llama",
"minecraft:tropical_fish",
"minecraft:turtle",
"minecraft:vex",
"minecraft:villager",
"minecraft:vindicator",
"minecraft:wandering_trader",
"minecraft:witch",
"minecraft:wither",
"minecraft:wither_skeleton",
"minecraft:wither_skull",
"minecraft:wolf",
"minecraft:zoglin",
"minecraft:zombie",
"minecraft:zombie_horse",
"minecraft:zombie_villager",
"minecraft:zombified_piglin",
"minecraft:player",
"minecraft:fishing_bobber"
],
"paintings": [ "paintings": [
"minecraft:kebab", "minecraft:kebab",
"minecraft:aztec", "minecraft:aztec",