Use mappings instead of hardcoding entity ids

This commit is contained in:
Nassim Jahnke 2022-04-01 16:54:07 +02:00
parent f0462085d3
commit 1d5ae0e3e0
No known key found for this signature in database
GPG Key ID: 6BE3B555EBC5982B
27 changed files with 575 additions and 190 deletions

View File

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

View File

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

View File

@ -26,14 +26,14 @@ import com.google.gson.JsonArray;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
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> mappedStringToId;
private final String[] idToString;
private final String[] mappedIdToString;
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;
stringToId = MappingDataLoader.arrayToMap(oldMappings);
mappedStringToId = MappingDataLoader.arrayToMap(newMappings);

View File

@ -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;
}
}

View File

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

View File

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

View File

@ -164,7 +164,7 @@ public class MappingDataLoader {
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());
if (value == -1) {
// Search in diff mappings

View File

@ -38,6 +38,28 @@ public interface Mappings {
*/
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.
*

View File

@ -26,7 +26,7 @@ import com.google.gson.JsonArray;
import it.unimi.dsi.fastutil.ints.IntArrayList;
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 blockParticleIds = new IntArrayList(4);

View File

@ -170,6 +170,16 @@ public class Entity1_10Types {
public EntityType getParent() {
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 {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -30,6 +30,7 @@ public interface EntityType {
* Returns the entity id.
*
* @return entity id
* @throws IllegalStateException if ids have not been loaded yet
*/
int getId();
@ -47,6 +48,22 @@ public interface EntityType {
*/
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) {
for (EntityType type : types) {
if (this == type) {

View File

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

View File

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

View File

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

View File

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

View File

@ -119,7 +119,6 @@ public final class EntityPackets extends EntityRewriter<Protocol1_19To1_18_2> {
public EntityPackets(final Protocol1_19To1_18_2 protocol) {
super(protocol);
mapTypes(Entity1_17Types.values(), Entity1_19Types.class);
}
@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));
}
@Override
public void onMappingDataLoaded() {
mapTypes();
}
@Override
public EntityType typeFromId(final int type) {
return Entity1_19Types.getTypeFromId(type);

View File

@ -24,6 +24,8 @@ import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.Via;
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.entity.DimensionData;
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.MetaHandlerEvent;
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 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];
protected final List<MetaFilter> metadataFilters = new ArrayList<>();
protected final boolean trackMappedType;
protected Int2IntMap typeMappings;
protected Mappings typeMappings;
protected EntityRewriter(T protocol) {
this(protocol, true);
@ -167,7 +167,7 @@ public abstract class EntityRewriter<T extends Protocol> extends RewriterBase<T>
@Override
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) {
if (typeMappings == null) {
typeMappings = new Int2IntOpenHashMap();
typeMappings.defaultReturnValue(-1);
typeMappings = Int2IntMapMappings.of();
}
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) {
if (typeMappings == null) {
typeMappings = new Int2IntOpenHashMap(oldTypes.length, .99F);
typeMappings.defaultReturnValue(-1);
typeMappings = Int2IntMapMappings.of();
}
for (EntityType oldType : oldTypes) {
try {
E newType = Enum.valueOf(newTypeClass, oldType.name());
typeMappings.put(oldType.getId(), newType.getId());
typeMappings.setNewId(oldType.getId(), newType.getId());
} 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 + "! " +
"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.
*

View File

@ -23765,6 +23765,121 @@
"minecraft:mending",
"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": [
"minecraft:kebab",
"minecraft:aztec",