955
This commit is contained in:
parent
e0a245d2ea
commit
11044315fd
32 changed files with 268 additions and 294 deletions
|
@ -1,75 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: booky10 <boooky10@gmail.com>
|
||||
Date: Mon, 3 Jul 2023 01:55:32 +0200
|
||||
Subject: [PATCH] Add hand to fish event for all player interactions
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
index a87fcd5b837e1c824cbd5587c3350986e2fd7acb..91497f5e6c07fcf1b05eca6846c51e1a15ed3bc0 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
@@ -475,7 +475,15 @@ public class FishingHook extends Projectile {
|
||||
@Override
|
||||
public void readAdditionalSaveData(CompoundTag nbt) {}
|
||||
|
||||
+ // Paper start - Add hand parameter to PlayerFishEvent
|
||||
+ @Deprecated
|
||||
+ @io.papermc.paper.annotation.DoNotUse
|
||||
public int retrieve(ItemStack usedItem) {
|
||||
+ return this.retrieve(net.minecraft.world.InteractionHand.MAIN_HAND, usedItem);
|
||||
+ }
|
||||
+
|
||||
+ public int retrieve(net.minecraft.world.InteractionHand hand, ItemStack usedItem) {
|
||||
+ // Paper end - Add hand parameter to PlayerFishEvent
|
||||
net.minecraft.world.entity.player.Player entityhuman = this.getPlayerOwner();
|
||||
|
||||
if (!this.level().isClientSide && entityhuman != null && !this.shouldStopFishing(entityhuman)) {
|
||||
@@ -483,7 +491,7 @@ public class FishingHook extends Projectile {
|
||||
|
||||
if (this.hookedIn != null) {
|
||||
// CraftBukkit start
|
||||
- PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), this.hookedIn.getBukkitEntity(), (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.CAUGHT_ENTITY);
|
||||
+ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), this.hookedIn.getBukkitEntity(), (FishHook) this.getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), PlayerFishEvent.State.CAUGHT_ENTITY); // Paper - Add hand parameter to PlayerFishEvent
|
||||
this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent);
|
||||
|
||||
if (playerFishEvent.isCancelled()) {
|
||||
@@ -512,7 +520,7 @@ public class FishingHook extends Projectile {
|
||||
}
|
||||
// Paper end
|
||||
// CraftBukkit start
|
||||
- PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), entityitem != null ? entityitem.getBukkitEntity() : null, (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.CAUGHT_FISH); // Paper - entityitem may be null
|
||||
+ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), entityitem != null ? entityitem.getBukkitEntity() : null, (FishHook) this.getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), PlayerFishEvent.State.CAUGHT_FISH); // Paper - entityitem may be null // Paper - Add hand parameter to PlayerFishEvent
|
||||
playerFishEvent.setExpToDrop(this.random.nextInt(6) + 1);
|
||||
this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent);
|
||||
|
||||
@@ -546,7 +554,7 @@ public class FishingHook extends Projectile {
|
||||
|
||||
if (this.onGround()) {
|
||||
// CraftBukkit start
|
||||
- PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.IN_GROUND);
|
||||
+ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), PlayerFishEvent.State.IN_GROUND); // Paper - Add hand parameter to PlayerFishEvent
|
||||
this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent);
|
||||
|
||||
if (playerFishEvent.isCancelled()) {
|
||||
@@ -557,7 +565,7 @@ public class FishingHook extends Projectile {
|
||||
}
|
||||
// CraftBukkit start
|
||||
if (i == 0) {
|
||||
- PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.REEL_IN);
|
||||
+ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), PlayerFishEvent.State.REEL_IN); // Paper - Add hand parameter to PlayerFishEvent
|
||||
this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent);
|
||||
if (playerFishEvent.isCancelled()) {
|
||||
return 0;
|
||||
diff --git a/src/main/java/net/minecraft/world/item/FishingRodItem.java b/src/main/java/net/minecraft/world/item/FishingRodItem.java
|
||||
index b9aca584c9765e995d1f8b9b2e45e5257fb6ab9d..95144f0ea5e99285c0a82b9d2e60766b785a236d 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/FishingRodItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/FishingRodItem.java
|
||||
@@ -29,7 +29,7 @@ public class FishingRodItem extends Item implements Vanishable {
|
||||
|
||||
if (user.fishing != null) {
|
||||
if (!world.isClientSide) {
|
||||
- i = user.fishing.retrieve(itemstack);
|
||||
+ i = user.fishing.retrieve(hand, itemstack); // Paper - Add hand parameter to PlayerFishEvent
|
||||
itemstack.hurtAndBreak(i, user, (entityhuman1) -> {
|
||||
entityhuman1.broadcastBreakEvent(hand);
|
||||
});
|
|
@ -1,118 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 15 Dec 2022 00:14:44 -0800
|
||||
Subject: [PATCH] Fix several issues with EntityBreedEvent
|
||||
|
||||
Upstream did not account for different hands when storing
|
||||
the breed item for later use in the event. Also they only
|
||||
stored a reference to the stack, not a copy so if the stack
|
||||
changed after love mode was started, the breed item in the event
|
||||
also changed. Also in several places, the breed item was stored after
|
||||
it was decreased by one to consume the item.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Animal.java b/src/main/java/net/minecraft/world/entity/animal/Animal.java
|
||||
index 907ed82fea71254d6624eda878e2668cd26422a7..081d1e38b7b1f286e138b0981aaa760e58761215 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Animal.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Animal.java
|
||||
@@ -152,8 +152,9 @@ public abstract class Animal extends AgeableMob {
|
||||
int i = this.getAge();
|
||||
|
||||
if (!this.level().isClientSide && i == 0 && this.canFallInLove()) {
|
||||
+ final ItemStack breedCopy = itemstack.copy(); // Paper - Fix EntityBreedEvent copying
|
||||
this.usePlayerItem(player, hand, itemstack);
|
||||
- this.setInLove(player);
|
||||
+ this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
@@ -182,10 +183,18 @@ public abstract class Animal extends AgeableMob {
|
||||
return this.inLove <= 0;
|
||||
}
|
||||
|
||||
+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - Fix EntityBreedEvent copying
|
||||
public void setInLove(@Nullable Player player) {
|
||||
+ // Paper start - Fix EntityBreedEvent copying
|
||||
+ this.setInLove(player, null);
|
||||
+ }
|
||||
+ public void setInLove(@Nullable Player player, @Nullable ItemStack breedItemCopy) {
|
||||
+ if (breedItemCopy != null) this.breedItem = breedItemCopy;
|
||||
+ // Paper end - Fix EntityBreedEvent copying
|
||||
// CraftBukkit start
|
||||
EntityEnterLoveModeEvent entityEnterLoveModeEvent = CraftEventFactory.callEntityEnterLoveModeEvent(player, this, 600);
|
||||
if (entityEnterLoveModeEvent.isCancelled()) {
|
||||
+ this.breedItem = null; // Paper - Fix EntityBreedEvent copying; clear if cancelled
|
||||
return;
|
||||
}
|
||||
this.inLove = entityEnterLoveModeEvent.getTicksInLove();
|
||||
@@ -193,7 +202,7 @@ public abstract class Animal extends AgeableMob {
|
||||
if (player != null) {
|
||||
this.loveCause = player.getUUID();
|
||||
}
|
||||
- this.breedItem = player.getInventory().getSelected(); // CraftBukkit
|
||||
+ // Paper - Fix EntityBreedEvent copying; set breed item in better place
|
||||
|
||||
this.level().broadcastEntityEvent(this, (byte) 18);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Panda.java b/src/main/java/net/minecraft/world/entity/animal/Panda.java
|
||||
index 0297e234f17c6157cfff79420b9eeaf4e0e2c3ab..d683c49fdf2d1e5b0f2620641f9c241e82f96825 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Panda.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Panda.java
|
||||
@@ -650,8 +650,9 @@ public class Panda extends Animal {
|
||||
this.usePlayerItem(player, hand, itemstack);
|
||||
this.ageUp((int) ((float) (-this.getAge() / 20) * 0.1F), true);
|
||||
} else if (!this.level().isClientSide && this.getAge() == 0 && this.canFallInLove()) {
|
||||
+ final ItemStack breedCopy = itemstack.copy(); // Paper - Fix EntityBreedEvent copying
|
||||
this.usePlayerItem(player, hand, itemstack);
|
||||
- this.setInLove(player);
|
||||
+ this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying
|
||||
} else {
|
||||
if (this.level().isClientSide || this.isSitting() || this.isInWater()) {
|
||||
return InteractionResult.PASS;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java
|
||||
index 7860331b640fe48d1f2357d9f8e2e40c682b3620..84ae19bf9bddd2b6ee4737577d8836d59be028c2 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java
|
||||
@@ -398,7 +398,7 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Saddl
|
||||
boolean flag1 = this.isTamed() && this.getAge() == 0 && this.canFallInLove();
|
||||
|
||||
if (flag1) {
|
||||
- this.setInLove(player);
|
||||
+ this.setInLove(player, item.copy()); // Paper - Fix EntityBreedEvent copying
|
||||
}
|
||||
|
||||
boolean flag2 = this.isBaby();
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
|
||||
index 94dd97662ba07689fbfa16ef5c7d99fe12ce83de..815eb15086976b8f9e03bf8182d9ed50aec14720 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
|
||||
@@ -513,7 +513,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener,
|
||||
b0 = 5;
|
||||
if (!this.level().isClientSide && this.isTamed() && this.getAge() == 0 && !this.isInLove()) {
|
||||
flag = true;
|
||||
- this.setInLove(player);
|
||||
+ this.setInLove(player, item.copy()); // Paper - Fix EntityBreedEvent copying
|
||||
}
|
||||
} else if (item.is(Items.GOLDEN_APPLE) || item.is(Items.ENCHANTED_GOLDEN_APPLE)) {
|
||||
f = 10.0F;
|
||||
@@ -521,7 +521,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener,
|
||||
b0 = 10;
|
||||
if (!this.level().isClientSide && this.isTamed() && this.getAge() == 0 && !this.isInLove()) {
|
||||
flag = true;
|
||||
- this.setInLove(player);
|
||||
+ this.setInLove(player, item.copy()); // Paper - Fix EntityBreedEvent copying
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java
|
||||
index 9b5b894d43f25566ab9c3698705e978ab823a0d2..6623674136b0f865d5b3d7a10d3bf05793b82f87 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java
|
||||
@@ -191,7 +191,7 @@ public class Llama extends AbstractChestedHorse implements VariantHolder<Llama.V
|
||||
f = 10.0F;
|
||||
if (this.isTamed() && this.getAge() == 0 && this.canFallInLove()) {
|
||||
flag = true;
|
||||
- this.setInLove(player);
|
||||
+ this.setInLove(player, item.copy()); // Paper - Fix EntityBreedEvent copying
|
||||
}
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: TonytheMacaroni <tonythemacaroni123@gmail.com>
|
||||
Date: Thu, 9 Nov 2023 20:34:44 -0500
|
||||
Subject: [PATCH] Add UUID attribute modifier API
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java b/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java
|
||||
index 52439f4b959c74027eb191a3af960c70beb978e8..a2c057d92ea34368c7efc538b6e5b15ef342c54e 100644
|
||||
--- a/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java
|
||||
+++ b/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java
|
||||
@@ -5,6 +5,7 @@ import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.attribute.AttributeModifier;
|
||||
import org.bukkit.craftbukkit.attribute.CraftAttributeInstance;
|
||||
|
||||
+import java.util.UUID;
|
||||
import java.util.Collection;
|
||||
|
||||
public class UnmodifiableAttributeInstance extends CraftAttributeInstance {
|
||||
@@ -18,6 +19,11 @@ public class UnmodifiableAttributeInstance extends CraftAttributeInstance {
|
||||
throw new UnsupportedOperationException("Cannot modify default attributes");
|
||||
}
|
||||
|
||||
+ @Override
|
||||
+ public void removeModifier(UUID uuid) {
|
||||
+ throw new UnsupportedOperationException("Cannot modify default attributes");
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public void addModifier(AttributeModifier modifier) {
|
||||
throw new UnsupportedOperationException("Cannot modify default attributes");
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java
|
||||
index e0faf9bf55f95ab21bd3452cee73196ae7ba8122..971d9a6a64d4d93950441e36aa41522c6b145ebb 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java
|
||||
@@ -44,6 +44,21 @@ public class CraftAttributeInstance implements AttributeInstance {
|
||||
return result;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public AttributeModifier getModifier(java.util.UUID uuid) {
|
||||
+ Preconditions.checkArgument(uuid != null, "UUID cannot be null");
|
||||
+ net.minecraft.world.entity.ai.attributes.AttributeModifier modifier = this.handle.getModifier(uuid);
|
||||
+ return modifier == null ? null : CraftAttributeInstance.convert(modifier);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void removeModifier(java.util.UUID uuid) {
|
||||
+ Preconditions.checkArgument(uuid != null, "UUID cannot be null");
|
||||
+ this.handle.removeModifier(uuid);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void addModifier(AttributeModifier modifier) {
|
||||
Preconditions.checkArgument(modifier != null, "modifier");
|
|
@ -1,28 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: booky10 <boooky10@gmail.com>
|
||||
Date: Sun, 12 Nov 2023 05:09:47 +0100
|
||||
Subject: [PATCH] Fix missing event call for entity teleport API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
index 6fcc7949351c5741908a0150498b811f57961899..76193067a21ff962cf2634b36d0ddf3eff8f85d7 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -256,6 +256,17 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
return false;
|
||||
}
|
||||
|
||||
+ // Paper start - fix teleport event not being called
|
||||
+ org.bukkit.event.entity.EntityTeleportEvent event = new org.bukkit.event.entity.EntityTeleportEvent(
|
||||
+ this, this.getLocation(), location);
|
||||
+ // cancelling the event is handled differently for players and entities,
|
||||
+ // entities just stop teleporting, players will still teleport to the "from" location of the event
|
||||
+ if (!event.callEvent() || event.getTo() == null) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ location = event.getTo();
|
||||
+ // Paper end
|
||||
+
|
||||
// If this entity is riding another entity, we must dismount before teleporting.
|
||||
if (dismount) this.entity.stopRiding(); // Paper - Teleport passenger API
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrPowerGamerBR <git@mrpowergamerbr.com>
|
||||
Date: Tue, 21 Nov 2023 12:16:39 -0300
|
||||
Subject: [PATCH] Lazily create LootContext for criterions
|
||||
|
||||
For each player on each tick, enter block triggers are invoked, and these create loot contexts that are promptly thrown away since the trigger doesn't pass the predicate
|
||||
|
||||
To avoid this, we now lazily create the LootContext if the criterion passes the predicate AND if any of the listener triggers require a loot context instance
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java b/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java
|
||||
index f43053ba082f9772b6ec02828fa2d6f387c32d26..35772110e9318df46a2729dbc0b5879b290011b7 100644
|
||||
--- a/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java
|
||||
+++ b/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java
|
||||
@@ -42,14 +42,14 @@ public abstract class SimpleCriterionTrigger<T extends SimpleCriterionTrigger.Si
|
||||
PlayerAdvancements playerAdvancements = player.getAdvancements();
|
||||
Set<CriterionTrigger.Listener<T>> set = (Set) playerAdvancements.criterionData.get(this); // Paper - fix AdvancementDataPlayer leak
|
||||
if (set != null && !set.isEmpty()) {
|
||||
- LootContext lootContext = EntityPredicate.createContext(player, player);
|
||||
+ LootContext lootContext = null; // EntityPredicate.createContext(player, player); // Paper - Perf: lazily create LootContext for criterions
|
||||
List<CriterionTrigger.Listener<T>> list = null;
|
||||
|
||||
for (CriterionTrigger.Listener<T> listener : set) {
|
||||
T simpleInstance = listener.trigger();
|
||||
if (predicate.test(simpleInstance)) {
|
||||
Optional<ContextAwarePredicate> optional = simpleInstance.player();
|
||||
- if (optional.isEmpty() || optional.get().matches(lootContext)) {
|
||||
+ if (optional.isEmpty() || optional.get().matches(lootContext = (lootContext == null ? EntityPredicate.createContext(player, player) : lootContext))) { // Paper - Perf: lazily create LootContext for criterions
|
||||
if (list == null) {
|
||||
list = Lists.newArrayList();
|
||||
}
|
|
@ -1,208 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 23 Nov 2023 10:33:25 -0800
|
||||
Subject: [PATCH] Don't fire sync events during worldgen
|
||||
|
||||
Fixes EntityPotionEffectEvent
|
||||
Fixes EntityPoseChangeEvent
|
||||
|
||||
Asynchronous chunk generation provides an opportunity for things
|
||||
to happen async that previously fired synchronous-only events. This
|
||||
patch is for mitigating those issues by various methods.
|
||||
|
||||
Also fixes correctly marking/clearing the entity generation flag.
|
||||
This patch sets the generation flag anytime an entity is created
|
||||
via StructureTemplate before loading from NBT to catch uses of
|
||||
the flag during the loading logic. This patch clears the generation
|
||||
flag from an entity when added to a ServerLevel for the situation
|
||||
where generation happened directly to a ServerLevel and the
|
||||
entity still has the flag set.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 8235dace0f4a1090dfbd403db34231ccafe5f30e..9816913ad729fd39c173364b92e5db06a733bc55 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -1220,6 +1220,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
// CraftBukkit start
|
||||
private boolean addEntity(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot
|
||||
+ entity.generation = false; // Paper - Don't fire sync event during generation; Reset flag if it was added during a ServerLevel generation process
|
||||
// Paper start - extra debug info
|
||||
if (entity.valid) {
|
||||
MinecraftServer.LOGGER.error("Attempted Double World add on {}", entity, new Throwable());
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index ad3cdb1a3ab07c48bf6b2662b93ddad5974db1a6..2848be4604e08d0d651d16e960cda9a4d0234d41 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -637,7 +637,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
|
||||
if (pose == this.getPose()) {
|
||||
return;
|
||||
}
|
||||
- this.level.getCraftServer().getPluginManager().callEvent(new EntityPoseChangeEvent(this.getBukkitEntity(), Pose.values()[pose.ordinal()]));
|
||||
+ // Paper start - Don't fire sync event during generation
|
||||
+ if (!this.generation) {
|
||||
+ this.level.getCraftServer().getPluginManager().callEvent(new EntityPoseChangeEvent(this.getBukkitEntity(), Pose.values()[pose.ordinal()]));
|
||||
+ }
|
||||
+ // Paper end - Don't fire sync event during generation
|
||||
// CraftBukkit end
|
||||
this.entityData.set(Entity.DATA_POSE, pose);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
|
||||
index 656c68b37bc25d6b77f295f9efe0a81dd20b69c1..8ba573bb4099ee5b27b61f333e72d794c48d5f29 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
|
||||
@@ -584,9 +584,15 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
|
||||
}
|
||||
|
||||
public static Optional<Entity> create(CompoundTag nbt, Level world) {
|
||||
+ // Paper start - Don't fire sync event during generation
|
||||
+ return create(nbt, world, false);
|
||||
+ }
|
||||
+ public static Optional<Entity> create(CompoundTag nbt, Level world, boolean generation) {
|
||||
+ // Paper end - Don't fire sync event during generation
|
||||
return Util.ifElse(EntityType.by(nbt).map((entitytypes) -> {
|
||||
return entitytypes.create(world);
|
||||
}), (entity) -> {
|
||||
+ if (generation) entity.generation = true; // Paper - Don't fire sync event during generation
|
||||
entity.load(nbt);
|
||||
}, () -> {
|
||||
EntityType.LOGGER.warn("Skipping Entity with id {}", nbt.getString("id"));
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 6b591f8b484be20418e8a6ca09aba84cda398a3d..a648cc01f2cdfac46fd2e760705cf85e534e926f 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -1142,6 +1142,11 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
}
|
||||
|
||||
public boolean addEffect(MobEffectInstance mobeffect, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause) {
|
||||
+ // Paper start - Don't fire sync event during generation
|
||||
+ return this.addEffect(mobeffect, entity, cause, true);
|
||||
+ }
|
||||
+ public boolean addEffect(MobEffectInstance mobeffect, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause, boolean fireEvent) {
|
||||
+ // Paper end - Don't fire sync event during generation
|
||||
// org.spigotmc.AsyncCatcher.catchOp("effect add"); // Spigot // Paper - move to API
|
||||
if (this.isTickingEffects) {
|
||||
this.effectsToProcess.add(new ProcessableEffect(mobeffect, cause));
|
||||
@@ -1161,10 +1166,13 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
override = new MobEffectInstance(mobeffect1).update(mobeffect);
|
||||
}
|
||||
|
||||
+ if (fireEvent) { // Paper - Don't fire sync event during generation
|
||||
EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent(this, mobeffect1, mobeffect, cause, override);
|
||||
+ override = event.isOverride(); // Paper - Don't fire sync event during generation
|
||||
if (event.isCancelled()) {
|
||||
return false;
|
||||
}
|
||||
+ } // Paper - Don't fire sync event during generation
|
||||
// CraftBukkit end
|
||||
|
||||
if (mobeffect1 == null) {
|
||||
@@ -1172,7 +1180,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
this.onEffectAdded(mobeffect, entity);
|
||||
flag = true;
|
||||
// CraftBukkit start
|
||||
- } else if (event.isOverride()) {
|
||||
+ } else if (override) { // Paper - Don't fire sync event during generation
|
||||
mobeffect1.update(mobeffect);
|
||||
this.onEffectUpdated(mobeffect1, true, entity);
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Spider.java b/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
index d90da2f9e4d6214577bc81bd6c70ba8593788898..ffa4f34d964fbcc53e2dfe11677832db21a6eb93 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
@@ -182,7 +182,7 @@ public class Spider extends Monster {
|
||||
MobEffect mobeffectlist = entityspider_groupdataspider.effect;
|
||||
|
||||
if (mobeffectlist != null) {
|
||||
- this.addEffect(new MobEffectInstance(mobeffectlist, -1), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.SPIDER_SPAWN); // CraftBukkit
|
||||
+ this.addEffect(new MobEffectInstance(mobeffectlist, -1), null, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.SPIDER_SPAWN, world instanceof net.minecraft.server.level.ServerLevel); // CraftBukkit // Paper - Don't fire sync event during generation; only if this is happening in a ServerLevel
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
|
||||
index ae8a42261337bf736d0cc1bbe18da2b773417ca4..471e8493622c89d44a82f42f135cb308c9e0fbfe 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
|
||||
@@ -518,7 +518,7 @@ public class StructureTemplate {
|
||||
private static Optional<Entity> createEntityIgnoreException(ServerLevelAccessor world, CompoundTag nbt) {
|
||||
// CraftBukkit start
|
||||
// try {
|
||||
- return EntityType.create(nbt, world.getLevel());
|
||||
+ return EntityType.create(nbt, world.getLevel(), true); // Paper - Don't fire sync event during generation
|
||||
// } catch (Exception exception) {
|
||||
// return Optional.empty();
|
||||
// }
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java b/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java
|
||||
index e37c2d82ed606cbfe00c152b08c3ab99ac751f69..7ed861cd67889e525ab4987c0afed245aca08833 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java
|
||||
@@ -93,15 +93,17 @@ public abstract class DelegatedGeneratorAccess implements WorldGenLevel {
|
||||
return this.handle.getLevel();
|
||||
}
|
||||
|
||||
- @Override
|
||||
- public void addFreshEntityWithPassengers(Entity arg0, CreatureSpawnEvent.SpawnReason arg1) {
|
||||
- this.handle.addFreshEntityWithPassengers(arg0, arg1);
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public void addFreshEntityWithPassengers(Entity entity) {
|
||||
- this.handle.addFreshEntityWithPassengers(entity);
|
||||
- }
|
||||
+ // Paper start - Don't fire sync event during generation; don't override these methods so all entities are run through addFreshEntity
|
||||
+ // @Override
|
||||
+ // public void addFreshEntityWithPassengers(Entity arg0, CreatureSpawnEvent.SpawnReason arg1) {
|
||||
+ // this.handle.addFreshEntityWithPassengers(arg0, arg1);
|
||||
+ // }
|
||||
+ //
|
||||
+ // @Override
|
||||
+ // public void addFreshEntityWithPassengers(Entity entity) {
|
||||
+ // this.handle.addFreshEntityWithPassengers(entity);
|
||||
+ // }
|
||||
+ // Paper end - Don't fire sync event during generation; don't override these methods
|
||||
|
||||
@Override
|
||||
public ServerLevel getMinecraftWorld() {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/TransformerGeneratorAccess.java b/src/main/java/org/bukkit/craftbukkit/util/TransformerGeneratorAccess.java
|
||||
index b4b297945fb601701aac845d09e88fb74b09c3fa..7482dfe64458320d44089c0778591694202e9f70 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/TransformerGeneratorAccess.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/TransformerGeneratorAccess.java
|
||||
@@ -39,21 +39,23 @@ public class TransformerGeneratorAccess extends DelegatedGeneratorAccess {
|
||||
return super.addFreshEntity(arg0, arg1);
|
||||
}
|
||||
|
||||
- @Override
|
||||
- public void addFreshEntityWithPassengers(Entity entity) {
|
||||
- if (this.structureTransformer != null && !this.structureTransformer.transformEntity(entity)) {
|
||||
- return;
|
||||
- }
|
||||
- super.addFreshEntityWithPassengers(entity);
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public void addFreshEntityWithPassengers(Entity arg0, SpawnReason arg1) {
|
||||
- if (this.structureTransformer != null && !this.structureTransformer.transformEntity(arg0)) {
|
||||
- return;
|
||||
- }
|
||||
- super.addFreshEntityWithPassengers(arg0, arg1);
|
||||
- }
|
||||
+ // Paper start - Don't fire sync event during generation; don't override these methods so all entities are run through addFreshEntity
|
||||
+ // @Override
|
||||
+ // public void addFreshEntityWithPassengers(Entity entity) {
|
||||
+ // if (this.structureTransformer != null && !this.structureTransformer.transformEntity(entity)) {
|
||||
+ // return;
|
||||
+ // }
|
||||
+ // super.addFreshEntityWithPassengers(entity);
|
||||
+ // }
|
||||
+ //
|
||||
+ // @Override
|
||||
+ // public void addFreshEntityWithPassengers(Entity arg0, SpawnReason arg1) {
|
||||
+ // if (this.structureTransformer != null && !this.structureTransformer.transformEntity(arg0)) {
|
||||
+ // return;
|
||||
+ // }
|
||||
+ // super.addFreshEntityWithPassengers(arg0, arg1);
|
||||
+ // }
|
||||
+ // Paper end - Don't fire sync event during generation; don't override these methods
|
||||
|
||||
public boolean setCraftBlock(BlockPos position, CraftBlockState craftBlockState, int i, int j) {
|
||||
if (this.structureTransformer != null) {
|
|
@ -1,23 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Mon, 27 Mar 2023 10:20:00 -0700
|
||||
Subject: [PATCH] Add Structure check API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index cdcab87bfe2e207ee1f4f8a111682efefbd96511..35cc9bc399386344c1acc6446262d278d57febd0 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -237,6 +237,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
};
|
||||
}
|
||||
// Paper end
|
||||
+ // Paper start - structure check API
|
||||
+ @Override
|
||||
+ public boolean hasStructureAt(final io.papermc.paper.math.Position position, final Structure structure) {
|
||||
+ return this.world.structureManager().getStructureWithPieceAt(io.papermc.paper.util.MCUtil.toBlockPos(position), net.minecraft.resources.ResourceKey.create(net.minecraft.core.registries.Registries.STRUCTURE, CraftNamespacedKey.toMinecraft(structure.getKey()))).isValid();
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
private static final Random rand = new Random();
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: hyper1423 <backup8822@gmail.com>
|
||||
Date: Sun, 3 Dec 2023 07:38:09 +0900
|
||||
Subject: [PATCH] Fix CraftMetaItem#getAttributeModifier duplication check
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
index 9137d6d56386111dfd072859df84e533580ee294..5cd0fbac267f9c69c5de4c200a95860f5c56d42e 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
@@ -1174,7 +1174,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
Preconditions.checkNotNull(modifier, "AttributeModifier cannot be null");
|
||||
this.checkAttributeList();
|
||||
for (Map.Entry<Attribute, AttributeModifier> entry : this.attributeModifiers.entries()) {
|
||||
- Preconditions.checkArgument(!entry.getValue().getUniqueId().equals(modifier.getUniqueId()), "Cannot register AttributeModifier. Modifier is already applied! %s", modifier);
|
||||
+ Preconditions.checkArgument(!(entry.getValue().getUniqueId().equals(modifier.getUniqueId()) && entry.getKey() == attribute), "Cannot register AttributeModifier. Modifier is already applied! %s", modifier); // Paper
|
||||
}
|
||||
return this.attributeModifiers.put(attribute, modifier);
|
||||
}
|
|
@ -1,243 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Tue, 22 Mar 2022 09:34:41 -0700
|
||||
Subject: [PATCH] Restore vanilla entity drops behavior
|
||||
|
||||
Instead of just tracking the itemstacks, this tracks with it, the
|
||||
action to take with that itemstack to apply the correct logic
|
||||
on dropping the item instead of generalizing it for all dropped
|
||||
items like CB does.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 2bb82dcffd8fdc25d658ec36a34f959b25217396..bd6c60ebfc76d19313bf01048268f8ce7e6603c5 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -891,22 +891,20 @@ public class ServerPlayer extends Player {
|
||||
if (this.isRemoved()) {
|
||||
return;
|
||||
}
|
||||
- java.util.List<org.bukkit.inventory.ItemStack> loot = new java.util.ArrayList<org.bukkit.inventory.ItemStack>(this.getInventory().getContainerSize());
|
||||
+ List<DefaultDrop> loot = new java.util.ArrayList<>(this.getInventory().getContainerSize()); // Paper - Restore vanilla drops behavior
|
||||
boolean keepInventory = this.level().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || this.isSpectator();
|
||||
|
||||
if (!keepInventory) {
|
||||
for (ItemStack item : this.getInventory().getContents()) {
|
||||
if (!item.isEmpty() && !EnchantmentHelper.hasVanishingCurse(item)) {
|
||||
- loot.add(CraftItemStack.asCraftMirror(item));
|
||||
+ loot.add(new DefaultDrop(item, stack -> this.drop(stack, true, false, false))); // Paper - Restore vanilla drops behavior; drop function taken from Inventory#dropAll (don't fire drop event)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.shouldDropLoot() && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Paper - fix player loottables running when mob loot gamerule is false
|
||||
// SPIGOT-5071: manually add player loot tables (SPIGOT-5195 - ignores keepInventory rule)
|
||||
this.dropFromLootTable(damageSource, this.lastHurtByPlayerTime > 0);
|
||||
- for (org.bukkit.inventory.ItemStack item : this.drops) {
|
||||
- loot.add(item);
|
||||
- }
|
||||
+ loot.addAll(this.drops); // Paper
|
||||
this.drops.clear(); // SPIGOT-5188: make sure to clear
|
||||
} // Paper - fix player loottables running when mob loot gamerule is false
|
||||
|
||||
@@ -2389,8 +2387,8 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public ItemEntity drop(ItemStack stack, boolean throwRandomly, boolean retainOwnership) {
|
||||
- ItemEntity entityitem = super.drop(stack, throwRandomly, retainOwnership);
|
||||
+ public ItemEntity drop(ItemStack stack, boolean throwRandomly, boolean retainOwnership, boolean callDropEvent) { // Paper - Restore vanilla drops behavior; override method with most params
|
||||
+ ItemEntity entityitem = super.drop(stack, throwRandomly, retainOwnership, callDropEvent); // Paper - Restore vanilla drops behavior; override method with most params
|
||||
|
||||
if (entityitem == null) {
|
||||
return null;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 2848be4604e08d0d651d16e960cda9a4d0234d41..5275e7a34f86830d43edcab3a0e94f8d8e9cfae5 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -2496,6 +2496,25 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
|
||||
|
||||
@Nullable
|
||||
public ItemEntity spawnAtLocation(ItemStack stack, float yOffset) {
|
||||
+ // Paper start - Restore vanilla drops behavior
|
||||
+ return this.spawnAtLocation(stack, yOffset, null);
|
||||
+ }
|
||||
+ public record DefaultDrop(Item item, org.bukkit.inventory.ItemStack stack, @Nullable java.util.function.Consumer<ItemStack> dropConsumer) {
|
||||
+ public DefaultDrop(final ItemStack stack, final java.util.function.Consumer<ItemStack> dropConsumer) {
|
||||
+ this(stack.getItem(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack), dropConsumer);
|
||||
+ }
|
||||
+
|
||||
+ public void runConsumer(final org.bukkit.World fallbackWorld, final Location fallbackLoc) {
|
||||
+ if (this.dropConsumer == null || org.bukkit.craftbukkit.inventory.CraftItemType.bukkitToMinecraft(this.stack.getType()) != this.item) {
|
||||
+ fallbackWorld.dropItem(fallbackLoc, this.stack);
|
||||
+ } else {
|
||||
+ this.dropConsumer.accept(org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(this.stack));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ @Nullable
|
||||
+ public ItemEntity spawnAtLocation(ItemStack stack, float yOffset, @Nullable java.util.function.Consumer<? super ItemEntity> delayedAddConsumer) {
|
||||
+ // Paper end - Restore vanilla drops behavior
|
||||
if (stack.isEmpty()) {
|
||||
return null;
|
||||
} else if (this.level().isClientSide) {
|
||||
@@ -2503,14 +2522,21 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
|
||||
} else {
|
||||
// CraftBukkit start - Capture drops for death event
|
||||
if (this instanceof net.minecraft.world.entity.LivingEntity && !((net.minecraft.world.entity.LivingEntity) this).forceDrops) {
|
||||
- ((net.minecraft.world.entity.LivingEntity) this).drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack)); // Paper - mirror so we can destroy it later
|
||||
+ // Paper start - Restore vanilla drops behavior
|
||||
+ ((net.minecraft.world.entity.LivingEntity) this).drops.add(new net.minecraft.world.entity.Entity.DefaultDrop(stack, itemStack -> {
|
||||
+ ItemEntity itemEntity = new ItemEntity(this.level, this.getX(), this.getY() + (double) yOffset, this.getZ(), itemStack); // stack is copied before consumer
|
||||
+ itemEntity.setDefaultPickUpDelay();
|
||||
+ this.level.addFreshEntity(itemEntity);
|
||||
+ if (delayedAddConsumer != null) delayedAddConsumer.accept(itemEntity);
|
||||
+ }));
|
||||
+ // Paper end - Restore vanilla drops behavior
|
||||
return null;
|
||||
}
|
||||
// CraftBukkit end
|
||||
ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY() + (double) yOffset, this.getZ(), stack.copy()); // Paper - copy so we can destroy original
|
||||
stack.setCount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe
|
||||
|
||||
- entityitem.setDefaultPickUpDelay();
|
||||
+ entityitem.setDefaultPickUpDelay(); // Paper - diff on change (in dropConsumer)
|
||||
// Paper start - Call EntityDropItemEvent
|
||||
return this.spawnAtLocation(entityitem);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index a648cc01f2cdfac46fd2e760705cf85e534e926f..d396201655fde7ff35cf2a342fa458e5ea3f80a8 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -255,7 +255,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
// CraftBukkit start
|
||||
public int expToDrop;
|
||||
public boolean forceDrops;
|
||||
- public ArrayList<org.bukkit.inventory.ItemStack> drops = new ArrayList<org.bukkit.inventory.ItemStack>();
|
||||
+ public ArrayList<DefaultDrop> drops = new ArrayList<>(); // Paper - Restore vanilla drops behavior
|
||||
public final org.bukkit.craftbukkit.attribute.CraftAttributeMap craftAttributes;
|
||||
public boolean collides = true;
|
||||
public Set<UUID> collidableExemptions = new HashSet<>();
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
||||
index 6c215470ad05d59f903cbeff15088a03b42c3f66..12440ee2dccc0a697fb403765f2e1b987ccc0283 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
||||
@@ -535,10 +535,10 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
|
||||
@Override
|
||||
protected void dropCustomDeathLoot(DamageSource source, int lootingMultiplier, boolean allowDrops) {
|
||||
super.dropCustomDeathLoot(source, lootingMultiplier, allowDrops);
|
||||
- ItemEntity entityitem = this.spawnAtLocation((ItemLike) Items.NETHER_STAR);
|
||||
+ ItemEntity entityitem = this.spawnAtLocation(new net.minecraft.world.item.ItemStack(Items.NETHER_STAR), 0, ItemEntity::setExtendedLifetime); // Paper - Restore vanilla drops behavior; spawnAtLocation returns null so modify the item entity with a consumer
|
||||
|
||||
if (entityitem != null) {
|
||||
- entityitem.setExtendedLifetime();
|
||||
+ entityitem.setExtendedLifetime(); // Paper - diff on change
|
||||
}
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
index f62b5976e307a69ca40d51ae76126005c801df0c..bbe299afd361a107e3936c8ea1a62067fcac9b7e 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -611,7 +611,7 @@ public class ArmorStand extends LivingEntity {
|
||||
itemstack.setHoverName(this.getCustomName());
|
||||
}
|
||||
|
||||
- this.drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); // CraftBukkit - add to drops
|
||||
+ this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior
|
||||
return this.brokenByAnything(damageSource); // Paper
|
||||
}
|
||||
|
||||
@@ -625,7 +625,7 @@ public class ArmorStand extends LivingEntity {
|
||||
for (i = 0; i < this.handItems.size(); ++i) {
|
||||
itemstack = (ItemStack) this.handItems.get(i);
|
||||
if (!itemstack.isEmpty()) {
|
||||
- this.drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)); // CraftBukkit - add to drops // Paper - mirror so we can destroy it later - though this call site was safe
|
||||
+ this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior; mirror so we can destroy it later - though this call site was safe & spawn drops correctly
|
||||
this.handItems.set(i, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
@@ -633,7 +633,7 @@ public class ArmorStand extends LivingEntity {
|
||||
for (i = 0; i < this.armorItems.size(); ++i) {
|
||||
itemstack = (ItemStack) this.armorItems.get(i);
|
||||
if (!itemstack.isEmpty()) {
|
||||
- this.drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)); // CraftBukkit - add to drops // Paper - mirror so we can destroy it later - though this call site was safe
|
||||
+ this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior; mirror so we can destroy it later - though this call site was safe & spawn drops correctly
|
||||
this.armorItems.set(i, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 53c3b2123d6fa78367aef53d6949e58170cb9fce..99292a908b36e3c75d51c6877c7a0c01d9671aa6 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -965,17 +965,23 @@ public class CraftEventFactory {
|
||||
}
|
||||
|
||||
public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim) {
|
||||
- return CraftEventFactory.callEntityDeathEvent(victim, new ArrayList<org.bukkit.inventory.ItemStack>(0));
|
||||
+ return CraftEventFactory.callEntityDeathEvent(victim, new ArrayList<>(0)); // Paper - Restore vanilla drops behavior
|
||||
}
|
||||
|
||||
- public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, List<org.bukkit.inventory.ItemStack> drops) {
|
||||
+ public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, List<Entity.DefaultDrop> drops) { // Paper - Restore vanilla drops behavior
|
||||
// Paper start
|
||||
return CraftEventFactory.callEntityDeathEvent(victim, drops, com.google.common.util.concurrent.Runnables.doNothing());
|
||||
}
|
||||
- public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, List<org.bukkit.inventory.ItemStack> drops, Runnable lootCheck) {
|
||||
+
|
||||
+ private static final java.util.function.Function<org.bukkit.inventory.ItemStack, Entity.DefaultDrop> FROM_FUNCTION = stack -> {
|
||||
+ if (stack == null) return null;
|
||||
+ return new Entity.DefaultDrop(CraftItemType.bukkitToMinecraft(stack.getType()), stack, null);
|
||||
+ };
|
||||
+
|
||||
+ public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, List<Entity.DefaultDrop> drops, Runnable lootCheck) { // Paper
|
||||
// Paper end
|
||||
CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity();
|
||||
- EntityDeathEvent event = new EntityDeathEvent(entity, drops, victim.getExpReward());
|
||||
+ EntityDeathEvent event = new EntityDeathEvent(entity, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward()); // Paper - Restore vanilla drops behavior
|
||||
populateFields(victim, event); // Paper - make cancellable
|
||||
CraftWorld world = (CraftWorld) entity.getWorld();
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
@@ -989,19 +995,23 @@ public class CraftEventFactory {
|
||||
victim.expToDrop = event.getDroppedExp();
|
||||
lootCheck.run(); // Paper - advancement triggers before destroying items
|
||||
|
||||
- for (org.bukkit.inventory.ItemStack stack : event.getDrops()) {
|
||||
+ // Paper start - Restore vanilla drops behavior
|
||||
+ for (Entity.DefaultDrop drop : drops) {
|
||||
+ if (drop == null) continue;
|
||||
+ final org.bukkit.inventory.ItemStack stack = drop.stack();
|
||||
+ // Paper end - Restore vanilla drops behavior
|
||||
if (stack == null || stack.getType() == Material.AIR || stack.getAmount() == 0) continue;
|
||||
|
||||
- world.dropItem(entity.getLocation(), stack); // Paper - note: dropItem already clones due to this being bukkit -> NMS
|
||||
+ drop.runConsumer(world, entity.getLocation()); // Paper - Restore vanilla drops behavior
|
||||
if (stack instanceof CraftItemStack) stack.setAmount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe, but don't nuke bukkit stacks of manually added items
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
- public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, List<org.bukkit.inventory.ItemStack> drops, net.kyori.adventure.text.Component deathMessage, boolean keepInventory) { // Paper - Adventure
|
||||
+ public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, List<Entity.DefaultDrop> drops, net.kyori.adventure.text.Component deathMessage, boolean keepInventory) { // Paper - Adventure & Restore vanilla drops behavior
|
||||
CraftPlayer entity = victim.getBukkitEntity();
|
||||
- PlayerDeathEvent event = new PlayerDeathEvent(entity, drops, victim.getExpReward(), 0, deathMessage);
|
||||
+ PlayerDeathEvent event = new PlayerDeathEvent(entity, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(), 0, deathMessage); // Paper - Restore vanilla drops behavior
|
||||
event.setKeepInventory(keepInventory);
|
||||
event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel
|
||||
populateFields(victim, event); // Paper - make cancellable
|
||||
@@ -1020,10 +1030,14 @@ public class CraftEventFactory {
|
||||
victim.expToDrop = event.getDroppedExp();
|
||||
victim.newExp = event.getNewExp();
|
||||
|
||||
- for (org.bukkit.inventory.ItemStack stack : event.getDrops()) {
|
||||
+ // Paper start - Restore vanilla drops behavior
|
||||
+ for (Entity.DefaultDrop drop : drops) {
|
||||
+ if (drop == null) continue;
|
||||
+ final org.bukkit.inventory.ItemStack stack = drop.stack();
|
||||
+ // Paper end - Restore vanilla drops behavior
|
||||
if (stack == null || stack.getType() == Material.AIR) continue;
|
||||
|
||||
- world.dropItem(entity.getLocation(), stack);
|
||||
+ drop.runConsumer(world, entity.getLocation()); // Paper - Restore vanilla drops behavior
|
||||
}
|
||||
|
||||
return event;
|
|
@ -1,171 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Tue, 27 Jun 2023 21:09:11 -0400
|
||||
Subject: [PATCH] Dont resend blocks on interactions
|
||||
|
||||
In general, the client now has an acknowledgment system which will prevent block changes made by the client to be reverted correctly.
|
||||
|
||||
It should be noted that this system does not yet support block entities, so those still need to resynced when needed.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
index d0ca98c3f9ea5c8cb1053da6b17e9a90c86b3ae7..5063eb6d4a24600262c32d2c9eb5fb5bf8fa354e 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
@@ -199,7 +199,7 @@ public class ServerPlayerGameMode {
|
||||
PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, pos, direction, this.player.getInventory().getSelected(), InteractionHand.MAIN_HAND);
|
||||
if (event.isCancelled()) {
|
||||
// Let the client know the block still exists
|
||||
- this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
|
||||
+ // this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos)); // Paper - Don't resync blocks
|
||||
// Update any tile entity data for this block
|
||||
capturedBlockEntity = true; // Paper - Send block entities after destroy prediction
|
||||
return;
|
||||
@@ -214,7 +214,7 @@ public class ServerPlayerGameMode {
|
||||
// Spigot start - handle debug stick left click for non-creative
|
||||
if (this.player.getMainHandItem().is(net.minecraft.world.item.Items.DEBUG_STICK)
|
||||
&& ((net.minecraft.world.item.DebugStickItem) net.minecraft.world.item.Items.DEBUG_STICK).handleInteraction(this.player, this.level.getBlockState(pos), this.level, pos, false, this.player.getMainHandItem())) {
|
||||
- this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
|
||||
+ // this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos)); // Paper - Don't resync block
|
||||
return;
|
||||
}
|
||||
// Spigot end
|
||||
@@ -232,15 +232,17 @@ public class ServerPlayerGameMode {
|
||||
// CraftBukkit start - Swings at air do *NOT* exist.
|
||||
if (event.useInteractedBlock() == Event.Result.DENY) {
|
||||
// If we denied a door from opening, we need to send a correcting update to the client, as it already opened the door.
|
||||
- BlockState data = this.level.getBlockState(pos);
|
||||
- if (data.getBlock() instanceof DoorBlock) {
|
||||
- // For some reason *BOTH* the bottom/top part have to be marked updated.
|
||||
- boolean bottom = data.getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER;
|
||||
- this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
|
||||
- this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, bottom ? pos.above() : pos.below()));
|
||||
- } else if (data.getBlock() instanceof TrapDoorBlock) {
|
||||
- this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
|
||||
- }
|
||||
+ // Paper start - Don't resync blocks
|
||||
+ //BlockState data = this.level.getBlockState(pos);
|
||||
+ //if (data.getBlock() instanceof DoorBlock) {
|
||||
+ // // For some reason *BOTH* the bottom/top part have to be marked updated.
|
||||
+ // boolean bottom = data.getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER;
|
||||
+ // this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
|
||||
+ // this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, bottom ? pos.above() : pos.below()));
|
||||
+ //} else if (data.getBlock() instanceof TrapDoorBlock) {
|
||||
+ // this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
|
||||
+ //}
|
||||
+ // Paper end - Don't resync blocks
|
||||
} else if (!iblockdata.isAir()) {
|
||||
iblockdata.attack(this.level, pos, this.player);
|
||||
f = iblockdata.getDestroyProgress(this.player, this.player.level(), pos);
|
||||
@@ -249,7 +251,7 @@ public class ServerPlayerGameMode {
|
||||
if (event.useItemInHand() == Event.Result.DENY) {
|
||||
// If we 'insta destroyed' then the client needs to be informed.
|
||||
if (f > 1.0f) {
|
||||
- this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
|
||||
+ // this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos)); // Paper - Don't resync blocks
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -257,7 +259,7 @@ public class ServerPlayerGameMode {
|
||||
|
||||
if (blockEvent.isCancelled()) {
|
||||
// Let the client know the block still exists
|
||||
- this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
|
||||
+ // this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos)); // Paper - Don't resync block
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -348,7 +350,7 @@ public class ServerPlayerGameMode {
|
||||
|
||||
// Tell client the block is gone immediately then process events
|
||||
// Don't tell the client if its a creative sword break because its not broken!
|
||||
- if (this.level.getBlockEntity(pos) == null && !isSwordNoBreak) {
|
||||
+ if (false && this.level.getBlockEntity(pos) == null && !isSwordNoBreak) { // Paper - Don't resync block
|
||||
ClientboundBlockUpdatePacket packet = new ClientboundBlockUpdatePacket(pos, Blocks.AIR.defaultBlockState());
|
||||
this.player.connection.send(packet);
|
||||
}
|
||||
@@ -374,13 +376,15 @@ public class ServerPlayerGameMode {
|
||||
if (isSwordNoBreak) {
|
||||
return false;
|
||||
}
|
||||
+ // Paper start - Don't resync blocks
|
||||
// Let the client know the block still exists
|
||||
- this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
|
||||
+ //this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
|
||||
|
||||
// Brute force all possible updates
|
||||
- for (Direction dir : Direction.values()) {
|
||||
- this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos.relative(dir)));
|
||||
- }
|
||||
+ //for (Direction dir : Direction.values()) {
|
||||
+ // this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos.relative(dir)));
|
||||
+ //}
|
||||
+ // Paper end - Don't resync blocks
|
||||
|
||||
// Update any tile entity data for this block
|
||||
if (!captureSentBlockEntities) { // Paper - Send block entities after destroy prediction
|
||||
@@ -537,16 +541,18 @@ public class ServerPlayerGameMode {
|
||||
if (event.useInteractedBlock() == Event.Result.DENY) {
|
||||
// If we denied a door from opening, we need to send a correcting update to the client, as it already opened the door.
|
||||
if (iblockdata.getBlock() instanceof DoorBlock) {
|
||||
- boolean bottom = iblockdata.getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER;
|
||||
- player.connection.send(new ClientboundBlockUpdatePacket(world, bottom ? blockposition.above() : blockposition.below()));
|
||||
+ // Paper start - Don't resync blocks
|
||||
+ // boolean bottom = iblockdata.getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER;
|
||||
+ // player.connection.send(new ClientboundBlockUpdatePacket(world, bottom ? blockposition.above() : blockposition.below()));
|
||||
+ // Paper end - Don't resync blocks
|
||||
} else if (iblockdata.getBlock() instanceof CakeBlock) {
|
||||
player.getBukkitEntity().sendHealthUpdate(); // SPIGOT-1341 - reset health for cake
|
||||
} else if (this.interactItemStack.getItem() instanceof DoubleHighBlockItem) {
|
||||
// send a correcting update to the client, as it already placed the upper half of the bisected item
|
||||
- player.connection.send(new ClientboundBlockUpdatePacket(world, blockposition.relative(hitResult.getDirection()).above()));
|
||||
+ //player.connection.send(new ClientboundBlockUpdatePacket(world, blockposition.relative(hitResult.getDirection()).above())); // Paper - Don't resync blocks
|
||||
|
||||
// send a correcting update to the client for the block above as well, this because of replaceable blocks (such as grass, sea grass etc)
|
||||
- player.connection.send(new ClientboundBlockUpdatePacket(world, blockposition.above()));
|
||||
+ //player.connection.send(new ClientboundBlockUpdatePacket(world, blockposition.above())); // Paper - Don't resync blocks
|
||||
// Paper start - extend Player Interact cancellation // TODO: consider merging this into the extracted method
|
||||
} else if (iblockdata.is(Blocks.STRUCTURE_BLOCK) || iblockdata.getBlock() instanceof net.minecraft.world.level.block.CommandBlock) {
|
||||
player.connection.send(new net.minecraft.network.protocol.game.ClientboundContainerClosePacket(this.player.containerMenu.containerId));
|
||||
diff --git a/src/main/java/net/minecraft/world/item/BucketItem.java b/src/main/java/net/minecraft/world/item/BucketItem.java
|
||||
index 4b9e726e6ac255e743479d5c2e0cdb98464399a4..6371f326fc86cfc53e39bf8ed13b646f7705fbbc 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/BucketItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/BucketItem.java
|
||||
@@ -77,7 +77,7 @@ public class BucketItem extends Item implements DispensibleContainerItem {
|
||||
PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) world, user, blockposition, blockposition, movingobjectpositionblock.getDirection(), itemstack, dummyFluid.getItem(), hand);
|
||||
|
||||
if (event.isCancelled()) {
|
||||
- ((ServerPlayer) user).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-5163 (see PlayerInteractManager)
|
||||
+ // ((ServerPlayer) user).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-5163 (see PlayerInteractManager) // Paper - Don't resend blocks
|
||||
((ServerPlayer) user).getBukkitEntity().updateInventory(); // SPIGOT-4541
|
||||
return InteractionResultHolder.fail(itemstack);
|
||||
}
|
||||
@@ -186,7 +186,7 @@ public class BucketItem extends Item implements DispensibleContainerItem {
|
||||
if (flag2 && entityhuman != null) {
|
||||
PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent((ServerLevel) world, entityhuman, blockposition, clicked, enumdirection, itemstack, enumhand);
|
||||
if (event.isCancelled()) {
|
||||
- ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-4238: needed when looking through entity
|
||||
+ // ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-4238: needed when looking through entity // Paper - Don't resend blocks
|
||||
((ServerPlayer) entityhuman).getBukkitEntity().updateInventory(); // SPIGOT-4541
|
||||
return false;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
index 9b4e20d4bfba2de08084f1d69cb2ebfff7455c14..06dc04a1fbb91a5a20d662aeee168b6a319551d0 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
@@ -458,10 +458,12 @@ public final class ItemStack {
|
||||
world.preventPoiUpdated = false;
|
||||
|
||||
// Brute force all possible updates
|
||||
- BlockPos placedPos = ((CraftBlock) placeEvent.getBlock()).getPosition();
|
||||
- for (Direction dir : Direction.values()) {
|
||||
- ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, placedPos.relative(dir)));
|
||||
- }
|
||||
+ // Paper start - Don't resync blocks
|
||||
+ // BlockPos placedPos = ((CraftBlock) placeEvent.getBlock()).getPosition();
|
||||
+ // for (Direction dir : Direction.values()) {
|
||||
+ // ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, placedPos.relative(dir)));
|
||||
+ // }
|
||||
+ // Paper end - Don't resync blocks
|
||||
SignItem.openSign = null; // SPIGOT-6758 - Reset on early return
|
||||
} else {
|
||||
// Change the stack to its new contents if it hasn't been tampered with.
|
|
@ -1,79 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sat, 16 Dec 2023 14:46:01 -0800
|
||||
Subject: [PATCH] add more scoreboard API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftObjective.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftObjective.java
|
||||
index b36e5574c10e6d70a399e2ac0704fd4f43dbb444..2d3abf2a1da487ead74d698cc5ea4eb729c35c8d 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftObjective.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftObjective.java
|
||||
@@ -185,6 +185,19 @@ final class CraftObjective extends CraftScoreboardComponent implements Objective
|
||||
final CraftObjective other = (CraftObjective) obj;
|
||||
return !(this.objective != other.objective && (this.objective == null || !this.objective.equals(other.objective)));
|
||||
}
|
||||
+ // Paper start - add more score API
|
||||
+ @Override
|
||||
+ public boolean willAutoUpdateDisplay() {
|
||||
+ this.checkState();
|
||||
+ return this.objective.displayAutoUpdate();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setAutoUpdateDisplay(final boolean autoUpdateDisplay) {
|
||||
+ this.checkState();
|
||||
+ this.objective.setDisplayAutoUpdate(autoUpdateDisplay);
|
||||
+ }
|
||||
+ // Paper end - add more score API
|
||||
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java
|
||||
index ceb1a39c02c3cfa7632a0fdca414c7046888fcb1..74d9c407e971804bed420370f7b684d8658eb5aa 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java
|
||||
@@ -74,4 +74,44 @@ final class CraftScore implements Score {
|
||||
board.resetSinglePlayerScore(entry, this.objective.getHandle());
|
||||
}
|
||||
// Paper end
|
||||
+
|
||||
+ // Paper start - add more score API
|
||||
+ @Override
|
||||
+ public boolean isTriggerable() {
|
||||
+ if (this.objective.getTrackedCriteria() != org.bukkit.scoreboard.Criteria.TRIGGER) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ final Scoreboard board = this.objective.checkState().board;
|
||||
+ final ReadOnlyScoreInfo scoreInfo = board.getPlayerScoreInfo(this.entry, this.objective.getHandle());
|
||||
+ return scoreInfo != null && !scoreInfo.isLocked();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setTriggerable(final boolean triggerable) {
|
||||
+ com.google.common.base.Preconditions.checkArgument(this.objective.getTrackedCriteria() == org.bukkit.scoreboard.Criteria.TRIGGER, "the criteria isn't 'trigger'");
|
||||
+ final Scoreboard board = this.objective.checkState().board;
|
||||
+ if (triggerable) {
|
||||
+ board.getOrCreatePlayerScore(this.entry, this.objective.getHandle()).unlock();
|
||||
+ } else {
|
||||
+ board.getOrCreatePlayerScore(this.entry, this.objective.getHandle()).lock();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public net.kyori.adventure.text.Component customName() {
|
||||
+ final Scoreboard board = this.objective.checkState().board;
|
||||
+ final ReadOnlyScoreInfo scoreInfo = board.getPlayerScoreInfo(this.entry, this.objective.getHandle());
|
||||
+ if (scoreInfo == null) {
|
||||
+ return null; // If score doesn't exist, don't create one
|
||||
+ }
|
||||
+ final net.minecraft.network.chat.Component display = board.getOrCreatePlayerScore(this.entry, this.objective.getHandle()).display();
|
||||
+ return display == null ? null : io.papermc.paper.adventure.PaperAdventure.asAdventure(display);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void customName(final net.kyori.adventure.text.Component customName) {
|
||||
+ final Scoreboard board = this.objective.checkState().board;
|
||||
+ board.getOrCreatePlayerScore(this.entry, this.objective.getHandle()).display(io.papermc.paper.adventure.PaperAdventure.asVanilla(customName));
|
||||
+ }
|
||||
+ // Paper end - add more score API
|
||||
}
|
|
@ -1,102 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Wed, 20 Dec 2023 02:03:05 -0800
|
||||
Subject: [PATCH] Improve Registry
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
|
||||
index b12b99253543445475b73a1d3d7c6364856b49e8..4fc02698a9312496e7f9bce1c64f317374d2a42f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
|
||||
@@ -131,6 +131,7 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
|
||||
|
||||
private final Class<? super B> bukkitClass;
|
||||
private final Map<NamespacedKey, B> cache = new HashMap<>();
|
||||
+ private final Map<B, NamespacedKey> byValue = new java.util.IdentityHashMap<>(); // Paper - improve Registry
|
||||
private final net.minecraft.core.Registry<M> minecraftRegistry;
|
||||
private final BiFunction<NamespacedKey, M, B> minecraftToBukkit;
|
||||
private boolean init;
|
||||
@@ -175,6 +176,7 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
|
||||
}
|
||||
|
||||
this.cache.put(namespacedKey, bukkit);
|
||||
+ this.byValue.put(bukkit, namespacedKey); // Paper - improve Registry
|
||||
|
||||
return bukkit;
|
||||
}
|
||||
@@ -197,4 +199,11 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
|
||||
|
||||
return this.minecraftToBukkit.apply(namespacedKey, minecraft);
|
||||
}
|
||||
+
|
||||
+ // Paper start - improve Registry
|
||||
+ @Override
|
||||
+ public NamespacedKey getKey(final B value) {
|
||||
+ return this.byValue.get(value);
|
||||
+ }
|
||||
+ // Paper end - improve Registry
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java b/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java
|
||||
index 147950b8a1c853e1b52fdb29b26e839c2dd7bd01..8a20186618de8de8dd941a12aeb7d4f3b7e70c18 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java
|
||||
@@ -35,6 +35,7 @@ public class CraftTrimMaterial implements TrimMaterial, Handleable<net.minecraft
|
||||
@Override
|
||||
@NotNull
|
||||
public NamespacedKey getKey() {
|
||||
+ if (true) return java.util.Objects.requireNonNull(org.bukkit.Registry.TRIM_MATERIAL.getKey(this), () -> this + " doesn't have a key"); // Paper
|
||||
return this.key;
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimPattern.java b/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimPattern.java
|
||||
index 88e9acd2084c5e7738017a91a454fc5407ab833b..dbb1619f8e8d98feb30f76beb8c23ebcd3ddca1f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimPattern.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimPattern.java
|
||||
@@ -35,6 +35,7 @@ public class CraftTrimPattern implements TrimPattern, Handleable<net.minecraft.w
|
||||
@Override
|
||||
@NotNull
|
||||
public NamespacedKey getKey() {
|
||||
+ if (true) return java.util.Objects.requireNonNull(org.bukkit.Registry.TRIM_PATTERN.getKey(this), () -> this + " doesn't have a key"); // Paper
|
||||
return this.key;
|
||||
}
|
||||
|
||||
diff --git a/src/test/java/org/bukkit/registry/PerRegistryTest.java b/src/test/java/org/bukkit/registry/PerRegistryTest.java
|
||||
index 1c4966520b6401e6571aa44d5934dfa280bc80e3..010de6fbb75eb5d51639695d260f916072fdb22d 100644
|
||||
--- a/src/test/java/org/bukkit/registry/PerRegistryTest.java
|
||||
+++ b/src/test/java/org/bukkit/registry/PerRegistryTest.java
|
||||
@@ -49,19 +49,22 @@ public class PerRegistryTest extends AbstractTestingBase {
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("data")
|
||||
- public void testGet(Registry<?> registry) {
|
||||
+ public <T extends Keyed> void testGet(Registry<T> registry) { // Paper - improve Registry
|
||||
registry.forEach(element -> {
|
||||
+ NamespacedKey key = registry.getKey(element); // Paper - improve Registry
|
||||
+ assertNotNull(key); // Paper - improve Registry
|
||||
// Values in the registry should be referentially equal to what is returned with #get()
|
||||
// This ensures that new instances are not created each time #get() is invoked
|
||||
- assertSame(element, registry.get(element.getKey()));
|
||||
+ assertSame(element, registry.get(key)); // Paper - improve Registry
|
||||
});
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("data")
|
||||
- public void testMatch(Registry<?> registry) {
|
||||
+ public <T extends Keyed> void testMatch(Registry<T> registry) { // Paper - improve Registry
|
||||
registry.forEach(element -> {
|
||||
- NamespacedKey key = element.getKey();
|
||||
+ NamespacedKey key = registry.getKey(element); // Paper - improve Registry
|
||||
+ assertNotNull(key); // Paper - improve Registry
|
||||
|
||||
this.assertSameMatchWithKeyMessage(registry, element, key.toString()); // namespace:key
|
||||
this.assertSameMatchWithKeyMessage(registry, element, key.getKey()); // key
|
||||
@@ -72,7 +75,7 @@ public class PerRegistryTest extends AbstractTestingBase {
|
||||
});
|
||||
}
|
||||
|
||||
- private void assertSameMatchWithKeyMessage(Registry<?> registry, Keyed element, String key) {
|
||||
+ private <T extends Keyed> void assertSameMatchWithKeyMessage(Registry<T> registry, T element, String key) { // Paper - improve Registry
|
||||
assertSame(element, registry.match(key), key);
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sat, 9 Dec 2023 19:15:59 -0800
|
||||
Subject: [PATCH] Fix NPE on null loc for EntityTeleportEvent
|
||||
|
||||
EntityTeleportEvent#setTo is marked as nullable and so is the
|
||||
getTo method. This fixes the handling of a null "to" location
|
||||
by treating it the same as the event being cancelled. This is
|
||||
already existing behavior for the EntityPortalEvent (which
|
||||
extends EntityTeleportEvent).
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/commands/TeleportCommand.java b/src/main/java/net/minecraft/server/commands/TeleportCommand.java
|
||||
index 3fec07b250a8f145e30c8c41888e47d2a3c902e1..2ddd033e1c3a2e5c8950b93c838491923803ccce 100644
|
||||
--- a/src/main/java/net/minecraft/server/commands/TeleportCommand.java
|
||||
+++ b/src/main/java/net/minecraft/server/commands/TeleportCommand.java
|
||||
@@ -169,9 +169,10 @@ public class TeleportCommand {
|
||||
Location to = new Location(world.getWorld(), x, y, z, f2, f3);
|
||||
EntityTeleportEvent event = new EntityTeleportEvent(target.getBukkitEntity(), target.getBukkitEntity().getLocation(), to);
|
||||
world.getCraftServer().getPluginManager().callEvent(event);
|
||||
- if (event.isCancelled()) {
|
||||
+ if (event.isCancelled() || event.getTo() == null) { // Paper
|
||||
return;
|
||||
}
|
||||
+ to = event.getTo(); // Paper - actually track new location
|
||||
|
||||
x = to.getX();
|
||||
y = to.getY();
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index d396201655fde7ff35cf2a342fa458e5ea3f80a8..bb52d084637c97d9cc1ebaeec28358a0ddb3952b 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -4201,7 +4201,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
if (!(this instanceof ServerPlayer)) {
|
||||
EntityTeleportEvent teleport = new EntityTeleportEvent(this.getBukkitEntity(), new Location(this.level().getWorld(), d3, d4, d5), new Location(this.level().getWorld(), d0, d6, d2));
|
||||
this.level().getCraftServer().getPluginManager().callEvent(teleport);
|
||||
- if (!teleport.isCancelled()) {
|
||||
+ if (!teleport.isCancelled() && teleport.getTo() != null) { // Paper
|
||||
Location to = teleport.getTo();
|
||||
this.teleportTo(to.getX(), to.getY(), to.getZ());
|
||||
} else {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/FollowOwnerGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/FollowOwnerGoal.java
|
||||
index 8e2f7e2385588224018f7f94ed9686415bc91deb..c0da573e3818a1dd2c1ef5a61c7cb34934b0a252 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/goal/FollowOwnerGoal.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/FollowOwnerGoal.java
|
||||
@@ -129,7 +129,7 @@ public class FollowOwnerGoal extends Goal {
|
||||
} else {
|
||||
// CraftBukkit start
|
||||
EntityTeleportEvent event = CraftEventFactory.callEntityTeleportEvent(this.tamable, (double) x + 0.5D, (double) y, (double) z + 0.5D);
|
||||
- if (event.isCancelled()) {
|
||||
+ if (event.isCancelled() || event.getTo() == null) { // Paper
|
||||
return false;
|
||||
}
|
||||
Location to = event.getTo();
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Shulker.java b/src/main/java/net/minecraft/world/entity/monster/Shulker.java
|
||||
index 06ab07fb5d8d0e2f97325890218a11fef551a0ba..b73dac8f68041f8a2e0752d70cc9d08b5cfd1cde 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Shulker.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Shulker.java
|
||||
@@ -408,7 +408,7 @@ public class Shulker extends AbstractGolem implements VariantHolder<Optional<Dye
|
||||
if (enumdirection != null) {
|
||||
// CraftBukkit start
|
||||
EntityTeleportEvent teleportEvent = CraftEventFactory.callEntityTeleportEvent(this, blockposition1.getX(), blockposition1.getY(), blockposition1.getZ());
|
||||
- if (teleportEvent.isCancelled()) {
|
||||
+ if (teleportEvent.isCancelled() || teleportEvent.getTo() == null) { // Paper
|
||||
return false;
|
||||
} else {
|
||||
blockposition1 = CraftLocation.toBlockPosition(teleportEvent.getTo());
|
|
@ -1,73 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Planz <lukas.planz@web.de>
|
||||
Date: Tue, 5 Sep 2023 20:34:20 +0200
|
||||
Subject: [PATCH] Add experience points API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
index e92cb12a04827c2afc0662a26320458527aa2bd4..020b74065f7489a46b70ac52e5abbdb22132f8d8 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -1834,7 +1834,7 @@ public abstract class Player extends LivingEntity {
|
||||
}
|
||||
|
||||
public int getXpNeededForNextLevel() {
|
||||
- return this.experienceLevel >= 30 ? 112 + (this.experienceLevel - 30) * 9 : (this.experienceLevel >= 15 ? 37 + (this.experienceLevel - 15) * 5 : 7 + this.experienceLevel * 2);
|
||||
+ return this.experienceLevel >= 30 ? 112 + (this.experienceLevel - 30) * 9 : (this.experienceLevel >= 15 ? 37 + (this.experienceLevel - 15) * 5 : 7 + this.experienceLevel * 2); // Paper - diff on change; calculateTotalExperiencePoints
|
||||
}
|
||||
// Paper start - send while respecting visibility
|
||||
private static void sendSoundEffect(Player fromEntity, double x, double y, double z, SoundEvent soundEffect, SoundSource soundCategory, float volume, float pitch) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 482b6bd9277277923528d8c9a3e9b49d3f5628bc..25450884fa763b27ceaf16dd1bb3e80c10cb40c3 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -1826,6 +1826,49 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
Preconditions.checkArgument(exp >= 0, "Total experience points must not be negative (%s)", exp);
|
||||
this.getHandle().totalExperience = exp;
|
||||
}
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int calculateTotalExperiencePoints() {
|
||||
+ return calculateTotalExperiencePoints(this.getLevel()) + Math.round(this.getExperiencePointsNeededForNextLevel() * getExp());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setExperienceLevelAndProgress(final int totalExperience) {
|
||||
+ Preconditions.checkArgument(totalExperience >= 0, "Total experience points must not be negative (%s)", totalExperience);
|
||||
+ int level = calculateLevelsForExperiencePoints(totalExperience);
|
||||
+ int remainingPoints = totalExperience - calculateTotalExperiencePoints(level);
|
||||
+
|
||||
+ this.getHandle().experienceLevel = level;
|
||||
+ this.getHandle().experienceProgress = (float) remainingPoints / this.getExperiencePointsNeededForNextLevel();
|
||||
+ this.getHandle().lastSentExp = -1;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getExperiencePointsNeededForNextLevel() {
|
||||
+ return this.getHandle().getXpNeededForNextLevel();
|
||||
+ }
|
||||
+
|
||||
+ // See https://minecraft.wiki/w/Experience#Leveling_up for reference
|
||||
+ private int calculateTotalExperiencePoints(int level) {
|
||||
+ if (level <= 16) {
|
||||
+ return (int) (Math.pow(level, 2) + 6 * level);
|
||||
+ } else if (level <= 31) {
|
||||
+ return (int) (2.5 * Math.pow(level, 2) - 40.5 * level + 360.0);
|
||||
+ } else {
|
||||
+ return (int) (4.5 * Math.pow(level, 2) - 162.5 * level + 2220.0);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private int calculateLevelsForExperiencePoints(int points) {
|
||||
+ if (points <= 352) { // Level 0-16
|
||||
+ return (int) Math.floor(Math.sqrt(points + 9) - 3);
|
||||
+ } else if (points <= 1507) { // Level 17-31
|
||||
+ return (int) Math.floor(8.1 + Math.sqrt(0.4 * (points - (7839.0 / 40.0))));
|
||||
+ } else { // 32+
|
||||
+ return (int) Math.floor((325.0 / 18.0) + Math.sqrt((2.0 / 9.0) * (points - (54215.0 / 72.0))));
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
@Override
|
||||
public void sendExperienceChange(float progress) {
|
|
@ -1,326 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Tue, 18 May 2021 12:32:02 -0700
|
||||
Subject: [PATCH] Add drops to shear events
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java
|
||||
index 45d356c1ed888b4d749379ceaa8a95d7d7c876d5..8d65cdb013706a932c2c73231108b2810b99e1c7 100644
|
||||
--- a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java
|
||||
+++ b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java
|
||||
@@ -103,11 +103,14 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior {
|
||||
|
||||
if (ishearable.readyForShearing()) {
|
||||
// CraftBukkit start
|
||||
- if (CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem).isCancelled()) {
|
||||
+ // Paper start - Add drops to shear events
|
||||
+ org.bukkit.event.block.BlockShearEntityEvent event = CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem, ishearable.generateDefaultDrops());
|
||||
+ if (event.isCancelled()) {
|
||||
+ // Paper end - Add drops to shear events
|
||||
continue;
|
||||
}
|
||||
// CraftBukkit end
|
||||
- ishearable.shear(SoundSource.BLOCKS);
|
||||
+ ishearable.shear(SoundSource.BLOCKS, CraftItemStack.asNMSCopy(event.getDrops())); // Paper - Add drops to shear events
|
||||
worldserver.gameEvent((Entity) null, GameEvent.SHEAR, blockposition);
|
||||
return true;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Shearable.java b/src/main/java/net/minecraft/world/entity/Shearable.java
|
||||
index 5e8cc5cfac8888628c6d513148f41be09ca65a2c..2ee48ac3b665db2b02bcb1a30ec972d43a3725b0 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Shearable.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Shearable.java
|
||||
@@ -3,7 +3,13 @@ package net.minecraft.world.entity;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
|
||||
public interface Shearable {
|
||||
+ default void shear(SoundSource soundCategory, java.util.List<net.minecraft.world.item.ItemStack> drops) { this.shear(soundCategory); } // Paper - Add drops to shear events
|
||||
void shear(SoundSource shearedSoundCategory);
|
||||
|
||||
boolean readyForShearing();
|
||||
+ // Paper start - custom shear drops; ensure all implementing entities override this
|
||||
+ default java.util.List<net.minecraft.world.item.ItemStack> generateDefaultDrops() {
|
||||
+ return java.util.Collections.emptyList();
|
||||
+ }
|
||||
+ // Paper end - custom shear drops
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java
|
||||
index 7243e4b95e98fda68d9e6adef0e41bebe825961a..161c128d27f50f145f88142191f1a5c93649ea65 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java
|
||||
@@ -123,11 +123,18 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder<Mushroo
|
||||
return InteractionResult.sidedSuccess(this.level().isClientSide);
|
||||
} else if (itemstack.is(Items.SHEARS) && this.readyForShearing()) {
|
||||
// CraftBukkit start
|
||||
- if (!CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) {
|
||||
- return InteractionResult.PASS;
|
||||
+ // Paper start - custom shear drops
|
||||
+ List<ItemStack> drops = this.generateDefaultDrops();
|
||||
+ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops);
|
||||
+ if (event != null) {
|
||||
+ if (event.isCancelled()) {
|
||||
+ return InteractionResult.PASS;
|
||||
+ }
|
||||
+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops());
|
||||
}
|
||||
+ // Paper end - custom shear drops
|
||||
// CraftBukkit end
|
||||
- this.shear(SoundSource.PLAYERS);
|
||||
+ this.shear(SoundSource.PLAYERS, drops); // Paper - custom shear drops
|
||||
this.gameEvent(GameEvent.SHEAR, player);
|
||||
if (!this.level().isClientSide) {
|
||||
itemstack.hurtAndBreak(1, player, (entityhuman1) -> {
|
||||
@@ -168,6 +175,22 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder<Mushroo
|
||||
|
||||
@Override
|
||||
public void shear(SoundSource shearedSoundCategory) {
|
||||
+ // Paper start - custom shear drops
|
||||
+ this.shear(shearedSoundCategory, this.generateDefaultDrops());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public List<ItemStack> generateDefaultDrops() {
|
||||
+ List<ItemStack> dropEntities = new java.util.ArrayList<>(5);
|
||||
+ for (int i = 0; i < 5; ++i) {
|
||||
+ dropEntities.add(new ItemStack(this.getVariant().getBlockState().getBlock()));
|
||||
+ }
|
||||
+ return dropEntities;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void shear(SoundSource shearedSoundCategory, List<ItemStack> drops) { // If drops is null, need to generate drops
|
||||
+ // Paper end - custom shear drops
|
||||
this.level().playSound((Player) null, (Entity) this, SoundEvents.MOOSHROOM_SHEAR, shearedSoundCategory, 1.0F, 1.0F);
|
||||
if (!this.level().isClientSide()) {
|
||||
Cow entitycow = (Cow) EntityType.COW.create(this.level());
|
||||
@@ -197,17 +220,12 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder<Mushroo
|
||||
this.discard(EntityRemoveEvent.Cause.TRANSFORMATION); // CraftBukkit - from above and add Bukkit remove cause
|
||||
// CraftBukkit end
|
||||
|
||||
- for (int i = 0; i < 5; ++i) {
|
||||
- // CraftBukkit start
|
||||
- ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(1.0D), this.getZ(), new ItemStack(this.getVariant().blockState.getBlock()));
|
||||
- EntityDropItemEvent event = new EntityDropItemEvent(this.getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity());
|
||||
- Bukkit.getPluginManager().callEvent(event);
|
||||
- if (event.isCancelled()) {
|
||||
- continue;
|
||||
- }
|
||||
- this.level().addFreshEntity(entityitem);
|
||||
- // CraftBukkit end
|
||||
+ // Paper start - custom shear drops; moved drop generation to separate method
|
||||
+ for (final ItemStack drop : drops) {
|
||||
+ ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(1.0D), this.getZ(), drop);
|
||||
+ this.spawnAtLocation(entityitem);
|
||||
}
|
||||
+ // Paper end - custom shear drops
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Sheep.java b/src/main/java/net/minecraft/world/entity/animal/Sheep.java
|
||||
index 55afa58f3df53ce548c7484d8fff62c903f9dc07..1d80678f7e8f658e43616f0baf723f096a99122a 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Sheep.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Sheep.java
|
||||
@@ -253,11 +253,18 @@ public class Sheep extends Animal implements Shearable {
|
||||
if (itemstack.is(Items.SHEARS)) {
|
||||
if (!this.level().isClientSide && this.readyForShearing()) {
|
||||
// CraftBukkit start
|
||||
- if (!CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) {
|
||||
- return InteractionResult.PASS;
|
||||
+ // Paper start - custom shear drops
|
||||
+ java.util.List<ItemStack> drops = this.generateDefaultDrops();
|
||||
+ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops);
|
||||
+ if (event != null) {
|
||||
+ if (event.isCancelled()) {
|
||||
+ return InteractionResult.PASS;
|
||||
+ }
|
||||
+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops());
|
||||
}
|
||||
+ // Paper end - custom shear drops
|
||||
// CraftBukkit end
|
||||
- this.shear(SoundSource.PLAYERS);
|
||||
+ this.shear(SoundSource.PLAYERS, drops); // Paper
|
||||
this.gameEvent(GameEvent.SHEAR, player);
|
||||
itemstack.hurtAndBreak(1, player, (entityhuman1) -> {
|
||||
entityhuman1.broadcastBreakEvent(hand);
|
||||
@@ -273,13 +280,30 @@ public class Sheep extends Animal implements Shearable {
|
||||
|
||||
@Override
|
||||
public void shear(SoundSource shearedSoundCategory) {
|
||||
+ // Paper start - custom shear drops
|
||||
+ this.shear(shearedSoundCategory, this.generateDefaultDrops());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public java.util.List<ItemStack> generateDefaultDrops() {
|
||||
+ int count = 1 + this.random.nextInt(3);
|
||||
+ java.util.List<ItemStack> dropEntities = new java.util.ArrayList<>(count);
|
||||
+ for (int j = 0; j < count; ++j) {
|
||||
+ dropEntities.add(new ItemStack(Sheep.ITEM_BY_DYE.get(this.getColor())));
|
||||
+ }
|
||||
+ return dropEntities;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void shear(SoundSource shearedSoundCategory, java.util.List<ItemStack> drops) {
|
||||
+ // Paper end - custom shear drops
|
||||
this.level().playSound((Player) null, (Entity) this, SoundEvents.SHEEP_SHEAR, shearedSoundCategory, 1.0F, 1.0F);
|
||||
this.setSheared(true);
|
||||
int i = 1 + this.random.nextInt(3);
|
||||
|
||||
- for (int j = 0; j < i; ++j) {
|
||||
+ for (final ItemStack drop : drops) { // Paper - custom shear drops (moved drop generation to separate method)
|
||||
this.forceDrops = true; // CraftBukkit
|
||||
- ItemEntity entityitem = this.spawnAtLocation((ItemLike) Sheep.ITEM_BY_DYE.get(this.getColor()), 1);
|
||||
+ ItemEntity entityitem = this.spawnAtLocation(drop, 1); // Paper - custom shear drops
|
||||
this.forceDrops = false; // CraftBukkit
|
||||
|
||||
if (entityitem != null) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
|
||||
index 54c01fdaf507a30196fb8f38888a570f9e393559..9eab1170cb123d3b60a02314702516704f959ab7 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
|
||||
@@ -153,11 +153,18 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
|
||||
|
||||
if (itemstack.is(Items.SHEARS) && this.readyForShearing()) {
|
||||
// CraftBukkit start
|
||||
- if (!CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) {
|
||||
- return InteractionResult.PASS;
|
||||
+ // Paper start - custom shear drops
|
||||
+ java.util.List<ItemStack> drops = this.generateDefaultDrops();
|
||||
+ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops);
|
||||
+ if (event != null) {
|
||||
+ if (event.isCancelled()) {
|
||||
+ return InteractionResult.PASS;
|
||||
+ }
|
||||
+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops());
|
||||
}
|
||||
+ // Paper end - custom shear drops
|
||||
// CraftBukkit end
|
||||
- this.shear(SoundSource.PLAYERS);
|
||||
+ this.shear(SoundSource.PLAYERS, drops); // Paper
|
||||
this.gameEvent(GameEvent.SHEAR, player);
|
||||
if (!this.level().isClientSide) {
|
||||
itemstack.hurtAndBreak(1, player, (entityhuman1) -> {
|
||||
@@ -173,12 +180,28 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
|
||||
|
||||
@Override
|
||||
public void shear(SoundSource shearedSoundCategory) {
|
||||
+ // Paper start - custom shear drops
|
||||
+ this.shear(shearedSoundCategory, this.generateDefaultDrops());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public java.util.List<ItemStack> generateDefaultDrops() {
|
||||
+ return java.util.Collections.singletonList(new ItemStack(Items.CARVED_PUMPKIN));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void shear(SoundSource shearedSoundCategory, java.util.List<ItemStack> drops) {
|
||||
+ // Paper end - custom shear drops
|
||||
this.level().playSound((Player) null, (Entity) this, SoundEvents.SNOW_GOLEM_SHEAR, shearedSoundCategory, 1.0F, 1.0F);
|
||||
if (!this.level().isClientSide()) {
|
||||
this.setPumpkin(false);
|
||||
- this.forceDrops = true; // CraftBukkit
|
||||
- this.spawnAtLocation(new ItemStack(Items.CARVED_PUMPKIN), 1.7F);
|
||||
- this.forceDrops = false; // CraftBukkit
|
||||
+ // Paper start - custom shear drops (moved drop generation to separate method)
|
||||
+ for (final ItemStack drop : drops) {
|
||||
+ this.forceDrops = true;
|
||||
+ this.spawnAtLocation(drop, 1.7F);
|
||||
+ this.forceDrops = false;
|
||||
+ }
|
||||
+ // Paper end - custom shear drops
|
||||
}
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 99292a908b36e3c75d51c6877c7a0c01d9671aa6..0a041d0e56dfe1319e5174cb0e6085dc35fa5c48 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -1674,20 +1674,20 @@ public class CraftEventFactory {
|
||||
player.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
- public static BlockShearEntityEvent callBlockShearEntityEvent(Entity animal, org.bukkit.block.Block dispenser, CraftItemStack is) {
|
||||
- BlockShearEntityEvent bse = new BlockShearEntityEvent(dispenser, animal.getBukkitEntity(), is);
|
||||
+ public static BlockShearEntityEvent callBlockShearEntityEvent(Entity animal, org.bukkit.block.Block dispenser, CraftItemStack is, List<ItemStack> drops) { // Paper - custom shear drops
|
||||
+ BlockShearEntityEvent bse = new BlockShearEntityEvent(dispenser, animal.getBukkitEntity(), is, Lists.transform(drops, CraftItemStack::asCraftMirror)); // Paper - custom shear drops
|
||||
Bukkit.getPluginManager().callEvent(bse);
|
||||
return bse;
|
||||
}
|
||||
|
||||
- public static boolean handlePlayerShearEntityEvent(net.minecraft.world.entity.player.Player player, Entity sheared, ItemStack shears, InteractionHand hand) {
|
||||
+ public static PlayerShearEntityEvent handlePlayerShearEntityEvent(net.minecraft.world.entity.player.Player player, Entity sheared, ItemStack shears, InteractionHand hand, List<ItemStack> drops) { // Paper - custom shear drops
|
||||
if (!(player instanceof ServerPlayer)) {
|
||||
- return true;
|
||||
+ return null; // Paper - custom shear drops
|
||||
}
|
||||
|
||||
- PlayerShearEntityEvent event = new PlayerShearEntityEvent((Player) player.getBukkitEntity(), sheared.getBukkitEntity(), CraftItemStack.asCraftMirror(shears), (hand == InteractionHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND));
|
||||
+ PlayerShearEntityEvent event = new PlayerShearEntityEvent((Player) player.getBukkitEntity(), sheared.getBukkitEntity(), CraftItemStack.asCraftMirror(shears), (hand == InteractionHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND), Lists.transform(drops, CraftItemStack::asCraftMirror)); // Paper - custom shear drops
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
- return !event.isCancelled();
|
||||
+ return event; // Paper - custom shear drops
|
||||
}
|
||||
|
||||
public static Cancellable handleStatisticsIncrease(net.minecraft.world.entity.player.Player entityHuman, net.minecraft.stats.Stat<?> statistic, int current, int newValue) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
index 38ceeca108c258852eeb7a48015010a689ac43ec..f67b048c3831fcab24acd12249cbd32d386c3ffe 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
@@ -66,6 +66,16 @@ public final class CraftItemStack extends ItemStack {
|
||||
return stack;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public static java.util.List<net.minecraft.world.item.ItemStack> asNMSCopy(java.util.List<? extends ItemStack> originals) {
|
||||
+ final java.util.List<net.minecraft.world.item.ItemStack> items = new java.util.ArrayList<>(originals.size());
|
||||
+ for (final ItemStack original : originals) {
|
||||
+ items.add(asNMSCopy(original));
|
||||
+ }
|
||||
+ return items;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public static net.minecraft.world.item.ItemStack copyNMSStack(net.minecraft.world.item.ItemStack original, int amount) {
|
||||
net.minecraft.world.item.ItemStack stack = original.copy();
|
||||
stack.setCount(amount);
|
||||
diff --git a/src/test/java/io/papermc/paper/entity/ShearableDropsTest.java b/src/test/java/io/papermc/paper/entity/ShearableDropsTest.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e612515f7709dbe5d1fa5751337cdc34fce10a98
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/io/papermc/paper/entity/ShearableDropsTest.java
|
||||
@@ -0,0 +1,34 @@
|
||||
+package io.papermc.paper.entity;
|
||||
+
|
||||
+import io.github.classgraph.ClassGraph;
|
||||
+import io.github.classgraph.ClassInfo;
|
||||
+import io.github.classgraph.MethodInfoList;
|
||||
+import io.github.classgraph.ScanResult;
|
||||
+import java.util.ArrayList;
|
||||
+import net.minecraft.world.entity.Shearable;
|
||||
+import org.bukkit.support.AbstractTestingBase;
|
||||
+import org.junit.jupiter.params.ParameterizedTest;
|
||||
+import org.junit.jupiter.params.provider.MethodSource;
|
||||
+
|
||||
+import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
+
|
||||
+class ShearableDropsTest extends AbstractTestingBase {
|
||||
+
|
||||
+ static Iterable<ClassInfo> parameters() {
|
||||
+ try (ScanResult scanResult = new ClassGraph()
|
||||
+ .enableClassInfo()
|
||||
+ .enableMethodInfo()
|
||||
+ .whitelistPackages("net.minecraft")
|
||||
+ .scan()
|
||||
+ ) {
|
||||
+ return new ArrayList<>(scanResult.getClassesImplementing(Shearable.class.getName()));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @ParameterizedTest
|
||||
+ @MethodSource("parameters")
|
||||
+ void checkShearableDropOverrides(final ClassInfo classInfo) {
|
||||
+ final MethodInfoList generateDefaultDrops = classInfo.getDeclaredMethodInfo("generateDefaultDrops");
|
||||
+ assertEquals(1, generateDefaultDrops.size(), classInfo.getName() + " doesn't implement Shearable#generateDefaultDrops");
|
||||
+ }
|
||||
+}
|
|
@ -1,80 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cryptite <cryptite@gmail.com>
|
||||
Date: Mon, 1 May 2023 16:22:43 -0500
|
||||
Subject: [PATCH] Add PlayerShieldDisableEvent
|
||||
|
||||
Called whenever a players shield is disabled. This is mainly caused by
|
||||
attacking players or monsters that carry axes.
|
||||
|
||||
The event, while similar to the PlayerItemCooldownEvent, offers other
|
||||
behaviour and can hence not be implemented as a childtype of said event.
|
||||
Specifically, cancelling the event prevents the game events from being
|
||||
sent to the player.
|
||||
|
||||
Plugins listening to just the PlayerItemCooldownEvent may not want said
|
||||
sideeffects, meaning the disable event cannot share a handlerlist with
|
||||
the cooldown event
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
index a59ee9d9b93404060e7a4702497071859daec6df..f7818fd5e59784554732c39ef5c56461ea0d62c4 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
@@ -1699,7 +1699,11 @@ public abstract class Mob extends LivingEntity implements Targeting {
|
||||
float f = 0.25F + (float) EnchantmentHelper.getBlockEfficiency(this) * 0.05F;
|
||||
|
||||
if (this.random.nextFloat() < f) {
|
||||
- player.getCooldowns().addCooldown(Items.SHIELD, 100);
|
||||
+ // Paper start - Add PlayerShieldDisableEvent
|
||||
+ final io.papermc.paper.event.player.PlayerShieldDisableEvent shieldDisableEvent = new io.papermc.paper.event.player.PlayerShieldDisableEvent((org.bukkit.entity.Player) player.getBukkitEntity(), getBukkitEntity(), 100);
|
||||
+ if (!shieldDisableEvent.callEvent()) return;
|
||||
+ player.getCooldowns().addCooldown(Items.SHIELD, shieldDisableEvent.getCooldown());
|
||||
+ // Paper end - Add PlayerShieldDisableEvent
|
||||
this.level().broadcastEntityEvent(player, (byte) 30);
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
index 020b74065f7489a46b70ac52e5abbdb22132f8d8..3e9c6e7e356ac08ec41736eaabf38714a8841d18 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -973,7 +973,7 @@ public abstract class Player extends LivingEntity {
|
||||
protected void blockUsingShield(LivingEntity attacker) {
|
||||
super.blockUsingShield(attacker);
|
||||
if (attacker.canDisableShield()) {
|
||||
- this.disableShield(true);
|
||||
+ this.disableShield(true, attacker); // Paper - Add PlayerShieldDisableEvent
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1456,7 +1456,14 @@ public abstract class Player extends LivingEntity {
|
||||
this.attack(target);
|
||||
}
|
||||
|
||||
+ @io.papermc.paper.annotation.DoNotUse @Deprecated // Paper - Add PlayerShieldDisableEvent
|
||||
public void disableShield(boolean sprinting) {
|
||||
+ // Paper start - Add PlayerShieldDisableEvent
|
||||
+ disableShield(sprinting, null);
|
||||
+ }
|
||||
+
|
||||
+ public void disableShield(boolean sprinting, @Nullable LivingEntity attacker) {
|
||||
+ // Paper end - Add PlayerShieldDisableEvent
|
||||
float f = 0.25F + (float) EnchantmentHelper.getBlockEfficiency(this) * 0.05F;
|
||||
|
||||
if (sprinting) {
|
||||
@@ -1464,7 +1471,16 @@ public abstract class Player extends LivingEntity {
|
||||
}
|
||||
|
||||
if (this.random.nextFloat() < f) {
|
||||
- this.getCooldowns().addCooldown(Items.SHIELD, 100);
|
||||
+ // Paper start - Add PlayerShieldDisableEvent
|
||||
+ final org.bukkit.entity.Entity finalAttacker = attacker != null ? attacker.getBukkitEntity() : null;
|
||||
+ if (finalAttacker != null) {
|
||||
+ final io.papermc.paper.event.player.PlayerShieldDisableEvent shieldDisableEvent = new io.papermc.paper.event.player.PlayerShieldDisableEvent((org.bukkit.entity.Player) getBukkitEntity(), finalAttacker, 100);
|
||||
+ if (!shieldDisableEvent.callEvent()) return;
|
||||
+ this.getCooldowns().addCooldown(Items.SHIELD, shieldDisableEvent.getCooldown());
|
||||
+ } else {
|
||||
+ this.getCooldowns().addCooldown(Items.SHIELD, 100);
|
||||
+ }
|
||||
+ // Paper end - Add PlayerShieldDisableEvent
|
||||
this.stopUsingItem();
|
||||
this.level().broadcastEntityEvent(this, (byte) 30);
|
||||
}
|
|
@ -1,143 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nassim Jahnke <nassim@njahnke.dev>
|
||||
Date: Thu, 4 Jan 2024 13:49:14 +0100
|
||||
Subject: [PATCH] Validate ResourceLocation in NBT reading
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/nbt/NbtUtils.java b/src/main/java/net/minecraft/nbt/NbtUtils.java
|
||||
index f3b11b08358fdd93464cd19b05047e10727a5799..c192ddee39afe1de0b5454bc94593b10fefbb24d 100644
|
||||
--- a/src/main/java/net/minecraft/nbt/NbtUtils.java
|
||||
+++ b/src/main/java/net/minecraft/nbt/NbtUtils.java
|
||||
@@ -222,8 +222,10 @@ public final class NbtUtils {
|
||||
if (!nbt.contains("Name", 8)) {
|
||||
return Blocks.AIR.defaultBlockState();
|
||||
} else {
|
||||
- ResourceLocation resourceLocation = new ResourceLocation(nbt.getString("Name"));
|
||||
- Optional<? extends Holder<Block>> optional = blockLookup.get(ResourceKey.create(Registries.BLOCK, resourceLocation));
|
||||
+ // Paper start - Validate resource location
|
||||
+ ResourceLocation resourceLocation = ResourceLocation.tryParse(nbt.getString("Name"));
|
||||
+ Optional<? extends Holder<Block>> optional = resourceLocation != null ? blockLookup.get(ResourceKey.create(Registries.BLOCK, resourceLocation)) : Optional.empty();
|
||||
+ // Paper end - Validate resource location
|
||||
if (optional.isEmpty()) {
|
||||
return Blocks.AIR.defaultBlockState();
|
||||
} else {
|
||||
diff --git a/src/main/java/net/minecraft/resources/ResourceLocation.java b/src/main/java/net/minecraft/resources/ResourceLocation.java
|
||||
index 3908f88959e43d2f485d5f239257e6564dbda6cd..b549f65d0e276a5ed5b8b2f6956268d05910724f 100644
|
||||
--- a/src/main/java/net/minecraft/resources/ResourceLocation.java
|
||||
+++ b/src/main/java/net/minecraft/resources/ResourceLocation.java
|
||||
@@ -33,6 +33,13 @@ public class ResourceLocation implements Comparable<ResourceLocation> {
|
||||
private final String path;
|
||||
|
||||
protected ResourceLocation(String namespace, String path, @Nullable ResourceLocation.Dummy extraData) {
|
||||
+ // Paper start - Validate ResourceLocation
|
||||
+ // Check for the max network string length (capped at Short.MAX_VALUE) as well as the max bytes of a StringTag (length written as an unsigned short)
|
||||
+ final String resourceLocation = namespace + ":" + path;
|
||||
+ if (resourceLocation.length() > Short.MAX_VALUE || io.netty.buffer.ByteBufUtil.utf8MaxBytes(resourceLocation) > 2 * Short.MAX_VALUE + 1) {
|
||||
+ throw new ResourceLocationException("Resource location too long: " + resourceLocation);
|
||||
+ }
|
||||
+ // Paper end - Validate ResourceLocation
|
||||
this.namespace = namespace;
|
||||
this.path = path;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
|
||||
index 8ba573bb4099ee5b27b61f333e72d794c48d5f29..69bdf3f2ee731e59e8d454816a9ca72cb49c0fe0 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
|
||||
@@ -614,7 +614,7 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
|
||||
}
|
||||
|
||||
public static Optional<EntityType<?>> by(CompoundTag nbt) {
|
||||
- return BuiltInRegistries.ENTITY_TYPE.getOptional(new ResourceLocation(nbt.getString("id")));
|
||||
+ return BuiltInRegistries.ENTITY_TYPE.getOptional(ResourceLocation.tryParse(nbt.getString("id"))); // Paper - Validate ResourceLocation
|
||||
}
|
||||
|
||||
@Nullable
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index bb52d084637c97d9cc1ebaeec28358a0ddb3952b..40e21effc948b02874a6ed1d1c340c4dc87579d6 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -879,12 +879,13 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
|
||||
if (nbt.contains("SleepingX", 99) && nbt.contains("SleepingY", 99) && nbt.contains("SleepingZ", 99)) {
|
||||
BlockPos blockposition = new BlockPos(nbt.getInt("SleepingX"), nbt.getInt("SleepingY"), nbt.getInt("SleepingZ"));
|
||||
-
|
||||
+ if (this.position().distanceToSqr(blockposition.getX(), blockposition.getY(), blockposition.getZ()) < 16 * 16) { // Paper - The sleeping pos will always also set the actual pos, so a desync suggests something is wrong
|
||||
this.setSleepingPos(blockposition);
|
||||
this.entityData.set(LivingEntity.DATA_POSE, Pose.SLEEPING);
|
||||
if (!this.firstTick) {
|
||||
this.setPosToBed(blockposition);
|
||||
}
|
||||
+ } // Paper - The sleeping pos will always also set the actual pos, so a desync suggests something is wrong
|
||||
}
|
||||
|
||||
if (nbt.contains("Brain", 10)) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
index f7818fd5e59784554732c39ef5c56461ea0d62c4..11c933a662c2275e2ef239cb0b5dd2480cc55490 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
@@ -608,7 +608,7 @@ public abstract class Mob extends LivingEntity implements Targeting {
|
||||
|
||||
this.setLeftHanded(nbt.getBoolean("LeftHanded"));
|
||||
if (nbt.contains("DeathLootTable", 8)) {
|
||||
- this.lootTable = new ResourceLocation(nbt.getString("DeathLootTable"));
|
||||
+ this.lootTable = ResourceLocation.tryParse(nbt.getString("DeathLootTable")); // Paper - Validate ResourceLocation
|
||||
this.lootTableSeed = nbt.getLong("DeathLootTableSeed");
|
||||
}
|
||||
|
||||
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 c30f19162e33dbe8f018b7dc66210681b6027389..e8faca6e443239968f0111519f9e5cd018ed3297 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
@@ -561,7 +561,7 @@ public abstract class AbstractArrow extends Projectile {
|
||||
this.setCritArrow(nbt.getBoolean("crit"));
|
||||
this.setPierceLevel(nbt.getByte("PierceLevel"));
|
||||
if (nbt.contains("SoundEvent", 8)) {
|
||||
- this.soundEvent = (SoundEvent) BuiltInRegistries.SOUND_EVENT.getOptional(new ResourceLocation(nbt.getString("SoundEvent"))).orElse(this.getDefaultHitGroundSoundEvent());
|
||||
+ this.soundEvent = (SoundEvent) BuiltInRegistries.SOUND_EVENT.getOptional(ResourceLocation.tryParse(nbt.getString("SoundEvent"))).orElse(this.getDefaultHitGroundSoundEvent()); // Paper - Validate resource location
|
||||
}
|
||||
|
||||
this.setShotFromCrossbow(nbt.getBoolean("ShotFromCrossbow"));
|
||||
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 f4ad1eea5bced6997edbc3a5ed1360b12b70f68f..648eefb973a4e5e543818c417a6ee39f283ea361 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java
|
||||
@@ -66,7 +66,7 @@ public interface ContainerEntity extends Container, MenuProvider {
|
||||
default void readChestVehicleSaveData(CompoundTag nbt) {
|
||||
this.clearItemStacks();
|
||||
if (nbt.contains("LootTable", 8)) {
|
||||
- this.setLootTable(new ResourceLocation(nbt.getString("LootTable")));
|
||||
+ this.setLootTable(ResourceLocation.tryParse(nbt.getString("LootTable"))); // Paper - Validate ResourceLocation
|
||||
this.setLootTableSeed(nbt.getLong("LootTableSeed"));
|
||||
}
|
||||
ContainerHelper.loadAllItems(nbt, this.getItemStacks()); // Paper - always load the items, table may still remain
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
index d04fc84eef11adb5ea64077f48794b6ed7fb3ada..89d06253b00604114e543ebbe12a9993ae95dc41 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
@@ -290,7 +290,12 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
||||
while (iterator.hasNext()) {
|
||||
String s = (String) iterator.next();
|
||||
|
||||
- this.recipesUsed.put(new ResourceLocation(s), nbttagcompound1.getInt(s));
|
||||
+ // Paper start - Validate ResourceLocation
|
||||
+ final ResourceLocation resourceLocation = ResourceLocation.tryParse(s);
|
||||
+ if (resourceLocation != null) {
|
||||
+ this.recipesUsed.put(resourceLocation, nbttagcompound1.getInt(s));
|
||||
+ }
|
||||
+ // Paper end - Validate ResourceLocation
|
||||
}
|
||||
|
||||
// Paper start - cook speed multiplier API
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BrushableBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BrushableBlockEntity.java
|
||||
index b5b1831631e233a96b6fd55972a8862b0f420da8..3f62e823bf9b5aa696e3c240613a0fb50340875e 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/BrushableBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/BrushableBlockEntity.java
|
||||
@@ -199,7 +199,7 @@ public class BrushableBlockEntity extends BlockEntity {
|
||||
|
||||
private boolean tryLoadLootTable(CompoundTag nbt) {
|
||||
if (nbt.contains("LootTable", 8)) {
|
||||
- this.lootTable = new ResourceLocation(nbt.getString("LootTable"));
|
||||
+ this.lootTable = ResourceLocation.tryParse(nbt.getString("LootTable")); // Paper - Validate ResourceLocation
|
||||
this.lootTableSeed = nbt.getLong("LootTableSeed");
|
||||
return true;
|
||||
} else {
|
|
@ -1,94 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Sat, 30 Dec 2023 15:00:06 -0500
|
||||
Subject: [PATCH] Properly handle experience dropping on block break
|
||||
|
||||
This causes spawnAfterBreak to spawn xp by default, removing the need to manually add xp wherever this method is used.
|
||||
For classes that use custom xp amounts, they can drop the resources with disabling
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index e881ed9de9d864e0522e1f7f97dc3debf57cf4b6..cedde2235227eb5820beefb98549994e1cca1198 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -625,7 +625,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
if (drop) {
|
||||
BlockEntity tileentity = iblockdata.hasBlockEntity() ? this.getBlockEntity(pos) : null;
|
||||
|
||||
- Block.dropResources(iblockdata, this, pos, tileentity, breakingEntity, ItemStack.EMPTY);
|
||||
+ Block.dropResources(iblockdata, this, pos, tileentity, breakingEntity, ItemStack.EMPTY, false); // Paper - Properly handle xp dropping
|
||||
+ iblockdata.getBlock().popExperience((ServerLevel) this, pos, xp, breakingEntity); // Paper - Properly handle xp dropping; custom amount
|
||||
}
|
||||
|
||||
boolean flag1 = this.setBlock(pos, fluid.createLegacyBlock(), 3, maxUpdateDepth);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
index c4bf01177b2dfcc88f6992dc85de216d448a79f8..6896d46fce2e466ebee23ac2dc00312ec1beefdb 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
@@ -321,23 +321,31 @@ public class Block extends BlockBehaviour implements ItemLike {
|
||||
for (ItemStack drop : Block.getDrops(state, serverLevel, pos, blockEntity)) {
|
||||
items.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(drop));
|
||||
}
|
||||
+ Block block = state.getBlock(); // Paper - Properly handle xp dropping
|
||||
io.papermc.paper.event.block.BlockBreakBlockEvent event = new io.papermc.paper.event.block.BlockBreakBlockEvent(org.bukkit.craftbukkit.block.CraftBlock.at(levelAccessor, pos), org.bukkit.craftbukkit.block.CraftBlock.at(levelAccessor, source), items);
|
||||
+ event.setExpToDrop(block.getExpDrop(state, serverLevel, pos, net.minecraft.world.item.ItemStack.EMPTY, true)); // Paper - Properly handle xp dropping
|
||||
event.callEvent();
|
||||
for (org.bukkit.inventory.ItemStack drop : event.getDrops()) {
|
||||
popResource(serverLevel, pos, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(drop));
|
||||
}
|
||||
- state.spawnAfterBreak(serverLevel, pos, ItemStack.EMPTY, true);
|
||||
+ state.spawnAfterBreak(serverLevel, pos, ItemStack.EMPTY, false); // Paper - Properly handle xp dropping
|
||||
+ block.popExperience(serverLevel, pos, event.getExpToDrop()); // Paper - Properly handle xp dropping
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// Paper end - Add BlockBreakBlockEvent
|
||||
|
||||
public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool) {
|
||||
+ // Paper start - Properly handle xp dropping
|
||||
+ dropResources(state, world, pos, blockEntity, entity, tool, true);
|
||||
+ }
|
||||
+ public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool, boolean dropExperience) {
|
||||
+ // Paper end - Properly handle xp dropping
|
||||
if (world instanceof ServerLevel) {
|
||||
Block.getDrops(state, (ServerLevel) world, pos, blockEntity, entity, tool).forEach((itemstack1) -> {
|
||||
Block.popResource(world, pos, itemstack1);
|
||||
});
|
||||
- state.spawnAfterBreak((ServerLevel) world, pos, tool, true);
|
||||
+ state.spawnAfterBreak((ServerLevel) world, pos, tool, dropExperience); // Paper - Properly handle xp dropping
|
||||
}
|
||||
|
||||
}
|
||||
@@ -421,7 +429,7 @@ public class Block extends BlockBehaviour implements ItemLike {
|
||||
player.awardStat(Stats.BLOCK_MINED.get(this));
|
||||
player.causeFoodExhaustion(0.005F, org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.BLOCK_MINED); // CraftBukkit - EntityExhaustionEvent
|
||||
if (includeDrops) { // Paper - fix drops not preventing stats/food exhaustion
|
||||
- Block.dropResources(state, world, pos, blockEntity, player, tool);
|
||||
+ Block.dropResources(state, world, pos, blockEntity, player, tool, dropExp); // Paper - Properly handle xp dropping
|
||||
} // Paper - fix drops not preventing stats/food exhaustion
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
index e57e3a26b0fb856e1ab693df5783fe8b9bee9719..64300077fce6eb28b6bddd42b3467eaa4c80c9f5 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
@@ -1183,6 +1183,7 @@ public abstract class BlockBehaviour implements FeatureElement {
|
||||
|
||||
public void spawnAfterBreak(ServerLevel world, BlockPos pos, ItemStack tool, boolean dropExperience) {
|
||||
this.getBlock().spawnAfterBreak(this.asState(), world, pos, tool, dropExperience);
|
||||
+ if (dropExperience) {getBlock().popExperience(world, pos, this.getBlock().getExpDrop(asState(), world, pos, tool, true));} // Paper - Properly handle xp dropping
|
||||
}
|
||||
|
||||
public List<ItemStack> getDrops(LootParams.Builder builder) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
index 461a66c323a74db5a70981fafc5fa20f54f0f40d..ac11f18690434922179b61ffcc3036dea025b0cb 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
@@ -509,7 +509,7 @@ public class CraftBlock implements Block {
|
||||
|
||||
// Modelled off EntityHuman#hasBlock
|
||||
if (block != Blocks.AIR && (item == null || !iblockdata.requiresCorrectToolForDrops() || nmsItem.isCorrectToolForDrops(iblockdata))) {
|
||||
- net.minecraft.world.level.block.Block.dropResources(iblockdata, this.world.getMinecraftWorld(), this.position, this.world.getBlockEntity(this.position), null, nmsItem);
|
||||
+ net.minecraft.world.level.block.Block.dropResources(iblockdata, this.world.getMinecraftWorld(), this.position, this.world.getBlockEntity(this.position), null, nmsItem, false); // Paper - Properly handle xp dropping
|
||||
// Paper start - improve Block#breanNaturally
|
||||
if (triggerEffect) {
|
||||
if (iblockdata.getBlock() instanceof net.minecraft.world.level.block.BaseFireBlock) {
|
|
@ -1,124 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nassim Jahnke <nassim@njahnke.dev>
|
||||
Date: Sat, 6 Jan 2024 14:31:00 +0100
|
||||
Subject: [PATCH] Fixup NamespacedKey handling
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperContainerEntityLootableInventory.java b/src/main/java/com/destroystokyo/paper/loottable/PaperContainerEntityLootableInventory.java
|
||||
index 9ca389ca789dc54bba3542cac0aac2e1dc66c870..15173e715fa36546820d930a46e0f0c493d07cfc 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/loottable/PaperContainerEntityLootableInventory.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperContainerEntityLootableInventory.java
|
||||
@@ -17,7 +17,7 @@ public class PaperContainerEntityLootableInventory implements PaperLootableEntit
|
||||
|
||||
@Override
|
||||
public org.bukkit.loot.LootTable getLootTable() {
|
||||
- return entity.getLootTable() != null ? Bukkit.getLootTable(CraftNamespacedKey.fromMinecraft(entity.getLootTable())) : null;
|
||||
+ return entity.getLootTable() != null && !entity.getLootTable().getPath().isEmpty() ? Bukkit.getLootTable(CraftNamespacedKey.fromMinecraft(entity.getLootTable())) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java b/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java
|
||||
index 9cfa5d36a6991067a3866e0d437749fafcc0158e..2ee4ee14ab3345486dad6b24fd9a4fcc6c746b99 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java
|
||||
@@ -15,7 +15,7 @@ public class PaperTileEntityLootableInventory implements PaperLootableBlockInven
|
||||
|
||||
@Override
|
||||
public org.bukkit.loot.LootTable getLootTable() {
|
||||
- return tileEntityLootable.lootTable != null ? Bukkit.getLootTable(CraftNamespacedKey.fromMinecraft(tileEntityLootable.lootTable)) : null;
|
||||
+ return tileEntityLootable.lootTable != null && !tileEntityLootable.lootTable.getPath().isEmpty() ? Bukkit.getLootTable(CraftNamespacedKey.fromMinecraft(tileEntityLootable.lootTable)) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttribute.java b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttribute.java
|
||||
index 8c9ce07f6a9c2799ce4d8b6a7d8eccd37cce6d43..f9e8c1f8416c4e5ae11e1d742cf3655faa480ce9 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttribute.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttribute.java
|
||||
@@ -24,7 +24,10 @@ public class CraftAttribute {
|
||||
public static Attribute stringToBukkit(String bukkit) {
|
||||
Preconditions.checkArgument(bukkit != null);
|
||||
|
||||
- return Registry.ATTRIBUTE.get(NamespacedKey.fromString(bukkit));
|
||||
+ // Paper start - Fixup NamespacedKey handling
|
||||
+ final NamespacedKey key = NamespacedKey.fromString(bukkit);
|
||||
+ return key != null ? Registry.ATTRIBUTE.get(key) : null;
|
||||
+ // Paper end - Fixup NamespacedKey handling
|
||||
}
|
||||
|
||||
public static net.minecraft.world.entity.ai.attributes.Attribute bukkitToMinecraft(Attribute bukkit) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java
|
||||
index 24b87a1566b48be1367970a9ba887a6b3a785bb9..9f2626c8c5cb8e713f7263b73d6a31d39f024f31 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java
|
||||
@@ -67,14 +67,22 @@ public class CraftMetaArmor extends CraftMetaItem implements ArmorMeta {
|
||||
if (tag.contains(CraftMetaArmor.TRIM.NBT)) {
|
||||
CompoundTag trimCompound = tag.getCompound(CraftMetaArmor.TRIM.NBT);
|
||||
|
||||
- if (trimCompound.contains(CraftMetaArmor.TRIM_MATERIAL.NBT) && trimCompound.contains(CraftMetaArmor.TRIM_PATTERN.NBT)) {
|
||||
- TrimMaterial trimMaterial = Registry.TRIM_MATERIAL.get(NamespacedKey.fromString(trimCompound.getString(CraftMetaArmor.TRIM_MATERIAL.NBT)));
|
||||
- TrimPattern trimPattern = Registry.TRIM_PATTERN.get(NamespacedKey.fromString(trimCompound.getString(CraftMetaArmor.TRIM_PATTERN.NBT)));
|
||||
+ // Paper start - Fixup NamedspacedKey handling
|
||||
+ if (trimCompound.contains(CraftMetaArmor.TRIM_MATERIAL.NBT, net.minecraft.nbt.Tag.TAG_STRING) && trimCompound.contains(CraftMetaArmor.TRIM_PATTERN.NBT, net.minecraft.nbt.Tag.TAG_STRING)) { // TODO Can also be inlined in a compound tag
|
||||
+ TrimMaterial trimMaterial = registryEntry(Registry.TRIM_MATERIAL, trimCompound.getString(TRIM_MATERIAL.NBT));
|
||||
+ TrimPattern trimPattern = registryEntry(Registry.TRIM_PATTERN, trimCompound.getString(TRIM_PATTERN.NBT));
|
||||
|
||||
- this.trim = new ArmorTrim(trimMaterial, trimPattern);
|
||||
+ this.trim = trimMaterial != null && trimPattern != null ? new ArmorTrim(trimMaterial, trimPattern) : null;
|
||||
+ // Paper end - Fixup NamedspacedKey handling
|
||||
}
|
||||
}
|
||||
}
|
||||
+ // Paper start - Fixup NamedspacedKey handling
|
||||
+ private <T extends org.bukkit.Keyed> T registryEntry(final Registry<T> registry, final String value) {
|
||||
+ final NamespacedKey key = NamespacedKey.fromString(value);
|
||||
+ return key != null ? registry.get(key) : null;
|
||||
+ }
|
||||
+ // Paper end - Fixup NamedspacedKey handling
|
||||
|
||||
CraftMetaArmor(Map<String, Object> map) {
|
||||
super(map);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMusicInstrument.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMusicInstrument.java
|
||||
index fad6295e75179edfc4e88d15c21b0b09f9156692..63e3c5c3f5aff273498d25db0fc9feb76ab27c2f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMusicInstrument.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMusicInstrument.java
|
||||
@@ -30,7 +30,10 @@ public class CraftMetaMusicInstrument extends CraftMetaItem implements MusicInst
|
||||
|
||||
if (tag.contains(CraftMetaMusicInstrument.GOAT_HORN_INSTRUMENT.NBT)) {
|
||||
String string = tag.getString(CraftMetaMusicInstrument.GOAT_HORN_INSTRUMENT.NBT);
|
||||
- this.instrument = Registry.INSTRUMENT.get(NamespacedKey.fromString(string));
|
||||
+ // Paper start - Fixup NamespacedKey handling
|
||||
+ final NamespacedKey key = NamespacedKey.fromString(string);
|
||||
+ this.instrument = key != null ? Registry.INSTRUMENT.get(key) : null;
|
||||
+ // Paper end - Fixup NamespacedKey handling
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionType.java b/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionType.java
|
||||
index 1ce2cf121c0768d06cbd4f9238286b02e139768b..afeb1f634a8d9e46136d8b425453e6c745132fbe 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionType.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionType.java
|
||||
@@ -43,7 +43,10 @@ public class CraftPotionType implements PotionType.InternalPotionData {
|
||||
public static PotionType stringToBukkit(String string) {
|
||||
Preconditions.checkArgument(string != null);
|
||||
|
||||
- return Registry.POTION.get(NamespacedKey.fromString(string));
|
||||
+ // Paper start - Fixup NamespacedKey handling
|
||||
+ final NamespacedKey key = NamespacedKey.fromString(string);
|
||||
+ return key != null ? Registry.POTION.get(key) : null;
|
||||
+ // Paper end - Fixup NamespacedKey handling
|
||||
}
|
||||
|
||||
private final NamespacedKey key;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftNamespacedKey.java b/src/main/java/org/bukkit/craftbukkit/util/CraftNamespacedKey.java
|
||||
index 5f40d240b879e3989897b6e45725a8e5a6a7f194..5014192edb9616ce725fc1592832034789527b6f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftNamespacedKey.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftNamespacedKey.java
|
||||
@@ -13,7 +13,7 @@ public final class CraftNamespacedKey {
|
||||
return null;
|
||||
}
|
||||
ResourceLocation minecraft = ResourceLocation.tryParse(string);
|
||||
- return (minecraft == null) ? null : CraftNamespacedKey.fromMinecraft(minecraft);
|
||||
+ return (minecraft == null || minecraft.getPath().isEmpty()) ? null : CraftNamespacedKey.fromMinecraft(minecraft); // Paper - Bukkit's parser does not match Vanilla for empty paths
|
||||
}
|
||||
|
||||
public static NamespacedKey fromString(String string) {
|
|
@ -1,50 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: FireInstall <kettnerl@hu-berlin.de>
|
||||
Date: Sat, 20 Jan 2024 16:20:06 +0100
|
||||
Subject: [PATCH] Expose LootTable of DecoratedPot
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftDecoratedPot.java b/src/main/java/org/bukkit/craftbukkit/block/CraftDecoratedPot.java
|
||||
index d595495943bd94a86aa32a6510e46a7ea5c8a723..e2fe5d8d7d8c00ed5d21cfe409933cdde8932e97 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftDecoratedPot.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftDecoratedPot.java
|
||||
@@ -40,6 +40,39 @@ public class CraftDecoratedPot extends CraftBlockEntityState<DecoratedPotBlockEn
|
||||
return new CraftInventoryDecoratedPot(this.getTileEntity());
|
||||
}
|
||||
|
||||
+ // Paper start - expose loot table
|
||||
+ @Override
|
||||
+ public void setLootTable(final org.bukkit.loot.LootTable table) {
|
||||
+ this.setLootTable(table, this.getSeed());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setLootTable(org.bukkit.loot.LootTable table, long seed) {
|
||||
+ net.minecraft.resources.ResourceLocation key = (table == null) ? null : org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(table.getKey());
|
||||
+ this.getSnapshot().setLootTable(key, seed);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.loot.LootTable getLootTable() {
|
||||
+ if (this.getSnapshot().getLootTable() == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ net.minecraft.resources.ResourceLocation key = this.getSnapshot().getLootTable();
|
||||
+ return org.bukkit.Bukkit.getLootTable(org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(key));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setSeed(final long seed) {
|
||||
+ this.getSnapshot().setLootTableSeed(seed);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public long getSeed() {
|
||||
+ return this.getSnapshot().getLootTableSeed();
|
||||
+ }
|
||||
+ // Paper end - expose loot table
|
||||
+
|
||||
@Override
|
||||
public void setSherd(Side face, Material sherd) {
|
||||
Preconditions.checkArgument(face != null, "face must not be null");
|
|
@ -1,59 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Mon, 27 Apr 2020 00:04:16 -0700
|
||||
Subject: [PATCH] Reduce allocation of Vec3D by entity tracker
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/VecDeltaCodec.java b/src/main/java/net/minecraft/network/protocol/game/VecDeltaCodec.java
|
||||
index a3d247c93ac1a2d872ff0e3841efc3d7b84fcbc1..23fe7c4c1844d321efed6b7b886c422761ad6594 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/VecDeltaCodec.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/VecDeltaCodec.java
|
||||
@@ -5,7 +5,7 @@ import org.jetbrains.annotations.VisibleForTesting;
|
||||
|
||||
public class VecDeltaCodec {
|
||||
private static final double TRUNCATION_STEPS = 4096.0;
|
||||
- private Vec3 base = Vec3.ZERO;
|
||||
+ public Vec3 base = Vec3.ZERO; // Paper
|
||||
|
||||
@VisibleForTesting
|
||||
static long encode(double value) {
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 22558aa7f83191519ca21357925309119d0718c7..d7c58ac9f9f4727cf13c0fd3bc370b10a2aba38f 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1735,10 +1735,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
public void updatePlayer(ServerPlayer player) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot
|
||||
if (player != this.entity) {
|
||||
- Vec3 vec3d = player.position().subtract(this.entity.position());
|
||||
+ // Paper start - remove allocation of Vec3D here
|
||||
+ // Vec3 vec3d = player.position().subtract(this.entity.position());
|
||||
+ double vec3d_dx = player.getX() - this.entity.getX();
|
||||
+ double vec3d_dz = player.getZ() - this.entity.getZ();
|
||||
+ // Paper end - remove allocation of Vec3D here
|
||||
int i = ChunkMap.this.getPlayerViewDistance(player);
|
||||
double d0 = (double) Math.min(this.getEffectiveRange(), i * 16);
|
||||
- double d1 = vec3d.x * vec3d.x + vec3d.z * vec3d.z;
|
||||
+ double d1 = vec3d_dx * vec3d_dx + vec3d_dz * vec3d_dz; // Paper
|
||||
double d2 = d0 * d0;
|
||||
boolean flag = d1 <= d2 && this.entity.broadcastToPlayer(player) && ChunkMap.this.isChunkTracked(player, this.entity.chunkPosition().x, this.entity.chunkPosition().z);
|
||||
// Paper start - Configurable entity tracking range by Y
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
index c2a4fde17673a2bc3133aa0c68608c3da75d5cc5..9154af6523f4eaab1636e0bad30f743244e47471 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
@@ -164,7 +164,13 @@ public class ServerEntity {
|
||||
i = Mth.floor(this.entity.getYRot() * 256.0F / 360.0F);
|
||||
j = Mth.floor(this.entity.getXRot() * 256.0F / 360.0F);
|
||||
Vec3 vec3d = this.entity.trackingPosition();
|
||||
- boolean flag1 = this.positionCodec.delta(vec3d).lengthSqr() >= 7.62939453125E-6D;
|
||||
+ // Paper start - reduce allocation of Vec3D here
|
||||
+ Vec3 base = this.positionCodec.base;
|
||||
+ double vec3d_dx = vec3d.x - base.x;
|
||||
+ double vec3d_dy = vec3d.y - base.y;
|
||||
+ double vec3d_dz = vec3d.z - base.z;
|
||||
+ boolean flag1 = (vec3d_dx * vec3d_dx + vec3d_dy * vec3d_dy + vec3d_dz * vec3d_dz) >= 7.62939453125E-6D;
|
||||
+ // Paper end - reduce allocation of Vec3D here
|
||||
Packet<?> packet1 = null;
|
||||
boolean flag2 = flag1 || this.tickCount % 60 == 0;
|
||||
boolean flag3 = Math.abs(i - this.yRotp) >= 1 || Math.abs(j - this.xRotp) >= 1;
|
Loading…
Add table
Add a link
Reference in a new issue