Change the way how EntityTrackers work to work correctly with multiple versions (WIP)

This commit is contained in:
Matsv 2016-11-19 15:51:38 +01:00
parent 0549cb5c3a
commit 6cf94fce66
No known key found for this signature in database
GPG Key ID: 97CEC2A2EA31350F
12 changed files with 815 additions and 103 deletions

View File

@ -34,7 +34,7 @@
<dependency>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-api</artifactId>
<version>1.10-SNAPSHOT</version>
<version>1.11-SNAPSHOT</version>
<scope>provided</scope>
</dependency>

View File

@ -10,9 +10,10 @@
package nl.matsv.viabackwards.api;
import nl.matsv.viabackwards.api.entities.AbstractEntityType;
import nl.matsv.viabackwards.api.exceptions.RemovedValueException;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
public interface MetaRewriter {
Metadata handleMetadata(boolean isObject, int entityType, Metadata data) throws RemovedValueException;
Metadata handleMetadata(AbstractEntityType type, Metadata data) throws RemovedValueException;
}

View File

@ -8,16 +8,22 @@
* 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 nl.matsv.viabackwards.api.storage;
package nl.matsv.viabackwards.api.entities;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
public interface AbstractEntityType {
/**
* Get the metadata id
*
* @return the metadata index
*/
int getId();
/**
* Get the parent class of the entity
*
* @return parent EntityType
*/
AbstractEntityType getParent();
@Data
@AllArgsConstructor
@EqualsAndHashCode
public class EntityType {
private boolean object;
private short entityType;
}

View File

@ -0,0 +1,197 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.api.entities;
import com.google.common.base.Optional;
import lombok.AllArgsConstructor;
import lombok.Getter;
import nl.matsv.viabackwards.ViaBackwards;
// 1.10 Entity / Object ids
public class EntityType1_10 {
public static EntityType getTypeFromId(int typeID, boolean isObject) {
Optional<EntityType> type;
if (isObject)
type = ObjectType.getPCEntity(typeID);
else
type = EntityType.findById(typeID);
if (!type.isPresent()) {
ViaBackwards.getPlatform().getLogger().severe("Could not find type id " + typeID + " isObject=" + isObject);
return EntityType.ENTITY; // Fall back to the basic ENTITY
}
return type.get();
}
@AllArgsConstructor
@Getter
public enum EntityType implements AbstractEntityType {
ENTITY(-1),
DROPPED_ITEM(1, EntityType.ENTITY),
EXPERIENCE_ORB(2, EntityType.ENTITY),
LEASH_HITCH(8, EntityType.ENTITY), // Actually entity hanging but it doesn't make a lot of difference for metadata
PAINTING(9, EntityType.ENTITY), // Actually entity hanging but it doesn't make a lot of difference for metadata
ARROW(10, EntityType.ENTITY),
SNOWBALL(11, EntityType.ENTITY), // Actually EntityProjectile
FIREBALL(12, EntityType.ENTITY),
SMALL_FIREBALL(13, EntityType.ENTITY),
ENDER_PEARL(14, EntityType.ENTITY), // Actually EntityProjectile
ENDER_SIGNAL(15, EntityType.ENTITY),
THROWN_EXP_BOTTLE(17, EntityType.ENTITY),
ITEM_FRAME(18, EntityType.ENTITY), // Actually EntityHanging
WITHER_SKULL(19, EntityType.ENTITY),
PRIMED_TNT(20, EntityType.ENTITY),
FALLING_BLOCK(21, EntityType.ENTITY),
FIREWORK(22, EntityType.ENTITY),
TIPPED_ARROW(23, EntityType.ARROW),
SPECTRAL_ARROW(24, EntityType.ARROW),
SHULKER_BULLET(25, EntityType.ENTITY),
DRAGON_FIREBALL(26, EntityType.FIREBALL),
ENTITY_LIVING(-1, ENTITY),
ENTITY_INSENTIENT(-1, ENTITY_LIVING),
ENTITY_AGEABLE(-1, ENTITY_INSENTIENT),
ENTITY_TAMEABLE_ANIMAL(-1, ENTITY_AGEABLE),
ENTITY_HUMAN(-1, ENTITY_LIVING),
ARMOR_STAND(30, EntityType.ENTITY_LIVING),
// Vehicles
MINECART_ABSTRACT(-1, ENTITY),
MINECART_COMMAND(40, MINECART_ABSTRACT),
BOAT(41, ENTITY),
MINECART_RIDEABLE(42, MINECART_ABSTRACT),
MINECART_CHEST(43, MINECART_ABSTRACT),
MINECART_FURNACE(44, MINECART_ABSTRACT),
MINECART_TNT(45, MINECART_ABSTRACT),
MINECART_HOPPER(46, MINECART_ABSTRACT),
MINECART_MOB_SPAWNER(47, MINECART_ABSTRACT),
CREEPER(50, ENTITY_INSENTIENT),
SKELETON(51, ENTITY_INSENTIENT),
SPIDER(52, ENTITY_INSENTIENT),
GIANT(53, ENTITY_INSENTIENT),
ZOMBIE(54, ENTITY_INSENTIENT),
SLIME(55, ENTITY_INSENTIENT),
GHAST(56, ENTITY_INSENTIENT),
PIG_ZOMBIE(57, ZOMBIE),
ENDERMAN(58, ENTITY_INSENTIENT),
CAVE_SPIDER(59, SPIDER),
SILVERFISH(60, ENTITY_INSENTIENT),
BLAZE(61, ENTITY_INSENTIENT),
MAGMA_CUBE(62, SLIME),
ENDER_DRAGON(63, ENTITY_INSENTIENT),
WITHER(64, ENTITY_INSENTIENT),
BAT(65, ENTITY_INSENTIENT),
WITCH(66, ENTITY_INSENTIENT),
ENDERMITE(67, ENTITY_INSENTIENT),
GUARDIAN(68, ENTITY_INSENTIENT),
IRON_GOLEM(99, ENTITY_INSENTIENT), // moved up to avoid illegal forward references
SHULKER(69, EntityType.IRON_GOLEM),
PIG(90, ENTITY_AGEABLE),
SHEEP(91, ENTITY_AGEABLE),
COW(92, ENTITY_AGEABLE),
CHICKEN(93, ENTITY_AGEABLE),
SQUID(94, ENTITY_INSENTIENT),
WOLF(95, ENTITY_TAMEABLE_ANIMAL),
MUSHROOM_COW(96, COW),
SNOWMAN(97, EntityType.IRON_GOLEM),
OCELOT(98, ENTITY_TAMEABLE_ANIMAL),
HORSE(100, ENTITY_AGEABLE),
RABBIT(101, ENTITY_AGEABLE),
POLAR_BEAR(102, ENTITY_AGEABLE),
VILLAGER(120, ENTITY_AGEABLE),
ENDER_CRYSTAL(200, ENTITY),
SPLASH_POTION(-1, ENTITY),
LINGERING_POTION(-1, SPLASH_POTION),
AREA_EFFECT_CLOUD(-1, ENTITY),
EGG(-1, ENTITY),
FISHING_HOOK(-1, ENTITY),
LIGHTNING(-1, ENTITY),
WEATHER(-1, ENTITY),
PLAYER(-1, ENTITY_HUMAN),
COMPLEX_PART(-1, ENTITY);
private final int id;
private final EntityType parent;
EntityType(int id) {
this.id = id;
this.parent = null;
}
public static Optional<EntityType> findById(int id) {
if (id == -1) // Check if this is called
return Optional.absent();
for (EntityType ent : EntityType.values())
if (ent.getId() == id)
return Optional.of(ent);
return Optional.absent();
}
}
@AllArgsConstructor
@Getter
public enum ObjectType {
BOAT(1, EntityType.BOAT),
ITEM(2, EntityType.DROPPED_ITEM),
AREA_EFFECT_CLOUD(3, EntityType.AREA_EFFECT_CLOUD),
MINECART(10, EntityType.MINECART_ABSTRACT),
TNT_PRIMED(50, EntityType.PRIMED_TNT),
ENDER_CRYSTAL(51, EntityType.ENDER_CRYSTAL),
TIPPED_ARROW(60, EntityType.TIPPED_ARROW),
SNOWBALL(61, EntityType.SNOWBALL),
EGG(62, EntityType.EGG),
FIREBALL(63, EntityType.FIREBALL),
SMALL_FIREBALL(64, EntityType.SMALL_FIREBALL),
ENDER_PEARL(65, EntityType.ENDER_PEARL),
WITHER_SKULL(66, EntityType.WITHER_SKULL),
SHULKER_BULLET(67, EntityType.SHULKER_BULLET),
FALLING_BLOCK(70, EntityType.FALLING_BLOCK),
ITEM_FRAME(71, EntityType.ITEM_FRAME),
ENDER_SIGNAL(72, EntityType.ENDER_SIGNAL),
POTION(73, EntityType.SPLASH_POTION),
THROWN_EXP_BOTTLE(75, EntityType.THROWN_EXP_BOTTLE),
FIREWORK(76, EntityType.FIREWORK),
LEASH(77, EntityType.LEASH_HITCH),
ARMOR_STAND(78, EntityType.ARMOR_STAND),
FISHIHNG_HOOK(90, EntityType.FISHING_HOOK),
SPECTRAL_ARROW(91, EntityType.SPECTRAL_ARROW),
DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL);
private final int id;
private final EntityType type;
public static Optional<ObjectType> findById(int id) {
if (id == -1)
return Optional.absent();
for (ObjectType ent : ObjectType.values())
if (ent.getId() == id)
return Optional.of(ent);
return Optional.absent();
}
public static Optional<EntityType> getPCEntity(int id) {
Optional<ObjectType> output = findById(id);
if (!output.isPresent())
return Optional.absent();
return Optional.of(output.get().getType());
}
}
}

View File

@ -0,0 +1,251 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.api.entities;
import com.google.common.base.Optional;
import lombok.AllArgsConstructor;
import lombok.Getter;
import nl.matsv.viabackwards.ViaBackwards;
public class EntityType1_11 {
public static EntityType getTypeFromId(int typeID, boolean isObject) {
Optional<EntityType> type;
if (isObject)
type = ObjectType.getPCEntity(typeID);
else
type = EntityType.findById(typeID);
if (!type.isPresent()) {
ViaBackwards.getPlatform().getLogger().severe("Could not find type id " + typeID + " isObject=" + isObject);
return EntityType.ENTITY; // Fall back to the basic ENTITY
}
return type.get();
}
@AllArgsConstructor
@Getter
public enum EntityType implements AbstractEntityType {
ENTITY(-1),
DROPPED_ITEM(1, ENTITY),
EXPERIENCE_ORB(2, ENTITY),
LEASH_HITCH(8, ENTITY), // Actually entity hanging but it doesn't make a lot of difference for metadata
PAINTING(9, ENTITY), // Actually entity hanging but it doesn't make a lot of difference for metadata
ARROW(10, ENTITY),
SNOWBALL(11, ENTITY), // Actually EntityProjectile
FIREBALL(12, ENTITY),
SMALL_FIREBALL(13, ENTITY),
ENDER_PEARL(14, ENTITY), // Actually EntityProjectile
ENDER_SIGNAL(15, ENTITY),
THROWN_EXP_BOTTLE(17, ENTITY),
ITEM_FRAME(18, ENTITY), // Actually EntityHanging
WITHER_SKULL(19, ENTITY),
PRIMED_TNT(20, ENTITY),
FALLING_BLOCK(21, ENTITY),
FIREWORK(22, ENTITY),
TIPPED_ARROW(23, ARROW),
SPECTRAL_ARROW(24, ARROW),
SHULKER_BULLET(25, ENTITY),
DRAGON_FIREBALL(26, FIREBALL),
EVOCATION_FANGS(33, ENTITY),
ENTITY_LIVING(-1, ENTITY),
ENTITY_INSENTIENT(-1, ENTITY_LIVING),
ENTITY_AGEABLE(-1, ENTITY_INSENTIENT),
ENTITY_TAMEABLE_ANIMAL(-1, ENTITY_AGEABLE),
ENTITY_HUMAN(-1, ENTITY_LIVING),
ARMOR_STAND(30, ENTITY_LIVING),
EVOCATION_ILLAGER(34, ENTITY_INSENTIENT),
VEX(35, ENTITY_INSENTIENT),
VINDICATION_ILLAGER(36, ENTITY_INSENTIENT),
// Vehicles
MINECART_ABSTRACT(-1, ENTITY),
MINECART_COMMAND(40, MINECART_ABSTRACT),
BOAT(41, ENTITY),
MINECART_RIDEABLE(42, MINECART_ABSTRACT),
MINECART_CHEST(43, MINECART_ABSTRACT),
MINECART_FURNACE(44, MINECART_ABSTRACT),
MINECART_TNT(45, MINECART_ABSTRACT),
MINECART_HOPPER(46, MINECART_ABSTRACT),
MINECART_MOB_SPAWNER(47, MINECART_ABSTRACT),
CREEPER(50, ENTITY_INSENTIENT),
ABSTRACT_SKELETON(-1, ENTITY_INSENTIENT),
SKELETON(51, ABSTRACT_SKELETON),
WITHER_SKELETON(5, ABSTRACT_SKELETON),
STRAY(6, ABSTRACT_SKELETON),
SPIDER(52, ENTITY_INSENTIENT),
GIANT(53, ENTITY_INSENTIENT),
ZOMBIE(54, ENTITY_INSENTIENT),
HUSK(23, ZOMBIE),
ZOMBIE_VILLAGER(27, ZOMBIE),
SLIME(55, ENTITY_INSENTIENT),
GHAST(56, ENTITY_INSENTIENT),
PIG_ZOMBIE(57, ZOMBIE),
ENDERMAN(58, ENTITY_INSENTIENT),
CAVE_SPIDER(59, SPIDER),
SILVERFISH(60, ENTITY_INSENTIENT),
BLAZE(61, ENTITY_INSENTIENT),
MAGMA_CUBE(62, SLIME),
ENDER_DRAGON(63, ENTITY_INSENTIENT),
WITHER(64, ENTITY_INSENTIENT),
BAT(65, ENTITY_INSENTIENT),
WITCH(66, ENTITY_INSENTIENT),
ENDERMITE(67, ENTITY_INSENTIENT),
GUARDIAN(68, ENTITY_INSENTIENT),
ELDER_GUARDIAN(4, EntityType.GUARDIAN), // Moved down to avoid illegal forward reference
IRON_GOLEM(99, ENTITY_INSENTIENT), // moved up to avoid illegal forward references
SHULKER(69, EntityType.IRON_GOLEM),
PIG(90, ENTITY_AGEABLE),
SHEEP(91, ENTITY_AGEABLE),
COW(92, ENTITY_AGEABLE),
CHICKEN(93, ENTITY_AGEABLE),
SQUID(94, ENTITY_INSENTIENT),
WOLF(95, ENTITY_TAMEABLE_ANIMAL),
MUSHROOM_COW(96, COW),
SNOWMAN(97, EntityType.IRON_GOLEM),
OCELOT(98, ENTITY_TAMEABLE_ANIMAL),
ABSTRACT_HORSE(-1, ENTITY_AGEABLE),
HORSE(100, ABSTRACT_HORSE),
SKELETON_HORSE(28, ABSTRACT_HORSE),
ZOMBIE_HORSE(29, ABSTRACT_HORSE),
CHESTED_HORSE(-1, ABSTRACT_HORSE),
DONKEY(31, CHESTED_HORSE),
MULE(32, CHESTED_HORSE),
LIAMA(103, CHESTED_HORSE),
RABBIT(101, ENTITY_AGEABLE),
POLAR_BEAR(102, ENTITY_AGEABLE),
VILLAGER(120, ENTITY_AGEABLE),
ENDER_CRYSTAL(200, ENTITY),
SPLASH_POTION(-1, ENTITY),
LINGERING_POTION(-1, SPLASH_POTION),
AREA_EFFECT_CLOUD(-1, ENTITY),
EGG(-1, ENTITY),
FISHING_HOOK(-1, ENTITY),
LIGHTNING(-1, ENTITY),
WEATHER(-1, ENTITY),
PLAYER(-1, ENTITY_HUMAN),
COMPLEX_PART(-1, ENTITY),
LIAMA_SPIT(-1, ENTITY);
private final int id;
private final EntityType parent;
EntityType(int id) {
this.id = id;
this.parent = null;
}
public static Optional<EntityType> findById(int id) {
if (id == -1) // Check if this is called
return Optional.absent();
for (EntityType ent : EntityType.values())
if (ent.getId() == id)
return Optional.of(ent);
return Optional.absent();
}
public boolean is(EntityType... types) {
for (EntityType type : types)
if (is(type))
return true;
return false;
}
public boolean is(EntityType type) {
return this == type;
}
public boolean isOrHasParent(EntityType type) {
EntityType parent = this;
do {
if (parent.equals(type))
return true;
parent = parent.getParent();
} while (parent != null);
return false;
}
}
@AllArgsConstructor
@Getter
public enum ObjectType {
BOAT(1, EntityType.BOAT),
ITEM(2, EntityType.DROPPED_ITEM),
AREA_EFFECT_CLOUD(3, EntityType.AREA_EFFECT_CLOUD),
MINECART(10, EntityType.MINECART_ABSTRACT),
TNT_PRIMED(50, EntityType.PRIMED_TNT),
ENDER_CRYSTAL(51, EntityType.ENDER_CRYSTAL),
TIPPED_ARROW(60, EntityType.TIPPED_ARROW),
SNOWBALL(61, EntityType.SNOWBALL),
EGG(62, EntityType.EGG),
FIREBALL(63, EntityType.FIREBALL),
SMALL_FIREBALL(64, EntityType.SMALL_FIREBALL),
ENDER_PEARL(65, EntityType.ENDER_PEARL),
WITHER_SKULL(66, EntityType.WITHER_SKULL),
SHULKER_BULLET(67, EntityType.SHULKER_BULLET),
LIAMA_SPIT(68, EntityType.LIAMA_SPIT),
FALLING_BLOCK(70, EntityType.FALLING_BLOCK),
ITEM_FRAME(71, EntityType.ITEM_FRAME),
ENDER_SIGNAL(72, EntityType.ENDER_SIGNAL),
POTION(73, EntityType.SPLASH_POTION),
THROWN_EXP_BOTTLE(75, EntityType.THROWN_EXP_BOTTLE),
FIREWORK(76, EntityType.FIREWORK),
LEASH(77, EntityType.LEASH_HITCH),
ARMOR_STAND(78, EntityType.ARMOR_STAND),
EVOCATION_FANGS(39, EntityType.EVOCATION_FANGS),
FISHIHNG_HOOK(90, EntityType.FISHING_HOOK),
SPECTRAL_ARROW(91, EntityType.SPECTRAL_ARROW),
DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL);
private final int id;
private final EntityType type;
public static Optional<ObjectType> findById(int id) {
if (id == -1)
return Optional.absent();
for (ObjectType ent : ObjectType.values())
if (ent.getId() == id)
return Optional.of(ent);
return Optional.absent();
}
public static Optional<EntityType> getPCEntity(int id) {
Optional<ObjectType> output = findById(id);
if (!output.isPresent())
return Optional.absent();
return Optional.of(output.get().getType());
}
}
}

View File

@ -14,9 +14,9 @@ import lombok.RequiredArgsConstructor;
import nl.matsv.viabackwards.ViaBackwards;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import nl.matsv.viabackwards.api.MetaRewriter;
import nl.matsv.viabackwards.api.entities.AbstractEntityType;
import nl.matsv.viabackwards.api.exceptions.RemovedValueException;
import nl.matsv.viabackwards.api.storage.EntityTracker;
import nl.matsv.viabackwards.api.storage.EntityType;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
@ -30,63 +30,39 @@ import java.util.logging.Logger;
@RequiredArgsConstructor
public abstract class EntityRewriter<T extends BackwardsProtocol> extends Rewriter<T> {
private final Map<Short, Short> entityTypes = new ConcurrentHashMap<>();
private final Map<Short, Short> objectTypes = new ConcurrentHashMap<>();
private final Map<AbstractEntityType, Short> entityTypes = new ConcurrentHashMap<>();
private final List<MetaRewriter> metaRewriters = new ArrayList<>();
protected short getNewEntityType(UserConnection connection, int id) {
EntityType type = getEntityType(connection, id);
if (type.isObject()) {
return getNewObjectId(type.getEntityType());
} else {
return getNewEntityId(type.getEntityType());
}
protected AbstractEntityType getEntityType(UserConnection connection, int id) {
return getEntityTracker(connection).getEntityType(id);
}
protected EntityType getEntityType(UserConnection connection, int id) {
return connection.get(EntityTracker.class).getEntityType(id);
protected void addTrackedEntity(UserConnection connection, int entityId, AbstractEntityType type) {
getEntityTracker(connection).trackEntityType(entityId, type);
}
protected void addTrackedEntity(UserConnection connection, int entityId, boolean isObject, short typeId) {
connection.get(EntityTracker.class).trackEntityType(entityId, new EntityType(isObject, typeId));
protected void rewriteEntityType(AbstractEntityType type, int newId) {
entityTypes.put(type, (short) newId);
}
protected void rewriteEntityId(int oldId, int newId) {
entityTypes.put((short) oldId, (short) newId);
protected boolean isRewriteEntityType(AbstractEntityType type) {
return entityTypes.containsKey(type);
}
protected boolean isRewriteEntityId(short id) {
return entityTypes.containsKey(id);
}
protected short getNewEntityId(short oldId) {
if (!isRewriteEntityId(oldId))
return oldId;
return entityTypes.get(oldId);
}
protected void rewriteObjectId(int oldId, int newId) {
objectTypes.put((short) oldId, (short) newId);
}
protected boolean isRewriteObjectId(short id) {
return objectTypes.containsKey(id);
}
protected short getNewObjectId(short oldId) {
if (!isRewriteObjectId(oldId))
return oldId;
return objectTypes.get(oldId);
protected short getNewEntityType(AbstractEntityType type) {
if (!isRewriteEntityType(type))
return -1;
return entityTypes.get(type);
}
public void registerMetaRewriter(MetaRewriter rewriter) {
metaRewriters.add(rewriter);
}
protected List<Metadata> handleMeta(UserConnection userConnection, int entityId, List<Metadata> metaData) {
EntityTracker tracker = userConnection.get(EntityTracker.class);
EntityType type = tracker.getEntityType(entityId);
protected List<Metadata> handleMeta(UserConnection user, int entityId, List<Metadata> metaData) {
EntityTracker tracker = user.get(EntityTracker.class);
AbstractEntityType type = tracker.get(getProtocol()).getEntityType(entityId);
List<Metadata> newMeta = new CopyOnWriteArrayList<>();
for (Metadata md : metaData) {
@ -94,9 +70,9 @@ public abstract class EntityRewriter<T extends BackwardsProtocol> extends Rewrit
try {
for (MetaRewriter rewriter : metaRewriters) {
if (type != null)
nmd = rewriter.handleMetadata(type.isObject(), type.getEntityType(), nmd);
nmd = rewriter.handleMetadata(type, nmd);
else
nmd = rewriter.handleMetadata(false, -1, nmd);
throw new Exception("Panic, entitytype is null");
if (nmd == null)
throw new RemovedValueException();
}
@ -114,4 +90,8 @@ public abstract class EntityRewriter<T extends BackwardsProtocol> extends Rewrit
return newMeta;
}
protected EntityTracker.ProtocolEntityTracker getEntityTracker(UserConnection user) {
return user.get(EntityTracker.class).get(getProtocol());
}
}

View File

@ -10,6 +10,8 @@
package nl.matsv.viabackwards.api.storage;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import nl.matsv.viabackwards.api.entities.AbstractEntityType;
import us.myles.ViaVersion.api.data.StoredObject;
import us.myles.ViaVersion.api.data.UserConnection;
@ -17,27 +19,39 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class EntityTracker extends StoredObject {
private Map<Integer, EntityType> entityMap = new ConcurrentHashMap<>();
private Map<BackwardsProtocol, ProtocolEntityTracker> trackers = new ConcurrentHashMap<>();
public EntityTracker(UserConnection user) {
super(user);
}
public void trackEntityType(int id, EntityType type) {
if (entityMap.containsKey(id))
return;
entityMap.put(id, type);
public void initProtocol(BackwardsProtocol protocol) {
trackers.put(protocol, new ProtocolEntityTracker());
}
public void removeEntity(int id) {
entityMap.remove(id);
public ProtocolEntityTracker get(BackwardsProtocol protocol) {
return trackers.get(protocol);
}
public EntityType getEntityType(int id) {
return entityMap.get(id);
}
public class ProtocolEntityTracker {
private Map<Integer, AbstractEntityType> entityMap = new ConcurrentHashMap<>();
public boolean containsEntity(int id) {
return entityMap.containsKey(id);
public void trackEntityType(int id, AbstractEntityType type) {
if (entityMap.containsKey(id))
return;
entityMap.put(id, type);
}
public void removeEntity(int id) {
entityMap.remove(id);
}
public AbstractEntityType getEntityType(int id) {
return entityMap.get(id);
}
public boolean containsEntity(int id) {
return entityMap.containsKey(id);
}
}
}

View File

@ -11,10 +11,12 @@
package nl.matsv.viabackwards.protocol.protocol1_10to1_11;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import nl.matsv.viabackwards.api.storage.EntityTracker;
import nl.matsv.viabackwards.protocol.protocol1_10to1_11.packets.BlockItemPackets;
import nl.matsv.viabackwards.protocol.protocol1_10to1_11.packets.EntityPackets;
import nl.matsv.viabackwards.protocol.protocol1_10to1_11.packets.PlayerPackets;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
public class Protocol1_10To1_11 extends BackwardsProtocol {
@Override
@ -25,7 +27,16 @@ public class Protocol1_10To1_11 extends BackwardsProtocol {
}
@Override
public void init(UserConnection userConnection) {
public void init(UserConnection user) {
// Register ClientWorld
if (!user.has(ClientWorld.class))
user.put(new ClientWorld(user));
// Register EntityTracker if it doesn't exist yet.
if (!user.has(EntityTracker.class))
user.put(new EntityTracker(user));
// Init protocol in EntityTracker
user.get(EntityTracker.class).initProtocol(this);
}
}

View File

@ -10,6 +10,7 @@
package nl.matsv.viabackwards.protocol.protocol1_10to1_11.packets;
import nl.matsv.viabackwards.api.entities.AbstractEntityType;
import nl.matsv.viabackwards.api.rewriters.EntityRewriter;
import nl.matsv.viabackwards.protocol.protocol1_10to1_11.Protocol1_10To1_11;
import us.myles.ViaVersion.api.PacketWrapper;
@ -18,17 +19,83 @@ import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.version.Types1_9;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import static nl.matsv.viabackwards.api.entities.EntityType1_11.*;
public class EntityPackets extends EntityRewriter<Protocol1_10To1_11> {
@Override
protected void registerPackets(Protocol1_10To1_11 protocol) {
// Spawn Mob packet
protocol.registerOutgoing(State.PLAY, 0x03, 0x03, new PacketRemapper() {
// Spawn Object
protocol.registerOutgoing(State.PLAY, 0x00, 0x00, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity id
map(Type.UUID); // 1 - UUID
map(Type.BYTE); // 2 - Type
// Track Entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
getTypeFromId(wrapper.get(Type.BYTE, 0), true)
);
}
});
}
});
// Spawn Experience Orb
protocol.registerOutgoing(State.PLAY, 0x01, 0x01, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity id
// Track entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
ObjectType.THROWN_EXP_BOTTLE.getType()
);
}
});
}
});
// Spawn Global Entity
protocol.registerOutgoing(State.PLAY, 0x02, 0x02, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Type.UUID); // 1 - Entity UUID
map(Type.BYTE); // 1 - Type
// Track entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
EntityType.WEATHER // Always thunder according to wiki.vg
);
}
});
}
});
// Spawn Mob
protocol.registerOutgoing(State.PLAY, 0x03, 0x03, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity id
map(Type.UUID); // 1 - UUID
map(Type.VAR_INT, Type.UNSIGNED_BYTE); // 2 - Entity Type
map(Type.DOUBLE); // 3 - X
map(Type.DOUBLE); // 4 - Y
@ -41,22 +108,205 @@ public class EntityPackets extends EntityRewriter<Protocol1_10To1_11> {
map(Type.SHORT); // 11 - Velocity Z
map(Types1_9.METADATA_LIST); // 12 - Metadata
// Track entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
// TODO
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
getTypeFromId(wrapper.get(Type.UNSIGNED_BYTE, 0), false)
);
}
});
// Rewrite entity ids
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityId = wrapper.get(Type.VAR_INT, 0);
AbstractEntityType type = getEntityType(wrapper.user(), entityId);
short newType = getNewEntityType(type);
// Keep doing what you are doing
if (newType == -1)
return;
wrapper.set(Type.UNSIGNED_BYTE, 0, newType);
}
});
// Rewrite metadata
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.set(
Types1_9.METADATA_LIST,
0,
handleMeta(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
wrapper.get(Types1_9.METADATA_LIST, 0)
)
);
}
});
}
});
// Spawn Painting
protocol.registerOutgoing(State.PLAY, 0x04, 0x04, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
// Track entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
EntityType.PAINTING
);
}
});
}
});
// Join game
protocol.registerOutgoing(State.PLAY, 0x23, 0x23, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Entity ID
map(Type.UNSIGNED_BYTE); // 1 - Gamemode
map(Type.INT); // 2 - Dimension
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.INT, 0),
EntityType.PLAYER
);
}
});
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
int dimensionId = wrapper.get(Type.INT, 1);
clientWorld.setEnvironment(dimensionId);
}
});
}
});
// Respawn Packet (save dimension id)
protocol.registerOutgoing(State.PLAY, 0x33, 0x33, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Dimension ID
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
int dimensionId = wrapper.get(Type.INT, 0);
clientWorld.setEnvironment(dimensionId);
}
});
}
});
// Spawn Player
protocol.registerOutgoing(State.PLAY, 0x05, 0x05, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Type.UUID); // 1 - Player UUID
map(Type.DOUBLE); // 2 - X
map(Type.DOUBLE); // 3 - Y
map(Type.DOUBLE); // 4 - Z
map(Type.BYTE); // 5 - Yaw
map(Type.BYTE); // 6 - Pitch
map(Types1_9.METADATA_LIST); // 7 - Metadata list
// Track Entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
EntityType.PLAYER
);
}
});
// Rewrite Metadata
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.set(
Types1_9.METADATA_LIST,
0,
handleMeta(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
wrapper.get(Types1_9.METADATA_LIST, 0)
)
);
}
});
}
});
// Destroy entities
protocol.registerOutgoing(State.PLAY, 0x30, 0x30, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT_ARRAY); // 0 - Entity IDS
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
for (int entity : wrapper.get(Type.VAR_INT_ARRAY, 0))
getEntityTracker(wrapper.user()).removeEntity(entity);
}
});
}
});
// Metadata packet
protocol.registerOutgoing(State.PLAY, 0x39, 0x39, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Types1_9.METADATA_LIST); // 1 - Metadata list
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.set(
Types1_9.METADATA_LIST,
0,
handleMeta(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
wrapper.get(Types1_9.METADATA_LIST, 0)
)
);
}
});
}
});
}
@Override
protected void registerRewrites() {
}
}

View File

@ -39,5 +39,8 @@ public class Protocol1_9_4To1_10 extends BackwardsProtocol {
// Register EntityTracker if it doesn't exist yet.
if (!user.has(EntityTracker.class))
user.put(new EntityTracker(user));
// Init protocol in EntityTracker
user.get(EntityTracker.class).initProtocol(this);
}
}

View File

@ -236,7 +236,7 @@ public class BlockItemPackets extends BlockItemRewriter<Protocol1_9_4To1_10> {
);
/* Register Metadata */
protocol.getEntityPackets().registerMetaRewriter((isObject, entityType, data) -> {
protocol.getEntityPackets().registerMetaRewriter((type, data) -> {
if (data.getMetaType().equals(MetaType1_9.Slot)) // Is Item
data.setValue(handleItemToClient((Item) data.getValue()));

View File

@ -10,9 +10,10 @@
package nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.packets;
import nl.matsv.viabackwards.api.entities.AbstractEntityType;
import nl.matsv.viabackwards.api.entities.EntityType1_10;
import nl.matsv.viabackwards.api.exceptions.RemovedValueException;
import nl.matsv.viabackwards.api.rewriters.EntityRewriter;
import nl.matsv.viabackwards.api.storage.EntityTracker;
import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.Protocol1_9_4To1_10;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_9;
@ -23,6 +24,8 @@ import us.myles.ViaVersion.api.type.types.version.Types1_9;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import static nl.matsv.viabackwards.api.entities.EntityType1_10.EntityType;
public class EntityPackets extends EntityRewriter<Protocol1_9_4To1_10> {
@Override
@ -43,8 +46,7 @@ public class EntityPackets extends EntityRewriter<Protocol1_9_4To1_10> {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
true,
wrapper.get(Type.BYTE, 0)
EntityType1_10.getTypeFromId(wrapper.get(Type.BYTE, 0), true)
);
}
});
@ -64,8 +66,7 @@ public class EntityPackets extends EntityRewriter<Protocol1_9_4To1_10> {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
true,
(short) 2
EntityType1_10.ObjectType.THROWN_EXP_BOTTLE.getType()
);
}
});
@ -86,8 +87,7 @@ public class EntityPackets extends EntityRewriter<Protocol1_9_4To1_10> {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
true,
wrapper.get(Type.BYTE, 0)
EntityType.WEATHER // Always thunder according to wiki.vg
);
}
});
@ -119,8 +119,7 @@ public class EntityPackets extends EntityRewriter<Protocol1_9_4To1_10> {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
false,
wrapper.get(Type.UNSIGNED_BYTE, 0)
EntityType1_10.getTypeFromId(wrapper.get(Type.UNSIGNED_BYTE, 0), false)
);
}
});
@ -129,13 +128,16 @@ public class EntityPackets extends EntityRewriter<Protocol1_9_4To1_10> {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.set(Type.UNSIGNED_BYTE, 0,
getNewEntityType(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0)
));
int entityId = wrapper.get(Type.VAR_INT, 0);
AbstractEntityType type = getEntityType(wrapper.user(), entityId);
short newType = getNewEntityType(type);
// Keep doing what you are doing
if (newType == -1)
return;
wrapper.set(Type.UNSIGNED_BYTE, 0, newType);
}
});
@ -170,8 +172,7 @@ public class EntityPackets extends EntityRewriter<Protocol1_9_4To1_10> {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
true,
(short) 9
EntityType.PAINTING
);
}
});
@ -192,8 +193,7 @@ public class EntityPackets extends EntityRewriter<Protocol1_9_4To1_10> {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.INT, 0),
false,
(short) -12
EntityType.PLAYER
);
}
});
@ -245,8 +245,7 @@ public class EntityPackets extends EntityRewriter<Protocol1_9_4To1_10> {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
false,
(short) -12
EntityType.PLAYER
);
}
});
@ -279,7 +278,7 @@ public class EntityPackets extends EntityRewriter<Protocol1_9_4To1_10> {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
for (int entity : wrapper.get(Type.VAR_INT_ARRAY, 0))
wrapper.user().get(EntityTracker.class).removeEntity(entity);
getEntityTracker(wrapper.user()).removeEntity(entity);
}
});
}
@ -312,11 +311,11 @@ public class EntityPackets extends EntityRewriter<Protocol1_9_4To1_10> {
@Override
protected void registerRewrites() {
rewriteEntityId(102, 91); // Replace polar bear with sheep
rewriteEntityType(EntityType.POLAR_BEAR, 91); // Replace polar bear with sheep
// Handle Polar bear
registerMetaRewriter((isObject, entityType, data) -> { // Change the sheep color when the polar bear is stending up
if (!isObject && entityType != 102)
registerMetaRewriter((entityType, data) -> { // Change the sheep color when the polar bear is standing up
if (!entityType.equals(EntityType.POLAR_BEAR))
return data;
if (data.getId() == 13) { // is boolean
@ -330,8 +329,8 @@ public class EntityPackets extends EntityRewriter<Protocol1_9_4To1_10> {
});
// Handle Husk
registerMetaRewriter((isObject, entityType, data) -> { // Change husk to normal zombie
if (isObject || entityType != 54)
registerMetaRewriter((entityType, data) -> { // Change husk to normal zombie
if (!entityType.equals(EntityType.ZOMBIE))
return data;
if (data.getId() == 13 && data.getMetaType().getTypeID() == 1 && (int) data.getValue() == 6)
@ -340,8 +339,8 @@ public class EntityPackets extends EntityRewriter<Protocol1_9_4To1_10> {
});
// Handle stray
registerMetaRewriter((isObject, entityType, data) -> { // Change stray- to normal skeleton
if (isObject || entityType != 51)
registerMetaRewriter((entityType, data) -> { // Change stray- to normal skeleton
if (!entityType.equals(EntityType.SKELETON))
return data;
if (data.getId() == 12 && data.getMetaType().getTypeID() == 1 && (int) data.getValue() == 2)
@ -350,7 +349,7 @@ public class EntityPackets extends EntityRewriter<Protocol1_9_4To1_10> {
});
// Handle the missing NoGravity tag
registerMetaRewriter((isObject, entityType, m) -> {
registerMetaRewriter((type, m) -> {
if (m.getId() == 5)
throw new RemovedValueException();
else if (m.getId() >= 5)