Skip to content

Commit

Permalink
Check for food component and fix null error with item use
Browse files Browse the repository at this point in the history
  • Loading branch information
SamB440 committed Jun 13, 2024
1 parent f43dbd9 commit 2107a00
Showing 1 changed file with 84 additions and 70 deletions.
154 changes: 84 additions & 70 deletions src/main/java/ac/grim/grimac/events/packets/PacketPlayerDigging.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down

0 comments on commit 2107a00

Please sign in to comment.