diff --git a/src/main/java/us/myles/ViaVersion2/api/data/StoredObject.java b/src/main/java/us/myles/ViaVersion2/api/data/StoredObject.java index 5384bde9d..1973bc329 100644 --- a/src/main/java/us/myles/ViaVersion2/api/data/StoredObject.java +++ b/src/main/java/us/myles/ViaVersion2/api/data/StoredObject.java @@ -1,4 +1,9 @@ package us.myles.ViaVersion2.api.data; +import lombok.AllArgsConstructor; +import lombok.Getter; +@Getter +@AllArgsConstructor public class StoredObject { + private UserConnection user; } diff --git a/src/main/java/us/myles/ViaVersion2/api/item/Item.java b/src/main/java/us/myles/ViaVersion2/api/item/Item.java index 71c972a92..ed4abcacd 100644 --- a/src/main/java/us/myles/ViaVersion2/api/item/Item.java +++ b/src/main/java/us/myles/ViaVersion2/api/item/Item.java @@ -1,14 +1,24 @@ package us.myles.ViaVersion2.api.item; +import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; +import org.bukkit.inventory.ItemStack; import org.spacehq.opennbt.tag.builtin.CompoundTag; @Getter @Setter +@NoArgsConstructor +@AllArgsConstructor public class Item { private short id; private byte amount; private short data; private CompoundTag tag; + + public static Item getItem(ItemStack stack) { + if(stack == null) return null; + return new Item((short) stack.getTypeId(), (byte) stack.getAmount(), stack.getDurability(), null); + } } diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolPipeline.java b/src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolPipeline.java index 79ab84421..b8585158f 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolPipeline.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolPipeline.java @@ -30,7 +30,7 @@ public class ProtocolPipeline extends Protocol { public void init(UserConnection userConnection) { this.userConnection = userConnection; - ProtocolInfo protocolInfo = new ProtocolInfo(); + ProtocolInfo protocolInfo = new ProtocolInfo(userConnection); protocolInfo.setPipeline(this); userConnection.put(protocolInfo); diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol/base/ProtocolInfo.java b/src/main/java/us/myles/ViaVersion2/api/protocol/base/ProtocolInfo.java index 22157c220..6789a4a69 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol/base/ProtocolInfo.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol/base/ProtocolInfo.java @@ -4,6 +4,7 @@ import lombok.Getter; import lombok.Setter; import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion2.api.data.StoredObject; +import us.myles.ViaVersion2.api.data.UserConnection; import us.myles.ViaVersion2.api.protocol.ProtocolPipeline; import java.util.UUID; @@ -16,4 +17,8 @@ public class ProtocolInfo extends StoredObject{ private String username; private UUID uuid; private ProtocolPipeline pipeline; + + public ProtocolInfo(UserConnection user) { + super(user); + } } diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/Protocol1_9TO1_8.java b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/Protocol1_9TO1_8.java index af067fb2b..0894f6664 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/Protocol1_9TO1_8.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/Protocol1_9TO1_8.java @@ -1,11 +1,15 @@ package us.myles.ViaVersion2.api.protocol1_9to1_8; +import org.bukkit.Bukkit; +import org.bukkit.inventory.ItemStack; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; +import us.myles.ViaVersion.api.ViaVersion; import us.myles.ViaVersion2.api.PacketWrapper; import us.myles.ViaVersion2.api.data.UserConnection; import us.myles.ViaVersion2.api.metadata.Metadata; import us.myles.ViaVersion2.api.protocol.Protocol; +import us.myles.ViaVersion2.api.protocol.base.ProtocolInfo; import us.myles.ViaVersion2.api.protocol1_9to1_8.packets.*; import us.myles.ViaVersion2.api.protocol1_9to1_8.storage.ClientChunks; import us.myles.ViaVersion2.api.protocol1_9to1_8.storage.EntityTracker; @@ -16,6 +20,9 @@ import us.myles.ViaVersion2.api.remapper.ValueTransformer; import us.myles.ViaVersion2.api.type.Type; import java.util.List; +import java.util.UUID; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; public class Protocol1_9TO1_8 extends Protocol { public static Type> METADATA_LIST = new MetadataListType(); @@ -59,10 +66,31 @@ public class Protocol1_9TO1_8 extends Protocol { @Override public void init(UserConnection userConnection) { // Entity tracker - userConnection.put(new EntityTracker()); + userConnection.put(new EntityTracker(userConnection)); // Chunk tracker - userConnection.put(new ClientChunks()); + userConnection.put(new ClientChunks(userConnection)); // Movement tracker - userConnection.put(new MovementTracker()); + userConnection.put(new MovementTracker(userConnection)); + } + + + public static ItemStack getHandItem(final UserConnection info) { + try { + return Bukkit.getScheduler().callSyncMethod(Bukkit.getPluginManager().getPlugin("ViaVersion"), new Callable() { + @Override + public ItemStack call() throws Exception { + UUID playerUUID = info.get(ProtocolInfo.class).getUuid(); + if (Bukkit.getPlayer(playerUUID) != null) { + return Bukkit.getPlayer(playerUUID).getItemInHand(); + } + return null; + } + }).get(10, TimeUnit.SECONDS); + } catch (Exception e) { + System.out.println("Error fetching hand item: " + e.getClass().getName()); + if (ViaVersion.getInstance().isDebug()) + e.printStackTrace(); + return null; + } } } diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/metadata/MetadataRewriter.java b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/metadata/MetadataRewriter.java index f3ac6918c..f8ee9d8b6 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/metadata/MetadataRewriter.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/metadata/MetadataRewriter.java @@ -47,7 +47,7 @@ public class MetadataRewriter { int newIndex = MetaIndex.PLAYER_HAND.getNewIndex(); int typeID = MetaIndex.PLAYER_HAND.getNewType().getTypeID(); Metadata metadata = new Metadata(newIndex, typeID, us.myles.ViaVersion2.api.type.Type.BYTE, val); -// list.add(metadata); + list.add(metadata); } break; case OptUUID: diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/EntityPackets.java b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/EntityPackets.java index 9e0cf40f2..a5b984172 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/EntityPackets.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/EntityPackets.java @@ -1,5 +1,6 @@ package us.myles.ViaVersion2.api.protocol1_9to1_8.packets; +import org.bukkit.Material; import us.myles.ViaVersion.ViaVersionPlugin; import us.myles.ViaVersion.api.ViaVersion; import us.myles.ViaVersion.packets.State; @@ -171,9 +172,7 @@ public class EntityPackets { } }); map(Type.ITEM); // 2 - Item - - // TODO - Blocking patch - + // Item Rewriter handler(new PacketHandler() { @Override public void handle(PacketWrapper wrapper) throws Exception { @@ -181,6 +180,23 @@ public class EntityPackets { ItemRewriter.toClient(stack); } }); + // Blocking + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + EntityTracker entityTracker = wrapper.user().get(EntityTracker.class); + int entityID = wrapper.get(Type.VAR_INT, 0); + Item stack = wrapper.get(Type.ITEM, 0); + + if(stack != null){ + if(Material.getMaterial(stack.getId()).name().endsWith("SWORD")){ + entityTracker.getValidBlocking().add(entityID); + return; + } + } + entityTracker.getValidBlocking().remove(entityID); + } + }); } }); // Entity Metadata Packet @@ -203,6 +219,17 @@ public class EntityPackets { } } }); + + // Handler for meta data + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + List metadataList = wrapper.get(Protocol1_9TO1_8.METADATA_LIST, 0); + int entityID = wrapper.get(Type.VAR_INT, 0); + EntityTracker tracker = wrapper.user().get(EntityTracker.class); + tracker.handleMetadata(entityID, metadataList); + } + }); } }); @@ -216,7 +243,6 @@ public class EntityPackets { map(Type.BYTE); // 2 - Amplifier map(Type.VAR_INT); // 3 - Duration map(Type.BOOLEAN, Type.BYTE); // 4 - Hide particles - // TODO: Test particles as conversion might not work } }); diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/InventoryPackets.java b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/InventoryPackets.java index c8d6dc92d..93c772208 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/InventoryPackets.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/InventoryPackets.java @@ -6,6 +6,7 @@ import us.myles.ViaVersion2.api.item.Item; import us.myles.ViaVersion2.api.protocol.Protocol; import us.myles.ViaVersion2.api.protocol1_9to1_8.ItemRewriter; import us.myles.ViaVersion2.api.protocol1_9to1_8.Protocol1_9TO1_8; +import us.myles.ViaVersion2.api.protocol1_9to1_8.storage.EntityTracker; import us.myles.ViaVersion2.api.remapper.PacketHandler; import us.myles.ViaVersion2.api.remapper.PacketRemapper; import us.myles.ViaVersion2.api.remapper.ValueCreator; @@ -164,14 +165,18 @@ public class InventoryPackets { protocol.registerIncoming(State.PLAY, 0x0F, 0x05); // Confirm Transaction Packet protocol.registerIncoming(State.PLAY, 0x11, 0x06); // Enchant Item Packet - // TODO Held Item change blocking patch protocol.registerIncoming(State.PLAY, 0x09, 0x17, new PacketRemapper() { @Override public void registerMap() { + // Blocking patch handler(new PacketHandler() { @Override public void handle(PacketWrapper wrapper) throws Exception { - System.out.println("held item"); + EntityTracker entityTracker = wrapper.user().get(EntityTracker.class); + if (entityTracker.isBlocking()) { + entityTracker.setBlocking(false); + entityTracker.setSecondHand(wrapper.user(), null); + } } }); } diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/PlayerPackets.java b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/PlayerPackets.java index 2786195f7..ca8acfe21 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/PlayerPackets.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/PlayerPackets.java @@ -1,10 +1,12 @@ package us.myles.ViaVersion2.api.protocol1_9to1_8.packets; +import org.bukkit.Material; import org.bukkit.entity.EntityType; import us.myles.ViaVersion.ViaVersionPlugin; import us.myles.ViaVersion.api.ViaVersion; import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion2.api.PacketWrapper; +import us.myles.ViaVersion2.api.item.Item; import us.myles.ViaVersion2.api.protocol.Protocol; import us.myles.ViaVersion2.api.protocol1_9to1_8.PlayerMovementMapper; import us.myles.ViaVersion2.api.protocol1_9to1_8.Protocol1_9TO1_8; @@ -307,6 +309,7 @@ public class PlayerPackets { handler(new PacketHandler() { @Override public void handle(PacketWrapper wrapper) throws Exception { + int hand = wrapper.read(Type.VAR_INT); // Wipe the input buffer wrapper.clearInputBuffer(); // First set this packet ID to Block placement @@ -314,7 +317,23 @@ public class PlayerPackets { wrapper.write(Type.LONG, -1L); wrapper.write(Type.BYTE, (byte) 255); // Write item in hand - wrapper.write(Type.SHORT, (short) -1); // TODO + Item item = Item.getItem(Protocol1_9TO1_8.getHandItem(wrapper.user())); + // Blocking patch + if (item != null) { + if (Material.getMaterial(item.getId()).name().endsWith("SWORD")) { + if (hand == 0) { + EntityTracker tracker = wrapper.user().get(EntityTracker.class); + if (!tracker.isBlocking()) { + tracker.setBlocking(true); + Item shield = new Item((short) 442, (byte) 1, (short) 0, null); + tracker.setSecondHand(wrapper.user(), shield); + } + wrapper.cancel(); + } + + } + } + wrapper.write(Type.ITEM, item); wrapper.write(Type.BYTE, (byte) 0); wrapper.write(Type.BYTE, (byte) 0); diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/SpawnPackets.java b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/SpawnPackets.java index 4ce3417dc..c581ed42a 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/SpawnPackets.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/SpawnPackets.java @@ -170,7 +170,6 @@ public class SpawnPackets { map(Type.SHORT); // 11 - Velocity Z map(Protocol1_9TO1_8.METADATA_LIST); - // TODO: Metadata detector for bossbars, wither stuff. handler(new PacketHandler() { @Override public void handle(PacketWrapper wrapper) throws Exception { @@ -184,6 +183,16 @@ public class SpawnPackets { } } }); + // Handler for meta data + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + List metadataList = wrapper.get(Protocol1_9TO1_8.METADATA_LIST, 0); + int entityID = wrapper.get(Type.VAR_INT, 0); + EntityTracker tracker = wrapper.user().get(EntityTracker.class); + tracker.handleMetadata(entityID, metadataList); + } + }); } }); @@ -250,6 +259,17 @@ public class SpawnPackets { } } }); + + // Handler for meta data + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + List metadataList = wrapper.get(Protocol1_9TO1_8.METADATA_LIST, 0); + int entityID = wrapper.get(Type.VAR_INT, 0); + EntityTracker tracker = wrapper.user().get(EntityTracker.class); + tracker.handleMetadata(entityID, metadataList); + } + }); } }); diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/WorldPackets.java b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/WorldPackets.java index 8b4ee309c..51b5b3025 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/WorldPackets.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/packets/WorldPackets.java @@ -6,9 +6,11 @@ import us.myles.ViaVersion2.api.PacketWrapper; import us.myles.ViaVersion2.api.protocol.Protocol; import us.myles.ViaVersion2.api.protocol1_9to1_8.Protocol1_9TO1_8; import us.myles.ViaVersion2.api.protocol1_9to1_8.storage.ClientChunks; +import us.myles.ViaVersion2.api.protocol1_9to1_8.storage.EntityTracker; import us.myles.ViaVersion2.api.protocol1_9to1_8.types.ChunkType; import us.myles.ViaVersion2.api.remapper.PacketHandler; import us.myles.ViaVersion2.api.remapper.PacketRemapper; +import us.myles.ViaVersion2.api.remapper.ValueCreator; import us.myles.ViaVersion2.api.type.Type; public class WorldPackets { @@ -125,7 +127,20 @@ public class WorldPackets { wrapper.cancel(); } }); - // TODO: Blocking patch stopped if blocking and 5 + // Blocking + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + int status = wrapper.get(Type.UNSIGNED_BYTE, 0); + if (status == 5) { + EntityTracker entityTracker = wrapper.user().get(EntityTracker.class); + if(entityTracker.isBlocking()){ + entityTracker.setBlocking(false); + entityTracker.setSecondHand(wrapper.user(), null); + } + } + } + }); } }); @@ -136,7 +151,13 @@ public class WorldPackets { map(Type.POSITION); // 0 - Position map(Type.VAR_INT, Type.BYTE); // 1 - Block Face map(Type.VAR_INT, Type.NOTHING); // 2 - Hand - // TODO: Insert hand item here + // TODO: Actual hand item + create(new ValueCreator() { + @Override + public void write(PacketWrapper wrapper) throws Exception { + wrapper.write(Type.SHORT, (short) -1); + } + }); // Did have item rewriter but its not needed map(Type.UNSIGNED_BYTE); // 4 - X map(Type.UNSIGNED_BYTE); // 5 - Y diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/storage/ClientChunks.java b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/storage/ClientChunks.java index 600d39fd1..74df72f9a 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/storage/ClientChunks.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/storage/ClientChunks.java @@ -6,6 +6,7 @@ import lombok.Getter; import org.bukkit.Bukkit; import us.myles.ViaVersion.util.ReflectionUtil; import us.myles.ViaVersion2.api.data.StoredObject; +import us.myles.ViaVersion2.api.data.UserConnection; import java.util.List; import java.util.Set; @@ -28,6 +29,10 @@ public class ClientChunks extends StoredObject { } } + public ClientChunks(UserConnection user) { + super(user); + } + public List transformMapChunkBulk(Object packet) { List list = Lists.newArrayList(); try { diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/storage/EntityTracker.java b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/storage/EntityTracker.java index 10c059636..cf83a5af7 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/storage/EntityTracker.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/storage/EntityTracker.java @@ -1,24 +1,46 @@ package us.myles.ViaVersion2.api.protocol1_9to1_8.storage; +import io.netty.buffer.ByteBuf; import lombok.Getter; import lombok.Setter; +import org.bukkit.Bukkit; import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import us.myles.ViaVersion.ViaVersionPlugin; +import us.myles.ViaVersion.api.ViaVersion; import us.myles.ViaVersion.api.boss.BossBar; +import us.myles.ViaVersion.api.boss.BossColor; +import us.myles.ViaVersion.api.boss.BossStyle; +import us.myles.ViaVersion.metadata.NewType; +import us.myles.ViaVersion.util.PacketUtil; +import us.myles.ViaVersion2.api.PacketWrapper; import us.myles.ViaVersion2.api.data.StoredObject; +import us.myles.ViaVersion2.api.data.UserConnection; +import us.myles.ViaVersion2.api.item.Item; +import us.myles.ViaVersion2.api.metadata.Metadata; +import us.myles.ViaVersion2.api.protocol.base.ProtocolInfo; +import us.myles.ViaVersion2.api.type.Type; import java.util.*; @Getter -public class EntityTracker extends StoredObject{ +public class EntityTracker extends StoredObject { private final Map uuidMap = new HashMap<>(); private final Map clientEntityTypes = new HashMap<>(); private final Map vehicleMap = new HashMap<>(); private final Map bossBarMap = new HashMap<>(); private final Set validBlocking = new HashSet<>(); private final Set knownHolograms = new HashSet<>(); + @Getter + @Setter + private boolean blocking = false; @Setter private int entityID; + public EntityTracker(UserConnection user) { + super(user); + } + public UUID getEntityUUID(int id) { if (uuidMap.containsKey(id)) { return uuidMap.get(id); @@ -29,6 +51,18 @@ public class EntityTracker extends StoredObject{ } } + public void setSecondHand(UserConnection connection, Item item) { + PacketWrapper wrapper = new PacketWrapper(0x3C, null, connection); + wrapper.write(Type.VAR_INT, entityID); + wrapper.write(Type.VAR_INT, 1); // slot + wrapper.write(Type.ITEM, item); + try { + wrapper.send(); + } catch (Exception e) { + e.printStackTrace(); + } + } + public void removeEntity(Integer entityID) { clientEntityTypes.remove(entityID); vehicleMap.remove(entityID); @@ -41,4 +75,95 @@ public class EntityTracker extends StoredObject{ bar.hide(); } } + + public void handleMetadata(int entityID, List metadataList) { + if (!clientEntityTypes.containsKey(entityID)) return; + + EntityType type = clientEntityTypes.get(entityID); + for (Metadata metadata : new ArrayList<>(metadataList)) { + // Fix: wither (crash fix) + if (type == EntityType.WITHER) { + if (metadata.getId() == 10) { + metadataList.remove(metadata); + //metadataList.add(new Metadata(10, NewType.Byte.getTypeID(), Type.BYTE, 0)); + } + } + // Fix: enderdragon (crash fix) + if (type == EntityType.ENDER_DRAGON) { + if (metadata.getId() == 11) { + metadataList.remove(metadata); + // metadataList.add(new Metadata(11, NewType.Byte.getTypeID(), Type.VAR_INT, 0)); + } + } + + if (type == EntityType.PLAYER) { + if (metadata.getId() == 0) { + // Byte + byte data = (byte) metadata.getValue(); + if (entityID != getEntityID() && ((ViaVersionPlugin) ViaVersion.getInstance()).isShieldBlocking()) { + if ((data & 0x10) == 0x10) { + if (validBlocking.contains(entityID)) { + Item shield = new Item((short) 442, (byte) 1, (short) 0, null); + setSecondHand(getUser(), shield); + } + } else { + setSecondHand(getUser(), null); + } + } + } + } + if (type == EntityType.ARMOR_STAND && ((ViaVersionPlugin) ViaVersion.getInstance()).isHologramPatch()) { + if (metadata.getId() == 0) { + byte data = (byte) metadata.getValue(); + if ((data & 0x20) == 0x20) { + if (!knownHolograms.contains(entityID)) { + knownHolograms.add(entityID); + // Send movement + ByteBuf buf = getUser().getChannel().alloc().buffer(); + PacketUtil.writeVarInt(0x25, buf); // Relative Move Packet + PacketUtil.writeVarInt(entityID, buf); + buf.writeShort(0); + buf.writeShort((short) (128D * (((ViaVersionPlugin) ViaVersion.getInstance()).getHologramYOffset() * 32D))); + buf.writeShort(0); + buf.writeBoolean(true); + getUser().sendRawPacket(buf, false); + } + } + } + } + Player player = Bukkit.getPlayer(getUser().get(ProtocolInfo.class).getUuid()); + // Boss bar + if (((ViaVersionPlugin) ViaVersion.getInstance()).isBossbarPatch()) { + if (type == EntityType.ENDER_DRAGON || type == EntityType.WITHER) { + if (metadata.getId() == 2) { + BossBar bar = bossBarMap.get(entityID); + String title = (String) metadata.getValue(); + title = title.isEmpty() ? (type == EntityType.ENDER_DRAGON ? "Ender Dragon" : "Wither") : title; + if (bar == null) { + bar = ViaVersion.getInstance().createBossBar(title, BossColor.PINK, BossStyle.SOLID); + bossBarMap.put(entityID, bar); + bar.addPlayer(player); + bar.show(); + } else { + bar.setTitle(title); + } + } else if (metadata.getId() == 6 && !((ViaVersionPlugin) ViaVersion.getInstance()).isBossbarAntiflicker()) { // If anti flicker is enabled, don't update health + BossBar bar = bossBarMap.get(entityID); + // Make health range between 0 and 1 + float maxHealth = type == EntityType.ENDER_DRAGON ? 200.0f : 300.0f; + float health = Math.max(0.0f, Math.min(((float) metadata.getValue()) / maxHealth, 1.0f)); + if (bar == null) { + String title = type == EntityType.ENDER_DRAGON ? "Ender Dragon" : "Wither"; + bar = ViaVersion.getInstance().createBossBar(title, health, BossColor.PINK, BossStyle.SOLID); + bossBarMap.put(entityID, bar); + bar.addPlayer(player); + bar.show(); + } else { + bar.setHealth(health); + } + } + } + } + } + } } diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/storage/MovementTracker.java b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/storage/MovementTracker.java index 7a44dc37b..809b7b074 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/storage/MovementTracker.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/storage/MovementTracker.java @@ -2,6 +2,7 @@ package us.myles.ViaVersion2.api.protocol1_9to1_8.storage; import lombok.Getter; import us.myles.ViaVersion2.api.data.StoredObject; +import us.myles.ViaVersion2.api.data.UserConnection; public class MovementTracker extends StoredObject{ private static final long IDLE_PACKET_DELAY = 50L; // Update every 50ms (20tps) @@ -9,6 +10,10 @@ public class MovementTracker extends StoredObject{ @Getter private long nextIdlePacket = 0L; + public MovementTracker(UserConnection user) { + super(user); + } + public void incrementIdlePacket() { // Notify of next update // Allow a maximum lag spike of 1 second (20 ticks/updates)