1.14 development

This commit is contained in:
Gerrygames 2018-10-24 19:05:14 +02:00
parent 58efd6158f
commit 0df089b3cb
10 changed files with 1124 additions and 0 deletions

View File

@ -0,0 +1,295 @@
package us.myles.ViaVersion.api.entities;
import com.google.common.base.Optional;
import lombok.AllArgsConstructor;
import lombok.Getter;
import us.myles.ViaVersion.api.Via;
public class Entity1_14Types {
public static EntityType getTypeFromId(int typeID, boolean isObject) {
Optional<EntityType> type;
if (isObject)
type = ObjectTypes.getPCEntity(typeID);
else
type = EntityType.findById(typeID);
if (!type.isPresent()) {
Via.getPlatform().getLogger().severe("Could not find type id " + typeID + " isObject=" + isObject);
return EntityType.ENTITY; // Fall back to the basic ENTITY
}
return type.get();
}
@AllArgsConstructor
@Getter
public enum EntityType {
// Auto generated
ENTITY(-1),
AREA_EFFECT_CLOUD(0, ENTITY),
ENDER_CRYSTAL(16, ENTITY),
EVOCATION_FANGS(20, ENTITY),
XP_ORB(22, ENTITY),
EYE_OF_ENDER_SIGNAL(23, ENTITY),
FALLING_BLOCK(24, ENTITY),
FIREWORKS_ROCKET(25, ENTITY),
ITEM(32, ENTITY),
LLAMA_SPIT(37, ENTITY),
TNT(56, ENTITY),
SHULKER_BULLET(61, ENTITY),
FISHING_BOBBER(96, ENTITY),
LIVINGENTITY(-1, ENTITY),
ARMOR_STAND(1, LIVINGENTITY),
PLAYER(95, LIVINGENTITY),
ABSTRACT_INSENTIENT(-1, LIVINGENTITY),
ENDER_DRAGON(17, ABSTRACT_INSENTIENT),
ABSTRACT_CREATURE(-1, ABSTRACT_INSENTIENT),
ABSTRACT_AGEABLE(-1, ABSTRACT_CREATURE),
VILLAGER(80, ABSTRACT_AGEABLE),
// Animals
ABSTRACT_ANIMAL(-1, ABSTRACT_AGEABLE),
CHICKEN(7, ABSTRACT_ANIMAL),
COW(9, ABSTRACT_ANIMAL),
MOOSHROOM(47, COW),
PIG(52, ABSTRACT_ANIMAL),
POLAR_BEAR(55, ABSTRACT_ANIMAL),
RABBIT(57, ABSTRACT_ANIMAL),
SHEEP(59, ABSTRACT_ANIMAL),
TURTLE(74, ABSTRACT_ANIMAL),
ABSTRACT_TAMEABLE_ANIMAL(-1, ABSTRACT_ANIMAL),
OCELOT(48, ABSTRACT_TAMEABLE_ANIMAL),
WOLF(88, ABSTRACT_TAMEABLE_ANIMAL),
ABSTRACT_PARROT(-1, ABSTRACT_TAMEABLE_ANIMAL),
PARROT(51, ABSTRACT_PARROT),
// Horses
ABSTRACT_HORSE(-1, ABSTRACT_ANIMAL),
CHESTED_HORSE(-1, ABSTRACT_HORSE),
DONKEY(11, CHESTED_HORSE),
MULE(46, CHESTED_HORSE),
LLAMA(36, CHESTED_HORSE),
HORSE(29, ABSTRACT_HORSE),
SKELETON_HORSE(64, ABSTRACT_HORSE),
ZOMBIE_HORSE(90, ABSTRACT_HORSE),
// Golem
ABSTRACT_GOLEM(-1, ABSTRACT_CREATURE),
SNOWMAN(66, ABSTRACT_GOLEM),
VILLAGER_GOLEM(81, ABSTRACT_GOLEM),
SHULKER(60, ABSTRACT_GOLEM),
// Fish
ABSTRACT_FISHES(-1, ABSTRACT_CREATURE),
COD_MOB(8, ABSTRACT_FISHES),
PUFFER_FISH(53, ABSTRACT_FISHES),
SALMON_MOB(58, ABSTRACT_FISHES),
TROPICAL_FISH(73, ABSTRACT_FISHES),
// Monsters
ABSTRACT_MONSTER(-1, ABSTRACT_CREATURE),
BLAZE(4, ABSTRACT_MONSTER),
CREEPER(10, ABSTRACT_MONSTER),
ENDERMITE(19, ABSTRACT_MONSTER),
ENDERMAN(18, ABSTRACT_MONSTER),
GIANT(27, ABSTRACT_MONSTER),
SILVERFISH(62, ABSTRACT_MONSTER),
VEX(79, ABSTRACT_MONSTER),
WITCH(84, ABSTRACT_MONSTER),
WITHER(85, ABSTRACT_MONSTER),
// Illagers
ABSTRACT_ILLAGER_BASE(-1, ABSTRACT_MONSTER),
ABSTRACT_EVO_ILLU_ILLAGER(-1, ABSTRACT_ILLAGER_BASE),
EVOCATION_ILLAGER(21, ABSTRACT_EVO_ILLU_ILLAGER),
ILLUSION_ILLAGER(31, ABSTRACT_EVO_ILLU_ILLAGER),
VINDICATION_ILLAGER(81, ABSTRACT_ILLAGER_BASE),
// Skeletons
ABSTRACT_SKELETON(-1, ABSTRACT_MONSTER),
SKELETON(63, ABSTRACT_SKELETON),
STRAY(72, ABSTRACT_SKELETON),
WITHER_SKELETON(86, ABSTRACT_SKELETON),
// Guardians
GUARDIAN(28, ABSTRACT_MONSTER),
ELDER_GUARDIAN(15, GUARDIAN),
// Spiders
SPIDER(70, ABSTRACT_MONSTER),
CAVE_SPIDER(6, SPIDER),
// Zombies - META CHECKED
ZOMBIE(89, ABSTRACT_MONSTER),
DROWNED(14, ZOMBIE),
HUSK(30, ZOMBIE),
ZOMBIE_PIGMAN(54, ZOMBIE),
ZOMBIE_VILLAGER(91, ZOMBIE),
// Flying entities
ABSTRACT_FLYING(-1, ABSTRACT_INSENTIENT),
GHAST(26, ABSTRACT_FLYING),
PHANTOM(92, ABSTRACT_FLYING),
ABSTRACT_AMBIENT(-1, ABSTRACT_INSENTIENT),
BAT(3, ABSTRACT_AMBIENT),
ABSTRACT_WATERMOB(-1, ABSTRACT_INSENTIENT),
SQUID(71, ABSTRACT_WATERMOB),
// Slimes
SLIME(65, ABSTRACT_INSENTIENT),
MAGMA_CUBE(38, SLIME),
// Hangable objects
ABSTRACT_HANGING(-1, ENTITY),
LEASH_KNOT(35, ABSTRACT_HANGING),
ITEM_FRAME(33, ABSTRACT_HANGING),
PAINTING(49, ABSTRACT_HANGING),
ABSTRACT_LIGHTNING(-1, ENTITY),
LIGHTNING_BOLT(94, ABSTRACT_LIGHTNING),
// Arrows
ABSTRACT_ARROW(-1, ENTITY),
ARROW(2, ABSTRACT_ARROW),
SPECTRAL_ARROW(69, ABSTRACT_ARROW),
TRIDENT(97, ABSTRACT_ARROW),
// Fireballs
ABSTRACT_FIREBALL(-1, ENTITY),
DRAGON_FIREBALL(13, ABSTRACT_FIREBALL),
FIREBALL(34, ABSTRACT_FIREBALL),
SMALL_FIREBALL(66, ABSTRACT_FIREBALL),
WITHER_SKULL(87, ABSTRACT_FIREBALL),
// Projectiles
PROJECTILE_ABSTRACT(-1, ENTITY),
SNOWBALL(68, PROJECTILE_ABSTRACT),
ENDER_PEARL(76, PROJECTILE_ABSTRACT),
EGG(75, PROJECTILE_ABSTRACT),
POTION(78, PROJECTILE_ABSTRACT),
XP_BOTTLE(77, PROJECTILE_ABSTRACT),
// Vehicles
MINECART_ABSTRACT(-1, ENTITY),
CHESTED_MINECART_ABSTRACT(-1, MINECART_ABSTRACT),
CHEST_MINECART(40, CHESTED_MINECART_ABSTRACT),
HOPPER_MINECART(43, CHESTED_MINECART_ABSTRACT),
MINECART(39, MINECART_ABSTRACT),
FURNACE_MINECART(42, MINECART_ABSTRACT),
COMMANDBLOCK_MINECART(41, MINECART_ABSTRACT),
TNT_MINECART(45, MINECART_ABSTRACT),
SPAWNER_MINECART(44, MINECART_ABSTRACT),
BOAT(5, ENTITY),
;
private final int id;
private final EntityType parent;
EntityType(int id) {
this.id = id;
this.parent = null;
}
public static Optional<EntityType> findById(int id) {
if (id == -1) // Check if this is called
return Optional.absent();
for (EntityType ent : EntityType.values())
if (ent.getId() == id)
return Optional.of(ent);
return Optional.absent();
}
public boolean is(EntityType... types) {
for (EntityType type : types)
if (is(type))
return true;
return false;
}
public boolean is(EntityType type) {
return this == type;
}
public boolean isOrHasParent(EntityType type) {
EntityType parent = this;
do {
if (parent == type)
return true;
parent = parent.getParent();
} while (parent != null);
return false;
}
}
@AllArgsConstructor
@Getter
public enum ObjectTypes {
BOAT(1, EntityType.BOAT),
ITEM(2, EntityType.ITEM),
AREA_EFFECT_CLOUD(3, EntityType.AREA_EFFECT_CLOUD),
MINECART(10, EntityType.MINECART_ABSTRACT),
TNT_PRIMED(50, EntityType.TNT),
ENDER_CRYSTAL(51, EntityType.ENDER_CRYSTAL),
TIPPED_ARROW(60, EntityType.ARROW),
SNOWBALL(61, EntityType.SNOWBALL),
EGG(62, EntityType.EGG),
FIREBALL(63, EntityType.FIREBALL),
SMALL_FIREBALL(64, EntityType.SMALL_FIREBALL),
ENDER_PEARL(65, EntityType.ENDER_PEARL),
WITHER_SKULL(66, EntityType.WITHER_SKULL),
SHULKER_BULLET(67, EntityType.SHULKER_BULLET),
LIAMA_SPIT(68, EntityType.LLAMA_SPIT),
FALLING_BLOCK(70, EntityType.FALLING_BLOCK),
ITEM_FRAME(71, EntityType.ITEM_FRAME),
ENDER_SIGNAL(72, EntityType.EYE_OF_ENDER_SIGNAL),
POTION(73, EntityType.POTION),
THROWN_EXP_BOTTLE(75, EntityType.XP_BOTTLE),
FIREWORK(76, EntityType.FIREWORKS_ROCKET),
LEASH(77, EntityType.LEASH_KNOT),
ARMOR_STAND(78, EntityType.ARMOR_STAND),
EVOCATION_FANGS(79, EntityType.EVOCATION_FANGS),
FISHIHNG_HOOK(90, EntityType.FISHING_BOBBER),
SPECTRAL_ARROW(91, EntityType.SPECTRAL_ARROW),
DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL),
;
private final int id;
private final EntityType type;
public static Optional<ObjectTypes> findById(int id) {
if (id == -1)
return Optional.absent();
for (ObjectTypes ent : ObjectTypes.values())
if (ent.getId() == id)
return Optional.of(ent);
return Optional.absent();
}
public static Optional<EntityType> getPCEntity(int id) {
Optional<ObjectTypes> output = findById(id);
if (!output.isPresent())
return Optional.absent();
return Optional.of(output.get().getType());
}
}
}

View File

@ -15,6 +15,7 @@ import us.myles.ViaVersion.protocols.protocol1_12_2to1_12_1.Protocol1_12_2TO1_12
import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.Protocol1_12To1_11_1;
import us.myles.ViaVersion.protocols.protocol1_13_2to1_13_1.Protocol1_13_2To1_13_1;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.Protocol1_14To1_13_2;
import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.Protocol1_9_1_2TO1_9_3_4;
import us.myles.ViaVersion.protocols.protocol1_9_1to1_9.Protocol1_9_1TO1_9;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.Protocol1_9_3TO1_9_1_2;
@ -59,6 +60,8 @@ public class ProtocolRegistry {
registerProtocol(new Protocol1_13To1_12_2(), Collections.singletonList(ProtocolVersion.v1_13.getId()), ProtocolVersion.v1_12_2.getId());
registerProtocol(new Protocol1_13_1To1_13(), Arrays.asList(ProtocolVersion.v1_13_1.getId()), ProtocolVersion.v1_13.getId());
registerProtocol(new Protocol1_13_2To1_13_1(), Arrays.asList(ProtocolVersion.v1_13_2.getId()), ProtocolVersion.v1_13_1.getId());
registerProtocol(new Protocol1_14To1_13_2(), Arrays.asList(ProtocolVersion.v1_14.getId()), ProtocolVersion.v1_13_2.getId());
}
/**

View File

@ -35,6 +35,7 @@ public class ProtocolVersion {
public static final ProtocolVersion v1_13;
public static final ProtocolVersion v1_13_1;
public static final ProtocolVersion v1_13_2;
public static final ProtocolVersion v1_14;
public static final ProtocolVersion unknown;
private final int id;
@ -66,6 +67,7 @@ public class ProtocolVersion {
register(v1_13 = new ProtocolVersion(393, "1.13"));
register(v1_13_1 = new ProtocolVersion(401, "1.13.1"));
register(v1_13_2 = new ProtocolVersion(404, "1.13.2"));
register(v1_14 = new ProtocolVersion(441, "1.14"));
register(unknown = new ProtocolVersion(-1, "UNKNOWN"));
}

View File

@ -0,0 +1,44 @@
package us.myles.ViaVersion.protocols.protocol1_14to1_13_2;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.entities.Entity1_14Types;
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.protocols.protocol1_14to1_13_2.packets.InventoryPackets;
import java.util.ArrayList;
import java.util.List;
public class MetadataRewriter {
public static void handleMetadata(int entityId, Entity1_14Types.EntityType type, List<Metadata> metadatas, UserConnection connection) {
for (Metadata metadata : new ArrayList<>(metadatas)) {
try {
// 1.13 changed item to flat item (no data)
if (metadata.getMetaType() == MetaType1_13_2.Slot) {
InventoryPackets.toClient((Item) metadata.getValue());
} else if (metadata.getMetaType() == MetaType1_13_2.BlockID) {
// Convert to new block id
int data = (int) metadata.getValue();
metadata.setValue(Protocol1_14To1_13_2.getNewBlockStateId(data));
}
if (type == null) continue;
if (type.isOrHasParent(Entity1_14Types.EntityType.MINECART_ABSTRACT) && metadata.getId() == 9) {
// New block format
int data = (int) metadata.getValue();
metadata.setValue(Protocol1_14To1_13_2.getNewBlockStateId(data));
}
} catch (Exception e) {
metadatas.remove(metadata);
if (!Via.getConfig().isSuppressMetadataErrors() || Via.getManager().isDebug()) {
Via.getPlatform().getLogger().warning("An error occurred with entity metadata handler");
Via.getPlatform().getLogger().warning("Metadata: " + metadata);
e.printStackTrace();
}
}
}
}
}

View File

@ -0,0 +1,89 @@
package us.myles.ViaVersion.protocols.protocol1_14to1_13_2;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.protocol.Protocol;
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_14to1_13_2.packets.EntityPackets;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.packets.InventoryPackets;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.packets.WorldPackets;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.storage.EntityTracker;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
public class Protocol1_14To1_13_2 extends Protocol {
@Override
protected void registerPackets() {
InventoryPackets.register(this);
EntityPackets.register(this);
WorldPackets.register(this);
registerOutgoing(State.PLAY, 0x4E, 0x4F);
registerOutgoing(State.PLAY, 0x4F, 0x50);
registerOutgoing(State.PLAY, 0x50, 0x51);
registerOutgoing(State.PLAY, 0x51, 0x52);
registerOutgoing(State.PLAY, 0x52, 0x53);
registerOutgoing(State.PLAY, 0x53, 0x54);
registerOutgoing(State.PLAY, 0x55, 0x56, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int blockTagsSize = wrapper.passthrough(Type.VAR_INT); // 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] = getNewBlockId(blockIds[j]);
}
}
int itemTagsSize = wrapper.passthrough(Type.VAR_INT); // 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] = InventoryPackets.getNewItemId(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);
}
wrapper.write(Type.VAR_INT, 0); // new unknown tags
}
});
}
});
}
public static int getNewBlockStateId(int id) {
if (id < 1121) return id;
else if (id < 3108) return id + 3;
else if (id < 3278) return id + 163;
else if (id < 3978) return id + 203;
else if (id < 3984) return id + 207;
else if (id < 3988) return id + 197;
else if (id < 5284) return id + 203;
else if (id < 7300) return id + 206;
else if (id < 8591) return id + 212;
else if (id < 8595) return id + 226;
else return id + 2192;
}
public static int getNewBlockId(int id) {
return id; //TODO
}
@Override
public void init(UserConnection userConnection) {
userConnection.put(new EntityTracker(userConnection));
if (!userConnection.has(ClientWorld.class))
userConnection.put(new ClientWorld(userConnection));
}
}

View File

@ -0,0 +1,67 @@
package us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data;
import com.google.common.base.Optional;
import java.util.HashMap;
import java.util.Map;
public class EntityTypeRewriter {
private static Map<Integer, Integer> entityTypes = new HashMap<>();
private static Map<Integer, Integer> objectTypes = new HashMap<>();
static {
regEnt(74, 75); // egg
regEnt(75, 76); // ender_pearl
regEnt(76, 77); // experience_bottle
regEnt(93, 96); // fishing_bobber
regEnt(80, 81); // iron_golem
regEnt(91, 94); // lightning_bolt
regEnt(50, 51); // parrot
regEnt(90, 92); // phantom
regEnt(51, 52); // pig
regEnt(92, 95); // player
regEnt(54, 55); // polar_bear
regEnt(77, 78); // potion
regEnt(52, 53); // pufferfish
regEnt(56, 57); // rabbit
regEnt(57, 58); // salmon
regEnt(58, 59); // sheep
regEnt(59, 60); // shulker
regEnt(60, 61); // shulker_bullet
regEnt(61, 62); // silverfish
regEnt(62, 63); // skeleton
regEnt(63, 64); // skeleton_horse
regEnt(64, 65); // slime
regEnt(65, 66); // small_fireball
regEnt(66, 67); // snowgolem
regEnt(67, 68); // snowball
regEnt(68, 69); // spectral_arrow
regEnt(69, 70); // spider
regEnt(70, 71); // squid
regEnt(71, 72); // stray
regEnt(55, 56); // tnt
regEnt(94, 97); // trident
regEnt(72, 73); // tropical_fish
regEnt(73, 74); // turtle
regEnt(78, 79); // vex
regEnt(79, 80); // villager
regEnt(81, 82); // vindicator
regEnt(82, 84); // witch
regEnt(83, 85); // wither
regEnt(84, 86); // wither_skeleton
regEnt(85, 87); // wither_skull
regEnt(86, 88); // wolf
regEnt(87, 89); // zombie
regEnt(88, 90); // zombie_horse
regEnt(53, 54); // zombie_pigman
regEnt(89, 91); // zombie_villager
}
private static void regEnt(int type1_13, int type1_14) {
entityTypes.put(type1_13, type1_14);
}
public static Optional<Integer> getNewId(int type1_13) {
return Optional.fromNullable(entityTypes.get(type1_13));
}
}

View File

@ -0,0 +1,157 @@
package us.myles.ViaVersion.protocols.protocol1_14to1_13_2.packets;
import com.google.common.base.Optional;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.entities.Entity1_14Types;
import us.myles.ViaVersion.api.protocol.Protocol;
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_13_2;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.MetadataRewriter;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.Protocol1_14To1_13_2;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.EntityTypeRewriter;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.storage.EntityTracker;
public class EntityPackets {
public static void register(Protocol protocol) {
// Spawn entity
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.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 {
int entityId = wrapper.get(Type.VAR_INT, 0);
byte type = wrapper.get(Type.BYTE, 0);
Entity1_14Types.EntityType entType = Entity1_14Types.getTypeFromId(type, true);
if (entType != null) {
if (entType.is(Entity1_14Types.EntityType.FALLING_BLOCK)) {
int data = wrapper.get(Type.INT, 0);
wrapper.set(Type.INT, 0, Protocol1_14To1_13_2.getNewBlockStateId(data));
}
}
// Register Type ID
wrapper.user().get(EntityTracker.class).addEntity(entityId, entType);
}
});
}
});
// 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_13_2.METADATA_LIST); // 12 - Metadata
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityId = wrapper.get(Type.VAR_INT, 0);
int type = wrapper.get(Type.VAR_INT, 1);
type = EntityTypeRewriter.getNewId(type).or(type);
Entity1_14Types.EntityType entType = Entity1_14Types.getTypeFromId(type, false);
wrapper.set(Type.VAR_INT, 1, type);
// Register Type ID
wrapper.user().get(EntityTracker.class).addEntity(entityId, entType);
MetadataRewriter.handleMetadata(entityId, entType, wrapper.get(Types1_13_2.METADATA_LIST, 0), wrapper.user());
}
});
}
});
// 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_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);
Entity1_14Types.EntityType entType = Entity1_14Types.EntityType.PLAYER;
// Register Type ID
wrapper.user().get(EntityTracker.class).addEntity(entityId, entType);
MetadataRewriter.handleMetadata(entityId, entType, wrapper.get(Types1_13_2.METADATA_LIST, 0), wrapper.user());
}
});
}
});
// Destroy entities
protocol.registerOutgoing(State.PLAY, 0x35, 0x35, 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))
wrapper.user().get(EntityTracker.class).removeEntity(entity);
}
});
}
});
// Metadata packet
protocol.registerOutgoing(State.PLAY, 0x3F, 0x3F, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(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);
Optional<Entity1_14Types.EntityType> type = wrapper.user().get(EntityTracker.class).get(entityId);
MetadataRewriter.handleMetadata(entityId, type.orNull(), wrapper.get(Types1_13_2.METADATA_LIST, 0), wrapper.user());
}
});
}
});
}
}

View File

@ -0,0 +1,245 @@
package us.myles.ViaVersion.protocols.protocol1_14to1_13_2.packets;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.protocol.Protocol;
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 InventoryPackets {
public static void register(Protocol protocol) {
/*
Outgoing packets
*/
// 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 {
Item stack = wrapper.get(Type.FLAT_VAR_INT_ITEM, 0);
toClient(stack);
}
});
}
});
// 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)
toClient(stack);
}
});
}
});
// Plugin message
protocol.registerOutgoing(State.PLAY, 0x19, 0x19, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // Channel
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
String channel = wrapper.get(Type.STRING, 0);
if (channel.equals("minecraft:trader_list") || channel.equals("trader_list")) {
wrapper.passthrough(Type.INT); // Passthrough Window ID
int size = wrapper.passthrough(Type.UNSIGNED_BYTE);
for (int i = 0; i < size; i++) {
// Input Item
toClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM));
// Output Item
InventoryPackets.toClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM));
boolean secondItem = wrapper.passthrough(Type.BOOLEAN); // Has second item
if (secondItem) {
// Second Item
InventoryPackets.toClient(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
}
}
}
});
}
});
// 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 {
Item stack = wrapper.get(Type.FLAT_VAR_INT_ITEM, 0);
toClient(stack);
}
});
}
});
// Declare Recipes
protocol.registerOutgoing(State.PLAY, 0x54, 0x55, new PacketRemapper() {
@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 id = wrapper.read(Type.STRING); // Recipe Identifier
String type = wrapper.read(Type.STRING);
if (type.equals("crafting_special_banneraddpattern")) {
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
}
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++) {
wrapper.passthrough(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT); // Ingredients
}
wrapper.passthrough(Type.FLAT_VAR_INT_ITEM); // Result
} else if (type.equals("smelting")) {
wrapper.passthrough(Type.STRING); // Group
wrapper.passthrough(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT); // Ingredients
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, 0x08, 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 {
Item item = wrapper.get(Type.FLAT_VAR_INT_ITEM, 0);
toServer(item);
}
});
}
});
// Creative Inventory Action
protocol.registerIncoming(State.PLAY, 0x24, 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 {
Item item = wrapper.get(Type.FLAT_VAR_INT_ITEM, 0);
toServer(item);
}
});
}
});
}
public static void toClient(Item item) {
if (item == null) return;
item.setId((short) getNewItemId(item.getId()));
}
public static int getNewItemId(int id) {
if (id < 108) return id;
else if (id < 119) return id + 3;
else if (id < 460) return id + 4;
else if (id < 542) return id + 43;
else if (id < 561) return id + 48;
else if (id < 593) return id + 49;
else if (id < 657) return id + 53;
else if (id < 662) return id + 54;
else if (id < 665) return id + 55;
else return id + 56;
}
public static void toServer(Item item) {
if (item == null) return;
item.setId((short) getOldItemId(item.getId()));
}
public static int getOldItemId(int id) {
if (id < 108) return id;
else if (id < 111) return 1;
else if (id < 122) return id - 3;
else if (id < 123) return 1;
else if (id < 464) return id - 4;
else if (id < 503) return 1;
else if (id < 585) return id - 43;
else if (id < 590) return 1;
else if (id < 609) return id - 48;
else if (id < 610) return 1;
else if (id < 642) return id - 49;
else if (id < 646) return 1;
else if (id < 710) return id - 53;
else if (id < 711) return 1;
else if (id < 716) return id - 54;
else if (id < 717) return 1;
else if (id < 720) return id - 55;
else if (id < 721) return 1;
else if (id < 846) return id - 56;
else return 1;
}
}

View File

@ -0,0 +1,189 @@
package us.myles.ViaVersion.protocols.protocol1_14to1_13_2.packets;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.minecraft.BlockChangeRecord;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
import us.myles.ViaVersion.api.protocol.Protocol;
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.types.Chunk1_13Type;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.Protocol1_14To1_13_2;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import java.util.Arrays;
public class WorldPackets {
public static void register(Protocol protocol) {
//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.passthrough(new Chunk1_13Type(clientWorld));
for (ChunkSection section : chunk.getSections()) {
if (section != null) {
for (int i = 0; i < section.getPalette().size(); i++) {
section.getPalette().set(i, Protocol1_14To1_13_2.getNewBlockStateId(section.getPalette().get(i)));
}
}
}
if (chunk.isBiomeData()) {
Arrays.fill(chunk.getBiomeData(), (byte) 1);
}
}
});
}
});
// Block Action
protocol.registerOutgoing(State.PLAY, 0x0A, 0x0A, new PacketRemapper() {
@Override
public void registerMap() {
map(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_14To1_13_2.getNewBlockId(wrapper.get(Type.VAR_INT, 0))); //TODO block ids
}
});
}
});
// Block Change
protocol.registerOutgoing(State.PLAY, 0xB, 0xB, new PacketRemapper() {
@Override
public void registerMap() {
map(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_14To1_13_2.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_14To1_13_2.getNewBlockStateId(id));
}
}
});
}
});
// Effect packet
protocol.registerOutgoing(State.PLAY, 0x23, 0x23, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // Effect Id
map(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 = InventoryPackets.getNewItemId(data));
} else if (id == 2001) { // Block break + block break sound
wrapper.set(Type.INT, 1, data = Protocol1_14To1_13_2.getNewBlockStateId(data));
}
}
});
}
});
//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);
}
});
}
});
//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);
}
});
}
});
//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) {
InventoryPackets.toClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM));
}
}
});
}
});
}
}

View File

@ -0,0 +1,33 @@
package us.myles.ViaVersion.protocols.protocol1_14to1_13_2.storage;
import com.google.common.base.Optional;
import us.myles.ViaVersion.api.data.StoredObject;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.entities.Entity1_14Types;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class EntityTracker extends StoredObject {
private final Map<Integer, Entity1_14Types.EntityType> clientEntityTypes = new ConcurrentHashMap<>();
public EntityTracker(UserConnection user) {
super(user);
}
public void removeEntity(int entityId) {
clientEntityTypes.remove(entityId);
}
public void addEntity(int entityId, Entity1_14Types.EntityType type) {
clientEntityTypes.put(entityId, type);
}
public boolean has(int entityId) {
return clientEntityTypes.containsKey(entityId);
}
public Optional<Entity1_14Types.EntityType> get(int id) {
return Optional.fromNullable(clientEntityTypes.get(id));
}
}