diff --git a/all/pom.xml b/all/pom.xml
index 30ef99e8..017b8776 100644
--- a/all/pom.xml
+++ b/all/pom.xml
@@ -15,7 +15,7 @@
viabackwards-parent
nl.matsv
- 3.0.0-SNAPSHOT
+ 3.0.0-19w11b
4.0.0
diff --git a/bukkit/pom.xml b/bukkit/pom.xml
index 8f98e030..94684dba 100644
--- a/bukkit/pom.xml
+++ b/bukkit/pom.xml
@@ -15,7 +15,7 @@
viabackwards-parent
nl.matsv
- 3.0.0-SNAPSHOT
+ 3.0.0-19w11b
4.0.0
diff --git a/bungee/pom.xml b/bungee/pom.xml
index d8f73ff1..1120c19a 100644
--- a/bungee/pom.xml
+++ b/bungee/pom.xml
@@ -15,7 +15,7 @@
viabackwards-parent
nl.matsv
- 3.0.0-SNAPSHOT
+ 3.0.0-19w11b
4.0.0
diff --git a/core/pom.xml b/core/pom.xml
index f6a7e408..91d26cd3 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -15,7 +15,7 @@
viabackwards-parent
nl.matsv
- 3.0.0-SNAPSHOT
+ 3.0.0-19w11b
4.0.0
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 4ce67b3e..4228b5a1 100644
--- a/core/src/main/java/nl/matsv/viabackwards/api/ViaBackwardsPlatform.java
+++ b/core/src/main/java/nl/matsv/viabackwards/api/ViaBackwardsPlatform.java
@@ -18,6 +18,7 @@ import nl.matsv.viabackwards.protocol.protocol1_12_1to1_12_2.Protocol1_12_1To1_1
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.Protocol1_12_2To1_13;
import nl.matsv.viabackwards.protocol.protocol1_12to1_12_1.Protocol1_12To1_12_1;
import nl.matsv.viabackwards.protocol.protocol1_13_1to1_13_2.Protocol1_13_1To1_13_2;
+import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.Protocol1_13_2To1_14;
import nl.matsv.viabackwards.protocol.protocol1_13to1_13_1.Protocol1_13To1_13_1;
import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.Protocol1_9_4To1_10;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
@@ -44,6 +45,7 @@ public interface ViaBackwardsPlatform {
ProtocolRegistry.registerProtocol(new Protocol1_12_2To1_13(), Collections.singletonList(ProtocolVersion.v1_12_2.getId()), ProtocolVersion.v1_13.getId());
ProtocolRegistry.registerProtocol(new Protocol1_13To1_13_1(), Collections.singletonList(ProtocolVersion.v1_13.getId()), ProtocolVersion.v1_13_1.getId());
ProtocolRegistry.registerProtocol(new Protocol1_13_1To1_13_2(), Collections.singletonList(ProtocolVersion.v1_13_1.getId()), ProtocolVersion.v1_13_2.getId());
+ ProtocolRegistry.registerProtocol(new Protocol1_13_2To1_14(), Collections.singletonList(ProtocolVersion.v1_13_2.getId()), ProtocolVersion.v1_14.getId());
}
}
diff --git a/core/src/main/java/nl/matsv/viabackwards/api/entities/types/EntityType1_14.java b/core/src/main/java/nl/matsv/viabackwards/api/entities/types/EntityType1_14.java
new file mode 100644
index 00000000..df97e3a1
--- /dev/null
+++ b/core/src/main/java/nl/matsv/viabackwards/api/entities/types/EntityType1_14.java
@@ -0,0 +1,257 @@
+package nl.matsv.viabackwards.api.entities.types;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import us.myles.ViaVersion.api.Via;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+public class EntityType1_14 {
+ public static EntityType1_14.EntityType getTypeFromId(int typeID) {
+ Optional type = EntityType.findById(typeID);
+
+ if (!type.isPresent()) {
+ Via.getPlatform().getLogger().severe("Could not find type id " + typeID);
+ return EntityType.ENTITY; // Fall back to the basic ENTITY
+ }
+
+ return type.get();
+ }
+
+ @AllArgsConstructor
+ @Getter
+ public enum EntityType implements AbstractEntityType {
+ // Auto generated
+
+ ENTITY(-1),
+
+ AREA_EFFECT_CLOUD(0, ENTITY),
+ ENDER_CRYSTAL(17, ENTITY),
+ EVOCATION_FANGS(21, ENTITY),
+ XP_ORB(23, ENTITY),
+ EYE_OF_ENDER_SIGNAL(24, ENTITY),
+ FALLING_BLOCK(25, ENTITY),
+ FIREWORKS_ROCKET(26, ENTITY),
+ ITEM(34, ENTITY),
+ LLAMA_SPIT(39, ENTITY),
+ TNT(58, ENTITY),
+ SHULKER_BULLET(63, ENTITY),
+ FISHING_BOBBER(101, ENTITY),
+
+ LIVINGENTITY(-1, ENTITY),
+ ARMOR_STAND(1, LIVINGENTITY),
+ PLAYER(100, LIVINGENTITY),
+
+ ABSTRACT_INSENTIENT(-1, LIVINGENTITY),
+ ENDER_DRAGON(18, ABSTRACT_INSENTIENT),
+
+ ABSTRACT_CREATURE(-1, ABSTRACT_INSENTIENT),
+
+ ABSTRACT_AGEABLE(-1, ABSTRACT_CREATURE),
+ VILLAGER(84, ABSTRACT_AGEABLE),
+ WANDERING_TRADER(88, ABSTRACT_AGEABLE),
+
+ // Animals
+ ABSTRACT_ANIMAL(-1, ABSTRACT_AGEABLE),
+ DOLPHIN(13, ABSTRACT_INSENTIENT),
+ CHICKEN(8, ABSTRACT_ANIMAL),
+ COW(10, ABSTRACT_ANIMAL),
+ MOOSHROOM(49, COW),
+ PIG(54, ABSTRACT_ANIMAL),
+ POLAR_BEAR(57, ABSTRACT_ANIMAL),
+ RABBIT(59, ABSTRACT_ANIMAL),
+ SHEEP(61, ABSTRACT_ANIMAL),
+ TURTLE(77, ABSTRACT_ANIMAL),
+ FOX(27, ABSTRACT_ANIMAL),
+
+ ABSTRACT_TAMEABLE_ANIMAL(-1, ABSTRACT_ANIMAL),
+ CAT(6, ABSTRACT_TAMEABLE_ANIMAL),
+ OCELOT(50, ABSTRACT_TAMEABLE_ANIMAL),
+ WOLF(93, ABSTRACT_TAMEABLE_ANIMAL),
+
+ ABSTRACT_PARROT(-1, ABSTRACT_TAMEABLE_ANIMAL),
+ PARROT(53, ABSTRACT_PARROT),
+
+ // Horses
+ ABSTRACT_HORSE(-1, ABSTRACT_ANIMAL),
+ CHESTED_HORSE(-1, ABSTRACT_HORSE),
+ DONKEY(12, CHESTED_HORSE),
+ MULE(48, CHESTED_HORSE),
+ LLAMA(38, CHESTED_HORSE),
+ TRADER_LLAMA(75, CHESTED_HORSE),
+ HORSE(31, ABSTRACT_HORSE),
+ SKELETON_HORSE(66, ABSTRACT_HORSE),
+ ZOMBIE_HORSE(95, ABSTRACT_HORSE),
+
+ // Golem
+ ABSTRACT_GOLEM(-1, ABSTRACT_CREATURE),
+ SNOWMAN(69, ABSTRACT_GOLEM),
+ VILLAGER_GOLEM(85, ABSTRACT_GOLEM),
+ SHULKER(62, ABSTRACT_GOLEM),
+
+ // Fish
+ ABSTRACT_FISHES(-1, ABSTRACT_CREATURE),
+ COD(9, ABSTRACT_FISHES),
+ PUFFER_FISH(55, ABSTRACT_FISHES),
+ SALMON_MOB(60, ABSTRACT_FISHES),
+ TROPICAL_FISH(76, ABSTRACT_FISHES),
+
+ // Monsters
+ ABSTRACT_MONSTER(-1, ABSTRACT_CREATURE),
+ BLAZE(4, ABSTRACT_MONSTER),
+ CREEPER(11, ABSTRACT_MONSTER),
+ ENDERMITE(20, ABSTRACT_MONSTER),
+ ENDERMAN(19, ABSTRACT_MONSTER),
+ GIANT(29, ABSTRACT_MONSTER),
+ SILVERFISH(64, ABSTRACT_MONSTER),
+ VEX(83, ABSTRACT_MONSTER),
+ WITCH(89, ABSTRACT_MONSTER),
+ WITHER(90, ABSTRACT_MONSTER),
+ RAVAGER(98, ABSTRACT_MONSTER),
+
+ // Illagers
+ ABSTRACT_ILLAGER_BASE(-1, ABSTRACT_MONSTER),
+ ABSTRACT_EVO_ILLU_ILLAGER(-1, ABSTRACT_ILLAGER_BASE),
+ EVOCATION_ILLAGER(22, ABSTRACT_EVO_ILLU_ILLAGER),
+ ILLUSION_ILLAGER(33, ABSTRACT_EVO_ILLU_ILLAGER),
+ VINDICATION_ILLAGER(86, ABSTRACT_ILLAGER_BASE),
+ PILLAGER(87, ABSTRACT_ILLAGER_BASE),
+
+ // Skeletons
+ ABSTRACT_SKELETON(-1, ABSTRACT_MONSTER),
+ SKELETON(65, ABSTRACT_SKELETON),
+ STRAY(74, ABSTRACT_SKELETON),
+ WITHER_SKELETON(91, ABSTRACT_SKELETON),
+
+ // Guardians
+ GUARDIAN(30, ABSTRACT_MONSTER),
+ ELDER_GUARDIAN(16, GUARDIAN),
+
+ // Spiders
+ SPIDER(72, ABSTRACT_MONSTER),
+ CAVE_SPIDER(7, SPIDER),
+
+ // Zombies - META CHECKED
+ ZOMBIE(94, ABSTRACT_MONSTER),
+ DROWNED(15, ZOMBIE),
+ HUSK(32, ZOMBIE),
+ ZOMBIE_PIGMAN(56, ZOMBIE),
+ ZOMBIE_VILLAGER(96, ZOMBIE),
+
+ // Flying entities
+ ABSTRACT_FLYING(-1, ABSTRACT_INSENTIENT),
+ GHAST(28, ABSTRACT_FLYING),
+ PHANTOM(97, ABSTRACT_FLYING),
+
+ ABSTRACT_AMBIENT(-1, ABSTRACT_INSENTIENT),
+ BAT(3, ABSTRACT_AMBIENT),
+
+ ABSTRACT_WATERMOB(-1, ABSTRACT_INSENTIENT),
+ SQUID(73, ABSTRACT_WATERMOB),
+
+ // Slimes
+ SLIME(67, ABSTRACT_INSENTIENT),
+ MAGMA_CUBE(40, SLIME),
+
+ // Hangable objects
+ ABSTRACT_HANGING(-1, ENTITY),
+ LEASH_KNOT(37, ABSTRACT_HANGING),
+ ITEM_FRAME(35, ABSTRACT_HANGING),
+ PAINTING(51, ABSTRACT_HANGING),
+
+ ABSTRACT_LIGHTNING(-1, ENTITY),
+ LIGHTNING_BOLT(99, ABSTRACT_LIGHTNING),
+
+ // Arrows
+ ABSTRACT_ARROW(-1, ENTITY),
+ ARROW(2, ABSTRACT_ARROW),
+ SPECTRAL_ARROW(71, ABSTRACT_ARROW),
+ TRIDENT(82, ABSTRACT_ARROW),
+
+ // Fireballs
+ ABSTRACT_FIREBALL(-1, ENTITY),
+ DRAGON_FIREBALL(14, ABSTRACT_FIREBALL),
+ FIREBALL(36, ABSTRACT_FIREBALL),
+ SMALL_FIREBALL(68, ABSTRACT_FIREBALL),
+ WITHER_SKULL(92, ABSTRACT_FIREBALL),
+
+ // Projectiles
+ PROJECTILE_ABSTRACT(-1, ENTITY),
+ SNOWBALL(70, PROJECTILE_ABSTRACT),
+ ENDER_PEARL(79, PROJECTILE_ABSTRACT),
+ EGG(78, PROJECTILE_ABSTRACT),
+ POTION(81, PROJECTILE_ABSTRACT),
+ XP_BOTTLE(80, PROJECTILE_ABSTRACT),
+
+ // Vehicles
+ MINECART_ABSTRACT(-1, ENTITY),
+ CHESTED_MINECART_ABSTRACT(-1, MINECART_ABSTRACT),
+ CHEST_MINECART(42, CHESTED_MINECART_ABSTRACT),
+ HOPPER_MINECART(45, CHESTED_MINECART_ABSTRACT),
+ MINECART(41, MINECART_ABSTRACT),
+ FURNACE_MINECART(44, MINECART_ABSTRACT),
+ COMMANDBLOCK_MINECART(43, MINECART_ABSTRACT),
+ TNT_MINECART(47, MINECART_ABSTRACT),
+ SPAWNER_MINECART(46, MINECART_ABSTRACT),
+ BOAT(5, ENTITY),
+ ;
+
+ private final int id;
+ private final EntityType parent;
+
+ EntityType(int id) {
+ this.id = id;
+ this.parent = null;
+ }
+
+ public static java.util.Optional findById(int id) {
+ if (id == -1) // Check if this is called
+ return java.util.Optional.empty();
+
+ for (EntityType ent : EntityType.values())
+ if (ent.getId() == id)
+ return java.util.Optional.of(ent);
+
+ return java.util.Optional.empty();
+ }
+
+ public boolean is(AbstractEntityType... types) {
+ for (AbstractEntityType type : types)
+ if (is(type))
+ return true;
+ return false;
+ }
+
+ public boolean is(AbstractEntityType type) {
+ return this == type;
+ }
+
+ public boolean isOrHasParent(AbstractEntityType type) {
+ EntityType parent = this;
+
+ do {
+ if (parent == 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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/Protocol1_13_2To1_14.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/Protocol1_13_2To1_14.java
new file mode 100644
index 00000000..b37a2a7a
--- /dev/null
+++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/Protocol1_13_2To1_14.java
@@ -0,0 +1,225 @@
+package nl.matsv.viabackwards.protocol.protocol1_13_2to1_14;
+
+import nl.matsv.viabackwards.ViaBackwards;
+import nl.matsv.viabackwards.api.BackwardsProtocol;
+import nl.matsv.viabackwards.api.entities.storage.EntityTracker;
+import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.data.BackwardsMappings;
+import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.data.SoundMapping;
+import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.packets.BlockItemPackets1_14;
+import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.packets.EntityPackets1_14;
+import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.packets.PlayerPackets1_14;
+import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.packets.SoundPackets1_14;
+import us.myles.ViaVersion.api.PacketWrapper;
+import us.myles.ViaVersion.api.data.UserConnection;
+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_3to1_9_1_2.storage.ClientWorld;
+
+public class Protocol1_13_2To1_14 extends BackwardsProtocol {
+ public static BlockItemPackets1_14 blockItem;
+ public static EntityPackets1_14 entity;
+
+ static {
+ BackwardsMappings.init();
+ SoundMapping.init();
+ }
+
+ @Override
+ protected void registerPackets() {
+ blockItem = new BlockItemPackets1_14();
+ blockItem.register(this);
+ entity = new EntityPackets1_14();
+ entity.register(this);
+ new PlayerPackets1_14().register(this);
+ new SoundPackets1_14().register(this);
+
+ out(State.PLAY, 0x2E, 0x2D); // c
+ out(State.PLAY, 0x2F, 0x2E); // c
+ out(State.PLAY, 0x30, 0x2F); // c
+ out(State.PLAY, 0x31, 0x30); // c
+ out(State.PLAY, 0x32, 0x31); // c
+ out(State.PLAY, 0x33, 0x32); // c
+ // Entity sound
+ out(State.PLAY, 0x4E, -1, new PacketRemapper() {
+ @Override
+ public void registerMap() { // c
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper packetWrapper) throws Exception {
+ packetWrapper.cancel(); // todo
+ }
+ });
+ }
+ });
+
+ //Unknown packet added in 19w11a - 0x02
+ registerIncoming(State.PLAY, 0x03, 0x02); // r
+ registerIncoming(State.PLAY, 0x04, 0x03); // r
+ registerIncoming(State.PLAY, 0x05, 0x04); // r
+ registerIncoming(State.PLAY, 0x06, 0x05); // r
+ registerIncoming(State.PLAY, 0x07, 0x06); // r
+ registerIncoming(State.PLAY, 0x08, 0x07); // r
+
+ registerIncoming(State.PLAY, 0x0A, 0x09); // r
+ registerIncoming(State.PLAY, 0x0B, 0x0A); // r
+
+ registerIncoming(State.PLAY, 0x0D, 0x0C); // r
+ registerIncoming(State.PLAY, 0x0E, 0x0D); // r
+ //Unknown packet added in 19w11a - 0x0F
+ registerIncoming(State.PLAY, 0x10, 0x0E); // r
+ registerIncoming(State.PLAY, 0x11, 0x0F); // r
+ registerIncoming(State.PLAY, 0x12, 0x10); // r
+ registerIncoming(State.PLAY, 0x13, 0x11); // r
+ registerIncoming(State.PLAY, 0x14, 0x12); // r
+ registerIncoming(State.PLAY, 0x15, 0x13); // r
+ registerIncoming(State.PLAY, 0x16, 0x14); // r
+ registerIncoming(State.PLAY, 0x17, 0x15); // r
+ registerIncoming(State.PLAY, 0x18, 0x16); // r
+ registerIncoming(State.PLAY, 0x19, 0x17); // r
+
+ registerIncoming(State.PLAY, 0x1B, 0x19); // r
+ registerIncoming(State.PLAY, 0x1C, 0x1A); // r
+
+ registerIncoming(State.PLAY, 0x1E, 0x1C); // r
+ registerIncoming(State.PLAY, 0x1F, 0x1D); // r
+ registerIncoming(State.PLAY, 0x20, 0x1E); // r
+ registerIncoming(State.PLAY, 0x21, 0x1F); // r
+ registerIncoming(State.PLAY, 0x22, 0x20); // r
+ registerIncoming(State.PLAY, 0x23, 0x21); // r
+
+ registerIncoming(State.PLAY, 0x25, 0x23); // r
+
+ registerIncoming(State.PLAY, 0x29, 0x27); // r
+ registerIncoming(State.PLAY, 0x2A, 0x28); // r
+
+ registerIncoming(State.PLAY, 0x2C, 0x2A); // r
+
+ registerOutgoing(State.PLAY, 0x4F, 0x4E); // c
+ registerOutgoing(State.PLAY, 0x50, 0x4F); // c
+ registerOutgoing(State.PLAY, 0x51, 0x50); // c
+
+ registerOutgoing(State.PLAY, 0x52, 0x51, new PacketRemapper() { // c
+ @Override
+ public void registerMap() {
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ wrapper.passthrough(Type.BOOLEAN); // Reset/clear
+ int size = wrapper.passthrough(Type.VAR_INT); // Mapping size
+
+ for (int i = 0; i < size; i++) {
+ wrapper.passthrough(Type.STRING); // Identifier
+
+ // Parent
+ if (wrapper.passthrough(Type.BOOLEAN))
+ wrapper.passthrough(Type.STRING);
+
+ // Display data
+ if (wrapper.passthrough(Type.BOOLEAN)) {
+ wrapper.passthrough(Type.STRING); // Title
+ wrapper.passthrough(Type.STRING); // Description
+ blockItem.handleItemToClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Icon
+ wrapper.passthrough(Type.VAR_INT); // Frame type
+ int flags = wrapper.passthrough(Type.INT); // Flags
+ if ((flags & 1) != 0)
+ wrapper.passthrough(Type.STRING); // Background texture
+ wrapper.passthrough(Type.FLOAT); // X
+ wrapper.passthrough(Type.FLOAT); // Y
+ }
+
+ wrapper.passthrough(Type.STRING_ARRAY); // Criteria
+
+ int arrayLength = wrapper.passthrough(Type.VAR_INT);
+ for (int array = 0; array < arrayLength; array++) {
+ wrapper.passthrough(Type.STRING_ARRAY); // String array
+ }
+ }
+ }
+ });
+ }
+ });
+
+ registerOutgoing(State.PLAY, 0x53, 0x52); // c
+ registerOutgoing(State.PLAY, 0x54, 0x53); // c
+
+ // tags
+ registerOutgoing(State.PLAY, 0x56, 0x55, new PacketRemapper() {
+ @Override
+ public void registerMap() { // c
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ int blockTagsSize = wrapper.read(Type.VAR_INT);
+ wrapper.write(Type.VAR_INT, blockTagsSize); // block tags
+ for (int i = 0; i < blockTagsSize; i++) {
+ wrapper.passthrough(Type.STRING);
+ Integer[] blockIds = wrapper.passthrough(Type.VAR_INT_ARRAY);
+ for (int j = 0; j < blockIds.length; j++) {
+ blockIds[j] = getNewBlockStateId(blockIds[j]);
+ }
+ }
+ int itemTagsSize = wrapper.read(Type.VAR_INT);
+ wrapper.write(Type.VAR_INT, itemTagsSize); // item tags
+ for (int i = 0; i < itemTagsSize; i++) {
+ wrapper.passthrough(Type.STRING);
+ Integer[] itemIds = wrapper.passthrough(Type.VAR_INT_ARRAY);
+ for (int j = 0; j < itemIds.length; j++) {
+ itemIds[j] = /*BlockItemPackets1_14.getNewItemId TODO BLOCK IDS*/(itemIds[j]);
+ }
+ }
+ int fluidTagsSize = wrapper.passthrough(Type.VAR_INT); // fluid tags
+ for (int i = 0; i < fluidTagsSize; i++) {
+ wrapper.passthrough(Type.STRING);
+ wrapper.passthrough(Type.VAR_INT_ARRAY);
+ }
+ // Eat entity tags
+ int entityTagsSize = wrapper.read(Type.VAR_INT);
+ for (int i = 0; i < entityTagsSize; i++) {
+ wrapper.read(Type.STRING);
+ wrapper.read(Type.VAR_INT_ARRAY);
+ }
+ }
+ });
+ }
+ });
+
+
+ // Light update
+ out(State.PLAY, 0x57, -1, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper packetWrapper) throws Exception {
+ packetWrapper.cancel(); // todo
+ }
+ });
+ }
+ });
+ }
+
+ public static int getNewBlockStateId(int id) {
+ int newId = BackwardsMappings.blockMappings.getNewBlock(id);
+ if (newId == -1) {
+ ViaBackwards.getPlatform().getLogger().warning("Missing 1.14 block for 1.13.2 block " + id);
+ return 0;
+ }
+ return newId;
+ }
+
+ @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_13_2to1_14/data/BackwardsMappings.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/data/BackwardsMappings.java
new file mode 100644
index 00000000..aba75614
--- /dev/null
+++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/data/BackwardsMappings.java
@@ -0,0 +1,99 @@
+package nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.data;
+
+import nl.matsv.viabackwards.ViaBackwards;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData;
+import us.myles.ViaVersion.util.GsonUtil;
+import us.myles.viaversion.libs.gson.JsonElement;
+import us.myles.viaversion.libs.gson.JsonObject;
+import us.myles.viaversion.libs.gson.JsonPrimitive;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+import java.util.Map;
+
+public class BackwardsMappings {
+ public static BlockMappings blockMappings;
+
+ public static void init() {
+ JsonObject mapping1_13_2 = MappingData.loadData("mapping-1.13.2.json");
+ JsonObject mapping1_14 = MappingData.loadData("mapping-1.14.json");
+ JsonObject mapping1_13_2to1_14 = loadData("mapping-1.13.2to1.14.json");
+
+ ViaBackwards.getPlatform().getLogger().info("Loading block mapping...");
+ blockMappings = new BlockMappingsShortArray(mapping1_14.getAsJsonObject("blockstates"), mapping1_13_2.getAsJsonObject("blockstates"), mapping1_13_2to1_14.getAsJsonObject("blockstates"));
+ }
+
+
+ private static void mapIdentifiers(short[] output, JsonObject newIdentifiers, JsonObject oldIdentifiers, JsonObject mapping) {
+ for (Map.Entry entry : newIdentifiers.entrySet()) {
+ String key = entry.getValue().getAsString();
+ Map.Entry value = findValue(oldIdentifiers, key);
+ if (value == null) {
+ JsonPrimitive replacement = mapping.getAsJsonPrimitive(key);
+ if (replacement == null && key.contains("[")) {
+ replacement = mapping.getAsJsonPrimitive(key.substring(0, key.indexOf('[')));
+ }
+ if (replacement != null) {
+ if (replacement.getAsString().startsWith("id:")) {
+ String id = replacement.getAsString().replace("id:", "");
+ value = findValue(oldIdentifiers, oldIdentifiers.getAsJsonPrimitive(id).getAsString());
+ } else {
+ value = findValue(oldIdentifiers, replacement.getAsString());
+ }
+ }
+ if (value == null) {
+ if (!Via.getConfig().isSuppress1_13ConversionErrors() || Via.getManager().isDebug()) {
+ if (replacement != null) {
+ ViaBackwards.getPlatform().getLogger().warning("No key for " + entry.getValue() + "/" + replacement.getAsString() + " :( ");
+ } else {
+ ViaBackwards.getPlatform().getLogger().warning("No key for " + entry.getValue() + " :( ");
+ }
+ }
+ continue;
+ }
+ }
+ output[Integer.parseInt(entry.getKey())] = Short.parseShort(value.getKey());
+ }
+ }
+
+
+ private static Map.Entry findValue(JsonObject object, String needle) {
+ for (Map.Entry entry : object.entrySet()) {
+ String value = entry.getValue().getAsString();
+ if (value.equals(needle)) {
+ return entry;
+ }
+ }
+ return null;
+ }
+
+ public static JsonObject loadData(String name) {
+ try (InputStreamReader reader = new InputStreamReader(BackwardsMappings.class.getClassLoader().getResourceAsStream("assets/viabackwards/data/" + name))) {
+ return GsonUtil.getGson().fromJson(reader, JsonObject.class);
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+
+ return null;
+ }
+
+ public interface BlockMappings {
+ int getNewBlock(int old);
+ }
+
+ private static class BlockMappingsShortArray implements BlockMappings {
+ private short[] oldToNew = new short[11258 + 1];
+
+ private BlockMappingsShortArray(JsonObject newIdentifiers, JsonObject oldIdentifiers, JsonObject mapping) {
+ Arrays.fill(oldToNew, (short) -1);
+ mapIdentifiers(oldToNew, newIdentifiers, oldIdentifiers, mapping);
+ }
+
+ @Override
+ public int getNewBlock(int old) {
+ return old >= 0 && old < oldToNew.length ? oldToNew[old] : -1;
+ }
+ }
+}
diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/data/EntityTypeMapping.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/data/EntityTypeMapping.java
new file mode 100644
index 00000000..98b02f20
--- /dev/null
+++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/data/EntityTypeMapping.java
@@ -0,0 +1,47 @@
+package nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.data;
+
+
+import us.myles.ViaVersion.api.entities.Entity1_13Types;
+import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.EntityTypeRewriter;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+public class EntityTypeMapping {
+ private static Map entityTypes = new HashMap<>();
+ private static Map oldEntityToOldObject = new HashMap<>();
+
+ static {
+ try {
+ Field field = EntityTypeRewriter.class.getDeclaredField("entityTypes");
+ field.setAccessible(true);
+ Map entityTypes = (Map) field.get(null);
+ entityTypes.forEach((type1_12, type1_13) -> EntityTypeMapping.entityTypes.put(type1_13, type1_12));
+ } catch (NoSuchFieldException | IllegalAccessException ex) {
+ ex.printStackTrace();
+ }
+ for (Map.Entry newToOld : entityTypes.entrySet()) {
+ Entity1_13Types.EntityType type1_13 = Entity1_13Types.getTypeFromId(newToOld.getValue(), false);
+ Entity1_13Types.ObjectTypes object1_13 = null;
+ for (Entity1_13Types.ObjectTypes objectType : Entity1_13Types.ObjectTypes.values()) {
+ if (objectType.getType() == type1_13) {
+ object1_13 = objectType;
+ break;
+ }
+ }
+ if (object1_13 != null) {
+ oldEntityToOldObject.put(type1_13.getId(), object1_13.getId());
+ }
+ }
+ }
+
+ public static Optional getOldId(int type1_14) {
+ return Optional.ofNullable(entityTypes.get(type1_14));
+ }
+
+ public static Optional getObjectId(int type1_13) {
+ return Optional.ofNullable(oldEntityToOldObject.get(type1_13));
+ }
+}
diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/data/SoundMapping.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/data/SoundMapping.java
new file mode 100644
index 00000000..826d070d
--- /dev/null
+++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/data/SoundMapping.java
@@ -0,0 +1,44 @@
+package nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.data;
+
+import us.myles.viaversion.libs.gson.JsonArray;
+import us.myles.viaversion.libs.gson.JsonElement;
+import us.myles.viaversion.libs.gson.JsonObject;
+
+import java.util.Arrays;
+
+import static us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData.loadData;
+
+public class SoundMapping {
+ private static short[] sounds = new short[789];
+
+ public static void init() {
+ JsonObject mapping1_13_2 = loadData("mapping-1.13.2.json");
+ JsonObject mapping1_14 = loadData("mapping-1.14.json");
+
+ Arrays.fill(sounds, (short) -1);
+ mapIdentifiers(sounds, mapping1_14.getAsJsonArray("sounds"), mapping1_13_2.getAsJsonArray("sounds"));
+ }
+
+ private static void mapIdentifiers(short[] output, JsonArray oldIdentifiers, JsonArray newIdentifiers) {
+ for (int i = 0; i < oldIdentifiers.size(); i++) {
+ JsonElement v = oldIdentifiers.get(i);
+ Integer index = findIndex(newIdentifiers, v.getAsString());
+ if (index == null) continue; //There will be missing sounds, since we are goind backwards
+ output[i] = index.shortValue();
+ }
+ }
+
+ private static Integer findIndex(JsonArray array, String value) {
+ for (int i = 0; i < array.size(); i++) {
+ JsonElement v = array.get(i);
+ if (v.getAsString().equals(value)) {
+ return i;
+ }
+ }
+ return null;
+ }
+
+ public static int getOldSound(int newSound) {
+ return newSound >= sounds.length ? -1 : sounds[newSound];
+ }
+}
diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/BlockItemPackets1_14.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/BlockItemPackets1_14.java
new file mode 100644
index 00000000..c5d7b9fa
--- /dev/null
+++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/BlockItemPackets1_14.java
@@ -0,0 +1,604 @@
+package nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.packets;
+
+import com.google.common.collect.ImmutableSet;
+import nl.matsv.viabackwards.ViaBackwards;
+import nl.matsv.viabackwards.api.rewriters.BlockItemRewriter;
+import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.Protocol1_13_2To1_14;
+import us.myles.ViaVersion.api.PacketWrapper;
+import us.myles.ViaVersion.api.minecraft.BlockChangeRecord;
+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.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;
+import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ChatRewriter;
+import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.types.Chunk1_13Type;
+import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.Protocol1_14To1_13_2;
+import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData;
+import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.types.Chunk1_14Type;
+import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
+import us.myles.viaversion.libs.opennbt.conversion.ConverterRegistry;
+import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag;
+import us.myles.viaversion.libs.opennbt.tag.builtin.ListTag;
+import us.myles.viaversion.libs.opennbt.tag.builtin.StringTag;
+import us.myles.viaversion.libs.opennbt.tag.builtin.Tag;
+
+import java.util.Set;
+
+public class BlockItemPackets1_14 extends BlockItemRewriter {
+ private static String NBT_TAG_NAME = "ViaBackwards|" + Protocol1_13_2To1_14.class.getSimpleName();
+
+ @Override
+ protected void registerPackets(Protocol1_13_2To1_14 protocol) {
+ // Open window
+ protocol.registerOutgoing(State.PLAY, 0x58, 0x14, new PacketRemapper() {
+ @Override
+ public void registerMap() { // c
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ int id = wrapper.read(Type.VAR_INT);
+ wrapper.write(Type.UNSIGNED_BYTE, (short) id);
+ int type = wrapper.read(Type.VAR_INT);
+ String stringType = null;
+ int slotSize = 0;
+ if (type < 6) {
+ stringType = "minecraft:container";
+ slotSize = (type + 1) * 9;
+ } else
+ switch (type) {
+ case 11:
+ stringType = "minecraft:crafting_table";
+ break;
+ case 14:
+ stringType = "minecraft:furnace";
+ break;
+ case 6:
+ stringType = "minecraft:dropper";
+ break;
+ case 12:
+ stringType = "minecraft:enchanting_table";
+ break;
+ case 10:
+ stringType = "minecraft:brewing_stand";
+ break;
+ case 18:
+ stringType = "minecraft:villager";
+ break;
+ case 8:
+ stringType = "minecraft:beacon";
+ break;
+ case 7:
+ stringType = "minecraft:anvil";
+ break;
+ case 15:
+ stringType = "minecraft:hopper";
+ break;
+ case 19:
+ stringType = "minecraft:shulker_box";
+ break;
+ }
+
+ if (stringType == null) {
+ ViaBackwards.getPlatform().getLogger().warning("Can't open inventory for 1.13 player! Type: " + type);
+ wrapper.cancel();
+ return;
+ }
+
+ wrapper.write(Type.STRING, stringType);
+ wrapper.passthrough(Type.STRING);
+ wrapper.write(Type.UNSIGNED_BYTE, (short) slotSize);
+ }
+ });
+ }
+ });
+
+ // Horse window
+ protocol.registerOutgoing(State.PLAY, 0x14, 0x14, new PacketRemapper() {
+ @Override
+ public void registerMap() { // c
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ wrapper.passthrough(Type.UNSIGNED_BYTE); // Window id
+ wrapper.write(Type.STRING, "EntityHorse"); // Type
+ wrapper.write(Type.STRING, "{\"translate\":\"minecraft.horse\"}"); // Title
+ wrapper.write(Type.UNSIGNED_BYTE, wrapper.read(Type.VAR_INT).shortValue()); // Number of slots
+ wrapper.passthrough(Type.INT); // Entity id
+ }
+ });
+ }
+ });
+
+ // Window items packet
+ protocol.registerOutgoing(State.PLAY, 0x15, 0x15, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.UNSIGNED_BYTE); // 0 - Window ID
+ map(Type.FLAT_VAR_INT_ITEM_ARRAY); // 1 - Window Values
+
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ Item[] stacks = wrapper.get(Type.FLAT_VAR_INT_ITEM_ARRAY, 0);
+ for (Item stack : stacks) handleItemToClient(stack);
+ }
+ });
+ }
+ });
+
+ // Set slot packet
+ protocol.registerOutgoing(State.PLAY, 0x17, 0x17, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.BYTE); // 0 - Window ID
+ map(Type.SHORT); // 1 - Slot ID
+ map(Type.FLAT_VAR_INT_ITEM); // 2 - Slot Value
+
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ handleItemToClient(wrapper.get(Type.FLAT_VAR_INT_ITEM, 0));
+ }
+ });
+ }
+ });
+
+ // Trade list
+ protocol.out(State.PLAY, 0x59, 0x19, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ wrapper.write(Type.STRING, "minecraft:trader_list");
+ wrapper.read(Type.STRING); // Remove channel
+
+ int windowId = wrapper.read(Type.INT);
+ wrapper.write(Type.VAR_INT, windowId);
+
+ int size = wrapper.passthrough(Type.UNSIGNED_BYTE);
+ for (int i = 0; i < size; i++) {
+ // Input Item
+ handleItemToClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM));
+ // Output Item
+ handleItemToClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM));
+
+ boolean secondItem = wrapper.passthrough(Type.BOOLEAN); // Has second item
+ if (secondItem) {
+ // Second Item
+ handleItemToClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM));
+ }
+
+ wrapper.passthrough(Type.BOOLEAN); // Trade disabled
+ wrapper.passthrough(Type.INT); // Number of tools uses
+ wrapper.passthrough(Type.INT); // Maximum number of trade uses
+
+ wrapper.read(Type.INT);
+ wrapper.read(Type.INT);
+ wrapper.read(Type.FLOAT);
+ }
+ wrapper.read(Type.VAR_INT);
+ wrapper.read(Type.VAR_INT);
+ wrapper.read(Type.BOOLEAN);
+ }
+ });
+ }
+ });
+
+ // Book open
+ protocol.registerOutgoing(State.PLAY, 0x2C, 0x19, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ wrapper.write(Type.STRING, "minecraft:book_open");
+ wrapper.passthrough(Type.VAR_INT);
+ }
+ });
+ }
+ });
+
+ // Entity Equipment Packet
+ protocol.registerOutgoing(State.PLAY, 0x42, 0x42, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.VAR_INT); // 0 - Entity ID
+ map(Type.VAR_INT); // 1 - Slot ID
+ map(Type.FLAT_VAR_INT_ITEM); // 2 - Item
+
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ handleItemToClient(wrapper.get(Type.FLAT_VAR_INT_ITEM, 0));
+ }
+ });
+ }
+ });
+
+ Set removedTypes = ImmutableSet.of("crafting_special_suspiciousstew", "blasting", "smoking", "campfire_cooking", "stonecutting");
+
+ // Declare Recipes
+ protocol.registerOutgoing(State.PLAY, 0x55, 0x54, new PacketRemapper() { // c
+ @Override
+ public void registerMap() {
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ int size = wrapper.passthrough(Type.VAR_INT);
+ int deleted = 0;
+ for (int i = 0; i < size; i++) {
+ String type = wrapper.read(Type.STRING);
+ String id = wrapper.read(Type.STRING); // Recipe Identifier
+ type = type.replace("minecraft:", "");
+ if (removedTypes.contains(type)) {
+ switch (type) {
+ case "blasting":
+ case "smoking":
+ case "campfire_cooking":
+ wrapper.read(Type.STRING); // Group
+ wrapper.read(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT); // Ingredients
+ wrapper.read(Type.FLAT_VAR_INT_ITEM);
+ wrapper.read(Type.FLOAT); // EXP
+ wrapper.read(Type.VAR_INT); // Cooking time
+ break;
+ case "stonecutting":
+ wrapper.read(Type.STRING); // Group?
+ wrapper.read(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT); // Ingredients
+ wrapper.read(Type.FLAT_VAR_INT_ITEM); // Result
+ break;
+ }
+ deleted++;
+ continue;
+ }
+ wrapper.write(Type.STRING, id);
+ wrapper.write(Type.STRING, type);
+
+ if (type.equals("crafting_shapeless")) {
+ wrapper.passthrough(Type.STRING); // Group
+ int ingredientsNo = wrapper.passthrough(Type.VAR_INT);
+ for (int j = 0; j < ingredientsNo; j++) {
+ Item[] items = wrapper.passthrough(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT); // Ingredients
+ for (Item item : items) handleItemToClient(item);
+ }
+ handleItemToClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Result
+ } else if (type.equals("crafting_shaped")) {
+ int ingredientsNo = wrapper.passthrough(Type.VAR_INT) * wrapper.passthrough(Type.VAR_INT);
+ wrapper.passthrough(Type.STRING); // Group
+ for (int j = 0; j < ingredientsNo; j++) {
+ Item[] items = wrapper.passthrough(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT); // Ingredients
+ for (Item item : items) handleItemToClient(item);
+ }
+ handleItemToClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Result
+ } else if (type.equals("smelting")) {
+ wrapper.passthrough(Type.STRING); // Group
+ Item[] items = wrapper.passthrough(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT); // Ingredients
+ for (Item item : items) handleItemToClient(item);
+ handleItemToClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM));
+ wrapper.passthrough(Type.FLOAT); // EXP
+ wrapper.passthrough(Type.VAR_INT); // Cooking time
+ }
+ }
+ wrapper.set(Type.VAR_INT, 0, size - deleted);
+ }
+ });
+ }
+ });
+
+
+ /*
+ Incoming packets
+ */
+
+ // Click window packet
+ protocol.registerIncoming(State.PLAY, 0x09, 0x08, 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.FLAT_VAR_INT_ITEM); // 5 - Clicked Item
+
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ handleItemToServer(wrapper.get(Type.FLAT_VAR_INT_ITEM, 0));
+ }
+ });
+ }
+ });
+
+ // Creative Inventory Action
+ protocol.registerIncoming(State.PLAY, 0x26, 0x24, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.SHORT); // 0 - Slot
+ map(Type.FLAT_VAR_INT_ITEM); // 1 - Clicked Item
+
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ handleItemToServer(wrapper.get(Type.FLAT_VAR_INT_ITEM, 0));
+ }
+ });
+ }
+ });
+
+ // Block break animation
+ protocol.registerOutgoing(State.PLAY, 0x08, 0x08, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.VAR_INT);
+ map(Type.POSITION1_14, Type.POSITION);
+ map(Type.BYTE);
+ }
+ });
+
+ // Update block entity
+ protocol.registerOutgoing(State.PLAY, 0x09, 0x09, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.POSITION1_14, Type.POSITION);
+ }
+ });
+
+ // Block Action
+ protocol.registerOutgoing(State.PLAY, 0x0A, 0x0A, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.POSITION1_14, Type.POSITION); // Location
+ map(Type.UNSIGNED_BYTE); // Action id
+ map(Type.UNSIGNED_BYTE); // Action param
+ map(Type.VAR_INT); // Block id - /!\ NOT BLOCK STATE
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ wrapper.set(Type.VAR_INT, 0, Protocol1_13_2To1_14.getNewBlockStateId(wrapper.get(Type.VAR_INT, 0)));
+ }
+ });
+ }
+ });
+
+ // Block Change
+ protocol.registerOutgoing(State.PLAY, 0xB, 0xB, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.POSITION1_14, Type.POSITION);
+ map(Type.VAR_INT);
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ int id = wrapper.get(Type.VAR_INT, 0);
+
+ wrapper.set(Type.VAR_INT, 0, Protocol1_13_2To1_14.getNewBlockStateId(id));
+ }
+ });
+ }
+ });
+
+ // Multi Block Change
+ protocol.registerOutgoing(State.PLAY, 0xF, 0xF, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.INT); // 0 - Chunk X
+ map(Type.INT); // 1 - Chunk Z
+ map(Type.BLOCK_CHANGE_RECORD_ARRAY); // 2 - Records
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ // Convert ids
+ for (BlockChangeRecord record : wrapper.get(Type.BLOCK_CHANGE_RECORD_ARRAY, 0)) {
+ int id = record.getBlockId();
+ record.setBlockId(Protocol1_13_2To1_14.getNewBlockStateId(id));
+ }
+ }
+ });
+ }
+ });
+
+ //Chunk
+ protocol.registerOutgoing(State.PLAY, 0x22, 0x22, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
+ Chunk chunk = wrapper.read(new Chunk1_14Type(clientWorld));
+ wrapper.write(new Chunk1_13Type(clientWorld), chunk);
+
+ for (ChunkSection section : chunk.getSections()) {
+ if (section == null) continue;
+ section.setBlockLight(new byte[2048]);
+ if (clientWorld.getEnvironment() == Environment.NORMAL) {
+ section.setSkyLight(new byte[2048]);
+ }
+ for (int i = 0; i < section.getPaletteSize(); i++) {
+ int old = section.getPaletteEntry(i);
+ int newId = Protocol1_13_2To1_14.getNewBlockStateId(old);
+ section.setPaletteEntry(i, newId);
+ }
+ }
+ }
+ });
+ }
+ });
+
+ // Effect packet
+ protocol.registerOutgoing(State.PLAY, 0x23, 0x23, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.INT); // Effect Id
+ map(Type.POSITION1_14, Type.POSITION); // Location
+ map(Type.INT); // Data
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ int id = wrapper.get(Type.INT, 0);
+ int data = wrapper.get(Type.INT, 1);
+ if (id == 1010) { // Play record
+ wrapper.set(Type.INT, 1, data = BlockItemPackets1_14.getNewItemId(data));
+ } else if (id == 2001) { // Block break + block break sound
+ wrapper.set(Type.INT, 1, data = Protocol1_14To1_13_2.getNewBlockStateId(data));
+ }
+ }
+ });
+ }
+ });
+
+ //spawn particle
+ protocol.registerOutgoing(State.PLAY, 0x24, 0x24, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.INT); // 0 - Particle ID
+ map(Type.BOOLEAN); // 1 - Long Distance
+ map(Type.FLOAT); // 2 - X
+ map(Type.FLOAT); // 3 - Y
+ map(Type.FLOAT); // 4 - Z
+ map(Type.FLOAT); // 5 - Offset X
+ map(Type.FLOAT); // 6 - Offset Y
+ map(Type.FLOAT); // 7 - Offset Z
+ map(Type.FLOAT); // 8 - Particle Data
+ map(Type.INT); // 9 - Particle Count
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ int id = wrapper.get(Type.INT, 0);
+ if (id == 3 || id == 20) {
+ int data = wrapper.passthrough(Type.VAR_INT);
+ wrapper.set(Type.VAR_INT, 0, Protocol1_14To1_13_2.getNewBlockStateId(data));
+ } else if (id == 27) {
+ handleItemToClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM));
+ }
+ }
+ });
+ }
+ });
+
+
+ //Map Data
+ protocol.registerOutgoing(State.PLAY, 0x26, 0x26, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.VAR_INT);
+ map(Type.BYTE);
+ map(Type.BOOLEAN);
+ map(Type.BOOLEAN, Type.NOTHING); // Locked
+ }
+ });
+
+ //respawn
+ protocol.registerOutgoing(State.PLAY, 0x38, 0x38, 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);
+ wrapper.write(Type.UNSIGNED_BYTE, (short) 0); // todo - do we need to store it from difficulty packet?
+ }
+ });
+ }
+ });
+
+ // Spawn position
+ protocol.registerOutgoing(State.PLAY, 0x49, 0x49, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.POSITION1_14, Type.POSITION);
+ }
+ });
+ }
+
+ @Override
+ protected void registerRewrites() {
+
+ }
+
+ @Override
+ public Item handleItemToClient(Item i) {
+ Item item = super.handleItemToClient(i);
+ if (item == null) return null;
+ item.setIdentifier(getOldItemId(item.getIdentifier()));
+
+ CompoundTag tag;
+ if ((tag = item.getTag()) != null) {
+ // Display Name now uses JSON
+ if (tag.get("display") instanceof CompoundTag) {
+ CompoundTag display = tag.get("display");
+ if (((CompoundTag) tag.get("display")).get("Lore") instanceof ListTag) {
+ ListTag lore = display.get("Lore");
+ ListTag via = display.get(NBT_TAG_NAME + "|Lore");
+ if (via != null) {
+ display.put(ConverterRegistry.convertToTag("Lore", ConverterRegistry.convertToValue(via)));
+ } else {
+ for (Tag loreEntry : lore) {
+ if (loreEntry instanceof StringTag) {
+ ((StringTag) loreEntry).setValue(
+ ChatRewriter.jsonTextToLegacy(
+ ((StringTag) loreEntry).getValue()
+ )
+ );
+ }
+ }
+ }
+ display.remove(NBT_TAG_NAME + "|Lore");
+ }
+ }
+ }
+ return item;
+ }
+
+ @Override
+ public Item handleItemToServer(Item i) {
+ Item item = super.handleItemToServer(i);
+ if (item == null) return null;
+ item.setIdentifier(getNewItemId(item.getIdentifier()));
+
+ CompoundTag tag;
+ if ((tag = item.getTag()) != null) {
+ // Display Lore now uses JSON
+ if (tag.get("display") instanceof CompoundTag) {
+ CompoundTag display = tag.get("display");
+ if (display.get("Lore") instanceof ListTag) {
+ ListTag lore = display.get("Lore");
+ display.put(ConverterRegistry.convertToTag(NBT_TAG_NAME + "|Lore", ConverterRegistry.convertToValue(lore)));
+ for (Tag loreEntry : lore) {
+ if (loreEntry instanceof StringTag) {
+ ((StringTag) loreEntry).setValue(
+ ChatRewriter.legacyTextToJson(
+ ((StringTag) loreEntry).getValue()
+ )
+ );
+ }
+ }
+ }
+ }
+ }
+ return item;
+ }
+
+ public static int getNewItemId(int id) {
+ Integer newId = MappingData.oldToNewItems.get(id);
+ if (newId == null) {
+ ViaBackwards.getPlatform().getLogger().warning("Missing 1.14 item for 1.13.2 item " + id);
+ return 1;
+ }
+ return newId;
+ }
+
+
+ public static int getOldItemId(int id) {
+ Integer oldId = MappingData.oldToNewItems.inverse().get(id);
+ return oldId != null ? oldId : 1;
+ }
+}
diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/EntityPackets1_14.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/EntityPackets1_14.java
new file mode 100644
index 00000000..dc59e8e6
--- /dev/null
+++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/EntityPackets1_14.java
@@ -0,0 +1,332 @@
+package nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.packets;
+
+import nl.matsv.viabackwards.ViaBackwards;
+import nl.matsv.viabackwards.api.entities.storage.EntityData;
+import nl.matsv.viabackwards.api.entities.storage.MetaStorage;
+import nl.matsv.viabackwards.api.entities.types.AbstractEntityType;
+import nl.matsv.viabackwards.api.entities.types.EntityType1_13;
+import nl.matsv.viabackwards.api.entities.types.EntityType1_14;
+import nl.matsv.viabackwards.api.rewriters.EntityRewriter;
+import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.packets.BlockItemPackets1_13;
+import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.Protocol1_13_2To1_14;
+import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.data.EntityTypeMapping;
+import us.myles.ViaVersion.api.PacketWrapper;
+import us.myles.ViaVersion.api.minecraft.VillagerData;
+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_13_2;
+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_12;
+import us.myles.ViaVersion.api.type.types.version.Types1_13_2;
+import us.myles.ViaVersion.api.type.types.version.Types1_14;
+import us.myles.ViaVersion.packets.State;
+import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
+
+import java.util.Optional;
+
+public class EntityPackets1_14 extends EntityRewriter {
+ @Override
+ protected void registerPackets(Protocol1_13_2To1_14 protocol) {
+ // Spawn Object
+ protocol.registerOutgoing(State.PLAY, 0x0, 0x0, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.VAR_INT); // 0 - Entity id
+ map(Type.UUID); // 1 - UUID
+ map(Type.VAR_INT, 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
+
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ byte type = wrapper.get(Type.BYTE, 0);
+ EntityType1_14.EntityType entityType = EntityType1_14.getTypeFromId(type);
+ if (entityType == null) {
+ ViaBackwards.getPlatform().getLogger().warning("Could not find 1.14 entity type " + type);
+ return;
+ }
+ addTrackedEntity(
+ wrapper.user(),
+ wrapper.get(Type.VAR_INT, 0),
+ entityType
+ );
+ }
+ });
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ Optional type = EntityType1_13.ObjectType.findById(EntityTypeMapping.getObjectId(
+ EntityTypeMapping.getOldId(wrapper.get(Type.BYTE, 0))
+ .orElse(0)
+ ).orElse(0));
+ if (type.isPresent()) {
+ wrapper.set(Type.BYTE, 0, (byte) type.get().getId());
+ }
+ if (type.isPresent() && type.get() == EntityType1_13.ObjectType.FALLING_BLOCK) {
+ int blockState = wrapper.get(Type.INT, 0);
+ int combined = BlockItemPackets1_13.toOldId(blockState);
+ combined = ((combined >> 4) & 0xFFF) | ((combined & 0xF) << 12);
+ wrapper.set(Type.INT, 0, combined);
+ } else if (type.isPresent() && type.get() == EntityType1_13.ObjectType.ITEM_FRAME) {
+ int data = wrapper.get(Type.INT, 0);
+ switch (data) {
+ case 3:
+ data = 0;
+ break;
+ case 4:
+ data = 1;
+ break;
+ case 5:
+ data = 3;
+ break;
+ }
+ wrapper.set(Type.INT, 0, data);
+ }
+ }
+ });
+ }
+ });
+
+ // Spawn mob packet
+ protocol.registerOutgoing(State.PLAY, 0x3, 0x3, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.VAR_INT); // 0 - Entity ID
+ map(Type.UUID); // 1 - Entity 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_14.METADATA_LIST, Types1_13_2.METADATA_LIST); // 12 - Metadata
+
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ int type = wrapper.get(Type.VAR_INT, 1);
+ EntityType1_14.EntityType entityType = EntityType1_14.getTypeFromId(type);
+ addTrackedEntity(
+ wrapper.user(),
+ wrapper.get(Type.VAR_INT, 0),
+ entityType
+ );
+ Optional oldId = EntityTypeMapping.getOldId(type);
+ if (!oldId.isPresent()) {
+ if (!hasData(entityType))
+ ViaBackwards.getPlatform().getLogger().warning("Could not find 1.13.2 entity type for 1.14 entity type " + type + "/" + entityType);
+ } else {
+ wrapper.set(Type.VAR_INT, 1, oldId.get());
+ }
+ }
+ });
+
+ // Handle 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_13_2.METADATA_LIST, 0));
+ handleMeta(
+ wrapper.user(),
+ wrapper.get(Type.VAR_INT, 0),
+ storage
+ );
+
+ Optional optEntDat = getEntityData(type);
+ if (optEntDat.isPresent()) {
+ EntityData data = optEntDat.get();
+
+ Optional replacementId = EntityTypeMapping.getOldId(data.getReplacementId());
+ wrapper.set(Type.VAR_INT, 1, replacementId.orElse(EntityType1_13.EntityType.ZOMBIE.getId()));
+ if (data.hasBaseMeta())
+ data.getDefaultMeta().handle(storage);
+ }
+
+ // Rewrite Metadata
+ wrapper.set(
+ Types1_13_2.METADATA_LIST,
+ 0,
+ storage.getMetaDataList()
+ );
+ }
+ });
+ }
+ });
+
+ // Spawn painting
+ protocol.registerOutgoing(State.PLAY, 0x04, 0x04, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.VAR_INT);
+ map(Type.UUID);
+ map(Type.VAR_INT);
+ map(Type.POSITION1_14, Type.POSITION);
+ map(Type.BYTE);
+ }
+ });
+
+ // Spawn player packet
+ 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_14.METADATA_LIST, Types1_13_2.METADATA_LIST); // 7 - Metadata
+
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ int entityId = wrapper.get(Type.VAR_INT, 0);
+
+ EntityType1_14.EntityType entType = EntityType1_14.EntityType.PLAYER;
+ // Register Type ID
+ addTrackedEntity(wrapper.user(), entityId, entType);
+ wrapper.set(Types1_13_2.METADATA_LIST, 0,
+ handleMeta(
+ wrapper.user(),
+ entityId,
+ new MetaStorage(wrapper.get(Types1_13_2.METADATA_LIST, 0))
+ ).getMetaDataList()
+ );
+ }
+ });
+ }
+ });
+
+
+ // Metadata packet
+ protocol.registerOutgoing(State.PLAY, 0x3F, 0x3F, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.VAR_INT); // 0 - Entity ID
+ map(Types1_14.METADATA_LIST, Types1_13_2.METADATA_LIST); // 1 - Metadata list
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ int entityId = wrapper.get(Type.VAR_INT, 0);
+
+ wrapper.set(Types1_13_2.METADATA_LIST, 0,
+ handleMeta(
+ wrapper.user(),
+ entityId,
+ new MetaStorage(wrapper.get(Types1_13_2.METADATA_LIST, 0))
+ ).getMetaDataList()
+ );
+ }
+ });
+ }
+ });
+
+ //join game
+ protocol.registerOutgoing(State.PLAY, 0x25, 0x25, 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 {
+ // Store the player
+ ClientWorld clientChunks = wrapper.user().get(ClientWorld.class);
+ int dimensionId = wrapper.get(Type.INT, 1);
+ clientChunks.setEnvironment(dimensionId);
+
+ int entityId = wrapper.get(Type.INT, 0);
+
+ // Register Type ID
+ addTrackedEntity(wrapper.user(), entityId, EntityType1_14.EntityType.PLAYER);
+
+ wrapper.write(Type.UNSIGNED_BYTE, (short) 0);
+ }
+ });
+ }
+ });
+ }
+
+ @Override
+ protected void registerRewrites() {
+ regEntType(EntityType1_14.EntityType.CAT, EntityType1_14.EntityType.OCELOT).mobName("Cat").spawnMetadata(e -> {
+ e.add(new Metadata(13, MetaType1_13_2.Byte, (byte) 0x4)); // Tamed cat
+ });
+ regEntType(EntityType1_14.EntityType.OCELOT, EntityType1_14.EntityType.OCELOT).mobName("Ocelot");
+ regEntType(EntityType1_14.EntityType.TRADER_LLAMA, EntityType1_14.EntityType.LLAMA).mobName("Trader Llama");
+
+ registerMetaHandler().handle(e -> {
+ if (e.getData().getMetaType().getTypeID() == 6) { // Slot
+ Protocol1_13_2To1_14.blockItem.handleItemToClient((Item) e.getData().getValue());
+ }
+ return e.getData();
+ });
+ // Remove bed location - todo send sleep packet
+ registerMetaHandler().filter(EntityType1_14.EntityType.LIVINGENTITY, true, 12).removed();
+ registerMetaHandler().filter(EntityType1_14.EntityType.LIVINGENTITY, true).handle(e -> {
+ if (e.getIndex() > 12) e.getData().setId(e.getIndex() - 1);
+ return e.getData();
+ });
+ // Remove entity pose
+ registerMetaHandler().filter(EntityType1_14.EntityType.ENTITY, true, 6).removed();
+ registerMetaHandler().filter(EntityType1_14.EntityType.ENTITY, true).handle(e -> {
+ if (e.getIndex() > 6) e.getData().setId(e.getIndex() - 1);
+ return e.getData();
+ });
+ registerMetaHandler().filter(EntityType1_14.EntityType.CAT, 13).removed();
+ registerMetaHandler().filter(EntityType1_14.EntityType.CAT, 14).removed();
+ registerMetaHandler().filter(EntityType1_14.EntityType.CAT, 15).removed();
+ // Villager data -> var int
+ registerMetaHandler().handle(e -> {
+ if (e.getData().getValue() instanceof VillagerData) {
+ e.getData().setMetaType(MetaType1_13_2.VarInt);
+ e.getData().setValue(villagerDataToProfession(((VillagerData) e.getData().getValue())));
+ }
+ return e.getData();
+ });
+ }
+
+ public int villagerDataToProfession(VillagerData data) {
+ switch (data.getProfession()) {
+ case 1: // Armorer
+ case 10: // Mason
+ case 13: // Toolsmith
+ case 14: // Weaponsmith
+ return 3; // Blacksmith
+ case 2: // Butcher
+ case 8: // Leatherworker
+ return 4; // Butcher
+ case 3: // Cartographer
+ case 9: // Librarian
+ return 1; // Librarian
+ case 4: // Cleric
+ return 2; // Priest
+ case 5: // Farmer
+ case 6: // Fisherman
+ case 7: // Fletcher
+ case 12: // Shepherd
+ return 0; // Farmer
+ case 0: // None
+ case 11: // Nitwit
+ default:
+ return 5; // Nitwit
+ }
+ }
+}
diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/PlayerPackets1_14.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/PlayerPackets1_14.java
new file mode 100644
index 00000000..d3a7404c
--- /dev/null
+++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/PlayerPackets1_14.java
@@ -0,0 +1,148 @@
+package nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.packets;
+
+import nl.matsv.viabackwards.api.rewriters.Rewriter;
+import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.Protocol1_13_2To1_14;
+import us.myles.ViaVersion.api.PacketWrapper;
+import us.myles.ViaVersion.api.minecraft.Position;
+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 PlayerPackets1_14 extends Rewriter {
+ @Override
+ protected void registerPackets(Protocol1_13_2To1_14 protocol) {
+
+ // Server Difficulty
+ protocol.registerOutgoing(State.PLAY, 0x0D, 0x0D, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.UNSIGNED_BYTE);
+ map(Type.BOOLEAN, Type.NOTHING); // Locked
+ }
+ });
+
+ // Open Sign Editor
+ protocol.registerOutgoing(State.PLAY, 0x2D, 0x2C, new PacketRemapper() { // c
+ @Override
+ public void registerMap() {
+ map(Type.POSITION1_14, Type.POSITION);
+ }
+ });
+
+ // Query Block NBT
+ protocol.registerIncoming(State.PLAY, 0x01, 0x01, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.VAR_INT);
+ map(Type.POSITION, Type.POSITION1_14);
+ }
+ });
+
+ // Edit Book
+ protocol.registerIncoming(State.PLAY, 0x0c, 0x0B, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ Protocol1_13_2To1_14.blockItem.handleItemToServer(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM));
+ }
+ });
+ }
+ });
+
+ // Player Digging
+ protocol.registerIncoming(State.PLAY, 0x1a, 0x18, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.VAR_INT);
+ map(Type.POSITION, Type.POSITION1_14);
+ map(Type.BYTE);
+ }
+ });
+
+ // Recipe Book Data
+ protocol.registerIncoming(State.PLAY, 0x1d, 0x1B, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.VAR_INT);
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ int type = wrapper.get(Type.VAR_INT, 0);
+ if (type == 0) {
+ wrapper.passthrough(Type.STRING);
+ } else if (type == 1) {
+ wrapper.passthrough(Type.BOOLEAN); // Crafting Recipe Book Open
+ wrapper.passthrough(Type.BOOLEAN); // Crafting Recipe Filter Active
+ wrapper.passthrough(Type.BOOLEAN); // Smelting Recipe Book Open
+ wrapper.passthrough(Type.BOOLEAN); // Smelting Recipe Filter Active
+
+ // Unknown new booleans
+ wrapper.read(Type.BOOLEAN);
+ wrapper.read(Type.BOOLEAN);
+ wrapper.read(Type.BOOLEAN);
+ wrapper.read(Type.BOOLEAN);
+ }
+ }
+ });
+ }
+ });
+
+ // Update Command Block
+ protocol.registerIncoming(State.PLAY, 0x24, 0x22, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.POSITION, Type.POSITION1_14);
+ }
+ });
+
+ // Update Structure Block
+ protocol.registerIncoming(State.PLAY, 0x27, 0x25, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.POSITION, Type.POSITION1_14);
+ }
+ });
+
+ // Update Sign
+ protocol.registerIncoming(State.PLAY, 0x28, 0x26, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.POSITION, Type.POSITION1_14);
+ }
+ });
+
+ // Player Block Placement
+ protocol.registerIncoming(State.PLAY, 0x2b, 0x29, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ Position position = wrapper.read(Type.POSITION);
+ int face = wrapper.read(Type.VAR_INT);
+ int hand = wrapper.read(Type.VAR_INT);
+ float x = wrapper.read(Type.FLOAT);
+ float y = wrapper.read(Type.FLOAT);
+ float z = wrapper.read(Type.FLOAT);
+
+ wrapper.write(Type.VAR_INT, hand);
+ wrapper.write(Type.POSITION1_14, position);
+ wrapper.write(Type.VAR_INT, face);
+ wrapper.write(Type.FLOAT, x);
+ wrapper.write(Type.FLOAT, y);
+ wrapper.write(Type.FLOAT, z);
+ wrapper.write(Type.BOOLEAN, false); // Inside block
+ }
+ });
+ }
+ });
+ }
+
+ @Override
+ protected void registerRewrites() {
+
+ }
+}
diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/SoundPackets1_14.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/SoundPackets1_14.java
new file mode 100644
index 00000000..5e803edb
--- /dev/null
+++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/SoundPackets1_14.java
@@ -0,0 +1,34 @@
+package nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.packets;
+
+import nl.matsv.viabackwards.api.rewriters.Rewriter;
+import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.Protocol1_13_2To1_14;
+import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.data.SoundMapping;
+import us.myles.ViaVersion.api.PacketWrapper;
+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 SoundPackets1_14 extends Rewriter {
+ @Override
+ protected void registerPackets(Protocol1_13_2To1_14 protocol) {
+ // Sound Effect
+ protocol.registerOutgoing(State.PLAY, 0x4D, 0x4D, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.VAR_INT); // Sound Id
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ wrapper.set(Type.VAR_INT, 0, SoundMapping.getOldSound(wrapper.get(Type.VAR_INT, 0)));
+ }
+ });
+ }
+ });
+ }
+
+ @Override
+ protected void registerRewrites() {
+
+ }
+}
diff --git a/core/src/main/resources/assets/viabackwards/data/mapping-1.13.2to1.14.json b/core/src/main/resources/assets/viabackwards/data/mapping-1.13.2to1.14.json
new file mode 100644
index 00000000..26bb3825
--- /dev/null
+++ b/core/src/main/resources/assets/viabackwards/data/mapping-1.13.2to1.14.json
@@ -0,0 +1,4 @@
+{
+ "blockstates": {
+ }
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 0953d46d..0c04e268 100644
--- a/pom.xml
+++ b/pom.xml
@@ -16,7 +16,7 @@
nl.matsv
viabackwards-parent
- 3.0.0-SNAPSHOT
+ 3.0.0-19w11b
pom
Allow newer clients to join older server versions.
@@ -60,7 +60,7 @@
us.myles
viaversion
- 2.0.0-SNAPSHOT
+ 2.0.0-19w09a
provided
diff --git a/sponge/pom.xml b/sponge/pom.xml
index 0ab7811a..d6f6be56 100644
--- a/sponge/pom.xml
+++ b/sponge/pom.xml
@@ -15,7 +15,7 @@
viabackwards-parent
nl.matsv
- 3.0.0-SNAPSHOT
+ 3.0.0-19w11b
4.0.0
diff --git a/velocity/pom.xml b/velocity/pom.xml
index 162c5196..e47b28be 100644
--- a/velocity/pom.xml
+++ b/velocity/pom.xml
@@ -15,7 +15,7 @@
viabackwards-parent
nl.matsv
- 3.0.0-SNAPSHOT
+ 3.0.0-19w11b
4.0.0