diff --git a/bukkit/pom.xml b/bukkit/pom.xml
index 6ca316f2a..2f90c95f4 100644
--- a/bukkit/pom.xml
+++ b/bukkit/pom.xml
@@ -5,7 +5,7 @@
viaversion-parent
us.myles
- 2.1.4-19w39a
+ 2.1.4-19w40a
4.0.0
diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/multiversion/PlayerSneakListener.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/multiversion/PlayerSneakListener.java
index a44dc1e74..867561286 100644
--- a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/multiversion/PlayerSneakListener.java
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/multiversion/PlayerSneakListener.java
@@ -31,18 +31,24 @@ public class PlayerSneakListener extends ViaBukkitListener {
private boolean is1_14Fix;
private boolean useCache;
- public PlayerSneakListener(ViaVersionPlugin plugin, boolean is1_9Fix, boolean is1_14Fix) {
+ public PlayerSneakListener(ViaVersionPlugin plugin, boolean is1_9Fix, boolean is1_14Fix) throws ReflectiveOperationException {
super(plugin, null);
this.is1_9Fix = is1_9Fix;
this.is1_14Fix = is1_14Fix;
+
+ final String packageName = plugin.getServer().getClass().getPackage().getName();
+ getHandle = Class.forName(packageName + ".entity.CraftPlayer").getMethod("getHandle");
+
+ final Class> entityPlayerClass = Class.forName(packageName
+ .replace("org.bukkit.craftbukkit", "net.minecraft.server") + ".EntityPlayer");
try {
- getHandle = Class.forName(plugin.getServer().getClass().getPackage().getName() + ".entity.CraftPlayer").getMethod("getHandle");
- setSize = Class.forName(plugin.getServer().getClass().getPackage().getName()
- .replace("org.bukkit.craftbukkit", "net.minecraft.server") + ".EntityPlayer").getMethod("setSize", Float.TYPE, Float.TYPE);
- } catch (ClassNotFoundException | NoSuchMethodException e) {
- e.printStackTrace();
+ setSize = entityPlayerClass.getMethod("setSize", Float.TYPE, Float.TYPE);
+ } catch (NoSuchMethodException e) {
+ // Don't catch this one
+ setSize = entityPlayerClass.getMethod("a", Float.TYPE, Float.TYPE);
}
+
// From 1.9 upwards the server hitbox is set in every entity tick, so we have to reset it everytime
if (ProtocolRegistry.SERVER_PROTOCOL >= ProtocolVersion.v1_9.getId()) {
sneaking = new WeakHashMap<>();
diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaConfig.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaConfig.java
index 74caf6135..fa486666b 100644
--- a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaConfig.java
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaConfig.java
@@ -270,6 +270,16 @@ public class BukkitViaConfig extends Config implements ViaVersionConfig {
return getBoolean("change-1_14-hitbox", false);
}
+ @Override
+ public boolean isNonFullBlockLightFix() {
+ return getBoolean("fix-non-full-blocklight", true);
+ }
+
+ @Override
+ public boolean is1_14HealthNaNFix() {
+ return getBoolean("fix-1_14-health-nan", true);
+ }
+
@Override
public boolean is1_15InstantRespawn() {
return getBoolean("use-1_15-instant-respawn", false);
diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaLoader.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaLoader.java
index b2e3e82e8..feb7acdfc 100644
--- a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaLoader.java
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaLoader.java
@@ -82,7 +82,12 @@ public class BukkitViaLoader implements ViaPlatformLoader {
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_14.getId()) {
boolean use1_9Fix = plugin.getConf().is1_9HitboxFix() && ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getId();
if (use1_9Fix || plugin.getConf().is1_14HitboxFix()) {
- storeListener(new PlayerSneakListener(plugin, use1_9Fix, plugin.getConf().is1_14HitboxFix())).register();
+ try {
+ storeListener(new PlayerSneakListener(plugin, use1_9Fix, plugin.getConf().is1_14HitboxFix())).register();
+ } catch (ReflectiveOperationException e) {
+ Via.getPlatform().getLogger().warning("Could not load hitbox fix - please report this on our GitHub");
+ e.printStackTrace();
+ }
}
}
diff --git a/bungee/pom.xml b/bungee/pom.xml
index f2a529fce..2c48434b0 100644
--- a/bungee/pom.xml
+++ b/bungee/pom.xml
@@ -5,7 +5,7 @@
viaversion-parent
us.myles
- 2.1.4-19w39a
+ 2.1.4-19w40a
4.0.0
diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeServerHandler.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeServerHandler.java
index 9808f1c2b..e2c5421ff 100644
--- a/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeServerHandler.java
+++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeServerHandler.java
@@ -66,6 +66,10 @@ public class BungeeServerHandler implements Listener {
// Set the handshake version every time someone connects to any server
@EventHandler
public void onServerConnect(ServerConnectEvent e) {
+ if (e.isCancelled()) {
+ return;
+ }
+
UserConnection user = Via.getManager().getConnection(e.getPlayer().getUniqueId());
if (user == null) return;
if (!user.has(BungeeStorage.class)) {
diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaConfig.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaConfig.java
index 678fb449d..99f37deab 100644
--- a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaConfig.java
+++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaConfig.java
@@ -323,6 +323,16 @@ public class BungeeViaConfig extends Config implements ViaVersionConfig {
return false;
}
+ @Override
+ public boolean isNonFullBlockLightFix() {
+ return getBoolean("fix-non-full-blocklight", true);
+ }
+
+ @Override
+ public boolean is1_14HealthNaNFix() {
+ return getBoolean("fix-1_14-health-nan", true);
+ }
+
@Override
public boolean is1_15InstantRespawn() {
return getBoolean("use-1_15-instant-respawn", false);
diff --git a/common/pom.xml b/common/pom.xml
index 479d5bf03..ae3f0a5b6 100644
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -5,7 +5,7 @@
viaversion-parent
us.myles
- 2.1.4-19w39a
+ 2.1.4-19w40a
4.0.0
diff --git a/common/src/main/java/us/myles/ViaVersion/api/ViaVersionConfig.java b/common/src/main/java/us/myles/ViaVersion/api/ViaVersionConfig.java
index 4fa64b5af..48f0514b7 100644
--- a/common/src/main/java/us/myles/ViaVersion/api/ViaVersionConfig.java
+++ b/common/src/main/java/us/myles/ViaVersion/api/ViaVersionConfig.java
@@ -338,6 +338,15 @@ public interface ViaVersionConfig {
*/
boolean is1_14HitboxFix();
+ /**
+ * Fixes non full blocks having 0 light for 1.14+ clients on sub 1.14 servers.
+ *
+ * @return True if enabled
+ */
+ boolean isNonFullBlockLightFix();
+
+ boolean is1_14HealthNaNFix();
+
/**
* Should 1.15 clients respawn instantly / without showing the death screen
*
diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java
index f0e585a77..166f86516 100644
--- a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java
+++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java
@@ -175,10 +175,18 @@ public class ChunkSection {
return blockLight == null ? null : blockLight.getHandle();
}
+ public NibbleArray getBlockLightNibbleArray() {
+ return blockLight;
+ }
+
public byte[] getSkyLight() {
return skyLight == null ? null : skyLight.getHandle();
}
+ public NibbleArray getSkyLightNibbleArray() {
+ return skyLight;
+ }
+
public void readBlockLight(ByteBuf input) {
if (this.blockLight == null) {
this.blockLight = new NibbleArray(LIGHT_LENGTH * 2);
@@ -193,7 +201,7 @@ public class ChunkSection {
input.readBytes(this.skyLight.getHandle());
}
- private static int index(int x, int y, int z) {
+ public static int index(int x, int y, int z) {
return y << 8 | z << 4 | x;
}
diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/NibbleArray.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/NibbleArray.java
index 4cfeddccc..3e1282214 100644
--- a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/NibbleArray.java
+++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/NibbleArray.java
@@ -30,7 +30,7 @@ public class NibbleArray {
* @return The value at the given XYZ
*/
public byte get(int x, int y, int z) {
- return get(y << 8 | z << 4 | x);
+ return get(ChunkSection.index(x, y, z));
}
/**
@@ -57,7 +57,7 @@ public class NibbleArray {
* @param value Desired Value
*/
public void set(int x, int y, int z, int value) {
- set(y << 8 | z << 4 | x, value);
+ set(ChunkSection.index(x, y, z), value);
}
/**
diff --git a/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolVersion.java b/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolVersion.java
index 4e156c956..9d144392a 100644
--- a/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolVersion.java
+++ b/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolVersion.java
@@ -77,7 +77,7 @@ public class ProtocolVersion {
register(v1_14_2 = new ProtocolVersion(485, "1.14.2"));
register(v1_14_3 = new ProtocolVersion(490, "1.14.3"));
register(v1_14_4 = new ProtocolVersion(498, "1.14.4"));
- register(v1_15 = new ProtocolVersion(556, "1.15"));
+ register(v1_15 = new ProtocolVersion(557, "1.15"));
register(unknown = new ProtocolVersion(-1, "UNKNOWN"));
}
diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/Protocol1_11To1_10.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/Protocol1_11To1_10.java
index 9fb7345c1..3d1ef411c 100644
--- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/Protocol1_11To1_10.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_11to1_10/Protocol1_11To1_10.java
@@ -378,34 +378,33 @@ public class Protocol1_11To1_10 extends Protocol {
});
}
- private int getNewSoundId(int id) { //TODO Make it better, suggestions are welcome. It's ugly and hardcoded now.
+ private int getNewSoundId(int id) {
if (id == 196) // Experience orb sound got removed
return -1;
- int newId = id;
- if (id >= 85) // Hello shulker boxes
- newId += 2;
- if (id >= 174) // Hello Guardian flop
- newId += 1;
- if (id >= 194) // Hello evocation things
- newId += 8;
+ if (id >= 85) // Shulker boxes
+ id += 2;
+ if (id >= 176) // Guardian flop
+ id += 1;
+ if (id >= 197) // evocation things
+ id += 8;
if (id >= 196) // Rip the Experience orb touch sound :'(
- newId -= 1;
- if (id >= 269) // Hello Liama's
- newId += 9;
- if (id >= 277) // Hello Mule chest
- newId += 1;
- if (id >= 370) // Hello Vex
- newId += 4;
- if (id >= 376) // Hello vindication
- newId += 3;
- if (id >= 423) // Equip Elytra
- newId += 1;
- if (id >= 427) // Hello empty bottle
- newId += 1;
- if (id >= 441) // Hello item totem use
- newId += 1;
- return newId;
+ id -= 1;
+ if (id >= 279) // Liama's
+ id += 9;
+ if (id >= 296) // Mule chest
+ id += 1;
+ if (id >= 390) // Vex
+ id += 4;
+ if (id >= 400) // vindication
+ id += 3;
+ if (id >= 450) // Elytra
+ id += 1;
+ if (id >= 455) // Empty bottle
+ id += 1;
+ if (id >= 470) // Totem use
+ id += 1;
+ return id;
}
diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/InventoryPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/InventoryPackets.java
index c9aed32b9..76d7f9290 100644
--- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/InventoryPackets.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/InventoryPackets.java
@@ -513,8 +513,12 @@ public class InventoryPackets {
return "wdl:request";
case "bungeecord:main":
return null;
+ case "FML|MP":
+ return "fml:mp";
+ case "FML|HS":
+ return "fml:hs";
default:
- return old.matches("([0-9a-z_.-]*:)?[0-9a-z_/.-]*") // Identifier regex
+ return old.matches("([0-9a-z_.-]+):([0-9a-z_/.-]+)") // Identifier regex
? old : null;
}
}
@@ -719,7 +723,7 @@ public class InventoryPackets {
}
public static String getOldPluginChannelId(String newId) {
- if (!newId.matches("([0-9a-z_.-]*:)?[0-9a-z_/.-]*")) {
+ if (!newId.matches("([0-9a-z_.-]+):([0-9a-z_/.-]+)")) {
return null; // Not valid
}
int separatorIndex = newId.indexOf(':');
@@ -750,6 +754,10 @@ public class InventoryPackets {
return "WDL|CONTROL";
case "wdl:request":
return "WDL|REQUEST";
+ case "fml:hs":
+ return "FML|HS";
+ case "fml:mp":
+ return "FML:MP";
default:
return newId.length() > 20 ? newId.substring(0, 20) : newId;
}
diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14_1to1_14/Protocol1_14_1To1_14.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14_1to1_14/Protocol1_14_1To1_14.java
index 77b4182ef..b3ceab226 100644
--- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14_1to1_14/Protocol1_14_1To1_14.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14_1to1_14/Protocol1_14_1To1_14.java
@@ -7,13 +7,13 @@ import us.myles.ViaVersion.protocols.protocol1_14_1to1_14.storage.EntityTracker;
public class Protocol1_14_1To1_14 extends Protocol {
- @Override
- protected void registerPackets() {
- EntityPackets.register(this);
- }
+ @Override
+ protected void registerPackets() {
+ EntityPackets.register(this);
+ }
- @Override
- public void init(UserConnection userConnection) {
- userConnection.put(new EntityTracker(userConnection));
- }
+ @Override
+ public void init(UserConnection userConnection) {
+ userConnection.put(new EntityTracker(userConnection));
+ }
}
diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14_1to1_14/packets/EntityPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14_1to1_14/packets/EntityPackets.java
index 7d7373909..6ff07ac6b 100644
--- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14_1to1_14/packets/EntityPackets.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14_1to1_14/packets/EntityPackets.java
@@ -14,88 +14,104 @@ import us.myles.ViaVersion.protocols.protocol1_14_1to1_14.storage.EntityTracker;
public class EntityPackets {
- public static void register(Protocol protocol) {
+ public static void register(Protocol protocol) {
- // Spawn Mob
- protocol.registerOutgoing(State.PLAY, 0x03, 0x03, new PacketRemapper() {
- @Override
- public void registerMap() {
- map(Type.VAR_INT); // 0 - Entity ID
- map(Type.UUID); // 1 - 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); // 12 - Metadata
+ // Spawn Mob
+ protocol.registerOutgoing(State.PLAY, 0x03, 0x03, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.VAR_INT); // 0 - Entity ID
+ map(Type.UUID); // 1 - 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); // 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);
+ 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);
- Entity1_14Types.EntityType entType = Entity1_14Types.getTypeFromId(type);
+ Entity1_14Types.EntityType entType = Entity1_14Types.getTypeFromId(type);
- // Register Type ID
- wrapper.user().get(EntityTracker.class).addEntity(entityId, entType);
+ // Register Type ID
+ wrapper.user().get(EntityTracker.class).addEntity(entityId, entType);
- MetadataRewriter.handleMetadata(entityId, entType, wrapper.get(Types1_14.METADATA_LIST, 0), wrapper.user());
- }
- });
- }
- });
+ MetadataRewriter.handleMetadata(entityId, entType, wrapper.get(Types1_14.METADATA_LIST, 0), wrapper.user());
+ }
+ });
+ }
+ });
- // Spawn Player
- protocol.registerOutgoing(State.PLAY, 0x05, 0x05, new PacketRemapper() {
- @Override
- public void registerMap() {
- map(Type.VAR_INT); // 0 - Entity ID
- map(Type.UUID); // 1 - Player UUID
- map(Type.DOUBLE); // 2 - X
- map(Type.DOUBLE); // 3 - Y
- map(Type.DOUBLE); // 4 - Z
- map(Type.BYTE); // 5 - Yaw
- map(Type.BYTE); // 6 - Pitch
- map(Types1_14.METADATA_LIST); // 7 - Metadata
+ // Spawn Player
+ protocol.registerOutgoing(State.PLAY, 0x05, 0x05, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.VAR_INT); // 0 - Entity ID
+ map(Type.UUID); // 1 - Player UUID
+ map(Type.DOUBLE); // 2 - X
+ map(Type.DOUBLE); // 3 - Y
+ map(Type.DOUBLE); // 4 - Z
+ map(Type.BYTE); // 5 - Yaw
+ map(Type.BYTE); // 6 - Pitch
+ map(Types1_14.METADATA_LIST); // 7 - Metadata
- handler(new PacketHandler() {
- @Override
- public void handle(PacketWrapper wrapper) throws Exception {
- int entityId = wrapper.get(Type.VAR_INT, 0);
+ 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;
+ 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_14.METADATA_LIST, 0), wrapper.user());
- }
- });
- }
- });
+ // Register Type ID
+ wrapper.user().get(EntityTracker.class).addEntity(entityId, entType);
+ MetadataRewriter.handleMetadata(entityId, entType, wrapper.get(Types1_14.METADATA_LIST, 0), wrapper.user());
+ }
+ });
+ }
+ });
- // Entity Metadata
- protocol.registerOutgoing(State.PLAY, 0x43, 0x43, new PacketRemapper() {
- @Override
- public void registerMap() {
- map(Type.VAR_INT); // 0 - Entity ID
- map(Types1_14.METADATA_LIST); // 1 - Metadata list
+ // Destroy entities
+ protocol.registerOutgoing(State.PLAY, 0x37, 0x37, 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);
+ }
+ }
+ });
+ }
+ });
- handler(new PacketHandler() {
- @Override
- public void handle(PacketWrapper wrapper) throws Exception {
- int entityId = wrapper.get(Type.VAR_INT, 0);
+ // Entity Metadata
+ protocol.registerOutgoing(State.PLAY, 0x43, 0x43, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ map(Type.VAR_INT); // 0 - Entity ID
+ map(Types1_14.METADATA_LIST); // 1 - Metadata list
- Optional type = wrapper.user().get(EntityTracker.class).get(entityId);
- MetadataRewriter.handleMetadata(entityId, type.orNull(), wrapper.get(Types1_14.METADATA_LIST, 0), wrapper.user());
- }
- });
- }
- });
- }
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ int entityId = wrapper.get(Type.VAR_INT, 0);
+
+ Optional type = wrapper.user().get(EntityTracker.class).get(entityId);
+ MetadataRewriter.handleMetadata(entityId, type.orNull(), wrapper.get(Types1_14.METADATA_LIST, 0), wrapper.user());
+ }
+ });
+ }
+ });
+ }
}
diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/MetadataRewriter.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/MetadataRewriter.java
index 52899f59b..6d9095d67 100644
--- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/MetadataRewriter.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/MetadataRewriter.java
@@ -39,6 +39,12 @@ public class MetadataRewriter {
if (metadata.getId() > 5) {
metadata.setId(metadata.getId() + 1);
}
+ if (metadata.getId() == 8 && type.isOrHasParent(Entity1_14Types.EntityType.LIVINGENTITY)) {
+ final float v = ((Number) metadata.getValue()).floatValue();
+ if (Float.isNaN(v) && Via.getConfig().is1_14HealthNaNFix()) {
+ metadata.setValue(1F);
+ }
+ }
//Metadata 12 added to living_entity
if (metadata.getId() > 11 && type.isOrHasParent(Entity1_14Types.EntityType.LIVINGENTITY)) {
diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/Protocol1_14To1_13_2.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/Protocol1_14To1_13_2.java
index 9a48579bc..34fb0c567 100644
--- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/Protocol1_14To1_13_2.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/Protocol1_14To1_13_2.java
@@ -323,6 +323,5 @@ public class Protocol1_14To1_13_2 extends Protocol {
userConnection.put(new EntityTracker(userConnection));
if (!userConnection.has(ClientWorld.class))
userConnection.put(new ClientWorld(userConnection));
-
}
}
diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/data/MappingData.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/data/MappingData.java
index dd72d6e68..63811fc01 100644
--- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/data/MappingData.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/data/MappingData.java
@@ -11,11 +11,7 @@ import us.myles.ViaVersion.util.GsonUtil;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
public class MappingData {
public static BiMap oldToNewItems = HashBiMap.create();
@@ -23,6 +19,7 @@ public class MappingData {
public static BlockMappings blockMappings;
public static SoundMappings soundMappings;
public static Set motionBlocking;
+ public static Set nonFullBlocks;
public static void init() {
JsonObject mapping1_13_2 = loadData("mapping-1.13.2.json");
@@ -57,6 +54,19 @@ public class MappingData {
MappingData.motionBlocking.add(id);
}
}
+
+ if (Via.getConfig().isNonFullBlockLightFix()) {
+ nonFullBlocks = new HashSet<>();
+ for (Map.Entry blockstates : mapping1_13_2.getAsJsonObject("blockstates").entrySet()) {
+ final String state = blockstates.getValue().getAsString();
+ if (state.contains("_slab") || state.contains("_stairs") || state.contains("_wall["))
+ nonFullBlocks.add(blockStateMappings.getNewBlock(Integer.parseInt(blockstates.getKey())));
+ }
+ nonFullBlocks.add(blockStateMappings.getNewBlock(8163)); // grass path
+ for (int i = 3060; i <= 3067; i++) { // farmland
+ nonFullBlocks.add(blockStateMappings.getNewBlock(i));
+ }
+ }
}
public static JsonObject loadData(String name) {
diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/packets/WorldPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/packets/WorldPackets.java
index c1d212082..3f10c4326 100644
--- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/packets/WorldPackets.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/packets/WorldPackets.java
@@ -2,12 +2,15 @@ package us.myles.ViaVersion.protocols.protocol1_14to1_13_2.packets;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.LongArrayTag;
-import com.google.common.primitives.Bytes;
import us.myles.ViaVersion.api.PacketWrapper;
+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.BlockChangeRecord;
+import us.myles.ViaVersion.api.minecraft.BlockFace;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
+import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
@@ -29,7 +32,7 @@ public class WorldPackets {
private static final int VOID_AIR = MappingData.blockStateMappings.getNewBlock(8591);
private static final int CAVE_AIR = MappingData.blockStateMappings.getNewBlock(8592);
public static final int SERVERSIDE_VIEW_DISTANCE = 64;
- private static final byte[] FULL_LIGHT = new byte[2048];
+ private static final Byte[] FULL_LIGHT = new Byte[2048];
static {
Arrays.fill(FULL_LIGHT, (byte) 0xff);
@@ -164,6 +167,7 @@ public class WorldPackets {
for (int s = 0; s < 16; s++) {
ChunkSection section = chunk.getSections()[s];
if (section == null) continue;
+
boolean hasBlock = false;
for (int i = 0; i < section.getPaletteSize(); i++) {
int old = section.getPaletteEntry(i);
@@ -177,6 +181,7 @@ public class WorldPackets {
section.setNonAirBlocksCount(0);
continue;
}
+
int nonAirBlockCount = 0;
for (int x = 0; x < 16; x++) {
for (int y = 0; y < 16; y++) {
@@ -189,9 +194,15 @@ public class WorldPackets {
if (MappingData.motionBlocking.contains(id)) {
motionBlocking[x + z * 16] = y + s * 16 + 2; // Should be +1 (top of the block) but +2 works :tm:
}
+
+ // Manually update light for non full blocks (block light must not be sent)
+ if (Via.getConfig().isNonFullBlockLightFix() && MappingData.nonFullBlocks.contains(id)) {
+ setNonFullLight(chunk, section, s, x, y, z);
+ }
}
}
}
+
section.setNonAirBlocksCount(nonAirBlockCount);
}
@@ -223,22 +234,22 @@ public class WorldPackets {
// not sending skylight/setting empty skylight causes client lag due to some weird calculations
// only do this on the initial chunk send (not when chunk.isGroundUp() is false)
if (chunk.isGroundUp())
- lightPacket.write(Type.BYTE_ARRAY, Bytes.asList(FULL_LIGHT).toArray(new Byte[0])); // chunk below 0
+ lightPacket.write(Type.BYTE_ARRAY, FULL_LIGHT); // chunk below 0
for (ChunkSection section : chunk.getSections()) {
if (section == null || !section.hasSkyLight()) {
if (chunk.isGroundUp()) {
- lightPacket.write(Type.BYTE_ARRAY, Bytes.asList(FULL_LIGHT).toArray(new Byte[0]));
+ lightPacket.write(Type.BYTE_ARRAY, FULL_LIGHT);
}
continue;
}
- lightPacket.write(Type.BYTE_ARRAY, Bytes.asList(section.getSkyLight()).toArray(new Byte[0]));
+ lightPacket.write(Type.BYTE_ARRAY, fromPrimitiveArray(section.getSkyLight()));
}
if (chunk.isGroundUp())
- lightPacket.write(Type.BYTE_ARRAY, Bytes.asList(FULL_LIGHT).toArray(new Byte[0])); // chunk above 255
+ lightPacket.write(Type.BYTE_ARRAY, FULL_LIGHT); // chunk above 255
for (ChunkSection section : chunk.getSections()) {
if (section == null) continue;
- lightPacket.write(Type.BYTE_ARRAY, Bytes.asList(section.getBlockLight()).toArray(new Byte[0]));
+ lightPacket.write(Type.BYTE_ARRAY, fromPrimitiveArray(section.getBlockLight()));
}
EntityTracker entityTracker = wrapper.user().get(EntityTracker.class);
@@ -257,6 +268,14 @@ public class WorldPackets {
lightPacket.send(Protocol1_14To1_13_2.class, true, true);
}
+
+ private Byte[] fromPrimitiveArray(byte[] bytes) {
+ Byte[] newArray = new Byte[bytes.length];
+ for (int i = 0; i < bytes.length; i++) {
+ newArray[i] = bytes[i];
+ }
+ return newArray;
+ }
});
}
});
@@ -437,4 +456,81 @@ public class WorldPackets {
return data;
}
+
+ private static void setNonFullLight(Chunk chunk, ChunkSection section, int ySection, int x, int y, int z) {
+ int skyLight = 0;
+ int blockLight = 0;
+ for (BlockFace blockFace : BlockFace.values()) {
+ NibbleArray skyLightArray = section.getSkyLightNibbleArray();
+ NibbleArray blockLightArray = section.getBlockLightNibbleArray();
+ int neighbourX = x + blockFace.getModX();
+ int neighbourY = y + blockFace.getModY();
+ int neighbourZ = z + blockFace.getModZ();
+
+ if (blockFace.getModX() != 0) {
+ // Another chunk, nothing we can do without an unnecessary amount of caching
+ if (neighbourX == 16 || neighbourX == -1) continue;
+ } else if (blockFace.getModY() != 0) {
+ if (neighbourY == 16 || neighbourY == -1) {
+ if (neighbourY == 16) {
+ ySection += 1;
+ neighbourY = 0;
+ } else {
+ ySection -= 1;
+ neighbourY = 15;
+ }
+
+ if (ySection == 16 || ySection == -1) continue;
+
+ ChunkSection newSection = chunk.getSections()[ySection];
+ if (newSection == null) continue;
+
+ skyLightArray = newSection.getSkyLightNibbleArray();
+ blockLightArray = newSection.getBlockLightNibbleArray();
+ }
+ } else if (blockFace.getModZ() != 0) {
+ // Another chunk, nothing we can do without an unnecessary amount of caching
+ if (neighbourZ == 16 || neighbourZ == -1) continue;
+ }
+
+ if (blockLightArray != null && blockLight != 15) {
+ int neighbourBlockLight = blockLightArray.get(neighbourX, neighbourY, neighbourZ);
+ if (neighbourBlockLight == 15) {
+ blockLight = 14;
+ } else if (neighbourBlockLight > blockLight) {
+ blockLight = neighbourBlockLight - 1; // lower light level by one
+ }
+ }
+ if (skyLightArray != null && skyLight != 15) {
+ int neighbourSkyLight = skyLightArray.get(neighbourX, neighbourY, neighbourZ);
+ if (neighbourSkyLight == 15) {
+ if (blockFace.getModY() == 1) {
+ // Keep 15 if block is exposed to sky
+ skyLight = 15;
+ continue;
+ }
+
+ skyLight = 14;
+ } else if (neighbourSkyLight > skyLight) {
+ skyLight = neighbourSkyLight - 1; // lower light level by one
+ }
+ }
+ }
+
+ if (skyLight != 0) {
+ if (!section.hasSkyLight()) {
+ byte[] newSkyLight = new byte[2028];
+ section.setSkyLight(newSkyLight);
+ }
+
+ section.getSkyLightNibbleArray().set(x, y, z, skyLight);
+ }
+ if (blockLight != 0) {
+ section.getBlockLightNibbleArray().set(x, y, z, blockLight);
+ }
+ }
+
+ private static long getChunkIndex(int x, int z) {
+ return ((x & 0x3FFFFFFL) << 38) | (z & 0x3FFFFFFL);
+ }
}
diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/EntityPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/EntityPackets.java
index 4792a00e7..8ccb52b3c 100644
--- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/EntityPackets.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/EntityPackets.java
@@ -140,7 +140,15 @@ public class EntityPackets {
// 1 - Slot ID
map(Type.SHORT, new ValueTransformer(Type.VAR_INT) {
@Override
- public Integer transform(PacketWrapper wrapper, Short slot) {
+ public Integer transform(PacketWrapper wrapper, Short slot) throws Exception {
+ int entityId = wrapper.get(Type.VAR_INT, 0);
+ int receiverId = wrapper.user().get(EntityTracker.class).getEntityID();
+ // Normally, 0 = hand and 1-4 = armor
+ // ... but if the sent id is equal to the receiver's id, 0-3 will instead mark the armor slots
+ // (In 1.9+, every client treats the received the same: 0=hand, 1=offhand, 2-5=armor)
+ if (entityId == receiverId) {
+ return slot.intValue() + 2;
+ }
return slot > 0 ? slot.intValue() + 1 : slot.intValue();
}
});
diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/sounds/SoundEffect.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/sounds/SoundEffect.java
index 85dffc247..6f8a2dd5f 100644
--- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/sounds/SoundEffect.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/sounds/SoundEffect.java
@@ -15,7 +15,7 @@ public enum SoundEffect {
DIG_GRAVEL("dig.gravel", "block.gravel.place", SoundCategory.BLOCK),
RANDOM_BOWHIT("random.bowhit", "block.tripwire.detach", SoundCategory.NEUTRAL),
DIG_GLASS("dig.glass", "block.glass.break", SoundCategory.BLOCK),
- MOB_ZOMBIE_SAY("mob.zombie.say", "entity.zombie_villager.ambient", SoundCategory.HOSTILE),
+ MOB_ZOMBIE_SAY("mob.zombie.say", "entity.zombie.ambient", SoundCategory.HOSTILE),
MOB_PIG_DEATH("mob.pig.death", "entity.pig.death", SoundCategory.NEUTRAL),
MOB_HORSE_DONKEY_HIT("mob.horse.donkey.hit", "entity.donkey.hurt", SoundCategory.NEUTRAL),
GAME_NEUTRAL_SWIM("game.neutral.swim", "entity.player.swim", SoundCategory.NEUTRAL),
@@ -207,7 +207,7 @@ public enum SoundEffect {
MOB_MAGMACUBE_SMALL("mob.magmacube.small", "entity.small_magmacube.squish", SoundCategory.HOSTILE),
FIRE_IGNITE("fire.ignite", "item.flintandsteel.use", SoundCategory.BLOCK, true),
MOB_ENDERDRAGON_HIT("mob.enderdragon.hit", "entity.enderdragon.hurt", SoundCategory.HOSTILE),
- MOB_ZOMBIE_HURT("mob.zombie.hurt", "entity.zombie_villager.hurt", SoundCategory.HOSTILE),
+ MOB_ZOMBIE_HURT("mob.zombie.hurt", "entity.zombie.hurt", SoundCategory.HOSTILE),
RANDOM_EXPLODE("random.explode", "block.end_gateway.spawn", SoundCategory.BLOCK),
MOB_SLIME_ATTACK("mob.slime.attack", "entity.slime.attack", SoundCategory.HOSTILE),
MOB_MAGMACUBE_JUMP("mob.magmacube.jump", "entity.magmacube.jump", SoundCategory.HOSTILE),
diff --git a/common/src/main/resources/assets/viaversion/config.yml b/common/src/main/resources/assets/viaversion/config.yml
index b377ae379..5394a40f7 100644
--- a/common/src/main/resources/assets/viaversion/config.yml
+++ b/common/src/main/resources/assets/viaversion/config.yml
@@ -126,6 +126,10 @@ change-1_9-hitbox: false
# WARNING: This gives 1.14+ players the ability to sneak under blocks, that players under that version cannot (sneaking in places that are only 1.5 blocks high)!
# Another thing to remember is that those players might be missed by projectiles and other hits directed at the very top of their head whilst sneaking.
change-1_14-hitbox: false
+# Fixes 1.14+ clients on sub 1.14 servers having a light value of 0 for non full blocks.
+fix-non-full-blocklight: true
+# Fixes walk animation not shown when health is set to Float.NaN
+fix-1_14-health-nan: true
# Should 1.15+ clients respawn instantly / without showing a death screen?
use-1_15-instant-respawn: false
#
diff --git a/common/src/main/resources/assets/viaversion/data/mapping-lang-1.12-1.13.json b/common/src/main/resources/assets/viaversion/data/mapping-lang-1.12-1.13.json
index 7fcc2d5c3..265326831 100644
--- a/common/src/main/resources/assets/viaversion/data/mapping-lang-1.12-1.13.json
+++ b/common/src/main/resources/assets/viaversion/data/mapping-lang-1.12-1.13.json
@@ -1242,8 +1242,8 @@
"entity.Villager.librarian": "entity.minecraft.villager.librarian",
"entity.Villager.cleric": "entity.minecraft.villager.cleric",
"entity.Villager.armor": "entity.minecraft.villager.armorer",
- "entity.Villager.weapon": "entity.minecraft.villager.weapon_smith",
- "entity.Villager.tool": "entity.minecraft.villager.tool_smith",
+ "entity.Villager.weapon": "entity.minecraft.villager.weaponsmith",
+ "entity.Villager.tool": "entity.minecraft.villager.toolsmith",
"entity.Villager.butcher": "entity.minecraft.villager.butcher",
"entity.Villager.leather": "entity.minecraft.villager.leatherworker",
"entity.Villager.nitwit": "entity.minecraft.villager.nitwit",
@@ -2745,4 +2745,4 @@
"advancements.story.smelt_iron.description": null,
"advancements.story.upgrade_tools.title": null,
"advancements.story.upgrade_tools.description": null
-}
\ No newline at end of file
+}
diff --git a/jar/pom.xml b/jar/pom.xml
index f36b49d54..4fe48c73e 100644
--- a/jar/pom.xml
+++ b/jar/pom.xml
@@ -5,7 +5,7 @@
viaversion-parent
us.myles
- 2.1.4-19w39a
+ 2.1.4-19w40a
4.0.0
viaversion-jar
diff --git a/pom.xml b/pom.xml
index 274e4e71a..a91f9586e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
us.myles
viaversion-parent
- 2.1.4-19w39a
+ 2.1.4-19w40a
pom
viaversion-parent
diff --git a/sponge-legacy/pom.xml b/sponge-legacy/pom.xml
index 2a0df8f84..9c1f0abcc 100644
--- a/sponge-legacy/pom.xml
+++ b/sponge-legacy/pom.xml
@@ -5,7 +5,7 @@
viaversion-parent
us.myles
- 2.1.4-19w39a
+ 2.1.4-19w40a
4.0.0
diff --git a/sponge/pom.xml b/sponge/pom.xml
index 9fa504508..76a23e947 100644
--- a/sponge/pom.xml
+++ b/sponge/pom.xml
@@ -5,7 +5,7 @@
viaversion-parent
us.myles
- 2.1.4-19w39a
+ 2.1.4-19w40a
4.0.0
diff --git a/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeViaConfig.java b/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeViaConfig.java
index 9a451b741..c6b2be549 100644
--- a/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeViaConfig.java
+++ b/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeViaConfig.java
@@ -276,6 +276,16 @@ public class SpongeViaConfig extends Config implements ViaVersionConfig {
return false;
}
+ @Override
+ public boolean isNonFullBlockLightFix() {
+ return getBoolean("fix-non-full-blocklight", true);
+ }
+
+ @Override
+ public boolean is1_14HealthNaNFix() {
+ return getBoolean("fix-1_14-health-nan", true);
+ }
+
@Override
public boolean is1_15InstantRespawn() {
return getBoolean("use-1_15-instant-respawn", false);
diff --git a/velocity/pom.xml b/velocity/pom.xml
index 47be564ad..1cb2a7a7a 100644
--- a/velocity/pom.xml
+++ b/velocity/pom.xml
@@ -5,7 +5,7 @@
viaversion-parent
us.myles
- 2.1.4-19w39a
+ 2.1.4-19w40a
4.0.0
diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java
index f68eec46c..ccffda7cb 100644
--- a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java
+++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java
@@ -329,6 +329,16 @@ public class VelocityViaConfig extends Config implements ViaVersionConfig {
return false;
}
+ @Override
+ public boolean isNonFullBlockLightFix() {
+ return getBoolean("fix-non-full-blocklight", true);
+ }
+
+ @Override
+ public boolean is1_14HealthNaNFix() {
+ return getBoolean("fix-1_14-health-nan", true);
+ }
+
@Override
public boolean is1_15InstantRespawn() {
return getBoolean("use-1_15-instant-respawn", false);