diff --git a/src/main/java/ac/grim/grimac/events/packets/PacketPlayerDigging.java b/src/main/java/ac/grim/grimac/events/packets/PacketPlayerDigging.java index 39c6954e76..9c9b259fc4 100644 --- a/src/main/java/ac/grim/grimac/events/packets/PacketPlayerDigging.java +++ b/src/main/java/ac/grim/grimac/events/packets/PacketPlayerDigging.java @@ -8,10 +8,13 @@ import com.github.retrooper.packetevents.event.PacketListenerPriority; import com.github.retrooper.packetevents.event.PacketReceiveEvent; import com.github.retrooper.packetevents.manager.server.ServerVersion; +import com.github.retrooper.packetevents.protocol.component.ComponentTypes; +import com.github.retrooper.packetevents.protocol.component.builtin.item.FoodProperties; import com.github.retrooper.packetevents.protocol.item.ItemStack; import com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentTypes; import com.github.retrooper.packetevents.protocol.item.type.ItemType; import com.github.retrooper.packetevents.protocol.item.type.ItemTypes; +import com.github.retrooper.packetevents.protocol.nbt.NBTCompound; import com.github.retrooper.packetevents.protocol.packettype.PacketType; import com.github.retrooper.packetevents.protocol.player.ClientVersion; import com.github.retrooper.packetevents.protocol.player.DiggingAction; @@ -27,95 +30,106 @@ public PacketPlayerDigging() { } public static void handleUseItem(GrimPlayer player, ItemStack item, InteractionHand hand) { - if (item != null) { - ItemType material = item.getType(); - - if (player.checkManager.getCompensatedCooldown().hasMaterial(material)) { - player.packetStateData.slowedByUsingItem = false; // resync, not required - return; // The player has a cooldown, and therefore cannot use this item! - } - - // 1.14 and below players cannot eat in creative, exceptions are potions or milk - if ((player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_15) || - (player.gamemode != GameMode.CREATIVE && material.hasAttribute(ItemTypes.ItemAttribute.EDIBLE))) - || material == ItemTypes.POTION || material == ItemTypes.MILK_BUCKET) { - - // Pls have this mapped correctly retrooper - if (item.getType() == ItemTypes.SPLASH_POTION) - return; - // 1.8 splash potion - if (PacketEvents.getAPI().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_9) && item.getLegacyData() > 16384) { - return; - } - - // Eatable items that don't require any hunger to eat - if (material == ItemTypes.POTION || material == ItemTypes.MILK_BUCKET - || material == ItemTypes.GOLDEN_APPLE || material == ItemTypes.ENCHANTED_GOLDEN_APPLE - || material == ItemTypes.HONEY_BOTTLE || material == ItemTypes.SUSPICIOUS_STEW || - material == ItemTypes.CHORUS_FRUIT) { - player.packetStateData.slowedByUsingItem = true; - player.packetStateData.eatingHand = hand; - - return; - } + if (item == null) { + player.packetStateData.slowedByUsingItem = false; + return; + } - // The other items that do require it - if (item.getType().hasAttribute(ItemTypes.ItemAttribute.EDIBLE) && ((player.bukkitPlayer != null && player.food < 20) || player.gamemode == GameMode.CREATIVE)) { - player.packetStateData.slowedByUsingItem = true; - player.packetStateData.eatingHand = hand; + final ItemType material = item.getType(); - return; - } + if (player.checkManager.getCompensatedCooldown().hasMaterial(material)) { + player.packetStateData.slowedByUsingItem = false; // resync, not required + return; // The player has a cooldown, and therefore cannot use this item! + } - // The player cannot eat this item, resync use status + // Check for data component stuff on 1.20.5+ + final FoodProperties foodComponent = item.getComponentOr(ComponentTypes.FOOD, null); + if (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_20_5) && foodComponent != null) { + if (foodComponent.isCanAlwaysEat() || player.food < 20 || player.gamemode == GameMode.CREATIVE) { + player.packetStateData.slowedByUsingItem = true; + player.packetStateData.eatingHand = hand; + return; + } else { player.packetStateData.slowedByUsingItem = false; } + } - if (material == ItemTypes.SHIELD && player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_9)) { - player.packetStateData.slowedByUsingItem = true; - player.packetStateData.eatingHand = hand; + // 1.14 and below players cannot eat in creative, exceptions are potions or milk + if ((player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_15) || + (player.gamemode != GameMode.CREATIVE && material.hasAttribute(ItemTypes.ItemAttribute.EDIBLE))) + || material == ItemTypes.POTION || material == ItemTypes.MILK_BUCKET) { + // Pls have this mapped correctly retrooper + if (item.getType() == ItemTypes.SPLASH_POTION) + return; + // 1.8 splash potion + if (PacketEvents.getAPI().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_9) && item.getLegacyData() > 16384) { return; } - // Avoid releasing crossbow as being seen as slowing player - if (material == ItemTypes.CROSSBOW && item.getNBT().getBoolean("Charged")) { - player.packetStateData.slowedByUsingItem = false; // TODO: Fix this + // Eatable items that don't require any hunger to eat + if (material == ItemTypes.POTION || material == ItemTypes.MILK_BUCKET + || material == ItemTypes.GOLDEN_APPLE || material == ItemTypes.ENCHANTED_GOLDEN_APPLE + || material == ItemTypes.HONEY_BOTTLE || material == ItemTypes.SUSPICIOUS_STEW || + material == ItemTypes.CHORUS_FRUIT) { + player.packetStateData.slowedByUsingItem = true; + player.packetStateData.eatingHand = hand; return; } - // The client and server don't agree on trident status because mojang is incompetent at netcode. - if (material == ItemTypes.TRIDENT) { - player.packetStateData.slowedByUsingItem = item.getEnchantmentLevel(EnchantmentTypes.RIPTIDE, PacketEvents.getAPI().getServerManager().getVersion().toClientVersion()) <= 0; + // The other items that do require it + if (item.getType().hasAttribute(ItemTypes.ItemAttribute.EDIBLE) && ((player.bukkitPlayer != null && player.food < 20) || player.gamemode == GameMode.CREATIVE)) { + player.packetStateData.slowedByUsingItem = true; player.packetStateData.eatingHand = hand; + return; } - // Players in survival can't use a bow without an arrow - // Crossbow charge checked previously - if (material == ItemTypes.BOW || material == ItemTypes.CROSSBOW) { - /*player.packetStateData.slowedByUsingItem = player.gamemode == GameMode.CREATIVE || - player.getInventory().hasItemType(ItemTypes.ARROW) || - player.getInventory().hasItemType(ItemTypes.TIPPED_ARROW) || - player.getInventory().hasItemType(ItemTypes.SPECTRAL_ARROW); - player.packetStateData.eatingHand = place.getHand();*/ - // TODO: How do we lag compensate arrows? Mojang removed idle packet. - // I think we may have to cancel the bukkit event if the player isn't slowed - // On 1.8, it wouldn't be too bad to handle bows correctly - // But on 1.9+, no idle packet and clients/servers don't agree on bow status - // Mojang pls fix - player.packetStateData.slowedByUsingItem = false; - } + // The player cannot eat this item, resync use status + player.packetStateData.slowedByUsingItem = false; + } - // Only 1.8 and below players can block with swords - if (material.hasAttribute(ItemTypes.ItemAttribute.SWORD)) { - if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) - player.packetStateData.slowedByUsingItem = true; - else if (PacketEvents.getAPI().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_9)) // ViaVersion stuff - player.packetStateData.slowedByUsingItem = false; - } - } else { + if (material == ItemTypes.SHIELD && player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_9)) { + player.packetStateData.slowedByUsingItem = true; + player.packetStateData.eatingHand = hand; + return; + } + + // Avoid releasing crossbow as being seen as slowing player + final NBTCompound nbt = item.getNBT(); // How can this be null? + if (material == ItemTypes.CROSSBOW && nbt != null && nbt.getBoolean("Charged")) { + player.packetStateData.slowedByUsingItem = false; // TODO: Fix this + return; + } + + // The client and server don't agree on trident status because mojang is incompetent at netcode. + if (material == ItemTypes.TRIDENT) { + player.packetStateData.slowedByUsingItem = item.getEnchantmentLevel(EnchantmentTypes.RIPTIDE, PacketEvents.getAPI().getServerManager().getVersion().toClientVersion()) <= 0; + player.packetStateData.eatingHand = hand; + } + + // Players in survival can't use a bow without an arrow + // Crossbow charge checked previously + if (material == ItemTypes.BOW || material == ItemTypes.CROSSBOW) { + /*player.packetStateData.slowedByUsingItem = player.gamemode == GameMode.CREATIVE || + player.getInventory().hasItemType(ItemTypes.ARROW) || + player.getInventory().hasItemType(ItemTypes.TIPPED_ARROW) || + player.getInventory().hasItemType(ItemTypes.SPECTRAL_ARROW); + player.packetStateData.eatingHand = place.getHand();*/ + // TODO: How do we lag compensate arrows? Mojang removed idle packet. + // I think we may have to cancel the bukkit event if the player isn't slowed + // On 1.8, it wouldn't be too bad to handle bows correctly + // But on 1.9+, no idle packet and clients/servers don't agree on bow status + // Mojang pls fix player.packetStateData.slowedByUsingItem = false; } + + // Only 1.8 and below players can block with swords + if (material.hasAttribute(ItemTypes.ItemAttribute.SWORD)) { + if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) + player.packetStateData.slowedByUsingItem = true; + else if (PacketEvents.getAPI().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_9)) // ViaVersion stuff + player.packetStateData.slowedByUsingItem = false; + } } @Override