mirror of
https://github.com/PaperMC/Paper.git
synced 2025-08-15 12:13:54 -07:00
Patch me this, patch me that
This commit is contained in:
@@ -1,32 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: TrollyLoki <trollyloki@gmail.com>
|
||||
Date: Wed, 11 Oct 2023 00:45:53 -0400
|
||||
Subject: [PATCH] Add API to get the collision shape of a block before it's
|
||||
placed
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
@@ -0,0 +0,0 @@ public class CraftBlockData implements BlockData {
|
||||
return this.state.isFaceSturdy(EmptyBlockGetter.INSTANCE, BlockPos.ZERO, CraftBlock.blockFaceToNotch(face), CraftBlockSupport.toNMS(support));
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public org.bukkit.util.VoxelShape getCollisionShape(Location location) {
|
||||
+ Preconditions.checkArgument(location != null, "location must not be null");
|
||||
+
|
||||
+ CraftWorld world = (CraftWorld) location.getWorld();
|
||||
+ Preconditions.checkArgument(world != null, "location must not have a null world");
|
||||
+
|
||||
+ BlockPos position = CraftLocation.toBlockPosition(location);
|
||||
+ net.minecraft.world.phys.shapes.VoxelShape shape = this.state.getCollisionShape(world.getHandle(), position);
|
||||
+ return new org.bukkit.craftbukkit.util.CraftVoxelShape(shape);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public Color getMapColor() {
|
||||
return Color.fromRGB(this.state.getMapColor(null, null).col);
|
@@ -1,48 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: RodneyMKay <36546810+RodneyMKay@users.noreply.github.com>
|
||||
Date: Wed, 8 Sep 2021 21:34:01 +0200
|
||||
Subject: [PATCH] Add PlayerPickItemEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
this.disconnect(Component.literal("Invalid hotbar selection (Hacking?)"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause
|
||||
return;
|
||||
}
|
||||
- this.player.getInventory().pickSlot(packet.getSlot()); // Paper - Diff above if changed
|
||||
// Paper end - validate pick item position
|
||||
+ // Paper start - Add PlayerPickItemEvent
|
||||
+ Player bukkitPlayer = this.player.getBukkitEntity();
|
||||
+ int targetSlot = this.player.getInventory().getSuitableHotbarSlot();
|
||||
+ int sourceSlot = packet.getSlot();
|
||||
+
|
||||
+ io.papermc.paper.event.player.PlayerPickItemEvent event = new io.papermc.paper.event.player.PlayerPickItemEvent(bukkitPlayer, targetSlot, sourceSlot);
|
||||
+ if (!event.callEvent()) return;
|
||||
+
|
||||
+ this.player.getInventory().pickSlot(event.getSourceSlot(), event.getTargetSlot());
|
||||
+ // Paper end - Add PlayerPickItemEvent
|
||||
this.player.connection.send(new ClientboundContainerSetSlotPacket(-2, 0, this.player.getInventory().selected, this.player.getInventory().getItem(this.player.getInventory().selected)));
|
||||
this.player.connection.send(new ClientboundContainerSetSlotPacket(-2, 0, packet.getSlot(), this.player.getInventory().getItem(packet.getSlot())));
|
||||
this.player.connection.send(new ClientboundSetCarriedItemPacket(this.player.getInventory().selected));
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Inventory.java b/src/main/java/net/minecraft/world/entity/player/Inventory.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Inventory.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Inventory.java
|
||||
@@ -0,0 +0,0 @@ public class Inventory implements Container, Nameable {
|
||||
}
|
||||
|
||||
public void pickSlot(int slot) {
|
||||
- this.selected = this.getSuitableHotbarSlot();
|
||||
+ // Paper start - Add PlayerPickItemEvent
|
||||
+ pickSlot(slot, this.getSuitableHotbarSlot());
|
||||
+ }
|
||||
+
|
||||
+ public void pickSlot(int slot, int targetSlot) {
|
||||
+ this.selected = targetSlot;
|
||||
+ // Paper end - Add PlayerPickItemEvent
|
||||
ItemStack itemstack = (ItemStack) this.items.get(this.selected);
|
||||
|
||||
this.items.set(this.selected, (ItemStack) this.items.get(slot));
|
@@ -1,26 +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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -0,0 +0,0 @@ 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),
|
||||
+ CraftStructure.bukkitToMinecraft(structure)
|
||||
+ ).isValid();
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
private static final Random rand = new Random();
|
||||
|
@@ -1,142 +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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java
|
||||
+++ b/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java
|
||||
@@ -0,0 +0,0 @@ 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 {
|
||||
@@ -0,0 +0,0 @@ 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/AttributeMappings.java b/src/main/java/org/bukkit/craftbukkit/attribute/AttributeMappings.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/attribute/AttributeMappings.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package org.bukkit.craftbukkit.attribute;
|
||||
+
|
||||
+import java.util.HashMap;
|
||||
+import java.util.Map;
|
||||
+import java.util.UUID;
|
||||
+import org.bukkit.NamespacedKey;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+final class AttributeMappings {
|
||||
+ private static final Map<UUID, NamespacedKey> ATTRIBUTE_MODIFIER_IDS = new HashMap<>();
|
||||
+
|
||||
+ static {
|
||||
+ add(-4483571535397864886L, -5989644940537681742L, "armor.body");
|
||||
+ add(8144722948526719024L, -7778190119041365872L, "effect.slowness");
|
||||
+ add(6967552254039378640L, -9116175396973475259L, "enchantment.aqua_affinity");
|
||||
+ add(5279725409867744698L, -5150363631200102632L, "attacking");
|
||||
+ add(148071211714102867L, -7685811609035173472L, "attacking");
|
||||
+ add(6196088217904236654L, -7493791321850887290L, "effect.minining_fatigue");
|
||||
+ add(-5084161844451524480L, -8859020046251006329L, "enchantment.soul_speed");
|
||||
+ add(-7907339078496465106L, -8112074600724210224L, "enchantment.swift_sneak");
|
||||
+ add(6688265815086220243L, -6545541163342161890L, "drinking");
|
||||
+ add(8315164243412860989L, -6631520853640075966L, "creative_mode_block_range");
|
||||
+ add(4389663563256579765L, -4827163546944004714L, "enchantment.efficiency");
|
||||
+ add(6732612758648800940L, -5145707699103688244L, "effect.health_boost");
|
||||
+ add(9079981369298536661L, -6728494925450710401L, "covered");
|
||||
+ add(-1521481167610687786L, -8630419745734927691L, "effect.absorption");
|
||||
+ add(-7473408062188862076L, -5872005994337939597L, "creative_mode_entity_range");
|
||||
+ add(-3721396875562958315L, -5317020504214661337L, "effect.unluck");
|
||||
+ add(-2861585646493481178L, -6113244764726669811L, "armor.leggings");
|
||||
+ add(6718535547217657911L, -5386630269401489641L, "enchantment.sweeping_edge");
|
||||
+ add(-7949229004988660584L, -7828611303000832459L, "effect.speed");
|
||||
+ add(-8650171790042118250L, -5749650997644763080L, "enchantment.soul_speed");
|
||||
+ add(551224288813600377L, -8734740027710371860L, "enchantment.respiration");
|
||||
+ add(-7046399332347654691L, -6723081531683397260L, "suffocating");
|
||||
+ add(7361814797886573596L, -8641397326606817395L, "sprinting");
|
||||
+ add(-6972338111383059132L, -8978659762232839026L, "armor.chestplate");
|
||||
+ add(-5371971015925809039L, -6062243582569928137L, "enchantment.fire_protection");
|
||||
+ add(7245570952092733273L, -8449101711440750679L, "effect.strength");
|
||||
+ add(-422425648963762075L, -5756800103171642205L, "base_attack_speed");
|
||||
+ add(-4607081316629330256L, -7008565754814018370L, "effect.jump_boost");
|
||||
+ add(271280981090454338L, -8746077033958322898L, "effect.luck");
|
||||
+ add(2211131075215181206L, -5513857709499300658L, "powder_snow");
|
||||
+ add(-8908768238899017377L, -8313820693701227669L, "armor.boots");
|
||||
+ add(-5797418877589107702L, -6181652684028920077L, "effect.haste");
|
||||
+ add(3086076556416732775L, -5150312587563650736L, "armor.helmet");
|
||||
+ add(-5082757096938257406L, -4891139119377885130L, "baby");
|
||||
+ add(2478452629826324956L, -7247530463494186011L, "effect.weakness");
|
||||
+ add(4659420831966187055L, -5191473055587376048L, "enchantment.blast_protection");
|
||||
+ add(7301951777949303281L, -6753860660653972126L, "evil");
|
||||
+ add(8533189226688352746L, -8254757081029716377L, "baby");
|
||||
+ add(1286946037536540352L, -5768092872487507967L, "enchantment.depth_strider");
|
||||
+ add(-3801225194067177672L, -6586624321849018929L, "base_attack_damage");
|
||||
+ }
|
||||
+
|
||||
+ public static @NotNull NamespacedKey uuidToKey(final UUID uuid) {
|
||||
+ final NamespacedKey key = ATTRIBUTE_MODIFIER_IDS.get(uuid);
|
||||
+ if (key != null) {
|
||||
+ return key;
|
||||
+ } else {
|
||||
+ return NamespacedKey.minecraft(uuid.toString());
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static void add(final long msb, final long lsb, final String id) {
|
||||
+ final UUID uuid = new UUID(msb, lsb);
|
||||
+ ATTRIBUTE_MODIFIER_IDS.put(uuid, NamespacedKey.minecraft(id));
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java
|
||||
@@ -0,0 +0,0 @@ public class CraftAttributeInstance implements AttributeInstance {
|
||||
return result;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public AttributeModifier getModifier(final net.kyori.adventure.key.Key key) {
|
||||
+ Preconditions.checkArgument(key != null, "Key cannot be null");
|
||||
+ net.minecraft.world.entity.ai.attributes.AttributeModifier modifier = this.handle.getModifier(io.papermc.paper.adventure.PaperAdventure.asVanilla(key));
|
||||
+ return modifier == null ? null : CraftAttributeInstance.convert(modifier);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void removeModifier(final net.kyori.adventure.key.Key key) {
|
||||
+ Preconditions.checkArgument(key != null, "Key cannot be null");
|
||||
+ this.handle.removeModifier(io.papermc.paper.adventure.PaperAdventure.asVanilla(key));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public AttributeModifier getModifier(java.util.UUID uuid) {
|
||||
+ Preconditions.checkArgument(uuid != null, "UUID cannot be null");
|
||||
+ return this.getModifier(AttributeMappings.uuidToKey(uuid));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void removeModifier(java.util.UUID uuid) {
|
||||
+ Preconditions.checkArgument(uuid != null, "UUID cannot be null");
|
||||
+ this.removeModifier(AttributeMappings.uuidToKey(uuid));
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void addModifier(AttributeModifier modifier) {
|
||||
Preconditions.checkArgument(modifier != null, "modifier");
|
@@ -1,411 +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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java
|
||||
+++ b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java
|
||||
@@ -0,0 +0,0 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior {
|
||||
if (entityliving instanceof Shearable ishearable) {
|
||||
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, (Holder) 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Shearable.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Shearable.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
+ 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 - custom shear drops
|
||||
this.gameEvent(GameEvent.SHEAR, player);
|
||||
if (!this.level().isClientSide) {
|
||||
itemstack.hurtAndBreak(1, player, getSlotForHand(hand));
|
||||
@@ -0,0 +0,0 @@ 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 java.util.List<ItemStack> generateDefaultDrops() {
|
||||
+ java.util.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, java.util.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());
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Sheep.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Sheep.java
|
||||
@@ -0,0 +0,0 @@ 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, getSlotForHand(hand));
|
||||
return InteractionResult.SUCCESS;
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
|
||||
@@ -0,0 +0,0 @@ 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, getSlotForHand(hand));
|
||||
@@ -0,0 +0,0 @@ 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), this.getEyeHeight());
|
||||
- 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, this.getEyeHeight());
|
||||
+ this.forceDrops = false;
|
||||
+ }
|
||||
+ // Paper end - custom shear drops
|
||||
}
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Bogged.java b/src/main/java/net/minecraft/world/entity/monster/Bogged.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Bogged.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Bogged.java
|
||||
@@ -0,0 +0,0 @@ public class Bogged extends AbstractSkeleton implements Shearable {
|
||||
|
||||
if (itemstack.is(Items.SHEARS) && this.readyForShearing()) {
|
||||
// CraftBukkit start
|
||||
- if (!org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) {
|
||||
- this.getEntityData().markDirty(Bogged.DATA_SHEARED); // CraftBukkit - mark dirty to restore sheared state to clients
|
||||
- return InteractionResult.PASS;
|
||||
+ // Paper start - expose drops in event
|
||||
+ java.util.List<net.minecraft.world.item.ItemStack> drops = generateDefaultDrops();
|
||||
+ final org.bukkit.event.player.PlayerShearEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops);
|
||||
+ if (event != null) {
|
||||
+ if (event.isCancelled()) {
|
||||
+ if (player instanceof final net.minecraft.server.level.ServerPlayer serverPlayer) this.resendPossiblyDesyncedDataValues(java.util.List.of(Bogged.DATA_SHEARED), serverPlayer);
|
||||
+ return InteractionResult.PASS;
|
||||
+ }
|
||||
+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops());
|
||||
+ // Paper end - expose drops in event
|
||||
}
|
||||
// CraftBukkit end
|
||||
- this.shear(SoundSource.PLAYERS);
|
||||
+ this.shear(SoundSource.PLAYERS, drops); // Paper - expose drops in event
|
||||
this.gameEvent(GameEvent.SHEAR, player);
|
||||
if (!this.level().isClientSide) {
|
||||
itemstack.hurtAndBreak(1, player, getSlotForHand(hand));
|
||||
@@ -0,0 +0,0 @@ public class Bogged extends AbstractSkeleton implements Shearable {
|
||||
|
||||
@Override
|
||||
public void shear(SoundSource shearedSoundCategory) {
|
||||
+ // Paper start - shear drop API
|
||||
+ this.shear(shearedSoundCategory, generateDefaultDrops());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void shear(SoundSource shearedSoundCategory, java.util.List<net.minecraft.world.item.ItemStack> drops) {
|
||||
+ // Paper end - shear drop API
|
||||
this.level().playSound((Player) null, (Entity) this, SoundEvents.BOGGED_SHEAR, shearedSoundCategory, 1.0F, 1.0F);
|
||||
- this.spawnShearedMushrooms();
|
||||
+ this.spawnDrops(drops); // Paper - shear drop API
|
||||
this.setSheared(true);
|
||||
}
|
||||
|
||||
private void spawnShearedMushrooms() {
|
||||
+ // Paper start - shear drops API
|
||||
+ this.spawnDrops(generateDefaultDrops()); // Only here for people calling spawnSheardMushrooms. Not used otherwise.
|
||||
+ }
|
||||
+ private void spawnDrops(java.util.List<net.minecraft.world.item.ItemStack> drops) {
|
||||
+ drops.forEach(stack -> {
|
||||
+ this.forceDrops = true;
|
||||
+ this.spawnAtLocation(stack, this.getBbHeight());
|
||||
+ this.forceDrops = false;
|
||||
+ });
|
||||
+ }
|
||||
+ private void generateShearedMushrooms(java.util.function.Consumer<ItemStack> stackConsumer) {
|
||||
+ // Paper end - shear drops API
|
||||
Level world = this.level();
|
||||
|
||||
if (world instanceof ServerLevel worldserver) {
|
||||
@@ -0,0 +0,0 @@ public class Bogged extends AbstractSkeleton implements Shearable {
|
||||
while (objectlistiterator.hasNext()) {
|
||||
ItemStack itemstack = (ItemStack) objectlistiterator.next();
|
||||
|
||||
- this.spawnAtLocation(itemstack, this.getBbHeight());
|
||||
+ stackConsumer.accept(itemstack); // Paper
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start - shear drops API
|
||||
+ @Override
|
||||
+ public java.util.List<ItemStack> generateDefaultDrops() {
|
||||
+ final java.util.List<ItemStack> drops = new java.util.ArrayList<>();
|
||||
+ this.generateShearedMushrooms(drops::add);
|
||||
+ return drops;
|
||||
+ }
|
||||
+ // Paper end - shear drops API
|
||||
+
|
||||
@Override
|
||||
public boolean readyForShearing() {
|
||||
return !this.isSheared() && this.isAlive();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
@@ -0,0 +0,0 @@ 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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/io/papermc/paper/entity/ShearableDropsTest.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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.environment.Normal;
|
||||
+import org.junit.jupiter.params.ParameterizedTest;
|
||||
+import org.junit.jupiter.params.provider.MethodSource;
|
||||
+
|
||||
+import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
+
|
||||
+@Normal
|
||||
+class ShearableDropsTest {
|
||||
+
|
||||
+ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
@@ -0,0 +0,0 @@ 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)) {
|
||||
@@ -0,0 +0,0 @@ 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()) {
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
|
||||
@@ -0,0 +0,0 @@ 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()) {
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/FishingRodItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/FishingRodItem.java
|
||||
@@ -0,0 +0,0 @@ public class FishingRodItem extends Item {
|
||||
|
||||
if (user.fishing != null) {
|
||||
if (!world.isClientSide) {
|
||||
- int i = user.fishing.retrieve(itemstack);
|
||||
+ int i = user.fishing.retrieve(hand, itemstack); // Paper - Add hand parameter to PlayerFishEvent
|
||||
|
||||
itemstack.hurtAndBreak(i, user, LivingEntity.getSlotForHand(hand));
|
||||
}
|
@@ -1,302 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Mon, 24 Jan 2022 00:09:02 -0800
|
||||
Subject: [PATCH] Add missing InventoryHolders to inventories
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/Container.java b/src/main/java/net/minecraft/world/Container.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/Container.java
|
||||
+++ b/src/main/java/net/minecraft/world/Container.java
|
||||
@@ -0,0 +0,0 @@ public interface Container extends Clearable {
|
||||
|
||||
java.util.List<org.bukkit.entity.HumanEntity> getViewers();
|
||||
|
||||
- org.bukkit.inventory.InventoryHolder getOwner();
|
||||
+ org.bukkit.inventory.@org.jetbrains.annotations.Nullable InventoryHolder getOwner(); // Paper - annotation
|
||||
|
||||
void setMaxStackSize(int size);
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/SimpleContainer.java b/src/main/java/net/minecraft/world/SimpleContainer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/SimpleContainer.java
|
||||
+++ b/src/main/java/net/minecraft/world/SimpleContainer.java
|
||||
@@ -0,0 +0,0 @@ public class SimpleContainer implements Container, StackedContentsCompatible {
|
||||
// CraftBukkit start - add fields and methods
|
||||
public List<HumanEntity> transaction = new java.util.ArrayList<HumanEntity>();
|
||||
private int maxStack = MAX_STACK;
|
||||
- protected org.bukkit.inventory.InventoryHolder bukkitOwner;
|
||||
+ protected @Nullable org.bukkit.inventory.InventoryHolder bukkitOwner; // Paper - annotation
|
||||
|
||||
public List<ItemStack> getContents() {
|
||||
return this.items;
|
||||
@@ -0,0 +0,0 @@ public class SimpleContainer implements Container, StackedContentsCompatible {
|
||||
}
|
||||
|
||||
public org.bukkit.inventory.InventoryHolder getOwner() {
|
||||
+ // Paper start - Add missing InventoryHolders
|
||||
+ if (this.bukkitOwner == null && this.bukkitOwnerCreator != null) {
|
||||
+ this.bukkitOwner = this.bukkitOwnerCreator.get();
|
||||
+ }
|
||||
+ // Paper end - Add missing InventoryHolders
|
||||
return this.bukkitOwner;
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class SimpleContainer implements Container, StackedContentsCompatible {
|
||||
public SimpleContainer(int size) {
|
||||
this(size, null);
|
||||
}
|
||||
+ // Paper start - Add missing InventoryHolders
|
||||
+ private @Nullable java.util.function.Supplier<? extends org.bukkit.inventory.InventoryHolder> bukkitOwnerCreator;
|
||||
+ public SimpleContainer(java.util.function.Supplier<? extends org.bukkit.inventory.InventoryHolder> bukkitOwnerCreator, int size) {
|
||||
+ this(size);
|
||||
+ this.bukkitOwnerCreator = bukkitOwnerCreator;
|
||||
+ }
|
||||
+ // Paper end - Add missing InventoryHolders
|
||||
|
||||
public SimpleContainer(int i, org.bukkit.inventory.InventoryHolder owner) {
|
||||
this.bukkitOwner = owner;
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractContainerMenu {
|
||||
this.stateId = this.stateId + 1 & 32767;
|
||||
return this.stateId;
|
||||
}
|
||||
+
|
||||
+ // Paper start - Add missing InventoryHolders
|
||||
+ // The reason this is a supplier, is that the createHolder method uses the bukkit InventoryView#getTopInventory to get the inventory in question
|
||||
+ // and that can't be obtained safely until the AbstractContainerMenu has been fully constructed. Using a supplier lazily
|
||||
+ // initializes the InventoryHolder safely.
|
||||
+ protected final Supplier<org.bukkit.inventory.BlockInventoryHolder> createBlockHolder(final ContainerLevelAccess context) {
|
||||
+ //noinspection ConstantValue
|
||||
+ Preconditions.checkArgument(context != null, "context was null");
|
||||
+ return () -> context.createBlockHolder(this);
|
||||
+ }
|
||||
+ // Paper end - Add missing InventoryHolders
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/BeaconMenu.java b/src/main/java/net/minecraft/world/inventory/BeaconMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/BeaconMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/BeaconMenu.java
|
||||
@@ -0,0 +0,0 @@ public class BeaconMenu extends AbstractContainerMenu {
|
||||
public BeaconMenu(int syncId, Container inventory, ContainerData propertyDelegate, ContainerLevelAccess context) {
|
||||
super(MenuType.BEACON, syncId);
|
||||
this.player = (Inventory) inventory; // CraftBukkit - TODO: check this
|
||||
- this.beacon = new SimpleContainer(1) { // CraftBukkit - decompile error
|
||||
+ this.beacon = new SimpleContainer(this.createBlockHolder(context), 1) { // CraftBukkit - decompile error // Paper - Add missing InventoryHolders
|
||||
@Override
|
||||
public boolean canPlaceItem(int slot, ItemStack stack) {
|
||||
return stack.is(ItemTags.BEACON_PAYMENT_ITEMS);
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java b/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java
|
||||
@@ -0,0 +0,0 @@ public class CartographyTableMenu extends AbstractContainerMenu {
|
||||
|
||||
public CartographyTableMenu(int syncId, Inventory inventory, final ContainerLevelAccess context) {
|
||||
super(MenuType.CARTOGRAPHY_TABLE, syncId);
|
||||
- this.container = new SimpleContainer(2) {
|
||||
+ this.container = new SimpleContainer(this.createBlockHolder(context), 2) { // Paper - Add missing InventoryHolders
|
||||
@Override
|
||||
public void setChanged() {
|
||||
CartographyTableMenu.this.slotsChanged(this);
|
||||
@@ -0,0 +0,0 @@ public class CartographyTableMenu extends AbstractContainerMenu {
|
||||
}
|
||||
// CraftBukkit end
|
||||
};
|
||||
- this.resultContainer = new ResultContainer() {
|
||||
+ this.resultContainer = new ResultContainer(this.createBlockHolder(context)) { // Paper - Add missing InventoryHolders
|
||||
@Override
|
||||
public void setChanged() {
|
||||
CartographyTableMenu.this.slotsChanged(this);
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/ContainerLevelAccess.java b/src/main/java/net/minecraft/world/inventory/ContainerLevelAccess.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/ContainerLevelAccess.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/ContainerLevelAccess.java
|
||||
@@ -0,0 +0,0 @@ public interface ContainerLevelAccess {
|
||||
return new org.bukkit.Location(this.getWorld().getWorld(), this.getPosition().getX(), this.getPosition().getY(), this.getPosition().getZ());
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ // Paper start - Add missing InventoryHolders
|
||||
+ default boolean isBlock() {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ default org.bukkit.inventory.@org.jetbrains.annotations.Nullable BlockInventoryHolder createBlockHolder(AbstractContainerMenu menu) {
|
||||
+ if (!this.isBlock()) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ return new org.bukkit.craftbukkit.inventory.CraftBlockInventoryHolder(this, menu.getBukkitView().getTopInventory());
|
||||
+ }
|
||||
+ // Paper end - Add missing InventoryHolders
|
||||
|
||||
ContainerLevelAccess NULL = new ContainerLevelAccess() {
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public interface ContainerLevelAccess {
|
||||
return pos;
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ // Paper start - Add missing InventoryHolders
|
||||
+ @Override
|
||||
+ public boolean isBlock() {
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end - Add missing InventoryHolders
|
||||
|
||||
@Override
|
||||
public <T> Optional<T> evaluate(BiFunction<Level, BlockPos, T> getter) {
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java
|
||||
@@ -0,0 +0,0 @@ public class EnchantmentMenu extends AbstractContainerMenu {
|
||||
|
||||
public EnchantmentMenu(int syncId, Inventory playerInventory, ContainerLevelAccess context) {
|
||||
super(MenuType.ENCHANTMENT, syncId);
|
||||
- this.enchantSlots = new SimpleContainer(2) {
|
||||
+ this.enchantSlots = new SimpleContainer(this.createBlockHolder(context), 2) { // Paper - Add missing InventoryHolders
|
||||
@Override
|
||||
public void setChanged() {
|
||||
super.setChanged();
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java
|
||||
@@ -0,0 +0,0 @@ public class GrindstoneMenu extends AbstractContainerMenu {
|
||||
|
||||
public GrindstoneMenu(int syncId, Inventory playerInventory, final ContainerLevelAccess context) {
|
||||
super(MenuType.GRINDSTONE, syncId);
|
||||
- this.resultSlots = new ResultContainer();
|
||||
- this.repairSlots = new SimpleContainer(2) {
|
||||
+ this.resultSlots = new ResultContainer(this.createBlockHolder(context)); // Paper - Add missing InventoryHolders
|
||||
+ this.repairSlots = new SimpleContainer(this.createBlockHolder(context), 2) { // Paper - Add missing InventoryHolders
|
||||
@Override
|
||||
public void setChanged() {
|
||||
super.setChanged();
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java
|
||||
@@ -0,0 +0,0 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
|
||||
protected final Player player;
|
||||
protected final Container inputSlots;
|
||||
private final List<Integer> inputSlotIndexes;
|
||||
- protected final ResultContainer resultSlots = new ResultContainer();
|
||||
+ protected final ResultContainer resultSlots; // Paper - Add missing InventoryHolders; delay field init
|
||||
private final int resultSlotIndex;
|
||||
|
||||
protected abstract boolean mayPickup(Player player, boolean present);
|
||||
@@ -0,0 +0,0 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
|
||||
public ItemCombinerMenu(@Nullable MenuType<?> type, int syncId, Inventory playerInventory, ContainerLevelAccess context) {
|
||||
super(type, syncId);
|
||||
this.access = context;
|
||||
+ this.resultSlots = new ResultContainer(this.createBlockHolder(this.access)); // Paper - Add missing InventoryHolders; delay field init
|
||||
this.player = playerInventory.player;
|
||||
ItemCombinerMenuSlotDefinition itemcombinermenuslotdefinition = this.createInputSlotDefinitions();
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
|
||||
protected abstract ItemCombinerMenuSlotDefinition createInputSlotDefinitions();
|
||||
|
||||
private SimpleContainer createContainer(int size) {
|
||||
- return new SimpleContainer(size) {
|
||||
+ return new SimpleContainer(this.createBlockHolder(this.access), size) { // Paper - Add missing InventoryHolders
|
||||
@Override
|
||||
public void setChanged() {
|
||||
super.setChanged();
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/LoomMenu.java b/src/main/java/net/minecraft/world/inventory/LoomMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/LoomMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/LoomMenu.java
|
||||
@@ -0,0 +0,0 @@ public class LoomMenu extends AbstractContainerMenu {
|
||||
this.selectablePatterns = List.of();
|
||||
this.slotUpdateListener = () -> {
|
||||
};
|
||||
- this.inputContainer = new SimpleContainer(3) {
|
||||
+ this.inputContainer = new SimpleContainer(this.createBlockHolder(context), 3) { // Paper - Add missing InventoryHolders
|
||||
@Override
|
||||
public void setChanged() {
|
||||
super.setChanged();
|
||||
@@ -0,0 +0,0 @@ public class LoomMenu extends AbstractContainerMenu {
|
||||
}
|
||||
// CraftBukkit end
|
||||
};
|
||||
- this.outputContainer = new SimpleContainer(1) {
|
||||
+ this.outputContainer = new SimpleContainer(this.createBlockHolder(context), 1) { // Paper - Add missing InventoryHolders
|
||||
@Override
|
||||
public void setChanged() {
|
||||
super.setChanged();
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/ResultContainer.java b/src/main/java/net/minecraft/world/inventory/ResultContainer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/ResultContainer.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/ResultContainer.java
|
||||
@@ -0,0 +0,0 @@ public class ResultContainer implements Container, RecipeCraftingHolder {
|
||||
}
|
||||
|
||||
public org.bukkit.inventory.InventoryHolder getOwner() {
|
||||
- return null; // Result slots don't get an owner
|
||||
+ // Paper start - Add missing InventoryHolders
|
||||
+ if (this.holder == null && this.holderCreator != null) {
|
||||
+ this.holder = this.holderCreator.get();
|
||||
+ }
|
||||
+ return this.holder; // Result slots don't get an owner
|
||||
+ // Paper end - Add missing InventoryHolders
|
||||
}
|
||||
|
||||
// Don't need a transaction; the InventoryCrafting keeps track of it for us
|
||||
@@ -0,0 +0,0 @@ public class ResultContainer implements Container, RecipeCraftingHolder {
|
||||
return null;
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ // Paper start - Add missing InventoryHolders
|
||||
+ private @Nullable java.util.function.Supplier<? extends org.bukkit.inventory.InventoryHolder> holderCreator;
|
||||
+ private @Nullable org.bukkit.inventory.InventoryHolder holder;
|
||||
+ public ResultContainer(java.util.function.Supplier<? extends org.bukkit.inventory.InventoryHolder> holderCreator) {
|
||||
+ this();
|
||||
+ this.holderCreator = holderCreator;
|
||||
+ }
|
||||
+ // Paper end - Add missing InventoryHolders
|
||||
|
||||
public ResultContainer() {
|
||||
this.itemStacks = NonNullList.withSize(1, ItemStack.EMPTY);
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java b/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java
|
||||
@@ -0,0 +0,0 @@ public class StonecutterMenu extends AbstractContainerMenu {
|
||||
this.input = ItemStack.EMPTY;
|
||||
this.slotUpdateListener = () -> {
|
||||
};
|
||||
- this.container = new SimpleContainer(1) {
|
||||
+ this.container = new SimpleContainer(this.createBlockHolder(context), 1) { // Paper - Add missing InventoryHolders
|
||||
@Override
|
||||
public void setChanged() {
|
||||
super.setChanged();
|
||||
@@ -0,0 +0,0 @@ public class StonecutterMenu extends AbstractContainerMenu {
|
||||
}
|
||||
// CraftBukkit end
|
||||
};
|
||||
- this.resultContainer = new ResultContainer();
|
||||
+ this.resultContainer = new ResultContainer(this.createBlockHolder(context)); // Paper - Add missing InventoryHolders
|
||||
this.access = context;
|
||||
this.level = playerInventory.player.level();
|
||||
this.inputSlot = this.addSlot(new Slot(this.container, 0, 20, 33));
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlockInventoryHolder.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlockInventoryHolder.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlockInventoryHolder.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlockInventoryHolder.java
|
||||
@@ -0,0 +0,0 @@ public class CraftBlockInventoryHolder implements BlockInventoryHolder {
|
||||
this.block = CraftBlock.at(world, pos);
|
||||
this.inventory = new CraftInventory(inv);
|
||||
}
|
||||
+ // Paper start - Add missing InventoryHolders
|
||||
+ public CraftBlockInventoryHolder(net.minecraft.world.inventory.ContainerLevelAccess levelAccess, Inventory inventory) {
|
||||
+ com.google.common.base.Preconditions.checkArgument(levelAccess.isBlock());
|
||||
+ this.block = CraftBlock.at(levelAccess.getWorld(), levelAccess.getPosition());
|
||||
+ this.inventory = inventory;
|
||||
+ }
|
||||
+ // Paper end - Add missing InventoryHolders
|
||||
|
||||
@Override
|
||||
public Block getBlock() {
|
@@ -1,37 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Sat, 23 Sep 2023 01:49:39 -0400
|
||||
Subject: [PATCH] Add missing logs for log-ips config option
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java b/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
@@ -0,0 +0,0 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
com.destroystokyo.paper.event.server.PaperServerListPingEvent event; // Paper
|
||||
|
||||
if (i == 0) {
|
||||
- LegacyQueryHandler.LOGGER.debug("Ping: (<1.3.x) from {}", socketaddress);
|
||||
+ LegacyQueryHandler.LOGGER.debug("Ping: (<1.3.x) from {}", net.minecraft.server.MinecraftServer.getServer().logIPs() ? socketaddress: "<ip address withheld>"); // Paper - Respect logIPs option
|
||||
|
||||
// Paper start - Call PaperServerListPingEvent and use results
|
||||
event = com.destroystokyo.paper.network.PaperLegacyStatusClient.processRequest(net.minecraft.server.MinecraftServer.getServer(), (java.net.InetSocketAddress) socketaddress, 39, null);
|
||||
@@ -0,0 +0,0 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
// LegacyQueryHandler.LOGGER.debug("Ping: (1.6) from {}", socketaddress);
|
||||
// Paper end
|
||||
} else {
|
||||
- LegacyQueryHandler.LOGGER.debug("Ping: (1.4-1.5.x) from {}", socketaddress);
|
||||
+ LegacyQueryHandler.LOGGER.debug("Ping: (1.4-1.5.x) from {}", net.minecraft.server.MinecraftServer.getServer().logIPs() ? socketaddress: "<ip address withheld>"); // Paper - Respect logIPs option
|
||||
}
|
||||
|
||||
if (s == null) {
|
||||
@@ -0,0 +0,0 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
buf.release();
|
||||
this.buf = null;
|
||||
|
||||
- LOGGER.debug("Ping: (1.6) from {}", ctx.channel().remoteAddress());
|
||||
+ LOGGER.debug("Ping: (1.6) from {}", net.minecraft.server.MinecraftServer.getServer().logIPs() ? ctx.channel().remoteAddress(): "<ip address withheld>"); // Paper - Respect logIPs option
|
||||
|
||||
java.net.InetSocketAddress virtualHost = com.destroystokyo.paper.network.PaperNetworkClient.prepareVirtualHost(host, port);
|
||||
com.destroystokyo.paper.event.server.PaperServerListPingEvent event = com.destroystokyo.paper.network.PaperLegacyStatusClient.processRequest(
|
@@ -1,30 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: booky10 <boooky10@gmail.com>
|
||||
Date: Sat, 14 Oct 2023 03:11:11 +0200
|
||||
Subject: [PATCH] Add player idle duration API
|
||||
|
||||
Implements API for getting and resetting a player's idle duration.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
}
|
||||
// Paper end
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public Duration getIdleDuration() {
|
||||
+ return Duration.ofMillis(net.minecraft.Util.getMillis() - this.getHandle().getLastActionTime());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void resetIdleDuration() {
|
||||
+ this.getHandle().resetLastActionTime();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public Player.Spigot spigot()
|
||||
{
|
||||
return this.spigot;
|
@@ -1,116 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: TonytheMacaroni <tonythemacaroni123@gmail.com>
|
||||
Date: Wed, 6 Sep 2023 19:24:16 -0400
|
||||
Subject: [PATCH] Add predicate for blocks when raytracing
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/BlockGetter.java b/src/main/java/net/minecraft/world/level/BlockGetter.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/BlockGetter.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/BlockGetter.java
|
||||
@@ -0,0 +0,0 @@ public interface BlockGetter extends LevelHeightAccessor {
|
||||
|
||||
// CraftBukkit start - moved block handling into separate method for use by Block#rayTrace
|
||||
default BlockHitResult clip(ClipContext raytrace1, BlockPos blockposition) {
|
||||
+ // Paper start - Add predicate for blocks when raytracing
|
||||
+ return clip(raytrace1, blockposition, null);
|
||||
+ }
|
||||
+
|
||||
+ default BlockHitResult clip(ClipContext raytrace1, BlockPos blockposition, java.util.function.Predicate<? super org.bukkit.block.Block> canCollide) {
|
||||
+ // Paper end - Add predicate for blocks when raytracing
|
||||
// Paper start - Prevent raytrace from loading chunks
|
||||
BlockState iblockdata = this.getBlockStateIfLoaded(blockposition);
|
||||
if (iblockdata == null) {
|
||||
@@ -0,0 +0,0 @@ public interface BlockGetter extends LevelHeightAccessor {
|
||||
return BlockHitResult.miss(raytrace1.getTo(), Direction.getNearest(vec3d.x, vec3d.y, vec3d.z), BlockPos.containing(raytrace1.getTo()));
|
||||
}
|
||||
// Paper end - Prevent raytrace from loading chunks
|
||||
- if (iblockdata.isAir()) return null; // Paper - Perf: optimise air cases
|
||||
+ if (iblockdata.isAir() || (canCollide != null && this instanceof LevelAccessor levelAccessor && !canCollide.test(org.bukkit.craftbukkit.block.CraftBlock.at(levelAccessor, blockposition)))) return null; // Paper - Perf: optimise air cases & check canCollide predicate
|
||||
FluidState fluid = iblockdata.getFluidState(); // Paper - Perf: don't need to go to world state again
|
||||
Vec3 vec3d = raytrace1.getFrom();
|
||||
Vec3 vec3d1 = raytrace1.getTo();
|
||||
@@ -0,0 +0,0 @@ public interface BlockGetter extends LevelHeightAccessor {
|
||||
// CraftBukkit end
|
||||
|
||||
default BlockHitResult clip(ClipContext context) {
|
||||
+ // Paper start - Add predicate for blocks when raytracing
|
||||
+ return clip(context, (java.util.function.Predicate<org.bukkit.block.Block>) null);
|
||||
+ }
|
||||
+
|
||||
+ default BlockHitResult clip(ClipContext context, java.util.function.Predicate<? super org.bukkit.block.Block> canCollide) {
|
||||
+ // Paper end - Add predicate for blocks when raytracing
|
||||
return (BlockHitResult) BlockGetter.traverseBlocks(context.getFrom(), context.getTo(), context, (raytrace1, blockposition) -> {
|
||||
- return this.clip(raytrace1, blockposition); // CraftBukkit - moved into separate method
|
||||
+ return this.clip(raytrace1, blockposition, canCollide); // CraftBukkit - moved into separate method // Paper - Add predicate for blocks when raytracing
|
||||
}, (raytrace1) -> {
|
||||
Vec3 vec3d = raytrace1.getFrom().subtract(raytrace1.getTo());
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public RayTraceResult rayTraceEntities(Location start, Vector direction, double maxDistance, double raySize, Predicate<? super Entity> filter) {
|
||||
+ // Paper start - Add predicate for blocks when raytracing
|
||||
+ return rayTraceEntities((io.papermc.paper.math.Position) start, direction, maxDistance, raySize, filter);
|
||||
+ }
|
||||
+
|
||||
+ public RayTraceResult rayTraceEntities(io.papermc.paper.math.Position start, Vector direction, double maxDistance, double raySize, Predicate<? super Entity> filter) {
|
||||
Preconditions.checkArgument(start != null, "Location start cannot be null");
|
||||
- Preconditions.checkArgument(this.equals(start.getWorld()), "Location start cannot be in a different world");
|
||||
- start.checkFinite();
|
||||
+ Preconditions.checkArgument(!(start instanceof Location location) || this.equals(location.getWorld()), "Location start cannot be in a different world");
|
||||
+ Preconditions.checkArgument(start.isFinite(), "Location start is not finite");
|
||||
+ // Paper end - Add predicate for blocks when raytracing
|
||||
|
||||
Preconditions.checkArgument(direction != null, "Vector direction cannot be null");
|
||||
direction.checkFinite();
|
||||
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public RayTraceResult rayTraceBlocks(Location start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks) {
|
||||
+ // Paper start - Add predicate for blocks when raytracing
|
||||
+ return this.rayTraceBlocks(start, direction, maxDistance, fluidCollisionMode, ignorePassableBlocks, null);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public RayTraceResult rayTraceBlocks(io.papermc.paper.math.Position start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, Predicate<? super Block> canCollide) {
|
||||
Preconditions.checkArgument(start != null, "Location start cannot be null");
|
||||
- Preconditions.checkArgument(this.equals(start.getWorld()), "Location start cannot be in a different world");
|
||||
- start.checkFinite();
|
||||
+ Preconditions.checkArgument(!(start instanceof Location location) || this.equals(location.getWorld()), "Location start cannot be in a different world");
|
||||
+ Preconditions.checkArgument(start.isFinite(), "Location start is not finite");
|
||||
+ // Paper end - Add predicate for blocks when raytracing
|
||||
|
||||
Preconditions.checkArgument(direction != null, "Vector direction cannot be null");
|
||||
direction.checkFinite();
|
||||
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
}
|
||||
|
||||
Vector dir = direction.clone().normalize().multiply(maxDistance);
|
||||
- Vec3 startPos = CraftLocation.toVec3D(start);
|
||||
+ Vec3 startPos = io.papermc.paper.util.MCUtil.toVec3(start); // Paper - Add predicate for blocks when raytracing
|
||||
Vec3 endPos = startPos.add(dir.getX(), dir.getY(), dir.getZ());
|
||||
- HitResult nmsHitResult = this.getHandle().clip(new ClipContext(startPos, endPos, ignorePassableBlocks ? ClipContext.Block.COLLIDER : ClipContext.Block.OUTLINE, CraftFluidCollisionMode.toNMS(fluidCollisionMode), CollisionContext.empty()));
|
||||
+ HitResult nmsHitResult = this.getHandle().clip(new ClipContext(startPos, endPos, ignorePassableBlocks ? ClipContext.Block.COLLIDER : ClipContext.Block.OUTLINE, CraftFluidCollisionMode.toNMS(fluidCollisionMode), CollisionContext.empty()), canCollide); // Paper - Add predicate for blocks when raytracing
|
||||
|
||||
return CraftRayTraceResult.fromNMS(this, nmsHitResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RayTraceResult rayTrace(Location start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, double raySize, Predicate<? super Entity> filter) {
|
||||
- RayTraceResult blockHit = this.rayTraceBlocks(start, direction, maxDistance, fluidCollisionMode, ignorePassableBlocks);
|
||||
+ // Paper start - Add predicate for blocks when raytracing
|
||||
+ return this.rayTrace(start, direction, maxDistance, fluidCollisionMode, ignorePassableBlocks, raySize, filter, null);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public RayTraceResult rayTrace(io.papermc.paper.math.Position start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, double raySize, Predicate<? super Entity> filter, Predicate<? super Block> canCollide) {
|
||||
+ RayTraceResult blockHit = this.rayTraceBlocks(start, direction, maxDistance, fluidCollisionMode, ignorePassableBlocks, canCollide);
|
||||
+ // Paper end - Add predicate for blocks when raytracing
|
||||
Vector startVec = null;
|
||||
double blockHitDistance = maxDistance;
|
||||
|
@@ -1,43 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nassim Jahnke <nassim@njahnke.dev>
|
||||
Date: Mon, 11 Sep 2023 12:01:57 +1000
|
||||
Subject: [PATCH] Add slot sanity checks in container clicks
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
break;
|
||||
case SWAP:
|
||||
if ((packet.getButtonNum() >= 0 && packet.getButtonNum() < 9) || packet.getButtonNum() == 40) {
|
||||
+ // Paper start - Add slot sanity checks to container clicks
|
||||
+ if (packet.getSlotNum() < 0) {
|
||||
+ action = InventoryAction.NOTHING;
|
||||
+ break;
|
||||
+ }
|
||||
+ // Paper end - Add slot sanity checks to container clicks
|
||||
click = (packet.getButtonNum() == 40) ? ClickType.SWAP_OFFHAND : ClickType.NUMBER_KEY;
|
||||
Slot clickedSlot = this.player.containerMenu.getSlot(packet.getSlotNum());
|
||||
if (clickedSlot.mayPickup(this.player)) {
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractContainerMenu {
|
||||
this.resetQuickCraft();
|
||||
}
|
||||
} else if (this.quickcraftStatus == 1) {
|
||||
+ if (slotIndex < 0) return; // Paper - Add slot sanity checks to container clicks
|
||||
slot = (Slot) this.slots.get(slotIndex);
|
||||
itemstack = this.getCarried();
|
||||
if (AbstractContainerMenu.canItemQuickReplace(slot, itemstack, true) && slot.mayPlace(itemstack) && (this.quickcraftType == 2 || itemstack.getCount() > this.quickcraftSlots.size()) && this.canDragTo(slot)) {
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractContainerMenu {
|
||||
int j2;
|
||||
|
||||
if (actionType == ClickType.SWAP && (button >= 0 && button < 9 || button == 40)) {
|
||||
+ if (slotIndex < 0) return; // Paper - Add slot sanity checks to container clicks
|
||||
ItemStack itemstack4 = playerinventory.getItem(button);
|
||||
|
||||
slot = (Slot) this.slots.get(slotIndex);
|
@@ -1,120 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Fri, 4 Mar 2022 12:45:03 -0800
|
||||
Subject: [PATCH] Add titleOverride to InventoryOpenEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
|
||||
this.nextContainerCounter();
|
||||
AbstractContainerMenu container = factory.createMenu(this.containerCounter, this.getInventory(), this);
|
||||
|
||||
+ Component title = null; // Paper - Add titleOverride to InventoryOpenEvent
|
||||
// CraftBukkit start - Inventory open hook
|
||||
if (container != null) {
|
||||
container.setTitle(factory.getDisplayName());
|
||||
|
||||
boolean cancelled = false;
|
||||
- container = CraftEventFactory.callInventoryOpenEvent(this, container, cancelled);
|
||||
+ // Paper start - Add titleOverride to InventoryOpenEvent
|
||||
+ final com.mojang.datafixers.util.Pair<net.kyori.adventure.text.Component, AbstractContainerMenu> result = CraftEventFactory.callInventoryOpenEventWithTitle(this, container, cancelled);
|
||||
+ container = result.getSecond();
|
||||
+ title = PaperAdventure.asVanilla(result.getFirst());
|
||||
+ // Paper end - Add titleOverride to InventoryOpenEvent
|
||||
if (container == null && !cancelled) { // Let pre-cancelled events fall through
|
||||
// SPIGOT-5263 - close chest if cancelled
|
||||
if (factory instanceof Container) {
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
|
||||
} else {
|
||||
// CraftBukkit start
|
||||
this.containerMenu = container;
|
||||
- if (!this.isImmobile()) this.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), container.getTitle())); // Paper - Prevent opening inventories when frozen
|
||||
+ if (!this.isImmobile()) this.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), Objects.requireNonNullElseGet(title, container::getTitle))); // Paper - Add titleOverride to InventoryOpenEvent
|
||||
// CraftBukkit end
|
||||
this.initMenu(container);
|
||||
return OptionalInt.of(this.containerCounter);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
@@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
Preconditions.checkArgument(windowType != null, "Unknown windowType");
|
||||
AbstractContainerMenu container = new CraftContainer(inventory, player, player.nextContainerCounter());
|
||||
|
||||
- container = CraftEventFactory.callInventoryOpenEvent(player, container);
|
||||
+ // Paper start - Add titleOverride to InventoryOpenEvent
|
||||
+ final com.mojang.datafixers.util.Pair<net.kyori.adventure.text.Component, AbstractContainerMenu> result = CraftEventFactory.callInventoryOpenEventWithTitle(player, container);
|
||||
+ container = result.getSecond();
|
||||
+ // Paper end - Add titleOverride to InventoryOpenEvent
|
||||
if (container == null) return;
|
||||
|
||||
//String title = container.getBukkitView().getTitle(); // Paper - comment
|
||||
net.kyori.adventure.text.Component adventure$title = container.getBukkitView().title(); // Paper
|
||||
if (adventure$title == null) adventure$title = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(container.getBukkitView().getTitle()); // Paper
|
||||
+ if (result.getFirst() != null) adventure$title = result.getFirst(); // Paper - Add titleOverride to InventoryOpenEvent
|
||||
|
||||
//player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, CraftChatMessage.fromString(title)[0])); // Paper - comment
|
||||
if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper - Prevent opening inventories when frozen
|
||||
@@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
}
|
||||
|
||||
// Trigger an INVENTORY_OPEN event
|
||||
- container = CraftEventFactory.callInventoryOpenEvent(player, container);
|
||||
+ // Paper start - Add titleOverride to InventoryOpenEvent
|
||||
+ final com.mojang.datafixers.util.Pair<net.kyori.adventure.text.Component, AbstractContainerMenu> result = CraftEventFactory.callInventoryOpenEventWithTitle(player, container);
|
||||
+ container = result.getSecond();
|
||||
+ // Paper end - Add titleOverride to InventoryOpenEvent
|
||||
if (container == null) {
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
//String title = inventory.getTitle(); // Paper - comment
|
||||
net.kyori.adventure.text.Component adventure$title = inventory.title(); // Paper
|
||||
if (adventure$title == null) adventure$title = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(inventory.getTitle()); // Paper
|
||||
+ if (result.getFirst() != null) adventure$title = result.getFirst(); // Paper - Add titleOverride to InventoryOpenEvent
|
||||
//player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, CraftChatMessage.fromString(title)[0])); // Paper - comment
|
||||
if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper - Prevent opening inventories when frozen
|
||||
player.containerMenu = container;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
}
|
||||
|
||||
public static AbstractContainerMenu callInventoryOpenEvent(ServerPlayer player, AbstractContainerMenu container) {
|
||||
- return CraftEventFactory.callInventoryOpenEvent(player, container, false);
|
||||
+ // Paper start - Add titleOverride to InventoryOpenEvent
|
||||
+ return callInventoryOpenEventWithTitle(player, container).getSecond();
|
||||
+ }
|
||||
+ public static com.mojang.datafixers.util.Pair<net.kyori.adventure.text.@org.jetbrains.annotations.Nullable Component, @org.jetbrains.annotations.Nullable AbstractContainerMenu> callInventoryOpenEventWithTitle(ServerPlayer player, AbstractContainerMenu container) {
|
||||
+ return CraftEventFactory.callInventoryOpenEventWithTitle(player, container, false);
|
||||
+ // Paper end - Add titleOverride to InventoryOpenEvent
|
||||
}
|
||||
|
||||
+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - use method that acknowledges title overrides
|
||||
public static AbstractContainerMenu callInventoryOpenEvent(ServerPlayer player, AbstractContainerMenu container, boolean cancelled) {
|
||||
+ // Paper start - Add titleOverride to InventoryOpenEvent
|
||||
+ return callInventoryOpenEventWithTitle(player, container, cancelled).getSecond();
|
||||
+ }
|
||||
+ public static com.mojang.datafixers.util.Pair<net.kyori.adventure.text.@org.jetbrains.annotations.Nullable Component, @org.jetbrains.annotations.Nullable AbstractContainerMenu> callInventoryOpenEventWithTitle(ServerPlayer player, AbstractContainerMenu container, boolean cancelled) {
|
||||
+ // Paper end - Add titleOverride to InventoryOpenEvent
|
||||
if (player.containerMenu != player.inventoryMenu) { // fire INVENTORY_CLOSE if one already open
|
||||
player.connection.handleContainerClose(new ServerboundContainerClosePacket(player.containerMenu.containerId), InventoryCloseEvent.Reason.OPEN_NEW); // Paper - Inventory close reason
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
|
||||
if (event.isCancelled()) {
|
||||
container.transferTo(player.containerMenu, craftPlayer);
|
||||
- return null;
|
||||
+ return com.mojang.datafixers.util.Pair.of(null, null); // Paper - Add titleOverride to InventoryOpenEvent
|
||||
}
|
||||
|
||||
- return container;
|
||||
+ return com.mojang.datafixers.util.Pair.of(event.titleOverride(), container); // Paper - Add titleOverride to InventoryOpenEvent
|
||||
}
|
||||
|
||||
public static ItemStack callPreCraftEvent(CraftingContainer matrix, Container resultInventory, ItemStack result, InventoryView lastCraftView, boolean isRepair) {
|
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: David Scandurra <david.scandurra@check24.de>
|
||||
Date: Wed, 25 Oct 2023 20:36:25 +0200
|
||||
Subject: [PATCH] Allow null itemstack for Player#sendEquipmentChange
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
@Override
|
||||
public void sendEquipmentChange(LivingEntity entity, EquipmentSlot slot, ItemStack item) {
|
||||
- this.sendEquipmentChange(entity, Map.of(slot, item));
|
||||
+ this.sendEquipmentChange(entity, java.util.Collections.singletonMap(slot, item)); // Paper - replace Map.of to allow null values
|
||||
}
|
||||
|
||||
@Override
|
@@ -1,31 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aeltumn <daniel@goossens.ch>
|
||||
Date: Mon, 28 Aug 2023 13:44:09 +0200
|
||||
Subject: [PATCH] Allow proper checking of empty item stacks
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftItemStack extends ItemStack {
|
||||
}
|
||||
// Paper end - MC Utils
|
||||
|
||||
+ // Paper start - override isEmpty to use vanilla's impl
|
||||
+ @Override
|
||||
+ public boolean isEmpty() {
|
||||
+ return handle == null || handle.isEmpty();
|
||||
+ }
|
||||
+ // Paper end - override isEmpty to use vanilla's impl
|
||||
+
|
||||
public static net.minecraft.world.item.ItemStack asNMSCopy(ItemStack original) {
|
||||
if (original instanceof CraftItemStack) {
|
||||
CraftItemStack stack = (CraftItemStack) original;
|
||||
return stack.handle == null ? net.minecraft.world.item.ItemStack.EMPTY : stack.handle.copy();
|
||||
}
|
||||
- if (original == null || original.getType() == Material.AIR) {
|
||||
+ if (original == null || original.isEmpty()) { // Paper - override isEmpty to use vanilla's impl; use isEmpty
|
||||
return net.minecraft.world.item.ItemStack.EMPTY;
|
||||
}
|
||||
|
@@ -1,39 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
|
||||
Date: Tue, 12 Jul 2022 18:01:14 +0200
|
||||
Subject: [PATCH] Allow trident custom damage
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java
|
||||
@@ -0,0 +0,0 @@ public class ThrownTrident extends AbstractArrow {
|
||||
|
||||
public ThrownTrident(EntityType<? extends ThrownTrident> type, Level world) {
|
||||
super(type, world);
|
||||
+ this.setBaseDamage(net.minecraft.world.item.TridentItem.BASE_DAMAGE); // Paper - Allow trident custom damage
|
||||
}
|
||||
|
||||
public ThrownTrident(Level world, LivingEntity owner, ItemStack stack) {
|
||||
super(EntityType.TRIDENT, owner, world, stack, (ItemStack) null);
|
||||
+ this.setBaseDamage(net.minecraft.world.item.TridentItem.BASE_DAMAGE); // Paper - Allow trident custom damage
|
||||
this.entityData.set(ThrownTrident.ID_LOYALTY, this.getLoyaltyFromItem(stack));
|
||||
this.entityData.set(ThrownTrident.ID_FOIL, stack.hasFoil());
|
||||
}
|
||||
|
||||
public ThrownTrident(Level world, double x, double y, double z, ItemStack stack) {
|
||||
super(EntityType.TRIDENT, x, y, z, world, stack, stack);
|
||||
+ this.setBaseDamage(net.minecraft.world.item.TridentItem.BASE_DAMAGE); // Paper - Allow trident custom damage
|
||||
this.entityData.set(ThrownTrident.ID_LOYALTY, this.getLoyaltyFromItem(stack));
|
||||
this.entityData.set(ThrownTrident.ID_FOIL, stack.hasFoil());
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class ThrownTrident extends AbstractArrow {
|
||||
@Override
|
||||
protected void onHitEntity(EntityHitResult entityHitResult) {
|
||||
Entity entity = entityHitResult.getEntity();
|
||||
- float f = 8.0F;
|
||||
+ float f = (float) this.getBaseDamage(); // Paper - Allow trident custom damage
|
||||
Entity entity1 = this.getOwner();
|
||||
DamageSource damagesource = this.damageSources().trident(this, (Entity) (entity1 == null ? this : entity1));
|
||||
Level world = this.level();
|
@@ -1,20 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: booky10 <boooky10@gmail.com>
|
||||
Date: Sun, 29 Oct 2023 02:36:10 +0100
|
||||
Subject: [PATCH] Broadcast take item packets with collector as source
|
||||
|
||||
This fixes players (which can't view the collector) seeing item pickups with themselves as the target.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
|
||||
public void take(Entity item, int count) {
|
||||
if (!item.isRemoved() && !this.level().isClientSide && (item instanceof ItemEntity || item instanceof AbstractArrow || item instanceof ExperienceOrb)) {
|
||||
- ((ServerLevel) this.level()).getChunkSource().broadcast(item, new ClientboundTakeItemEntityPacket(item.getId(), this.getId(), count));
|
||||
+ ((ServerLevel) this.level()).getChunkSource().broadcastAndSend(this, new ClientboundTakeItemEntityPacket(item.getId(), this.getId(), count)); // Paper - broadcast with collector as source
|
||||
}
|
||||
|
||||
}
|
@@ -1,27 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Warrior <50800980+Warriorrrr@users.noreply.github.com>
|
||||
Date: Wed, 13 Sep 2023 05:46:10 +0200
|
||||
Subject: [PATCH] Call BlockRedstoneEvents for lecterns
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/LecternBlock.java b/src/main/java/net/minecraft/world/level/block/LecternBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/LecternBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/LecternBlock.java
|
||||
@@ -0,0 +0,0 @@ public class LecternBlock extends BaseEntityBlock {
|
||||
}
|
||||
|
||||
private static void changePowered(Level world, BlockPos pos, BlockState state, boolean powered) {
|
||||
+ // Paper start - call BlockRedstoneEvents for lecterns
|
||||
+ final int currentRedstoneLevel = state.getValue(LecternBlock.POWERED) ? 15 : 0, targetRedstoneLevel = powered ? 15 : 0;
|
||||
+ if (currentRedstoneLevel != targetRedstoneLevel) {
|
||||
+ final org.bukkit.event.block.BlockRedstoneEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(world, pos, currentRedstoneLevel, targetRedstoneLevel);
|
||||
+
|
||||
+ if (event.getNewCurrent() != targetRedstoneLevel) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - call BlockRedstoneEvents for lecterns
|
||||
world.setBlock(pos, (BlockState) state.setValue(LecternBlock.POWERED, powered), 3);
|
||||
LecternBlock.updateBelow(world, pos, state);
|
||||
}
|
@@ -1,28 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
|
||||
Date: Tue, 27 Jun 2023 13:26:06 +0200
|
||||
Subject: [PATCH] Configure sniffer egg hatch time
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java b/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java
|
||||
@@ -0,0 +0,0 @@ public class SnifferEggBlock extends Block {
|
||||
|
||||
// Paper start - Call BlockFadeEvent
|
||||
private void rescheduleTick(ServerLevel world, BlockPos pos) {
|
||||
- int baseDelay = hatchBoost(world, pos) ? BOOSTED_HATCH_TIME_TICKS : REGULAR_HATCH_TIME_TICKS;
|
||||
+ int baseDelay = hatchBoost(world, pos) ? world.paperConfig().entities.sniffer.boostedHatchTime.or(BOOSTED_HATCH_TIME_TICKS) : world.paperConfig().entities.sniffer.hatchTime.or(REGULAR_HATCH_TIME_TICKS); // Paper - Configure sniffer egg hatch time
|
||||
world.scheduleTick(pos, this, (baseDelay / 3) + world.random.nextInt(RANDOM_HATCH_OFFSET_TICKS));
|
||||
// reschedule to avoid being stuck here and behave like the other calls (see #onPlace)
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class SnifferEggBlock extends Block {
|
||||
world.levelEvent(3009, pos, 0);
|
||||
}
|
||||
|
||||
- int i = bl ? 12000 : 24000;
|
||||
+ int i = bl ? world.paperConfig().entities.sniffer.boostedHatchTime.or(BOOSTED_HATCH_TIME_TICKS) : world.paperConfig().entities.sniffer.hatchTime.or(REGULAR_HATCH_TIME_TICKS); // Paper
|
||||
int j = i / 3;
|
||||
world.gameEvent(GameEvent.BLOCK_PLACE, pos, GameEvent.Context.of(state));
|
||||
world.scheduleTick(pos, this, j + world.random.nextInt(300));
|
@@ -1,75 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martijn Muijsers <martijnmuijsers@live.nl>
|
||||
Date: Tue, 15 Aug 2023 21:04:55 +0200
|
||||
Subject: [PATCH] Do crystal-portal proximity check before entity lookup
|
||||
|
||||
This adds a very cheap distance check when an end crystal is placed.
|
||||
|
||||
Attempting to respawn the dragon, which involves looking up the end crystal
|
||||
entities near the portal, every time an end crystal is placed, can be slow on
|
||||
some servers that have players placing end crystals as a style of combat.
|
||||
|
||||
The very cheap distance check prevents running the entity lookup every time.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/EndCrystalItem.java b/src/main/java/net/minecraft/world/item/EndCrystalItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/EndCrystalItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/EndCrystalItem.java
|
||||
@@ -0,0 +0,0 @@ public class EndCrystalItem extends Item {
|
||||
if (!iblockdata.is(Blocks.OBSIDIAN) && !iblockdata.is(Blocks.BEDROCK)) {
|
||||
return InteractionResult.FAIL;
|
||||
} else {
|
||||
- BlockPos blockposition1 = blockposition.above();
|
||||
+ BlockPos blockposition1 = blockposition.above(); final BlockPos aboveBlockPosition = blockposition1; // Paper - OBFHELPER
|
||||
|
||||
if (!world.isEmptyBlock(blockposition1)) {
|
||||
return InteractionResult.FAIL;
|
||||
@@ -0,0 +0,0 @@ public class EndCrystalItem extends Item {
|
||||
EndDragonFight enderdragonbattle = ((ServerLevel) world).getDragonFight();
|
||||
|
||||
if (enderdragonbattle != null) {
|
||||
- enderdragonbattle.tryRespawn();
|
||||
+ enderdragonbattle.tryRespawn(aboveBlockPosition); // Paper - Perf: Do crystal-portal proximity check before entity lookup
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
@@ -0,0 +0,0 @@ public class EndDragonFight {
|
||||
}
|
||||
|
||||
public boolean tryRespawn() { // CraftBukkit - return boolean
|
||||
+ // Paper start - Perf: Do crystal-portal proximity check before entity lookup
|
||||
+ return this.tryRespawn(null);
|
||||
+ }
|
||||
+
|
||||
+ public boolean tryRespawn(@Nullable BlockPos placedEndCrystalPos) { // placedEndCrystalPos is null if the tryRespawn() call was not caused by a placed end crystal
|
||||
+ // Paper end - Perf: Do crystal-portal proximity check before entity lookup
|
||||
if (this.dragonKilled && this.respawnStage == null) {
|
||||
BlockPos blockposition = this.portalLocation;
|
||||
|
||||
@@ -0,0 +0,0 @@ public class EndDragonFight {
|
||||
blockposition = this.portalLocation;
|
||||
}
|
||||
|
||||
+ // Paper start - Perf: Do crystal-portal proximity check before entity lookup
|
||||
+ if (placedEndCrystalPos != null) {
|
||||
+ // The end crystal must be 0 or 1 higher than the portal origin
|
||||
+ int dy = placedEndCrystalPos.getY() - blockposition.getY();
|
||||
+ if (dy != 0 && dy != 1) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // The end crystal must be within a distance of 1 in one planar direction, and 3 in the other
|
||||
+ int dx = placedEndCrystalPos.getX() - blockposition.getX();
|
||||
+ int dz = placedEndCrystalPos.getZ() - blockposition.getZ();
|
||||
+ if (!((dx >= -1 && dx <= 1 && dz >= -3 && dz <= 3) || (dx >= -3 && dx <= 3 && dz >= -1 && dz <= 1))) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Perf: Do crystal-portal proximity check before entity lookup
|
||||
+
|
||||
List<EndCrystal> list = Lists.newArrayList();
|
||||
BlockPos blockposition1 = blockposition.above(1);
|
||||
Iterator iterator = Direction.Plane.HORIZONTAL.iterator();
|
@@ -1,50 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Sun, 18 Jun 2023 23:04:46 -0700
|
||||
Subject: [PATCH] Do not read tile entities in chunks that are positioned
|
||||
outside of the chunk
|
||||
|
||||
The tile entities are not accessible and so should not be loaded.
|
||||
This can happen as a result of users moving regionfiles around,
|
||||
which would cause a crash on Folia but would appear to function
|
||||
fine on Paper.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
||||
for (int k1 = 0; k1 < nbttaglist3.size(); ++k1) {
|
||||
CompoundTag nbttagcompound4 = nbttaglist3.getCompound(k1);
|
||||
|
||||
+ // Paper start - do not read tile entities positioned outside the chunk
|
||||
+ BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound4);
|
||||
+ if ((blockposition.getX() >> 4) != chunkPos.x || (blockposition.getZ() >> 4) != chunkPos.z) {
|
||||
+ LOGGER.warn("Tile entity serialized in chunk " + chunkPos + " in world '" + world.getWorld().getName() + "' positioned at " + blockposition + " is located outside of the chunk");
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Paper end - do not read tile entities positioned outside the chunk
|
||||
((ChunkAccess) object1).setBlockEntityNbt(nbttagcompound4);
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
||||
CompoundTag nbttagcompound1 = nbttaglist1.getCompound(i);
|
||||
boolean flag = nbttagcompound1.getBoolean("keepPacked");
|
||||
|
||||
+ // Paper start - do not read tile entities positioned outside the chunk
|
||||
+ BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound1); // moved up
|
||||
+ ChunkPos chunkPos = chunk.getPos();
|
||||
+ if ((blockposition.getX() >> 4) != chunkPos.x || (blockposition.getZ() >> 4) != chunkPos.z) {
|
||||
+ LOGGER.warn("Tile entity serialized in chunk " + chunkPos + " in world '" + world.getWorld().getName() + "' positioned at " + blockposition + " is located outside of the chunk");
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Paper end - do not read tile entities positioned outside the chunk
|
||||
+
|
||||
if (flag) {
|
||||
chunk.setBlockEntityNbt(nbttagcompound1);
|
||||
} else {
|
||||
- BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound1);
|
||||
+ // Paper - do not read tile entities positioned outside the chunk; move up
|
||||
BlockEntity tileentity = BlockEntity.loadStatic(blockposition, chunk.getBlockState(blockposition), nbttagcompound1, world.registryAccess());
|
||||
|
||||
if (tileentity != null) {
|
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brokkonaut <hannos17@gmx.de>
|
||||
Date: Sat, 21 Oct 2023 20:52:57 +0100
|
||||
Subject: [PATCH] Don't check if we can see non-visible entities
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
// Paper end - Configurable entity tracking range by Y
|
||||
|
||||
// CraftBukkit start - respect vanish API
|
||||
- if (!player.getBukkitEntity().canSee(this.entity.getBukkitEntity())) {
|
||||
+ if (flag && !player.getBukkitEntity().canSee(this.entity.getBukkitEntity())) { // Paper - only consider hits
|
||||
flag = false;
|
||||
}
|
||||
// CraftBukkit end
|
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ 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));
|
||||
@@ -0,0 +0,0 @@ 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) {
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
flag = true;
|
||||
mobeffect.onEffectAdded(this);
|
||||
// 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
@@ -0,0 +0,0 @@ public class Spider extends Monster {
|
||||
Holder<MobEffect> holder = entityspider_groupdataspider.effect;
|
||||
|
||||
if (holder != null) {
|
||||
- this.addEffect(new MobEffectInstance(holder, -1), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.SPIDER_SPAWN); // CraftBukkit
|
||||
+ this.addEffect(new MobEffectInstance(holder, -1), null, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.SPIDER_SPAWN, world instanceof net.minecraft.server.level.ServerLevel); // CraftBukkit
|
||||
}
|
||||
}
|
||||
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/TransformerGeneratorAccess.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/TransformerGeneratorAccess.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
@@ -0,0 +0,0 @@ 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()) {
|
||||
EnchantmentHelper.onHitBlock(this.level, this.player.getMainHandItem(), this.player, this.player, EquipmentSlot.MAINHAND, Vec3.atCenterOf(pos), iblockdata, (item) -> {
|
||||
this.player.onEquippedItemBroken(item, EquipmentSlot.MAINHAND);
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
}
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
@@ -0,0 +0,0 @@ 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.JIGSAW) || 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/BucketItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/BucketItem.java
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
@@ -0,0 +0,0 @@ public final class ItemStack implements DataComponentHolder {
|
||||
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,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tamion <70228790+notTamion@users.noreply.github.com>
|
||||
Date: Sat, 4 Nov 2023 23:57:05 +0100
|
||||
Subject: [PATCH] Expand LingeringPotion API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
|
||||
@@ -0,0 +0,0 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
|
||||
boolean noEffects = potioncontents.hasEffects(); // Paper - Fix potions splash events
|
||||
// CraftBukkit start
|
||||
org.bukkit.event.entity.LingeringPotionSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callLingeringPotionSplashEvent(this, position, entityareaeffectcloud);
|
||||
- if (!(event.isCancelled() || entityareaeffectcloud.isRemoved() || (noEffects && !entityareaeffectcloud.potionContents.hasEffects()))) { // Paper - don't spawn area effect cloud if the effects were empty and not changed during the event handling
|
||||
+ if (!(event.isCancelled() || entityareaeffectcloud.isRemoved() || (!event.allowsEmptyCreation() && (noEffects && !entityareaeffectcloud.potionContents.hasEffects())))) { // Paper - don't spawn area effect cloud if the effects were empty and not changed during the event handling
|
||||
this.level().addFreshEntity(entityareaeffectcloud);
|
||||
} else {
|
||||
entityareaeffectcloud.discard(null); // CraftBukkit - add Bukkit remove cause
|
@@ -1,32 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: The456gamer <the456gamer@the456gamer.dev>
|
||||
Date: Mon, 21 Aug 2023 14:13:42 +0100
|
||||
Subject: [PATCH] Expose hand in BlockCanBuildEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/BlockItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/BlockItem.java
|
||||
@@ -0,0 +0,0 @@ public class BlockItem extends Item {
|
||||
boolean defaultReturn = (!this.mustSurvive() || state.canSurvive(context.getLevel(), context.getClickedPos())) && world.checkEntityCollision(state, entityhuman, voxelshapecollision, context.getClickedPos(), true); // Paper - Cancel hit for vanished players
|
||||
org.bukkit.entity.Player player = (context.getPlayer() instanceof ServerPlayer) ? (org.bukkit.entity.Player) context.getPlayer().getBukkitEntity() : null;
|
||||
|
||||
- BlockCanBuildEvent event = new BlockCanBuildEvent(CraftBlock.at(context.getLevel(), context.getClickedPos()), player, CraftBlockData.fromData(state), defaultReturn);
|
||||
+ BlockCanBuildEvent event = new BlockCanBuildEvent(CraftBlock.at(context.getLevel(), context.getClickedPos()), player, CraftBlockData.fromData(state), defaultReturn, org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(context.getHand())); // Paper - Expose hand in BlockCanBuildEvent
|
||||
context.getLevel().getCraftServer().getPluginManager().callEvent(event);
|
||||
|
||||
return event.isBuildable();
|
||||
diff --git a/src/main/java/net/minecraft/world/item/StandingAndWallBlockItem.java b/src/main/java/net/minecraft/world/item/StandingAndWallBlockItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/StandingAndWallBlockItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/StandingAndWallBlockItem.java
|
||||
@@ -0,0 +0,0 @@ public class StandingAndWallBlockItem extends BlockItem {
|
||||
boolean defaultReturn = world.isUnobstructed(iblockdata1, blockposition, CollisionContext.empty());
|
||||
org.bukkit.entity.Player player = (context.getPlayer() instanceof ServerPlayer) ? (org.bukkit.entity.Player) context.getPlayer().getBukkitEntity() : null;
|
||||
|
||||
- BlockCanBuildEvent event = new BlockCanBuildEvent(CraftBlock.at(world, blockposition), player, CraftBlockData.fromData(iblockdata1), defaultReturn);
|
||||
+ BlockCanBuildEvent event = new BlockCanBuildEvent(CraftBlock.at(world, blockposition), player, CraftBlockData.fromData(iblockdata1), defaultReturn, org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(context.getHand())); // Paper - Expose hand in BlockCanBuildEvent
|
||||
context.getLevel().getCraftServer().getPluginManager().callEvent(event);
|
||||
|
||||
return (event.isBuildable()) ? iblockdata1 : null;
|
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
@@ -0,0 +0,0 @@ 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().getKey().equals(modifier.getKey()), "Cannot register AttributeModifier. Modifier is already applied! %s", modifier);
|
||||
+ Preconditions.checkArgument(!(entry.getValue().getKey().equals(modifier.getKey()) && entry.getKey() == attribute), "Cannot register AttributeModifier. Modifier is already applied! %s", modifier); // Paper - attribute modifiers with same namespaced key but on different attributes are fine
|
||||
}
|
||||
return this.attributeModifiers.put(attribute, modifier);
|
||||
}
|
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sat, 23 Sep 2023 22:07:15 -0700
|
||||
Subject: [PATCH] Fix NPE in AdvancementProgress#getDateAwarded
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementProgress.java b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementProgress.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementProgress.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementProgress.java
|
||||
@@ -0,0 +0,0 @@ public class CraftAdvancementProgress implements AdvancementProgress {
|
||||
@Override
|
||||
public Date getDateAwarded(String criteria) {
|
||||
CriterionProgress criterion = this.handle.getCriterion(criteria);
|
||||
- return (criterion == null) ? null : Date.from(criterion.getObtained());
|
||||
+ return (criterion == null) ? null : criterion.getObtained() == null ? null : Date.from(criterion.getObtained()); // Paper - fix NPE if criterion isn't obtained
|
||||
}
|
||||
|
||||
@Override
|
@@ -1,43 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
|
||||
Date: Fri, 20 Oct 2023 19:50:22 +0200
|
||||
Subject: [PATCH] Fix NPE in SculkBloomEvent world access
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi
|
||||
public SculkCatalystBlockEntity(BlockPos pos, BlockState state) {
|
||||
super(BlockEntityType.SCULK_CATALYST, pos, state);
|
||||
this.catalystListener = new SculkCatalystBlockEntity.CatalystListener(state, new BlockPositionSource(pos));
|
||||
- this.catalystListener.level = this.level; // CraftBukkit
|
||||
}
|
||||
|
||||
+ // Paper start - Fix NPE in SculkBloomEvent world access
|
||||
+ @Override
|
||||
+ public void setLevel(Level level) {
|
||||
+ super.setLevel(level);
|
||||
+ this.catalystListener.sculkSpreader.level = level;
|
||||
+ }
|
||||
+ // Paper end - Fix NPE in SculkBloomEvent world access
|
||||
+
|
||||
public static void serverTick(Level world, BlockPos pos, BlockState state, SculkCatalystBlockEntity blockEntity) {
|
||||
org.bukkit.craftbukkit.event.CraftEventFactory.sourceBlockOverride = blockEntity.getBlockPos(); // CraftBukkit - SPIGOT-7068: Add source block override, not the most elegant way but better than passing down a BlockPosition up to five methods deep.
|
||||
blockEntity.catalystListener.getSculkSpreader().updateCursors(world, pos, world.getRandom(), true);
|
||||
@@ -0,0 +0,0 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi
|
||||
final SculkSpreader sculkSpreader;
|
||||
private final BlockState blockState;
|
||||
private final PositionSource positionSource;
|
||||
- private Level level; // CraftBukkit
|
||||
|
||||
public CatalystListener(BlockState state, PositionSource positionSource) {
|
||||
this.blockState = state;
|
||||
this.positionSource = positionSource;
|
||||
this.sculkSpreader = SculkSpreader.createLevelSpreader();
|
||||
- this.sculkSpreader.level = this.level; // CraftBukkit
|
||||
+ // this.sculkSpreader.level = this.level; // CraftBukkit // Paper - Fix NPE in SculkBloomEvent world access
|
||||
}
|
||||
|
||||
@Override
|
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/commands/TeleportCommand.java
|
||||
+++ b/src/main/java/net/minecraft/server/commands/TeleportCommand.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ 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/TamableAnimal.java b/src/main/java/net/minecraft/world/entity/TamableAnimal.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/TamableAnimal.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/TamableAnimal.java
|
||||
@@ -0,0 +0,0 @@ public abstract class TamableAnimal extends Animal implements OwnableEntity {
|
||||
} else {
|
||||
// CraftBukkit start
|
||||
EntityTeleportEvent event = CraftEventFactory.callEntityTeleportEvent(this, (double) x + 0.5D, (double) y, (double) z + 0.5D);
|
||||
- if (event.isCancelled()) {
|
||||
+ if (event.isCancelled() || event.getTo() == null) { // Paper - prevent NP on null event to location
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Shulker.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Shulker.java
|
||||
@@ -0,0 +0,0 @@ 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,43 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: LemonCaramel <admin@caramel.moe>
|
||||
Date: Sun, 24 Sep 2023 20:19:44 +0900
|
||||
Subject: [PATCH] Fix UnsafeValues#loadAdvancement
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
ResourceLocation minecraftkey = CraftNamespacedKey.toMinecraft(key);
|
||||
|
||||
JsonElement jsonelement = ServerAdvancementManager.GSON.fromJson(advancement, JsonElement.class);
|
||||
- net.minecraft.advancements.Advancement nms = net.minecraft.advancements.Advancement.CODEC.parse(JsonOps.INSTANCE, jsonelement).getOrThrow(JsonParseException::new);
|
||||
+ final net.minecraft.resources.RegistryOps<JsonElement> ops = CraftRegistry.getMinecraftRegistry().createSerializationContext(JsonOps.INSTANCE); // Paper - use RegistryOps
|
||||
+ final net.minecraft.advancements.Advancement nms = net.minecraft.advancements.Advancement.CODEC.parse(ops, jsonelement).getOrThrow(JsonParseException::new); // Paper - use RegistryOps
|
||||
if (nms != null) {
|
||||
- MinecraftServer.getServer().getAdvancements().advancements.put(minecraftkey, new AdvancementHolder(minecraftkey, nms));
|
||||
+ // Paper start - Fix throw UnsupportedOperationException
|
||||
+ //MinecraftServer.getServer().getAdvancements().advancements.put(minecraftkey, new AdvancementHolder(minecraftkey, nms));
|
||||
+ final com.google.common.collect.ImmutableMap.Builder<ResourceLocation, AdvancementHolder> mapBuilder = com.google.common.collect.ImmutableMap.builder();
|
||||
+ mapBuilder.putAll(MinecraftServer.getServer().getAdvancements().advancements);
|
||||
+
|
||||
+ final AdvancementHolder holder = new AdvancementHolder(minecraftkey, nms);
|
||||
+ mapBuilder.put(minecraftkey, holder);
|
||||
+
|
||||
+ MinecraftServer.getServer().getAdvancements().advancements = mapBuilder.build();
|
||||
+ final net.minecraft.advancements.AdvancementTree tree = MinecraftServer.getServer().getAdvancements().tree();
|
||||
+ tree.addAll(java.util.List.of(holder));
|
||||
+
|
||||
+ // recalculate advancement position
|
||||
+ final net.minecraft.advancements.AdvancementNode node = tree.get(minecraftkey);
|
||||
+ if (node != null) {
|
||||
+ final net.minecraft.advancements.AdvancementNode root = node.root();
|
||||
+ if (root.holder().value().display().isPresent()) {
|
||||
+ net.minecraft.advancements.TreeNodePosition.run(root);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Fix throw UnsupportedOperationException
|
||||
Advancement bukkit = Bukkit.getAdvancement(key);
|
||||
|
||||
if (bukkit != null) {
|
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -0,0 +0,0 @@ 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,43 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Warrior <50800980+Warriorrrr@users.noreply.github.com>
|
||||
Date: Sun, 24 Sep 2023 18:35:28 +0200
|
||||
Subject: [PATCH] Fix missing map initialize event call
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.level.storage.DimensionDataStorage readSavedData(Ljava/util/function/Function;Lnet/minecraft/util/datafix/DataFixTypes;Ljava/lang/String;)Lnet/minecraft/world/level/saveddata/SavedData;
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
@Nullable
|
||||
@Override
|
||||
public MapItemSavedData getMapData(MapId id) {
|
||||
- // CraftBukkit start
|
||||
- MapItemSavedData worldmap = (MapItemSavedData) this.getServer().overworld().getDataStorage().get(MapItemSavedData.factory(), id.key());
|
||||
- if (worldmap != null) {
|
||||
- worldmap.id = id;
|
||||
+ // Paper start - Call missing map initialize event and set id
|
||||
+ final DimensionDataStorage storage = this.getServer().overworld().getDataStorage();
|
||||
+
|
||||
+ final net.minecraft.world.level.saveddata.SavedData existing = storage.cache.get(id.key());
|
||||
+ if (existing == null && !storage.cache.containsKey(id.key())) {
|
||||
+ final MapItemSavedData worldmap = (MapItemSavedData) this.getServer().overworld().getDataStorage().get(MapItemSavedData.factory(), id.key());
|
||||
+ storage.cache.put(id.key(), worldmap);
|
||||
+ if (worldmap != null) {
|
||||
+ worldmap.id = id;
|
||||
+ new MapInitializeEvent(worldmap.mapView).callEvent();
|
||||
+ return worldmap;
|
||||
+ }
|
||||
+ } else if (existing instanceof MapItemSavedData mapItemSavedData) {
|
||||
+ mapItemSavedData.id = id;
|
||||
}
|
||||
- return worldmap;
|
||||
- // CraftBukkit end
|
||||
+
|
||||
+ return existing instanceof MapItemSavedData data ? data : null;
|
||||
+ // Paper end - Call missing map initialize event and set id
|
||||
}
|
||||
|
||||
@Override
|
@@ -1,27 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Tue, 8 Aug 2023 17:29:33 -0700
|
||||
Subject: [PATCH] Fix race condition on UpgradeData.BlockFixers class init
|
||||
|
||||
The CHUNKY_FIXERS field is modified during the constructors
|
||||
of the BlockFixers, but the code that uses CHUNKY_FIXERS does
|
||||
not properly ensure that BlockFixers has been initialised before
|
||||
using it, leading to a possible race condition where instances of
|
||||
BlockFixers are accessed before they have initialised correctly.
|
||||
|
||||
We can force the class to initialise fully before accessing the
|
||||
field by calling any method on the class, and for convenience
|
||||
we use values().
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/UpgradeData.java b/src/main/java/net/minecraft/world/level/chunk/UpgradeData.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/UpgradeData.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/UpgradeData.java
|
||||
@@ -0,0 +0,0 @@ public class UpgradeData {
|
||||
Fluid fluid = tick.type() == Fluids.EMPTY ? level.getFluidState(tick.pos()).getType() : tick.type();
|
||||
level.scheduleTick(tick.pos(), fluid, tick.delay(), tick.priority());
|
||||
});
|
||||
+ UpgradeData.BlockFixers.values(); // Paper - force the class init so that we don't access CHUNKY_FIXERS before all BlockFixers are initialised
|
||||
CHUNKY_FIXERS.forEach(logic -> logic.processChunk(level));
|
||||
}
|
||||
|
@@ -1,133 +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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Animal.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Animal.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ 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();
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Panda.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Panda.java
|
||||
@@ -0,0 +0,0 @@ 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/armadillo/Armadillo.java b/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java
|
||||
@@ -0,0 +0,0 @@ public class Armadillo extends Animal {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public void setInLove(@Nullable Player player) {
|
||||
- super.setInLove(player);
|
||||
+ public void setInLove(@Nullable Player player, @Nullable ItemStack breedItemCopy) { // Paper
|
||||
+ super.setInLove(player, breedItemCopy); // Paper
|
||||
this.makeSound(SoundEvents.ARMADILLO_EAT);
|
||||
}
|
||||
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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,113 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
|
||||
Date: Thu, 31 Aug 2023 17:32:48 +0200
|
||||
Subject: [PATCH] Fix silent equipment change for mobs
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
||||
|
||||
@Override
|
||||
public void setItemSlot(EquipmentSlot slot, ItemStack stack) {
|
||||
+ // Paper start - Fix silent equipment change
|
||||
+ setItemSlot(slot, stack, false);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setItemSlot(EquipmentSlot slot, ItemStack stack, boolean silent) {
|
||||
+ // Paper end - Fix silent equipment change
|
||||
this.verifyEquippedItem(stack);
|
||||
switch (slot.getType()) {
|
||||
case HAND:
|
||||
- this.onEquipItem(slot, (ItemStack) this.handItems.set(slot.getIndex(), stack), stack);
|
||||
+ this.onEquipItem(slot, (ItemStack) this.handItems.set(slot.getIndex(), stack), stack, silent); // Paper - Fix silent equipment change
|
||||
break;
|
||||
case HUMANOID_ARMOR:
|
||||
- this.onEquipItem(slot, (ItemStack) this.armorItems.set(slot.getIndex(), stack), stack);
|
||||
+ this.onEquipItem(slot, (ItemStack) this.armorItems.set(slot.getIndex(), stack), stack, silent); // Paper - Fix silent equipment change
|
||||
break;
|
||||
case ANIMAL_ARMOR:
|
||||
ItemStack itemstack1 = this.bodyArmorItem;
|
||||
|
||||
this.bodyArmorItem = stack;
|
||||
- this.onEquipItem(slot, itemstack1, stack);
|
||||
+ this.onEquipItem(slot, itemstack1, stack, silent); // Paper - Fix silent equipment change
|
||||
}
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
|
||||
// Paper end - shouldBurnInDay API
|
||||
|
||||
@Override
|
||||
- public void setItemSlot(EquipmentSlot slot, ItemStack stack) {
|
||||
- super.setItemSlot(slot, stack);
|
||||
+ public void setItemSlot(EquipmentSlot slot, ItemStack stack, boolean silent) { // Paper - Fix silent equipment change
|
||||
+ super.setItemSlot(slot, stack, silent); // Paper - Fix silent equipment change
|
||||
if (!this.level().isClientSide) {
|
||||
this.reassessWeaponGoal();
|
||||
}
|
||||
diff --git a/src/test/java/io/papermc/paper/entity/EntitySetItemSlotSilentOverrideTest.java b/src/test/java/io/papermc/paper/entity/EntitySetItemSlotSilentOverrideTest.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/io/papermc/paper/entity/EntitySetItemSlotSilentOverrideTest.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.entity;
|
||||
+
|
||||
+import io.github.classgraph.ClassGraph;
|
||||
+import io.github.classgraph.ClassInfo;
|
||||
+import io.github.classgraph.MethodInfo;
|
||||
+import io.github.classgraph.MethodInfoList;
|
||||
+import io.github.classgraph.MethodParameterInfo;
|
||||
+import io.github.classgraph.ScanResult;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.List;
|
||||
+import java.util.stream.Stream;
|
||||
+import org.bukkit.support.environment.Normal;
|
||||
+import org.junit.jupiter.params.ParameterizedTest;
|
||||
+import org.junit.jupiter.params.provider.MethodSource;
|
||||
+
|
||||
+import static org.junit.jupiter.api.Assertions.fail;
|
||||
+
|
||||
+@Normal
|
||||
+public class EntitySetItemSlotSilentOverrideTest {
|
||||
+
|
||||
+ public static Stream<ClassInfo> parameters() {
|
||||
+ final List<ClassInfo> classInfo = new ArrayList<>();
|
||||
+ try (ScanResult scanResult = new ClassGraph()
|
||||
+ .enableClassInfo()
|
||||
+ .enableMethodInfo()
|
||||
+ .whitelistPackages("net.minecraft")
|
||||
+ .scan()
|
||||
+ ) {
|
||||
+ for (final ClassInfo subclass : scanResult.getSubclasses("net.minecraft.world.entity.LivingEntity")) {
|
||||
+ final MethodInfoList setItemSlot = subclass.getDeclaredMethodInfo("setItemSlot");
|
||||
+ if (!setItemSlot.isEmpty()) {
|
||||
+ classInfo.add(subclass);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return classInfo.stream();
|
||||
+ }
|
||||
+
|
||||
+ @ParameterizedTest
|
||||
+ @MethodSource("parameters")
|
||||
+ public void checkSetItemSlotSilentOverrides(ClassInfo overridesSetItemSlot) {
|
||||
+ final MethodInfoList setItemSlot = overridesSetItemSlot.getDeclaredMethodInfo("setItemSlot");
|
||||
+ for (final MethodInfo methodInfo : setItemSlot) {
|
||||
+ for (final MethodParameterInfo methodParameterInfo : methodInfo.getParameterInfo()) {
|
||||
+ if ("boolean".equals(methodParameterInfo.getTypeDescriptor().toStringWithSimpleNames())) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ fail(overridesSetItemSlot.getName() + " needs to override setItemSlot with the boolean silent parameter as well");
|
||||
+ }
|
||||
+}
|
@@ -1,129 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Wed, 23 Aug 2023 13:22:09 -0700
|
||||
Subject: [PATCH] Fix slot desync
|
||||
|
||||
General patch fixing slot desyncs between the server and client that
|
||||
result from cancelled events/paper introduced logic.
|
||||
|
||||
Co-authored-by: Minecrell <minecrell@minecrell.net>
|
||||
Co-authored-by: Newwind <support@newwindserver.com>
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
|
||||
|
||||
// Use method to resend items in hands in case of client desync, because the item use got cancelled.
|
||||
// For example, when cancelling the leash event
|
||||
+ @Deprecated // Paper - this shouldn't be used, use the regular sendAllDataToRemote call to resync all
|
||||
public void resendItemInHands() {
|
||||
this.containerMenu.findSlot(this.getInventory(), this.getInventory().selected).ifPresent(s -> {
|
||||
this.containerSynchronizer.sendSlotChange(this.containerMenu, s, this.getMainHandItem());
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
// Refresh the current entity metadata
|
||||
entity.refreshEntityData(ServerGamePacketListenerImpl.this.player);
|
||||
// SPIGOT-7136 - Allays
|
||||
- if (entity instanceof Allay) {
|
||||
+ if (entity instanceof Allay || entity instanceof net.minecraft.world.entity.animal.horse.AbstractHorse) { // Paper - Fix horse armor desync
|
||||
ServerGamePacketListenerImpl.this.send(new ClientboundSetEquipmentPacket(entity.getId(), Arrays.stream(net.minecraft.world.entity.EquipmentSlot.values()).map((slot) -> Pair.of(slot, ((LivingEntity) entity).getItemBySlot(slot).copy())).collect(Collectors.toList())));
|
||||
- ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote();
|
||||
}
|
||||
+
|
||||
+ ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote(); // Paper - fix slot desync - always refresh player inventory
|
||||
}
|
||||
|
||||
if (event.isCancelled()) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
if (!this.level().isClientSide()) {
|
||||
// CraftBukkit start - fire PlayerLeashEntityEvent
|
||||
if (CraftEventFactory.callPlayerLeashEntityEvent(this, player, player, hand).isCancelled()) {
|
||||
- ((ServerPlayer) player).resendItemInHands(); // SPIGOT-7615: Resend to fix client desync with used item
|
||||
+ // ((ServerPlayer) player).resendItemInHands(); // SPIGOT-7615: Resend to fix client desync with used item // Paper - Fix inventory desync
|
||||
((ServerPlayer) player).connection.send(new ClientboundSetEntityLinkPacket(this, leashable.getLeashHolder()));
|
||||
+ player.containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Cow.java b/src/main/java/net/minecraft/world/entity/animal/Cow.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Cow.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Cow.java
|
||||
@@ -0,0 +0,0 @@ public class Cow extends Animal {
|
||||
PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level(), player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET, hand);
|
||||
|
||||
if (event.isCancelled()) {
|
||||
+ player.containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
|
||||
@@ -0,0 +0,0 @@ public class Goat extends Animal {
|
||||
PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level(), player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET, hand);
|
||||
|
||||
if (event.isCancelled()) {
|
||||
+ player.containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ArmorStandItem.java b/src/main/java/net/minecraft/world/item/ArmorStandItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ArmorStandItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ArmorStandItem.java
|
||||
@@ -0,0 +0,0 @@ public class ArmorStandItem extends Item {
|
||||
entityarmorstand.moveTo(entityarmorstand.getX(), entityarmorstand.getY(), entityarmorstand.getZ(), f, 0.0F);
|
||||
// CraftBukkit start
|
||||
if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(context, entityarmorstand).isCancelled()) {
|
||||
+ if (context.getPlayer() != null) context.getPlayer().containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/BlockItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/BlockItem.java
|
||||
@@ -0,0 +0,0 @@ public class BlockItem extends Item {
|
||||
if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) {
|
||||
blockstate.update(true, false);
|
||||
|
||||
- if (this instanceof SolidBucketItem) {
|
||||
+ if (true) { // Paper - if the event is called here, the inventory should be updated
|
||||
((ServerPlayer) entityhuman).getBukkitEntity().updateInventory(); // SPIGOT-4541
|
||||
}
|
||||
return InteractionResult.FAIL;
|
||||
diff --git a/src/main/java/net/minecraft/world/item/EndCrystalItem.java b/src/main/java/net/minecraft/world/item/EndCrystalItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/EndCrystalItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/EndCrystalItem.java
|
||||
@@ -0,0 +0,0 @@ public class EndCrystalItem extends Item {
|
||||
entityendercrystal.setShowBottom(false);
|
||||
// CraftBukkit start
|
||||
if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(context, entityendercrystal).isCancelled()) {
|
||||
+ if (context.getPlayer() != null) context.getPlayer().containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/world/item/MinecartItem.java b/src/main/java/net/minecraft/world/item/MinecartItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/MinecartItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/MinecartItem.java
|
||||
@@ -0,0 +0,0 @@ public class MinecartItem extends Item {
|
||||
|
||||
// CraftBukkit start
|
||||
if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(context, entityminecartabstract).isCancelled()) {
|
||||
+ if (context.getPlayer() != null) context.getPlayer().containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
// CraftBukkit end
|
@@ -1,54 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: The456gamer <the456gamer@the456gamer.dev>
|
||||
Date: Mon, 28 Aug 2023 01:32:39 +0100
|
||||
Subject: [PATCH] Fix spigot's Forced-Stats
|
||||
|
||||
moves the loading after vanilla loading, so it overrides the values.
|
||||
disables saving any forced stats, so it stays at the same value (without enabling disableStatSaving)
|
||||
fixes stat initialization to not cause a NullPointerException
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/stats/ServerStatsCounter.java b/src/main/java/net/minecraft/stats/ServerStatsCounter.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/stats/ServerStatsCounter.java
|
||||
+++ b/src/main/java/net/minecraft/stats/ServerStatsCounter.java
|
||||
@@ -0,0 +0,0 @@ public class ServerStatsCounter extends StatsCounter {
|
||||
public ServerStatsCounter(MinecraftServer server, File file) {
|
||||
this.server = server;
|
||||
this.file = file;
|
||||
- // Spigot start
|
||||
- for ( Map.Entry<ResourceLocation, Integer> entry : org.spigotmc.SpigotConfig.forcedStats.entrySet() )
|
||||
- {
|
||||
- Stat<ResourceLocation> wrapper = Stats.CUSTOM.get( entry.getKey() );
|
||||
- this.stats.put( wrapper, entry.getValue().intValue() );
|
||||
- }
|
||||
- // Spigot end
|
||||
if (file.isFile()) {
|
||||
try {
|
||||
this.parseLocal(server.getFixerUpper(), FileUtils.readFileToString(file));
|
||||
@@ -0,0 +0,0 @@ public class ServerStatsCounter extends StatsCounter {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Moved after stat fetching for player state file
|
||||
+ // Moves the loading after vanilla loading, so it overrides the values.
|
||||
+ // Disables saving any forced stats, so it stays at the same value (without enabling disableStatSaving)
|
||||
+ // Fixes stat initialization to not cause a NullPointerException
|
||||
+ // Spigot start
|
||||
+ for ( Map.Entry<ResourceLocation, Integer> entry : org.spigotmc.SpigotConfig.forcedStats.entrySet() )
|
||||
+ {
|
||||
+ Stat<ResourceLocation> wrapper = Stats.CUSTOM.get(java.util.Objects.requireNonNull(BuiltInRegistries.CUSTOM_STAT.get(entry.getKey()))); // Paper - ensured by SpigotConfig#stats
|
||||
+ this.stats.put( wrapper, entry.getValue().intValue() );
|
||||
+ }
|
||||
+ // Spigot end
|
||||
+ // Paper end - Moved after stat fetching for player state file
|
||||
}
|
||||
|
||||
public void save() {
|
||||
@@ -0,0 +0,0 @@ public class ServerStatsCounter extends StatsCounter {
|
||||
@Override
|
||||
public void setValue(Player player, Stat<?> stat, int value) {
|
||||
if ( org.spigotmc.SpigotConfig.disableStatSaving ) return; // Spigot
|
||||
+ if (stat.getType() == Stats.CUSTOM && stat.getValue() instanceof final ResourceLocation resourceLocation && org.spigotmc.SpigotConfig.forcedStats.get(resourceLocation) != null) return; // Paper - disable saving forced stats
|
||||
super.setValue(player, stat, value);
|
||||
this.dirty.add(stat);
|
||||
}
|
@@ -1,72 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tamion <70228790+notTamion@users.noreply.github.com>
|
||||
Date: Sat, 30 Sep 2023 12:36:14 +0200
|
||||
Subject: [PATCH] Fix strikeLightningEffect powers lightning rods and clears
|
||||
copper
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LightningBolt.java b/src/main/java/net/minecraft/world/entity/LightningBolt.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LightningBolt.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LightningBolt.java
|
||||
@@ -0,0 +0,0 @@ public class LightningBolt extends Entity {
|
||||
private ServerPlayer cause;
|
||||
private final Set<Entity> hitEntities = Sets.newHashSet();
|
||||
private int blocksSetOnFire;
|
||||
+ public boolean isEffect; // Paper - Properly handle lightning effects api
|
||||
|
||||
public LightningBolt(EntityType<? extends LightningBolt> type, Level world) {
|
||||
super(type, world);
|
||||
@@ -0,0 +0,0 @@ public class LightningBolt extends Entity {
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
- if (this.life == 2) {
|
||||
+ if (!this.isEffect && this.life == 2) { // Paper - Properly handle lightning effects api
|
||||
if (this.level().isClientSide()) {
|
||||
this.level().playLocalSound(this.getX(), this.getY(), this.getZ(), SoundEvents.LIGHTNING_BOLT_THUNDER, SoundSource.WEATHER, 10000.0F, 0.8F + this.random.nextFloat() * 0.2F, false);
|
||||
this.level().playLocalSound(this.getX(), this.getY(), this.getZ(), SoundEvents.LIGHTNING_BOLT_IMPACT, SoundSource.WEATHER, 2.0F, 0.5F + this.random.nextFloat() * 0.2F, false);
|
||||
@@ -0,0 +0,0 @@ public class LightningBolt extends Entity {
|
||||
}
|
||||
}
|
||||
|
||||
- if (this.life >= 0 && !this.visualOnly) { // CraftBukkit - add !this.visualOnly
|
||||
+ if (this.life >= 0 && !this.isEffect) { // CraftBukkit - add !this.visualOnly // Paper - Properly handle lightning effects api
|
||||
if (!(this.level() instanceof ServerLevel)) {
|
||||
this.level().setSkyFlashTime(2);
|
||||
} else if (!this.visualOnly) {
|
||||
@@ -0,0 +0,0 @@ public class LightningBolt extends Entity {
|
||||
}
|
||||
|
||||
private void spawnFire(int spreadAttempts) {
|
||||
- if (!this.visualOnly && !this.level().isClientSide && this.level().getGameRules().getBoolean(GameRules.RULE_DOFIRETICK)) {
|
||||
+ if (!this.visualOnly && !this.isEffect && !this.level().isClientSide && this.level().getGameRules().getBoolean(GameRules.RULE_DOFIRETICK)) { // Paper - Properly handle lightning effects api
|
||||
BlockPos blockposition = this.blockPosition();
|
||||
BlockState iblockdata = BaseFireBlock.getState(this.level(), blockposition);
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
LightningBolt lightning = EntityType.LIGHTNING_BOLT.create(this.world);
|
||||
lightning.moveTo(loc.getX(), loc.getY(), loc.getZ());
|
||||
- lightning.setVisualOnly(isVisual);
|
||||
+ lightning.isEffect = isVisual; // Paper - Properly handle lightning effects api
|
||||
this.world.strikeLightning(lightning, LightningStrikeEvent.Cause.CUSTOM);
|
||||
return (LightningStrike) lightning.getBukkitEntity();
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java
|
||||
@@ -0,0 +0,0 @@ public class CraftLightningStrike extends CraftEntity implements LightningStrike
|
||||
|
||||
@Override
|
||||
public boolean isEffect() {
|
||||
- return this.getHandle().visualOnly;
|
||||
+ return this.getHandle().isEffect; // Paper - Properly handle lightning effects api
|
||||
}
|
||||
|
||||
public int getFlashes() {
|
@@ -1,25 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sat, 23 Sep 2023 22:31:54 -0700
|
||||
Subject: [PATCH] Fix team sidebar objectives not being cleared
|
||||
|
||||
Objectives displayed in team sidebars were not cleared when switching
|
||||
scoreboards. If a player's scoreboard has a displayed objective for the
|
||||
'gold' sidebar, and their scoreboard was switched to one where they
|
||||
still had a 'gold' team, it would still be displayed
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftScoreboardManager implements ScoreboardManager {
|
||||
|
||||
// Old objective tracking
|
||||
HashSet<Objective> removed = new HashSet<>();
|
||||
- for (int i = 0; i < 3; ++i) {
|
||||
- Objective scoreboardobjective = oldboard.getDisplayObjective(net.minecraft.world.scores.DisplaySlot.BY_ID.apply(i));
|
||||
+ for (net.minecraft.world.scores.DisplaySlot slot : net.minecraft.world.scores.DisplaySlot.values()) { // Paper - clear all display slots
|
||||
+ Objective scoreboardobjective = oldboard.getDisplayObjective(slot); // Paper - clear all display slots
|
||||
if (scoreboardobjective != null && !removed.contains(scoreboardobjective)) {
|
||||
entityplayer.connection.send(new ClientboundSetObjectivePacket(scoreboardobjective, 1));
|
||||
removed.add(scoreboardobjective);
|
@@ -1,42 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aeltumn <daniel@goossens.ch>
|
||||
Date: Thu, 24 Aug 2023 13:05:30 +0200
|
||||
Subject: [PATCH] Implement OfflinePlayer#isConnected
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa
|
||||
return this.getPlayer() != null;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean isConnected() {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public String getName() {
|
||||
Player player = this.getPlayer();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
return this.server.getPlayer(this.getUniqueId()) != null;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean isConnected() {
|
||||
+ return !this.getHandle().hasDisconnected();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public InetSocketAddress getAddress() {
|
||||
if (this.getHandle().connection.protocol() == null) return null;
|
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
|
||||
@@ -0,0 +0,0 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
|
||||
|
||||
private final Class<?> bukkitClass; // Paper - relax preload class
|
||||
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 final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> serializationUpdater; // Paper - rename to make it *clear* what it is *only* for
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
}
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimPattern.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimPattern.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/test/java/org/bukkit/registry/PerRegistryTest.java
|
||||
+++ b/src/test/java/org/bukkit/registry/PerRegistryTest.java
|
||||
@@ -0,0 +0,0 @@ public class PerRegistryTest {
|
||||
|
||||
@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
|
||||
@@ -0,0 +0,0 @@ public class PerRegistryTest {
|
||||
});
|
||||
}
|
||||
|
||||
- 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java
|
||||
+++ b/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java
|
||||
@@ -0,0 +0,0 @@ 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,91 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 18 Dec 2022 13:40:05 -0800
|
||||
Subject: [PATCH] More DragonBattle API
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.level.dimension.end.EndDragonFight GATEWAY_COUNT
|
||||
public net.minecraft.world.level.dimension.end.EndDragonFight gateways
|
||||
public net.minecraft.world.level.dimension.end.EndDragonFight respawnCrystals
|
||||
public net.minecraft.world.level.dimension.end.EndDragonFight spawnNewGateway(Lnet/minecraft/core/BlockPos;)V
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
@@ -0,0 +0,0 @@ public class EndDragonFight {
|
||||
this.gateways.clear();
|
||||
}
|
||||
|
||||
+ // Paper start - More DragonBattle API
|
||||
+ public boolean spawnNewGatewayIfPossible() {
|
||||
+ if (!this.gateways.isEmpty()) {
|
||||
+ this.spawnNewGateway();
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ public List<EndCrystal> getSpikeCrystals() {
|
||||
+ final List<EndCrystal> endCrystals = new java.util.ArrayList<>();
|
||||
+ for (final SpikeFeature.EndSpike spike : SpikeFeature.getSpikesForLevel(this.level)) {
|
||||
+ endCrystals.addAll(this.level.getEntitiesOfClass(EndCrystal.class, spike.getTopBoundingBox()));
|
||||
+ }
|
||||
+ return endCrystals;
|
||||
+ }
|
||||
+ // Paper end - More DragonBattle API
|
||||
+
|
||||
private void spawnNewGateway() {
|
||||
if (!this.gateways.isEmpty()) {
|
||||
int i = (Integer) this.gateways.remove(this.gateways.size() - 1);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/boss/CraftDragonBattle.java b/src/main/java/org/bukkit/craftbukkit/boss/CraftDragonBattle.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/boss/CraftDragonBattle.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/boss/CraftDragonBattle.java
|
||||
@@ -0,0 +0,0 @@ public class CraftDragonBattle implements DragonBattle {
|
||||
private DragonRespawnAnimation toNMSRespawnPhase(RespawnPhase phase) {
|
||||
return (phase != RespawnPhase.NONE) ? DragonRespawnAnimation.values()[phase.ordinal()] : null;
|
||||
}
|
||||
+ // Paper start - More DragonBattle API
|
||||
+ @Override
|
||||
+ public int getGatewayCount() {
|
||||
+ return EndDragonFight.GATEWAY_COUNT - this.handle.gateways.size();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean spawnNewGateway() {
|
||||
+ return this.handle.spawnNewGatewayIfPossible();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void spawnNewGateway(final io.papermc.paper.math.Position position) {
|
||||
+ this.handle.spawnNewGateway(io.papermc.paper.util.MCUtil.toBlockPos(position));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public java.util.List<org.bukkit.entity.EnderCrystal> getRespawnCrystals() {
|
||||
+ if (this.handle.respawnCrystals == null) {
|
||||
+ return java.util.Collections.emptyList();
|
||||
+ }
|
||||
+
|
||||
+ final java.util.List<org.bukkit.entity.EnderCrystal> enderCrystals = new java.util.ArrayList<>();
|
||||
+ for (final net.minecraft.world.entity.boss.enderdragon.EndCrystal endCrystal : this.handle.respawnCrystals) {
|
||||
+ if (!endCrystal.isRemoved() && endCrystal.isAlive() && endCrystal.valid) {
|
||||
+ enderCrystals.add(((org.bukkit.entity.EnderCrystal) endCrystal.getBukkitEntity()));
|
||||
+ }
|
||||
+ }
|
||||
+ return java.util.Collections.unmodifiableList(enderCrystals);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public java.util.List<org.bukkit.entity.EnderCrystal> getHealingCrystals() {
|
||||
+ final java.util.List<org.bukkit.entity.EnderCrystal> enderCrystals = new java.util.ArrayList<>();
|
||||
+ for (final net.minecraft.world.entity.boss.enderdragon.EndCrystal endCrystal : this.handle.getSpikeCrystals()) {
|
||||
+ if (!endCrystal.isRemoved() && endCrystal.isAlive() && endCrystal.valid) {
|
||||
+ enderCrystals.add(((org.bukkit.entity.EnderCrystal) endCrystal.getBukkitEntity()));
|
||||
+ }
|
||||
+ }
|
||||
+ return java.util.Collections.unmodifiableList(enderCrystals);
|
||||
+ }
|
||||
+ // Paper end - More DragonBattle API
|
||||
}
|
@@ -1,52 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: astei <andrew@steinborn.me>
|
||||
Date: Sat, 28 Oct 2023 19:46:21 -0400
|
||||
Subject: [PATCH] Optimize VarInts
|
||||
|
||||
https://github.com/PaperMC/Paper/pull/6957#issuecomment-985250854
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/VarInt.java b/src/main/java/net/minecraft/network/VarInt.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/VarInt.java
|
||||
+++ b/src/main/java/net/minecraft/network/VarInt.java
|
||||
@@ -0,0 +0,0 @@ public class VarInt {
|
||||
private static final int DATA_BITS_PER_BYTE = 7;
|
||||
|
||||
public static int getByteSize(int i) {
|
||||
+ // Paper start - Optimize VarInts
|
||||
+ return VARINT_EXACT_BYTE_LENGTHS[Integer.numberOfLeadingZeros(i)];
|
||||
+ }
|
||||
+ private static final int[] VARINT_EXACT_BYTE_LENGTHS = new int[33];
|
||||
+ static {
|
||||
+ for (int i = 0; i <= 32; ++i) {
|
||||
+ VARINT_EXACT_BYTE_LENGTHS[i] = (int) Math.ceil((31d - (i - 1)) / 7d);
|
||||
+ }
|
||||
+ VARINT_EXACT_BYTE_LENGTHS[32] = 1; // Special case for the number 0.
|
||||
+ }
|
||||
+ public static int getByteSizeOld(int i) {
|
||||
+ // Paper end - Optimize VarInts
|
||||
for (int j = 1; j < 5; j++) {
|
||||
if ((i & -1 << j * 7) == 0) {
|
||||
return j;
|
||||
@@ -0,0 +0,0 @@ public class VarInt {
|
||||
}
|
||||
|
||||
public static ByteBuf write(ByteBuf buf, int i) {
|
||||
+ // Paper start - Optimize VarInts
|
||||
+ // Peel the one and two byte count cases explicitly as they are the most common VarInt sizes
|
||||
+ // that the proxy will write, to improve inlining.
|
||||
+ if ((i & (0xFFFFFFFF << 7)) == 0) {
|
||||
+ buf.writeByte(i);
|
||||
+ } else if ((i & (0xFFFFFFFF << 14)) == 0) {
|
||||
+ int w = (i & 0x7F | 0x80) << 8 | (i >>> 7);
|
||||
+ buf.writeShort(w);
|
||||
+ } else {
|
||||
+ writeOld(buf, i);
|
||||
+ }
|
||||
+ return buf;
|
||||
+ }
|
||||
+ public static ByteBuf writeOld(ByteBuf buf, int i) {
|
||||
+ // Paper end - Optimize VarInts
|
||||
while ((i & -128) != 0) {
|
||||
buf.writeByte(i & 127 | 128);
|
||||
i >>>= 7;
|
@@ -1,39 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martijn Muijsers <martijnmuijsers@live.nl>
|
||||
Date: Mon, 21 Aug 2023 21:05:09 +0200
|
||||
Subject: [PATCH] Optimize nearest structure border iteration
|
||||
|
||||
Getting the nearest generated structure contains a nested set of loops that
|
||||
iterates over all chunks at a specific chessboard distance. It does this by
|
||||
iterating over the entire square of chunks within that distance, and checking
|
||||
if the coordinates are at exactly the right distance to be on the border.
|
||||
|
||||
This patch optimizes the iteration by only iterating over the border chunks.
|
||||
This evaluated chunks are the same, and in the same order, as before, to
|
||||
ensure that the returned found structure (which may for example be a buried
|
||||
treasure that will be marked on a treasure map) is the same as in vanilla.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||
@@ -0,0 +0,0 @@ public abstract class ChunkGenerator {
|
||||
int i1 = placement.spacing();
|
||||
|
||||
for (int j1 = -radius; j1 <= radius; ++j1) {
|
||||
- boolean flag1 = j1 == -radius || j1 == radius;
|
||||
+ // Paper start - Perf: iterate over border chunks instead of entire square chunk area
|
||||
+ boolean flag1 = j1 == -radius || j1 == radius; final boolean onBorderAlongZAxis = flag1; // Paper - OBFHELPER
|
||||
|
||||
- for (int k1 = -radius; k1 <= radius; ++k1) {
|
||||
- boolean flag2 = k1 == -radius || k1 == radius;
|
||||
+ for (int k1 = -radius; k1 <= radius; k1 += onBorderAlongZAxis ? 1 : radius * 2) {
|
||||
+ // boolean flag2 = k1 == -radius || k1 == radius;
|
||||
|
||||
- if (flag1 || flag2) {
|
||||
+ // if (flag1 || flag2) {
|
||||
+ if (true) {
|
||||
+ // Paper end - Perf: iterate over border chunks instead of entire square chunk area
|
||||
int l1 = centerChunkX + i1 * j1;
|
||||
int i2 = centerChunkZ + i1 * k1;
|
||||
ChunkPos chunkcoordintpair = placement.getPotentialStructureChunk(seed, l1, i2);
|
@@ -1,270 +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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
|
||||
if (this.isRemoved()) {
|
||||
return;
|
||||
}
|
||||
- java.util.List<org.bukkit.inventory.ItemStack> loot = new java.util.ArrayList<>(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.has(item, EnchantmentEffectComponents.PREVENT_EQUIPMENT_DROP)) {
|
||||
- loot.add(CraftItemStack.asCraftMirror(item).markForInventoryDrop());
|
||||
+ 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);
|
||||
- this.dropCustomDeathLoot(this.serverLevel(), damageSource, flag);
|
||||
+ // Paper - Restore vanilla drops behaviour; custom death loot is a noop on server player, remove.
|
||||
|
||||
loot.addAll(this.drops);
|
||||
this.drops.clear(); // SPIGOT-5188: make sure to clear
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
|
||||
@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 java.util.function.Consumer<org.bukkit.inventory.ItemStack> fallback) {
|
||||
+ if (this.dropConsumer == null || org.bukkit.craftbukkit.inventory.CraftItemType.bukkitToMinecraft(this.stack.getType()) != this.item) {
|
||||
+ fallback.accept(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) {
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
} 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
protected float appliedScale;
|
||||
// CraftBukkit start
|
||||
public int expToDrop;
|
||||
- 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
|
||||
@Override
|
||||
protected void dropCustomDeathLoot(ServerLevel world, DamageSource source, boolean causedByPlayer) {
|
||||
super.dropCustomDeathLoot(world, source, causedByPlayer);
|
||||
- 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
ItemStack itemstack = new ItemStack(Items.ARMOR_STAND);
|
||||
|
||||
itemstack.set(DataComponents.CUSTOM_NAME, 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(world, damageSource); // Paper
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
}
|
||||
|
||||
public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource) {
|
||||
- return CraftEventFactory.callEntityDeathEvent(victim, damageSource, new ArrayList<org.bukkit.inventory.ItemStack>(0));
|
||||
+ return CraftEventFactory.callEntityDeathEvent(victim, damageSource, new ArrayList<>(0)); // Paper - Restore vanilla drops behavior
|
||||
}
|
||||
|
||||
- public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource, List<org.bukkit.inventory.ItemStack> drops) {
|
||||
+ public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource, List<Entity.DefaultDrop> drops) { // Paper - Restore vanilla drops behavior
|
||||
// Paper start
|
||||
return CraftEventFactory.callEntityDeathEvent(victim, damageSource, drops, com.google.common.util.concurrent.Runnables.doNothing());
|
||||
}
|
||||
- public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource, 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, DamageSource damageSource, List<Entity.DefaultDrop> drops, Runnable lootCheck) { // Paper
|
||||
// Paper end
|
||||
CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity();
|
||||
CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
|
||||
- EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(damageSource.getEntity()));
|
||||
+ EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(damageSource.getEntity())); // Paper - Restore vanilla drops behavior
|
||||
populateFields(victim, event); // Paper - make cancellable
|
||||
CraftWorld world = (CraftWorld) entity.getWorld();
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
@@ -0,0 +0,0 @@ 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(s -> world.dropItem(entity.getLocation(), s)); // 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, DamageSource damageSource, List<org.bukkit.inventory.ItemStack> drops, net.kyori.adventure.text.Component deathMessage, boolean keepInventory) { // Paper - Adventure
|
||||
+ public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, DamageSource damageSource, List<Entity.DefaultDrop> drops, net.kyori.adventure.text.Component deathMessage, boolean keepInventory) { // Paper - Adventure & Restore vanilla drops behavior
|
||||
CraftPlayer entity = victim.getBukkitEntity();
|
||||
CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
|
||||
- PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(damageSource.getEntity()), 0, deathMessage);
|
||||
+ PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(damageSource.getEntity()), 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
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
|
||||
- if (stack instanceof CraftItemStack craftItemStack && craftItemStack.isForInventoryDrop()) {
|
||||
- victim.drop(CraftItemStack.asNMSCopy(stack), true, false, false); // SPIGOT-7800, SPIGOT-7801: Vanilla Behaviour for Player Inventory dropped items
|
||||
- } else {
|
||||
- victim.forceDrops = true;
|
||||
- victim.spawnAtLocation(CraftItemStack.asNMSCopy(stack)); // SPIGOT-7806: Vanilla Behaviour for items not related to Player Inventory dropped items
|
||||
- victim.forceDrops = false;
|
||||
- }
|
||||
+ drop.runConsumer(s -> victim.drop(CraftItemStack.unwrap(s), true, false, false)); // Paper - Restore vanilla drops behavior
|
||||
}
|
||||
|
||||
return event;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftItemStack extends ItemStack {
|
||||
this.setItemMeta(itemMeta);
|
||||
}
|
||||
|
||||
- /**
|
||||
- * Gets if the item is marked as an inventory drop in death events.
|
||||
- *
|
||||
- * @return true if the item is marked as an inventory drop
|
||||
- */
|
||||
- @ApiStatus.Internal
|
||||
- public boolean isForInventoryDrop() {
|
||||
- return this.isForInventoryDrop;
|
||||
- }
|
||||
-
|
||||
- /**
|
||||
- * Marks this item as an inventory drop in death events.
|
||||
- *
|
||||
- * @return the ItemStack marked as an inventory drop
|
||||
- */
|
||||
- @ApiStatus.Internal
|
||||
- public ItemStack markForInventoryDrop() {
|
||||
- this.isForInventoryDrop = true;
|
||||
- return this;
|
||||
- }
|
||||
-
|
||||
@Override
|
||||
public MaterialData getData() {
|
||||
return this.handle != null ? CraftMagicNumbers.getMaterialData(this.handle.getItem()) : super.getData();
|
@@ -1,32 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Sauve <paul@technove.co>
|
||||
Date: Thu, 18 Feb 2021 13:13:27 -0600
|
||||
Subject: [PATCH] Skip POI finding if stuck in vehicle
|
||||
|
||||
Copyright (C) 2020 Technove LLC
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
|
||||
@@ -0,0 +0,0 @@ public class AcquirePoi {
|
||||
return false;
|
||||
} else {
|
||||
mutableLong.setValue(time + 20L + (long)world.getRandom().nextInt(20));
|
||||
+ if (entity.getNavigation().isStuck()) mutableLong.add(200); // Paper - Perf: Wait an additional 10s to check again if they're stuck
|
||||
PoiManager poiManager = world.getPoiManager();
|
||||
long2ObjectMap.long2ObjectEntrySet().removeIf(entry -> !entry.getValue().isStillValid(time));
|
||||
Predicate<BlockPos> predicate2 = pos -> {
|
@@ -1,23 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: booky10 <boooky10@gmail.com>
|
||||
Date: Sun, 27 Aug 2023 16:11:31 +0200
|
||||
Subject: [PATCH] Update entity data when attaching firework to entity
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.projectile.FireworkRocketEntity DATA_ATTACHED_TO_TARGET
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
|
||||
@@ -0,0 +0,0 @@ public class CraftFirework extends CraftProjectile implements Firework {
|
||||
}
|
||||
|
||||
this.getHandle().attachedToEntity = (entity != null) ? ((CraftLivingEntity) entity).getHandle() : null;
|
||||
+ // Paper start - update entity data
|
||||
+ this.getHandle().getEntityData().set(FireworkRocketEntity.DATA_ATTACHED_TO_TARGET,
|
||||
+ entity != null ? java.util.OptionalInt.of(entity.getEntityId()) : java.util.OptionalInt.empty());
|
||||
+ // Paper end - update entity data
|
||||
return true;
|
||||
}
|
||||
|
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftObjective.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftObjective.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
}
|
Reference in New Issue
Block a user