1020
This commit is contained in:
parent
7616ebccd8
commit
6a315742d9
21 changed files with 221 additions and 263 deletions
215
patches/server/1001-fix-horse-inventories.patch
Normal file
215
patches/server/1001-fix-horse-inventories.patch
Normal 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
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
23
patches/server/1003-Add-ItemType-getItemRarity.patch
Normal file
23
patches/server/1003-Add-ItemType-getItemRarity.patch
Normal 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
|
||||
}
|
64
patches/server/1004-Add-plugin-info-at-startup.patch
Normal file
64
patches/server/1004-Add-plugin-info-at-startup.patch
Normal 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...
|
|
@ -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);
|
65
patches/server/1006-Fix-PickupStatus-getting-reset.patch
Normal file
65
patches/server/1006-Fix-PickupStatus-getting-reset.patch
Normal 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
|
||||
}
|
|
@ -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) {
|
|
@ -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
|
||||
}
|
|
@ -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();
|
||||
});
|
21
patches/server/1010-Add-skipping-world-symlink-scan.patch
Normal file
21
patches/server/1010-Add-skipping-world-symlink-scan.patch
Normal 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);
|
47
patches/server/1011-Add-even-more-Enchantment-API.patch
Normal file
47
patches/server/1011-Add-even-more-Enchantment-API.patch
Normal 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());
|
161
patches/server/1012-Leashable-API.patch
Normal file
161
patches/server/1012-Leashable-API.patch
Normal 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
|
||||
}
|
54
patches/server/1013-Fix-CraftBukkit-drag-system.patch
Normal file
54
patches/server/1013-Fix-CraftBukkit-drag-system.patch
Normal 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);
|
|
@ -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);
|
|
@ -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"
|
39
patches/server/1016-Add-enchantment-seed-update-API.patch
Normal file
39
patches/server/1016-Add-enchantment-seed-update-API.patch
Normal 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() {
|
|
@ -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) {
|
352
patches/server/1018-Fix-InventoryOpenEvent-cancellation.patch
Normal file
352
patches/server/1018-Fix-InventoryOpenEvent-cancellation.patch
Normal 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;
|
|
@ -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);
|
29
patches/server/1020-Check-dead-flag-in-isAlive.patch
Normal file
29
patches/server/1020-Check-dead-flag-in-isAlive.patch
Normal 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) {
|
Loading…
Add table
Add a link
Reference in a new issue