From 51c502486e559c89bf0ae5c24dd0ffdddf4c45ee Mon Sep 17 00:00:00 2001 From: Matsv Date: Wed, 31 May 2017 00:03:42 +0200 Subject: [PATCH] Continue 1.11 update. --- README.md | 7 + .../nl/matsv/viabackwards/BukkitPlugin.java | 5 + .../nl/matsv/viabackwards/BungeePlugin.java | 5 + .../api/ViaBackwardsPlatform.java | 39 +- .../api/entities/AbstractEntityType.java | 9 + .../entities/AbstractObjectType.java} | 38 +- .../api/entities/EntityType1_10.java | 59 ++- .../api/entities/EntityType1_11.java | 50 ++- .../api/rewriters/BlockItemRewriter.java | 19 +- .../api/rewriters/EntityRewriter.java | 98 +++-- .../viabackwards/api/storage/EntityData.java | 40 ++ .../MetaHandler.java} | 7 +- .../viabackwards/api/v2/MetaHandlerEvent.java | 39 ++ .../api/v2/MetaHandlerSettings.java | 89 +++++ .../viabackwards/api/v2/MetaStorage.java | 63 ++++ .../Protocol1_10To1_11.java | 6 +- .../packets/BlockItemPackets.java | 36 +- .../packets/EntityPackets.java | 262 +++++++++++-- .../Protocol1_11To1_11_1.java | 40 ++ .../packets/EntityPackets.java | 354 ++++++++++++++++++ .../packets/ItemPackets.java | 156 ++++++++ .../chunks/Chunk1_10Type.java | 120 ------ .../chunks/ChunkSection1_10.java | 306 --------------- .../packets/BlockItemPackets.java | 36 +- .../packets/EntityPackets.java | 139 ++++--- pom.xml | 2 +- .../nl/matsv/viabackwards/SpongePlugin.java | 6 + 27 files changed, 1400 insertions(+), 630 deletions(-) rename core/src/main/java/nl/matsv/viabackwards/{protocol/protocol1_9_4to1_10/chunks/Chunk1_10.java => api/entities/AbstractObjectType.java} (62%) create mode 100644 core/src/main/java/nl/matsv/viabackwards/api/storage/EntityData.java rename core/src/main/java/nl/matsv/viabackwards/api/{MetaRewriter.java => v2/MetaHandler.java} (84%) create mode 100644 core/src/main/java/nl/matsv/viabackwards/api/v2/MetaHandlerEvent.java create mode 100644 core/src/main/java/nl/matsv/viabackwards/api/v2/MetaHandlerSettings.java create mode 100644 core/src/main/java/nl/matsv/viabackwards/api/v2/MetaStorage.java create mode 100644 core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_11to1_11_1/Protocol1_11To1_11_1.java create mode 100644 core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_11to1_11_1/packets/EntityPackets.java create mode 100644 core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_11to1_11_1/packets/ItemPackets.java delete mode 100644 core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_9_4to1_10/chunks/Chunk1_10Type.java delete mode 100644 core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_9_4to1_10/chunks/ChunkSection1_10.java diff --git a/README.md b/README.md index ffb2ce1b..a090bec7 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,10 @@ Allows 1.9.x on a 1.10 Spigot server Requires [ViaVersion](http://viaversion.com) to be installed **Spigot page:** https://www.spigotmc.org/resources/viabackwards.27448/ + + +TODO: + +- Entity names that changed? +- llama inventory slots +- Rewrite Shulker box name \ No newline at end of file diff --git a/bukkit/src/main/java/nl/matsv/viabackwards/BukkitPlugin.java b/bukkit/src/main/java/nl/matsv/viabackwards/BukkitPlugin.java index 88ba3f86..845ebb00 100644 --- a/bukkit/src/main/java/nl/matsv/viabackwards/BukkitPlugin.java +++ b/bukkit/src/main/java/nl/matsv/viabackwards/BukkitPlugin.java @@ -18,4 +18,9 @@ public class BukkitPlugin extends JavaPlugin implements ViaBackwardsPlatform { public void onEnable() { this.init(); } + + @Override + public void disable() { + getPluginLoader().disablePlugin(this); + } } diff --git a/bungee/src/main/java/nl/matsv/viabackwards/BungeePlugin.java b/bungee/src/main/java/nl/matsv/viabackwards/BungeePlugin.java index 82ea0595..53ce97f4 100644 --- a/bungee/src/main/java/nl/matsv/viabackwards/BungeePlugin.java +++ b/bungee/src/main/java/nl/matsv/viabackwards/BungeePlugin.java @@ -19,4 +19,9 @@ public class BungeePlugin extends Plugin implements ViaBackwardsPlatform { public void onEnable() { this.init(); } + + // Why is this not a thing in Bungee? O_o + @Override + public void disable() { + } } diff --git a/core/src/main/java/nl/matsv/viabackwards/api/ViaBackwardsPlatform.java b/core/src/main/java/nl/matsv/viabackwards/api/ViaBackwardsPlatform.java index dcf7e258..8fc4e02f 100644 --- a/core/src/main/java/nl/matsv/viabackwards/api/ViaBackwardsPlatform.java +++ b/core/src/main/java/nl/matsv/viabackwards/api/ViaBackwardsPlatform.java @@ -12,10 +12,13 @@ package nl.matsv.viabackwards.api; import nl.matsv.viabackwards.ViaBackwards; import nl.matsv.viabackwards.protocol.protocol1_10to1_11.Protocol1_10To1_11; +import nl.matsv.viabackwards.protocol.protocol1_11to1_11_1.Protocol1_11To1_11_1; import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.Protocol1_9_4To1_10; import us.myles.ViaVersion.api.protocol.ProtocolRegistry; import us.myles.ViaVersion.api.protocol.ProtocolVersion; +import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks.ChunkSection1_9_3_4; +import java.lang.reflect.Method; import java.util.Collections; import java.util.logging.Logger; @@ -25,8 +28,12 @@ public interface ViaBackwardsPlatform { */ default void init() { ViaBackwards.init(this); - ProtocolRegistry.registerProtocol(new Protocol1_9_4To1_10(), Collections.singletonList(ProtocolVersion.v1_9_3.getId()), ProtocolVersion.v1_10.getId()); - ProtocolRegistry.registerProtocol(new Protocol1_10To1_11(), Collections.singletonList(ProtocolVersion.v1_10.getId()), ProtocolVersion.v1_11.getId()); + + if (!isOutdated()) { + ProtocolRegistry.registerProtocol(new Protocol1_9_4To1_10(), Collections.singletonList(ProtocolVersion.v1_9_3.getId()), ProtocolVersion.v1_10.getId()); + ProtocolRegistry.registerProtocol(new Protocol1_10To1_11(), Collections.singletonList(ProtocolVersion.v1_10.getId()), ProtocolVersion.v1_11.getId()); + ProtocolRegistry.registerProtocol(new Protocol1_11To1_11_1(), Collections.singletonList(ProtocolVersion.v1_11.getId()), ProtocolVersion.v1_11_1.getId()); + } } /** @@ -35,4 +42,32 @@ public interface ViaBackwardsPlatform { * @return logger instance */ Logger getLogger(); + + // TODO remove or better implement on full release + default boolean isOutdated() { + Method m = null; + try { + m = ChunkSection1_9_3_4.class.getMethod("getBlock", int.class, int.class, int.class); + } catch (NoSuchMethodException ignored) { + } + + if (m == null) { + getLogger().severe("================================"); + getLogger().severe("YOUR VIAVERSION IS OUTDATED"); + getLogger().severe("PLEASE USE THE LATEST DEVBUILD"); + getLogger().severe("LINK: https://ci.viaversion.com/job/ViaVersion-DEV/"); + getLogger().severe("VIABACKWARDS WILL NOW DISABLE"); + getLogger().severe("================================"); + + disable(); + return true; + } + + return false; + } + + /** + * Disable the plugin + */ + void disable(); } diff --git a/core/src/main/java/nl/matsv/viabackwards/api/entities/AbstractEntityType.java b/core/src/main/java/nl/matsv/viabackwards/api/entities/AbstractEntityType.java index 07bb2d40..ada0f314 100644 --- a/core/src/main/java/nl/matsv/viabackwards/api/entities/AbstractEntityType.java +++ b/core/src/main/java/nl/matsv/viabackwards/api/entities/AbstractEntityType.java @@ -10,6 +10,8 @@ package nl.matsv.viabackwards.api.entities; +import java.util.List; + public interface AbstractEntityType { /** @@ -26,4 +28,11 @@ public interface AbstractEntityType { */ AbstractEntityType getParent(); + boolean is(AbstractEntityType... types); + + boolean is(AbstractEntityType type); + + boolean isOrHasParent(AbstractEntityType type); + + List getParents(); } diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_9_4to1_10/chunks/Chunk1_10.java b/core/src/main/java/nl/matsv/viabackwards/api/entities/AbstractObjectType.java similarity index 62% rename from core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_9_4to1_10/chunks/Chunk1_10.java rename to core/src/main/java/nl/matsv/viabackwards/api/entities/AbstractObjectType.java index f777dcfc..4f3866d6 100644 --- a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_9_4to1_10/chunks/Chunk1_10.java +++ b/core/src/main/java/nl/matsv/viabackwards/api/entities/AbstractObjectType.java @@ -8,28 +8,20 @@ * 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.protocol.protocol1_9_4to1_10.chunks; +package nl.matsv.viabackwards.api.entities; -import lombok.AllArgsConstructor; -import lombok.Data; -import us.myles.ViaVersion.api.minecraft.chunks.Chunk; -import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag; +public interface AbstractObjectType { + /** + * Get the metadata id + * + * @return the metadata index + */ + int getId(); -import java.util.List; - -@Data -@AllArgsConstructor -public class Chunk1_10 implements Chunk { - private int x; - private int z; - private boolean groundUp; - private int bitmask; - private ChunkSection1_10[] sections; - private byte[] biomeData; - private List blockEntities; - - @Override - public boolean isBiomeData() { - return biomeData != null; - } -} \ No newline at end of file + /** + * Get the entity type + * + * @return Entity type + */ + AbstractEntityType getType(); +} diff --git a/core/src/main/java/nl/matsv/viabackwards/api/entities/EntityType1_10.java b/core/src/main/java/nl/matsv/viabackwards/api/entities/EntityType1_10.java index 39c0599c..987c47b3 100644 --- a/core/src/main/java/nl/matsv/viabackwards/api/entities/EntityType1_10.java +++ b/core/src/main/java/nl/matsv/viabackwards/api/entities/EntityType1_10.java @@ -10,11 +10,14 @@ package nl.matsv.viabackwards.api.entities; -import com.google.common.base.Optional; import lombok.AllArgsConstructor; import lombok.Getter; import nl.matsv.viabackwards.ViaBackwards; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + // 1.10 Entity / Object ids public class EntityType1_10 { @@ -27,7 +30,7 @@ public class EntityType1_10 { type = EntityType.findById(typeID); if (!type.isPresent()) { - ViaBackwards.getPlatform().getLogger().severe("Could not find type id " + typeID + " isObject=" + isObject); + ViaBackwards.getPlatform().getLogger().severe("[EntityType1_10] Could not find type id " + typeID + " isObject=" + isObject); return EntityType.ENTITY; // Fall back to the basic ENTITY } @@ -133,19 +136,59 @@ public class EntityType1_10 { public static Optional findById(int id) { if (id == -1) // Check if this is called - return Optional.absent(); + return Optional.empty(); for (EntityType ent : EntityType.values()) if (ent.getId() == id) return Optional.of(ent); - return Optional.absent(); + return Optional.empty(); + } + + @Override + public boolean is(AbstractEntityType... types) { + for (AbstractEntityType type : types) + if (is(type)) + return true; + return false; + } + + @Override + public boolean is(AbstractEntityType type) { + return this == type; + } + + @Override + public boolean isOrHasParent(AbstractEntityType type) { + EntityType parent = this; + + do { + if (parent.equals(type)) + return true; + + parent = parent.getParent(); + } while (parent != null); + + return false; + } + + @Override + public List getParents() { + List types = new ArrayList<>(); + EntityType parent = this; + + do { + types.add(parent); + parent = parent.getParent(); + } while (parent != null); + + return types; } } @AllArgsConstructor @Getter - public enum ObjectType { + public enum ObjectType implements AbstractObjectType { BOAT(1, EntityType.BOAT), ITEM(2, EntityType.DROPPED_ITEM), AREA_EFFECT_CLOUD(3, EntityType.AREA_EFFECT_CLOUD), @@ -177,20 +220,20 @@ public class EntityType1_10 { public static Optional findById(int id) { if (id == -1) - return Optional.absent(); + return Optional.empty(); for (ObjectType ent : ObjectType.values()) if (ent.getId() == id) return Optional.of(ent); - return Optional.absent(); + return Optional.empty(); } public static Optional getPCEntity(int id) { Optional output = findById(id); if (!output.isPresent()) - return Optional.absent(); + return Optional.empty(); return Optional.of(output.get().getType()); } } diff --git a/core/src/main/java/nl/matsv/viabackwards/api/entities/EntityType1_11.java b/core/src/main/java/nl/matsv/viabackwards/api/entities/EntityType1_11.java index e26bfd9d..273f13cd 100644 --- a/core/src/main/java/nl/matsv/viabackwards/api/entities/EntityType1_11.java +++ b/core/src/main/java/nl/matsv/viabackwards/api/entities/EntityType1_11.java @@ -10,14 +10,17 @@ package nl.matsv.viabackwards.api.entities; -import com.google.common.base.Optional; import lombok.AllArgsConstructor; import lombok.Getter; import nl.matsv.viabackwards.ViaBackwards; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + public class EntityType1_11 { - public static EntityType getTypeFromId(int typeID, boolean isObject) { + public static EntityType getTypeFromId(int typeID, boolean isObject) throws Exception { Optional type; if (isObject) @@ -26,7 +29,7 @@ public class EntityType1_11 { type = EntityType.findById(typeID); if (!type.isPresent()) { - ViaBackwards.getPlatform().getLogger().severe("Could not find type id " + typeID + " isObject=" + isObject); + ViaBackwards.getPlatform().getLogger().severe("[EntityType1_11] Could not find type id " + typeID + " isObject=" + isObject); return EntityType.ENTITY; // Fall back to the basic ENTITY } @@ -53,7 +56,6 @@ public class EntityType1_11 { 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), @@ -161,27 +163,30 @@ public class EntityType1_11 { public static Optional findById(int id) { if (id == -1) // Check if this is called - return Optional.absent(); + return Optional.empty(); for (EntityType ent : EntityType.values()) if (ent.getId() == id) return Optional.of(ent); - return Optional.absent(); + return Optional.empty(); } - public boolean is(EntityType... types) { - for (EntityType type : types) + @Override + public boolean is(AbstractEntityType... types) { + for (AbstractEntityType type : types) if (is(type)) return true; return false; } - public boolean is(EntityType type) { + @Override + public boolean is(AbstractEntityType type) { return this == type; } - public boolean isOrHasParent(EntityType type) { + @Override + public boolean isOrHasParent(AbstractEntityType type) { EntityType parent = this; do { @@ -193,18 +198,31 @@ public class EntityType1_11 { return false; } + + @Override + public List getParents() { + List types = new ArrayList<>(); + EntityType parent = this; + + do { + types.add(parent); + parent = parent.getParent(); + } while (parent != null); + + return types; + } } @AllArgsConstructor @Getter - public enum ObjectType { + public enum ObjectType implements AbstractObjectType { 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), + TIPPED_ARROW(60, EntityType.ARROW), SNOWBALL(61, EntityType.SNOWBALL), EGG(62, EntityType.EGG), FIREBALL(63, EntityType.FIREBALL), @@ -221,7 +239,7 @@ public class EntityType1_11 { FIREWORK(76, EntityType.FIREWORK), LEASH(77, EntityType.LEASH_HITCH), ARMOR_STAND(78, EntityType.ARMOR_STAND), - EVOCATION_FANGS(39, EntityType.EVOCATION_FANGS), + EVOCATION_FANGS(79, EntityType.EVOCATION_FANGS), FISHIHNG_HOOK(90, EntityType.FISHING_HOOK), SPECTRAL_ARROW(91, EntityType.SPECTRAL_ARROW), DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL); @@ -231,20 +249,20 @@ public class EntityType1_11 { public static Optional findById(int id) { if (id == -1) - return Optional.absent(); + return Optional.empty(); for (ObjectType ent : ObjectType.values()) if (ent.getId() == id) return Optional.of(ent); - return Optional.absent(); + return Optional.empty(); } public static Optional getPCEntity(int id) { Optional output = findById(id); if (!output.isPresent()) - return Optional.absent(); + return Optional.empty(); return Optional.of(output.get().getType()); } } diff --git a/core/src/main/java/nl/matsv/viabackwards/api/rewriters/BlockItemRewriter.java b/core/src/main/java/nl/matsv/viabackwards/api/rewriters/BlockItemRewriter.java index 98646f21..760f42bb 100644 --- a/core/src/main/java/nl/matsv/viabackwards/api/rewriters/BlockItemRewriter.java +++ b/core/src/main/java/nl/matsv/viabackwards/api/rewriters/BlockItemRewriter.java @@ -75,11 +75,26 @@ public abstract class BlockItemRewriter extends Rew return item; } - protected Block handleBlock(int block) { + protected int handleBlockID(int idx) { + int type = idx >> 4; + int meta = idx & 15; + + if (!containsBlock(type)) + return idx; + + Block b = handleBlock(type, meta); + return (b.getId() << 4 | (b.getData() & 15)); + } + + protected Block handleBlock(int block, int data) { if (!containsBlock(block)) return null; - return blockRewriter.get(block); + Block b = blockRewriter.get(block); + // For some blocks, the data can still be useful (: + if (b.getData() == -1) + b.setData(data); + return b; } protected boolean containsBlock(int block) { diff --git a/core/src/main/java/nl/matsv/viabackwards/api/rewriters/EntityRewriter.java b/core/src/main/java/nl/matsv/viabackwards/api/rewriters/EntityRewriter.java index d7339f74..1acb1060 100644 --- a/core/src/main/java/nl/matsv/viabackwards/api/rewriters/EntityRewriter.java +++ b/core/src/main/java/nl/matsv/viabackwards/api/rewriters/EntityRewriter.java @@ -13,26 +13,31 @@ package nl.matsv.viabackwards.api.rewriters; 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.entities.AbstractObjectType; import nl.matsv.viabackwards.api.exceptions.RemovedValueException; +import nl.matsv.viabackwards.api.storage.EntityData; import nl.matsv.viabackwards.api.storage.EntityTracker; -import us.myles.ViaVersion.api.ViaVersion; +import nl.matsv.viabackwards.api.v2.MetaHandlerEvent; +import nl.matsv.viabackwards.api.v2.MetaHandlerSettings; +import nl.matsv.viabackwards.api.v2.MetaStorage; +import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.data.UserConnection; import us.myles.ViaVersion.api.minecraft.metadata.Metadata; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.logging.Logger; @RequiredArgsConstructor public abstract class EntityRewriter extends Rewriter { - private final Map entityTypes = new ConcurrentHashMap<>(); - - private final List metaRewriters = new ArrayList<>(); + private final Map entityTypes = new ConcurrentHashMap<>(); + private final Map objectTypes = new ConcurrentHashMap<>(); + private final List metaHandlers = new ArrayList<>(); protected AbstractEntityType getEntityType(UserConnection connection, int id) { return getEntityTracker(connection).getEntityType(id); @@ -42,53 +47,76 @@ public abstract class EntityRewriter extends Rewrit getEntityTracker(connection).trackEntityType(entityId, type); } - protected void rewriteEntityType(AbstractEntityType type, int newId) { - entityTypes.put(type, (short) newId); + protected Optional getEntityData(AbstractEntityType type) { + if (!entityTypes.containsKey(type)) + return Optional.empty(); + return Optional.of(entityTypes.get(type)); } - protected boolean isRewriteEntityType(AbstractEntityType type) { - return entityTypes.containsKey(type); + protected Optional getObjectData(AbstractObjectType type) { + if (!objectTypes.containsKey(type)) + return Optional.empty(); + return Optional.of(objectTypes.get(type)); } - protected short getNewEntityType(AbstractEntityType type) { - if (!isRewriteEntityType(type)) - return -1; - return entityTypes.get(type); + protected EntityData regEntType(AbstractEntityType oldEnt, AbstractEntityType replacement) { + return regEntType(oldEnt, (short) replacement.getId()); } - public void registerMetaRewriter(MetaRewriter rewriter) { - metaRewriters.add(rewriter); + private EntityData regEntType(AbstractEntityType oldEnt, short replacementId) { + EntityData data = new EntityData(oldEnt.getId(), false, replacementId, -1); + entityTypes.put(oldEnt, data); + return data; } - protected List handleMeta(UserConnection user, int entityId, List metaData) { + protected EntityData regObjType(AbstractObjectType oldObj, AbstractObjectType replacement, int data) { + return regObjType(oldObj, (short) replacement.getId(), data); + } + + private EntityData regObjType(AbstractObjectType oldObj, short replacementId, int data) { + EntityData entData = new EntityData(oldObj.getId(), true, replacementId, data); + objectTypes.put(oldObj, entData); + return entData; + } + + public MetaHandlerSettings registerMetaHandler() { + MetaHandlerSettings settings = new MetaHandlerSettings(); + metaHandlers.add(settings); + return settings; + } + + protected MetaStorage handleMeta(UserConnection user, int entityId, MetaStorage storage) throws Exception { EntityTracker tracker = user.get(EntityTracker.class); + AbstractEntityType type = tracker.get(getProtocol()).getEntityType(entityId); - List newMeta = new CopyOnWriteArrayList<>(); - for (Metadata md : metaData) { - Metadata nmd = md; - try { - for (MetaRewriter rewriter : metaRewriters) { - if (type != null) - nmd = rewriter.handleMetadata(type, nmd); - else - throw new Exception("Panic, entitytype is null"); + List newList = new CopyOnWriteArrayList<>(); + + for (MetaHandlerSettings settings : metaHandlers) { + for (Metadata md : storage.getMetaDataList()) { + Metadata nmd = md; + try { + if (settings.isGucci(type, nmd)) + nmd = settings.getHandler().handle(new MetaHandlerEvent(type, nmd.getId(), nmd, storage)); + if (nmd == null) throw new RemovedValueException(); - } - newMeta.add(nmd); - } catch (RemovedValueException ignored) { - } catch (Exception e) { - if (ViaVersion.getInstance().isDebug()) { - Logger log = ViaBackwards.getPlatform().getLogger(); - log.warning("Unable to handle metadata " + md); - log.warning("Full metadata list " + metaData); - e.printStackTrace(); + newList.add(nmd); + } catch (RemovedValueException ignored) { + } catch (Exception e) { + if (Via.getManager().isDebug()) { + Logger log = ViaBackwards.getPlatform().getLogger(); + log.warning("Unable to handle metadata " + nmd); + log.warning("Full metadata list " + storage); + e.printStackTrace(); + } } } + storage.setMetaDataList(new ArrayList<>(newList)); + newList.clear(); } - return newMeta; + return storage; } protected EntityTracker.ProtocolEntityTracker getEntityTracker(UserConnection user) { diff --git a/core/src/main/java/nl/matsv/viabackwards/api/storage/EntityData.java b/core/src/main/java/nl/matsv/viabackwards/api/storage/EntityData.java new file mode 100644 index 00000000..dafefc19 --- /dev/null +++ b/core/src/main/java/nl/matsv/viabackwards/api/storage/EntityData.java @@ -0,0 +1,40 @@ +/* + * 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.storage; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.ToString; +import nl.matsv.viabackwards.api.v2.MetaStorage; + +@RequiredArgsConstructor +@Getter +@ToString +public class EntityData { + private final int id; + private final boolean isObject; + + private final int replacementId; + private final int objectData; + private MetaCreator defaultMeta; + + public void spawnMetadata(MetaCreator handler) { + this.defaultMeta = handler; + } + + public boolean hasBaseMeta() { + return this.defaultMeta != null; + } + + public interface MetaCreator { + void handle(MetaStorage storage); + } +} diff --git a/core/src/main/java/nl/matsv/viabackwards/api/MetaRewriter.java b/core/src/main/java/nl/matsv/viabackwards/api/v2/MetaHandler.java similarity index 84% rename from core/src/main/java/nl/matsv/viabackwards/api/MetaRewriter.java rename to core/src/main/java/nl/matsv/viabackwards/api/v2/MetaHandler.java index 46ab85fe..039a6af7 100644 --- a/core/src/main/java/nl/matsv/viabackwards/api/MetaRewriter.java +++ b/core/src/main/java/nl/matsv/viabackwards/api/v2/MetaHandler.java @@ -8,12 +8,11 @@ * 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; +package nl.matsv.viabackwards.api.v2; -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(AbstractEntityType type, Metadata data) throws RemovedValueException; +public interface MetaHandler { + Metadata handle(MetaHandlerEvent e) throws RemovedValueException; } diff --git a/core/src/main/java/nl/matsv/viabackwards/api/v2/MetaHandlerEvent.java b/core/src/main/java/nl/matsv/viabackwards/api/v2/MetaHandlerEvent.java new file mode 100644 index 00000000..836f3a3c --- /dev/null +++ b/core/src/main/java/nl/matsv/viabackwards/api/v2/MetaHandlerEvent.java @@ -0,0 +1,39 @@ +/* + * 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.v2; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import nl.matsv.viabackwards.api.entities.AbstractEntityType; +import us.myles.ViaVersion.api.minecraft.metadata.Metadata; + +import java.util.Optional; + +@Getter +@AllArgsConstructor +public class MetaHandlerEvent { + private AbstractEntityType type; + private int index = -1; + private Metadata data; + @Getter + private MetaStorage storage; + + public boolean hasData() { + return data != null; + } + + public Optional getMetaByIndex(int index) { + for (Metadata meta : getStorage().getMetaDataList()) + if (index == meta.getId()) + return Optional.of(meta); + return Optional.empty(); + } +} diff --git a/core/src/main/java/nl/matsv/viabackwards/api/v2/MetaHandlerSettings.java b/core/src/main/java/nl/matsv/viabackwards/api/v2/MetaHandlerSettings.java new file mode 100644 index 00000000..3b6fdc18 --- /dev/null +++ b/core/src/main/java/nl/matsv/viabackwards/api/v2/MetaHandlerSettings.java @@ -0,0 +1,89 @@ +/* + * 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.v2; + +import lombok.Getter; +import lombok.ToString; +import nl.matsv.viabackwards.api.entities.AbstractEntityType; +import us.myles.ViaVersion.api.minecraft.metadata.Metadata; + +import java.util.List; + +@ToString +@Getter +public class MetaHandlerSettings { + private AbstractEntityType filterType; + private boolean filterFamily = false; + private int filterIndex = -1; + private MetaHandler handler; + + public MetaHandlerSettings filter(AbstractEntityType type) { + return filter(type, filterFamily, filterIndex); + } + + public MetaHandlerSettings filter(AbstractEntityType type, boolean filterFamily) { + return filter(type, filterFamily, filterIndex); + } + + public MetaHandlerSettings filter(int index) { + return filter(filterType, filterFamily, index); + } + + public MetaHandlerSettings filter(AbstractEntityType type, int index) { + return filter(type, filterFamily, index); + } + + public MetaHandlerSettings filter(AbstractEntityType type, boolean filterFamily, int index) { + this.filterType = type; + this.filterFamily = filterFamily; + this.filterIndex = index; + return this; + } + + public void handle(MetaHandler handler) { + this.handler = handler; + } + + public boolean hasHandler() { + return handler != null; + } + + public boolean hasType() { + return filterType != null; + } + + public boolean hasIndex() { + return filterIndex > -1; + } + + public boolean isFilterFamily() { + return filterFamily; + } + + public boolean isGucci(AbstractEntityType type, Metadata metadata) { + if (hasHandler()) { + if (hasType()) { + List family = type.getParents(); + if (isFilterFamily()) { + if (!family.contains(getFilterType())) + return false; + } else { + if (!getFilterType().is(type)) + return false; + } + } + if (hasIndex() && metadata.getId() != getFilterIndex()) + return false; + return true; + } + return false; + } +} diff --git a/core/src/main/java/nl/matsv/viabackwards/api/v2/MetaStorage.java b/core/src/main/java/nl/matsv/viabackwards/api/v2/MetaStorage.java new file mode 100644 index 00000000..4f9028c1 --- /dev/null +++ b/core/src/main/java/nl/matsv/viabackwards/api/v2/MetaStorage.java @@ -0,0 +1,63 @@ +/* + * 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.v2; + +import lombok.*; +import us.myles.ViaVersion.api.minecraft.metadata.Metadata; + +import java.util.List; +import java.util.Optional; + +@Getter +@Setter +@ToString +@AllArgsConstructor +public class MetaStorage { + @NonNull + private List metaDataList; + + public boolean has(Metadata data) { + return this.getMetaDataList().contains(data); + } + + public void delete(Metadata data) { + this.getMetaDataList().remove(data); + } + + public void delete(int index) { + Optional data = get(index); + if (data.isPresent()) + delete(data.get()); + } + + public void add(Metadata data) { + this.getMetaDataList().add(data); + } + + public Optional get(int index) { + for (Metadata meta : this.getMetaDataList()) + if (index == meta.getId()) + return Optional.of(meta); + return Optional.empty(); + } + + public Metadata getOrDefault(int index, Metadata data) { + return getOrDefault(index, false, data); + } + + public Metadata getOrDefault(int index, boolean removeIfExists, Metadata data) { + Optional existingData = get(index); + + if (removeIfExists && existingData.isPresent()) + delete(existingData.get()); + return existingData.orElse(data); + } +} diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_10to1_11/Protocol1_10To1_11.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_10to1_11/Protocol1_10To1_11.java index c2cefa9c..706dda31 100644 --- a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_10to1_11/Protocol1_10To1_11.java +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_10to1_11/Protocol1_10To1_11.java @@ -10,6 +10,7 @@ package nl.matsv.viabackwards.protocol.protocol1_10to1_11; +import lombok.Getter; import nl.matsv.viabackwards.api.BackwardsProtocol; import nl.matsv.viabackwards.api.storage.EntityTracker; import nl.matsv.viabackwards.protocol.protocol1_10to1_11.packets.BlockItemPackets; @@ -19,9 +20,12 @@ 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 { + @Getter + private EntityPackets entityPackets; // Required for the item rewriter + @Override protected void registerPackets() { - new EntityPackets().register(this); + (entityPackets = new EntityPackets()).register(this); new PlayerPackets().register(this); new BlockItemPackets().register(this); } diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_10to1_11/packets/BlockItemPackets.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_10to1_11/packets/BlockItemPackets.java index cdf27e21..af68a2c8 100644 --- a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_10to1_11/packets/BlockItemPackets.java +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_10to1_11/packets/BlockItemPackets.java @@ -12,16 +12,18 @@ package nl.matsv.viabackwards.protocol.protocol1_10to1_11.packets; import nl.matsv.viabackwards.api.rewriters.BlockItemRewriter; import nl.matsv.viabackwards.protocol.protocol1_10to1_11.Protocol1_10To1_11; -import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.chunks.Chunk1_10; -import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.chunks.Chunk1_10Type; -import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.chunks.ChunkSection1_10; import nl.matsv.viabackwards.utils.Block; import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.minecraft.item.Item; +import us.myles.ViaVersion.api.minecraft.metadata.Metadata; +import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_9; import us.myles.ViaVersion.api.remapper.PacketHandler; import us.myles.ViaVersion.api.remapper.PacketRemapper; import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.packets.State; +import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks.Chunk1_9_3_4; +import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks.ChunkSection1_9_3_4; +import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.types.Chunk1_9_3_4Type; import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; public class BlockItemPackets extends BlockItemRewriter { @@ -165,20 +167,21 @@ public class BlockItemPackets extends BlockItemRewriter { public void handle(PacketWrapper wrapper) throws Exception { ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); - Chunk1_10Type type = new Chunk1_10Type(clientWorld); // Use the 1.10 Chunk type since nothing changed. - Chunk1_10 chunk = (Chunk1_10) wrapper.passthrough(type); + Chunk1_9_3_4Type type = new Chunk1_9_3_4Type(clientWorld); // Use the 1.10 Chunk type since nothing changed. + Chunk1_9_3_4 chunk = (Chunk1_9_3_4) wrapper.passthrough(type); for (int i = 0; i < chunk.getSections().length; i++) { - ChunkSection1_10 section = chunk.getSections()[i]; + ChunkSection1_9_3_4 section = chunk.getSections()[i]; if (section == null) continue; for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { - int block = section.getBlockId(x, y, z); - if (containsBlock(block)) { - Block b = handleBlock(block); + int block = section.getBlock(x, y, z); + int btype = block >> 4; + if (containsBlock(btype)) { + Block b = handleBlock(btype, block & 15); // Type / data section.setBlock(x, y, z, b.getId(), b.getData()); } } @@ -233,16 +236,15 @@ public class BlockItemPackets extends BlockItemRewriter { } } ); - } - protected int handleBlockID(int idx) { - int type = idx >> 4; + protocol.getEntityPackets().registerMetaHandler().handle(e -> { + Metadata data = e.getData(); - if (!containsBlock(type)) - return idx; + if (data.getMetaType().equals(MetaType1_9.Slot)) // Is Item + data.setValue(handleItemToClient((Item) data.getValue())); - Block b = handleBlock(type); - return (b.getId() << 4 | (b.getData() & 15)); + return data; + }); } @Override @@ -253,7 +255,7 @@ public class BlockItemPackets extends BlockItemRewriter { new Item((short) 54, (byte) 1, (short) 0, getNamedTag("1.11 Shulker Box (Color #" + (i - 219) + ")")), new Block(i, 1)); - // Observer to Dispenser + // Observer to Dispenser TODO facing position? rewriteBlockItem(218, new Item((short) 23, (byte) 1, (short) 0, getNamedTag("1.11 Observer")), new Block(23, 0)); // Totem of Undying to Dead Bush diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_10to1_11/packets/EntityPackets.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_10to1_11/packets/EntityPackets.java index c8c98b4f..d1c9ab11 100644 --- a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_10to1_11/packets/EntityPackets.java +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_10to1_11/packets/EntityPackets.java @@ -10,10 +10,17 @@ package nl.matsv.viabackwards.protocol.protocol1_10to1_11.packets; +import nl.matsv.viabackwards.ViaBackwards; import nl.matsv.viabackwards.api.entities.AbstractEntityType; +import nl.matsv.viabackwards.api.exceptions.RemovedValueException; import nl.matsv.viabackwards.api.rewriters.EntityRewriter; +import nl.matsv.viabackwards.api.storage.EntityData; +import nl.matsv.viabackwards.api.v2.MetaStorage; import nl.matsv.viabackwards.protocol.protocol1_10to1_11.Protocol1_10To1_11; import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.minecraft.metadata.Metadata; +import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_9; import us.myles.ViaVersion.api.remapper.PacketHandler; import us.myles.ViaVersion.api.remapper.PacketRemapper; import us.myles.ViaVersion.api.type.Type; @@ -21,10 +28,14 @@ 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 java.util.Optional; + import static nl.matsv.viabackwards.api.entities.EntityType1_11.*; + public class EntityPackets extends EntityRewriter { + @Override protected void registerPackets(Protocol1_10To1_11 protocol) { // Spawn Object @@ -34,6 +45,12 @@ public class EntityPackets extends EntityRewriter { map(Type.VAR_INT); // 0 - Entity id map(Type.UUID); // 1 - UUID map(Type.BYTE); // 2 - Type + map(Type.DOUBLE); // 3 - x + map(Type.DOUBLE); // 4 - y + map(Type.DOUBLE); // 5 - z + map(Type.BYTE); // 6 - Pitch + map(Type.BYTE); // 7 - Yaw + map(Type.INT); // 8 - data // Track Entity handler(new PacketHandler() { @@ -46,6 +63,27 @@ public class EntityPackets extends EntityRewriter { ); } }); + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + Optional type = ObjectType.findById(wrapper.get(Type.BYTE, 0)); + + if (type.isPresent()) { + Optional optEntDat = getObjectData(type.get()); + if (optEntDat.isPresent()) { + EntityData data = optEntDat.get(); + wrapper.set(Type.BYTE, 0, ((Integer) data.getReplacementId()).byteValue()); + if (data.getObjectData() != -1) + wrapper.set(Type.INT, 0, data.getObjectData()); + } + } else { + if (Via.getManager().isDebug()) { + ViaBackwards.getPlatform().getLogger().warning("Could not find Entity Type" + wrapper.get(Type.BYTE, 0)); + } + } + } + }); } }); @@ -120,35 +158,33 @@ public class EntityPackets extends EntityRewriter { } }); - // Rewrite entity ids + // Rewrite entity type / metadata 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; + MetaStorage storage = new MetaStorage(wrapper.get(Types1_9.METADATA_LIST, 0)); + handleMeta( + wrapper.user(), + wrapper.get(Type.VAR_INT, 0), + storage + ); - wrapper.set(Type.UNSIGNED_BYTE, 0, newType); - } - }); + Optional optEntDat = getEntityData(type); + if (optEntDat.isPresent()) { + EntityData data = optEntDat.get(); + wrapper.set(Type.UNSIGNED_BYTE, 0, ((Integer) data.getReplacementId()).shortValue()); + if (data.hasBaseMeta()) + data.getDefaultMeta().handle(storage); + } - // Rewrite metadata - handler(new PacketHandler() { - @Override - public void handle(PacketWrapper wrapper) throws Exception { + // Rewrite Metadata wrapper.set( Types1_9.METADATA_LIST, 0, - handleMeta( - wrapper.user(), - wrapper.get(Type.VAR_INT, 0), - wrapper.get(Types1_9.METADATA_LIST, 0) - ) + storage.getMetaDataList() ); } }); @@ -256,8 +292,8 @@ public class EntityPackets extends EntityRewriter { handleMeta( wrapper.user(), wrapper.get(Type.VAR_INT, 0), - wrapper.get(Types1_9.METADATA_LIST, 0) - ) + new MetaStorage(wrapper.get(Types1_9.METADATA_LIST, 0)) + ).getMetaDataList() ); } }); @@ -296,8 +332,8 @@ public class EntityPackets extends EntityRewriter { handleMeta( wrapper.user(), wrapper.get(Type.VAR_INT, 0), - wrapper.get(Types1_9.METADATA_LIST, 0) - ) + new MetaStorage(wrapper.get(Types1_9.METADATA_LIST, 0)) + ).getMetaDataList() ); } }); @@ -307,6 +343,188 @@ public class EntityPackets extends EntityRewriter { @Override protected void registerRewrites() { + // Guardian + regEntType(EntityType.ELDER_GUARDIAN, EntityType.GUARDIAN); + // Skeletons + regEntType(EntityType.WITHER_SKELETON, EntityType.SKELETON).spawnMetadata(storage -> storage.add(getSkeletonTypeMeta(1))); + regEntType(EntityType.STRAY, EntityType.SKELETON).spawnMetadata(storage -> storage.add(getSkeletonTypeMeta(2))); + // Zombies + regEntType(EntityType.HUSK, EntityType.ZOMBIE).spawnMetadata(storage -> handleZombieType(storage, 6)); + regEntType(EntityType.ZOMBIE_VILLAGER, EntityType.ZOMBIE).spawnMetadata(storage -> handleZombieType(storage, 1)); + // Horses + regEntType(EntityType.HORSE, EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(0))); // Nob able to ride the horse without having the MetaType sent. + regEntType(EntityType.DONKEY, EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(1))); + regEntType(EntityType.MULE, EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(2))); + regEntType(EntityType.SKELETON_HORSE, EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(4))); + regEntType(EntityType.ZOMBIE_HORSE, EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(3))); + // New mobs + regEntType(EntityType.EVOCATION_FANGS, EntityType.SHULKER); + regEntType(EntityType.EVOCATION_ILLAGER, EntityType.VILLAGER); + regEntType(EntityType.VEX, EntityType.BAT); + regEntType(EntityType.VINDICATION_ILLAGER, EntityType.VILLAGER).spawnMetadata(storage -> storage.add(new Metadata(13, MetaType1_9.VarInt, 4))); // Base Profession + regEntType(EntityType.LIAMA, EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(1))); // TODO fix chest slots + regEntType(EntityType.LIAMA_SPIT, EntityType.SNOWBALL); + + regObjType(ObjectType.LIAMA_SPIT, ObjectType.SNOWBALL, -1); + // Replace with endertorchthingies + regObjType(ObjectType.EVOCATION_FANGS, ObjectType.FALLING_BLOCK, 198 | 1 << 12); + + // Handle ElderGuardian & target metadata + registerMetaHandler().filter(EntityType.GUARDIAN, true, 12).handle(e -> { + Metadata data = e.getData(); + + boolean b = (boolean) data.getValue(); + int bitmask = b ? 0x02 : 0; + + if (e.getType().is(EntityType.ELDER_GUARDIAN)) + bitmask |= 0x04; + + data.setMetaType(MetaType1_9.Byte); + data.setValue((byte) bitmask); + + return data; + }); + + // Handle skeleton swing + registerMetaHandler().filter(EntityType.ABSTRACT_SKELETON, true, 12).handle(e -> { + e.getData().setId(13); + return e.getData(); + }); + + /* + ZOMBIE CHANGES + */ + registerMetaHandler().filter(EntityType.ZOMBIE, true).handle(e -> { + Metadata data = e.getData(); + + switch (data.getId()) { + case 13: + throw new RemovedValueException(); + case 14: + data.setId(15); + break; + case 15: + data.setId(14); + break; + // Profession + case 16: + data.setId(13); + data.setValue(1 + (int) data.getValue()); + break; + } + + return data; + }); + + // Handle Evocation Illager + registerMetaHandler().filter(EntityType.EVOCATION_ILLAGER, 12).handle(e -> { + Metadata data = e.getData(); + data.setId(13); + data.setMetaType(MetaType1_9.VarInt); + data.setValue(((Byte) data.getValue()).intValue()); // Change the profession for the states + + return data; + }); + + // Handle Vex (Remove this field completely since the position is not updated correctly when idling for bats. Sad ): + registerMetaHandler().filter(EntityType.VEX, 12).handle(e -> { + Metadata data = e.getData(); + data.setValue((byte) 0x00); + return data; + }); + + // Handle VindicationIllager + registerMetaHandler().filter(EntityType.VINDICATION_ILLAGER, 12).handle(e -> { + Metadata data = e.getData(); + data.setId(13); + data.setMetaType(MetaType1_9.VarInt); + + data.setValue((byte) data.getValue() == 1 ? 2 : 4); + + return data; + }); + + /* + HORSES + */ + + // Handle Horse (Correct owner) + registerMetaHandler().filter(EntityType.ABSTRACT_HORSE, true, 14).handle(e -> { + Metadata data = e.getData(); + data.setId(16); + return data; + }); + + // Handle horse armor + registerMetaHandler().filter(EntityType.HORSE, 16).handle(e -> { + Metadata data = e.getData(); + data.setId(17); + return data; + }); + + // Handle chested horse - flag is still sent in horse flags + registerMetaHandler().filter(EntityType.CHESTED_HORSE, true, 15).handle(e -> { + throw new RemovedValueException(); + }); + + // Get rid of Liama metadata TODO maybe for some special magic in the future? + registerMetaHandler().filter(EntityType.LIAMA).handle(e -> { + int index = e.getIndex(); + if (index == 16 || index == 17 || index == 18) + throw new RemovedValueException(); + return e.getData(); + }); + + // Handle villager - Change non-existing profession + registerMetaHandler().filter(EntityType.VILLAGER, 13).handle(e -> { + Metadata data = e.getData(); + if ((int) data.getValue() == 5) + data.setValue(0); + + return data; + }); + + // handle new Shulker color meta + registerMetaHandler().filter(EntityType.SHULKER, 15).handle(e -> { + throw new RemovedValueException(); + }); } + + /* + 0 - Skeleton + 1 - Wither Skeleton + 2 - Stray + */ + private Metadata getSkeletonTypeMeta(int type) { + return new Metadata(12, MetaType1_9.VarInt, type); + } + + /* + 0 - Zombie + 1-5 - Villager with profession + 6 - Husk + */ + private Metadata getZombieTypeMeta(int type) { + return new Metadata(13, MetaType1_9.VarInt, type); + } + + private void handleZombieType(MetaStorage storage, int type) { + Optional meta = storage.get(13); + + if (!meta.isPresent()) + storage.add(getZombieTypeMeta(type)); + } + + /* + Horse 0 + Donkey 1 + Mule 2 + Zombie horse 3 + Skeleton horse 4 + */ + private Metadata getHorseMetaType(int type) { + return new Metadata(14, MetaType1_9.VarInt, type); + } + } diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_11to1_11_1/Protocol1_11To1_11_1.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_11to1_11_1/Protocol1_11To1_11_1.java new file mode 100644 index 00000000..f2f87d92 --- /dev/null +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_11to1_11_1/Protocol1_11To1_11_1.java @@ -0,0 +1,40 @@ +/* + * 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.protocol.protocol1_11to1_11_1; + +import nl.matsv.viabackwards.api.BackwardsProtocol; +import nl.matsv.viabackwards.api.storage.EntityTracker; +import nl.matsv.viabackwards.protocol.protocol1_11to1_11_1.packets.EntityPackets; +import nl.matsv.viabackwards.protocol.protocol1_11to1_11_1.packets.ItemPackets; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; + +public class Protocol1_11To1_11_1 extends BackwardsProtocol { + @Override + protected void registerPackets() { + new EntityPackets().register(this); + new ItemPackets().register(this); + } + + @Override + 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); + } +} diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_11to1_11_1/packets/EntityPackets.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_11to1_11_1/packets/EntityPackets.java new file mode 100644 index 00000000..e38b0ae1 --- /dev/null +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_11to1_11_1/packets/EntityPackets.java @@ -0,0 +1,354 @@ +/* + * 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.protocol.protocol1_11to1_11_1.packets; + +import nl.matsv.viabackwards.ViaBackwards; +import nl.matsv.viabackwards.api.entities.AbstractEntityType; +import nl.matsv.viabackwards.api.exceptions.RemovedValueException; +import nl.matsv.viabackwards.api.rewriters.EntityRewriter; +import nl.matsv.viabackwards.api.storage.EntityData; +import nl.matsv.viabackwards.api.v2.MetaStorage; +import nl.matsv.viabackwards.protocol.protocol1_11to1_11_1.Protocol1_11To1_11_1; +import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.remapper.PacketHandler; +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 java.util.Optional; + +import static nl.matsv.viabackwards.api.entities.EntityType1_11.*; + +public class EntityPackets extends EntityRewriter { + + @Override + protected void registerPackets(Protocol1_11To1_11_1 protocol) { + // 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 + map(Type.DOUBLE); // 3 - x + map(Type.DOUBLE); // 4 - y + map(Type.DOUBLE); // 5 - z + map(Type.BYTE); // 6 - Pitch + map(Type.BYTE); // 7 - Yaw + map(Type.INT); // 8 - data + + // 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) + ); + } + }); + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + Optional type = ObjectType.findById(wrapper.get(Type.BYTE, 0)); + + if (type.isPresent()) { + Optional optEntDat = getObjectData(type.get()); + if (optEntDat.isPresent()) { + EntityData data = optEntDat.get(); + wrapper.set(Type.BYTE, 0, ((Integer) data.getReplacementId()).byteValue()); + if (data.getObjectData() != -1) + wrapper.set(Type.INT, 0, data.getObjectData()); + } + } else { + if (Via.getManager().isDebug()) { + ViaBackwards.getPlatform().getLogger().warning("Could not find Entity Type" + wrapper.get(Type.BYTE, 0)); + } + } + } + }); + } + }); + + // 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.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); // 2 - Entity Type + map(Type.DOUBLE); // 3 - X + map(Type.DOUBLE); // 4 - Y + map(Type.DOUBLE); // 5 - Z + map(Type.BYTE); // 6 - Yaw + map(Type.BYTE); // 7 - Pitch + map(Type.BYTE); // 8 - Head Pitch + map(Type.SHORT); // 9 - Velocity X + map(Type.SHORT); // 10 - Velocity Y + 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 { + addTrackedEntity( + wrapper.user(), + wrapper.get(Type.VAR_INT, 0), + getTypeFromId(wrapper.get(Type.VAR_INT, 1), false) + ); + } + }); + + + // Rewrite entity type / metadata + 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); + + MetaStorage storage = new MetaStorage(wrapper.get(Types1_9.METADATA_LIST, 0)); + handleMeta( + wrapper.user(), + wrapper.get(Type.VAR_INT, 0), + storage + ); + + Optional optEntDat = getEntityData(type); + if (optEntDat.isPresent()) { + EntityData data = optEntDat.get(); + wrapper.set(Type.UNSIGNED_BYTE, 0, ((Integer) data.getReplacementId()).shortValue()); + if (data.hasBaseMeta()) + data.getDefaultMeta().handle(storage); + } + + // Rewrite Metadata + wrapper.set( + Types1_9.METADATA_LIST, + 0, + storage.getMetaDataList() + ); + } + }); + } + }); + + // 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), + new MetaStorage(wrapper.get(Types1_9.METADATA_LIST, 0)) + ).getMetaDataList() + ); + } + }); + } + }); + + // 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), + new MetaStorage(wrapper.get(Types1_9.METADATA_LIST, 0)) + ).getMetaDataList() + ); + } + }); + } + }); + } + + @Override + protected void registerRewrites() { + // TODO tipped arrows check no particles changes? + // Handle non-existing firework metadata (index 7 entity id for boosting) + registerMetaHandler().filter(EntityType.FIREWORK, 7).handle(e -> { + throw new RemovedValueException(); + }); + + // Handle non-existing pig metadata (index 14 - boost time) + registerMetaHandler().filter(EntityType.PIG, 14).handle(e -> { + throw new RemovedValueException(); + }); + } +} diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_11to1_11_1/packets/ItemPackets.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_11to1_11_1/packets/ItemPackets.java new file mode 100644 index 00000000..a33c31ba --- /dev/null +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_11to1_11_1/packets/ItemPackets.java @@ -0,0 +1,156 @@ +/* + * 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.protocol.protocol1_11to1_11_1.packets; + +import nl.matsv.viabackwards.api.rewriters.BlockItemRewriter; +import nl.matsv.viabackwards.protocol.protocol1_11to1_11_1.Protocol1_11To1_11_1; +import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.minecraft.item.Item; +import us.myles.ViaVersion.api.remapper.PacketHandler; +import us.myles.ViaVersion.api.remapper.PacketRemapper; +import us.myles.ViaVersion.api.type.Type; +import us.myles.ViaVersion.packets.State; + +public class ItemPackets extends BlockItemRewriter { + + @Override + protected void registerPackets(Protocol1_11To1_11_1 protocol) { + // Set slot packet + protocol.registerOutgoing(State.PLAY, 0x16, 0x16, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.BYTE); // 0 - Window ID + map(Type.SHORT); // 1 - Slot ID + map(Type.ITEM); // 2 - Slot Value + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + Item stack = wrapper.get(Type.ITEM, 0); + wrapper.set(Type.ITEM, 0, handleItemToClient(stack)); + } + }); + } + }); + + // Window items packet + protocol.registerOutgoing(State.PLAY, 0x14, 0x14, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.UNSIGNED_BYTE); // 0 - Window ID + map(Type.ITEM_ARRAY); // 1 - Window Values + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + Item[] stacks = wrapper.get(Type.ITEM_ARRAY, 0); + for (int i = 0; i < stacks.length; i++) + stacks[i] = handleItemToClient(stacks[i]); + } + }); + } + }); + + // Entity Equipment Packet + protocol.registerOutgoing(State.PLAY, 0x3C, 0x3C, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT); // 0 - Entity ID + map(Type.VAR_INT); // 1 - Slot ID + map(Type.ITEM); // 2 - Item + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + Item stack = wrapper.get(Type.ITEM, 0); + wrapper.set(Type.ITEM, 0, handleItemToClient(stack)); + } + }); + } + }); + + // Plugin message Packet -> Trading + protocol.registerOutgoing(State.PLAY, 0x18, 0x18, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.STRING); // 0 - Channel + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + if (wrapper.get(Type.STRING, 0).equalsIgnoreCase("MC|TrList")) { + wrapper.passthrough(Type.INT); // Passthrough Window ID + + int size = wrapper.passthrough(Type.BYTE); + for (int i = 0; i < size; i++) { + wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Input Item + wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Output Item + + boolean secondItem = wrapper.passthrough(Type.BOOLEAN); // Has second item + if (secondItem) + wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Second Item + + wrapper.passthrough(Type.BOOLEAN); // Trade disabled + wrapper.passthrough(Type.INT); // Number of tools uses + wrapper.passthrough(Type.INT); // Maximum number of trade uses + } + } + } + }); + } + }); + + // Click window packet + protocol.registerIncoming(State.PLAY, 0x07, 0x07, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.UNSIGNED_BYTE); // 0 - Window ID + map(Type.SHORT); // 1 - Slot + map(Type.BYTE); // 2 - Button + map(Type.SHORT); // 3 - Action number + map(Type.VAR_INT); // 4 - Mode + map(Type.ITEM); // 5 - Clicked Item + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + Item item = wrapper.get(Type.ITEM, 0); + handleItemToServer(item); + } + }); + } + } + ); + + // Creative Inventory Action + protocol.registerIncoming(State.PLAY, 0x18, 0x18, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.SHORT); // 0 - Slot + map(Type.ITEM); // 1 - Clicked Item + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + Item item = wrapper.get(Type.ITEM, 0); + handleItemToServer(item); + } + }); + } + } + ); + } + + @Override + protected void registerRewrites() { + rewriteItem(452, new Item((short) 265, (byte) 1, (short) 0, getNamedTag("1.11.2 Iron Nugget"))); + } +} diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_9_4to1_10/chunks/Chunk1_10Type.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_9_4to1_10/chunks/Chunk1_10Type.java deleted file mode 100644 index 28f0f85b..00000000 --- a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_9_4to1_10/chunks/Chunk1_10Type.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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.protocol.protocol1_9_4to1_10.chunks; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import nl.matsv.viabackwards.ViaBackwards; -import us.myles.ViaVersion.api.Via; -import us.myles.ViaVersion.api.minecraft.Environment; -import us.myles.ViaVersion.api.minecraft.chunks.Chunk; -import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; -import us.myles.ViaVersion.api.type.PartialType; -import us.myles.ViaVersion.api.type.Type; -import us.myles.ViaVersion.api.type.types.minecraft.BaseChunkType; -import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; -import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag; - -import java.util.Arrays; -import java.util.BitSet; -import java.util.List; - -public class Chunk1_10Type extends PartialType { - - public Chunk1_10Type(ClientWorld param) { - super(param, Chunk.class); - } - - @Override - public Chunk read(ByteBuf input, ClientWorld world) throws Exception { - int chunkX = input.readInt(); - int chunkZ = input.readInt(); - - boolean groundUp = input.readBoolean(); - int primaryBitmask = Type.VAR_INT.read(input); - Type.VAR_INT.read(input); - - BitSet usedSections = new BitSet(16); - ChunkSection1_10[] sections = new ChunkSection1_10[16]; - // Calculate section count from bitmask - for (int i = 0; i < 16; i++) { - if ((primaryBitmask & (1 << i)) != 0) { - usedSections.set(i); - } - } - - // Read sections - for (int i = 0; i < 16; i++) { - if (!usedSections.get(i)) continue; // Section not set - ChunkSection1_10 section = new ChunkSection1_10(); - sections[i] = section; - section.readBlocks(input); - section.readBlockLight(input); - if (world.getEnvironment() == Environment.NORMAL) { - section.readSkyLight(input); - } - } - - byte[] biomeData = groundUp ? new byte[256] : null; - if (groundUp) { - input.readBytes(biomeData); - } - - List nbtData = Arrays.asList(Type.NBT_ARRAY.read(input)); - - // Temp patch for plugins that sent wrong too big chunks TODO find the issue in LibsDisguise and PR it. - if (input.readableBytes() > 0) { - byte[] array = new byte[input.readableBytes()]; - input.readBytes(array); - if (Via.getManager().isDebug()) - ViaBackwards.getPlatform().getLogger().warning("Found " + array.length + " more bytes than expected while reading the chunk"); - } - - return new Chunk1_10(chunkX, chunkZ, groundUp, primaryBitmask, sections, biomeData, nbtData); - } - - @Override - public void write(ByteBuf output, ClientWorld world, Chunk chunk) throws Exception { - output.writeInt(chunk.getX()); - output.writeInt(chunk.getZ()); - - output.writeBoolean(chunk.isGroundUp()); - Type.VAR_INT.write(output, chunk.getBitmask()); - - ByteBuf buf = Unpooled.buffer(); - for (int i = 0; i < 16; i++) { - ChunkSection section = chunk.getSections()[i]; - if (section == null) continue; // Section not set - section.writeBlocks(buf); - section.writeBlockLight(buf); - - if (!section.hasSkyLight()) continue; // No sky light, we're done here. - section.writeSkyLight(buf); - - } - buf.readerIndex(0); - Type.VAR_INT.write(output, buf.readableBytes() + (chunk.isBiomeData() ? 256 : 0)); - output.writeBytes(buf); - buf.release(); // release buffer - - // Write biome data - if (chunk.isBiomeData()) { - output.writeBytes(chunk.getBiomeData()); - } - - Type.NBT_ARRAY.write(output, chunk.getBlockEntities().toArray(new CompoundTag[0])); - } - - @Override - public Class getBaseClass() { - return BaseChunkType.class; - } -} diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_9_4to1_10/chunks/ChunkSection1_10.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_9_4to1_10/chunks/ChunkSection1_10.java deleted file mode 100644 index 30fed344..00000000 --- a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_9_4to1_10/chunks/ChunkSection1_10.java +++ /dev/null @@ -1,306 +0,0 @@ -/* - * 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.protocol.protocol1_9_4to1_10.chunks; - -import com.google.common.collect.Lists; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import lombok.Getter; -import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; -import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray; -import us.myles.ViaVersion.api.type.Type; - -import java.util.List; - -/** - * From the ViaVersion code {@link us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.chunks.ChunkSection1_9_1_2} - */ -public class ChunkSection1_10 implements ChunkSection { - /** - * Size (dimensions) of blocks in a chunks section. - */ - public static final int SIZE = 16 * 16 * 16; // width * depth * height - /** - * Length of the sky and block light nibble arrays. - */ - public static final int LIGHT_LENGTH = 16 * 16 * 16 / 2; // size * size * size / 2 (nibble bit count) - /** - * Length of the block data array. - */ - @Getter - private final List palette = Lists.newArrayList(); - private final int[] blocks; - private final NibbleArray blockLight; - private NibbleArray skyLight; - - public ChunkSection1_10() { - this.blocks = new int[SIZE]; - this.blockLight = new NibbleArray(SIZE); - palette.add(0); // AIR - } - - /** - * Set a block in the chunks - * - * @param x Block X - * @param y Block Y - * @param z Block Z - * @param type The type of the block - * @param data The data value of the block - */ - public void setBlock(int x, int y, int z, int type, int data) { - setBlock(index(x, y, z), type, data); - } - - public int getBlockId(int x, int y, int z) { - int index = blocks[index(x, y, z)]; - return palette.get(index) >> 4; - } - - /** - * Set a block in the chunks based on the index - * - * @param idx Index - * @param type The type of the block - * @param data The data value of the block - */ - public void setBlock(int idx, int type, int data) { - int hash = type << 4 | (data & 0xF); - int index = palette.indexOf(hash); - if (index == -1) { - index = palette.size(); - palette.add(hash); - } - - blocks[idx] = index; - } - - /** - * Set the block light array - * - * @param data The value to set the block light to - */ - public void setBlockLight(byte[] data) { - blockLight.setHandle(data); - } - - /** - * Set the sky light array - * - * @param data The value to set the sky light to - */ - public void setSkyLight(byte[] data) { - if (data.length != LIGHT_LENGTH) throw new IllegalArgumentException("Data length != " + LIGHT_LENGTH); - this.skyLight = new NibbleArray(data); - } - - private int index(int x, int y, int z) { - return y << 8 | z << 4 | x; - } - - /** - * Read blocks from input stream. - * This reads all the block related data: - *
    - *
  • Block length/palette type
  • - *
  • Palette
  • - *
  • Block hashes/palette reference
  • - *
- * - * @param input The buffer to read from. - * @throws Exception If it fails to read - */ - public void readBlocks(ByteBuf input) throws Exception { - palette.clear(); - - // Reaad bits per block - int bitsPerBlock = input.readUnsignedByte(); - long maxEntryValue = (1L << bitsPerBlock) - 1; - - if (bitsPerBlock == 0) { - bitsPerBlock = 13; - } - if (bitsPerBlock < 4) { - bitsPerBlock = 4; - } - if (bitsPerBlock > 8) { - bitsPerBlock = 13; - } - int paletteLength = Type.VAR_INT.read(input); - // Read palette - for (int i = 0; i < paletteLength; i++) { - if (bitsPerBlock != 13) { - palette.add(Type.VAR_INT.read(input)); - } else { - Type.VAR_INT.read(input); - } - } - - // Read blocks - Long[] blockData = Type.LONG_ARRAY.read(input); - if (blockData.length > 0) { - for (int i = 0; i < blocks.length; i++) { - int bitIndex = i * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((i + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - int val; - if (startIndex == endIndex) { - val = (int) (blockData[startIndex] >>> startBitSubIndex & maxEntryValue); - } else { - int endBitSubIndex = 64 - startBitSubIndex; - val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue); - } - - if (bitsPerBlock == 13) { - int type = val >> 4; - int data = val & 0xF; - - setBlock(i, type, data); - } else { - blocks[i] = val; - } - } - } - } - - /** - * Read block light from buffer. - * - * @param input The buffer to read from - */ - public void readBlockLight(ByteBuf input) { - byte[] handle = new byte[LIGHT_LENGTH]; - input.readBytes(handle); - blockLight.setHandle(handle); - } - - /** - * Read sky light from buffer. - * Note: Only sent in overworld! - * - * @param input The buffer to read from - */ - public void readSkyLight(ByteBuf input) { - byte[] handle = new byte[LIGHT_LENGTH]; - input.readBytes(handle); - if (skyLight != null) { - skyLight.setHandle(handle); - return; - } - - this.skyLight = new NibbleArray(handle); - } - - /** - * Write the blocks to a buffer. - * - * @param output The buffer to write to. - * @throws Exception Throws if it failed to write. - */ - public void writeBlocks(ByteBuf output) throws Exception { - // Write bits per block - int bitsPerBlock = 4; - while (palette.size() > 1 << bitsPerBlock) { - bitsPerBlock += 1; - } - long maxEntryValue = (1L << bitsPerBlock) - 1; - output.writeByte(bitsPerBlock); - - // Write pallet (or not) - Type.VAR_INT.write(output, palette.size()); - for (int mappedId : palette) { - Type.VAR_INT.write(output, mappedId); - } - - int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0); - Type.VAR_INT.write(output, length); - long[] data = new long[length]; - for (int index = 0; index < blocks.length; index++) { - int value = blocks[index]; - int bitIndex = index * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; - if (startIndex != endIndex) { - int endBitSubIndex = 64 - startBitSubIndex; - data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; - } - } - for (long l : data) { - Type.LONG.write(output, l); - } - } - - /** - * Write the block light to a buffer - * - * @param output The buffer to write to - */ - public void writeBlockLight(ByteBuf output) { - output.writeBytes(blockLight.getHandle()); - } - - /** - * Write the sky light to a buffer - * - * @param output The buffer to write to - */ - public void writeSkyLight(ByteBuf output) { - output.writeBytes(skyLight.getHandle()); - } - - /** - * Check if sky light is present - * - * @return True if skylight is present - */ - public boolean hasSkyLight() { - return skyLight != null; - } - - /** - * Get expected size of this chunks section. - * - * @return Amount of bytes sent by this section - * @throws Exception If it failed to calculate bits properly - */ - public int getExpectedSize() throws Exception { - int bitsPerBlock = palette.size() > 255 ? 16 : 8; - int bytes = 1; // bits per block - bytes += paletteBytes(); // palette - bytes += countBytes(bitsPerBlock == 16 ? SIZE * 2 : SIZE); // block data length - bytes += (palette.size() > 255 ? 2 : 1) * SIZE; // block data - bytes += LIGHT_LENGTH; // block light - bytes += hasSkyLight() ? LIGHT_LENGTH : 0; // sky light - return bytes; - } - - private int paletteBytes() throws Exception { - // Count bytes used by pallet - int bytes = countBytes(palette.size()); - for (int mappedId : palette) { - bytes += countBytes(mappedId); - } - return bytes; - } - - private int countBytes(int value) throws Exception { - // Count amount of bytes that would be sent if the value were sent as a VarInt - ByteBuf buf = Unpooled.buffer(); - Type.VAR_INT.write(buf, value); - buf.readerIndex(0); - int bitCount = buf.readableBytes(); - buf.release(); - return bitCount; - } -} diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_9_4to1_10/packets/BlockItemPackets.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_9_4to1_10/packets/BlockItemPackets.java index 5255cb09..a8b52feb 100644 --- a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_9_4to1_10/packets/BlockItemPackets.java +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_9_4to1_10/packets/BlockItemPackets.java @@ -12,17 +12,18 @@ package nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.packets; import nl.matsv.viabackwards.api.rewriters.BlockItemRewriter; import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.Protocol1_9_4To1_10; -import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.chunks.Chunk1_10; -import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.chunks.Chunk1_10Type; -import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.chunks.ChunkSection1_10; import nl.matsv.viabackwards.utils.Block; import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.minecraft.item.Item; +import us.myles.ViaVersion.api.minecraft.metadata.Metadata; import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_9; import us.myles.ViaVersion.api.remapper.PacketHandler; import us.myles.ViaVersion.api.remapper.PacketRemapper; import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.packets.State; +import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks.Chunk1_9_3_4; +import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks.ChunkSection1_9_3_4; +import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.types.Chunk1_9_3_4Type; import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; public class BlockItemPackets extends BlockItemRewriter { @@ -166,20 +167,21 @@ public class BlockItemPackets extends BlockItemRewriter { public void handle(PacketWrapper wrapper) throws Exception { ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); - Chunk1_10Type type = new Chunk1_10Type(clientWorld); - Chunk1_10 chunk = (Chunk1_10) wrapper.passthrough(type); + Chunk1_9_3_4Type type = new Chunk1_9_3_4Type(clientWorld); + Chunk1_9_3_4 chunk = (Chunk1_9_3_4) wrapper.passthrough(type); for (int i = 0; i < chunk.getSections().length; i++) { - ChunkSection1_10 section = chunk.getSections()[i]; + ChunkSection1_9_3_4 section = chunk.getSections()[i]; if (section == null) continue; for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { - int block = section.getBlockId(x, y, z); - if (containsBlock(block)) { - Block b = handleBlock(block); + int block = section.getBlock(x, y, z); + int btype = block >> 4; + if (containsBlock(btype)) { + Block b = handleBlock(btype, block & 15); // Type / data section.setBlock(x, y, z, b.getId(), b.getData()); } } @@ -235,8 +237,10 @@ public class BlockItemPackets extends BlockItemRewriter { } ); - /* Register Metadata */ - protocol.getEntityPackets().registerMetaRewriter((type, data) -> { + + protocol.getEntityPackets().registerMetaHandler().handle(e -> { + Metadata data = e.getData(); + if (data.getMetaType().equals(MetaType1_9.Slot)) // Is Item data.setValue(handleItemToClient((Item) data.getValue())); @@ -244,16 +248,6 @@ public class BlockItemPackets extends BlockItemRewriter { }); } - protected int handleBlockID(int idx) { - int type = idx >> 4; - - if (!containsBlock(type)) - return idx; - - Block b = handleBlock(type); - return (b.getId() << 4 | (b.getData() & 15)); - } - @Override protected void registerRewrites() { rewriteItem(255, new Item((short) 166, (byte) 1, (short) 0, getNamedTag("1.10 Structure Block"))); // Structure block only item since the structure block is in 1.9 diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_9_4to1_10/packets/EntityPackets.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_9_4to1_10/packets/EntityPackets.java index 75a67efc..2900878f 100644 --- a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_9_4to1_10/packets/EntityPackets.java +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_9_4to1_10/packets/EntityPackets.java @@ -10,12 +10,18 @@ package nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.packets; +import nl.matsv.viabackwards.ViaBackwards; import nl.matsv.viabackwards.api.entities.AbstractEntityType; import nl.matsv.viabackwards.api.entities.EntityType1_10; +import nl.matsv.viabackwards.api.entities.EntityType1_11; import nl.matsv.viabackwards.api.exceptions.RemovedValueException; import nl.matsv.viabackwards.api.rewriters.EntityRewriter; +import nl.matsv.viabackwards.api.storage.EntityData; +import nl.matsv.viabackwards.api.v2.MetaStorage; import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.Protocol1_9_4To1_10; import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.minecraft.metadata.Metadata; import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_9; import us.myles.ViaVersion.api.remapper.PacketHandler; import us.myles.ViaVersion.api.remapper.PacketRemapper; @@ -24,7 +30,10 @@ 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 java.util.Optional; + import static nl.matsv.viabackwards.api.entities.EntityType1_10.EntityType; +import static nl.matsv.viabackwards.api.entities.EntityType1_11.getTypeFromId; public class EntityPackets extends EntityRewriter { @@ -38,6 +47,12 @@ public class EntityPackets extends EntityRewriter { map(Type.VAR_INT); // 0 - Entity id map(Type.UUID); // 1 - UUID map(Type.BYTE); // 2 - Type + map(Type.DOUBLE); // 3 - x + map(Type.DOUBLE); // 4 - y + map(Type.DOUBLE); // 5 - z + map(Type.BYTE); // 6 - Pitch + map(Type.BYTE); // 7 - Yaw + map(Type.INT); // 8 - data // Track Entity handler(new PacketHandler() { @@ -46,10 +61,31 @@ public class EntityPackets extends EntityRewriter { addTrackedEntity( wrapper.user(), wrapper.get(Type.VAR_INT, 0), - EntityType1_10.getTypeFromId(wrapper.get(Type.BYTE, 0), true) + getTypeFromId(wrapper.get(Type.BYTE, 0), true) ); } }); + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + Optional type = EntityType1_11.ObjectType.findById(wrapper.get(Type.BYTE, 0)); + + if (type.isPresent()) { + Optional optEntDat = getObjectData(type.get()); + if (optEntDat.isPresent()) { + EntityData data = optEntDat.get(); + wrapper.set(Type.BYTE, 0, ((Integer) data.getReplacementId()).byteValue()); + if (data.getObjectData() != -1) + wrapper.set(Type.INT, 0, data.getObjectData()); + } + } else { + if (Via.getManager().isDebug()) { + ViaBackwards.getPlatform().getLogger().warning("Could not find Entity Type" + wrapper.get(Type.BYTE, 0)); + } + } + } + }); } }); @@ -124,38 +160,37 @@ public class EntityPackets extends EntityRewriter { } }); - // Rewrite entity ids + // Rewrite entity type / metadata 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; + MetaStorage storage = new MetaStorage(wrapper.get(Types1_9.METADATA_LIST, 0)); + handleMeta( + wrapper.user(), + wrapper.get(Type.VAR_INT, 0), + storage + ); - wrapper.set(Type.UNSIGNED_BYTE, 0, newType); - } - }); + Optional optEntDat = getEntityData(type); + if (optEntDat.isPresent()) { + EntityData data = optEntDat.get(); + wrapper.set(Type.UNSIGNED_BYTE, 0, ((Integer) data.getReplacementId()).shortValue()); + if (data.hasBaseMeta()) + data.getDefaultMeta().handle(storage); + } - // Rewrite metadata - handler(new PacketHandler() { - @Override - public void handle(PacketWrapper wrapper) throws Exception { + // Rewrite Metadata wrapper.set( Types1_9.METADATA_LIST, 0, - handleMeta( - wrapper.user(), - wrapper.get(Type.VAR_INT, 0), - wrapper.get(Types1_9.METADATA_LIST, 0) - ) + storage.getMetaDataList() ); } }); + } }); @@ -260,8 +295,8 @@ public class EntityPackets extends EntityRewriter { handleMeta( wrapper.user(), wrapper.get(Type.VAR_INT, 0), - wrapper.get(Types1_9.METADATA_LIST, 0) - ) + new MetaStorage(wrapper.get(Types1_9.METADATA_LIST, 0)) + ).getMetaDataList() ); } }); @@ -300,8 +335,8 @@ public class EntityPackets extends EntityRewriter { handleMeta( wrapper.user(), wrapper.get(Type.VAR_INT, 0), - wrapper.get(Types1_9.METADATA_LIST, 0) - ) + new MetaStorage(wrapper.get(Types1_9.METADATA_LIST, 0)) + ).getMetaDataList() ); } }); @@ -311,50 +346,50 @@ public class EntityPackets extends EntityRewriter { @Override protected void registerRewrites() { - rewriteEntityType(EntityType.POLAR_BEAR, 91); // Replace polar bear with sheep + regEntType(EntityType.POLAR_BEAR, EntityType.SHEEP); - // Handle Polar bear - registerMetaRewriter((entityType, data) -> { // Change the sheep color when the polar bear is standing up - if (!entityType.equals(EntityType.POLAR_BEAR)) - return data; + // Change the sheep color when the polar bear is standing up (index 13 -> Standing up) + registerMetaHandler().filter(EntityType.POLAR_BEAR, 13).handle((e -> { + Metadata data = e.getData(); + boolean b = (boolean) data.getValue(); - if (data.getId() == 13) { // is boolean - boolean b = (boolean) data.getValue(); + data.setMetaType(MetaType1_9.Byte); + data.setValue(b ? (byte) (14 & 0x0F) : (byte) (0)); - data.setId(13); - data.setMetaType(MetaType1_9.Byte); - data.setValue(b ? (byte) (14 & 0x0F) : 0); - } return data; - }); + })); - // Handle Husk - 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) + // Handle husk (index 13 -> Zombie Type) + registerMetaHandler().filter(EntityType.ZOMBIE, 13).handle(e -> { + Metadata data = e.getData(); + + if ((int) data.getValue() == 6) // Is type Husk data.setValue(0); + return data; }); - // Handle stray - registerMetaRewriter((entityType, data) -> { // Change stray- to normal skeleton - if (!entityType.equals(EntityType.SKELETON)) - return data; + // Handle Stray (index 12 -> Skeleton Type) + registerMetaHandler().filter(EntityType.SKELETON, 12).handle(e -> { + Metadata data = e.getData(); + + if ((int) data.getValue() == 2) + data.setValue(0); // Change to default skeleton - if (data.getId() == 12 && data.getMetaType().getTypeID() == 1 && (int) data.getValue() == 2) - data.setValue(0); return data; }); - // Handle the missing NoGravity tag - registerMetaRewriter((type, m) -> { - if (m.getId() == 5) + // Handle the missing NoGravity tag for every metadata + registerMetaHandler().handle(e -> { + Metadata data = e.getData(); + + if (data.getId() == 5) throw new RemovedValueException(); - else if (m.getId() >= 5) - m.setId(m.getId() - 1); - return m; + else if (data.getId() >= 5) + data.setId(data.getId() - 1); + + return data; }); } } diff --git a/pom.xml b/pom.xml index 73ea015c..7df391b0 100644 --- a/pom.xml +++ b/pom.xml @@ -65,7 +65,7 @@ us.myles viaversion - 1.0.3 + 1.0.5-1_12pre5 provided diff --git a/sponge/src/main/java/nl/matsv/viabackwards/SpongePlugin.java b/sponge/src/main/java/nl/matsv/viabackwards/SpongePlugin.java index 3c5b2a60..2ac7ea7e 100644 --- a/sponge/src/main/java/nl/matsv/viabackwards/SpongePlugin.java +++ b/sponge/src/main/java/nl/matsv/viabackwards/SpongePlugin.java @@ -46,4 +46,10 @@ public class SpongePlugin implements ViaBackwardsPlatform { public Logger getLogger() { return logger; } + + // TODO check how to for sponge, site was offline + @Override + public void disable() { + + } }