Merge 1.15 support

This commit is contained in:
Myles 2019-12-10 15:31:07 +00:00
commit 8136eb15e1
48 changed files with 28885 additions and 31 deletions

View File

@ -1,4 +1,4 @@
# ViaVersion 2.1.3 - Spigot, Sponge, BungeeCord, Velocity # ViaVersion 2.2.0 - Spigot, Sponge, BungeeCord, Velocity
[![Build Status](https://travis-ci.com/ViaVersion/ViaVersion.svg?branch=master)](https://travis-ci.com/ViaVersion/ViaVersion) [![Build Status](https://travis-ci.com/ViaVersion/ViaVersion.svg?branch=master)](https://travis-ci.com/ViaVersion/ViaVersion)
[![Discord](https://img.shields.io/badge/chat-on%20discord-blue.svg)](https://viaversion.com/discord) [![Discord](https://img.shields.io/badge/chat-on%20discord-blue.svg)](https://viaversion.com/discord)

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>viaversion-parent</artifactId> <artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId> <groupId>us.myles</groupId>
<version>2.1.4-SNAPSHOT</version> <version>2.2.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -279,4 +279,9 @@ public class BukkitViaConfig extends Config implements ViaVersionConfig {
public boolean is1_14HealthNaNFix() { public boolean is1_14HealthNaNFix() {
return getBoolean("fix-1_14-health-nan", true); return getBoolean("fix-1_14-health-nan", true);
} }
@Override
public boolean is1_15InstantRespawn() {
return getBoolean("use-1_15-instant-respawn", false);
}
} }

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>viaversion-parent</artifactId> <artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId> <groupId>us.myles</groupId>
<version>2.1.4-SNAPSHOT</version> <version>2.2.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -332,4 +332,9 @@ public class BungeeViaConfig extends Config implements ViaVersionConfig {
public boolean is1_14HealthNaNFix() { public boolean is1_14HealthNaNFix() {
return getBoolean("fix-1_14-health-nan", true); return getBoolean("fix-1_14-health-nan", true);
} }
@Override
public boolean is1_15InstantRespawn() {
return getBoolean("use-1_15-instant-respawn", false);
}
} }

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>viaversion-parent</artifactId> <artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId> <groupId>us.myles</groupId>
<version>2.1.4-SNAPSHOT</version> <version>2.2.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -346,4 +346,11 @@ public interface ViaVersionConfig {
boolean isNonFullBlockLightFix(); boolean isNonFullBlockLightFix();
boolean is1_14HealthNaNFix(); boolean is1_14HealthNaNFix();
/**
* Should 1.15 clients respawn instantly / without showing the death screen
*
* @return True if enabled
*/
boolean is1_15InstantRespawn();
} }

View File

@ -0,0 +1,248 @@
package us.myles.ViaVersion.api.entities;
import com.google.common.base.Optional;
import lombok.AllArgsConstructor;
import lombok.Getter;
import us.myles.ViaVersion.api.Via;
import java.util.HashMap;
import java.util.Map;
public class Entity1_15Types {
public static EntityType getTypeFromId(int typeID) {
Optional<EntityType> 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 {
ENTITY(-1),
AREA_EFFECT_CLOUD(0, ENTITY),
ENDER_CRYSTAL(18, ENTITY),
EVOCATION_FANGS(22, ENTITY),
XP_ORB(24, ENTITY),
EYE_OF_ENDER_SIGNAL(25, ENTITY),
FALLING_BLOCK(26, ENTITY),
FIREWORKS_ROCKET(27, ENTITY),
ITEM(35, ENTITY),
LLAMA_SPIT(40, ENTITY),
TNT(59, ENTITY),
SHULKER_BULLET(64, ENTITY),
FISHING_BOBBER(102, ENTITY),
LIVINGENTITY(-1, ENTITY),
ARMOR_STAND(1, LIVINGENTITY),
PLAYER(101, LIVINGENTITY),
ABSTRACT_INSENTIENT(-1, LIVINGENTITY),
ENDER_DRAGON(19, ABSTRACT_INSENTIENT),
BEE(4, ABSTRACT_INSENTIENT),
ABSTRACT_CREATURE(-1, ABSTRACT_INSENTIENT),
ABSTRACT_AGEABLE(-1, ABSTRACT_CREATURE),
VILLAGER(85, ABSTRACT_AGEABLE),
WANDERING_TRADER(89, ABSTRACT_AGEABLE),
// Animals
ABSTRACT_ANIMAL(-1, ABSTRACT_AGEABLE),
DOLPHIN(14, ABSTRACT_INSENTIENT),
CHICKEN(9, ABSTRACT_ANIMAL),
COW(11, ABSTRACT_ANIMAL),
MOOSHROOM(50, COW),
PANDA(53, ABSTRACT_INSENTIENT),
PIG(55, ABSTRACT_ANIMAL),
POLAR_BEAR(58, ABSTRACT_ANIMAL),
RABBIT(60, ABSTRACT_ANIMAL),
SHEEP(62, ABSTRACT_ANIMAL),
TURTLE(78, ABSTRACT_ANIMAL),
FOX(28, ABSTRACT_ANIMAL),
ABSTRACT_TAMEABLE_ANIMAL(-1, ABSTRACT_ANIMAL),
CAT(7, ABSTRACT_TAMEABLE_ANIMAL),
OCELOT(51, ABSTRACT_TAMEABLE_ANIMAL),
WOLF(94, ABSTRACT_TAMEABLE_ANIMAL),
ABSTRACT_PARROT(-1, ABSTRACT_TAMEABLE_ANIMAL),
PARROT(54, ABSTRACT_PARROT),
// Horses
ABSTRACT_HORSE(-1, ABSTRACT_ANIMAL),
CHESTED_HORSE(-1, ABSTRACT_HORSE),
DONKEY(13, CHESTED_HORSE),
MULE(49, CHESTED_HORSE),
LLAMA(39, CHESTED_HORSE),
TRADER_LLAMA(76, CHESTED_HORSE),
HORSE(32, ABSTRACT_HORSE),
SKELETON_HORSE(67, ABSTRACT_HORSE),
ZOMBIE_HORSE(96, ABSTRACT_HORSE),
// Golem
ABSTRACT_GOLEM(-1, ABSTRACT_CREATURE),
SNOWMAN(70, ABSTRACT_GOLEM),
VILLAGER_GOLEM(86, ABSTRACT_GOLEM),
SHULKER(63, ABSTRACT_GOLEM),
// Fish
ABSTRACT_FISHES(-1, ABSTRACT_CREATURE),
COD(10, ABSTRACT_FISHES),
PUFFER_FISH(56, ABSTRACT_FISHES),
SALMON_MOB(61, ABSTRACT_FISHES),
TROPICAL_FISH(77, ABSTRACT_FISHES),
// Monsters
ABSTRACT_MONSTER(-1, ABSTRACT_CREATURE),
BLAZE(5, ABSTRACT_MONSTER),
CREEPER(12, ABSTRACT_MONSTER),
ENDERMITE(21, ABSTRACT_MONSTER),
ENDERMAN(20, ABSTRACT_MONSTER),
GIANT(30, ABSTRACT_MONSTER),
SILVERFISH(65, ABSTRACT_MONSTER),
VEX(84, ABSTRACT_MONSTER),
WITCH(90, ABSTRACT_MONSTER),
WITHER(91, ABSTRACT_MONSTER),
RAVAGER(99, ABSTRACT_MONSTER),
// Illagers
ABSTRACT_ILLAGER_BASE(-1, ABSTRACT_MONSTER),
ABSTRACT_EVO_ILLU_ILLAGER(-1, ABSTRACT_ILLAGER_BASE),
EVOCATION_ILLAGER(23, ABSTRACT_EVO_ILLU_ILLAGER),
ILLUSION_ILLAGER(34, ABSTRACT_EVO_ILLU_ILLAGER),
VINDICATION_ILLAGER(87, ABSTRACT_ILLAGER_BASE),
PILLAGER(88, ABSTRACT_ILLAGER_BASE),
// Skeletons
ABSTRACT_SKELETON(-1, ABSTRACT_MONSTER),
SKELETON(66, ABSTRACT_SKELETON),
STRAY(75, ABSTRACT_SKELETON),
WITHER_SKELETON(92, ABSTRACT_SKELETON),
// Guardians
GUARDIAN(31, ABSTRACT_MONSTER),
ELDER_GUARDIAN(17, GUARDIAN),
// Spiders
SPIDER(73, ABSTRACT_MONSTER),
CAVE_SPIDER(8, SPIDER),
// Zombies
ZOMBIE(95, ABSTRACT_MONSTER),
DROWNED(16, ZOMBIE),
HUSK(33, ZOMBIE),
ZOMBIE_PIGMAN(57, ZOMBIE),
ZOMBIE_VILLAGER(97, ZOMBIE),
// Flying entities
ABSTRACT_FLYING(-1, ABSTRACT_INSENTIENT),
GHAST(29, ABSTRACT_FLYING),
PHANTOM(98, ABSTRACT_FLYING),
ABSTRACT_AMBIENT(-1, ABSTRACT_INSENTIENT),
BAT(3, ABSTRACT_AMBIENT),
ABSTRACT_WATERMOB(-1, ABSTRACT_INSENTIENT),
SQUID(74, ABSTRACT_WATERMOB),
// Slimes
SLIME(68, ABSTRACT_INSENTIENT),
MAGMA_CUBE(41, SLIME),
// Hangable objects
ABSTRACT_HANGING(-1, ENTITY),
LEASH_KNOT(38, ABSTRACT_HANGING),
ITEM_FRAME(36, ABSTRACT_HANGING),
PAINTING(52, ABSTRACT_HANGING),
ABSTRACT_LIGHTNING(-1, ENTITY),
LIGHTNING_BOLT(100, ABSTRACT_LIGHTNING),
// Arrows
ABSTRACT_ARROW(-1, ENTITY),
ARROW(2, ABSTRACT_ARROW),
SPECTRAL_ARROW(72, ABSTRACT_ARROW),
TRIDENT(83, ABSTRACT_ARROW),
// Fireballs
ABSTRACT_FIREBALL(-1, ENTITY),
DRAGON_FIREBALL(15, ABSTRACT_FIREBALL),
FIREBALL(37, ABSTRACT_FIREBALL),
SMALL_FIREBALL(69, ABSTRACT_FIREBALL),
WITHER_SKULL(93, ABSTRACT_FIREBALL),
// Projectiles
PROJECTILE_ABSTRACT(-1, ENTITY),
SNOWBALL(71, PROJECTILE_ABSTRACT),
ENDER_PEARL(80, PROJECTILE_ABSTRACT),
EGG(79, PROJECTILE_ABSTRACT),
POTION(82, PROJECTILE_ABSTRACT),
XP_BOTTLE(81, PROJECTILE_ABSTRACT),
// Vehicles
MINECART_ABSTRACT(-1, ENTITY),
CHESTED_MINECART_ABSTRACT(-1, MINECART_ABSTRACT),
CHEST_MINECART(43, CHESTED_MINECART_ABSTRACT),
HOPPER_MINECART(46, CHESTED_MINECART_ABSTRACT),
MINECART(42, MINECART_ABSTRACT),
FURNACE_MINECART(45, MINECART_ABSTRACT),
COMMANDBLOCK_MINECART(44, MINECART_ABSTRACT),
TNT_MINECART(48, MINECART_ABSTRACT),
SPAWNER_MINECART(47, MINECART_ABSTRACT),
BOAT(6, ENTITY);
private static final Map<Integer, EntityType> TYPES = new HashMap<>();
private final int id;
private final EntityType parent;
EntityType(int id) {
this.id = id;
this.parent = null;
}
static {
for (EntityType type : EntityType.values()) {
TYPES.put(type.id, type);
}
}
public static Optional<EntityType> findById(int id) {
if (id == -1)
return Optional.absent();
return Optional.fromNullable(TYPES.get(id));
}
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;
}
}
}

View File

@ -17,6 +17,8 @@ public interface Chunk {
int[] getBiomeData(); int[] getBiomeData();
void setBiomeData(int[] biomeData);
CompoundTag getHeightMap(); CompoundTag getHeightMap();
void setHeightMap(CompoundTag heightMap); void setHeightMap(CompoundTag heightMap);

View File

@ -4,7 +4,7 @@ import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import us.myles.ViaVersion.api.minecraft.metadata.MetaType; import us.myles.ViaVersion.api.minecraft.metadata.MetaType;
import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2; import us.myles.ViaVersion.api.type.types.version.Types1_13;
@RequiredArgsConstructor @RequiredArgsConstructor
@Getter @Getter
@ -24,7 +24,7 @@ public enum MetaType1_13 implements MetaType {
OptUUID(12, Type.OPTIONAL_UUID), OptUUID(12, Type.OPTIONAL_UUID),
BlockID(13, Type.VAR_INT), BlockID(13, Type.VAR_INT),
NBTTag(14, Type.NBT), NBTTag(14, Type.NBT),
PARTICLE(15, Protocol1_13To1_12_2.PARTICLE_TYPE), PARTICLE(15, Types1_13.PARTICLE),
Discontinued(99, null); Discontinued(99, null);
private final int typeID; private final int typeID;

View File

@ -4,7 +4,7 @@ import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import us.myles.ViaVersion.api.minecraft.metadata.MetaType; import us.myles.ViaVersion.api.minecraft.metadata.MetaType;
import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_13_2to1_13_1.Protocol1_13_2To1_13_1; import us.myles.ViaVersion.api.type.types.version.Types1_13_2;
@RequiredArgsConstructor @RequiredArgsConstructor
@Getter @Getter
@ -24,7 +24,7 @@ public enum MetaType1_13_2 implements MetaType {
OptUUID(12, Type.OPTIONAL_UUID), OptUUID(12, Type.OPTIONAL_UUID),
BlockID(13, Type.VAR_INT), BlockID(13, Type.VAR_INT),
NBTTag(14, Type.NBT), NBTTag(14, Type.NBT),
PARTICLE(15, Protocol1_13_2To1_13_1.PARTICLE_TYPE), PARTICLE(15, Types1_13_2.PARTICLE),
Discontinued(99, null); Discontinued(99, null);
private final int typeID; private final int typeID;

View File

@ -4,7 +4,7 @@ import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import us.myles.ViaVersion.api.minecraft.metadata.MetaType; import us.myles.ViaVersion.api.minecraft.metadata.MetaType;
import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_13_2to1_13_1.Protocol1_13_2To1_13_1; import us.myles.ViaVersion.api.type.types.version.Types1_14;
@RequiredArgsConstructor @RequiredArgsConstructor
@Getter @Getter
@ -24,7 +24,7 @@ public enum MetaType1_14 implements MetaType {
OptUUID(12, Type.OPTIONAL_UUID), OptUUID(12, Type.OPTIONAL_UUID),
BlockID(13, Type.VAR_INT), BlockID(13, Type.VAR_INT),
NBTTag(14, Type.NBT), NBTTag(14, Type.NBT),
PARTICLE(15, Protocol1_13_2To1_13_1.PARTICLE_TYPE), PARTICLE(15, Types1_14.PARTICLE),
VillagerData(16, Type.VILLAGER_DATA), VillagerData(16, Type.VILLAGER_DATA),
OptVarInt(17, Type.OPTIONAL_VAR_INT), OptVarInt(17, Type.OPTIONAL_VAR_INT),
Pose(18, Type.VAR_INT), Pose(18, Type.VAR_INT),

View File

@ -21,6 +21,7 @@ import us.myles.ViaVersion.protocols.protocol1_14_2to1_14_1.Protocol1_14_2To1_14
import us.myles.ViaVersion.protocols.protocol1_14_3to1_14_2.Protocol1_14_3To1_14_2; import us.myles.ViaVersion.protocols.protocol1_14_3to1_14_2.Protocol1_14_3To1_14_2;
import us.myles.ViaVersion.protocols.protocol1_14_4to1_14_3.Protocol1_14_4To1_14_3; import us.myles.ViaVersion.protocols.protocol1_14_4to1_14_3.Protocol1_14_4To1_14_3;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.Protocol1_14To1_13_2; import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.Protocol1_14To1_13_2;
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.Protocol1_15To1_14_4;
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_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_1to1_9.Protocol1_9_1To1_9;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.Protocol1_9_3To1_9_1_2; import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.Protocol1_9_3To1_9_1_2;
@ -70,6 +71,8 @@ public class ProtocolRegistry {
registerProtocol(new Protocol1_14_2To1_14_1(), Collections.singletonList(ProtocolVersion.v1_14_2.getId()), ProtocolVersion.v1_14_1.getId()); registerProtocol(new Protocol1_14_2To1_14_1(), Collections.singletonList(ProtocolVersion.v1_14_2.getId()), ProtocolVersion.v1_14_1.getId());
registerProtocol(new Protocol1_14_3To1_14_2(), Collections.singletonList(ProtocolVersion.v1_14_3.getId()), ProtocolVersion.v1_14_2.getId()); registerProtocol(new Protocol1_14_3To1_14_2(), Collections.singletonList(ProtocolVersion.v1_14_3.getId()), ProtocolVersion.v1_14_2.getId());
registerProtocol(new Protocol1_14_4To1_14_3(), Collections.singletonList(ProtocolVersion.v1_14_4.getId()), ProtocolVersion.v1_14_3.getId()); registerProtocol(new Protocol1_14_4To1_14_3(), Collections.singletonList(ProtocolVersion.v1_14_4.getId()), ProtocolVersion.v1_14_3.getId());
registerProtocol(new Protocol1_15To1_14_4(), Collections.singletonList(ProtocolVersion.v1_15.getId()), ProtocolVersion.v1_14_4.getId());
} }
/** /**

View File

@ -40,6 +40,7 @@ public class ProtocolVersion {
public static final ProtocolVersion v1_14_2; public static final ProtocolVersion v1_14_2;
public static final ProtocolVersion v1_14_3; public static final ProtocolVersion v1_14_3;
public static final ProtocolVersion v1_14_4; public static final ProtocolVersion v1_14_4;
public static final ProtocolVersion v1_15;
public static final ProtocolVersion unknown; public static final ProtocolVersion unknown;
private final int id; private final int id;
@ -76,6 +77,7 @@ public class ProtocolVersion {
register(v1_14_2 = new ProtocolVersion(485, "1.14.2")); register(v1_14_2 = new ProtocolVersion(485, "1.14.2"));
register(v1_14_3 = new ProtocolVersion(490, "1.14.3")); register(v1_14_3 = new ProtocolVersion(490, "1.14.3"));
register(v1_14_4 = new ProtocolVersion(498, "1.14.4")); register(v1_14_4 = new ProtocolVersion(498, "1.14.4"));
register(v1_15 = new ProtocolVersion(573, "1.15"));
register(unknown = new ProtocolVersion(-1, "UNKNOWN")); register(unknown = new ProtocolVersion(-1, "UNKNOWN"));
} }

View File

@ -1,4 +1,4 @@
package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data; package us.myles.ViaVersion.api.type.types;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;

View File

@ -0,0 +1,46 @@
package us.myles.ViaVersion.api.type.types.minecraft;
import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.Particle;
public class Particle1_14Type extends Type<Particle> {
public Particle1_14Type() {
super("Particle", Particle.class);
}
@Override
public void write(ByteBuf buffer, Particle object) throws Exception {
Type.VAR_INT.write(buffer, object.getId());
for (Particle.ParticleData data : object.getArguments())
data.getType().write(buffer, data.getValue());
}
@Override
public Particle read(ByteBuf buffer) throws Exception {
int type = Type.VAR_INT.read(buffer);
Particle particle = new Particle(type);
switch (type) {
// Block / Falling Dust /
case 3:
case 23:
particle.getArguments().add(new Particle.ParticleData(Type.VAR_INT, Type.VAR_INT.read(buffer))); // Flat Block
break;
// Dust
case 14:
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.read(buffer))); // Red 0 - 1
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.read(buffer))); // Green 0 - 1
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.read(buffer))); // Blue 0 - 1
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.read(buffer)));// Scale 0.01 - 4
break;
// Item
case 32:
particle.getArguments().add(new Particle.ParticleData(Type.FLAT_VAR_INT_ITEM, Type.FLAT_VAR_INT_ITEM.read(buffer))); // Flat item
break;
}
return particle;
}
}

View File

@ -3,6 +3,8 @@ package us.myles.ViaVersion.api.type.types.version;
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata; import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.Particle;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.types.Particle1_13Type;
import java.util.List; import java.util.List;
@ -18,4 +20,9 @@ public class Types1_13 {
public static final Type<Metadata> METADATA = new Metadata1_13Type(); public static final Type<Metadata> METADATA = new Metadata1_13Type();
public static final Type<ChunkSection> CHUNK_SECTION = new ChunkSectionType1_13(); public static final Type<ChunkSection> CHUNK_SECTION = new ChunkSectionType1_13();
/**
* Particle type for 1.13
*/
public static Type<Particle> PARTICLE = new Particle1_13Type();
} }

View File

@ -2,6 +2,8 @@ package us.myles.ViaVersion.api.type.types.version;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata; import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.Particle;
import us.myles.ViaVersion.protocols.protocol1_13_2to1_13_1.types.Particle1_13_2Type;
import java.util.List; import java.util.List;
@ -15,4 +17,9 @@ public class Types1_13_2 {
* Metadata type for 1.13 * Metadata type for 1.13
*/ */
public static final Type<Metadata> METADATA = new Metadata1_13_2Type(); public static final Type<Metadata> METADATA = new Metadata1_13_2Type();
/**
* Particle type for 1.13.2
*/
public static Type<Particle> PARTICLE = new Particle1_13_2Type();
} }

View File

@ -2,6 +2,8 @@ package us.myles.ViaVersion.api.type.types.version;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata; import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.Particle;
import us.myles.ViaVersion.api.type.types.minecraft.Particle1_14Type;
import java.util.List; import java.util.List;
@ -15,4 +17,9 @@ public class Types1_14 {
* Metadata type for 1.14 * Metadata type for 1.14
*/ */
public static final Type<Metadata> METADATA = new Metadata1_14Type(); public static final Type<Metadata> METADATA = new Metadata1_14Type();
/**
* Particle type for 1.14
*/
public static final Type<Particle> PARTICLE = new Particle1_14Type();
} }

View File

@ -11,10 +11,8 @@ import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_13_2to1_13_1.packets.EntityPackets; import us.myles.ViaVersion.protocols.protocol1_13_2to1_13_1.packets.EntityPackets;
import us.myles.ViaVersion.protocols.protocol1_13_2to1_13_1.packets.InventoryPackets; import us.myles.ViaVersion.protocols.protocol1_13_2to1_13_1.packets.InventoryPackets;
import us.myles.ViaVersion.protocols.protocol1_13_2to1_13_1.packets.WorldPackets; import us.myles.ViaVersion.protocols.protocol1_13_2to1_13_1.packets.WorldPackets;
import us.myles.ViaVersion.protocols.protocol1_13_2to1_13_1.types.Particle1_13_2Type;
public class Protocol1_13_2To1_13_1 extends Protocol { public class Protocol1_13_2To1_13_1 extends Protocol {
public static final Particle1_13_2Type PARTICLE_TYPE = new Particle1_13_2Type();
@Override @Override
protected void registerPackets() { protected void registerPackets() {

View File

@ -2,7 +2,7 @@ package us.myles.ViaVersion.protocols.protocol1_13_2to1_13_1.types;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.Particle; import us.myles.ViaVersion.api.type.types.Particle;
public class Particle1_13_2Type extends Type<Particle> { public class Particle1_13_2Type extends Type<Particle> {
public Particle1_13_2Type() { public Particle1_13_2Type() {

View File

@ -6,7 +6,7 @@ import us.myles.ViaVersion.api.entities.Entity1_13Types;
import us.myles.ViaVersion.api.minecraft.item.Item; import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata; import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_13; import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_13;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.Particle; import us.myles.ViaVersion.api.type.types.Particle;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.ParticleRewriter; import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.ParticleRewriter;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.InventoryPackets; import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.InventoryPackets;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.WorldPackets; import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.WorldPackets;

View File

@ -32,7 +32,6 @@ import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.BlockConnectio
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.BlockStorage; import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.BlockStorage;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.EntityTracker; import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.EntityTracker;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.TabCompleteTracker; import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.TabCompleteTracker;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.types.Particle1_13Type;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import us.myles.ViaVersion.util.GsonUtil; import us.myles.ViaVersion.util.GsonUtil;
@ -41,7 +40,6 @@ import java.util.Map;
// Development of 1.13 support! // Development of 1.13 support!
public class Protocol1_13To1_12_2 extends Protocol { public class Protocol1_13To1_12_2 extends Protocol {
public static final Particle1_13Type PARTICLE_TYPE = new Particle1_13Type();
public static final PacketHandler POS_TO_3_INT = new PacketHandler() { public static final PacketHandler POS_TO_3_INT = new PacketHandler() {
@Override @Override

View File

@ -5,6 +5,7 @@ import lombok.RequiredArgsConstructor;
import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.minecraft.item.Item; import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.Particle;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.InventoryPackets; import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.InventoryPackets;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.WorldPackets; import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.WorldPackets;

View File

@ -19,7 +19,7 @@ import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.blockconnections.Conne
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.blockconnections.ConnectionHandler; import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.blockconnections.ConnectionHandler;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData; import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.NamedSoundRewriter; import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.NamedSoundRewriter;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.Particle; import us.myles.ViaVersion.api.type.types.Particle;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.ParticleRewriter; import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.ParticleRewriter;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.providers.BlockEntityProvider; import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.providers.BlockEntityProvider;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.providers.PaintingProvider; import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.providers.PaintingProvider;

View File

@ -2,7 +2,7 @@ package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.types;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.Particle; import us.myles.ViaVersion.api.type.types.Particle;
// TODO make future proof // TODO make future proof
public class Particle1_13Type extends Type<Particle> { public class Particle1_13Type extends Type<Particle> {

View File

@ -9,7 +9,7 @@ import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata; import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_14; import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_14;
import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.Particle; import us.myles.ViaVersion.api.type.types.Particle;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.packets.InventoryPackets; import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.packets.InventoryPackets;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.storage.EntityTracker; import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.storage.EntityTracker;

View File

@ -83,7 +83,7 @@ public class MappingData {
} }
} }
private static void mapIdentifiers(Map<Integer, Integer> output, JsonObject oldIdentifiers, JsonObject newIdentifiers) { public static void mapIdentifiers(Map<Integer, Integer> output, JsonObject oldIdentifiers, JsonObject newIdentifiers) {
for (Map.Entry<String, JsonElement> entry : oldIdentifiers.entrySet()) { for (Map.Entry<String, JsonElement> entry : oldIdentifiers.entrySet()) {
Map.Entry<String, JsonElement> value = findValue(newIdentifiers, entry.getValue().getAsString()); Map.Entry<String, JsonElement> value = findValue(newIdentifiers, entry.getValue().getAsString());
if (value == null) { if (value == null) {
@ -147,10 +147,10 @@ public class MappingData {
int getNewSound(int old); int getNewSound(int old);
} }
private static class SoundMappingShortArray implements SoundMappings { public static class SoundMappingShortArray implements SoundMappings {
private short[] oldToNew; private short[] oldToNew;
private SoundMappingShortArray(JsonArray mapping1_13_2, JsonArray mapping1_14) { public SoundMappingShortArray(JsonArray mapping1_13_2, JsonArray mapping1_14) {
oldToNew = new short[mapping1_13_2.size()]; oldToNew = new short[mapping1_13_2.size()];
Arrays.fill(oldToNew, (short) -1); Arrays.fill(oldToNew, (short) -1);
mapIdentifiers(oldToNew, mapping1_13_2, mapping1_14); mapIdentifiers(oldToNew, mapping1_13_2, mapping1_14);
@ -166,10 +166,10 @@ public class MappingData {
int getNewBlock(int old); int getNewBlock(int old);
} }
private static class BlockMappingsShortArray implements BlockMappings { public static class BlockMappingsShortArray implements BlockMappings {
private short[] oldToNew; private short[] oldToNew;
private BlockMappingsShortArray(JsonObject mapping1_13_2, JsonObject mapping1_14) { public BlockMappingsShortArray(JsonObject mapping1_13_2, JsonObject mapping1_14) {
oldToNew = new short[mapping1_13_2.entrySet().size()]; oldToNew = new short[mapping1_13_2.entrySet().size()];
Arrays.fill(oldToNew, (short) -1); Arrays.fill(oldToNew, (short) -1);
mapIdentifiers(oldToNew, mapping1_13_2, mapping1_14); mapIdentifiers(oldToNew, mapping1_13_2, mapping1_14);

View File

@ -26,7 +26,6 @@ import java.util.UUID;
public class EntityPackets { public class EntityPackets {
public static void register(Protocol protocol) { public static void register(Protocol protocol) {
// Spawn entity // Spawn entity
protocol.registerOutgoing(State.PLAY, 0x00, 0x00, new PacketRemapper() { protocol.registerOutgoing(State.PLAY, 0x00, 0x00, new PacketRemapper() {
@Override @Override

View File

@ -0,0 +1,55 @@
package us.myles.ViaVersion.protocols.protocol1_15to1_14_4;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.entities.Entity1_15Types;
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_14;
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.packets.InventoryPackets;
import java.util.ArrayList;
import java.util.List;
public class MetadataRewriter {
public static void handleMetadata(int entityId, Entity1_15Types.EntityType type, List<Metadata> metadatas, UserConnection connection) {
for (Metadata metadata : new ArrayList<>(metadatas)) {
try {
if (metadata.getMetaType() == MetaType1_14.Slot) {
InventoryPackets.toClient((Item) metadata.getValue());
} else if (metadata.getMetaType() == MetaType1_14.BlockID) {
// Convert to new block id
int data = (int) metadata.getValue();
metadata.setValue(Protocol1_15To1_14_4.getNewBlockStateId(data));
}
if (type == null) continue;
// Metadata 12 added to abstract_living
if (metadata.getId() > 11 && type.isOrHasParent(Entity1_15Types.EntityType.LIVINGENTITY)) {
metadata.setId(metadata.getId() + 1); //TODO is it 11 or 12? what is it for?
}
//NOTES:
//new boolean with id 11 for trident, default = false, added in 19w45a
//new boolean with id 17 for enderman
if (type.isOrHasParent(Entity1_15Types.EntityType.WOLF)) {
if (metadata.getId() == 18) {
metadatas.remove(metadata);
} else if (metadata.getId() > 18) {
metadata.setId(metadata.getId() - 1);
}
}
} 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,274 @@
package us.myles.ViaVersion.protocols.protocol1_15to1_14_4;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.Via;
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_15to1_14_4.data.MappingData;
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.packets.EntityPackets;
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.packets.InventoryPackets;
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.packets.PlayerPackets;
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.packets.WorldPackets;
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.storage.EntityTracker;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
public class Protocol1_15To1_14_4 extends Protocol {
@Override
protected void registerPackets() {
MappingData.init();
EntityPackets.register(this);
PlayerPackets.register(this);
WorldPackets.register(this);
InventoryPackets.register(this);
// Entity Sound Effect (added somewhere in 1.14)
registerOutgoing(State.PLAY, 0x50, 0x51, 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, MappingData.soundMappings.getNewSound(wrapper.get(Type.VAR_INT, 0)));
}
});
}
});
// Sound Effect
registerOutgoing(State.PLAY, 0x51, 0x52, 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, MappingData.soundMappings.getNewSound(wrapper.get(Type.VAR_INT, 0)));
}
});
}
});
// Edit Book
registerIncoming(State.PLAY, 0x0C, 0x0D, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
InventoryPackets.toServer(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM));
}
});
}
});
// Advancements
registerOutgoing(State.PLAY, 0x57, 0x58, new PacketRemapper() {
@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
InventoryPackets.toClient(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
}
}
}
});
}
});
// Tags
registerOutgoing(State.PLAY, 0x5B, 0x5C, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
//TODO do the new (flower) tags have to be sent?
int blockTagsSize = wrapper.passthrough(Type.VAR_INT);
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);
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);
}
int entityTagsSize = wrapper.passthrough(Type.VAR_INT); // entity tags
for (int i = 0; i < entityTagsSize; i++) {
wrapper.passthrough(Type.STRING);
Integer[] entitIds = wrapper.passthrough(Type.VAR_INT_ARRAY);
for (int j = 0; j < entitIds.length; j++) {
entitIds[j] = EntityPackets.getNewEntityId(entitIds[j]);
}
}
}
});
}
});
registerOutgoing(State.PLAY, 0x08, 0x09);
registerOutgoing(State.PLAY, 0x09, 0x0A);
registerOutgoing(State.PLAY, 0x0C, 0x0D);
registerOutgoing(State.PLAY, 0x0D, 0x0E);
registerOutgoing(State.PLAY, 0x0E, 0x0F);
registerOutgoing(State.PLAY, 0x10, 0x11);
registerOutgoing(State.PLAY, 0x11, 0x12);
registerOutgoing(State.PLAY, 0x12, 0x13);
registerOutgoing(State.PLAY, 0x13, 0x14);
registerOutgoing(State.PLAY, 0x15, 0x16);
registerOutgoing(State.PLAY, 0x17, 0x18);
registerOutgoing(State.PLAY, 0x18, 0x19);
registerOutgoing(State.PLAY, 0x19, 0x1A);
registerOutgoing(State.PLAY, 0x1A, 0x1B);
registerOutgoing(State.PLAY, 0x1B, 0x1C);
registerOutgoing(State.PLAY, 0x1C, 0x1D);
registerOutgoing(State.PLAY, 0x1D, 0x1E);
registerOutgoing(State.PLAY, 0x1E, 0x1F);
registerOutgoing(State.PLAY, 0x1F, 0x20);
registerOutgoing(State.PLAY, 0x20, 0x21);
registerOutgoing(State.PLAY, 0x24, 0x25);
registerOutgoing(State.PLAY, 0x26, 0x27);
registerOutgoing(State.PLAY, 0x28, 0x29);
registerOutgoing(State.PLAY, 0x29, 0x2A);
registerOutgoing(State.PLAY, 0x2A, 0x2B);
registerOutgoing(State.PLAY, 0x2B, 0x2C);
registerOutgoing(State.PLAY, 0x2C, 0x2D);
registerOutgoing(State.PLAY, 0x2D, 0x2E);
registerOutgoing(State.PLAY, 0x2E, 0x2F);
registerOutgoing(State.PLAY, 0x2F, 0x30);
registerOutgoing(State.PLAY, 0x30, 0x31);
registerOutgoing(State.PLAY, 0x31, 0x32);
registerOutgoing(State.PLAY, 0x32, 0x33);
registerOutgoing(State.PLAY, 0x33, 0x34);
registerOutgoing(State.PLAY, 0x34, 0x35);
registerOutgoing(State.PLAY, 0x35, 0x36);
registerOutgoing(State.PLAY, 0x36, 0x37);
registerOutgoing(State.PLAY, 0x38, 0x39);
registerOutgoing(State.PLAY, 0x39, 0x3A);
registerOutgoing(State.PLAY, 0x3B, 0x3C);
registerOutgoing(State.PLAY, 0x3C, 0x3D);
registerOutgoing(State.PLAY, 0x3D, 0x3E);
registerOutgoing(State.PLAY, 0x3E, 0x3F);
registerOutgoing(State.PLAY, 0x3F, 0x40);
registerOutgoing(State.PLAY, 0x40, 0x41);
registerOutgoing(State.PLAY, 0x41, 0x42);
registerOutgoing(State.PLAY, 0x42, 0x43);
registerOutgoing(State.PLAY, 0x44, 0x45);
registerOutgoing(State.PLAY, 0x45, 0x46);
registerOutgoing(State.PLAY, 0x47, 0x48);
registerOutgoing(State.PLAY, 0x48, 0x49);
registerOutgoing(State.PLAY, 0x49, 0x4A);
registerOutgoing(State.PLAY, 0x4A, 0x4B);
registerOutgoing(State.PLAY, 0x4B, 0x4C);
registerOutgoing(State.PLAY, 0x4C, 0x4D);
registerOutgoing(State.PLAY, 0x4D, 0x4E);
registerOutgoing(State.PLAY, 0x4E, 0x4F);
registerOutgoing(State.PLAY, 0x4F, 0x50);
registerOutgoing(State.PLAY, 0x52, 0x53);
registerOutgoing(State.PLAY, 0x53, 0x54);
registerOutgoing(State.PLAY, 0x54, 0x55);
registerOutgoing(State.PLAY, 0x55, 0x56);
registerOutgoing(State.PLAY, 0x56, 0x57);
registerOutgoing(State.PLAY, 0x58, 0x59);
registerOutgoing(State.PLAY, 0x59, 0x5A);
registerOutgoing(State.PLAY, 0x5C, 0x08);
}
public static int getNewSoundId(int id) {
int newId = MappingData.soundMappings.getNewSound(id);
if (newId == -1) {
Via.getPlatform().getLogger().warning("Missing 1.15 sound for 1.14.4 sound " + id);
return 0;
}
return newId;
}
public static int getNewBlockStateId(int id) {
int newId = MappingData.blockStateMappings.getNewBlock(id);
if (newId == -1) {
Via.getPlatform().getLogger().warning("Missing 1.15 blockstate for 1.14.4 blockstate " + id);
return 0;
}
return newId;
}
public static int getNewBlockId(int id) {
int newId = MappingData.blockMappings.getNewBlock(id);
if (newId == -1) {
Via.getPlatform().getLogger().warning("Missing 1.15 block for 1.14.4 block " + id);
return 0;
}
return newId;
}
@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,27 @@
package us.myles.ViaVersion.protocols.protocol1_15to1_14_4.data;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.gson.JsonObject;
import us.myles.ViaVersion.api.Via;
public class MappingData {
public static BiMap<Integer, Integer> oldToNewItems = HashBiMap.create();
public static us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData.BlockMappings blockMappings;
public static us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData.BlockMappings blockStateMappings;
public static us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData.SoundMappings soundMappings;
public static void init() {
JsonObject mapping1_14_4 = us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData.loadData("mapping-1.14.4.json");
JsonObject mapping1_15 = us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData.loadData("mapping-1.15.json");
Via.getPlatform().getLogger().info("Loading 1.14.4 -> 1.15 blockstate mapping...");
blockStateMappings = new us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData.BlockMappingsShortArray(mapping1_14_4.getAsJsonObject("blockstates"), mapping1_15.getAsJsonObject("blockstates"));
Via.getPlatform().getLogger().info("Loading 1.14.4 -> 1.15 block mapping...");
blockMappings = new us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData.BlockMappingsShortArray(mapping1_14_4.getAsJsonObject("blocks"), mapping1_15.getAsJsonObject("blocks"));
Via.getPlatform().getLogger().info("Loading 1.14.4 -> 1.15 item mapping...");
us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData.mapIdentifiers(oldToNewItems, mapping1_14_4.getAsJsonObject("items"), mapping1_15.getAsJsonObject("items"));
Via.getPlatform().getLogger().info("Loading 1.14.4 -> 1.15 sound mapping...");
soundMappings = new us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData.SoundMappingShortArray(mapping1_14_4.getAsJsonArray("sounds"), mapping1_15.getAsJsonArray("sounds"));
}
}

View File

@ -0,0 +1,153 @@
package us.myles.ViaVersion.protocols.protocol1_15to1_14_4.packets;
import com.google.common.base.Optional;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.entities.Entity1_15Types;
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_14;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.MetadataRewriter;
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.Protocol1_15To1_14_4;
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.storage.EntityTracker;
import java.util.UUID;
public class EntityPackets {
public static void register(Protocol protocol) {
// Spawn entity
protocol.registerOutgoing(State.PLAY, 0x00, 0x00, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity id
map(Type.UUID); // 1 - UUID
map(Type.VAR_INT); // 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
map(Type.SHORT); // 9 - Velocity X
map(Type.SHORT); // 10 - Velocity Y
map(Type.SHORT); // 11 - Velocity Z
// Track Entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityId = wrapper.get(Type.VAR_INT, 0);
UUID uuid = wrapper.get(Type.UUID, 0);
int typeId = wrapper.get(Type.VAR_INT, 1);
Entity1_15Types.EntityType entityType = Entity1_15Types.getTypeFromId(getNewEntityId(typeId));
wrapper.user().get(EntityTracker.class).addEntity(entityId, entityType);
wrapper.set(Type.VAR_INT, 1, entityType.getId());
if (entityType == Entity1_15Types.EntityType.FALLING_BLOCK) {
wrapper.set(Type.INT, 0, Protocol1_15To1_14_4.getNewBlockStateId(wrapper.get(Type.INT, 0)));
}
}
});
}
});
// Spawn mob packet
protocol.registerOutgoing(State.PLAY, 0x03, 0x03, 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, Type.NOTHING); // removed - probably sent in an update packet?
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityId = wrapper.get(Type.VAR_INT, 0);
int typeId = wrapper.get(Type.VAR_INT, 1);
Entity1_15Types.EntityType entityType = Entity1_15Types.getTypeFromId(getNewEntityId(typeId));
wrapper.user().get(EntityTracker.class).addEntity(entityId, entityType);
wrapper.set(Type.VAR_INT, 1, entityType.getId());
}
});
}
});
// 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, Type.NOTHING); // removed - probably sent in an update packet?
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityId = wrapper.get(Type.VAR_INT, 0);
Entity1_15Types.EntityType entityType = Entity1_15Types.EntityType.PLAYER;
wrapper.user().get(EntityTracker.class).addEntity(entityId, entityType);
}
});
}
});
// Metadata packet
protocol.registerOutgoing(State.PLAY, 0x43, 0x44, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Types1_14.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_15Types.EntityType> type = wrapper.user().get(EntityTracker.class).get(entityId);
MetadataRewriter.handleMetadata(entityId, type.orNull(), wrapper.get(Types1_14.METADATA_LIST, 0), wrapper.user());
}
});
}
});
// Destroy entities
protocol.registerOutgoing(State.PLAY, 0x37, 0x38, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT_ARRAY);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
EntityTracker entityTracker = wrapper.user().get(EntityTracker.class);
for (int entity : wrapper.get(Type.VAR_INT_ARRAY, 0)) {
entityTracker.removeEntity(entity);
}
}
});
}
});
}
public static int getNewEntityId(int oldId) {
return oldId >= 4 ? oldId + 1 : oldId; // 4 = bee
}
}

View File

@ -0,0 +1,234 @@
package us.myles.ViaVersion.protocols.protocol1_15to1_14_4.packets;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.Via;
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;
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.data.MappingData;
public class InventoryPackets {
public static void register(Protocol protocol) {
// Window items packet
protocol.registerOutgoing(State.PLAY, 0x14, 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);
}
});
}
});
// Trade list packet
protocol.registerOutgoing(State.PLAY, 0x27, 0x28, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.passthrough(Type.VAR_INT);
int size = wrapper.passthrough(Type.UNSIGNED_BYTE);
for (int i = 0; i < size; i++) {
Item input = wrapper.passthrough(Type.FLAT_VAR_INT_ITEM);
toClient(input);
Item output = wrapper.passthrough(Type.FLAT_VAR_INT_ITEM);
toClient(output);
if (wrapper.passthrough(Type.BOOLEAN)) { // Has second item
// Second Item
Item second = wrapper.passthrough(Type.FLAT_VAR_INT_ITEM);
toClient(second);
}
wrapper.passthrough(Type.BOOLEAN); // Trade disabled
wrapper.passthrough(Type.INT); // Number of tools uses
wrapper.passthrough(Type.INT); // Maximum number of trade uses
wrapper.passthrough(Type.INT);
wrapper.passthrough(Type.INT);
wrapper.passthrough(Type.FLOAT);
wrapper.passthrough(Type.INT);
}
wrapper.passthrough(Type.VAR_INT);
wrapper.passthrough(Type.VAR_INT);
wrapper.passthrough(Type.BOOLEAN);
}
});
}
});
// Set slot packet
protocol.registerOutgoing(State.PLAY, 0x16, 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 {
toClient(wrapper.get(Type.FLAT_VAR_INT_ITEM, 0));
}
});
}
});
// Entity Equipment Packet
protocol.registerOutgoing(State.PLAY, 0x46, 0x47, 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 {
toClient(wrapper.get(Type.FLAT_VAR_INT_ITEM, 0));
}
});
}
});
// Declare Recipes
protocol.registerOutgoing(State.PLAY, 0x5A, 0x5B, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int size = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < size; i++) {
String type = wrapper.passthrough(Type.STRING).replace("minecraft:", "");
String id = wrapper.passthrough(Type.STRING);
switch (type) {
case "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) toClient(item);
}
toClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Result
break;
}
case "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) toClient(item);
}
toClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Result
break;
}
case "blasting":
case "smoking":
case "campfire_cooking":
case "smelting": {
wrapper.passthrough(Type.STRING); // Group
Item[] items = wrapper.passthrough(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT); // Ingredients
for (Item item : items) toClient(item);
toClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM));
wrapper.passthrough(Type.FLOAT); // EXP
wrapper.passthrough(Type.VAR_INT); // Cooking time
break;
}
case "stonecutting": {
wrapper.passthrough(Type.STRING);
Item[] items = wrapper.passthrough(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT); // Ingredients
for (Item item : items) toClient(item);
toClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM));
break;
}
}
}
}
});
}
});
// Click window packet
protocol.registerIncoming(State.PLAY, 0x09, 0x09, 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 {
toServer(wrapper.get(Type.FLAT_VAR_INT_ITEM, 0));
}
});
}
});
// Creative Inventory Action
protocol.registerIncoming(State.PLAY, 0x26, 0x26, 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 {
toServer(wrapper.get(Type.FLAT_VAR_INT_ITEM, 0));
}
});
}
});
}
public static void toClient(Item item) {
if (item == null) return;
item.setIdentifier(getNewItemId(item.getIdentifier()));
}
public static void toServer(Item item) {
if (item == null) return;
item.setIdentifier(getOldItemId(item.getIdentifier()));
}
public static int getNewItemId(int id) {
Integer newId = MappingData.oldToNewItems.get(id);
if (newId == null) {
Via.getPlatform().getLogger().warning("Missing 1.15 item for 1.14 item " + id);
return 1;
}
return newId;
}
public static int getOldItemId(int id) {
Integer oldId = MappingData.oldToNewItems.inverse().get(id);
return oldId != null ? oldId : 1;
}
}

View File

@ -0,0 +1,91 @@
package us.myles.ViaVersion.protocols.protocol1_15to1_14_4.packets;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.entities.Entity1_15Types;
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.remapper.ValueCreator;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.storage.EntityTracker;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
public class PlayerPackets {
public static void register(Protocol protocol) {
// Respawn
protocol.registerOutgoing(State.PLAY, 0x3A, 0x3B, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT);
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);
}
});
create(new ValueCreator() {
@Override
public void write(PacketWrapper wrapper) throws Exception {
wrapper.write(Type.LONG, 0L); // Level Seed
}
});
}
});
// Join Game
protocol.registerOutgoing(State.PLAY, 0x25, 0x26, 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 {
Entity1_15Types.EntityType entType = Entity1_15Types.EntityType.PLAYER;
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
tracker.addEntity(wrapper.get(Type.INT, 0), entType);
}
});
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);
// Register Type ID
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
int entityId = wrapper.get(Type.INT, 0);
tracker.addEntity(entityId, Entity1_15Types.EntityType.PLAYER);
}
});
create(new ValueCreator() {
@Override
public void write(PacketWrapper wrapper) throws Exception {
wrapper.write(Type.LONG, 0L); // Level Seed
}
});
map(Type.UNSIGNED_BYTE); // 3 - Max Players
map(Type.STRING); // 4 - Level Type
map(Type.VAR_INT); // 5 - View Distance
map(Type.BOOLEAN); // 6 - Reduce Debug Info
create(new ValueCreator() {
@Override
public void write(PacketWrapper wrapper) throws Exception {
wrapper.write(Type.BOOLEAN, !Via.getConfig().is1_15InstantRespawn()); // Show Death Screen
}
});
}
});
}
}

View File

@ -0,0 +1,170 @@
package us.myles.ViaVersion.protocols.protocol1_15to1_14_4.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_14to1_13_2.types.Chunk1_14Type;
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.Protocol1_15To1_14_4;
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.types.Chunk1_15Type;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
public class WorldPackets {
public static void register(Protocol protocol) {
// Block Action
protocol.registerOutgoing(State.PLAY, 0x0A, 0x0B, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.POSITION1_14); // 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_15To1_14_4.getNewBlockId(wrapper.get(Type.VAR_INT, 0)));
}
});
}
});
// Block Change
protocol.registerOutgoing(State.PLAY, 0x0B, 0x0C, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.POSITION1_14);
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_15To1_14_4.getNewBlockStateId(id));
}
});
}
});
// Multi Block Change
protocol.registerOutgoing(State.PLAY, 0x0F, 0x10, 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_15To1_14_4.getNewBlockStateId(id));
}
}
});
}
});
// Chunk Data
protocol.registerOutgoing(State.PLAY, 0x21, 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_15Type(clientWorld), chunk);
if (chunk.isGroundUp()) {
int[] biomeData = chunk.getBiomeData();
int[] newBiomeData = new int[1024];
// Now in 4x4x4 areas - take the biome of each "middle"
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
int x = (j << 2) + 2;
int z = (i << 2) + 2;
int oldIndex = (z << 4 | x);
newBiomeData[i << 2 | j] = biomeData[oldIndex];
}
}
// ... and copy it to the new y layers
for (int i = 1; i < 64; ++i) {
System.arraycopy(newBiomeData, 0, newBiomeData, i * 16, 16);
}
chunk.setBiomeData(newBiomeData);
}
for (int s = 0; s < 16; s++) {
ChunkSection section = chunk.getSections()[s];
if (section == null) continue;
for (int i = 0; i < section.getPaletteSize(); i++) {
int old = section.getPaletteEntry(i);
int newId = Protocol1_15To1_14_4.getNewBlockStateId(old);
section.setPaletteEntry(i, newId);
}
}
}
});
}
});
// Effect
protocol.registerOutgoing(State.PLAY, 0x22, 0x23, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // Effect Id
map(Type.POSITION1_14); // 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, InventoryPackets.getNewItemId(data));
} else if (id == 2001) { // Block break + block break sound
wrapper.set(Type.INT, 1, data = Protocol1_15To1_14_4.getNewBlockStateId(data));
}
}
});
}
});
// Spawn Particle
protocol.registerOutgoing(State.PLAY, 0x23, 0x24, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Particle ID
map(Type.BOOLEAN); // 1 - Long Distance
map(Type.FLOAT, Type.DOUBLE); // 2 - X
map(Type.FLOAT, Type.DOUBLE); // 3 - Y
map(Type.FLOAT, Type.DOUBLE); // 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 == 23) {
int data = wrapper.passthrough(Type.VAR_INT);
wrapper.set(Type.VAR_INT, 0, Protocol1_15To1_14_4.getNewBlockStateId(data));
} else if (id == 32) {
InventoryPackets.toClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM));
}
}
});
}
});
}
}

View File

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

View File

@ -0,0 +1,114 @@
package us.myles.ViaVersion.protocols.protocol1_15to1_14_4.types;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.minecraft.chunks.BaseChunk;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
import us.myles.ViaVersion.api.type.PartialType;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.minecraft.BaseChunkType;
import us.myles.ViaVersion.api.type.types.version.Types1_13;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.List;
public class Chunk1_15Type extends PartialType<Chunk, ClientWorld> {
public Chunk1_15Type(ClientWorld param) {
super(param, Chunk.class);
}
@Override
public Chunk read(ByteBuf input, ClientWorld world) throws Exception {
int chunkX = input.readInt();
int chunkZ = input.readInt();
boolean groundUp = input.readBoolean();
int primaryBitmask = Type.VAR_INT.read(input);
CompoundTag heightMap = Type.NBT.read(input);
int[] biomeData = groundUp ? new int[1024] : null;
if (groundUp) {
for (int i = 0; i < 1024; i++) {
biomeData[i] = input.readInt();
}
}
Type.VAR_INT.read(input);
BitSet usedSections = new BitSet(16);
ChunkSection[] sections = new ChunkSection[16];
// Calculate section count from bitmask
for (int i = 0; i < 16; i++) {
if ((primaryBitmask & (1 << i)) != 0) {
usedSections.set(i);
}
}
// Read sections
for (int i = 0; i < 16; i++) {
if (!usedSections.get(i)) continue; // Section not set
short nonAirBlocksCount = input.readShort();
ChunkSection section = Types1_13.CHUNK_SECTION.read(input);
section.setNonAirBlocksCount(nonAirBlocksCount);
sections[i] = section;
}
List<CompoundTag> nbtData = new ArrayList<>(Arrays.asList(Type.NBT_ARRAY.read(input)));
// Read all the remaining bytes (workaround for #681)
if (input.readableBytes() > 0) {
byte[] array = Type.REMAINING_BYTES.read(input);
if (Via.getManager().isDebug()) {
Via.getPlatform().getLogger().warning("Found " + array.length + " more bytes than expected while reading the chunk: " + chunkX + "/" + chunkZ);
}
}
return new BaseChunk(chunkX, chunkZ, groundUp, primaryBitmask, sections, biomeData, heightMap, nbtData);
}
@Override
public void write(ByteBuf output, ClientWorld world, Chunk chunk) throws Exception {
output.writeInt(chunk.getX());
output.writeInt(chunk.getZ());
output.writeBoolean(chunk.isGroundUp());
Type.VAR_INT.write(output, chunk.getBitmask());
Type.NBT.write(output, chunk.getHeightMap());
// Write biome data
if (chunk.isBiomeData()) {
for (int value : chunk.getBiomeData()) {
output.writeInt(value);
}
}
ByteBuf buf = output.alloc().buffer();
try {
for (int i = 0; i < 16; i++) {
ChunkSection section = chunk.getSections()[i];
if (section == null) continue; // Section not set
buf.writeShort(section.getNonAirBlocksCount());
Types1_13.CHUNK_SECTION.write(buf, section);
}
buf.readerIndex(0);
Type.VAR_INT.write(output, buf.readableBytes());
output.writeBytes(buf);
} finally {
buf.release(); // release buffer
}
// Write Block Entities
Type.NBT_ARRAY.write(output, chunk.getBlockEntities().toArray(new CompoundTag[0]));
}
@Override
public Class<? extends Type> getBaseClass() {
return BaseChunkType.class;
}
}

View File

@ -130,6 +130,8 @@ change-1_14-hitbox: false
fix-non-full-blocklight: true fix-non-full-blocklight: true
# Fixes walk animation not shown when health is set to Float.NaN # Fixes walk animation not shown when health is set to Float.NaN
fix-1_14-health-nan: true fix-1_14-health-nan: true
# Should 1.15+ clients respawn instantly / without showing a death screen?
use-1_15-instant-respawn: false
# #
# Enable serverside block-connections for 1.13+ clients # Enable serverside block-connections for 1.13+ clients
serverside-blockconnections: false serverside-blockconnections: false

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>viaversion-parent</artifactId> <artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId> <groupId>us.myles</groupId>
<version>2.1.4-SNAPSHOT</version> <version>2.2.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<name>viaversion-jar</name> <name>viaversion-jar</name>

View File

@ -6,7 +6,7 @@
<groupId>us.myles</groupId> <groupId>us.myles</groupId>
<artifactId>viaversion-parent</artifactId> <artifactId>viaversion-parent</artifactId>
<version>2.1.4-SNAPSHOT</version> <version>2.2.0</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>viaversion-parent</name> <name>viaversion-parent</name>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>viaversion-parent</artifactId> <artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId> <groupId>us.myles</groupId>
<version>2.1.4-SNAPSHOT</version> <version>2.2.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>viaversion-parent</artifactId> <artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId> <groupId>us.myles</groupId>
<version>2.1.4-SNAPSHOT</version> <version>2.2.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -285,4 +285,9 @@ public class SpongeViaConfig extends Config implements ViaVersionConfig {
public boolean is1_14HealthNaNFix() { public boolean is1_14HealthNaNFix() {
return getBoolean("fix-1_14-health-nan", true); return getBoolean("fix-1_14-health-nan", true);
} }
@Override
public boolean is1_15InstantRespawn() {
return getBoolean("use-1_15-instant-respawn", false);
}
} }

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>viaversion-parent</artifactId> <artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId> <groupId>us.myles</groupId>
<version>2.1.4-SNAPSHOT</version> <version>2.2.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -338,4 +338,9 @@ public class VelocityViaConfig extends Config implements ViaVersionConfig {
public boolean is1_14HealthNaNFix() { public boolean is1_14HealthNaNFix() {
return getBoolean("fix-1_14-health-nan", true); return getBoolean("fix-1_14-health-nan", true);
} }
@Override
public boolean is1_15InstantRespawn() {
return getBoolean("use-1_15-instant-respawn", false);
}
} }