From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 19 Apr 2020 00:17:56 -0500 Subject: [PATCH] Anvil API diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java index dd4218e108f87f3305b76fbc8d88f488b447c609..ecfa807e78c16a24099d40becd0c7916f239aed1 100644 --- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java @@ -76,6 +76,7 @@ public abstract class AbstractContainerMenu { @Nullable private ContainerSynchronizer synchronizer; private boolean suppressRemoteUpdates; + @Nullable protected ItemStack activeQuickItem = null; // Purpur - Anvil API // CraftBukkit start public boolean checkReachable = true; diff --git a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java index 362278407679f245ebcea778f2199b357339e1fe..07e4c67ed1e5b14315ccbce4f0dd8abf0e5e6635 100644 --- a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java @@ -25,6 +25,12 @@ import org.slf4j.Logger; import org.bukkit.craftbukkit.inventory.view.CraftAnvilView; // CraftBukkit end +// Purpur start - Anvil API +import net.minecraft.network.protocol.game.ClientboundContainerSetDataPacket; +import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket; +import net.minecraft.server.level.ServerPlayer; +// Purpur end - Anvil API + public class AnvilMenu extends ItemCombinerMenu { public static final int INPUT_SLOT = 0; @@ -54,6 +60,10 @@ public class AnvilMenu extends ItemCombinerMenu { private CraftAnvilView bukkitEntity; // CraftBukkit end public boolean bypassEnchantmentLevelRestriction = false; // Paper - bypass anvil level restrictions + // Purpur start - Anvil API + public boolean bypassCost = false; + public boolean canDoUnsafeEnchants = false; + // Purpur end - Anvil API public AnvilMenu(int syncId, Inventory inventory) { this(syncId, inventory, ContainerLevelAccess.NULL); @@ -81,12 +91,17 @@ public class AnvilMenu extends ItemCombinerMenu { @Override protected boolean mayPickup(Player player, boolean present) { - return (player.hasInfiniteMaterials() || player.experienceLevel >= this.cost.get()) && this.cost.get() > AnvilMenu.DEFAULT_DENIED_COST && present; // CraftBukkit - allow cost 0 like a free item + return (player.hasInfiniteMaterials() || player.experienceLevel >= this.cost.get()) && (this.bypassCost || this.cost.get() > AnvilMenu.DEFAULT_DENIED_COST) && present; // CraftBukkit - allow cost 0 like a free item // Purpur - Anvil API } @Override protected void onTake(Player player, ItemStack stack) { + // Purpur start - Anvil API + ItemStack itemstack = this.activeQuickItem != null ? this.activeQuickItem : stack; + if (org.purpurmc.purpur.event.inventory.AnvilTakeResultEvent.getHandlerList().getRegisteredListeners().length > 0) new org.purpurmc.purpur.event.inventory.AnvilTakeResultEvent(player.getBukkitEntity(), getBukkitView(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)).callEvent(); + // Purpur end - Anvil API if (!player.getAbilities().instabuild) { + if (this.bypassCost) ((ServerPlayer) player).lastSentExp = -1; else // Purpur - Anvil API player.giveExperienceLevels(-this.cost.get()); } @@ -137,6 +152,12 @@ public class AnvilMenu extends ItemCombinerMenu { @Override public void createResult() { + // Purpur start - Anvil API + this.bypassCost = false; + this.canDoUnsafeEnchants = false; + if (org.purpurmc.purpur.event.inventory.AnvilUpdateResultEvent.getHandlerList().getRegisteredListeners().length > 0) new org.purpurmc.purpur.event.inventory.AnvilUpdateResultEvent(getBukkitView()).callEvent(); + // Purpur end - Anvil API + ItemStack itemstack = this.inputSlots.getItem(0); this.cost.set(1); @@ -144,7 +165,7 @@ public class AnvilMenu extends ItemCombinerMenu { long j = 0L; byte b0 = 0; - if (!itemstack.isEmpty() && EnchantmentHelper.canStoreEnchantments(itemstack)) { + if (!itemstack.isEmpty() && this.canDoUnsafeEnchants || EnchantmentHelper.canStoreEnchantments(itemstack)) { // Purpur - Anvil API ItemStack itemstack1 = itemstack.copy(); ItemStack itemstack2 = this.inputSlots.getItem(1); ItemEnchantments.Mutable itemenchantments_a = new ItemEnchantments.Mutable(EnchantmentHelper.getEnchantmentsForCrafting(itemstack1)); @@ -223,7 +244,7 @@ public class AnvilMenu extends ItemCombinerMenu { Holder holder1 = (Holder) iterator1.next(); if (!holder1.equals(holder) && !Enchantment.areCompatible(holder, holder1)) { - flag3 = false; + flag3 = this.canDoUnsafeEnchants; // Purpur - Anvil API ++i; } } @@ -281,6 +302,12 @@ public class AnvilMenu extends ItemCombinerMenu { this.cost.set(this.maximumRepairCost - 1); // CraftBukkit } + // Purpur start - Anvil API + if (this.bypassCost && this.cost.get() >= this.maximumRepairCost) { + this.cost.set(this.maximumRepairCost - 1); + } + // Purpur end - Anvil API + if (this.cost.get() >= this.maximumRepairCost && !this.player.getAbilities().instabuild) { // CraftBukkit itemstack1 = ItemStack.EMPTY; } @@ -302,6 +329,13 @@ public class AnvilMenu extends ItemCombinerMenu { org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(this.getBukkitView(), itemstack1); // CraftBukkit this.sendAllDataToRemote(); // CraftBukkit - SPIGOT-6686: Always send completed inventory to stay in sync with client this.broadcastChanges(); + + // Purpur start - Anvil API + if (this.canDoUnsafeEnchants && itemstack1 != ItemStack.EMPTY) { + ((ServerPlayer) this.player).connection.send(new ClientboundContainerSetSlotPacket(this.containerId, this.incrementStateId(), 2, itemstack1)); + ((ServerPlayer) this.player).connection.send(new ClientboundContainerSetDataPacket(this.containerId, 0, this.cost.get())); + } + // Purpur end - Anvil API } else { org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(this.getBukkitView(), ItemStack.EMPTY); // CraftBukkit this.cost.set(AnvilMenu.DEFAULT_DENIED_COST); // CraftBukkit - use a variable for set a cost for denied item diff --git a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java index 7de5e47f9a54263734eeef855a2dc07ef64d30ea..b3bd9bbd96efc4784b86c2be6bb857da4db919b8 100644 --- a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java +++ b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java @@ -178,7 +178,9 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu { return ItemStack.EMPTY; } + this.activeQuickItem = itemstack; // Purpur - Anvil API slot1.onTake(player, itemstack1); + this.activeQuickItem = null; // Purpur - Anvil API } return itemstack; diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java index 792cb6adf0c7a6335cc5985fce8bed2e0f1149af..5734c5caffda79383ae30df20c3defb51b87f39e 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java @@ -19,6 +19,10 @@ public class CraftInventoryAnvil extends CraftResultInventory implements AnvilIn private int repairCost; private int repairCostAmount; private int maximumRepairCost; + // Purpur start - Anvil API + private boolean bypassCost; + private boolean canDoUnsafeEnchants; + // Purpur end - Anvil API public CraftInventoryAnvil(Location location, Container inventory, Container resultInventory) { super(inventory, resultInventory); @@ -27,6 +31,10 @@ public class CraftInventoryAnvil extends CraftResultInventory implements AnvilIn this.repairCost = CraftInventoryAnvil.DEFAULT_REPAIR_COST; this.repairCostAmount = CraftInventoryAnvil.DEFAULT_REPAIR_COST_AMOUNT; this.maximumRepairCost = CraftInventoryAnvil.DEFAULT_MAXIMUM_REPAIR_COST; + // Purpur start - Anvil API + this.bypassCost = false; + this.canDoUnsafeEnchants = false; + // Purpur end - Anvil API } @Override @@ -113,4 +121,30 @@ public class CraftInventoryAnvil extends CraftResultInventory implements AnvilIn consumer.accept(cav); } } + + // Purpur start - Anvil API + @Override + public boolean canBypassCost() { + this.syncWithArbitraryViewValue((cav) -> this.bypassCost = cav.canBypassCost()); + return this.bypassCost; + } + + @Override + public void setBypassCost(boolean bypassCost) { + this.bypassCost = bypassCost; + this.syncViews((cav) -> cav.setBypassCost(bypassCost)); + } + + @Override + public boolean canDoUnsafeEnchants() { + this.syncWithArbitraryViewValue((cav) -> this.canDoUnsafeEnchants = cav.canDoUnsafeEnchants()); + return this.canDoUnsafeEnchants; + } + + @Override + public void setDoUnsafeEnchants(boolean canDoUnsafeEnchants) { + this.canDoUnsafeEnchants = canDoUnsafeEnchants; + this.syncViews((cav) -> cav.setDoUnsafeEnchants(canDoUnsafeEnchants)); + } + // Purpur end - Anvil API } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftAnvilView.java b/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftAnvilView.java index f86c95a13dff012de5db3e41ac261e9e8d44d9f3..1db0b790d824e419bb5fb6ab1f3003e120f9763b 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftAnvilView.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftAnvilView.java @@ -75,4 +75,26 @@ public class CraftAnvilView extends CraftInventoryView