This commit is contained in:
Bjarne Koll 2024-10-25 00:08:35 +02:00
parent 7616ebccd8
commit 6a315742d9
No known key found for this signature in database
GPG key ID: 27F6CCCF55D2EE62
21 changed files with 221 additions and 263 deletions

View file

@ -0,0 +1,215 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sat, 6 Jul 2024 13:57:10 -0700
Subject: [PATCH] fix horse inventories
Horse inventories now combine 2 inventories (like
result inventories).
== AT ==
public net/minecraft/world/inventory/HorseInventoryMenu SLOT_BODY_ARMOR
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
index 9bcc0931510607b8fbd01233e2b3c346369b214d..467693a60786688b753cebac3b0a88898e332eee 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
@@ -112,7 +112,7 @@ public abstract class CraftAbstractHorse extends CraftAnimals implements Abstrac
@Override
public AbstractHorseInventory getInventory() {
- return new CraftSaddledInventory(getHandle().inventory);
+ return new CraftSaddledInventory(getHandle().inventory, this.getHandle().getBodyArmorAccess()); // Paper - use both inventories
}
// Paper start - Horse API
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAbstractHorse.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAbstractHorse.java
index 4946da593713f4d11d88ac1bb68a089f2f6d5ae0..54e81472259dc13dfc7b2af6b211628c39435890 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAbstractHorse.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAbstractHorse.java
@@ -6,17 +6,106 @@ import org.bukkit.inventory.ItemStack;
public class CraftInventoryAbstractHorse extends CraftInventory implements AbstractHorseInventory {
- public CraftInventoryAbstractHorse(Container inventory) {
+ // Paper start - combine both horse inventories
+ private final Container bodyArmor;
+ public CraftInventoryAbstractHorse(Container inventory, final Container bodyArmor) {
super(inventory);
+ this.bodyArmor = bodyArmor;
+ // Paper end - combine both horse inventories
}
@Override
public ItemStack getSaddle() {
- return this.getItem(0);
+ return this.getItem(net.minecraft.world.entity.animal.horse.AbstractHorse.INV_SLOT_SADDLE); // Paper
}
@Override
public void setSaddle(ItemStack stack) {
- this.setItem(0, stack);
+ this.setItem(net.minecraft.world.entity.animal.horse.AbstractHorse.INV_SLOT_SADDLE, stack); // Paper
}
+
+ // Paper start - combine both horse inventories
+ public Container getMainInventory() {
+ return this.inventory;
+ }
+
+ public Container getArmorInventory() {
+ return this.bodyArmor;
+ }
+
+ public ItemStack getArmor() {
+ return this.getItem(net.minecraft.world.inventory.HorseInventoryMenu.SLOT_BODY_ARMOR);
+ }
+
+ public void setArmor(ItemStack armor) {
+ this.setItem(net.minecraft.world.inventory.HorseInventoryMenu.SLOT_BODY_ARMOR, armor);
+ }
+
+ @Override
+ public int getSize() {
+ return this.getMainInventory().getContainerSize() + this.getArmorInventory().getContainerSize();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return this.getMainInventory().isEmpty() && this.getArmorInventory().isEmpty();
+ }
+
+ @Override
+ public ItemStack[] getContents() {
+ ItemStack[] items = new ItemStack[this.getSize()];
+
+ items[net.minecraft.world.entity.animal.horse.AbstractHorse.INV_SLOT_SADDLE] = this.getSaddle();
+ items[net.minecraft.world.inventory.HorseInventoryMenu.SLOT_BODY_ARMOR] = this.getArmor();
+
+ for (int i = net.minecraft.world.inventory.HorseInventoryMenu.SLOT_BODY_ARMOR + 1; i < items.length; i++) {
+ net.minecraft.world.item.ItemStack item = this.getMainInventory().getItem(i - 1);
+ items[i] = item.isEmpty() ? null : CraftItemStack.asCraftMirror(item);
+ }
+
+ return items;
+ }
+
+ @Override
+ public void setContents(ItemStack[] items) {
+ com.google.common.base.Preconditions.checkArgument(items.length <= this.getSize(), "Invalid inventory size (%s); expected %s or less", items.length, this.getSize());
+
+ this.setSaddle(org.apache.commons.lang3.ArrayUtils.get(items, net.minecraft.world.entity.animal.horse.AbstractHorse.INV_SLOT_SADDLE));
+ this.setArmor(org.apache.commons.lang3.ArrayUtils.get(items, net.minecraft.world.inventory.HorseInventoryMenu.SLOT_BODY_ARMOR));
+
+ for (int i = net.minecraft.world.inventory.HorseInventoryMenu.SLOT_BODY_ARMOR + 1; i < this.getSize(); i++) {
+ net.minecraft.world.item.ItemStack item = i >= items.length ? net.minecraft.world.item.ItemStack.EMPTY : CraftItemStack.asNMSCopy(items[i]);
+ this.getMainInventory().setItem(i - 1, item);
+ }
+ }
+
+ @Override
+ public ItemStack getItem(final int index) {
+ if (index == net.minecraft.world.inventory.HorseInventoryMenu.SLOT_BODY_ARMOR) {
+ final net.minecraft.world.item.ItemStack item = this.getArmorInventory().getItem(0);
+ return item.isEmpty() ? null : CraftItemStack.asCraftMirror(item);
+ } else {
+ int shiftedIndex = index;
+ if (index > net.minecraft.world.inventory.HorseInventoryMenu.SLOT_BODY_ARMOR) {
+ shiftedIndex--;
+ }
+
+ final net.minecraft.world.item.ItemStack item = this.getMainInventory().getItem(shiftedIndex);
+ return item.isEmpty() ? null : CraftItemStack.asCraftMirror(item);
+ }
+ }
+
+ @Override
+ public void setItem(final int index, final ItemStack item) {
+ if (index == net.minecraft.world.inventory.HorseInventoryMenu.SLOT_BODY_ARMOR) {
+ this.getArmorInventory().setItem(0, CraftItemStack.asNMSCopy(item));
+ } else {
+ int shiftedIndex = index;
+ if (index > net.minecraft.world.inventory.HorseInventoryMenu.SLOT_BODY_ARMOR) {
+ shiftedIndex--;
+ }
+ this.getMainInventory().setItem(shiftedIndex, CraftItemStack.asNMSCopy(item));
+ }
+ }
+ // Paper end - combine both horse inventories
}
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java
index 07a304edc2a7b3450a55728e78a4fe37febdbadc..ebf0da48378b9376b3be2ca731315485003f6a89 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java
@@ -6,21 +6,9 @@ import org.bukkit.inventory.ItemStack;
public class CraftInventoryHorse extends CraftSaddledInventory implements HorseInventory {
- private final Container bodyArmorInventory;
-
+ // Paper start - properly combine both inventories
public CraftInventoryHorse(Container inventory, Container bodyArmorInventory) {
- super(inventory);
- this.bodyArmorInventory = bodyArmorInventory;
- }
-
- @Override
- public ItemStack getArmor() {
- net.minecraft.world.item.ItemStack item = this.bodyArmorInventory.getItem(0);
- return item.isEmpty() ? null : CraftItemStack.asCraftMirror(item);
- }
-
- @Override
- public void setArmor(ItemStack stack) {
- this.bodyArmorInventory.setItem(0, CraftItemStack.asNMSCopy(stack));
+ super(inventory, bodyArmorInventory);
}
+ // Paper end - properly combine both inventories
}
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryLlama.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryLlama.java
index dcbc80646ebfc384c4f6ab1beee46a4b71a67af8..0804b642d966f2cb09f4101410e2ff1d154ea594 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryLlama.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryLlama.java
@@ -6,21 +6,19 @@ import org.bukkit.inventory.LlamaInventory;
public class CraftInventoryLlama extends CraftInventoryAbstractHorse implements LlamaInventory {
- private final Container bodyArmorInventory;
-
+ // Paper start - properly combine both inventories
public CraftInventoryLlama(Container inventory, Container bodyArmorInventory) {
- super(inventory);
- this.bodyArmorInventory = bodyArmorInventory;
+ super(inventory, bodyArmorInventory);
+ // Paper end - properly combine both inventories
}
@Override
public ItemStack getDecor() {
- net.minecraft.world.item.ItemStack item = this.bodyArmorInventory.getItem(0);
- return item.isEmpty() ? null : CraftItemStack.asCraftMirror(item);
+ return this.getArmor(); // Paper
}
@Override
public void setDecor(ItemStack stack) {
- this.bodyArmorInventory.setItem(0, CraftItemStack.asNMSCopy(stack));
+ this.setArmor(stack); // Paper
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSaddledInventory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSaddledInventory.java
index 3a617c07d445bacf5a13e0e3ff6481823cfc8477..1c100c7c210485c1d3510745de7d18f58ba72557 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSaddledInventory.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSaddledInventory.java
@@ -5,8 +5,10 @@ import org.bukkit.inventory.SaddledHorseInventory;
public class CraftSaddledInventory extends CraftInventoryAbstractHorse implements SaddledHorseInventory {
- public CraftSaddledInventory(Container inventory) {
- super(inventory);
+ // Paper start - combine both inventories
+ public CraftSaddledInventory(Container inventory, final Container bodyArmor) {
+ super(inventory, bodyArmor);
+ // Paper end - combine both inventories
}
}

View file

@ -0,0 +1,73 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Bjarne Koll <lynxplay101@gmail.com>
Date: Mon, 8 Jul 2024 22:01:08 +0200
Subject: [PATCH] Only call EntityDamageEvents before actuallyHurt
The recent upstream update moved around the event logic for
EntiyDamageEvent and its derivatives.
However, the event was called on every call to #hurt as it was moved out
of actuallyHurt.
This patch moves the invocation directly before the #actuallyHurt calls,
respective invulnerable timings.
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index f75b66c9ec786bc6f4d3f5cd5127c815f11166c4..b4d1848858fae20f81c27b31bc0c280c6705f082 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -1491,12 +1491,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
// CraftBukkit start
- EntityDamageEvent event = this.handleEntityDamage(source, amount);
- amount = 0;
- amount += (float) event.getDamage(DamageModifier.BASE);
- amount += (float) event.getDamage(DamageModifier.BLOCKING);
- amount += (float) event.getDamage(DamageModifier.FREEZING);
- amount += (float) event.getDamage(DamageModifier.HARD_HAT);
+ EntityDamageEvent event; // Paper - move this into the actual invuln check....
// CraftBukkit end
this.walkAnimation.setSpeed(1.5F);
@@ -1511,6 +1506,11 @@ public abstract class LivingEntity extends Entity implements Attackable {
return false;
}
+ // Paper start - only call damage event when actuallyHurt will be called - move call logic down
+ event = this.handleEntityDamage(source, amount);
+ amount = computeAmountFromEntityDamageEvent(event);
+ // Paper end - only call damage event when actuallyHurt will be called - move call logic down
+
// CraftBukkit start
if (!this.actuallyHurt(world, source, (float) event.getFinalDamage() - this.lastHurt, event)) {
return false;
@@ -1520,6 +1520,10 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.lastHurt = amount;
flag1 = false;
} else {
+ // Paper start - only call damage event when actuallyHurt will be called - move call logic down
+ event = this.handleEntityDamage(source, amount);
+ amount = computeAmountFromEntityDamageEvent(event);
+ // Paper end - only call damage event when actuallyHurt will be called - move call logic down
// CraftBukkit start
if (!this.actuallyHurt(world, source, (float) event.getFinalDamage(), event)) {
return false;
@@ -1655,6 +1659,18 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
}
+ // Paper start - only call damage event when actuallyHurt will be called - move out amount computation logic
+ private float computeAmountFromEntityDamageEvent(final EntityDamageEvent event) {
+ // Taken from hurt()'s craftbukkit diff.
+ float amount = 0;
+ amount += (float) event.getDamage(DamageModifier.BASE);
+ amount += (float) event.getDamage(DamageModifier.BLOCKING);
+ amount += (float) event.getDamage(DamageModifier.FREEZING);
+ amount += (float) event.getDamage(DamageModifier.HARD_HAT);
+ return amount;
+ }
+ // Paper end - only call damage event when actuallyHurt will be called - move out amount computation logic
+
protected void blockUsingShield(LivingEntity attacker) {
attacker.blockedByShield(this);
}

View file

@ -0,0 +1,23 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Tue, 9 Jul 2024 18:37:37 -0700
Subject: [PATCH] Add ItemType#getItemRarity
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java
index 96dfcfa12c63c682edcdec98647ca6a94d9fb4ed..d3f650d040afae8cb962696381c692cd7884bb4d 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java
@@ -262,4 +262,12 @@ public class CraftItemType<M extends ItemMeta> implements ItemType.Typed<M>, Han
return this.item.getDescriptionId();
}
// Paper end - add Translatable
+
+ // Paper start - expand ItemRarity API
+ @Override
+ public org.bukkit.inventory.ItemRarity getItemRarity() {
+ final net.minecraft.world.item.Rarity rarity = this.item.components().get(DataComponents.RARITY);
+ return rarity == null ? null : org.bukkit.inventory.ItemRarity.valueOf(rarity.name());
+ }
+ // Paper end - expand ItemRarity API
}

View file

@ -0,0 +1,64 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Thu, 18 Jul 2024 18:44:28 -0700
Subject: [PATCH] Add plugin info at startup
diff --git a/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java b/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java
index 49d8e207795997e5deaf830eb971067f84bfc791..70413fddd23ca1165cb5090cce4fddcb1bbca93f 100644
--- a/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java
+++ b/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java
@@ -6,7 +6,10 @@ import io.papermc.paper.plugin.entrypoint.Entrypoint;
import io.papermc.paper.plugin.entrypoint.LaunchEntryPointHandler;
import io.papermc.paper.plugin.provider.PluginProvider;
import io.papermc.paper.plugin.provider.type.paper.PaperPluginParent;
+import io.papermc.paper.plugin.provider.type.spigot.SpigotPluginProvider;
import io.papermc.paper.pluginremap.PluginRemapper;
+import java.util.Set;
+import java.util.TreeSet;
import java.util.function.Function;
import joptsimple.OptionSet;
import net.minecraft.server.dedicated.DedicatedServer;
@@ -101,6 +104,7 @@ public class PluginInitializerManager {
}
public static void load(OptionSet optionSet) throws Exception {
+ LOGGER.info("Initializing plugins...");
// We have to load the bukkit configuration inorder to get the update folder location.
io.papermc.paper.plugin.PluginInitializerManager pluginSystem = io.papermc.paper.plugin.PluginInitializerManager.init(optionSet);
if (pluginSystem.pluginRemapper != null) pluginSystem.pluginRemapper.loadingPlugins();
@@ -112,6 +116,34 @@ public class PluginInitializerManager {
@SuppressWarnings("unchecked")
java.util.List<Path> files = ((java.util.List<File>) optionSet.valuesOf("add-plugin")).stream().map(File::toPath).toList();
io.papermc.paper.plugin.util.EntrypointUtil.registerProvidersFromSource(io.papermc.paper.plugin.provider.source.PluginFlagProviderSource.INSTANCE, files);
+
+ final Set<String> paperPluginNames = new TreeSet<>();
+ final Set<String> legacyPluginNames = new TreeSet<>();
+ LaunchEntryPointHandler.INSTANCE.getStorage().forEach((entrypoint, providerStorage) -> {
+ providerStorage.getRegisteredProviders().forEach(provider -> {
+ if (provider instanceof final SpigotPluginProvider legacy) {
+ legacyPluginNames.add(String.format("%s (%s)", legacy.getMeta().getName(), legacy.getMeta().getVersion()));
+ } else if (provider instanceof final PaperPluginParent.PaperServerPluginProvider paper) {
+ paperPluginNames.add(String.format("%s (%s)", provider.getMeta().getName(), provider.getMeta().getVersion()));
+ }
+ });
+ });
+ final int total = paperPluginNames.size() + legacyPluginNames.size();
+ LOGGER.info("Initialized {} plugin{}", total, total == 1 ? "" : "s");
+ if (!paperPluginNames.isEmpty()) {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.info("Paper plugins ({}):\n - {}", paperPluginNames.size(), String.join("\n - ", paperPluginNames));
+ } else {
+ LOGGER.info("Paper plugins ({}):\n - {}", paperPluginNames.size(), String.join(", ", paperPluginNames));
+ }
+ }
+ if (!legacyPluginNames.isEmpty()) {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.info("Bukkit plugins ({}):\n - {}", legacyPluginNames.size(), String.join("\n - ", legacyPluginNames));
+ } else {
+ LOGGER.info("Bukkit plugins ({}):\n - {}", legacyPluginNames.size(), String.join(", ", legacyPluginNames));
+ }
+ }
}
// This will be the end of me...

View file

@ -0,0 +1,26 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Newwind <support@newwindserver.com>
Date: Thu, 25 Jul 2024 13:00:37 +0200
Subject: [PATCH] Make interaction leniency distance configurable
The server validates incoming interaction packets by ensuring the player
sending them is inside their interaction range. For this, the server adds
a magic value, by default 1.0, to the original interaction range to
account for latency issues.
This value however may be too low in high latency environments.
The patch exposes a new configuration option to configure said value.
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 14a8e05420ae4ca2f1d9028e19379d162a3e6971..c9fd2b8cc5a14d4ef4072765d5274d0c470bcfe6 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2722,7 +2722,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
AABB axisalignedbb = entity.getBoundingBox();
- if (this.player.canInteractWithEntity(axisalignedbb, 3.0D)) {
+ if (this.player.canInteractWithEntity(axisalignedbb, io.papermc.paper.configuration.GlobalConfiguration.get().misc.clientInteractionLeniencyDistance.or(3.0D))) { // Paper - configurable lenience value for interact range
packet.dispatch(new ServerboundInteractPacket.Handler() {
private void performInteraction(InteractionHand enumhand, ServerGamePacketListenerImpl.EntityInteraction playerconnection_a, PlayerInteractEntityEvent event) { // CraftBukkit
ItemStack itemstack = ServerGamePacketListenerImpl.this.player.getItemInHand(enumhand);

View file

@ -0,0 +1,65 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tamion <70228790+notTamion@users.noreply.github.com>
Date: Sun, 21 Jul 2024 19:11:22 +0200
Subject: [PATCH] Fix PickupStatus getting reset
diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
index 14e31ae88e90d8ea1a98800cc6c1c3527bb2ed6b..accc246f441c8bf5e1a755cfc0db8f97c0c01c6b 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
@@ -714,7 +714,14 @@ public abstract class AbstractArrow extends Projectile {
@Override
public void setOwner(@Nullable Entity entity) {
+ // Paper start - Fix PickupStatus getting reset
+ this.setOwner(entity, true);
+ }
+
+ public void setOwner(@Nullable Entity entity, boolean resetPickup) {
+ // Paper end - Fix PickupStatus getting reset
super.setOwner(entity);
+ if (!resetPickup) return; // Paper - Fix PickupStatus getting reset
Entity entity1 = entity;
byte b0 = 0;
diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
index 3982b32cf69250ebd138eff225b65313f75286ea..03c1bffd3125bb7a82ac921b0a23dcab55c33c4f 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
@@ -353,7 +353,13 @@ public abstract class Projectile extends Entity implements TraceableEntity {
public boolean deflect(ProjectileDeflection deflection, @Nullable Entity deflector, @Nullable Entity owner, boolean fromAttack) {
deflection.deflect(this, deflector, this.random);
if (!this.level().isClientSide) {
- this.setOwner(owner);
+ // Paper start - Fix PickupStatus getting reset
+ if (this instanceof AbstractArrow arrow) {
+ arrow.setOwner(owner, false);
+ } else {
+ this.setOwner(owner);
+ }
+ // Paper end - Fix PickupStatus getting reset
this.onDeflection(deflector, fromAttack);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java
index 1f30109abd86b76af343eb5eb75ec3db83ef9417..d0c30fd12aa9866900fe72b97d10c257479cf010 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java
@@ -173,4 +173,16 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr
this.getHandle().setSoundEvent(org.bukkit.craftbukkit.CraftSound.bukkitToMinecraft(sound));
}
// Paper end
+
+ // Paper start - Fix PickupStatus getting reset - Copy of CraftProjectile#setShooter, calling setOwner(Entity,boolean)
+ @Override
+ public void setShooter(org.bukkit.projectiles.ProjectileSource shooter, boolean resetPickupStatus) {
+ if (shooter instanceof CraftEntity craftEntity) {
+ this.getHandle().setOwner(craftEntity.getHandle(), resetPickupStatus);
+ } else {
+ this.getHandle().setOwner(null, resetPickupStatus);
+ }
+ this.getHandle().projectileSource = shooter;
+ }
+ // Paper end - Fix PickupStatus getting reset
}

View file

@ -0,0 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nassim Jahnke <nassim@njahnke.dev>
Date: Wed, 7 Aug 2024 14:33:25 +0200
Subject: [PATCH] Check for block type in SculkSensorBlock#canActivate
diff --git a/src/main/java/net/minecraft/world/level/block/SculkSensorBlock.java b/src/main/java/net/minecraft/world/level/block/SculkSensorBlock.java
index 22d299a19f19ad5dd13262792ae448311d1ea3e4..0ed449a188d98f87dbddd2d76009fed02a29ed25 100644
--- a/src/main/java/net/minecraft/world/level/block/SculkSensorBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/SculkSensorBlock.java
@@ -219,7 +219,7 @@ public class SculkSensorBlock extends BaseEntityBlock implements SimpleWaterlogg
}
public static boolean canActivate(BlockState state) {
- return SculkSensorBlock.getPhase(state) == SculkSensorPhase.INACTIVE;
+ return state.getBlock() instanceof SculkSensorBlock && SculkSensorBlock.getPhase(state) == SculkSensorPhase.INACTIVE; // Paper - Check for a valid type
}
public static void deactivate(Level world, BlockPos pos, BlockState state) {

View file

@ -0,0 +1,155 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Wed, 12 Sep 2018 18:53:55 +0300
Subject: [PATCH] Add API for CanPlaceOn and CanDestroy NBT values
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
index 450c5aa14b4195eb7123492c7a111ec6f40ce412..7d9f75e680e243ac8c7defdd150e431b47225945 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
@@ -2498,4 +2498,117 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
}
// Paper end
+ // Paper start - Add an API for can-place-on/can-break adventure mode predicates
+ @Override
+ public Set<Material> getCanDestroy() {
+ return !this.hasDestroyableKeys() ? Collections.emptySet() : convertToLegacyMaterial(this.canBreakPredicates);
+ }
+
+ @Override
+ public void setCanDestroy(final Set<Material> canDestroy) {
+ Preconditions.checkArgument(canDestroy != null, "Cannot replace with null set!");
+ this.canBreakPredicates = convertFromLegacyMaterial(canDestroy);
+ }
+
+ @Override
+ public Set<Material> getCanPlaceOn() {
+ return !this.hasPlaceableKeys() ? Collections.emptySet() : convertToLegacyMaterial(this.canPlaceOnPredicates);
+ }
+
+ @Override
+ public void setCanPlaceOn(final Set<Material> canPlaceOn) {
+ Preconditions.checkArgument(canPlaceOn != null, "Cannot replace with null set!");
+ this.canPlaceOnPredicates = convertFromLegacyMaterial(canPlaceOn);
+ }
+
+ private static List<net.minecraft.advancements.critereon.BlockPredicate> convertFromLegacyMaterial(final Collection<Material> materials) {
+ return materials.stream().map(m -> {
+ return net.minecraft.advancements.critereon.BlockPredicate.Builder.block().of(CraftBlockType.bukkitToMinecraft(m)).build();
+ }).toList();
+ }
+
+ private static Set<Material> convertToLegacyMaterial(final List<net.minecraft.advancements.critereon.BlockPredicate> predicates) {
+ return predicates.stream()
+ .flatMap(p -> p.blocks().map(net.minecraft.core.HolderSet::stream).orElse(java.util.stream.Stream.empty()))
+ .map(holder -> CraftBlockType.minecraftToBukkit(holder.value()))
+ .collect(java.util.stream.Collectors.toSet());
+ }
+
+ @Override
+ public Set<com.destroystokyo.paper.Namespaced> getDestroyableKeys() {
+ return !this.hasDestroyableKeys() ? Collections.emptySet() : convertToLegacyNamespaced(this.canBreakPredicates);
+ }
+
+ @Override
+ public void setDestroyableKeys(final Collection<com.destroystokyo.paper.Namespaced> canDestroy) {
+ Preconditions.checkArgument(canDestroy != null, "Cannot replace with null collection!");
+ Preconditions.checkArgument(ofAcceptableType(canDestroy), "Can only use NamespacedKey or NamespacedTag objects!");
+ this.canBreakPredicates = convertFromLegacyNamespaced(canDestroy);
+ }
+
+ @Override
+ public Set<com.destroystokyo.paper.Namespaced> getPlaceableKeys() {
+ return !this.hasPlaceableKeys() ? Collections.emptySet() : convertToLegacyNamespaced(this.canPlaceOnPredicates);
+ }
+
+ @Override
+ public void setPlaceableKeys(final Collection<com.destroystokyo.paper.Namespaced> canPlaceOn) {
+ Preconditions.checkArgument(canPlaceOn != null, "Cannot replace with null collection!");
+ Preconditions.checkArgument(ofAcceptableType(canPlaceOn), "Can only use NamespacedKey or NamespacedTag objects!");
+ this.canPlaceOnPredicates = convertFromLegacyNamespaced(canPlaceOn);
+ }
+
+ private static List<net.minecraft.advancements.critereon.BlockPredicate> convertFromLegacyNamespaced(final Collection<com.destroystokyo.paper.Namespaced> namespaceds) {
+ final List<net.minecraft.advancements.critereon.BlockPredicate> predicates = new ArrayList<>();
+ for (final com.destroystokyo.paper.Namespaced namespaced : namespaceds) {
+ if (namespaced instanceof final org.bukkit.NamespacedKey key) {
+ predicates.add(net.minecraft.advancements.critereon.BlockPredicate.Builder.block().of(CraftBlockType.bukkitToMinecraft(Objects.requireNonNull(org.bukkit.Registry.MATERIAL.get(key)))).build());
+ } else if (namespaced instanceof final com.destroystokyo.paper.NamespacedTag tag) {
+ predicates.add(net.minecraft.advancements.critereon.BlockPredicate.Builder.block().of(net.minecraft.tags.TagKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath(tag.getNamespace(), tag.getKey()))).build());
+ }
+ }
+ return predicates;
+ }
+
+ private static Set<com.destroystokyo.paper.Namespaced> convertToLegacyNamespaced(final Collection<net.minecraft.advancements.critereon.BlockPredicate> predicates) {
+ final Set<com.destroystokyo.paper.Namespaced> namespaceds = Sets.newHashSet();
+ for (final net.minecraft.advancements.critereon.BlockPredicate predicate : predicates) {
+ if (predicate.blocks().isEmpty()) {
+ continue;
+ }
+ final net.minecraft.core.HolderSet<net.minecraft.world.level.block.Block> holders = predicate.blocks().get();
+ if (holders instanceof final net.minecraft.core.HolderSet.Named<net.minecraft.world.level.block.Block> named) {
+ namespaceds.add(new com.destroystokyo.paper.NamespacedTag(named.key().location().getNamespace(), named.key().location().getPath()));
+ } else {
+ holders.forEach(h -> {
+ h.unwrapKey().ifPresent(key -> {
+ namespaceds.add(new org.bukkit.NamespacedKey(key.location().getNamespace(), key.location().getPath()));
+ });
+ });
+ }
+ }
+ return namespaceds;
+ }
+
+ @Override
+ public boolean hasPlaceableKeys() {
+ return this.canPlaceOnPredicates != null;
+ }
+
+ @Override
+ public boolean hasDestroyableKeys() {
+ return this.canBreakPredicates != null;
+ }
+
+ // not a fan of this
+ private static boolean ofAcceptableType(final Collection<com.destroystokyo.paper.Namespaced> namespacedResources) {
+ for (com.destroystokyo.paper.Namespaced resource : namespacedResources) {
+ if (!(resource instanceof org.bukkit.NamespacedKey || resource instanceof com.destroystokyo.paper.NamespacedTag)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ // Paper end - Add an API for can-place-on/can-break adventure mode predicates
}
diff --git a/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java b/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java
index 6930d0afb230a88aa813b02e4d55c95d3a049688..db8d8e2a07296d62c3097f02b03319e2e1ba9394 100644
--- a/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java
+++ b/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java
@@ -690,4 +690,22 @@ public class MaterialRerouting {
return ItemStack.of(material, amount);
}
// Paper end
+
+ // Paper start - methods added post 1.13, no-op (https://github.com/PaperMC/Paper/pull/1015)
+ public static Set<Material> getCanDestroy(final ItemMeta meta) {
+ return meta.getCanDestroy();
+ }
+
+ public static void setCanDestroy(final ItemMeta meta, final Set<Material> materials) {
+ meta.setCanDestroy(materials);
+ }
+
+ public static Set<Material> getCanPlaceOn(final ItemMeta meta) {
+ return meta.getCanPlaceOn();
+ }
+
+ public static void setCanPlaceOn(final ItemMeta meta, final Set<Material> materials) {
+ meta.setCanPlaceOn(materials);
+ }
+ // Paper end
}

View file

@ -0,0 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Newwind <support@newwindserver.com>
Date: Wed, 7 Aug 2024 13:25:55 +0200
Subject: [PATCH] Configuration for horizontal-only item merging
Most of the visual artifacts that result from having item merge radius above vanilla levels is from items merging vertically,
which realistically, only happens when a player is dropping items, or items are dropping from breaking a block.
Most of the scenarios where item merging makes sense involves the two item entities being on the same Y level. i.e on the ground next to each other.
This is even more apparent since paper fixed items being able to merge through blocks.
This patch allows us to configure items to only merge horizontally, which is what vanilla does.
This allows us to have both the reduced number of item entities a high item-merge radius provides,
without most of the visual artifacts caused by items merging vertically.
diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
index e83a705f54063a17fc69a22683333aacad5a43ce..246b5649883e4f305afa5a887b9df0f3735f7593 100644
--- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
+++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
@@ -285,7 +285,7 @@ public class ItemEntity extends Entity implements TraceableEntity {
if (this.isMergable()) {
// Spigot start
double radius = this.level().spigotConfig.itemMerge;
- List<ItemEntity> list = this.level().getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate(radius, radius - 0.5D, radius), (entityitem) -> {
+ List<ItemEntity> list = this.level().getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate(radius, this.level().paperConfig().entities.behavior.onlyMergeItemsHorizontally ? 0 : radius - 0.5D, radius), (entityitem) -> { // Paper - configuration to only merge items horizontally
// Spigot end
return entityitem != this && entityitem.isMergable();
});

View file

@ -0,0 +1,21 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: mja00 <me@mja00.dev>
Date: Mon, 12 Aug 2024 06:27:15 -0400
Subject: [PATCH] Add skipping world symlink scan
In worlds that are extremely large (greater than 1TB), it can take an insanely long time to walk the entire world for symlinks.
This patch adds a system property to disable the symlink scan, which can be used to speed up world loading.
diff --git a/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java b/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java
index b5abdd1498a3d19559149c30ba959aa2bcf0246c..79397b3c76e4b9d2ee03dfa16c2daf4f71ae8b4d 100644
--- a/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java
+++ b/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java
@@ -411,7 +411,7 @@ public class LevelStorageSource {
public LevelStorageSource.LevelStorageAccess validateAndCreateAccess(String s, ResourceKey<LevelStem> dimensionType) throws IOException, ContentValidationException { // CraftBukkit
Path path = this.getLevelPath(s);
- List<ForbiddenSymlinkInfo> list = this.worldDirValidator.validateDirectory(path, true);
+ List<ForbiddenSymlinkInfo> list = Boolean.getBoolean("paper.disableWorldSymlinkValidation") ? List.of() : this.worldDirValidator.validateDirectory(path, true); // Paper - add skipping of symlinks scan
if (!list.isEmpty()) {
throw new ContentValidationException(path, list);

View file

@ -0,0 +1,47 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 19 Jul 2024 08:42:45 -0700
Subject: [PATCH] Add even more Enchantment API
In a separate patch because RegistryKeySet is used
and the previous "more enchant api" patch is before that.
diff --git a/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java b/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java
index 4221a1e9cba35c8dc58e51e162e7fcbd0e8b31af..34934f0dbe66ee200cd99c002c53645660041548 100644
--- a/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java
+++ b/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java
@@ -216,6 +216,34 @@ public class CraftEnchantment extends Enchantment implements Handleable<net.mine
}
// Paper end - more Enchantment API
+ // Paper start - even more Enchantment API
+ @Override
+ public net.kyori.adventure.text.Component description() {
+ return io.papermc.paper.adventure.PaperAdventure.asAdventure(this.handle.value().description());
+ }
+
+ @Override
+ public io.papermc.paper.registry.set.RegistryKeySet<org.bukkit.inventory.ItemType> getSupportedItems() {
+ return io.papermc.paper.registry.set.PaperRegistrySets.convertToApi(io.papermc.paper.registry.RegistryKey.ITEM, this.handle.value().getSupportedItems());
+ }
+
+ @Override
+ public io.papermc.paper.registry.set.RegistryKeySet<org.bukkit.inventory.ItemType> getPrimaryItems() {
+ final java.util.Optional<net.minecraft.core.HolderSet<net.minecraft.world.item.Item>> primaryItems = this.handle.value().definition().primaryItems();
+ return primaryItems.map(holders -> io.papermc.paper.registry.set.PaperRegistrySets.convertToApi(io.papermc.paper.registry.RegistryKey.ITEM, holders)).orElse(null);
+ }
+
+ @Override
+ public int getWeight() {
+ return this.handle.value().getWeight();
+ }
+
+ @Override
+ public io.papermc.paper.registry.set.RegistryKeySet<org.bukkit.enchantments.Enchantment> getExclusiveWith() {
+ return io.papermc.paper.registry.set.PaperRegistrySets.convertToApi(io.papermc.paper.registry.RegistryKey.ENCHANTMENT, this.handle.value().exclusiveSet());
+ }
+ // Paper end - even more Enchantment API
+
@Override
public String getTranslationKey() {
return Util.makeDescriptionId("enchantment", this.handle.unwrapKey().get().location());

View file

@ -0,0 +1,161 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
Date: Sat, 22 Jun 2024 21:17:54 +0200
Subject: [PATCH] Leashable API
diff --git a/src/main/java/io/papermc/paper/entity/PaperLeashable.java b/src/main/java/io/papermc/paper/entity/PaperLeashable.java
new file mode 100644
index 0000000000000000000000000000000000000000..a9ddf9a4a07cd29833f38d7e5f42b2b14ec98f78
--- /dev/null
+++ b/src/main/java/io/papermc/paper/entity/PaperLeashable.java
@@ -0,0 +1,50 @@
+package io.papermc.paper.entity;
+
+import com.google.common.base.Preconditions;
+import net.minecraft.world.entity.Leashable;
+import org.bukkit.craftbukkit.entity.CraftEntity;
+import org.bukkit.entity.Entity;
+
+public interface PaperLeashable extends io.papermc.paper.entity.Leashable {
+
+ Leashable getHandle();
+
+ @Override
+ default boolean isLeashed() {
+ return this.getHandle().getLeashHolder() != null;
+ }
+
+ @Override
+ default Entity getLeashHolder() throws IllegalStateException {
+ Preconditions.checkState(this.isLeashed(), "Entity not leashed");
+ return this.getHandle().getLeashHolder().getBukkitEntity();
+ }
+
+ private boolean unleash() {
+ if (!this.isLeashed()) {
+ return false;
+ }
+
+ this.getHandle().dropLeash(true, false);
+ return true;
+ }
+
+ @Override
+ default boolean setLeashHolder(Entity holder) {
+ if (this.getHandle() instanceof net.minecraft.world.entity.Entity entity && entity.generation) {
+ return false;
+ }
+
+ if (holder == null) {
+ return this.unleash();
+ }
+
+ if (holder.isDead()) {
+ return false;
+ }
+
+ this.unleash();
+ this.getHandle().setLeashedTo(((CraftEntity) holder).getHandle(), true);
+ return true;
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java
index 412fd9e87ec81cf50cb8bc82fe2dad5dd0029039..9046d6fa36b9f5e5d25835ad8d94c869c0764060 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java
@@ -8,7 +8,7 @@ import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.entity.Boat;
import org.bukkit.entity.Entity;
-public abstract class CraftBoat extends CraftVehicle implements Boat {
+public abstract class CraftBoat extends CraftVehicle implements Boat, io.papermc.paper.entity.PaperLeashable { // Paper - Leashable API
public CraftBoat(CraftServer server, AbstractBoat entity) {
super(server, entity);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
index f16067b674118a47735ad22797988d50b4415040..d0c409f4efad289e3e325f44b500fc72589d89d4 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
@@ -784,43 +784,17 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
@Override
public boolean isLeashed() {
- if (!(this.getHandle() instanceof Mob)) {
- return false;
- }
- return ((Mob) this.getHandle()).getLeashHolder() != null;
+ return false; // Paper - implement in CraftMob & PaperLeashable
}
@Override
public Entity getLeashHolder() throws IllegalStateException {
- Preconditions.checkState(this.isLeashed(), "Entity not leashed");
- return ((Mob) this.getHandle()).getLeashHolder().getBukkitEntity();
- }
-
- private boolean unleash() {
- if (!this.isLeashed()) {
- return false;
- }
- ((Mob) this.getHandle()).dropLeash(true, false);
- return true;
+ throw new IllegalStateException("Entity not leashed"); // Paper - implement in CraftMob & PaperLeashable
}
@Override
public boolean setLeashHolder(Entity holder) {
- if (this.getHandle().generation || (this.getHandle() instanceof WitherBoss) || !(this.getHandle() instanceof Mob)) {
- return false;
- }
-
- if (holder == null) {
- return this.unleash();
- }
-
- if (holder.isDead()) {
- return false;
- }
-
- this.unleash();
- ((Mob) this.getHandle()).setLeashedTo(((CraftEntity) holder).getHandle(), true);
- return true;
+ return false; // Paper - implement in CraftMob & PaperLeashable
}
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
index 95d7015a61098d1d22a501124d6bb8fba1516fe3..778a9d3f8bfe5dba59e1e655e4eeb8822678b8cf 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
@@ -11,7 +11,7 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Mob;
import org.bukkit.loot.LootTable;
-public abstract class CraftMob extends CraftLivingEntity implements Mob {
+public abstract class CraftMob extends CraftLivingEntity implements Mob, io.papermc.paper.entity.PaperLeashable { // Paper - Leashable API
public CraftMob(CraftServer server, net.minecraft.world.entity.Mob entity) {
super(server, entity);
paperPathfinder = new com.destroystokyo.paper.entity.PaperPathfinder(entity); // Paper - Mob Pathfinding API
@@ -175,4 +175,21 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob {
return getHandle().getExperienceReward((net.minecraft.server.level.ServerLevel) this.getHandle().level(), null);
}
// Paper end
+
+ // Paper start - Leashable API
+ @Override
+ public boolean isLeashed() {
+ return io.papermc.paper.entity.PaperLeashable.super.isLeashed();
+ }
+
+ @Override
+ public org.bukkit.entity.Entity getLeashHolder() throws IllegalStateException {
+ return io.papermc.paper.entity.PaperLeashable.super.getLeashHolder();
+ }
+
+ @Override
+ public boolean setLeashHolder(final org.bukkit.entity.Entity holder) {
+ return io.papermc.paper.entity.PaperLeashable.super.setLeashHolder(holder);
+ }
+ // Paper end - Leashable API
}

View file

@ -0,0 +1,54 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tamion <70228790+notTamion@users.noreply.github.com>
Date: Sun, 26 May 2024 22:20:21 +0200
Subject: [PATCH] Fix CraftBukkit drag system
== AT ==
public net.minecraft.world.inventory.AbstractContainerMenu quickcraftSlots
public net.minecraft.world.inventory.AbstractContainerMenu quickcraftStatus
public net.minecraft.world.inventory.AbstractContainerMenu quickcraftType
public net.minecraft.world.inventory.AbstractContainerMenu resetQuickCraft()V
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index c9fd2b8cc5a14d4ef4072765d5274d0c470bcfe6..1ab3f730301e8ac22702601a04ad8f1521585daa 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -3080,6 +3080,25 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
}
break;
case QUICK_CRAFT:
+ // Paper start - Fix CraftBukkit drag system
+ AbstractContainerMenu containerMenu = this.player.containerMenu;
+ int currentStatus = this.player.containerMenu.quickcraftStatus;
+ int newStatus = AbstractContainerMenu.getQuickcraftHeader(packet.getButtonNum());
+ if ((currentStatus != 1 || newStatus != 2 && currentStatus != newStatus)) {
+ } else if (containerMenu.getCarried().isEmpty()) {
+ } else if (newStatus == 0) {
+ } else if (newStatus == 1) {
+ } else if (newStatus == 2) {
+ if (!this.player.containerMenu.quickcraftSlots.isEmpty()) {
+ if (this.player.containerMenu.quickcraftSlots.size() == 1) {
+ int index = containerMenu.quickcraftSlots.iterator().next().index;
+ containerMenu.resetQuickCraft();
+ this.handleContainerClick(new ServerboundContainerClickPacket(packet.getContainerId(), packet.getStateId(), index, containerMenu.quickcraftType, net.minecraft.world.inventory.ClickType.PICKUP, packet.getCarriedItem(), packet.getChangedSlots()));
+ return;
+ }
+ }
+ }
+ // Paper end - Fix CraftBukkit drag system
this.player.containerMenu.clicked(packet.getSlotNum(), packet.getButtonNum(), packet.getClickType(), this.player);
break;
case PICKUP_ALL:
diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
index 78d0ff45c016e900d87010e8b26b0bb10e63f445..4680f77a275d8d2b226018db89a571ac25998dd8 100644
--- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
+++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
@@ -468,7 +468,7 @@ public abstract class AbstractContainerMenu {
}
} else if (this.quickcraftStatus == 2) {
if (!this.quickcraftSlots.isEmpty()) {
- if (false && this.quickcraftSlots.size() == 1) { // CraftBukkit - treat everything as a drag since we are unable to easily call InventoryClickEvent instead
+ if (this.quickcraftSlots.size() == 1) { // Paper - Fix CraftBukkit drag system
k = ((Slot) this.quickcraftSlots.iterator().next()).index;
this.resetQuickCraft();
this.doClick(k, this.quickcraftType, ClickType.PICKUP, player);

View file

@ -0,0 +1,39 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Mon, 19 Aug 2024 13:43:06 -0700
Subject: [PATCH] Fix SculkBloomEvent firing for block entity loading
diff --git a/src/main/java/net/minecraft/world/level/block/SculkSpreader.java b/src/main/java/net/minecraft/world/level/block/SculkSpreader.java
index b9a1709b79c1f7a21c9d08f986d4ea3b546e4a67..24590d131587c4e1def920333140b1575f9d7471 100644
--- a/src/main/java/net/minecraft/world/level/block/SculkSpreader.java
+++ b/src/main/java/net/minecraft/world/level/block/SculkSpreader.java
@@ -126,7 +126,7 @@ public class SculkSpreader {
int i = Math.min(list.size(), 32);
for (int j = 0; j < i; ++j) {
- this.addCursor((SculkSpreader.ChargeCursor) list.get(j));
+ this.addCursor((SculkSpreader.ChargeCursor) list.get(j), false); // Paper - don't fire event for block entity loading
}
}
@@ -146,16 +146,16 @@ public class SculkSpreader {
while (charge > 0) {
int j = Math.min(charge, 1000);
- this.addCursor(new SculkSpreader.ChargeCursor(pos, j));
+ this.addCursor(new SculkSpreader.ChargeCursor(pos, j), true); // Paper - allow firing event for other causes
charge -= j;
}
}
- private void addCursor(SculkSpreader.ChargeCursor cursor) {
+ private void addCursor(SculkSpreader.ChargeCursor cursor, boolean fireEvent) { // Paper - add boolean to conditionally fire SculkBloomEvent
if (this.cursors.size() < 32) {
// CraftBukkit start
- if (!this.isWorldGeneration()) { // CraftBukkit - SPIGOT-7475: Don't call event during world generation
+ if (!this.isWorldGeneration() && fireEvent) { // CraftBukkit - SPIGOT-7475: Don't call event during world generation // Paper - add boolean to conditionally fire SculkBloomEvent
CraftBlock bukkitBlock = CraftBlock.at(this.level, cursor.pos);
SculkBloomEvent event = new SculkBloomEvent(bukkitBlock, cursor.getCharge());
Bukkit.getPluginManager().callEvent(event);

View file

@ -0,0 +1,41 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Newwind <support@newwindserver.com>
Date: Thu, 22 Aug 2024 22:55:37 +0200
Subject: [PATCH] Remove set damage lootable item function from compasses
In VanillaChestLoot, compasses accidentally have a setdamage loot
function on them, but compasses don't take durability, resulting in a warning.
This patch simply removes attempting to add damage to the compass item.
diff --git a/src/main/java/net/minecraft/data/loot/packs/VanillaChestLoot.java b/src/main/java/net/minecraft/data/loot/packs/VanillaChestLoot.java
index 096899338640bb8a7052db06bf55e9fe33bf1cbe..cff6b265622701266349b6cf68eb874aa6fb6321 100644
--- a/src/main/java/net/minecraft/data/loot/packs/VanillaChestLoot.java
+++ b/src/main/java/net/minecraft/data/loot/packs/VanillaChestLoot.java
@@ -946,7 +946,6 @@ public record VanillaChestLoot(HolderLookup.Provider registries) implements Loot
.add(
LootItem.lootTableItem(Items.COMPASS)
.apply(SetItemCountFunction.setCount(ConstantValue.exactly(1.0F)))
- .apply(SetItemDamageFunction.setDamage(UniformGenerator.between(0.15F, 0.8F)))
.setWeight(1)
)
.add(LootItem.lootTableItem(Items.BUCKET).apply(SetItemCountFunction.setCount(UniformGenerator.between(1.0F, 2.0F))).setWeight(1))
diff --git a/src/main/resources/data/minecraft/loot_table/chests/trial_chambers/intersection_barrel.json b/src/main/resources/data/minecraft/loot_table/chests/trial_chambers/intersection_barrel.json
index b5f5415a9f8bbb9d59926dc6c09e4a12dce2e9b9..fea6273ab4fe2383101f351a13d127e615b81d71 100644
--- a/src/main/resources/data/minecraft/loot_table/chests/trial_chambers/intersection_barrel.json
+++ b/src/main/resources/data/minecraft/loot_table/chests/trial_chambers/intersection_barrel.json
@@ -70,15 +70,6 @@
"add": false,
"count": 1.0,
"function": "minecraft:set_count"
- },
- {
- "add": false,
- "damage": {
- "type": "minecraft:uniform",
- "max": 0.8,
- "min": 0.15
- },
- "function": "minecraft:set_damage"
}
],
"name": "minecraft:compass"

View file

@ -0,0 +1,39 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: okx-code <okx@okx.sh>
Date: Sat, 17 Aug 2024 13:02:45 +0100
Subject: [PATCH] Add enchantment seed update API
diff --git a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java
index b7300052f3c3d496ea41b681a2d5d5b554e67c63..50a735dd97daab4fb9579f922a4c63de60204f29 100644
--- a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java
+++ b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java
@@ -399,4 +399,10 @@ public class EnchantmentMenu extends AbstractContainerMenu {
return this.bukkitEntity;
}
// CraftBukkit end
+
+ // Paper start - add enchantment seed update API
+ public void setEnchantmentSeed(int seed) {
+ this.enchantmentSeed.set(seed);
+ }
+ // Paper end - add enchantment seed update API
}
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftEnchantmentView.java b/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftEnchantmentView.java
index 17f0ce8fcb6d44579d88cfcf01de40485b0037dc..abe709ab9002b30a996e46779843969c984c9be9 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftEnchantmentView.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftEnchantmentView.java
@@ -26,6 +26,13 @@ public class CraftEnchantmentView extends CraftInventoryView<EnchantmentMenu, En
return this.container.getEnchantmentSeed();
}
+ // Paper start - add enchantment seed update API
+ @Override
+ public void setEnchantmentSeed(int seed) {
+ this.container.setEnchantmentSeed(seed);
+ }
+ // Paper end - add enchantment seed update API
+
@NotNull
@Override
public EnchantmentOffer[] getOffers() {

View file

@ -0,0 +1,27 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Gegy <gegy.dev@gmail.com>
Date: Mon, 26 Aug 2024 19:45:07 +0200
Subject: [PATCH] Fix: synchronise sending chat to client with updating message
signature cache
In the case where multiple messages from different players are being processed in parallel, there was a potential race condition where the messages would be sent to the client in a different order than the message signature cache was updated. However, the cache relies on the fact that the client and server get the exact same updates in the same order. This race condition would cause the caches to become corrupted, and any future message received by the client would fail to validate.
This also applies to the last seen state of the server, which becomes inconsistent in the same way as the message signature cache and would cause any messages sent to be rejected by the server too.
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 1ab3f730301e8ac22702601a04ad8f1521585daa..1722f11ad070715077f5dcaff008b98f7ee104ab 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2663,8 +2663,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
return;
}
// CraftBukkit end
+ // Paper start - Ensure that client receives chat packets in the same order that we add into the message signature cache
+ synchronized (this.messageSignatureCache) {
this.send(new ClientboundPlayerChatPacket(message.link().sender(), message.link().index(), message.signature(), message.signedBody().pack(this.messageSignatureCache), message.unsignedContent(), message.filterMask(), params));
this.addPendingMessage(message);
+ }
+ // Paper end - Ensure that client receives chat packets in the same order that we add into the message signature cache
}
public void sendDisguisedChatMessage(Component message, ChatType.Bound params) {

View file

@ -0,0 +1,352 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tamion <70228790+notTamion@users.noreply.github.com>
Date: Mon, 19 Aug 2024 18:05:26 +0200
Subject: [PATCH] Fix InventoryOpenEvent cancellation
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index b0cec2132c21abac64420e0d9a23b5346dfd9ee4..c1870b953e22922762015cb8d7f71a2b7f004299 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -1942,6 +1942,10 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
} else if (factory instanceof ChestBlock.DoubleInventory) {
// SPIGOT-5355 - double chests too :(
((ChestBlock.DoubleInventory) factory).inventorylargechest.stopOpen(this);
+ // Paper start - Fix InventoryOpenEvent cancellation
+ } else if (!this.enderChestInventory.isActiveChest(null)) {
+ this.enderChestInventory.stopOpen(this);
+ // Paper end - Fix InventoryOpenEvent cancellation
}
return OptionalInt.empty();
}
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
index 5d189ba60d40f5c42b2dacc339594ed067418e95..504c996220b278c194c93e001a3b326d549868ec 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
@@ -572,8 +572,7 @@ public class ServerPlayerGameMode {
} else if (this.gameModeForPlayer == GameType.SPECTATOR) {
MenuProvider itileinventory = iblockdata.getMenuProvider(world, blockposition);
- if (itileinventory != null) {
- player.openMenu(itileinventory);
+ if (itileinventory != null && player.openMenu(itileinventory).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
return InteractionResult.CONSUME;
} else {
return InteractionResult.PASS;
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractChestBoat.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractChestBoat.java
index 8033abfd77bcc20326b992a9d81e2faa9582fb83..1f4cc08e84a23213bb9786ea09ad77caeec2d336 100644
--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractChestBoat.java
+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractChestBoat.java
@@ -125,10 +125,10 @@ public abstract class AbstractChestBoat extends AbstractBoat implements HasCusto
@Override
public void openCustomInventoryScreen(Player player) {
- player.openMenu(this);
+ // Paper - fix inventory open cancel - moved into below if
Level world = player.level();
- if (world instanceof ServerLevel worldserver) {
+ if (world instanceof ServerLevel worldserver && player.openMenu(this).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
this.gameEvent(GameEvent.CONTAINER_OPEN, player);
PiglinAi.angerNearbyPiglins(worldserver, player, true);
}
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java b/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java
index 35f90e06dcf30c2e6a2a63e81215283ffbb3ec05..5e7a5248852319471525019b3efcfdb730a9af46 100644
--- a/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java
+++ b/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java
@@ -95,7 +95,11 @@ public interface ContainerEntity extends Container, MenuProvider {
}
default InteractionResult interactWithContainerVehicle(Player player) {
- player.openMenu(this);
+ // Paper start - Fix InventoryOpenEvent cancellation
+ if (player.openMenu(this).isEmpty()) {
+ return InteractionResult.PASS;
+ }
+ // Paper end - Fix InventoryOpenEvent cancellation
return InteractionResult.SUCCESS;
}
diff --git a/src/main/java/net/minecraft/world/level/block/AnvilBlock.java b/src/main/java/net/minecraft/world/level/block/AnvilBlock.java
index f50135ddd1e3699b0e3390b316d82f3884bab719..50c907c962f936d2035bb7550750cdbd220b29c2 100644
--- a/src/main/java/net/minecraft/world/level/block/AnvilBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/AnvilBlock.java
@@ -62,8 +62,9 @@ public class AnvilBlock extends FallingBlock {
@Override
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) {
if (!world.isClientSide) {
- player.openMenu(state.getMenuProvider(world, pos));
+ if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INTERACT_WITH_ANVIL);
+ } // Paper - Fix InventoryOpenEvent cancellation
}
return InteractionResult.SUCCESS;
diff --git a/src/main/java/net/minecraft/world/level/block/BarrelBlock.java b/src/main/java/net/minecraft/world/level/block/BarrelBlock.java
index 85fbba41ca0b6aded476043d280c746a8f5bacb9..2338b94158e3b685dc1ea8394ff271d85b5f7a7e 100644
--- a/src/main/java/net/minecraft/world/level/block/BarrelBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/BarrelBlock.java
@@ -41,8 +41,7 @@ public class BarrelBlock extends BaseEntityBlock {
@Override
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) {
- if (world instanceof ServerLevel serverLevel && world.getBlockEntity(pos) instanceof BarrelBlockEntity barrelBlockEntity) {
- player.openMenu(barrelBlockEntity);
+ if (world instanceof ServerLevel serverLevel && world.getBlockEntity(pos) instanceof BarrelBlockEntity barrelBlockEntity && player.openMenu(barrelBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.OPEN_BARREL);
PiglinAi.angerNearbyPiglins(serverLevel, player, true);
}
diff --git a/src/main/java/net/minecraft/world/level/block/BeaconBlock.java b/src/main/java/net/minecraft/world/level/block/BeaconBlock.java
index 5e61dfa142dd108dd4b35de47c6ff424b1b28c02..debe8dbf1d5f3e58774903c5fcdcea672274ea61 100644
--- a/src/main/java/net/minecraft/world/level/block/BeaconBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/BeaconBlock.java
@@ -46,8 +46,7 @@ public class BeaconBlock extends BaseEntityBlock implements BeaconBeamBlock {
@Override
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) {
- if (!world.isClientSide && world.getBlockEntity(pos) instanceof BeaconBlockEntity beaconBlockEntity) {
- player.openMenu(beaconBlockEntity);
+ if (!world.isClientSide && world.getBlockEntity(pos) instanceof BeaconBlockEntity beaconBlockEntity && player.openMenu(beaconBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INTERACT_WITH_BEACON);
}
diff --git a/src/main/java/net/minecraft/world/level/block/BlastFurnaceBlock.java b/src/main/java/net/minecraft/world/level/block/BlastFurnaceBlock.java
index b491cc959d4ce65a7ba16b64a7e1a56e77d0052c..03fed46291ff2236da619c941f864b8c78408450 100644
--- a/src/main/java/net/minecraft/world/level/block/BlastFurnaceBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/BlastFurnaceBlock.java
@@ -45,8 +45,7 @@ public class BlastFurnaceBlock extends AbstractFurnaceBlock {
@Override
protected void openContainer(Level world, BlockPos pos, Player player) {
BlockEntity blockEntity = world.getBlockEntity(pos);
- if (blockEntity instanceof BlastFurnaceBlockEntity) {
- player.openMenu((MenuProvider)blockEntity);
+ if (blockEntity instanceof BlastFurnaceBlockEntity && player.openMenu((MenuProvider)blockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INTERACT_WITH_BLAST_FURNACE);
}
}
diff --git a/src/main/java/net/minecraft/world/level/block/BrewingStandBlock.java b/src/main/java/net/minecraft/world/level/block/BrewingStandBlock.java
index 4109e4965f65bdd81fa956f9e0882cb7877bd2aa..cbaa6fc04eb8d765e0dd8238f2b82eed196d13c7 100644
--- a/src/main/java/net/minecraft/world/level/block/BrewingStandBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/BrewingStandBlock.java
@@ -73,8 +73,7 @@ public class BrewingStandBlock extends BaseEntityBlock {
@Override
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) {
- if (!world.isClientSide && world.getBlockEntity(pos) instanceof BrewingStandBlockEntity brewingStandBlockEntity) {
- player.openMenu(brewingStandBlockEntity);
+ if (!world.isClientSide && world.getBlockEntity(pos) instanceof BrewingStandBlockEntity brewingStandBlockEntity && player.openMenu(brewingStandBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INTERACT_WITH_BREWINGSTAND);
}
diff --git a/src/main/java/net/minecraft/world/level/block/CartographyTableBlock.java b/src/main/java/net/minecraft/world/level/block/CartographyTableBlock.java
index 20feecb9c7f5537e00788a30969b002dceda605f..9e7066ec9fa5a0a852f6e38052887a47be98cb55 100644
--- a/src/main/java/net/minecraft/world/level/block/CartographyTableBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/CartographyTableBlock.java
@@ -32,8 +32,9 @@ public class CartographyTableBlock extends Block {
@Override
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) {
if (!world.isClientSide) {
- player.openMenu(state.getMenuProvider(world, pos));
+ if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INTERACT_WITH_CARTOGRAPHY_TABLE);
+ } // Paper - Fix InventoryOpenEvent cancellation
}
return InteractionResult.SUCCESS;
diff --git a/src/main/java/net/minecraft/world/level/block/ChestBlock.java b/src/main/java/net/minecraft/world/level/block/ChestBlock.java
index 590837cb242eda62dca3c937a26b8ba26c41850c..edef8fc62f8dba1b57214d8d7d805ff0d83f4114 100644
--- a/src/main/java/net/minecraft/world/level/block/ChestBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/ChestBlock.java
@@ -252,8 +252,7 @@ public class ChestBlock extends AbstractChestBlock<ChestBlockEntity> implements
if (world instanceof ServerLevel worldserver) {
MenuProvider itileinventory = this.getMenuProvider(state, world, pos);
- if (itileinventory != null) {
- player.openMenu(itileinventory);
+ if (itileinventory != null && player.openMenu(itileinventory).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(this.getOpenChestStat());
PiglinAi.angerNearbyPiglins(worldserver, player, true);
}
diff --git a/src/main/java/net/minecraft/world/level/block/CraftingTableBlock.java b/src/main/java/net/minecraft/world/level/block/CraftingTableBlock.java
index 673a92d383db463b5c4e2ac3a4ecbd7e97c15c6d..6a2123cd808fa79f3cdb1cb56632d29bfe99058d 100644
--- a/src/main/java/net/minecraft/world/level/block/CraftingTableBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/CraftingTableBlock.java
@@ -31,8 +31,9 @@ public class CraftingTableBlock extends Block {
@Override
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) {
if (!world.isClientSide) {
- player.openMenu(state.getMenuProvider(world, pos));
+ if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INTERACT_WITH_CRAFTING_TABLE);
+ } // Paper - Fix InventoryOpenEvent cancellation
}
return InteractionResult.SUCCESS;
diff --git a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java
index a02f24448b002824b068278fa427003008c0d0f1..0427d590912561cb4f0354715e4ac513e53b3eb3 100644
--- a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java
@@ -80,8 +80,9 @@ public class DispenserBlock extends BaseEntityBlock {
if (tileentity instanceof DispenserBlockEntity) {
DispenserBlockEntity tileentitydispenser = (DispenserBlockEntity) tileentity;
- player.openMenu(tileentitydispenser);
+ if (player.openMenu(tileentitydispenser).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(tileentitydispenser instanceof DropperBlockEntity ? Stats.INSPECT_DROPPER : Stats.INSPECT_DISPENSER);
+ } // Paper - Fix InventoryOpenEvent cancellation
}
}
diff --git a/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java b/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java
index ef0d469176ee74b6bb5f9e9cc508735145fda5b8..ebb9baca7a65173f7c9fdf9bf47a8db876719625 100644
--- a/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java
@@ -86,11 +86,13 @@ public class EnderChestBlock extends AbstractChestBlock<EnderChestBlockEntity> i
if (world.getBlockState(blockPos).isRedstoneConductor(world, blockPos)) { // Paper - diff on change; make sure that EnderChest#isBlocked uses the same logic
return InteractionResult.SUCCESS;
} else {
- if (world instanceof ServerLevel serverLevel) {
+ // Paper start - Fix InventoryOpenEvent cancellation - moved up;
+ if (world instanceof ServerLevel serverLevel && player.openMenu(
+ new SimpleMenuProvider((i, inventory, playerx) -> ChestMenu.threeRows(i, inventory, playerEnderChestContainer), CONTAINER_TITLE)
+ ).isPresent()) {
+ // Paper end - Fix InventoryOpenEvent cancellation - moved up;
playerEnderChestContainer.setActiveChest(enderChestBlockEntity);
- player.openMenu(
- new SimpleMenuProvider((i, inventory, playerx) -> ChestMenu.threeRows(i, inventory, playerEnderChestContainer), CONTAINER_TITLE)
- );
+ // Paper - Fix InventoryOpenEvent cancellation - moved up;
player.awardStat(Stats.OPEN_ENDERCHEST);
PiglinAi.angerNearbyPiglins(serverLevel, player, true);
}
diff --git a/src/main/java/net/minecraft/world/level/block/FurnaceBlock.java b/src/main/java/net/minecraft/world/level/block/FurnaceBlock.java
index 72a3002c291181e7d874a149a22b8004ee2a0b18..618b566f067d53f32351e13b692095ebf6402925 100644
--- a/src/main/java/net/minecraft/world/level/block/FurnaceBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/FurnaceBlock.java
@@ -45,8 +45,7 @@ public class FurnaceBlock extends AbstractFurnaceBlock {
@Override
protected void openContainer(Level world, BlockPos pos, Player player) {
BlockEntity blockEntity = world.getBlockEntity(pos);
- if (blockEntity instanceof FurnaceBlockEntity) {
- player.openMenu((MenuProvider)blockEntity);
+ if (blockEntity instanceof FurnaceBlockEntity && player.openMenu((MenuProvider)blockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INTERACT_WITH_FURNACE);
}
}
diff --git a/src/main/java/net/minecraft/world/level/block/GrindstoneBlock.java b/src/main/java/net/minecraft/world/level/block/GrindstoneBlock.java
index 15fb9e8f63d1db1125680aced7f9b477d4ebf43a..59c000612bbf7beb7208af48001d3b1e5111ebd4 100644
--- a/src/main/java/net/minecraft/world/level/block/GrindstoneBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/GrindstoneBlock.java
@@ -157,8 +157,9 @@ public class GrindstoneBlock extends FaceAttachedHorizontalDirectionalBlock {
@Override
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) {
if (!world.isClientSide) {
- player.openMenu(state.getMenuProvider(world, pos));
+ if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INTERACT_WITH_GRINDSTONE);
+ } // Paper - Fix InventoryOpenEvent cancellation
}
return InteractionResult.SUCCESS;
diff --git a/src/main/java/net/minecraft/world/level/block/HopperBlock.java b/src/main/java/net/minecraft/world/level/block/HopperBlock.java
index b61324fe162f32817b87e4adb80df57b9433259f..005a2a66a6e8a492acfa7ba91117884cda08562d 100644
--- a/src/main/java/net/minecraft/world/level/block/HopperBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/HopperBlock.java
@@ -125,8 +125,7 @@ public class HopperBlock extends BaseEntityBlock {
@Override
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) {
- if (!world.isClientSide && world.getBlockEntity(pos) instanceof HopperBlockEntity hopperBlockEntity) {
- player.openMenu(hopperBlockEntity);
+ if (!world.isClientSide && world.getBlockEntity(pos) instanceof HopperBlockEntity hopperBlockEntity && player.openMenu(hopperBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INSPECT_HOPPER);
}
diff --git a/src/main/java/net/minecraft/world/level/block/LecternBlock.java b/src/main/java/net/minecraft/world/level/block/LecternBlock.java
index 3537795720be76483579fc50715914974c97c9c4..ec6ff0b192ae2f1586095519ad2472e76b2b5589 100644
--- a/src/main/java/net/minecraft/world/level/block/LecternBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/LecternBlock.java
@@ -298,8 +298,7 @@ public class LecternBlock extends BaseEntityBlock {
private void openScreen(Level world, BlockPos pos, Player player) {
BlockEntity tileentity = world.getBlockEntity(pos);
- if (tileentity instanceof LecternBlockEntity) {
- player.openMenu((LecternBlockEntity) tileentity);
+ if (tileentity instanceof LecternBlockEntity && player.openMenu((LecternBlockEntity) tileentity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INTERACT_WITH_LECTERN);
}
diff --git a/src/main/java/net/minecraft/world/level/block/LoomBlock.java b/src/main/java/net/minecraft/world/level/block/LoomBlock.java
index 2806ca5b0e3c73a3704a514dba2038072947d9ae..1b57f8cf3f4f27f6a76fec82a542ec1c582470c9 100644
--- a/src/main/java/net/minecraft/world/level/block/LoomBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/LoomBlock.java
@@ -33,8 +33,9 @@ public class LoomBlock extends HorizontalDirectionalBlock {
@Override
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) {
if (!world.isClientSide) {
- player.openMenu(state.getMenuProvider(world, pos));
+ if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INTERACT_WITH_LOOM);
+ } // Paper - Fix InventoryOpenEvent cancellation
}
return InteractionResult.SUCCESS;
diff --git a/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java b/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java
index a0607cb6c6f74285363dfbd49033a8bde5ca6ae3..155c7240b1112729333e6968122568c707d8f66b 100644
--- a/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java
@@ -104,8 +104,8 @@ public class ShulkerBoxBlock extends BaseEntityBlock {
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) {
if (world instanceof ServerLevel serverLevel
&& world.getBlockEntity(pos) instanceof ShulkerBoxBlockEntity shulkerBoxBlockEntity
- && canOpen(state, world, pos, shulkerBoxBlockEntity)) {
- player.openMenu(shulkerBoxBlockEntity);
+ && canOpen(state, world, pos, shulkerBoxBlockEntity) // Paper - Fix InventoryOpenEvent cancellation - expand if for belows check
+ && player.openMenu(shulkerBoxBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.OPEN_SHULKER_BOX);
PiglinAi.angerNearbyPiglins(serverLevel, player, true);
}
diff --git a/src/main/java/net/minecraft/world/level/block/SmithingTableBlock.java b/src/main/java/net/minecraft/world/level/block/SmithingTableBlock.java
index 6b316b8829f542023c20293d664a2d0716fb6c4c..43dc3d2c419a8b4a76de49a1e625076741a98c73 100644
--- a/src/main/java/net/minecraft/world/level/block/SmithingTableBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/SmithingTableBlock.java
@@ -38,8 +38,9 @@ public class SmithingTableBlock extends CraftingTableBlock {
@Override
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) {
if (!world.isClientSide) {
- player.openMenu(state.getMenuProvider(world, pos));
+ if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INTERACT_WITH_SMITHING_TABLE);
+ } // Paper - Fix InventoryOpenEvent cancellation
}
return InteractionResult.SUCCESS;
diff --git a/src/main/java/net/minecraft/world/level/block/SmokerBlock.java b/src/main/java/net/minecraft/world/level/block/SmokerBlock.java
index b0929942ca06ee14d2ba4f2ec2ee93743ee6233e..83669dfbfec46d319aec82ea2beaa90c9f6b81c3 100644
--- a/src/main/java/net/minecraft/world/level/block/SmokerBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/SmokerBlock.java
@@ -44,8 +44,7 @@ public class SmokerBlock extends AbstractFurnaceBlock {
@Override
protected void openContainer(Level world, BlockPos pos, Player player) {
BlockEntity blockEntity = world.getBlockEntity(pos);
- if (blockEntity instanceof SmokerBlockEntity) {
- player.openMenu((MenuProvider)blockEntity);
+ if (blockEntity instanceof SmokerBlockEntity && player.openMenu((MenuProvider)blockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INTERACT_WITH_SMOKER);
}
}
diff --git a/src/main/java/net/minecraft/world/level/block/StonecutterBlock.java b/src/main/java/net/minecraft/world/level/block/StonecutterBlock.java
index 3a879d1a469a8f597bfba861d41abd75a5743ab8..e61644241f24b42bb4f702d3eef5b590b4d107c8 100644
--- a/src/main/java/net/minecraft/world/level/block/StonecutterBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/StonecutterBlock.java
@@ -48,8 +48,9 @@ public class StonecutterBlock extends Block {
@Override
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) {
if (!world.isClientSide) {
- player.openMenu(state.getMenuProvider(world, pos));
+ if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INTERACT_WITH_STONECUTTER);
+ } // Paper - Fix InventoryOpenEvent cancellation
}
return InteractionResult.SUCCESS;

View file

@ -0,0 +1,23 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nathan <nathanmaestas21@cnm.edu>
Date: Sat, 31 Aug 2024 18:09:55 -0600
Subject: [PATCH] Fire BlockExpEvent on grindstone use
diff --git a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java
index 3b303d41b9facfb2892ff8402ee0de4608db7318..5687f492fc76f699e2a388790ca5380d9b8c8d0a 100644
--- a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java
+++ b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java
@@ -98,7 +98,11 @@ public class GrindstoneMenu extends AbstractContainerMenu {
public void onTake(net.minecraft.world.entity.player.Player player, ItemStack stack) {
context.execute((world, blockposition) -> {
if (world instanceof ServerLevel) {
- ExperienceOrb.award((ServerLevel) world, Vec3.atCenterOf(blockposition), this.getExperienceAmount(world), org.bukkit.entity.ExperienceOrb.SpawnReason.GRINDSTONE, player); // Paper
+ // Paper start - Fire BlockExpEvent on grindstone use
+ org.bukkit.event.block.BlockExpEvent event = new org.bukkit.event.block.BlockExpEvent(org.bukkit.craftbukkit.block.CraftBlock.at(world, blockposition), this.getExperienceAmount(world));
+ event.callEvent();
+ ExperienceOrb.award((ServerLevel) world, Vec3.atCenterOf(blockposition), event.getExpToDrop(), org.bukkit.entity.ExperienceOrb.SpawnReason.GRINDSTONE, player);
+ // Paper end - Fire BlockExpEvent on grindstone use
}
world.levelEvent(1042, blockposition, 0);

View file

@ -0,0 +1,29 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Newwind <support@newwindserver.com>
Date: Mon, 26 Aug 2024 14:01:37 +0200
Subject: [PATCH] Check dead flag in isAlive()
If a plugin sets the health of a living entity above 0 after it has already died, the entity will be "revived".
It will behave the exact same as before, except with the internal "dead" flag set, resulting in 2 behavior changes,
A: it's completely invulnerable to all damage
B: it's unable to pickup items
isValid() for these bugged entities will return true, isDead() will return false, despite the dead flag.
This patch checks that the mob isn't dead before saying its alive.
Also, even if the plugin is responsibly checking !isDead() before modifying health, on very rare circumstances
I am currently unable to replicate, these "revived" entities can still appear
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index b4d1848858fae20f81c27b31bc0c280c6705f082..f57c830a7286eb8cab1061c8ddebe6abab1fcced 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -2147,7 +2147,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
@Override
public boolean isAlive() {
- return !this.isRemoved() && this.getHealth() > 0.0F;
+ return !this.isRemoved() && this.getHealth() > 0.0F && !this.dead; // Paper - Check this.dead
}
public boolean isLookingAtMe(LivingEntity entity, double d0, boolean flag, boolean visualShape, Predicate<LivingEntity> predicate, DoubleSupplier... entityYChecks) {