[ci skip] Add more patch identifying comments, merge related patches

This commit is contained in:
Nassim Jahnke 2024-01-15 12:38:39 +01:00
parent 44f3ecd436
commit 64b98ef110
29 changed files with 147 additions and 147 deletions

View file

@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
float f = ComposterBlock.COMPOSTABLES.getFloat(itemstack.getItem());
- if ((i != 0 || f <= 0.0F) && rand >= (double) f) {
+ // Paper start
+ // Paper start - Add CompostItemEvent and EntityCompostItemEvent
+ boolean willRaiseLevel = !((i != 0 || f <= 0.0F) && rand >= (double) f);
+ final io.papermc.paper.event.block.CompostItemEvent event;
+ if (entity == null) {
@ -27,7 +27,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ willRaiseLevel = event.willRaiseLevel();
+
+ if (!willRaiseLevel) {
+ // Paper end
+ // Paper end - Add CompostItemEvent and EntityCompostItemEvent
return iblockdata;
} else {
int j = i + 1;
@ -35,11 +35,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.changed = true;
BlockState iblockdata = ComposterBlock.addItem((Entity) null, this.state, this.level, this.pos, itemstack);
+ // Paper start
+ // Paper start - Add CompostItemEvent and EntityCompostItemEvent
+ if (iblockdata == null) {
+ return;
+ }
+ // Paper end
+ // Paper end - Add CompostItemEvent and EntityCompostItemEvent
this.level.levelEvent(1500, this.pos, iblockdata != this.state ? 1 : 0);
this.removeItemNoUpdate(0);
}

View file

@ -12,11 +12,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
public boolean isFacingFrontText(net.minecraft.world.entity.player.Player player) {
+ // Paper start
+ // Paper start - Add Sign#getInteractableSideFor
+ return this.isFacingFrontText(player.getX(), player.getZ());
+ }
+ public boolean isFacingFrontText(double x, double z) {
+ // Paper end
+ // Paper end - Add Sign#getInteractableSideFor
Block block = this.getBlockState().getBlock();
if (block instanceof SignBlock) {
@ -24,8 +24,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
Vec3 vec3d = blocksign.getSignHitboxCenterPosition(this.getBlockState());
- double d0 = player.getX() - ((double) this.getBlockPos().getX() + vec3d.x);
- double d1 = player.getZ() - ((double) this.getBlockPos().getZ() + vec3d.z);
+ double d0 = x - ((double) this.getBlockPos().getX() + vec3d.x); // Paper
+ double d1 = z - ((double) this.getBlockPos().getZ() + vec3d.z); // Paper
+ double d0 = x - ((double) this.getBlockPos().getX() + vec3d.x); // Paper - Add Sign#getInteractableSideFor
+ double d1 = z - ((double) this.getBlockPos().getZ() + vec3d.z); // Paper - Add Sign#getInteractableSideFor
float f = blocksign.getYRotationDegrees(this.getBlockState());
float f1 = (float) (Mth.atan2(d1, d0) * 57.2957763671875D) - 90.0F;

View file

@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (world.getBlockEntity(SignItem.openSign) instanceof SignBlockEntity tileentitysign) {
if (world.getBlockState(SignItem.openSign).getBlock() instanceof SignBlock blocksign) {
- blocksign.openTextEdit(entityhuman, tileentitysign, true, org.bukkit.event.player.PlayerSignOpenEvent.Cause.PLACE); // Craftbukkit
+ blocksign.openTextEdit(entityhuman, tileentitysign, true, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.PLACE); // Paper
+ blocksign.openTextEdit(entityhuman, tileentitysign, true, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.PLACE); // Paper - Add PlayerOpenSignEvent
}
}
} finally {
@ -26,7 +26,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return InteractionResult.SUCCESS;
} else if (!this.otherPlayerIsEditingSign(player, tileentitysign) && player.mayBuild() && this.hasEditableText(player, tileentitysign, flag1)) {
- this.openTextEdit(player, tileentitysign, flag1, org.bukkit.event.player.PlayerSignOpenEvent.Cause.INTERACT); // CraftBukkit
+ this.openTextEdit(player, tileentitysign, flag1, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.INTERACT); // Paper
+ this.openTextEdit(player, tileentitysign, flag1, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.INTERACT); // Paper - Add PlayerOpenSignEvent
return this.getInteractionResult(flag);
} else {
return InteractionResult.PASS;
@ -34,7 +34,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return blockpropertywood;
}
+ @io.papermc.paper.annotation.DoNotUse @Deprecated // Paper
+ @io.papermc.paper.annotation.DoNotUse @Deprecated // Paper - Add PlayerOpenSignEvent
public void openTextEdit(Player player, SignBlockEntity blockEntity, boolean front) {
- // Craftbukkit start
- this.openTextEdit(player, blockEntity, front, org.bukkit.event.player.PlayerSignOpenEvent.Cause.UNKNOWN);
@ -42,7 +42,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
-
- public void openTextEdit(Player entityhuman, SignBlockEntity tileentitysign, boolean flag, org.bukkit.event.player.PlayerSignOpenEvent.Cause cause) {
- if (!org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerSignOpenEvent(entityhuman, tileentitysign, flag, cause)) {
+ // Paper start - PlayerOpenSignEvent
+ // Paper start - Add PlayerOpenSignEvent
+ this.openTextEdit(player, blockEntity, front, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.UNKNOWN);
+ }
+ public void openTextEdit(Player entityhuman, SignBlockEntity tileentitysign, boolean flag, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause cause) {
@ -62,12 +62,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ case INTERACT -> org.bukkit.event.player.PlayerSignOpenEvent.Cause.INTERACT;
+ case UNKNOWN -> org.bukkit.event.player.PlayerSignOpenEvent.Cause.UNKNOWN;
+ };
+ // Paper end - PlayerOpenSignEvent
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerSignOpenEvent(entityhuman, tileentitysign, flag, legacyCause)) { // Paper
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerSignOpenEvent(entityhuman, tileentitysign, flag, legacyCause)) {
+ // Paper end - Add PlayerOpenSignEvent
return;
}
- // Craftbukkit end
+ } // Paper
+ } // Paper - Add PlayerOpenSignEvent
tileentitysign.setAllowedPlayerEditor(entityhuman.getUUID());
entityhuman.openTextEdit(tileentitysign, flag);
}
@ -79,15 +79,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
Preconditions.checkArgument(sign.isPlaced(), "Sign must be placed");
Preconditions.checkArgument(sign.getWorld() == player.getWorld(), "Sign must be in same world as Player");
+ // Paper start
+ // Paper start - Add PlayerOpenSignEvent
+ io.papermc.paper.event.player.PlayerOpenSignEvent event = new io.papermc.paper.event.player.PlayerOpenSignEvent((Player) player, sign, side, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.PLUGIN);
+ if (!event.callEvent()) return;
+ if (PlayerSignOpenEvent.getHandlerList().getRegisteredListeners().length > 0) {
+ // Paper end
+ // Paper end - Add PlayerOpenSignEvent
if (!CraftEventFactory.callPlayerSignOpenEvent(player, sign, side, PlayerSignOpenEvent.Cause.PLUGIN)) {
return;
}
+ } // Paper
+ } // Paper - Add PlayerOpenSignEvent
SignBlockEntity handle = ((CraftSign<?>) sign).getTileEntity();
handle.setAllowedPlayerEditor(player.getUniqueId());

View file

@ -30,7 +30,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
};
- if (!org.apache.commons.lang3.StringUtils.isBlank(name)) // Paper - Don't lookup a profile with a blank name)
- if (!org.apache.commons.lang3.StringUtils.isBlank(name)) // Paper - Don't lookup a profile with a blank name
+ if (!org.apache.commons.lang3.StringUtils.isBlank(name) // Paper - Don't lookup a profile with a blank name
+ && io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode()) // Paper - Add setting for proxy online mode status
repository.findProfilesByNames(new String[]{name}, profilelookupcallback);

View file

@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ private static final int DEFAULT_ENTRY_COUNT = 10;
+ private static final int GROW_FACTOR = 8;
+ private SynchedEntityData.DataItem<?>[] itemsArray = new SynchedEntityData.DataItem<?>[DEFAULT_ENTRY_COUNT];
+ // Paper end
+ // Paper end - array backed synched entity data
public SynchedEntityData(Entity trackedEntity) {
this.entity = trackedEntity;
@ -33,7 +33,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ this.itemsArray[key.getId()] = datawatcher_item;
+ // Paper end
+ // Paper end - array backed synched entity data
}
public <T> boolean hasItem(EntityDataAccessor<T> key) {
@ -50,7 +50,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ return (DataItem<T>) this.itemsArray[id];
+ // Paper end
+ // Paper end - array backed synched entity data
// Spigot end
}

View file

@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.permutation = axisTransformation;
this.transformation = (new Matrix3f()).scaling(flipX ? -1.0F : 1.0F, flipY ? -1.0F : 1.0F, flipZ ? -1.0F : 1.0F);
this.transformation.mul(axisTransformation.transformation());
+ this.initializeRotationDirections(); // Paper
+ this.initializeRotationDirections(); // Paper - Avoid Lazy Initialization for Enum Fields
}
private BooleanList packInversions() {
@ -23,7 +23,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
- public Direction rotate(Direction direction) {
+ public void initializeRotationDirections() { // Paper
+ public void initializeRotationDirections() { // Paper - Avoid Lazy Initialization for Enum Fields
if (this.rotatedDirections == null) {
this.rotatedDirections = Maps.newEnumMap(Direction.class);
Direction.Axis[] axiss = Direction.Axis.values();
@ -31,10 +31,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
}
+ // Paper start - Move lazy initialization to constructor
+ // Paper start - Avoid Lazy Initialization for Enum Fields
+ }
+ public Direction rotate(Direction direction) {
+ // Paper end
+ // Paper end - Avoid Lazy Initialization for Enum Fields
return this.rotatedDirections.get(direction);
}

View file

@ -12,13 +12,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.setSuccess(true);
if (iblockdata.is(Blocks.RESPAWN_ANCHOR)) {
if ((Integer) iblockdata.getValue(RespawnAnchorBlock.CHARGE) != 4) {
+ // Paper start
+ // Paper start - Call missing BlockDispenseEvent
+ ItemStack result = org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDispenseEvent(pointer, blockposition, stack, this);
+ if (result != null) {
+ this.setSuccess(false);
+ return result;
+ }
+ // Paper end
+ // Paper end - Call missing BlockDispenseEvent
RespawnAnchorBlock.charge((Entity) null, worldserver, blockposition, iblockdata);
stack.shrink(1);
} else {
@ -26,13 +26,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
Optional<BlockState> optional = HoneycombItem.getWaxed(iblockdata);
if (optional.isPresent()) {
+ // Paper start
+ // Paper start - Call missing BlockDispenseEvent
+ ItemStack result = org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDispenseEvent(pointer, blockposition, stack, this);
+ if (result != null) {
+ this.setSuccess(false);
+ return result;
+ }
+ // Paper end
+ // Paper end - Call missing BlockDispenseEvent
worldserver.setBlockAndUpdate(blockposition, (BlockState) optional.get());
worldserver.levelEvent(3003, blockposition, 0);
stack.shrink(1);
@ -40,12 +40,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (!worldserver.getBlockState(blockposition1).is(BlockTags.CONVERTABLE_TO_MUD)) {
return this.defaultDispenseItemBehavior.dispense(pointer, stack);
} else {
+ // Paper start
+ // Paper start - Call missing BlockDispenseEvent
+ ItemStack result = org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDispenseEvent(pointer, blockposition1, stack, this);
+ if (result != null) {
+ return result;
+ }
+ // Paper end
+ // Paper end - Call missing BlockDispenseEvent
if (!worldserver.isClientSide) {
for (int k = 0; k < 5; ++k) {
worldserver.sendParticles(ParticleTypes.SPLASH, (double) blockposition.getX() + worldserver.random.nextDouble(), (double) (blockposition.getY() + 1), (double) blockposition.getZ() + worldserver.random.nextDouble(), 1, 0.0D, 0.0D, 0.0D, 1.0D);
@ -57,7 +57,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
// Paper end
+ // Paper start - missing BlockDispenseEvent calls
+ // Paper start - Call missing BlockDispenseEvent
+ @Nullable
+ public static ItemStack handleBlockDispenseEvent(net.minecraft.core.dispenser.BlockSource pointer, BlockPos to, ItemStack itemStack, net.minecraft.core.dispenser.DispenseItemBehavior instance) {
+ org.bukkit.block.Block bukkitBlock = pointer.level().getWorld().getBlockAt(pointer.pos().getX(), pointer.pos().getY(), pointer.pos().getZ());
@ -81,7 +81,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ return null;
+ }
+ // Paper end - missing BlockDispenseEvent calls
+ // Paper end - Call missing BlockDispenseEvent
+
// Paper start - add EntityFertilizeEggEvent
/**

View file

@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ final YamlConfiguration commandsDefaults = YamlConfiguration.loadConfiguration(new InputStreamReader(this.getClass().getClassLoader().getResourceAsStream("configurations/commands.yml"), Charsets.UTF_8));
+ if (this.commandsConfiguration.contains("aliases")) commandsDefaults.set("aliases", null);
+ this.commandsConfiguration.setDefaults(commandsDefaults);
+ // Paper stop - dont enforce icanhasbukkit default if alias block exists
+ // Paper stop - don't enforce icanhasbukkit default if alias block exists
this.saveCommandsConfig();
// Migrate aliases from old file and add previously implicit $1- to pass all arguments

View file

@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
};
+ if (!org.apache.commons.lang3.StringUtils.isBlank(name)) // Paper - Don't lookup a profile with a blank name)
+ if (!org.apache.commons.lang3.StringUtils.isBlank(name)) // Paper - Don't lookup a profile with a blank name
repository.findProfilesByNames(new String[]{name}, profilelookupcallback);
GameProfile gameprofile = (GameProfile) atomicreference.get();

View file

@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
int j = Math.min(this.xpToDurability(amount), itemstack.getDamageValue());
// CraftBukkit start
- org.bukkit.event.player.PlayerItemMendEvent event = CraftEventFactory.callPlayerItemMendEvent(player, this, itemstack, entry.getKey(), j);
+ org.bukkit.event.player.PlayerItemMendEvent event = CraftEventFactory.callPlayerItemMendEvent(player, this, itemstack, entry.getKey(), j, this::durabilityToXp); // Paper
+ org.bukkit.event.player.PlayerItemMendEvent event = CraftEventFactory.callPlayerItemMendEvent(player, this, itemstack, entry.getKey(), j, this::durabilityToXp); // Paper - Expand PlayerItemMendEvent
j = event.getRepairAmount();
if (event.isCancelled()) {
return amount;
@ -22,13 +22,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
itemstack.setDamageValue(itemstack.getDamageValue() - j);
- int k = amount - this.durabilityToXp(j);
+ int k = amount - event.getDurabilityToXpOperation().applyAsInt(j); // Paper
+ int k = amount - event.getDurabilityToXpOperation().applyAsInt(j); // Paper - Expand PlayerItemMendEvent
this.value = k; // CraftBukkit - update exp value of orb for PlayerItemMendEvent calls
+ // Paper start
+ // Paper start - Expand PlayerItemMendEvent
+ if (j == 0 && amount == k) { // if repair amount is 0 and no xp was removed, don't do recursion; treat as cancelled
+ return k;
+ }
+ // Paper end
+ // Paper end - Expand PlayerItemMendEvent
return k > 0 ? this.repairPlayerItems(player, k) : 0;
} else {
@ -41,12 +41,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
int i = Math.min(orb.xpToDurability(amount), itemstack.getDamageValue());
- org.bukkit.event.player.PlayerItemMendEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemMendEvent(handle, orb, itemstack, stackEntry.getKey(), i);
+ org.bukkit.event.player.PlayerItemMendEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemMendEvent(handle, orb, itemstack, stackEntry.getKey(), i, orb::durabilityToXp); // Paper
+ org.bukkit.event.player.PlayerItemMendEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemMendEvent(handle, orb, itemstack, stackEntry.getKey(), i, orb::durabilityToXp); // Paper - Expand PlayerItemMendEvent
i = event.getRepairAmount();
orb.discard();
if (!event.isCancelled()) {
- amount -= orb.durabilityToXp(i);
+ amount -= event.getDurabilityToXpOperation().applyAsInt(i); // Paper
+ amount -= event.getDurabilityToXpOperation().applyAsInt(i); // Paper - Expand PlayerItemMendEvent
itemstack.setDamageValue(itemstack.getDamageValue() - i);
}
}
@ -59,11 +59,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
- public static PlayerItemMendEvent callPlayerItemMendEvent(net.minecraft.world.entity.player.Player entity, net.minecraft.world.entity.ExperienceOrb orb, net.minecraft.world.item.ItemStack nmsMendedItem, net.minecraft.world.entity.EquipmentSlot slot, int repairAmount) {
+ public static PlayerItemMendEvent callPlayerItemMendEvent(net.minecraft.world.entity.player.Player entity, net.minecraft.world.entity.ExperienceOrb orb, net.minecraft.world.item.ItemStack nmsMendedItem, net.minecraft.world.entity.EquipmentSlot slot, int repairAmount, java.util.function.IntUnaryOperator durabilityToXpOp) { // Paper
+ public static PlayerItemMendEvent callPlayerItemMendEvent(net.minecraft.world.entity.player.Player entity, net.minecraft.world.entity.ExperienceOrb orb, net.minecraft.world.item.ItemStack nmsMendedItem, net.minecraft.world.entity.EquipmentSlot slot, int repairAmount, java.util.function.IntUnaryOperator durabilityToXpOp) { // Paper - Expand PlayerItemMendEvent
Player player = (Player) entity.getBukkitEntity();
org.bukkit.inventory.ItemStack bukkitStack = CraftItemStack.asCraftMirror(nmsMendedItem);
- PlayerItemMendEvent event = new PlayerItemMendEvent(player, bukkitStack, CraftEquipmentSlot.getSlot(slot), (ExperienceOrb) orb.getBukkitEntity(), repairAmount);
+ PlayerItemMendEvent event = new PlayerItemMendEvent(player, bukkitStack, CraftEquipmentSlot.getSlot(slot), (ExperienceOrb) orb.getBukkitEntity(), repairAmount, durabilityToXpOp); // Paper
+ PlayerItemMendEvent event = new PlayerItemMendEvent(player, bukkitStack, CraftEquipmentSlot.getSlot(slot), (ExperienceOrb) orb.getBukkitEntity(), repairAmount, durabilityToXpOp); // Paper - Expand PlayerItemMendEvent
Bukkit.getPluginManager().callEvent(event);
return event;
}

View file

@ -12,11 +12,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} else if (source.is(DamageTypes.SONIC_BOOM)) {
cause = DamageCause.SONIC_BOOM;
}
+ // Paper start - fix handle of Falling Blocks
+ // Paper start - fix falling block handling
+ else if (source.is(DamageTypes.FALLING_STALACTITE) || source.is(DamageTypes.FALLING_BLOCK) || source.is(DamageTypes.FALLING_ANVIL)) {
+ cause = DamageCause.FALLING_BLOCK;
+ }
+ // Paper end
+ // Paper end - fix falling block handling
return CraftEventFactory.callEntityDamageEvent(damager, entity, cause, modifiers, modifierFunctions, cancelled, source.isCritical()); // Paper - add critical damage API
} else if (source.is(DamageTypes.FELL_OUT_OF_WORLD)) {

View file

@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public boolean dropItem(boolean dropAll) {
- if (!(this.getHandle() instanceof ServerPlayer)) return false;
- return ((ServerPlayer) this.getHandle()).drop(dropAll);
+ // Paper start - notify client of remote slot change
+ // Paper start - Fix HumanEntity#drop not updating the client inv
+ if (!(this.getHandle() instanceof ServerPlayer player)) return false;
+ boolean success = player.drop(dropAll);
+ if (!success) return false;
@ -24,7 +24,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ final java.util.OptionalInt optionalSlot = player.containerMenu.findSlot(inv, inv.selected);
+ optionalSlot.ifPresent(slot -> player.containerSynchronizer.sendSlotChange(player.containerMenu, slot, inv.getSelected()));
+ return true;
+ // Paper end
+ // Paper end - Fix HumanEntity#drop not updating the client inv
}
@Override

View file

@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
for (CraftBlockState blockstate : blocks) {
world.setBlock(blockstate.getPosition(),blockstate.getHandle(), blockstate.getFlag()); // SPIGOT-7248 - manual update to avoid physics where appropriate
+ if (blockstate instanceof org.bukkit.craftbukkit.block.CapturedBlockState capturedBlockState) capturedBlockState.checkTreeBlockHack(); // Paper
+ if (blockstate instanceof org.bukkit.craftbukkit.block.CapturedBlockState capturedBlockState) capturedBlockState.checkTreeBlockHack(); // Paper - Fix beehives generating from using bonemeal
}
entityhuman.awardStat(Stats.ITEM_USED.get(item)); // SPIGOT-7236 - award stat
}
@ -24,12 +24,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public boolean update(boolean force, boolean applyPhysics) {
boolean result = super.update(force, applyPhysics);
+ // Paper start
+ // Paper start - Fix beehives generating from using bonemeal
+ this.checkTreeBlockHack();
+ return result;
+ }
+ public void checkTreeBlockHack() {
+ // Paper end
+ // Paper end - Fix beehives generating from using bonemeal
// SPIGOT-5537: Horrible hack to manually add bees given World.captureTreeGeneration does not support tiles
if (this.treeBlock && this.getType() == Material.BEE_NEST) {
WorldGenLevel generatoraccessseed = this.world.getHandle();
@ -38,7 +38,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
- return result;
+ // Paper
+ // Paper - Fix beehives generating from using bonemeal
}
@Override

View file

@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
SoundType soundeffecttype = iblockdata1.getSoundType();
- // world.playSound(entityhuman, blockposition, this.getPlaceSound(iblockdata1), SoundCategory.BLOCKS, (soundeffecttype.getVolume() + 1.0F) / 2.0F, soundeffecttype.getPitch() * 0.8F);
+ if (entityhuman == null) world.playSound(entityhuman, blockposition, this.getPlaceSound(iblockdata1), net.minecraft.sounds.SoundSource.BLOCKS, (soundeffecttype.getVolume() + 1.0F) / 2.0F, soundeffecttype.getPitch() * 0.8F); // Paper - reintroduce this for the dispenser (i.e the shulker)
+ if (entityhuman == null) world.playSound(entityhuman, blockposition, this.getPlaceSound(iblockdata1), net.minecraft.sounds.SoundSource.BLOCKS, (soundeffecttype.getVolume() + 1.0F) / 2.0F, soundeffecttype.getPitch() * 0.8F); // Paper - Fix block place logic; reintroduce this for the dispenser (i.e the shulker)
world.gameEvent(GameEvent.BLOCK_PLACE, blockposition, GameEvent.Context.of(entityhuman, iblockdata1));
if ((entityhuman == null || !entityhuman.getAbilities().instabuild) && itemstack != ItemStack.EMPTY) { // CraftBukkit
itemstack.shrink(1);
@ -36,7 +36,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- }
-
- tileentityjukebox.setTheItem(record);
+ tileentityjukebox.setTheItem(this.copy()); // Paper - sync this with record item, jukebox has now an inventory
+ tileentityjukebox.setTheItem(this.copy()); // Paper - Fix block place logic; sync this with record item, jukebox has now an inventory
world.gameEvent(GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(entityhuman, world.getBlockState(blockposition)));
}
@ -48,7 +48,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit start
iblockdata1.updateIndirectNeighbourShapes(this, blockposition, k, j - 1); // Don't call an event for the old block to limit event spam
CraftWorld world = ((ServerLevel) this).getWorld();
+ boolean cancelledUpdates = false; // Paper
+ boolean cancelledUpdates = false; // Paper - Fix block place logic
if (world != null && ((ServerLevel)this).hasPhysicsEvent) { // Paper
BlockPhysicsEvent event = new BlockPhysicsEvent(world.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), CraftBlockData.fromData(iblockdata));
this.getCraftServer().getPluginManager().callEvent(event);
@ -56,13 +56,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- if (event.isCancelled()) {
- return;
- }
+ cancelledUpdates = event.isCancelled(); // Paper
+ cancelledUpdates = event.isCancelled(); // Paper - Fix block place logic
}
// CraftBukkit end
+ if (!cancelledUpdates) { // Paper
+ if (!cancelledUpdates) { // Paper - Fix block place logic
iblockdata.updateNeighbourShapes(this, blockposition, k, j - 1);
iblockdata.updateIndirectNeighbourShapes(this, blockposition, k, j - 1);
+ } // Paper
+ } // Paper - Fix block place logic
}
// CraftBukkit start - SPIGOT-5710

View file

@ -12,17 +12,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return this.permissionLevel >= level;
}
+ // Paper start
+ // Paper start - Fix permission levels for command blocks
+ private boolean forceRespectPermissionLevel() {
+ return this.source == CommandSource.NULL || (this.source instanceof final net.minecraft.world.level.BaseCommandBlock commandBlock && commandBlock.getLevel().paperConfig().commandBlocks.forceFollowPermLevel);
+ }
+ // Paper end
+ // Paper end - Fix permission levels for command blocks
+
// CraftBukkit start
public boolean hasPermission(int i, String bukkitPermission) {
- // World is null when loading functions
- return ((this.getLevel() == null || !this.getLevel().getCraftServer().ignoreVanillaPermissions) && this.permissionLevel >= i) || this.getBukkitSender().hasPermission(bukkitPermission);
+ // Paper start
+ // Paper start - Fix permission levels for command blocks
+ final java.util.function.BooleanSupplier hasBukkitPerm = () -> this.source == CommandSource.NULL /*treat NULL as having all bukkit perms*/ || this.getBukkitSender().hasPermission(bukkitPermission); // lazily check bukkit perms to the benefit of custom permission setups
+ // if the server is null, we must check the vanilla perm level system
+ // if ignoreVanillaPermissions is true, we can skip vanilla perms and just run the bukkit perm check
@ -36,7 +36,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ }
+ return hasBukkitPerm.getAsBoolean();
+ // Paper end
+ // Paper end - Fix permission levels for command blocks
}
// CraftBukkit end
@ -58,7 +58,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- || cmd.equalsIgnoreCase("pardon") || cmd.equalsIgnoreCase("pardon-ip") || cmd.equalsIgnoreCase("reload")) {
- return;
- }
+ // Paper - use proper permission levels to block these commands
+ // Paper - Fix permission levels for command blocks
// Handle vanilla commands;
if (sender.getLevel().getCraftServer().getCommandBlockOverride(args[0])) {

View file

@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Wed, 15 Mar 2023 18:29:45 -0700
Subject: [PATCH] Fix certain inventories returning null Locations
Subject: [PATCH] Fix inventories returning null Locations
Wandering Trader, AbstractHorse, Beacon and Composter inventories returned null locations
when a block or entity location is readily available
@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public Location getLocation() {
+ // Paper start
+ // Paper start - Fix inventories returning null Locations
+ // When the block inventory does not have a tile state that implements getLocation, e. g. composters
+ if (this.bukkitOwner instanceof org.bukkit.inventory.BlockInventoryHolder blockInventoryHolder) {
+ return blockInventoryHolder.getBlock().getLocation();
@ -25,7 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (this.bukkitOwner instanceof org.bukkit.entity.Entity entity) {
+ return entity.getLocation();
+ }
+ // Paper end
+ // Paper end - Fix inventories returning null Locations
return null;
}
@ -37,12 +37,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public int getMaxStackSize() {
return 1;
}
+ // Paper start
+ // Paper start - Fix inventories returning null Locations
+ @Override
+ public org.bukkit.Location getLocation() {
+ return context.getLocation();
+ }
+ // Paper end
+ // Paper end - Fix inventories returning null Locations
};
checkContainerDataCount(propertyDelegate, 3);
this.beaconData = propertyDelegate;
@ -55,7 +55,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public Location getLocation() {
- return (this.merchant instanceof Villager) ? ((Villager) this.merchant).getBukkitEntity().getLocation() : null;
+ return (this.merchant instanceof AbstractVillager) ? ((AbstractVillager) this.merchant).getBukkitEntity().getLocation() : null; // Paper
+ return (this.merchant instanceof AbstractVillager) ? ((AbstractVillager) this.merchant).getBukkitEntity().getLocation() : null; // Paper - Fix inventories returning null Locations
}
// CraftBukkit end

View file

@ -13,11 +13,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// SPIGOT-1288 - play sound stripped from ItemBlock
if (this.item instanceof BlockItem) {
- SoundType soundeffecttype = ((BlockItem) this.item).getBlock().defaultBlockState().getSoundType(); // TODO: not strictly correct, however currently only affects decorated pots
+ // Paper start
+ // Paper start - Fix spigot sound playing for BlockItem ItemStacks
+ BlockPos position = new net.minecraft.world.item.context.BlockPlaceContext(context).getClickedPos();
+ net.minecraft.world.level.block.state.BlockState blockData = world.getBlockState(position);
+ SoundType soundeffecttype = blockData.getSoundType();
+ // Paper end
+ // Paper end - Fix spigot sound playing for BlockItem ItemStacks
world.playSound(entityhuman, blockposition, soundeffecttype.getPlaceSound(), SoundSource.BLOCKS, (soundeffecttype.getVolume() + 1.0F) / 2.0F, soundeffecttype.getPitch() * 0.8F);
}

View file

@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
b = loadFlag(b, nbt, "see_through", (byte)2);
b = loadFlag(b, nbt, "default_background", (byte)4);
- Optional<Display.TextDisplay.Align> optional = Display.TextDisplay.Align.CODEC.decode(NbtOps.INSTANCE, nbt.get("alignment")).resultOrPartial(Util.prefix("Display entity", Display.LOGGER::error)).map(Pair::getFirst);
+ Optional<Display.TextDisplay.Align> optional = Display.TextDisplay.Align.CODEC.decode(NbtOps.INSTANCE, nbt.get("alignment")).result().map(Pair::getFirst); // Paper - hide error message
+ Optional<Display.TextDisplay.Align> optional = Display.TextDisplay.Align.CODEC.decode(NbtOps.INSTANCE, nbt.get("alignment")).result().map(Pair::getFirst); // Paper - Hide text display error on spawn
if (optional.isPresent()) {
byte var10000;
switch ((Display.TextDisplay.Align)optional.get()) {

View file

@ -27,7 +27,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
ServerLevel worldserver = (ServerLevel) iterator.next();
+ worldserver.updateLagCompensationTick(); // Paper - lag compensation
worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper
net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper
net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - Perf: Optimize Hoppers
worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper
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
@ -71,7 +71,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.getEntityData().resendPossiblyDesyncedDataValues(java.util.List.of(DATA_LIVING_ENTITY_FLAGS), serverPlayer);
}
// Paper end
// Paper end - Properly cancel usable items
+ // Paper start - lag compensate eating
+ protected long eatStartTime;
+ protected int totalEatTimeTicks;

View file

@ -25,7 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
for (CraftBlockState blockstate : blocks) {
world.setBlock(blockstate.getPosition(),blockstate.getHandle(), blockstate.getFlag()); // SPIGOT-7248 - manual update to avoid physics where appropriate
+ world.checkCapturedTreeStateForObserverNotify(blockposition, blockstate); // Paper - notify observers even if grow failed
if (blockstate instanceof org.bukkit.craftbukkit.block.CapturedBlockState capturedBlockState) capturedBlockState.checkTreeBlockHack(); // Paper
if (blockstate instanceof org.bukkit.craftbukkit.block.CapturedBlockState capturedBlockState) capturedBlockState.checkTreeBlockHack(); // Paper - Fix beehives generating from using bonemeal
}
entityhuman.awardStat(Stats.ITEM_USED.get(item)); // SPIGOT-7236 - award stat
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java

View file

@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
Entity entity = this.entity;
- if (entity instanceof ItemFrame) {
+ if (!this.trackedPlayers.isEmpty() && entity instanceof ItemFrame) { // Paper - Only tick item frames if players can see it
+ if (!this.trackedPlayers.isEmpty() && entity instanceof ItemFrame) { // Paper - Perf: Only tick item frames if players can see it
ItemFrame entityitemframe = (ItemFrame) entity;
if (true || this.tickCount % 10 == 0) { // CraftBukkit - Moved below, should always enter this block

View file

@ -57,7 +57,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
while (iterator.hasNext()) {
ServerLevel worldserver = (ServerLevel) iterator.next();
worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper
+ net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper
+ net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - Perf: Optimize Hoppers
worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper
this.profiler.push(() -> {
@ -70,17 +70,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public ItemStack copy() {
- if (this.isEmpty()) {
+ // Paper start
+ // Paper start - Perf: Optimize Hoppers
+ return this.copy(false);
+ }
+
+ public ItemStack copy(boolean originalItem) {
+ if (!originalItem && this.isEmpty()) {
+ // Paper end
+ // Paper end - Perf: Optimize Hoppers
return ItemStack.EMPTY;
} else {
- ItemStack itemstack = new ItemStack(this.getItem(), this.count);
+ ItemStack itemstack = new ItemStack(originalItem ? this.item : this.getItem(), this.count); // Paper
+ ItemStack itemstack = new ItemStack(originalItem ? this.item : this.getItem(), this.count); // Paper - Perf: Optimize Hoppers
itemstack.setPopTime(this.getPopTime());
if (this.tag != null) {
@ -92,7 +92,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
import co.aikar.timings.Timing; // Paper
public abstract class BlockEntity {
+ static boolean ignoreTileUpdates; // Paper
+ static boolean ignoreTileUpdates; // Paper - Perf: Optimize Hoppers
public Timing tickTimer = MinecraftTimings.getTileEntityTimings(this); // Paper
// CraftBukkit start - data containers
@ -100,7 +100,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public void setChanged() {
if (this.level != null) {
+ if (ignoreTileUpdates) return; // Paper
+ if (ignoreTileUpdates) return; // Paper - Perf: Optimize Hoppers
BlockEntity.setChanged(this.level, this.worldPosition, this.blockState);
}
@ -112,7 +112,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
+ // Paper start - optimize hoppers
+ // Paper start - Perf: Optimize Hoppers
+ private static final int HOPPER_EMPTY = 0;
+ private static final int HOPPER_HAS_ITEMS = 1;
+ private static final int HOPPER_IS_FULL = 2;
@ -147,7 +147,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ return empty ? HOPPER_EMPTY : (full ? HOPPER_IS_FULL : HOPPER_HAS_ITEMS);
+ }
+ // Paper end - optimize hoppers
+ // Paper end - Perf: Optimize Hoppers
+
private static boolean tryMoveItems(Level world, BlockPos pos, BlockState state, HopperBlockEntity blockEntity, BooleanSupplier booleansupplier) {
if (world.isClientSide) {
@ -157,14 +157,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
boolean flag = false;
- if (!blockEntity.isEmpty()) {
+ int fullState = getFullState(blockEntity); // Paper - optimize hoppers
+ int fullState = getFullState(blockEntity); // Paper - Perf: Optimize Hoppers
+
+ if (fullState != HOPPER_EMPTY) { // Paper - optimize hoppers
+ if (fullState != HOPPER_EMPTY) { // Paper - Perf: Optimize Hopperss
flag = HopperBlockEntity.ejectItems(world, pos, state, (Container) blockEntity, blockEntity); // CraftBukkit
}
- if (!blockEntity.inventoryFull()) {
+ if (fullState != HOPPER_IS_FULL || flag) { // Paper - optimize hoppers
+ if (fullState != HOPPER_IS_FULL || flag) { // Paper - Perf: Optimize Hoppers
flag |= booleansupplier.getAsBoolean();
}
@ -172,7 +172,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return false;
}
+ // Paper start - Optimize Hoppers
+ // Paper start - Perf: Optimize Hoppers
+ private static boolean skipPullModeEventFire;
+ private static boolean skipPushModeEventFire;
+ public static boolean skipHopperEvents;
@ -366,7 +366,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ private static final java.util.function.BiPredicate<ItemStack, Integer> STACK_SIZE_TEST = (itemstack, i) -> itemstack.getCount() >= itemstack.getMaxStackSize();
+ private static final java.util.function.BiPredicate<ItemStack, Integer> IS_EMPTY_TEST = (itemstack, i) -> itemstack.isEmpty();
+ // Paper end
+ // Paper end - Perf: Optimize Hoppers
+
private static boolean ejectItems(Level world, BlockPos blockposition, BlockState iblockdata, Container iinventory, HopperBlockEntity hopper) { // CraftBukkit
Container iinventory1 = HopperBlockEntity.getAttachedContainer(world, blockposition, iblockdata);
@ -453,7 +453,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- return false;
+ // return false;
+ // Paper end
+ // Paper end - Perf: Optimize Hoppers
}
}
}
@ -466,7 +466,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
-
- return itemstack.getCount() >= itemstack.getMaxStackSize();
- });
+ // Paper start - optimize hoppers
+ // Paper start - Perf: Optimize Hoppers
+ if (inventory instanceof WorldlyContainer worldlyContainer) {
+ for (final int slot : worldlyContainer.getSlotsForFace(direction)) {
+ final ItemStack stack = inventory.getItem(slot);
@ -484,14 +484,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ return true;
+ }
+ // Paper end - optimize hoppers
+ // Paper end - Perf: Optimize Hoppers
}
private static boolean isEmptyContainer(Container inv, Direction facing) {
- return HopperBlockEntity.getSlots(inv, facing).allMatch((i) -> {
- return inv.getItem(i).isEmpty();
- });
+ return allMatch(inv, facing, IS_EMPTY_TEST);
+ return allMatch(inv, facing, IS_EMPTY_TEST); // Paper - Perf: Optimize Hoppers
}
public static boolean suckInItems(Level world, Hopper hopper) {
@ -502,7 +502,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- return HopperBlockEntity.isEmptyContainer(iinventory, enumdirection) ? false : HopperBlockEntity.getSlots(iinventory, enumdirection).anyMatch((i) -> {
- return HopperBlockEntity.a(hopper, iinventory, i, enumdirection, world); // Spigot
- });
+ // Paper start - optimize hoppers and remove streams
+ // Paper start - Perf: Optimize Hoppers
+ skipPullModeEventFire = skipHopperEvents;
+ // merge container isEmpty check and move logic into one loop
+ if (iinventory instanceof WorldlyContainer worldlyContainer) {
@ -528,7 +528,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ return false;
+ }
+ // Paper end
+ // Paper end - Perf: Optimize Hoppers
} else {
Iterator iterator = HopperBlockEntity.getItemsAtAndAbove(world, hopper).iterator();
@ -579,7 +579,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
-
- itemstack1.shrink(origCount - itemstack2.getCount()); // Spigot
- iinventory.setItem(i, itemstack1);
+ // Paper start - replace pull logic; MAKE SURE TO CHECK FOR DIFFS WHEN UPDATING
+ // Paper start - Perf: Optimize Hoppers; replace pull logic; MAKE SURE TO CHECK FOR DIFFS WHEN UPDATING
+ if (!itemstack.isEmpty() && HopperBlockEntity.canTakeItemFromContainer(ihopper, iinventory, itemstack, i, enumdirection)) { // If this logic changes, update above. this is left unused incase reflective plugins
+ return hopperPull(world, ihopper, iinventory, itemstack, i);
+ // ItemStack itemstack1 = itemstack.copy();
@ -620,7 +620,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ // itemstack1.shrink(origCount - itemstack2.getCount()); // Spigot
+ // iinventory.setItem(i, itemstack1);
+ // Paper end
+ // Paper end - Perf: Optimize Hoppers
}
return false;
@ -630,13 +630,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit start
- InventoryPickupItemEvent event = new InventoryPickupItemEvent(inventory.getOwner().getInventory(), (org.bukkit.entity.Item) itemEntity.getBukkitEntity());
+ if (InventoryPickupItemEvent.getHandlerList().getRegisteredListeners().length > 0) { // Paper - optimize hoppers
+ InventoryPickupItemEvent event = new InventoryPickupItemEvent(getInventory(inventory), (org.bukkit.entity.Item) itemEntity.getBukkitEntity()); // Paper - use getInventory() to avoid snapshot creation
+ InventoryPickupItemEvent event = new InventoryPickupItemEvent(getInventory(inventory), (org.bukkit.entity.Item) itemEntity.getBukkitEntity()); // Paper - Perf: Optimize Hoppers; use getInventory() to avoid snapshot creation
itemEntity.level().getCraftServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return false;
}
// CraftBukkit end
+ } // Paper - optimize hoppers
+ } // Paper - Perf: Optimize Hoppers
ItemStack itemstack = itemEntity.getItem().copy();
ItemStack itemstack1 = HopperBlockEntity.addItem((Container) null, inventory, itemstack, (Direction) null);
@ -644,9 +644,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
stack = stack.split(to.getMaxStackSize());
}
// Spigot end
+ ignoreTileUpdates = true; // Paper
+ ignoreTileUpdates = true; // Paper - Perf: Optimize Hoppers
to.setItem(slot, stack);
+ ignoreTileUpdates = false; // Paper
+ ignoreTileUpdates = false; // Paper - Perf: Optimize Hoppers
stack = leftover; // Paper
flag = true;
} else if (HopperBlockEntity.canMergeItems(itemstack1, stack)) {
@ -654,16 +654,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit end
}
+ // Paper start - optimize hopper item suck in
+ // Paper start - Perf: Optimize Hoppers
+ static final AABB HOPPER_ITEM_SUCK_OVERALL = Hopper.SUCK.bounds();
+ static final AABB[] HOPPER_ITEM_SUCK_INDIVIDUAL = Hopper.SUCK.toAabbs().toArray(new AABB[0]);
+ // Paper end - optimize hopper item suck in
+ // Paper end - Perf: Optimize Hoppers
+
public static List<ItemEntity> getItemsAtAndAbove(Level world, Hopper hopper) {
- return (List) hopper.getSuckShape().toAabbs().stream().flatMap((axisalignedbb) -> {
- return world.getEntitiesOfClass(ItemEntity.class, axisalignedbb.move(hopper.getLevelX() - 0.5D, hopper.getLevelY() - 0.5D, hopper.getLevelZ() - 0.5D), EntitySelector.ENTITY_STILL_ALIVE).stream();
- }).collect(Collectors.toList());
+ // Paper start - optimize hopper item suck in
+ // Paper start - Perf: Optimize Hoppers
+ // eliminate multiple getEntitiesOfClass() but maintain the voxelshape collision by moving
+ // the individual AABB checks into the predicate
+ final double shiftX = hopper.getLevelX() - 0.5D;
@ -682,23 +682,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ return false;
+ });
+ // Paper end - optimize hopper item suck in
+ // Paper end - Perf: Optimize Hoppers
}
@Nullable
public static Container getContainerAt(Level world, BlockPos pos) {
- return HopperBlockEntity.getContainerAt(world, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D);
+ return HopperBlockEntity.getContainerAt(world, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, true); // Paper
+ return HopperBlockEntity.getContainerAt(world, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, true); // Paper - Perf: Optimize Hoppers
}
@Nullable
private static Container getContainerAt(Level world, double x, double y, double z) {
+ // Paper start - add optimizeEntities parameter
+ // Paper start - Perf: Optimize Hoppers
+ return HopperBlockEntity.getContainerAt(world, x, y, z, false);
+ }
+ @Nullable
+ private static Container getContainerAt(Level world, double x, double y, double z, final boolean optimizeEntities) {
+ // Paper end - add optimizeEntities parameter
+ // Paper end - Perf: Optimize Hoppers
Object object = null;
BlockPos blockposition = BlockPos.containing(x, y, z);
if ( !world.spigotConfig.hopperCanLoadChunks && !world.hasChunkAt( blockposition ) ) return null; // Spigot
@ -708,8 +708,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- if (object == null) {
- List<Entity> list = world.getEntities((Entity) null, new AABB(x - 0.5D, y - 0.5D, z - 0.5D, x + 0.5D, y + 0.5D, z + 0.5D), EntitySelector.CONTAINER_ENTITY_SELECTOR);
+ if (object == null && (!optimizeEntities || !world.paperConfig().hopper.ignoreOccludingBlocks || !iblockdata.getBukkitMaterial().isOccluding())) { // Paper
+ List<Entity> list = world.getEntitiesOfClass((Class)Container.class, new AABB(x - 0.5D, y - 0.5D, z - 0.5D, x + 0.5D, y + 0.5D, z + 0.5D), EntitySelector.CONTAINER_ENTITY_SELECTOR); // Paper - optimize hoppers, use getEntitiesOfClass
+ if (object == null && (!optimizeEntities || !world.paperConfig().hopper.ignoreOccludingBlocks || !iblockdata.getBukkitMaterial().isOccluding())) { // Paper - Perf: Optimize Hoppers
+ List<Entity> list = world.getEntitiesOfClass((Class)Container.class, new AABB(x - 0.5D, y - 0.5D, z - 0.5D, x + 0.5D, y + 0.5D, z + 0.5D), EntitySelector.CONTAINER_ENTITY_SELECTOR); // Paper - Perf: Optimize Hoppers
if (!list.isEmpty()) {
object = (Container) list.get(world.random.nextInt(list.size()));
@ -718,7 +718,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private static boolean canMergeItems(ItemStack first, ItemStack second) {
- return first.getCount() <= first.getMaxStackSize() && ItemStack.isSameItemSameTags(first, second);
+ return first.getCount() < first.getMaxStackSize() && first.is(second.getItem()) && first.getDamageValue() == second.getDamageValue() && ((first.isEmpty() && second.isEmpty()) || java.util.Objects.equals(first.getTag(), second.getTag())); // Paper - used to return true for full itemstacks?!
+ return first.getCount() < first.getMaxStackSize() && first.is(second.getItem()) && first.getDamageValue() == second.getDamageValue() && ((first.isEmpty() && second.isEmpty()) || java.util.Objects.equals(first.getTag(), second.getTag())); // Paper - Perf: Optimize Hoppers; used to return true for full itemstacks?!
}
@Override
@ -731,20 +731,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public boolean isEmpty() {
this.unpackLootTable((Player)null);
- return this.getItems().stream().allMatch(ItemStack::isEmpty);
+ // Paper start
+ // Paper start - Perf: Optimize Hoppers
+ for (final ItemStack itemStack : this.getItems()) {
+ if (!itemStack.isEmpty()) {
+ return false;
+ }
+ }
+ return true;
+ // Paper end
+ // Paper end - Perf: Optimize Hoppers
}
@Override
public ItemStack getItem(int slot) {
- this.unpackLootTable((Player)null);
+ if (slot == 0) this.unpackLootTable((Player)null); // Paper
+ if (slot == 0) this.unpackLootTable((Player) null); // Paper - Perf: Optimize Hoppers
return this.getItems().get(slot);
}

View file

@ -12,11 +12,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public void gameEvent(GameEvent event, Vec3 emitterPos, GameEvent.Context emitter) {
+ // Paper start
+ // Paper start - Prevent GameEvents being fired from unloaded chunks
+ if (this.getChunkIfLoadedImmediately((Mth.floor(emitterPos.x) >> 4), (Mth.floor(emitterPos.z) >> 4)) == null) {
+ return;
+ }
+ // Paper end
+ // Paper end - Prevent GameEvents being fired from unloaded chunks
this.gameEventDispatcher.post(event, emitterPos, emitter);
}

View file

@ -13,13 +13,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
serialized.chatSession = buf.readNullable(RemoteChatSession.Data::read);
}, (buf, entry) -> {
- buf.writeNullable(entry.chatSession, RemoteChatSession.Data::write);
+ // Paper start
+ // Paper start - Prevent causing expired keys from impacting new joins
+ RemoteChatSession.Data chatSession = entry.chatSession;
+ if (chatSession != null && chatSession.profilePublicKey().hasExpired()) {
+ chatSession = null;
+ }
+ buf.writeNullable(chatSession, RemoteChatSession.Data::write);
+ // Paper end
+ // Paper end - Prevent causing expired keys from impacting new joins
}),
UPDATE_GAME_MODE((serialized, buf) -> {
serialized.gameMode = GameType.byId(buf.readVarInt());
@ -31,7 +31,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private int knownMovePacketCount;
@Nullable
private RemoteChatSession chatSession;
+ private boolean hasLoggedExpiry = false; // Paper
+ private boolean hasLoggedExpiry = false; // Paper - Prevent causing expired keys from impacting new joins
private SignedMessageChain.Decoder signedMessageDecoder;
private final LastSeenMessagesValidator lastSeenMessages = new LastSeenMessagesValidator(20);
private final MessageSignatureCache messageSignatureCache = MessageSignatureCache.createDefault();
@ -39,12 +39,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.disconnect(Component.translatable("multiplayer.disconnect.idling"), org.bukkit.event.player.PlayerKickEvent.Cause.IDLING); // Paper - kick event cause
}
+ // Paper start
+ // Paper start - Prevent causing expired keys from impacting new joins
+ if (!hasLoggedExpiry && this.chatSession != null && this.chatSession.profilePublicKey().data().hasExpired()) {
+ LOGGER.info("Player profile key for {} has expired!", this.player.getName().getString());
+ hasLoggedExpiry = true;
+ }
+ // Paper end
+ // Paper end - Prevent causing expired keys from impacting new joins
+
}
@ -53,7 +53,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private void resetPlayerChatState(RemoteChatSession session) {
this.chatSession = session;
+ this.hasLoggedExpiry = false; // Paper
+ this.hasLoggedExpiry = false; // Paper - Prevent causing expired keys from impacting new joins
this.signedMessageDecoder = session.createMessageDecoder(this.player.getUUID());
this.chatMessageChain.append(() -> {
this.player.setChatSession(session);

View file

@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Tue, 23 May 2023 22:33:36 -0400
Subject: [PATCH] Properly Cancel Usable Items
Subject: [PATCH] Properly cancel usable items
This fixes the bug causing cancelling PlayerInteractEvent to cause items to continue to be used despite being cancelled on the server.
@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
// Paper end - extend Player Interact cancellation
player.getBukkitEntity().updateInventory(); // SPIGOT-2867
+ this.player.resyncUsingItem(this.player); // Paper - Resend player's using item status
+ this.player.resyncUsingItem(this.player); // Paper - Properly cancel usable items
enuminteractionresult = (event.useItemInHand() != Event.Result.ALLOW) ? InteractionResult.SUCCESS : InteractionResult.PASS;
} else if (this.gameModeForPlayer == GameType.SPECTATOR) {
MenuProvider itileinventory = iblockdata.getMenuProvider(world, blockposition);
@ -25,11 +25,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return enuminteractionresult1;
}
+ // Paper start - Cancel only if cancelled + if the interact result is different from default response
+ // Paper start - Properly cancel usable items; Cancel only if cancelled + if the interact result is different from default response
+ else if (this.interactResult && this.interactResult != cancelledItem) {
+ this.player.resyncUsingItem(this.player);
+ }
+ // Paper end
+ // Paper end - Properly cancel usable items
}
return enuminteractionresult;
// CraftBukkit end
@ -41,7 +41,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
if (cancelled) {
+ this.player.resyncUsingItem(this.player); // Paper - Resend player's using item status
+ this.player.resyncUsingItem(this.player); // Paper - Properly cancel usable items
this.player.getBukkitEntity().updateInventory(); // SPIGOT-2524
return;
}
@ -53,11 +53,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return ((Byte) this.entityData.get(LivingEntity.DATA_LIVING_ENTITY_FLAGS) & 2) > 0 ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND;
}
+ // Paper start
+ // Paper start - Properly cancel usable items
+ public void resyncUsingItem(ServerPlayer serverPlayer) {
+ this.getEntityData().resendPossiblyDesyncedDataValues(java.util.List.of(DATA_LIVING_ENTITY_FLAGS), serverPlayer);
+ }
+ // Paper end
+ // Paper end - Properly cancel usable items
private void updatingUsingItem() {
if (this.isUsingItem()) {
if (ItemStack.isSameItem(this.getItemInHand(this.getUsedItemHand()), this.useItem)) {

View file

@ -21,7 +21,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public boolean inWorld = false;
public boolean generation;
public int maxAirTicks = this.getDefaultMaxAirSupply(); // CraftBukkit - SPIGOT-6907: re-implement LivingEntity#setMaximumAir()
+ @Nullable // Paper
+ @Nullable // Paper - Refresh ProjectileSource for projectiles
public org.bukkit.projectiles.ProjectileSource projectileSource; // For projectiles only
public boolean lastDamageCancelled; // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Keep track if the event was canceled
public boolean persistentInvisibility = false;
@ -35,16 +35,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
- this.projectileSource = (entity != null && entity.getBukkitEntity() instanceof ProjectileSource) ? (ProjectileSource) entity.getBukkitEntity() : null; // CraftBukkit
-
+ // Paper start - Fix null owners not being handled
+ // Paper start - Refresh ProjectileSource for projectiles
+ else {
+ this.ownerUUID = null;
+ this.cachedOwner = null;
+ this.projectileSource = null;
+ }
+ // Paper end
+ // Paper end - Refresh ProjectileSource for projectiles
+ this.refreshProjectileSource(false); // Paper
+ }
+ // Paper start
+ // Paper start - Refresh ProjectileSource for projectiles
+ public void refreshProjectileSource(boolean fillCache) {
+ if (fillCache) {
+ this.getOwner();
@ -53,13 +53,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.projectileSource = projSource;
+ }
}
+ // Paper end
+ // Paper end - Refresh ProjectileSource for projectiles
@Nullable
@Override
public Entity getOwner() {
if (this.cachedOwner != null && !this.cachedOwner.isRemoved()) {
+ this.refreshProjectileSource(false); // Paper
+ this.refreshProjectileSource(false); // Paper - Refresh ProjectileSource for projectiles
return this.cachedOwner;
} else {
if (this.ownerUUID != null) {
@ -67,7 +67,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
ServerLevel worldserver = (ServerLevel) world;
this.cachedOwner = worldserver.getEntity(this.ownerUUID);
+ this.refreshProjectileSource(false); // Paper
+ this.refreshProjectileSource(false); // Paper - Refresh ProjectileSource for projectiles
return this.cachedOwner;
}
}
@ -79,7 +79,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public final org.bukkit.projectiles.ProjectileSource getShooter() {
+ this.getHandle().refreshProjectileSource(true); // Paper
+ this.getHandle().refreshProjectileSource(true); // Paper - Refresh ProjectileSource for projectiles
return this.getHandle().projectileSource;
}

View file

@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
tryPreloadClass(net.minecraft.world.level.lighting.LayerLightEventListener.DummyLightLayerEventListener.class.getName());
tryPreloadClass(net.minecraft.world.level.lighting.LayerLightEventListener.class.getName());
tryPreloadClass(net.minecraft.util.ExceptionCollector.class.getName());
+ tryPreloadClass(io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.PlayerChunkLoaderData.class.getName());
+ tryPreloadClass(io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.PlayerChunkLoaderData.class.getName()); // Paper - Prepopulate BFS lookup for potatos
// Paper end
}
}

View file

@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public void ackBlockChangesUpTo(int sequence) {
if (sequence < 0) {
+ this.disconnect("Expected packet sequence nr >= 0", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper
+ this.disconnect("Expected packet sequence nr >= 0", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - Treat sequence violations like they should be
throw new IllegalArgumentException("Expected packet sequence nr >= 0");
} else {
this.ackBlockChangesUpTo = Math.max(sequence, this.ackBlockChangesUpTo);

View file

@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public static final GameRules.Key<GameRules.BooleanValue> RULE_DO_VINES_SPREAD = GameRules.register("doVinesSpread", GameRules.Category.UPDATES, GameRules.BooleanValue.create(true));
public static final GameRules.Key<GameRules.BooleanValue> RULE_ENDER_PEARLS_VANISH_ON_DEATH = GameRules.register("enderPearlsVanishOnDeath", GameRules.Category.PLAYER, GameRules.BooleanValue.create(true));
private final Map<GameRules.Key<?>, GameRules.Value<?>> rules;
+ private final GameRules.Value<?>[] gameruleArray; // Paper
+ private final GameRules.Value<?>[] gameruleArray; // Paper - Perf: Use array for gamerule storage
private static <T extends GameRules.Value<T>> GameRules.Key<T> register(String name, GameRules.Category category, GameRules.Type<T> type) {
GameRules.Key<T> gamerules_gamerulekey = new GameRules.Key<>(name, category);
@ -21,18 +21,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public GameRules() {
- this.rules = (Map) GameRules.GAME_RULE_TYPES.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, (entry) -> {
+ // Paper start - use this to ensure gameruleArray is initialized
+ // Paper start - Perf: Use array for gamerule storage
+ this((Map) GameRules.GAME_RULE_TYPES.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, (entry) -> {
return ((GameRules.Type) entry.getValue()).createRule();
- }));
+ })));
+ // Paper end
+ // Paper end - Perf: Use array for gamerule storage
}
private GameRules(Map<GameRules.Key<?>, GameRules.Value<?>> rules) {
this.rules = rules;
+
+ // Paper start
+ // Paper start - Perf: Use array for gamerule storage
+ int arraySize = rules.keySet().stream().mapToInt(key -> key.gameRuleIndex).max().orElse(-1) + 1;
+ GameRules.Value<?>[] values = new GameRules.Value[arraySize];
+
@ -41,12 +41,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ this.gameruleArray = values;
+ // Paper end
+ // Paper end - Perf: Use array for gamerule storage
}
public <T extends GameRules.Value<T>> T getRule(GameRules.Key<T> key) {
- return (T) this.rules.get(key); // CraftBukkit - decompile error
+ return key == null ? null : (T) this.gameruleArray[key.gameRuleIndex]; // Paper
+ return key == null ? null : (T) this.gameruleArray[key.gameRuleIndex]; // Paper - Perf: Use array for gamerule storage
}
public CompoundTag createTag() {
@ -54,10 +54,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
public static final class Key<T extends GameRules.Value<T>> {
+ // Paper start
+ // Paper start - Perf: Use array for gamerule storage
+ private static int lastGameRuleIndex = 0;
+ public final int gameRuleIndex = lastGameRuleIndex++;
+ // Paper end
+ // Paper end - Perf: Use array for gamerule storage
final String id;
private final GameRules.Category category;