some work
This commit is contained in:
@@ -1,45 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Noah van der Aa <ndvdaa@gmail.com>
|
||||
Date: Sun, 8 Aug 2021 19:56:02 +0200
|
||||
Subject: [PATCH] Add CompostItemEvent and EntityCompostItemEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java
|
||||
@@ -0,0 +0,0 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder {
|
||||
int i = (Integer) iblockdata.getValue(ComposterBlock.LEVEL);
|
||||
float f = ComposterBlock.COMPOSTABLES.getFloat(itemstack.getItem());
|
||||
|
||||
- if ((i != 0 || f <= 0.0F) && rand >= (double) f) {
|
||||
+ // Paper start
|
||||
+ boolean willRaiseLevel = !((i != 0 || f <= 0.0F) && rand >= (double) f);
|
||||
+ final io.papermc.paper.event.block.CompostItemEvent event;
|
||||
+ if (entity == null) {
|
||||
+ event = new io.papermc.paper.event.block.CompostItemEvent(org.bukkit.craftbukkit.block.CraftBlock.at(generatoraccess, blockposition), itemstack.getBukkitStack(), willRaiseLevel);
|
||||
+ } else {
|
||||
+ event = new io.papermc.paper.event.entity.EntityCompostItemEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(generatoraccess, blockposition), itemstack.getBukkitStack(), willRaiseLevel);
|
||||
+ }
|
||||
+ if (!event.callEvent()) { // check for cancellation of entity event (non entity event can't be cancelled cause of hoppers)
|
||||
+ return null;
|
||||
+ }
|
||||
+ willRaiseLevel = event.willRaiseLevel();
|
||||
+
|
||||
+ if (!willRaiseLevel) {
|
||||
+ // Paper end
|
||||
return iblockdata;
|
||||
} else {
|
||||
int j = i + 1;
|
||||
@@ -0,0 +0,0 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder {
|
||||
this.changed = true;
|
||||
BlockState iblockdata = ComposterBlock.addItem((Entity) null, this.state, this.level, this.pos, itemstack);
|
||||
|
||||
+ // Paper start
|
||||
+ if (iblockdata == null) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.level.levelEvent(1500, this.pos, iblockdata != this.state ? 1 : 0);
|
||||
this.removeItemNoUpdate(0);
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: TheTuso <piotrekpasztor@gmail.com>
|
||||
Date: Thu, 2 Feb 2023 16:40:41 +0100
|
||||
Subject: [PATCH] Add Entity Body Yaw 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 {
|
||||
public boolean isInPowderedSnow() {
|
||||
return getHandle().isInPowderSnow || getHandle().wasInPowderSnow; // depending on the location in the entity "tick" either could be needed.
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public double getX() {
|
||||
+ return this.entity.getX();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public double getY() {
|
||||
+ return this.entity.getY();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public double getZ() {
|
||||
+ return this.entity.getZ();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public float getPitch() {
|
||||
+ return this.entity.getXRot();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public float getYaw() {
|
||||
+ return this.entity.getBukkitYaw();
|
||||
+ }
|
||||
// Paper end
|
||||
// Paper Start - Collision API
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
this.damageItemStack0(this.getHandle().getItemBySlot(nmsSlot), amount, nmsSlot);
|
||||
}
|
||||
|
||||
+ @Override
|
||||
+ public float getBodyYaw() {
|
||||
+ return this.getHandle().getVisualRotationYInDegrees();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setBodyYaw(float bodyYaw) {
|
||||
+ this.getHandle().setYBodyRot(bodyYaw);
|
||||
+ }
|
||||
+
|
||||
private void damageItemStack0(net.minecraft.world.item.ItemStack nmsStack, int amount, net.minecraft.world.entity.EquipmentSlot slot) {
|
||||
nmsStack.hurtAndBreak(amount, this.getHandle(), livingEntity -> {
|
||||
if (slot != null) {
|
||||
@@ -1,104 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
|
||||
Date: Fri, 24 Jun 2022 12:39:34 +0200
|
||||
Subject: [PATCH] Add EntityFertilizeEggEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Turtle.java b/src/main/java/net/minecraft/world/entity/animal/Turtle.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java
|
||||
@@ -0,0 +0,0 @@ public class Turtle extends Animal {
|
||||
if (entityplayer == null && this.partner.getLoveCause() != null) {
|
||||
entityplayer = this.partner.getLoveCause();
|
||||
}
|
||||
+ // Paper start - Add EntityFertilizeEggEvent event
|
||||
+ io.papermc.paper.event.entity.EntityFertilizeEggEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityFertilizeEggEvent(this.animal, this.partner);
|
||||
+ if (event.isCancelled()) return;
|
||||
+ // Paper end - Add EntityFertilizeEggEvent event
|
||||
|
||||
if (entityplayer != null) {
|
||||
entityplayer.awardStat(Stats.ANIMALS_BRED);
|
||||
@@ -0,0 +0,0 @@ public class Turtle extends Animal {
|
||||
RandomSource randomsource = this.animal.getRandom();
|
||||
|
||||
if (this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
|
||||
- this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), randomsource.nextInt(7) + 1, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer)); // Paper;
|
||||
+ if(event.getExperience() > 0) this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), event.getExperience(), org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer)); // Paper - Add EntityFertilizeEggEvent event
|
||||
}
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java
|
||||
@@ -0,0 +0,0 @@ public class Frog extends Animal implements VariantHolder<FrogVariant> {
|
||||
|
||||
@Override
|
||||
public void spawnChildFromBreeding(ServerLevel world, Animal other) {
|
||||
- this.finalizeSpawnChildFromBreeding(world, other, (AgeableMob)null);
|
||||
+ // Paper start - Add EntityFertilizeEggEvent event
|
||||
+ final io.papermc.paper.event.entity.EntityFertilizeEggEvent result = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityFertilizeEggEvent(this, other);
|
||||
+ if (result.isCancelled()) return;
|
||||
+
|
||||
+ this.finalizeSpawnChildFromBreeding(world, other, (AgeableMob)null, result.getExperience()); // Paper - use craftbukkit call that takes experience amount
|
||||
+ // Paper end - Add EntityFertilizeEggEvent event
|
||||
this.getBrain().setMemory(MemoryModuleType.IS_PREGNANT, Unit.INSTANCE);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java
|
||||
@@ -0,0 +0,0 @@ public class Sniffer extends Animal {
|
||||
|
||||
@Override
|
||||
public void spawnChildFromBreeding(ServerLevel world, Animal other) {
|
||||
+ // Paper start - Add EntityFertilizeEggEvent event
|
||||
+ final io.papermc.paper.event.entity.EntityFertilizeEggEvent result = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityFertilizeEggEvent(this, other);
|
||||
+ if (result.isCancelled()) return;
|
||||
+ // Paper end - Add EntityFertilizeEggEvent event
|
||||
+
|
||||
ItemStack itemstack = new ItemStack(Items.SNIFFER_EGG);
|
||||
ItemEntity entityitem = new ItemEntity(world, this.position().x(), this.position().y(), this.position().z(), itemstack);
|
||||
|
||||
entityitem.setDefaultPickUpDelay();
|
||||
- this.finalizeSpawnChildFromBreeding(world, other, (AgeableMob) null);
|
||||
+ this.finalizeSpawnChildFromBreeding(world, other, (AgeableMob) null, result.getExperience()); // Paper - Add EntityFertilizeEggEvent event
|
||||
if (this.spawnAtLocation(entityitem) != null) { // Paper - call EntityDropItemEvent
|
||||
this.playSound(SoundEvents.SNIFFER_EGG_PLOP, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 0.5F);
|
||||
} // Paper
|
||||
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 {
|
||||
return event.callEvent();
|
||||
}
|
||||
// Paper end
|
||||
+
|
||||
+ // Paper start - add EntityFertilizeEggEvent
|
||||
+ /**
|
||||
+ * Calls the io.papermc.paper.event.entity.EntityFertilizeEggEvent.
|
||||
+ * If the event is cancelled, this method also resets the love on both the {@code breeding} and {@code other} entity.
|
||||
+ *
|
||||
+ * @param breeding the entity on which #spawnChildFromBreeding was called.
|
||||
+ * @param other the partner of the entity.
|
||||
+ * @return the event after it was called. The instance may be used to retrieve the experience of the event.
|
||||
+ */
|
||||
+ public static io.papermc.paper.event.entity.EntityFertilizeEggEvent callEntityFertilizeEggEvent(net.minecraft.world.entity.animal.Animal breeding,
|
||||
+ net.minecraft.world.entity.animal.Animal other) {
|
||||
+ net.minecraft.server.level.ServerPlayer serverPlayer = breeding.getLoveCause();
|
||||
+ if (serverPlayer == null) serverPlayer = other.getLoveCause();
|
||||
+ final int experience = breeding.getRandom().nextInt(7) + 1; // From Animal#spawnChildFromBreeding(ServerLevel, Animal)
|
||||
+
|
||||
+ final io.papermc.paper.event.entity.EntityFertilizeEggEvent event = new io.papermc.paper.event.entity.EntityFertilizeEggEvent((org.bukkit.entity.LivingEntity) breeding.getBukkitEntity(), (org.bukkit.entity.LivingEntity) other.getBukkitEntity(), serverPlayer == null ? null : serverPlayer.getBukkitEntity(), breeding.breedItem == null ? null : org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(breeding.breedItem).clone(), experience);
|
||||
+ if (!event.callEvent()) {
|
||||
+ breeding.resetLove();
|
||||
+ other.resetLove(); // stop the pathfinding to avoid infinite loop
|
||||
+ }
|
||||
+
|
||||
+ return event;
|
||||
+ }
|
||||
+ // Paper end - add EntityFertilizeEggEvent
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: GodOfPro <1387ilia@gmail.com>
|
||||
Date: Tue, 11 Apr 2023 16:31:39 +0430
|
||||
Subject: [PATCH] Add Mob Experience reward API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob {
|
||||
getHandle().setLeftHanded(leftHanded);
|
||||
}
|
||||
// Paper end
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getPossibleExperienceReward() {
|
||||
+ return getHandle().getExperienceReward();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Sun, 17 Oct 2021 15:39:48 -0400
|
||||
Subject: [PATCH] Add Shearable API
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/entity/PaperShearable.java b/src/main/java/io/papermc/paper/entity/PaperShearable.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/entity/PaperShearable.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.entity;
|
||||
+
|
||||
+import io.papermc.paper.adventure.PaperAdventure;
|
||||
+import net.kyori.adventure.sound.Sound;
|
||||
+import net.minecraft.world.entity.Shearable;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public interface PaperShearable extends io.papermc.paper.entity.Shearable {
|
||||
+
|
||||
+ Shearable getHandle();
|
||||
+
|
||||
+ @Override
|
||||
+ default boolean readyToBeSheared() {
|
||||
+ return this.getHandle().readyForShearing();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default void shear(@NotNull Sound.Source source) {
|
||||
+ this.getHandle().shear(PaperAdventure.asVanilla(source));
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.MushroomCow;
|
||||
import org.bukkit.entity.MushroomCow.Variant;
|
||||
|
||||
-public class CraftMushroomCow extends CraftCow implements MushroomCow {
|
||||
+public class CraftMushroomCow extends CraftCow implements MushroomCow, io.papermc.paper.entity.PaperShearable { // Paper
|
||||
public CraftMushroomCow(CraftServer server, net.minecraft.world.entity.animal.MushroomCow entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSheep.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSheep.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSheep.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSheep.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.DyeColor;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Sheep;
|
||||
|
||||
-public class CraftSheep extends CraftAnimals implements Sheep {
|
||||
+public class CraftSheep extends CraftAnimals implements Sheep, io.papermc.paper.entity.PaperShearable { // Paper
|
||||
public CraftSheep(CraftServer server, net.minecraft.world.entity.animal.Sheep entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.entity.animal.SnowGolem;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Snowman;
|
||||
|
||||
-public class CraftSnowman extends CraftGolem implements Snowman, com.destroystokyo.paper.entity.CraftRangedEntity<SnowGolem> { // Paper
|
||||
+public class CraftSnowman extends CraftGolem implements Snowman, com.destroystokyo.paper.entity.CraftRangedEntity<SnowGolem>, io.papermc.paper.entity.PaperShearable { // Paper
|
||||
public CraftSnowman(CraftServer server, SnowGolem entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Fri, 23 Jun 2023 12:16:28 -0700
|
||||
Subject: [PATCH] Add Sign#getInteractableSideFor
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C
|
||||
}
|
||||
|
||||
public boolean isFacingFrontText(net.minecraft.world.entity.player.Player player) {
|
||||
+ // Paper start
|
||||
+ return this.isFacingFrontText(player.getX(), player.getZ());
|
||||
+ }
|
||||
+ public boolean isFacingFrontText(double x, double z) {
|
||||
+ // Paper end
|
||||
Block block = this.getBlockState().getBlock();
|
||||
|
||||
if (block instanceof SignBlock) {
|
||||
SignBlock blocksign = (SignBlock) block;
|
||||
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
|
||||
float f = blocksign.getYRotationDegrees(this.getBlockState());
|
||||
float f1 = (float) (Mth.atan2(d1, d0) * 57.2957763671875D) - 90.0F;
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java b/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java
|
||||
@@ -0,0 +0,0 @@ public class CraftSign<T extends SignBlockEntity> extends CraftBlockEntityState<
|
||||
}
|
||||
// Paper end
|
||||
|
||||
+ // Paper start - side facing API
|
||||
+ @Override
|
||||
+ public Side getInteractableSideFor(final double x, final double z) {
|
||||
+ this.requirePlaced();
|
||||
+ return this.getSnapshot().isFacingFrontText(x, z) ? Side.FRONT : Side.BACK;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public static Component[] sanitizeLines(String[] lines) {
|
||||
Component[] components = new Component[4];
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: by77er <by77er@gmail.com>
|
||||
Date: Mon, 12 Jun 2023 12:56:46 -0400
|
||||
Subject: [PATCH] Add event for player editing sign
|
||||
|
||||
|
||||
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 {
|
||||
try {
|
||||
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
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/SignBlock.java b/src/main/java/net/minecraft/world/level/block/SignBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/SignBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/SignBlock.java
|
||||
@@ -0,0 +0,0 @@ public abstract class SignBlock extends BaseEntityBlock implements SimpleWaterlo
|
||||
} else if (flag2) {
|
||||
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
|
||||
return InteractionResult.SUCCESS;
|
||||
} else {
|
||||
return InteractionResult.PASS;
|
||||
@@ -0,0 +0,0 @@ public abstract class SignBlock extends BaseEntityBlock implements SimpleWaterlo
|
||||
return blockpropertywood;
|
||||
}
|
||||
|
||||
+ @io.papermc.paper.annotation.DoNotUse @Deprecated // Paper
|
||||
public void openTextEdit(Player player, SignBlockEntity blockEntity, boolean front) {
|
||||
- // Craftbukkit start
|
||||
- this.openTextEdit(player, blockEntity, front, org.bukkit.event.player.PlayerSignOpenEvent.Cause.UNKNOWN);
|
||||
+ // Paper start - PlayerOpenSignEvent
|
||||
+ this.openTextEdit(player, blockEntity, front, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.UNKNOWN);
|
||||
}
|
||||
-
|
||||
- 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)) {
|
||||
+ public void openTextEdit(Player entityhuman, SignBlockEntity tileentitysign, boolean flag, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause cause) {
|
||||
+ org.bukkit.entity.Player bukkitPlayer = (org.bukkit.entity.Player) entityhuman.getBukkitEntity();
|
||||
+ org.bukkit.block.Block bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(tileentitysign.getLevel(), tileentitysign.getBlockPos());
|
||||
+ org.bukkit.craftbukkit.block.CraftSign<?> bukkitSign = (org.bukkit.craftbukkit.block.CraftSign<?>) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(bukkitBlock);
|
||||
+ io.papermc.paper.event.player.PlayerOpenSignEvent event = new io.papermc.paper.event.player.PlayerOpenSignEvent(
|
||||
+ bukkitPlayer,
|
||||
+ bukkitSign,
|
||||
+ flag ? org.bukkit.block.sign.Side.FRONT : org.bukkit.block.sign.Side.BACK,
|
||||
+ cause);
|
||||
+ if (!event.callEvent()) return;
|
||||
+ if (org.bukkit.event.player.PlayerSignOpenEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||
+ final org.bukkit.event.player.PlayerSignOpenEvent.Cause legacyCause = switch (cause) {
|
||||
+ case PLACE -> org.bukkit.event.player.PlayerSignOpenEvent.Cause.PLACE;
|
||||
+ case PLUGIN -> org.bukkit.event.player.PlayerSignOpenEvent.Cause.PLUGIN;
|
||||
+ 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
|
||||
return;
|
||||
}
|
||||
- // Craftbukkit end
|
||||
+ } // Paper
|
||||
tileentitysign.setAllowedPlayerEditor(entityhuman.getUUID());
|
||||
entityhuman.openTextEdit(tileentitysign, flag);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java b/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java
|
||||
@@ -0,0 +0,0 @@ public class CraftSign<T extends SignBlockEntity> extends CraftBlockEntityState<
|
||||
Preconditions.checkArgument(sign.isPlaced(), "Sign must be placed");
|
||||
Preconditions.checkArgument(sign.getWorld() == player.getWorld(), "Sign must be in same world as Player");
|
||||
|
||||
+ // Paper start
|
||||
+ 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
|
||||
if (!CraftEventFactory.callPlayerSignOpenEvent(player, sign, side, PlayerSignOpenEvent.Cause.PLUGIN)) {
|
||||
return;
|
||||
}
|
||||
+ } // Paper
|
||||
|
||||
SignBlockEntity handle = ((CraftSign<?>) sign).getTileEntity();
|
||||
handle.setAllowedPlayerEditor(player.getUniqueId());
|
||||
@@ -1,24 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sat, 17 Jun 2023 13:17:25 -0700
|
||||
Subject: [PATCH] Add method to remove all active potion effects
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
return effects;
|
||||
}
|
||||
|
||||
+ // Paper start - LivingEntity#clearActivePotionEffects();
|
||||
+ @Override
|
||||
+ public boolean clearActivePotionEffects() {
|
||||
+ return this.getHandle().removeAllEffects(EntityPotionEffectEvent.Cause.PLUGIN);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public <T extends Projectile> T launchProjectile(Class<? extends T> projectile) {
|
||||
return this.launchProjectile(projectile, null);
|
||||
@@ -1,175 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Boy <sivertpaulsen2@gmail.com>
|
||||
Date: Sun, 18 Jun 2023 17:45:33 +0200
|
||||
Subject: [PATCH] Add option to disable block updates
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/ChorusPlantBlock.java b/src/main/java/net/minecraft/world/level/block/ChorusPlantBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/ChorusPlantBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/ChorusPlantBlock.java
|
||||
@@ -0,0 +0,0 @@ public class ChorusPlantBlock extends PipeBlock {
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext ctx) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableChorusPlantUpdates) return this.defaultBlockState(); // Paper - add option to disable block updates
|
||||
return this.getStateForPlacement(ctx.getLevel(), ctx.getClickedPos());
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ChorusPlantBlock extends PipeBlock {
|
||||
|
||||
@Override
|
||||
public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableChorusPlantUpdates) return state; // Paper - add option to disable block updates
|
||||
if (!state.canSurvive(world, pos)) {
|
||||
world.scheduleTick(pos, this, 1);
|
||||
return super.updateShape(state, direction, neighborState, world, pos, neighborPos);
|
||||
@@ -0,0 +0,0 @@ public class ChorusPlantBlock extends PipeBlock {
|
||||
|
||||
@Override
|
||||
public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableChorusPlantUpdates) return; // Paper - add option to disable block updates
|
||||
if (!state.canSurvive(world, pos)) {
|
||||
world.destroyBlock(pos, true);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class ChorusPlantBlock extends PipeBlock {
|
||||
|
||||
@Override
|
||||
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableChorusPlantUpdates) return true; // Paper - add option to disable block updates
|
||||
BlockState blockState = world.getBlockState(pos.below());
|
||||
boolean bl = !world.getBlockState(pos.above()).isAir() && !blockState.isAir();
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/HugeMushroomBlock.java b/src/main/java/net/minecraft/world/level/block/HugeMushroomBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/HugeMushroomBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/HugeMushroomBlock.java
|
||||
@@ -0,0 +0,0 @@ public class HugeMushroomBlock extends Block {
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext ctx) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return this.defaultBlockState(); // Paper - add option to disable block updates
|
||||
BlockGetter blockGetter = ctx.getLevel();
|
||||
BlockPos blockPos = ctx.getClickedPos();
|
||||
return this.defaultBlockState().setValue(DOWN, Boolean.valueOf(!blockGetter.getBlockState(blockPos.below()).is(this))).setValue(UP, Boolean.valueOf(!blockGetter.getBlockState(blockPos.above()).is(this))).setValue(NORTH, Boolean.valueOf(!blockGetter.getBlockState(blockPos.north()).is(this))).setValue(EAST, Boolean.valueOf(!blockGetter.getBlockState(blockPos.east()).is(this))).setValue(SOUTH, Boolean.valueOf(!blockGetter.getBlockState(blockPos.south()).is(this))).setValue(WEST, Boolean.valueOf(!blockGetter.getBlockState(blockPos.west()).is(this)));
|
||||
@@ -0,0 +0,0 @@ public class HugeMushroomBlock extends Block {
|
||||
|
||||
@Override
|
||||
public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return state; // Paper - add option to disable block updates
|
||||
return neighborState.is(this) ? state.setValue(PROPERTY_BY_DIRECTION.get(direction), Boolean.valueOf(false)) : super.updateShape(state, direction, neighborState, world, pos, neighborPos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState rotate(BlockState state, Rotation rotation) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return state; // Paper - add option to disable block updates
|
||||
return state.setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.NORTH)), state.getValue(NORTH)).setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.SOUTH)), state.getValue(SOUTH)).setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.EAST)), state.getValue(EAST)).setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.WEST)), state.getValue(WEST)).setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.UP)), state.getValue(UP)).setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.DOWN)), state.getValue(DOWN));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState mirror(BlockState state, Mirror mirror) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return state; // Paper - add option to disable block updates
|
||||
return state.setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.NORTH)), state.getValue(NORTH)).setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.SOUTH)), state.getValue(SOUTH)).setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.EAST)), state.getValue(EAST)).setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.WEST)), state.getValue(WEST)).setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.UP)), state.getValue(UP)).setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.DOWN)), state.getValue(DOWN));
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/NoteBlock.java b/src/main/java/net/minecraft/world/level/block/NoteBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/NoteBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/NoteBlock.java
|
||||
@@ -0,0 +0,0 @@ public class NoteBlock extends Block {
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext ctx) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) return this.defaultBlockState(); // Paper - place without considering instrument
|
||||
return this.setInstrument(ctx.getLevel(), ctx.getClickedPos(), this.defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) return state; // Paper - prevent noteblock instrument from updating
|
||||
boolean flag = direction.getAxis() == Direction.Axis.Y;
|
||||
|
||||
return flag ? this.setInstrument(world, pos, state) : super.updateShape(state, direction, neighborState, world, pos, neighborPos);
|
||||
@@ -0,0 +0,0 @@ public class NoteBlock extends Block {
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) return; // Paper - prevent noteblock powered-state from updating
|
||||
boolean flag1 = world.hasNeighborSignal(pos);
|
||||
|
||||
if (flag1 != (Boolean) state.getValue(NoteBlock.POWERED)) {
|
||||
@@ -0,0 +0,0 @@ public class NoteBlock extends Block {
|
||||
} else if (world.isClientSide) {
|
||||
return InteractionResult.SUCCESS;
|
||||
} else {
|
||||
- state = (BlockState) state.cycle(NoteBlock.NOTE);
|
||||
+ if (!io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) state = (BlockState) state.cycle(NoteBlock.NOTE); // Paper - prevent noteblock note from updating
|
||||
world.setBlock(pos, state, 3);
|
||||
this.playNote(player, state, world, pos);
|
||||
player.awardStat(Stats.TUNE_NOTEBLOCK);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/TripWireBlock.java b/src/main/java/net/minecraft/world/level/block/TripWireBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/TripWireBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/TripWireBlock.java
|
||||
@@ -0,0 +0,0 @@ public class TripWireBlock extends Block {
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext ctx) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return this.defaultBlockState(); // Paper - place tripwire without updating
|
||||
Level world = ctx.getLevel();
|
||||
BlockPos blockposition = ctx.getClickedPos();
|
||||
|
||||
@@ -0,0 +0,0 @@ public class TripWireBlock extends Block {
|
||||
|
||||
@Override
|
||||
public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return state; // Paper - prevent tripwire from updating
|
||||
return direction.getAxis().isHorizontal() ? (BlockState) state.setValue((Property) TripWireBlock.PROPERTY_BY_DIRECTION.get(direction), this.shouldConnectTo(neighborState, direction)) : super.updateShape(state, direction, neighborState, world, pos, neighborPos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating
|
||||
if (!oldState.is(state.getBlock())) {
|
||||
this.updateSource(world, pos, state);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class TripWireBlock extends Block {
|
||||
|
||||
@Override
|
||||
public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean moved) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating
|
||||
if (!moved && !state.is(newState.getBlock())) {
|
||||
this.updateSource(world, pos, (BlockState) state.setValue(TripWireBlock.POWERED, true), true); // Paper - fix state inconsistency
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class TripWireBlock extends Block {
|
||||
|
||||
@Override
|
||||
public void playerWillDestroy(Level world, BlockPos pos, BlockState state, Player player) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent disarming tripwires
|
||||
if (!world.isClientSide && !player.getMainHandItem().isEmpty() && player.getMainHandItem().is(Items.SHEARS)) {
|
||||
world.setBlock(pos, (BlockState) state.setValue(TripWireBlock.DISARMED, true), 4);
|
||||
world.gameEvent((Entity) player, GameEvent.SHEAR, pos);
|
||||
@@ -0,0 +0,0 @@ public class TripWireBlock extends Block {
|
||||
}
|
||||
|
||||
private void updateSource(Level world, BlockPos pos, BlockState state) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating
|
||||
// Paper start - fix state inconsistency
|
||||
this.updateSource(world, pos, state, false);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class TripWireBlock extends Block {
|
||||
|
||||
@Override
|
||||
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent tripwires from detecting collision
|
||||
if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
|
||||
if (!world.isClientSide) {
|
||||
if (!(Boolean) state.getValue(TripWireBlock.POWERED)) {
|
||||
@@ -0,0 +0,0 @@ public class TripWireBlock extends Block {
|
||||
|
||||
@Override
|
||||
public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent tripwire pressed check
|
||||
if ((Boolean) world.getBlockState(pos).getValue(TripWireBlock.POWERED)) {
|
||||
this.checkPressed(world, pos);
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Malfrador <malfrador@gmail.com>
|
||||
Date: Wed, 31 May 2023 23:30:00 +0200
|
||||
Subject: [PATCH] Add transient 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 @@ public class UnmodifiableAttributeInstance extends CraftAttributeInstance {
|
||||
throw new UnsupportedOperationException("Cannot modify default attributes");
|
||||
}
|
||||
|
||||
+ @Override
|
||||
+ public void addTransientModifier(AttributeModifier modifier) {
|
||||
+ throw new UnsupportedOperationException("Cannot modify default attributes");
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public void removeModifier(AttributeModifier modifier) {
|
||||
throw new UnsupportedOperationException("Cannot modify default attributes");
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java
|
||||
index 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 {
|
||||
this.handle.addPermanentModifier(CraftAttributeInstance.convert(modifier));
|
||||
}
|
||||
|
||||
+ // Paper start - Transient modifier API
|
||||
+ @Override
|
||||
+ public void addTransientModifier(AttributeModifier modifier) {
|
||||
+ Preconditions.checkArgument(modifier != null, "modifier");
|
||||
+ this.handle.addTransientModifier(CraftAttributeInstance.convert(modifier));
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void removeModifier(AttributeModifier modifier) {
|
||||
Preconditions.checkArgument(modifier != null, "modifier");
|
||||
@@ -1,56 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: jellysquid3 <jellysquid3@users.noreply.github.com>
|
||||
Date: Sat, 8 Jul 2023 21:38:05 +0200
|
||||
Subject: [PATCH] Array backed synched entity data
|
||||
|
||||
Original code by jellysquid3 in Lithium, licensed under the GNU Lesser General Public License v3.0 (https://www.gnu.org/licenses/lgpl-3.0.html)
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java b/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java
|
||||
+++ b/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java
|
||||
@@ -0,0 +0,0 @@ public class SynchedEntityData {
|
||||
private final Int2ObjectMap<SynchedEntityData.DataItem<?>> itemsById = new Int2ObjectOpenHashMap();
|
||||
// private final ReadWriteLock lock = new ReentrantReadWriteLock(); // Spigot - not required
|
||||
private boolean isDirty;
|
||||
+ // Paper start - array backed synched entity data
|
||||
+ 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
|
||||
|
||||
public SynchedEntityData(Entity trackedEntity) {
|
||||
this.entity = trackedEntity;
|
||||
@@ -0,0 +0,0 @@ public class SynchedEntityData {
|
||||
// this.lock.writeLock().lock(); // Spigot - not required
|
||||
this.itemsById.put(key.getId(), datawatcher_item);
|
||||
// this.lock.writeLock().unlock(); // Spigot - not required
|
||||
+ // Paper start - array backed synched entity data
|
||||
+ if (this.itemsArray.length <= key.getId()) {
|
||||
+ final int newSize = Math.min(key.getId() + GROW_FACTOR, MAX_ID_VALUE);
|
||||
+
|
||||
+ this.itemsArray = java.util.Arrays.copyOf(this.itemsArray, newSize);
|
||||
+ }
|
||||
+
|
||||
+ this.itemsArray[key.getId()] = datawatcher_item;
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public <T> boolean hasItem(EntityDataAccessor<T> key) {
|
||||
@@ -0,0 +0,0 @@ public class SynchedEntityData {
|
||||
|
||||
return datawatcher_item;
|
||||
*/
|
||||
- return (SynchedEntityData.DataItem) this.itemsById.get(key.getId());
|
||||
+ // Paper start - array backed synched entity data
|
||||
+ final int id = key.getId();
|
||||
+
|
||||
+ if (id < 0 || id >= this.itemsArray.length) {
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ return (DataItem<T>) this.itemsArray[id];
|
||||
+ // Paper end
|
||||
// Spigot end
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Sun, 14 May 2023 00:47:28 -0400
|
||||
Subject: [PATCH] Avoid Lazy Initialization for Enum Fields
|
||||
|
||||
This patch is meant to get rid of any instances of lazy initialization that Minecraft introduces for enums.
|
||||
This has the possibility to create race condition issues, and generally don't make sense to be lazily done anyways.
|
||||
|
||||
diff --git a/src/main/java/com/mojang/math/OctahedralGroup.java b/src/main/java/com/mojang/math/OctahedralGroup.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/mojang/math/OctahedralGroup.java
|
||||
+++ b/src/main/java/com/mojang/math/OctahedralGroup.java
|
||||
@@ -0,0 +0,0 @@ public enum OctahedralGroup implements StringRepresentable {
|
||||
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
|
||||
}
|
||||
|
||||
private BooleanList packInversions() {
|
||||
@@ -0,0 +0,0 @@ public enum OctahedralGroup implements StringRepresentable {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
- public Direction rotate(Direction direction) {
|
||||
+ public void initializeRotationDirections() { // Paper
|
||||
if (this.rotatedDirections == null) {
|
||||
this.rotatedDirections = Maps.newEnumMap(Direction.class);
|
||||
Direction.Axis[] axiss = Direction.Axis.values();
|
||||
@@ -0,0 +0,0 @@ public enum OctahedralGroup implements StringRepresentable {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Move lazy initialization to constructor
|
||||
+ }
|
||||
+ public Direction rotate(Direction direction) {
|
||||
+ // Paper end
|
||||
return this.rotatedDirections.get(direction);
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Mon, 1 May 2023 18:31:26 -0700
|
||||
Subject: [PATCH] Break redstone on top of trap doors early
|
||||
|
||||
This logic hooks into the neighbour update which should be invoked
|
||||
as a result of redstone powering the trap door.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/TrapDoorBlock.java b/src/main/java/net/minecraft/world/level/block/TrapDoorBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/TrapDoorBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/TrapDoorBlock.java
|
||||
@@ -0,0 +0,0 @@ public class TrapDoorBlock extends HorizontalDirectionalBlock implements SimpleW
|
||||
flag1 = eventRedstone.getNewCurrent() > 0;
|
||||
}
|
||||
// CraftBukkit end
|
||||
- if ((Boolean) state.getValue(TrapDoorBlock.OPEN) != flag1) {
|
||||
+ boolean open = (Boolean) state.getValue(TrapDoorBlock.OPEN) != flag1; // Paper - break redstone on trapdoors early
|
||||
+ // Paper start - break redstone on trapdoors early
|
||||
+ // note: this must run before any state for this block/its neighborus are written to the world
|
||||
+ // we allow the redstone event to fire so that plugins can block
|
||||
+ if (flag1 && open) { // if we are now powered and it caused the trap door to open
|
||||
+ // in this case, first check for the redstone on top first
|
||||
+ BlockPos abovePos = pos.above();
|
||||
+ BlockState above = world.getBlockState(abovePos);
|
||||
+ if (above.getBlock() instanceof RedStoneWireBlock) {
|
||||
+ world.setBlock(abovePos, Blocks.AIR.defaultBlockState(), Block.UPDATE_CLIENTS | Block.UPDATE_NEIGHBORS);
|
||||
+ Block.popResource(world, abovePos, new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.REDSTONE));
|
||||
+ // now check that this didn't change our state
|
||||
+ if (world.getBlockState(pos) != state) {
|
||||
+ // our state was changed, so we cannot propagate this update
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - break redstone on trapdoors early
|
||||
+ if (open) { // Paper - break redstone on trapdoors early
|
||||
state = (BlockState) state.setValue(TrapDoorBlock.OPEN, flag1);
|
||||
this.playSound((Player) null, world, pos, flag1);
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
|
||||
Date: Fri, 9 Jun 2023 13:04:42 +0200
|
||||
Subject: [PATCH] Call BlockGrowEvent for missing blocks
|
||||
|
||||
Call the event for pitcher crops and sniffer egg
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java b/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java
|
||||
@@ -0,0 +0,0 @@ public class PitcherCropBlock extends DoublePlantBlock implements BonemealableBl
|
||||
private void grow(ServerLevel world, BlockState state, BlockPos pos, int amount) {
|
||||
int i = Math.min(state.getValue(AGE) + amount, 4);
|
||||
if (this.canGrow(world, pos, state, i)) {
|
||||
- world.setBlock(pos, state.setValue(AGE, Integer.valueOf(i)), 2);
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, pos, state.setValue(AGE, Integer.valueOf(i)), 2)) return; // Paper
|
||||
if (i >= 3) {
|
||||
BlockPos blockPos = pos.above();
|
||||
world.setBlock(blockPos, copyWaterloggedFrom(world, pos, this.defaultBlockState().setValue(AGE, Integer.valueOf(i)).setValue(HALF, DoubleBlockHalf.UPPER)), 3);
|
||||
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 {
|
||||
@Override
|
||||
public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
|
||||
if (!this.isReadyToHatch(state)) {
|
||||
+ // Paper start
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, pos, state.setValue(HATCH, Integer.valueOf(this.getHatchLevel(state) + 1)), 2)) {
|
||||
+ rescheduleTick(world, pos);
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
world.playSound((Player)null, pos, SoundEvents.SNIFFER_EGG_CRACK, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F);
|
||||
- world.setBlock(pos, state.setValue(HATCH, Integer.valueOf(this.getHatchLevel(state) + 1)), 2);
|
||||
} else {
|
||||
// Paper start - Call BlockFadeEvent
|
||||
if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, state.getFluidState().createLegacyBlock()).isCancelled()) {
|
||||
@@ -1,88 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
|
||||
Date: Sat, 29 Oct 2022 15:41:56 +0200
|
||||
Subject: [PATCH] Call missing BlockDispenseEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
|
||||
+++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
|
||||
@@ -0,0 +0,0 @@ public interface DispenseItemBehavior {
|
||||
this.setSuccess(true);
|
||||
if (iblockdata.is(Blocks.RESPAWN_ANCHOR)) {
|
||||
if ((Integer) iblockdata.getValue(RespawnAnchorBlock.CHARGE) != 4) {
|
||||
+ // Paper start
|
||||
+ ItemStack result = org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDispenseEvent(pointer, blockposition, stack, this);
|
||||
+ if (result != null) {
|
||||
+ this.setSuccess(false);
|
||||
+ return result;
|
||||
+ }
|
||||
+ // Paper end
|
||||
RespawnAnchorBlock.charge((Entity) null, worldserver, blockposition, iblockdata);
|
||||
stack.shrink(1);
|
||||
} else {
|
||||
@@ -0,0 +0,0 @@ public interface DispenseItemBehavior {
|
||||
Optional<BlockState> optional = HoneycombItem.getWaxed(iblockdata);
|
||||
|
||||
if (optional.isPresent()) {
|
||||
+ // Paper start
|
||||
+ ItemStack result = org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDispenseEvent(pointer, blockposition, stack, this);
|
||||
+ if (result != null) {
|
||||
+ this.setSuccess(false);
|
||||
+ return result;
|
||||
+ }
|
||||
+ // Paper end
|
||||
worldserver.setBlockAndUpdate(blockposition, (BlockState) optional.get());
|
||||
worldserver.levelEvent(3003, blockposition, 0);
|
||||
stack.shrink(1);
|
||||
@@ -0,0 +0,0 @@ public interface DispenseItemBehavior {
|
||||
if (!worldserver.getBlockState(blockposition1).is(BlockTags.CONVERTABLE_TO_MUD)) {
|
||||
return this.defaultDispenseItemBehavior.dispense(pointer, stack);
|
||||
} else {
|
||||
+ // Paper start
|
||||
+ ItemStack result = org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDispenseEvent(pointer, blockposition1, stack, this);
|
||||
+ if (result != null) {
|
||||
+ return result;
|
||||
+ }
|
||||
+ // Paper end
|
||||
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);
|
||||
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 {
|
||||
}
|
||||
// Paper end
|
||||
|
||||
+ // Paper start - missing BlockDispenseEvent calls
|
||||
+ @Nullable
|
||||
+ public static ItemStack handleBlockDispenseEvent(net.minecraft.core.BlockSource pointer, BlockPos to, ItemStack itemStack, net.minecraft.core.dispenser.DispenseItemBehavior instance) {
|
||||
+ org.bukkit.block.Block bukkitBlock = pointer.getLevel().getWorld().getBlockAt(pointer.getPos().getX(), pointer.getPos().getY(), pointer.getPos().getZ());
|
||||
+ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemStack.copyWithCount(1));
|
||||
+
|
||||
+ org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(to.getX(), to.getY(), to.getZ()));
|
||||
+ if (!net.minecraft.world.level.block.DispenserBlock.eventFired) {
|
||||
+ if (!event.callEvent()) {
|
||||
+ return itemStack;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ // Chain to handler for new item
|
||||
+ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem());
|
||||
+ net.minecraft.core.dispenser.DispenseItemBehavior idispensebehavior = net.minecraft.world.level.block.DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem());
|
||||
+ if (idispensebehavior != net.minecraft.core.dispenser.DispenseItemBehavior.NOOP && idispensebehavior != instance) {
|
||||
+ idispensebehavior.dispense(pointer, eventStack);
|
||||
+ return itemStack;
|
||||
+ }
|
||||
+ }
|
||||
+ return null;
|
||||
+ }
|
||||
+ // Paper end - missing BlockDispenseEvent calls
|
||||
+
|
||||
// Paper start - add EntityFertilizeEggEvent
|
||||
/**
|
||||
* Calls the io.papermc.paper.event.entity.EntityFertilizeEggEvent.
|
||||
@@ -1,25 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 5 Mar 2023 14:38:21 -0800
|
||||
Subject: [PATCH] Correctly handle ArmorStand invisibility
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
@@ -0,0 +0,0 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
this.getHandle().noPhysics = !gravity;
|
||||
}
|
||||
|
||||
+ // Paper start - Armor Stand has its own invisible field
|
||||
+ @Override
|
||||
+ public void setInvisible(final boolean invisible) {
|
||||
+ this.getHandle().setInvisible(invisible);
|
||||
+ super.setInvisible(invisible);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
return !this.getHandle().isInvisible();
|
||||
@@ -1,36 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Bjarne Koll <git@lynxplay.dev>
|
||||
Date: Tue, 10 Jan 2023 21:06:42 +0100
|
||||
Subject: [PATCH] Correctly shrink items during EntityResurrectEvent
|
||||
|
||||
The EntityResurrectEvent logic is supposed to locate a totem of undying
|
||||
in any of the interaction slots of the player inventory and then, if the
|
||||
called EntityResurrectEvent is not cancelled, shrink that item by 1,
|
||||
usually reducing it to zero.
|
||||
|
||||
For this, the logic iterates over the items in the interaction slots and
|
||||
breaks out the loop if a totem of undying was found.
|
||||
However, even if no totem of undying was found, the iteration item stack
|
||||
variable remains as a refernce to the last interaction slot probed.
|
||||
|
||||
Plugins uncancelling a EntityResurrectEvent, which is published
|
||||
pre-cancelled to listeners if no totem of undying could be found,
|
||||
would hence cause the server logic to shrink completely unrelated items
|
||||
found in, at the writing of this patch, the players off hand slot.
|
||||
|
||||
This patch corrects this behaviour by only shrinking the item if a totem
|
||||
of undying was found and the event was called uncancelled.
|
||||
|
||||
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 {
|
||||
this.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
|
||||
if (!event.isCancelled()) {
|
||||
- if (!itemstack1.isEmpty()) {
|
||||
+ if (!itemstack1.isEmpty() && itemstack != null) { // Paper - only reduce item if actual totem was found
|
||||
itemstack1.shrink(1);
|
||||
}
|
||||
if (itemstack != null && this instanceof ServerPlayer) {
|
||||
@@ -1,23 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: TheMeinerLP <p.glanz@madfix.me>
|
||||
Date: Tue, 13 Jun 2023 16:10:59 +0200
|
||||
Subject: [PATCH] Don't enforce icanhasbukkit default if alias block exists
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
}
|
||||
this.commandsConfiguration = YamlConfiguration.loadConfiguration(this.getCommandsConfigFile());
|
||||
this.commandsConfiguration.options().copyDefaults(true);
|
||||
- this.commandsConfiguration.setDefaults(YamlConfiguration.loadConfiguration(new InputStreamReader(getClass().getClassLoader().getResourceAsStream("configurations/commands.yml"), Charsets.UTF_8)));
|
||||
+ // Paper start - don't enforce icanhasbukkit default if alias block exists
|
||||
+ final YamlConfiguration commandsDefaults = YamlConfiguration.loadConfiguration(new InputStreamReader(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
|
||||
this.saveCommandsConfig();
|
||||
|
||||
// Migrate aliases from old file and add previously implicit $1- to pass all arguments
|
||||
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Wed, 5 Jul 2023 23:11:53 +0100
|
||||
Subject: [PATCH] Don't load chunks for supporting block checks
|
||||
|
||||
|
||||
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 Nameable, EntityAccess, CommandSource {
|
||||
}
|
||||
|
||||
protected BlockPos getOnPos(float offset) {
|
||||
- if (this.mainSupportingBlockPos.isPresent()) {
|
||||
+ if (this.mainSupportingBlockPos.isPresent() && this.level().getChunkIfLoadedImmediately(this.mainSupportingBlockPos.get()) != null) { // Paper - ensure no loads
|
||||
BlockPos blockposition = (BlockPos) this.mainSupportingBlockPos.get();
|
||||
|
||||
if (offset <= 1.0E-5F) {
|
||||
@@ -1,69 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 20 Jan 2022 18:11:20 -0800
|
||||
Subject: [PATCH] Expand PlayerItemMendEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
@@ -0,0 +0,0 @@ public class ExperienceOrb extends Entity {
|
||||
ItemStack itemstack = (ItemStack) entry.getValue();
|
||||
int j = Math.min(this.xpToDurability(this.value), 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
|
||||
j = event.getRepairAmount();
|
||||
if (event.isCancelled()) {
|
||||
return amount;
|
||||
@@ -0,0 +0,0 @@ public class ExperienceOrb extends Entity {
|
||||
// CraftBukkit end
|
||||
|
||||
itemstack.setDamageValue(itemstack.getDamageValue() - j);
|
||||
- int k = amount - this.durabilityToXp(j);
|
||||
+ int k = amount - event.getDurabilityToXpOperation().applyAsInt(j); // Paper
|
||||
this.value = k; // CraftBukkit - update exp value of orb for PlayerItemMendEvent calls
|
||||
+ // Paper start
|
||||
+ 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
|
||||
|
||||
return k > 0 ? this.repairPlayerItems(player, k) : 0;
|
||||
} else {
|
||||
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 {
|
||||
orb.setPosRaw(handle.getX(), handle.getY(), handle.getZ());
|
||||
|
||||
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
|
||||
i = event.getRepairAmount();
|
||||
orb.discard();
|
||||
if (!event.isCancelled()) {
|
||||
- amount -= orb.durabilityToXp(i);
|
||||
+ amount -= event.getDurabilityToXpOperation().applyAsInt(i); // Paper
|
||||
itemstack.setDamageValue(itemstack.getDamageValue() - i);
|
||||
}
|
||||
}
|
||||
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 {
|
||||
return event;
|
||||
}
|
||||
|
||||
- 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
|
||||
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
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
return event;
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: SoSeDiK <mrsosedik@gmail.com>
|
||||
Date: Tue, 11 Oct 2022 23:30:32 +0300
|
||||
Subject: [PATCH] Expose pre-collision moving velocity to
|
||||
VehicleBlockCollisionEvent
|
||||
|
||||
|
||||
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 Nameable, EntityAccess, CommandSource {
|
||||
}
|
||||
|
||||
if (!bl.getType().isAir()) {
|
||||
- VehicleBlockCollisionEvent event = new VehicleBlockCollisionEvent(vehicle, bl);
|
||||
+ VehicleBlockCollisionEvent event = new VehicleBlockCollisionEvent(vehicle, bl, org.bukkit.craftbukkit.util.CraftVector.toBukkit(moveVector)); // Paper - Expose pre-collision velocity
|
||||
this.level.getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Doc <nachito94@msn.com>
|
||||
Date: Mon, 1 May 2023 13:34:57 -0400
|
||||
Subject: [PATCH] Fix DamageCause for Falling Blocks
|
||||
|
||||
|
||||
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 {
|
||||
} else if (source.is(DamageTypes.SONIC_BOOM)) {
|
||||
cause = DamageCause.SONIC_BOOM;
|
||||
}
|
||||
+ // Paper start - fix handle of Falling Blocks
|
||||
+ else if (source.is(DamageTypes.FALLING_STALACTITE) || source.is(DamageTypes.FALLING_BLOCK) || source.is(DamageTypes.FALLING_ANVIL)) {
|
||||
+ cause = DamageCause.FALLING_BLOCK;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
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)) {
|
||||
@@ -1,30 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 10 Oct 2021 18:18:01 -0700
|
||||
Subject: [PATCH] Fix HumanEntity#drop not updating the client inv
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.server.level.ServerPlayer containerSynchronizer
|
||||
|
||||
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 {
|
||||
// Paper end
|
||||
@Override
|
||||
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
|
||||
+ if (!(this.getHandle() instanceof ServerPlayer player)) return false;
|
||||
+ boolean success = player.drop(dropAll);
|
||||
+ if (!success) return false;
|
||||
+ final net.minecraft.world.entity.player.Inventory inv = player.getInventory();
|
||||
+ 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
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,24 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Warrior <50800980+Warriorrrr@users.noreply.github.com>
|
||||
Date: Mon, 27 Feb 2023 19:16:07 +0100
|
||||
Subject: [PATCH] Fix MC-157464 Prevent sleeping villagers moving towards food
|
||||
|
||||
Fixes sleeping villagers moving to nearby food by adding an !isSleeping predicate
|
||||
|
||||
Relevant links:
|
||||
https://bugs.mojang.com/browse/MC-157464
|
||||
https://github.com/PaperMC/Paper/issues/8569
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java
|
||||
@@ -0,0 +0,0 @@ public class VillagerGoalPackages {
|
||||
private static final float STROLL_SPEED_MODIFIER = 0.4F;
|
||||
|
||||
public static ImmutableList<Pair<Integer, ? extends BehaviorControl<? super Villager>>> getCorePackage(VillagerProfession profession, float speed) {
|
||||
- return ImmutableList.of(Pair.of(0, new Swim(0.8F)), Pair.of(0, InteractWithDoor.create()), Pair.of(0, new LookAtTargetSink(45, 90)), Pair.of(0, new VillagerPanicTrigger()), Pair.of(0, WakeUp.create()), Pair.of(0, ReactToBell.create()), Pair.of(0, SetRaidStatus.create()), Pair.of(0, ValidateNearbyPoi.create(profession.heldJobSite(), MemoryModuleType.JOB_SITE)), Pair.of(0, ValidateNearbyPoi.create(profession.acquirableJobSite(), MemoryModuleType.POTENTIAL_JOB_SITE)), Pair.of(1, new MoveToTargetSink()), Pair.of(2, PoiCompetitorScan.create()), Pair.of(3, new LookAndFollowTradingPlayerSink(speed)), Pair.of(5, GoToWantedItem.create(speed, false, 4)), Pair.of(6, AcquirePoi.create(profession.acquirableJobSite(), MemoryModuleType.JOB_SITE, MemoryModuleType.POTENTIAL_JOB_SITE, true, Optional.empty())), Pair.of(7, new GoToPotentialJobSite(speed)), Pair.of(8, YieldJobSite.create(speed)), Pair.of(10, AcquirePoi.create((poiType) -> {
|
||||
+ return ImmutableList.of(Pair.of(0, new Swim(0.8F)), Pair.of(0, InteractWithDoor.create()), Pair.of(0, new LookAtTargetSink(45, 90)), Pair.of(0, new VillagerPanicTrigger()), Pair.of(0, WakeUp.create()), Pair.of(0, ReactToBell.create()), Pair.of(0, SetRaidStatus.create()), Pair.of(0, ValidateNearbyPoi.create(profession.heldJobSite(), MemoryModuleType.JOB_SITE)), Pair.of(0, ValidateNearbyPoi.create(profession.acquirableJobSite(), MemoryModuleType.POTENTIAL_JOB_SITE)), Pair.of(1, new MoveToTargetSink()), Pair.of(2, PoiCompetitorScan.create()), Pair.of(3, new LookAndFollowTradingPlayerSink(speed)), Pair.of(5, GoToWantedItem.create(villager -> !villager.isSleeping(), speed, false, 4)), Pair.of(6, AcquirePoi.create(profession.acquirableJobSite(), MemoryModuleType.JOB_SITE, MemoryModuleType.POTENTIAL_JOB_SITE, true, Optional.empty())), Pair.of(7, new GoToPotentialJobSite(speed)), Pair.of(8, YieldJobSite.create(speed)), Pair.of(10, AcquirePoi.create((poiType) -> { // Paper - Fix MC-157464
|
||||
return poiType.is(PoiTypes.HOME);
|
||||
}, MemoryModuleType.HOME, false, Optional.of((byte)14))), Pair.of(10, AcquirePoi.create((poiType) -> {
|
||||
return poiType.is(PoiTypes.MEETING);
|
||||
@@ -1,42 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 23 Feb 2023 13:19:13 -0800
|
||||
Subject: [PATCH] Fix SpawnEggMeta#get/setSpawnedType
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java
|
||||
@@ -0,0 +0,0 @@ public class CraftMetaSpawnEgg extends CraftMetaItem implements SpawnEggMeta {
|
||||
throw new UnsupportedOperationException("Must change item type to set spawned type");
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public EntityType getCustomSpawnedType() {
|
||||
+ return java.util.Optional.ofNullable(this.entityTag)
|
||||
+ .map(tag -> tag.getString(ENTITY_ID.NBT))
|
||||
+ .flatMap(net.minecraft.world.entity.EntityType::byString)
|
||||
+ .map(org.bukkit.craftbukkit.util.CraftMagicNumbers::getEntityType)
|
||||
+ .orElse(null);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCustomSpawnedType(final EntityType type) {
|
||||
+ if (type == null) {
|
||||
+ if (this.entityTag != null) {
|
||||
+ this.entityTag.remove(ENTITY_ID.NBT);
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (this.entityTag == null) {
|
||||
+ this.entityTag = new CompoundTag();
|
||||
+ }
|
||||
+ this.entityTag.putString(ENTITY_ID.NBT, type.key().toString());
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
boolean equalsCommon(CraftMetaItem meta) {
|
||||
if (!super.equalsCommon(meta)) {
|
||||
@@ -1,33 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 9 Apr 2023 21:11:58 -0700
|
||||
Subject: [PATCH] Fix a couple of upstream bed issues
|
||||
|
||||
Upstream incorrectly skipped explosion logic if
|
||||
the bed was occupied and added a "feature" where
|
||||
if you set your spawn in a respawn anchor world
|
||||
but then replaced it with a bed, you could respawn
|
||||
at the bed in that world.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/BedBlock.java b/src/main/java/net/minecraft/world/level/block/BedBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/BedBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/BedBlock.java
|
||||
@@ -0,0 +0,0 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock
|
||||
world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK);
|
||||
return InteractionResult.SUCCESS;
|
||||
} else if ((Boolean) state.getValue(BedBlock.OCCUPIED)) {
|
||||
+ if (!BedBlock.canSetSpawn(world)) return this.explodeBed(state, world, pos); // Paper - check explode first
|
||||
if (!this.kickVillagerOutOfBed(world, pos)) {
|
||||
player.displayClientMessage(Component.translatable("block.minecraft.bed.occupied"), true);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock
|
||||
// CraftBukkit end
|
||||
|
||||
public static boolean canSetSpawn(Level world) {
|
||||
- // CraftBukkit - moved world and biome check into EntityHuman
|
||||
- return true || world.dimensionType().bedWorks();
|
||||
+ return world.dimensionType().bedWorks(); // Paper - actually check if the bed works
|
||||
}
|
||||
|
||||
private boolean kickVillagerOutOfBed(Level world, BlockPos pos) {
|
||||
@@ -1,46 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 16 Mar 2023 10:04:17 +0100
|
||||
Subject: [PATCH] Fix advancement triggers for entity damage
|
||||
|
||||
Changes the Interaction entity's trigger to use the vanilla
|
||||
generic damage source
|
||||
|
||||
Fixes a couple places where the original damage and modified damage
|
||||
were passed in the reverse order to the advancement triggers
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Interaction.java b/src/main/java/net/minecraft/world/entity/Interaction.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Interaction.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Interaction.java
|
||||
@@ -0,0 +0,0 @@ public class Interaction extends Entity implements Attackable, Targeting {
|
||||
if (entityhuman instanceof ServerPlayer) {
|
||||
ServerPlayer entityplayer = (ServerPlayer) entityhuman;
|
||||
|
||||
- CriteriaTriggers.PLAYER_HURT_ENTITY.trigger(entityplayer, this, source, (float) event.getFinalDamage(), 1.0F, false); // CraftBukkit
|
||||
+ CriteriaTriggers.PLAYER_HURT_ENTITY.trigger(entityplayer, this, entityhuman.damageSources().generic(), 1.0F, (float) event.getFinalDamage(), false); // CraftBukkit // Paper - use correct source and fix taken/dealt param order
|
||||
}
|
||||
|
||||
return !this.getResponse();
|
||||
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 {
|
||||
// Duplicate triggers if blocking
|
||||
if (event.getDamage(DamageModifier.BLOCKING) < 0) {
|
||||
if (this instanceof ServerPlayer) {
|
||||
- CriteriaTriggers.ENTITY_HURT_PLAYER.trigger((ServerPlayer) this, damagesource, f, originalDamage, true);
|
||||
+ CriteriaTriggers.ENTITY_HURT_PLAYER.trigger((ServerPlayer) this, damagesource, originalDamage, f, true); // Paper - fix taken/dealt param order
|
||||
f2 = (float) -event.getDamage(DamageModifier.BLOCKING);
|
||||
if (f2 > 0.0F && f2 < 3.4028235E37F) {
|
||||
((ServerPlayer) this).awardStat(Stats.DAMAGE_BLOCKED_BY_SHIELD, Math.round(originalDamage * 10.0F));
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
}
|
||||
|
||||
if (damagesource.getEntity() instanceof ServerPlayer) {
|
||||
- CriteriaTriggers.PLAYER_HURT_ENTITY.trigger((ServerPlayer) damagesource.getEntity(), this, damagesource, f, originalDamage, true);
|
||||
+ CriteriaTriggers.PLAYER_HURT_ENTITY.trigger((ServerPlayer) damagesource.getEntity(), this, damagesource, originalDamage, f, true); // Paper - fix taken/dealt param order
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -1,44 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 26 Mar 2023 18:07:56 -0700
|
||||
Subject: [PATCH] Fix beehives generating from using bonemeal
|
||||
|
||||
|
||||
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 {
|
||||
}
|
||||
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
|
||||
}
|
||||
entityhuman.awardStat(Stats.ITEM_USED.get(item)); // SPIGOT-7236 - award stat
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CapturedBlockState.java b/src/main/java/org/bukkit/craftbukkit/block/CapturedBlockState.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CapturedBlockState.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CapturedBlockState.java
|
||||
@@ -0,0 +0,0 @@ public final class CapturedBlockState extends CraftBlockState {
|
||||
public boolean update(boolean force, boolean applyPhysics) {
|
||||
boolean result = super.update(force, applyPhysics);
|
||||
|
||||
+ // Paper start
|
||||
+ this.checkTreeBlockHack();
|
||||
+ return result;
|
||||
+ }
|
||||
+ public void checkTreeBlockHack() {
|
||||
+ // Paper end
|
||||
// SPIGOT-5537: Horrible hack to manually add bees given World.captureTreeGeneration does not support tiles
|
||||
if (this.treeBlock && getType() == Material.BEE_NEST) {
|
||||
WorldGenLevel generatoraccessseed = this.world.getHandle();
|
||||
@@ -0,0 +0,0 @@ public final class CapturedBlockState extends CraftBlockState {
|
||||
// End copied block
|
||||
}
|
||||
|
||||
- return result;
|
||||
+ // Paper
|
||||
}
|
||||
|
||||
public static CapturedBlockState getBlockState(Level world, BlockPos pos, int flag) {
|
||||
@@ -1,68 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
|
||||
Date: Mon, 3 Apr 2023 18:46:49 +0200
|
||||
Subject: [PATCH] Fix block place logic
|
||||
|
||||
Fix several issues when a player interact with a block:
|
||||
* the place sound isn't played for the dispensed shulker block
|
||||
* desync of the jukebox blocks between bukkit handler and the vanilla interaction
|
||||
* poi can desync when the BlockPhysicsEvent is cancelled
|
||||
|
||||
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 {
|
||||
|
||||
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)
|
||||
world.gameEvent(GameEvent.BLOCK_PLACE, blockposition, GameEvent.Context.of(entityhuman, iblockdata1));
|
||||
if ((entityhuman == null || !entityhuman.getAbilities().instabuild) && itemstack != ItemStack.EMPTY) { // CraftBukkit
|
||||
itemstack.shrink(1);
|
||||
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 {
|
||||
if (tileentity instanceof JukeboxBlockEntity) {
|
||||
JukeboxBlockEntity tileentityjukebox = (JukeboxBlockEntity) tileentity;
|
||||
|
||||
- // There can only be one
|
||||
- ItemStack record = this.copy();
|
||||
- if (!record.isEmpty()) {
|
||||
- record.setCount(1);
|
||||
- }
|
||||
-
|
||||
- tileentityjukebox.setFirstItem(record);
|
||||
+ tileentityjukebox.setFirstItem(this.copy()); // Paper - sync this with record item, jukebox has now an inventory
|
||||
world.gameEvent(GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(entityhuman, world.getBlockState(blockposition)));
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
// 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
|
||||
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);
|
||||
|
||||
- if (event.isCancelled()) {
|
||||
- return;
|
||||
- }
|
||||
+ cancelledUpdates = event.isCancelled(); // Paper
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ if (!cancelledUpdates) { // Paper
|
||||
iblockdata.updateNeighbourShapes(this, blockposition, k, j - 1);
|
||||
iblockdata.updateIndirectNeighbourShapes(this, blockposition, k, j - 1);
|
||||
+ } // Paper
|
||||
}
|
||||
|
||||
// CraftBukkit start - SPIGOT-5710
|
||||
@@ -1,61 +0,0 @@
|
||||
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
|
||||
|
||||
Wandering Trader, AbstractHorse, Beacon and Composter inventories returned null locations
|
||||
when a block or entity location is readily available
|
||||
|
||||
Co-authored-by: Lukas Planz <lukas.planz@web.de>
|
||||
|
||||
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 {
|
||||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
+ // Paper start
|
||||
+ // 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();
|
||||
+ }
|
||||
+ // When the bukkit owner is a bukkit entity, but does not implement Container itself, e. g. horses
|
||||
+ if (this.bukkitOwner instanceof org.bukkit.entity.Entity entity) {
|
||||
+ return entity.getLocation();
|
||||
+ }
|
||||
+ // Paper end
|
||||
return null;
|
||||
}
|
||||
|
||||
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 int getMaxStackSize() {
|
||||
return 1;
|
||||
}
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public org.bukkit.Location getLocation() {
|
||||
+ return context.getLocation();
|
||||
+ }
|
||||
+ // Paper end
|
||||
};
|
||||
checkContainerDataCount(propertyDelegate, 3);
|
||||
this.beaconData = propertyDelegate;
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/MerchantContainer.java b/src/main/java/net/minecraft/world/inventory/MerchantContainer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/MerchantContainer.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/MerchantContainer.java
|
||||
@@ -0,0 +0,0 @@ public class MerchantContainer implements Container {
|
||||
|
||||
@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
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nassim Jahnke <nassim@njahnke.dev>
|
||||
Date: Sat, 18 Mar 2023 18:51:33 +0100
|
||||
Subject: [PATCH] Fix chiseled bookshelf and jukebox setItem with air
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/ChiseledBookShelfBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ChiseledBookShelfBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/ChiseledBookShelfBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/ChiseledBookShelfBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public class ChiseledBookShelfBlockEntity extends BlockEntity implements Contain
|
||||
|
||||
@Override
|
||||
public void setItem(int slot, ItemStack stack) {
|
||||
- if (stack.is(ItemTags.BOOKSHELF_BOOKS)) {
|
||||
+ if (stack.isEmpty() || stack.is(ItemTags.BOOKSHELF_BOOKS)) { // Paper
|
||||
this.items.set(slot, stack);
|
||||
if (level != null) this.updateState(slot); // CraftBukkit - SPIGOT-7381: check for null world
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public class JukeboxBlockEntity extends BlockEntity implements Clearable, Contai
|
||||
|
||||
@Override
|
||||
public void setItem(int slot, ItemStack stack) {
|
||||
+ // Paper start
|
||||
+ if (stack.isEmpty()) {
|
||||
+ this.removeItem(slot, 0);
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (stack.is(ItemTags.MUSIC_DISCS) && this.level != null) {
|
||||
this.items.set(slot, stack);
|
||||
this.setHasRecordBlockState((Entity) null, true);
|
||||
@@ -1,30 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Mon, 15 May 2023 00:20:59 -0700
|
||||
Subject: [PATCH] Fix concurrenct access to lookups field in RegistryOps
|
||||
|
||||
The concurrent access occurs on the Netty IO threads when
|
||||
serializing packets. Thus, it seems it was an oversight of
|
||||
the implementator of this function as there are typically
|
||||
more than one Netty IO thread.
|
||||
|
||||
Fixes https://github.com/PaperMC/Folia/issues/11
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/resources/RegistryOps.java b/src/main/java/net/minecraft/resources/RegistryOps.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/resources/RegistryOps.java
|
||||
+++ b/src/main/java/net/minecraft/resources/RegistryOps.java
|
||||
@@ -0,0 +0,0 @@ public class RegistryOps<T> extends DelegatingOps<T> {
|
||||
|
||||
private static RegistryOps.RegistryInfoLookup memoizeLookup(final RegistryOps.RegistryInfoLookup registryInfoGetter) {
|
||||
return new RegistryOps.RegistryInfoLookup() {
|
||||
- private final Map<ResourceKey<? extends Registry<?>>, Optional<? extends RegistryOps.RegistryInfo<?>>> lookups = new HashMap<>();
|
||||
+ private final Map<ResourceKey<? extends Registry<?>>, Optional<? extends RegistryOps.RegistryInfo<?>>> lookups = new java.util.concurrent.ConcurrentHashMap<>(); // Paper - fix concurrent access to lookups field
|
||||
|
||||
@Override
|
||||
public <T> Optional<RegistryOps.RegistryInfo<T>> lookup(ResourceKey<? extends Registry<? extends T>> registryRef) {
|
||||
- return this.lookups.computeIfAbsent(registryRef, registryInfoGetter::lookup);
|
||||
+ return (Optional<RegistryOps.RegistryInfo<T>>)this.lookups.computeIfAbsent(registryRef, registryInfoGetter::lookup); // Paper - fix concurrent access to lookups field
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 19 Mar 2023 20:36:22 -0700
|
||||
Subject: [PATCH] Fix crash relating to bad recipes in furnace-like tile
|
||||
entities
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
||||
Entry<ResourceLocation> entry = (Entry) objectiterator.next();
|
||||
|
||||
worldserver.getRecipeManager().byKey((ResourceLocation) entry.getKey()).ifPresent((irecipe) -> {
|
||||
+ if (!(irecipe instanceof AbstractCookingRecipe)) return; // Paper - don't process non-cooking recipes
|
||||
list.add(irecipe);
|
||||
AbstractFurnaceBlockEntity.createExperience(worldserver, vec3d, entry.getIntValue(), ((AbstractCookingRecipe) irecipe).getExperience(), blockposition, entityplayer, itemstack, amount); // CraftBukkit
|
||||
});
|
||||
@@ -1,20 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Warrior <50800980+Warriorrrr@users.noreply.github.com>
|
||||
Date: Fri, 7 Apr 2023 20:11:17 +0200
|
||||
Subject: [PATCH] Fix demo flag not enabling demo mode
|
||||
|
||||
https://github.com/PaperMC/Paper/issues/9046
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/Main.java
|
||||
+++ b/src/main/java/net/minecraft/server/Main.java
|
||||
@@ -0,0 +0,0 @@ public class Main {
|
||||
/*
|
||||
dedicatedserver1.setSingleplayerProfile(optionset.has(optionspec8) ? new GameProfile((UUID) null, (String) optionset.valueOf(optionspec8)) : null);
|
||||
dedicatedserver1.setPort((Integer) optionset.valueOf(optionspec11));
|
||||
- dedicatedserver1.setDemo(optionset.has(optionspec2));
|
||||
+ */dedicatedserver1.setDemo(optionset.has("demo"));/* // Paper - Restore setting the demo mode
|
||||
dedicatedserver1.setId((String) optionset.valueOf(optionspec12));
|
||||
*/
|
||||
boolean flag1 = !optionset.has("nogui") && !optionset.nonOptionArguments().contains("nogui");
|
||||
@@ -1,25 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Mon, 3 Apr 2023 21:14:19 -0700
|
||||
Subject: [PATCH] Fix destroying beehive without any players nearby throwing an
|
||||
exception
|
||||
|
||||
If the player moves out of range by the time the block is destroyed,
|
||||
then the exception would throw and remove the player from the world
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java
|
||||
@@ -0,0 +0,0 @@ public class BeehiveBlock extends BaseEntityBlock {
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
List<Player> list1 = world.getEntitiesOfClass(Player.class, (new AABB(pos)).inflate(8.0D, 6.0D, 8.0D));
|
||||
+ // Paper start - if there are no players nearby, then nextInt() will throw
|
||||
+ if (list1.isEmpty()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - if there are no players nearby, then nextInt() will throw
|
||||
int i = list1.size();
|
||||
Iterator iterator = list.iterator();
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 26 Jan 2023 16:19:26 -0800
|
||||
Subject: [PATCH] Fix force-opening enchantment tables
|
||||
|
||||
|
||||
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 {
|
||||
|
||||
// If there isn't an enchant table we can force create one, won't be very useful though.
|
||||
BlockPos pos = CraftLocation.toBlockPosition(location);
|
||||
- this.getHandle().openMenu(((EnchantmentTableBlock) Blocks.ENCHANTING_TABLE).getMenuProvider(null, this.getHandle().level(), pos));
|
||||
+ // Paper start
|
||||
+ MenuProvider menuProvider = ((EnchantmentTableBlock) Blocks.ENCHANTING_TABLE).getMenuProvider(null, this.getHandle().level(), pos);
|
||||
+ if (menuProvider == null) {
|
||||
+ if (!force) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ menuProvider = new net.minecraft.world.SimpleMenuProvider((syncId, inventory, player) -> {
|
||||
+ return new net.minecraft.world.inventory.EnchantmentMenu(syncId, inventory, net.minecraft.world.inventory.ContainerLevelAccess.create(this.getHandle().level(), pos));
|
||||
+ }, Component.translatable("container.enchant"));
|
||||
+ }
|
||||
+ this.getHandle().openMenu(menuProvider);
|
||||
+ // Paper end
|
||||
|
||||
if (force) {
|
||||
this.getHandle().containerMenu.checkReachable = false;
|
||||
@@ -1,20 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Redned <redned235@gmail.com>
|
||||
Date: Mon, 12 Jun 2023 11:54:12 -0500
|
||||
Subject: [PATCH] Fix incorrect crafting result amount for fireworks
|
||||
|
||||
Although vanilla does not specifically call this method anywhere, this fixes a bug where the result using the Bukkit API returns the wrong amount.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/crafting/FireworkRocketRecipe.java b/src/main/java/net/minecraft/world/item/crafting/FireworkRocketRecipe.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/crafting/FireworkRocketRecipe.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/crafting/FireworkRocketRecipe.java
|
||||
@@ -0,0 +0,0 @@ public class FireworkRocketRecipe extends CustomRecipe {
|
||||
|
||||
@Override
|
||||
public ItemStack getResultItem(RegistryAccess registryManager) {
|
||||
- return new ItemStack(Items.FIREWORK_ROCKET);
|
||||
+ return new ItemStack(Items.FIREWORK_ROCKET, 3); // Paper - Fix incorrect crafting result amount
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,29 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
|
||||
Date: Sun, 11 Jun 2023 19:02:46 +0200
|
||||
Subject: [PATCH] Fix sniffer removeExploredLocation
|
||||
|
||||
Add support to remove explored location in different world
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSniffer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSniffer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSniffer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSniffer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftSniffer extends CraftAnimals implements Sniffer {
|
||||
@Override
|
||||
public void removeExploredLocation(Location location) {
|
||||
Preconditions.checkArgument(location != null, "location cannot be null");
|
||||
- if (location.getWorld() != getWorld()) {
|
||||
- return;
|
||||
- }
|
||||
|
||||
BlockPos blockPosition = CraftLocation.toBlockPosition(location);
|
||||
- this.getHandle().getBrain().setMemory(MemoryModuleType.SNIFFER_EXPLORED_POSITIONS, this.getHandle().getExploredPositions().filter(blockPositionExplored -> !blockPositionExplored.equals(blockPosition)).collect(Collectors.toList()));
|
||||
+ // Paper start
|
||||
+ net.minecraft.world.level.Level level = location.getWorld() != null ? ((org.bukkit.craftbukkit.CraftWorld) location.getWorld()).getHandle() : this.getHandle().level();
|
||||
+ net.minecraft.core.GlobalPos globalPos = net.minecraft.core.GlobalPos.of(level.dimension(), blockPosition);
|
||||
+ this.getHandle().getBrain().setMemory(MemoryModuleType.SNIFFER_EXPLORED_POSITIONS, this.getHandle().getExploredPositions().filter(blockPositionExplored -> !blockPositionExplored.equals(globalPos)).collect(Collectors.toList()));
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,23 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Thu, 8 Jun 2023 20:23:13 -0400
|
||||
Subject: [PATCH] Fix spigot sound playing for BlockItem ItemStacks
|
||||
|
||||
|
||||
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 {
|
||||
|
||||
// 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
|
||||
+ 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
|
||||
world.playSound(entityhuman, blockposition, soundeffecttype.getPlaceSound(), SoundSource.BLOCKS, (soundeffecttype.getVolume() + 1.0F) / 2.0F, soundeffecttype.getPitch() * 0.8F);
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nassim Jahnke <nassim@njahnke.dev>
|
||||
Date: Thu, 16 Mar 2023 16:27:50 +0100
|
||||
Subject: [PATCH] Fix text display error on spawn
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Display.java b/src/main/java/net/minecraft/world/entity/Display.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Display.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Display.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Display extends Entity {
|
||||
Logger logger = Display.LOGGER;
|
||||
|
||||
Objects.requireNonNull(logger);
|
||||
- Optional<Display.TextDisplay.Align> optional = dataresult.resultOrPartial(Util.prefix("Display entity", logger::error)).map(Pair::getFirst);
|
||||
+ Optional<Display.TextDisplay.Align> optional = dataresult.result().map(Pair::getFirst); // Paper - hide error message
|
||||
|
||||
if (optional.isPresent()) {
|
||||
byte b1;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 8 Jun 2023 21:51:50 -0700
|
||||
Subject: [PATCH] Ignore inline definitions of trim material & pattern
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java
|
||||
@@ -0,0 +0,0 @@ public class CraftMetaArmor extends CraftMetaItem implements ArmorMeta {
|
||||
if (tag.contains(TRIM.NBT)) {
|
||||
CompoundTag trimCompound = tag.getCompound(TRIM.NBT);
|
||||
|
||||
- if (trimCompound.contains(TRIM_MATERIAL.NBT) && trimCompound.contains(TRIM_PATTERN.NBT)) {
|
||||
+ if (trimCompound.contains(TRIM_MATERIAL.NBT, net.minecraft.nbt.Tag.TAG_STRING) && trimCompound.contains(TRIM_PATTERN.NBT, net.minecraft.nbt.Tag.TAG_STRING)) { // Paper - for now, ignore inline definitions of trim material & pattern
|
||||
TrimMaterial trimMaterial = Registry.TRIM_MATERIAL.get(NamespacedKey.fromString(trimCompound.getString(TRIM_MATERIAL.NBT)));
|
||||
TrimPattern trimPattern = Registry.TRIM_PATTERN.get(NamespacedKey.fromString(trimCompound.getString(TRIM_PATTERN.NBT)));
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Tue, 27 Jun 2023 16:32:39 -0700
|
||||
Subject: [PATCH] Improve command function perm level checks
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/commands/CommandSourceStack.java
|
||||
+++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java
|
||||
@@ -0,0 +0,0 @@ public class CommandSourceStack implements SharedSuggestionProvider, com.destroy
|
||||
|
||||
// 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
|
||||
+ boolean hasPermissionLevel = this.permissionLevel >= i;
|
||||
+ if (this.source == CommandSource.NULL) {
|
||||
+ return hasPermissionLevel;
|
||||
+ } else {
|
||||
+ return (!this.getLevel().getCraftServer().ignoreVanillaPermissions && hasPermissionLevel) || this.getBukkitSender().hasPermission(bukkitPermission);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Warrior <50800980+Warriorrrr@users.noreply.github.com>
|
||||
Date: Sun, 7 May 2023 22:33:50 +0200
|
||||
Subject: [PATCH] More accurate isInOpenWater impl
|
||||
|
||||
For fishing hooks, the openWater field is true by default, and only calculated when a "fish" is approaching the bobber.
|
||||
This patch changes the API impl to calculate the open water state itself instead of returning this field.
|
||||
|
||||
Relevant link: https://github.com/PaperMC/Paper/issues/9131
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.projectile.FishingHook calculateOpenWater(Lnet/minecraft/core/BlockPos;)Z
|
||||
public net.minecraft.world.entity.projectile.FishingHook outOfWaterTime
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java
|
||||
@@ -0,0 +0,0 @@ public class CraftFishHook extends CraftProjectile implements FishHook {
|
||||
|
||||
@Override
|
||||
public boolean isInOpenWater() {
|
||||
- return this.getHandle().isOpenWaterFishing();
|
||||
+ return this.getHandle().outOfWaterTime < 10 && this.getHandle().calculateOpenWater(this.getHandle().blockPosition()); // Paper - isOpenWaterFishing is only calculated when a "fish" is approaching the hook
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,20 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Redned <redned235@gmail.com>
|
||||
Date: Mon, 19 Jun 2023 15:45:53 -0500
|
||||
Subject: [PATCH] Only tick item frames if players can see it
|
||||
|
||||
In the event that an item frame cannot be seen by any players, ticking the item frame every tick is unnecessary. This can be a very hot section of the entity tracker when lots of item frames are present on a server, so this reduces the logic which speeds it up.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
@@ -0,0 +0,0 @@ public class ServerEntity {
|
||||
|
||||
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
|
||||
ItemFrame entityitemframe = (ItemFrame) entity;
|
||||
|
||||
if (true || this.tickCount % 10 == 0) { // CraftBukkit - Moved below, should always enter this block
|
||||
@@ -1,37 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Mon, 15 May 2023 20:25:26 -0700
|
||||
Subject: [PATCH] Optimise recalcBlockCounts() for empty sections
|
||||
|
||||
In 1.18, every chunk section is initialised to a non-null value
|
||||
and recalcBlockCounts() is invoked for each section.
|
||||
However, in a standard world, most sections are empty. In such cases,
|
||||
recalcBlockCounts() would iterate over ever position - even though
|
||||
the block data would all be air. To avoid this, we skip
|
||||
searching the section unless the palette indicates there _could_ be
|
||||
a non-air block state or non-empty fluid state.
|
||||
|
||||
Chunk loading initially showed that recalcBlockCounts() over
|
||||
sections with a ZeroBitStorage data to to take ~20% of the process,
|
||||
now it takes <1%.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||
@@ -0,0 +0,0 @@ public class LevelChunkSection {
|
||||
this.nonEmptyBlockCount = 0;
|
||||
this.tickingBlockCount = 0;
|
||||
this.tickingFluidCount = 0;
|
||||
+ if (this.maybeHas((BlockState state) -> !state.isAir() || !state.getFluidState().isEmpty())) { // Paper - do not run forEachLocation on clearly empty sections
|
||||
this.states.forEachLocation((BlockState iblockdata, int i) -> {
|
||||
FluidState fluid = iblockdata.getFluidState();
|
||||
|
||||
@@ -0,0 +0,0 @@ public class LevelChunkSection {
|
||||
}
|
||||
|
||||
});
|
||||
+ } // Paper - do not run forEachLocation on clearly empty sections
|
||||
// Paper end
|
||||
this.initBlockCollisionData(); // Paper
|
||||
}
|
||||
@@ -1,608 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 27 Apr 2016 22:09:52 -0400
|
||||
Subject: [PATCH] Optimize Hoppers
|
||||
|
||||
* Removes unnecessary extra calls to .update() that are very expensive
|
||||
* Lots of itemstack cloning removed. Only clone if the item is actually moved
|
||||
* Return true when a plugin cancels inventory move item event instead of false, as false causes pulls to cycle through all items.
|
||||
However, pushes do not exhibit the same behavior, so this is not something plugins could of been relying on.
|
||||
* Add option (Default on) to cooldown hoppers when they fail to move an item due to full inventory
|
||||
* Skip subsequent InventoryMoveItemEvents if a plugin does not use the item after first event fire for an iteration
|
||||
* Don't check for Entities with Inventories if the block above us is also occluding (not just Inventoried)
|
||||
* Remove Streams from Item Suck In and restore restore 1.12 AABB checks which is simpler and no voxel allocations (was doing TWO Item Suck ins)
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
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
|
||||
worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper
|
||||
|
||||
this.profiler.push(() -> {
|
||||
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 {
|
||||
}
|
||||
|
||||
public ItemStack copy() {
|
||||
- if (this.isEmpty()) {
|
||||
+ // Paper start
|
||||
+ return this.copy(false);
|
||||
+ }
|
||||
+
|
||||
+ public ItemStack copy(boolean originalItem) {
|
||||
+ if (!originalItem && this.isEmpty()) {
|
||||
+ // Paper end
|
||||
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.setPopTime(this.getPopTime());
|
||||
if (this.tag != null) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
@@ -0,0 +0,0 @@ import co.aikar.timings.MinecraftTimings; // Paper
|
||||
import co.aikar.timings.Timing; // Paper
|
||||
|
||||
public abstract class BlockEntity {
|
||||
+ static boolean ignoreTileUpdates; // Paper
|
||||
|
||||
public Timing tickTimer = MinecraftTimings.getTileEntityTimings(this); // Paper
|
||||
// CraftBukkit start - data containers
|
||||
@@ -0,0 +0,0 @@ public abstract class BlockEntity {
|
||||
|
||||
public void setChanged() {
|
||||
if (this.level != null) {
|
||||
+ if (ignoreTileUpdates) return; // Paper
|
||||
BlockEntity.setChanged(this.level, this.worldPosition, this.blockState);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
return false;
|
||||
}
|
||||
|
||||
+ // Paper start - Optimize Hoppers
|
||||
+ private static boolean skipPullModeEventFire;
|
||||
+ private static boolean skipPushModeEventFire;
|
||||
+ public static boolean skipHopperEvents;
|
||||
+
|
||||
+ private static boolean hopperPush(final Level level, final Container destination, final Direction direction, final HopperBlockEntity hopper) {
|
||||
+ skipPushModeEventFire = skipHopperEvents;
|
||||
+ boolean foundItem = false;
|
||||
+ for (int i = 0; i < hopper.getContainerSize(); ++i) {
|
||||
+ final ItemStack item = hopper.getItem(i);
|
||||
+ if (!item.isEmpty()) {
|
||||
+ foundItem = true;
|
||||
+ ItemStack origItemStack = item;
|
||||
+ ItemStack movedItem = origItemStack;
|
||||
+
|
||||
+ final int originalItemCount = origItemStack.getCount();
|
||||
+ final int movedItemCount = Math.min(level.spigotConfig.hopperAmount, originalItemCount);
|
||||
+ origItemStack.setCount(movedItemCount);
|
||||
+
|
||||
+ // We only need to fire the event once to give protection plugins a chance to cancel this event
|
||||
+ // Because nothing uses getItem, every event call should end up the same result.
|
||||
+ if (!skipPushModeEventFire) {
|
||||
+ movedItem = callPushMoveEvent(destination, movedItem, hopper);
|
||||
+ if (movedItem == null) { // cancelled
|
||||
+ origItemStack.setCount(originalItemCount);
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ final ItemStack remainingItem = addItem(hopper, destination, movedItem, direction);
|
||||
+ final int remainingItemCount = remainingItem.getCount();
|
||||
+ if (remainingItemCount != movedItemCount) {
|
||||
+ origItemStack = origItemStack.copy(true);
|
||||
+ origItemStack.setCount(originalItemCount);
|
||||
+ if (!origItemStack.isEmpty()) {
|
||||
+ origItemStack.setCount(originalItemCount - movedItemCount + remainingItemCount);
|
||||
+ }
|
||||
+ hopper.setItem(i, origItemStack);
|
||||
+ destination.setChanged();
|
||||
+ return true;
|
||||
+ }
|
||||
+ origItemStack.setCount(originalItemCount);
|
||||
+ }
|
||||
+ }
|
||||
+ if (foundItem && level.paperConfig().hopper.cooldownWhenFull) { // Inventory was full - cooldown
|
||||
+ hopper.setCooldown(level.spigotConfig.hopperTransfer);
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ private static boolean hopperPull(final Level level, final Hopper hopper, final Container container, ItemStack origItemStack, final int i) {
|
||||
+ ItemStack movedItem = origItemStack;
|
||||
+ final int originalItemCount = origItemStack.getCount();
|
||||
+ final int movedItemCount = Math.min(level.spigotConfig.hopperAmount, originalItemCount);
|
||||
+ container.setChanged(); // original logic always marks source inv as changed even if no move happens.
|
||||
+ movedItem.setCount(movedItemCount);
|
||||
+
|
||||
+ if (!skipPullModeEventFire) {
|
||||
+ movedItem = callPullMoveEvent(hopper, container, movedItem);
|
||||
+ if (movedItem == null) { // cancelled
|
||||
+ origItemStack.setCount(originalItemCount);
|
||||
+ // Drastically improve performance by returning true.
|
||||
+ // No plugin could of relied on the behavior of false as the other call
|
||||
+ // site for IMIE did not exhibit the same behavior
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ final ItemStack remainingItem = addItem(container, hopper, movedItem, null);
|
||||
+ final int remainingItemCount = remainingItem.getCount();
|
||||
+ if (remainingItemCount != movedItemCount) {
|
||||
+ origItemStack = origItemStack.copy(true);
|
||||
+ origItemStack.setCount(originalItemCount);
|
||||
+ if (!origItemStack.isEmpty()) {
|
||||
+ origItemStack.setCount(originalItemCount - movedItemCount + remainingItemCount);
|
||||
+ }
|
||||
+
|
||||
+ ignoreTileUpdates = true;
|
||||
+ container.setItem(i, origItemStack);
|
||||
+ ignoreTileUpdates = false;
|
||||
+ container.setChanged();
|
||||
+ return true;
|
||||
+ }
|
||||
+ origItemStack.setCount(originalItemCount);
|
||||
+
|
||||
+ if (level.paperConfig().hopper.cooldownWhenFull) {
|
||||
+ cooldownHopper(hopper);
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ private static ItemStack callPushMoveEvent(Container iinventory, ItemStack itemstack, HopperBlockEntity hopper) {
|
||||
+ final Inventory destinationInventory = getInventory(iinventory);
|
||||
+ final InventoryMoveItemEvent event = new InventoryMoveItemEvent(hopper.getOwner(false).getInventory(),
|
||||
+ CraftItemStack.asCraftMirror(itemstack), destinationInventory, true);
|
||||
+ final boolean result = event.callEvent();
|
||||
+ if (!event.calledGetItem && !event.calledSetItem) {
|
||||
+ skipPushModeEventFire = true;
|
||||
+ }
|
||||
+ if (!result) {
|
||||
+ cooldownHopper(hopper);
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ if (event.calledSetItem) {
|
||||
+ return CraftItemStack.asNMSCopy(event.getItem());
|
||||
+ } else {
|
||||
+ return itemstack;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ private static ItemStack callPullMoveEvent(final Hopper hopper, final Container container, final ItemStack itemstack) {
|
||||
+ final Inventory sourceInventory = getInventory(container);
|
||||
+ final Inventory destination = getInventory(hopper);
|
||||
+
|
||||
+ // Mirror is safe as no plugins ever use this item
|
||||
+ final InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, CraftItemStack.asCraftMirror(itemstack), destination, false);
|
||||
+ final boolean result = event.callEvent();
|
||||
+ if (!event.calledGetItem && !event.calledSetItem) {
|
||||
+ skipPullModeEventFire = true;
|
||||
+ }
|
||||
+ if (!result) {
|
||||
+ cooldownHopper(hopper);
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ if (event.calledSetItem) {
|
||||
+ return CraftItemStack.asNMSCopy(event.getItem());
|
||||
+ } else {
|
||||
+ return itemstack;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static Inventory getInventory(final Container container) {
|
||||
+ final Inventory sourceInventory;
|
||||
+ if (container instanceof CompoundContainer compoundContainer) {
|
||||
+ // Have to special-case large chests as they work oddly
|
||||
+ sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest(compoundContainer);
|
||||
+ } else if (container instanceof BlockEntity blockEntity) {
|
||||
+ sourceInventory = blockEntity.getOwner(false).getInventory();
|
||||
+ } else if (container.getOwner() != null) {
|
||||
+ sourceInventory = container.getOwner().getInventory();
|
||||
+ } else {
|
||||
+ sourceInventory = new CraftInventory(container);
|
||||
+ }
|
||||
+ return sourceInventory;
|
||||
+ }
|
||||
+
|
||||
+ private static void cooldownHopper(final Hopper hopper) {
|
||||
+ if (hopper instanceof HopperBlockEntity blockEntity && blockEntity.getLevel() != null) {
|
||||
+ blockEntity.setCooldown(blockEntity.getLevel().spigotConfig.hopperTransfer);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static boolean allMatch(Container iinventory, Direction enumdirection, java.util.function.BiPredicate<ItemStack, Integer> test) {
|
||||
+ if (iinventory instanceof WorldlyContainer) {
|
||||
+ for (int i : ((WorldlyContainer) iinventory).getSlotsForFace(enumdirection)) {
|
||||
+ if (!test.test(iinventory.getItem(i), i)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ int size = iinventory.getContainerSize();
|
||||
+ for (int i = 0; i < size; i++) {
|
||||
+ if (!test.test(iinventory.getItem(i), i)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ private static boolean anyMatch(Container iinventory, Direction enumdirection, java.util.function.BiPredicate<ItemStack, Integer> test) {
|
||||
+ if (iinventory instanceof WorldlyContainer) {
|
||||
+ for (int i : ((WorldlyContainer) iinventory).getSlotsForFace(enumdirection)) {
|
||||
+ if (test.test(iinventory.getItem(i), i)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ int size = iinventory.getContainerSize();
|
||||
+ for (int i = 0; i < size; i++) {
|
||||
+ if (test.test(iinventory.getItem(i), i)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+ 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
|
||||
+
|
||||
private static boolean ejectItems(Level world, BlockPos blockposition, BlockState iblockdata, Container iinventory, HopperBlockEntity hopper) { // CraftBukkit
|
||||
Container iinventory1 = HopperBlockEntity.getAttachedContainer(world, blockposition, iblockdata);
|
||||
|
||||
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
if (HopperBlockEntity.isFullContainer(iinventory1, enumdirection)) {
|
||||
return false;
|
||||
} else {
|
||||
- for (int i = 0; i < iinventory.getContainerSize(); ++i) {
|
||||
- if (!iinventory.getItem(i).isEmpty()) {
|
||||
- ItemStack itemstack = iinventory.getItem(i).copy();
|
||||
- // ItemStack itemstack1 = addItem(iinventory, iinventory1, iinventory.removeItem(i, 1), enumdirection);
|
||||
-
|
||||
- // CraftBukkit start - Call event when pushing items into other inventories
|
||||
- CraftItemStack oitemstack = CraftItemStack.asCraftMirror(iinventory.removeItem(i, world.spigotConfig.hopperAmount)); // Spigot
|
||||
-
|
||||
- Inventory destinationInventory;
|
||||
- // Have to special case large chests as they work oddly
|
||||
- if (iinventory1 instanceof CompoundContainer) {
|
||||
- destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) iinventory1);
|
||||
- } else if (iinventory1.getOwner() != null) {
|
||||
- destinationInventory = iinventory1.getOwner().getInventory();
|
||||
- } else {
|
||||
- destinationInventory = new CraftInventory(iinventory);
|
||||
- }
|
||||
-
|
||||
- InventoryMoveItemEvent event = new InventoryMoveItemEvent(iinventory.getOwner().getInventory(), oitemstack.clone(), destinationInventory, true);
|
||||
- world.getCraftServer().getPluginManager().callEvent(event);
|
||||
- if (event.isCancelled()) {
|
||||
- hopper.setItem(i, itemstack);
|
||||
- hopper.setCooldown(world.spigotConfig.hopperTransfer); // Spigot
|
||||
- return false;
|
||||
- }
|
||||
- int origCount = event.getItem().getAmount(); // Spigot
|
||||
- ItemStack itemstack1 = HopperBlockEntity.addItem(iinventory, iinventory1, CraftItemStack.asNMSCopy(event.getItem()), enumdirection);
|
||||
+ // Paper start - replace logic; MAKE SURE TO CHECK FOR DIFFS ON UPDATES
|
||||
+ return hopperPush(world, iinventory1, enumdirection, hopper);
|
||||
+ // for (int i = 0; i < iinventory.getContainerSize(); ++i) {
|
||||
+ // if (!iinventory.getItem(i).isEmpty()) {
|
||||
+ // ItemStack itemstack = iinventory.getItem(i).copy();
|
||||
+ // // ItemStack itemstack1 = addItem(iinventory, iinventory1, iinventory.removeItem(i, 1), enumdirection);
|
||||
+
|
||||
+ // // CraftBukkit start - Call event when pushing items into other inventories
|
||||
+ // CraftItemStack oitemstack = CraftItemStack.asCraftMirror(iinventory.removeItem(i, world.spigotConfig.hopperAmount)); // Spigot
|
||||
+
|
||||
+ // Inventory destinationInventory;
|
||||
+ // // Have to special case large chests as they work oddly
|
||||
+ // if (iinventory1 instanceof CompoundContainer) {
|
||||
+ // destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) iinventory1);
|
||||
+ // } else if (iinventory1.getOwner() != null) {
|
||||
+ // destinationInventory = iinventory1.getOwner().getInventory();
|
||||
+ // } else {
|
||||
+ // destinationInventory = new CraftInventory(iinventory);
|
||||
+ // }
|
||||
+
|
||||
+ // InventoryMoveItemEvent event = new InventoryMoveItemEvent(iinventory.getOwner().getInventory(), oitemstack.clone(), destinationInventory, true);
|
||||
+ // world.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ // if (event.isCancelled()) {
|
||||
+ // hopper.setItem(i, itemstack);
|
||||
+ // hopper.setCooldown(world.spigotConfig.hopperTransfer); // Spigot
|
||||
+ // return false;
|
||||
+ // }
|
||||
+ // int origCount = event.getItem().getAmount(); // Spigot
|
||||
+ // ItemStack itemstack1 = HopperBlockEntity.addItem(iinventory, iinventory1, CraftItemStack.asNMSCopy(event.getItem()), enumdirection);
|
||||
// CraftBukkit end
|
||||
|
||||
- if (itemstack1.isEmpty()) {
|
||||
- iinventory1.setChanged();
|
||||
- return true;
|
||||
- }
|
||||
+ // if (itemstack1.isEmpty()) {
|
||||
+ // iinventory1.setChanged();
|
||||
+ // return true;
|
||||
+ // }
|
||||
|
||||
- itemstack.shrink(origCount - itemstack1.getCount()); // Spigot
|
||||
- iinventory.setItem(i, itemstack);
|
||||
- }
|
||||
- }
|
||||
+ // itemstack.shrink(origCount - itemstack1.getCount()); // Spigot
|
||||
+ // iinventory.setItem(i, itemstack);
|
||||
+ // }
|
||||
+ // }
|
||||
|
||||
- return false;
|
||||
+ // return false;
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
}
|
||||
|
||||
private static boolean isFullContainer(Container inventory, Direction direction) {
|
||||
- return HopperBlockEntity.getSlots(inventory, direction).allMatch((i) -> {
|
||||
- ItemStack itemstack = inventory.getItem(i);
|
||||
-
|
||||
- return itemstack.getCount() >= itemstack.getMaxStackSize();
|
||||
- });
|
||||
+ return allMatch(inventory, direction, STACK_SIZE_TEST); // Paper - no streams
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public static boolean suckInItems(Level world, Hopper hopper) {
|
||||
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
if (iinventory != null) {
|
||||
Direction enumdirection = Direction.DOWN;
|
||||
|
||||
- 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
|
||||
+ skipPullModeEventFire = skipHopperEvents;
|
||||
+ return !HopperBlockEntity.isEmptyContainer(iinventory, enumdirection) && anyMatch(iinventory, enumdirection, (item, i) -> {
|
||||
+ // Logic copied from below to avoid extra getItem calls
|
||||
+ if (!item.isEmpty() && canTakeItemFromContainer(hopper, iinventory, item, i, enumdirection)) {
|
||||
+ return hopperPull(world, hopper, iinventory, item, i);
|
||||
+ } else {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
});
|
||||
} else {
|
||||
Iterator iterator = HopperBlockEntity.getItemsAtAndAbove(world, hopper).iterator();
|
||||
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
}
|
||||
}
|
||||
|
||||
+ @io.papermc.paper.annotation.DoNotUse // Paper - method unused as logic is inlined above
|
||||
private static boolean a(Hopper ihopper, Container iinventory, int i, Direction enumdirection, Level world) { // Spigot
|
||||
ItemStack itemstack = iinventory.getItem(i);
|
||||
|
||||
- if (!itemstack.isEmpty() && HopperBlockEntity.canTakeItemFromContainer(ihopper, iinventory, itemstack, i, enumdirection)) {
|
||||
- ItemStack itemstack1 = itemstack.copy();
|
||||
- // ItemStack itemstack2 = addItem(iinventory, ihopper, iinventory.removeItem(i, 1), (EnumDirection) null);
|
||||
- // CraftBukkit start - Call event on collection of items from inventories into the hopper
|
||||
- CraftItemStack oitemstack = CraftItemStack.asCraftMirror(iinventory.removeItem(i, world.spigotConfig.hopperAmount)); // Spigot
|
||||
-
|
||||
- Inventory sourceInventory;
|
||||
- // Have to special case large chests as they work oddly
|
||||
- if (iinventory instanceof CompoundContainer) {
|
||||
- sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) iinventory);
|
||||
- } else if (iinventory.getOwner() != null) {
|
||||
- sourceInventory = iinventory.getOwner().getInventory();
|
||||
- } else {
|
||||
- sourceInventory = new CraftInventory(iinventory);
|
||||
- }
|
||||
-
|
||||
- InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, oitemstack.clone(), ihopper.getOwner().getInventory(), false);
|
||||
-
|
||||
- Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
- if (event.isCancelled()) {
|
||||
- iinventory.setItem(i, itemstack1);
|
||||
-
|
||||
- if (ihopper instanceof HopperBlockEntity) {
|
||||
- ((HopperBlockEntity) ihopper).setCooldown(world.spigotConfig.hopperTransfer); // Spigot
|
||||
- }
|
||||
-
|
||||
- return false;
|
||||
- }
|
||||
- int origCount = event.getItem().getAmount(); // Spigot
|
||||
- ItemStack itemstack2 = HopperBlockEntity.addItem(iinventory, ihopper, CraftItemStack.asNMSCopy(event.getItem()), null);
|
||||
- // CraftBukkit end
|
||||
-
|
||||
- if (itemstack2.isEmpty()) {
|
||||
- iinventory.setChanged();
|
||||
- return true;
|
||||
- }
|
||||
-
|
||||
- itemstack1.shrink(origCount - itemstack2.getCount()); // Spigot
|
||||
- iinventory.setItem(i, itemstack1);
|
||||
+ // Paper start - 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();
|
||||
+ // // ItemStack itemstack2 = addItem(iinventory, ihopper, iinventory.removeItem(i, 1), (EnumDirection) null);
|
||||
+ // // CraftBukkit start - Call event on collection of items from inventories into the hopper
|
||||
+ // CraftItemStack oitemstack = CraftItemStack.asCraftMirror(iinventory.removeItem(i, world.spigotConfig.hopperAmount)); // Spigot
|
||||
+
|
||||
+ // Inventory sourceInventory;
|
||||
+ // // Have to special case large chests as they work oddly
|
||||
+ // if (iinventory instanceof CompoundContainer) {
|
||||
+ // sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) iinventory);
|
||||
+ // } else if (iinventory.getOwner() != null) {
|
||||
+ // sourceInventory = iinventory.getOwner().getInventory();
|
||||
+ // } else {
|
||||
+ // sourceInventory = new CraftInventory(iinventory);
|
||||
+ // }
|
||||
+
|
||||
+ // InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, oitemstack.clone(), ihopper.getOwner().getInventory(), false);
|
||||
+
|
||||
+ // Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
+ // if (event.isCancelled()) {
|
||||
+ // iinventory.setItem(i, itemstack1);
|
||||
+
|
||||
+ // if (ihopper instanceof HopperBlockEntity) {
|
||||
+ // ((HopperBlockEntity) ihopper).setCooldown(world.spigotConfig.hopperTransfer); // Spigot
|
||||
+ // }
|
||||
+
|
||||
+ // return false;
|
||||
+ // }
|
||||
+ // int origCount = event.getItem().getAmount(); // Spigot
|
||||
+ // ItemStack itemstack2 = HopperBlockEntity.addItem(iinventory, ihopper, CraftItemStack.asNMSCopy(event.getItem()), null);
|
||||
+ // // CraftBukkit end
|
||||
+
|
||||
+ // if (itemstack2.isEmpty()) {
|
||||
+ // iinventory.setChanged();
|
||||
+ // return true;
|
||||
+ // }
|
||||
+
|
||||
+ // itemstack1.shrink(origCount - itemstack2.getCount()); // Spigot
|
||||
+ // iinventory.setItem(i, itemstack1);
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
public static boolean addItem(Container inventory, ItemEntity itemEntity) {
|
||||
boolean flag = false;
|
||||
// CraftBukkit start
|
||||
- InventoryPickupItemEvent event = new InventoryPickupItemEvent(inventory.getOwner().getInventory(), (org.bukkit.entity.Item) itemEntity.getBukkitEntity());
|
||||
+ InventoryPickupItemEvent event = new InventoryPickupItemEvent(getInventory(inventory), (org.bukkit.entity.Item) itemEntity.getBukkitEntity()); // Paper - use getInventory() to avoid snapshot creation
|
||||
itemEntity.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return false;
|
||||
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
stack = stack.split(to.getMaxStackSize());
|
||||
}
|
||||
// Spigot end
|
||||
+ ignoreTileUpdates = true; // Paper
|
||||
to.setItem(slot, stack);
|
||||
+ ignoreTileUpdates = false; // Paper
|
||||
stack = leftover; // Paper
|
||||
flag = true;
|
||||
} else if (HopperBlockEntity.canMergeItems(itemstack1, stack)) {
|
||||
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
// CraftBukkit end
|
||||
}
|
||||
|
||||
+ // Paper start - optimize hopper item suck in
|
||||
+ 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
|
||||
+
|
||||
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
|
||||
+ // eliminate multiple getEntitiesOfClass() but maintain the voxelshape collision by moving
|
||||
+ // the individual AABB checks into the predicate
|
||||
+ final double shiftX = hopper.getLevelX() - 0.5D;
|
||||
+ final double shiftY = hopper.getLevelY() - 0.5D;
|
||||
+ final double shiftZ = hopper.getLevelZ() - 0.5D;
|
||||
+ return world.getEntitiesOfClass(ItemEntity.class, HOPPER_ITEM_SUCK_OVERALL.move(shiftX, shiftY, shiftZ), (final Entity entity) -> {
|
||||
+ if (!entity.isAlive()) { // EntitySelector.ENTITY_STILL_ALIVE
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ for (final AABB aabb : HOPPER_ITEM_SUCK_INDIVIDUAL) {
|
||||
+ if (aabb.move(shiftX, shiftY, shiftZ).intersects(entity.getBoundingBox())) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+ });
|
||||
+ // Paper end - optimize hopper item suck in
|
||||
}
|
||||
|
||||
@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
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Container getContainerAt(Level world, double x, double y, double z) {
|
||||
+ // Paper start - add optimizeEntities parameter
|
||||
+ 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
|
||||
Object object = null;
|
||||
BlockPos blockposition = BlockPos.containing(x, y, z);
|
||||
if ( !world.spigotConfig.hopperCanLoadChunks && !world.hasChunkAt( blockposition ) ) return null; // Spigot
|
||||
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
}
|
||||
}
|
||||
|
||||
- if (object == null) {
|
||||
+ if (object == null && (!optimizeEntities || !world.paperConfig().hopper.ignoreOccludingBlocks || !org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(block).isOccluding())) { // Paper
|
||||
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 (!list.isEmpty()) {
|
||||
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
}
|
||||
|
||||
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?!
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
this.unpackLootTable((Player)null);
|
||||
- return this.getItems().stream().allMatch(ItemStack::isEmpty);
|
||||
+ // Paper start
|
||||
+ for (final ItemStack itemStack : this.getItems()) {
|
||||
+ if (!itemStack.isEmpty()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ return true;
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(int slot) {
|
||||
- this.unpackLootTable((Player)null);
|
||||
+ if (slot == 0) this.unpackLootTable((Player)null); // Paper
|
||||
return this.getItems().get(slot);
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Thu, 6 Jul 2023 20:17:37 -0700
|
||||
Subject: [PATCH] Optimize player lookups for beacons
|
||||
|
||||
For larger ranges, it's better to iterate over the player list
|
||||
than the entity slices.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
|
||||
double d0 = blockEntity != null ? blockEntity.getEffectRange() : (i * 10 + 10);// Paper - custom beacon ranges
|
||||
|
||||
AABB axisalignedbb = (new AABB(blockposition)).inflate(d0).expandTowards(0.0D, (double) world.getHeight(), 0.0D);
|
||||
- List<Player> list = world.getEntitiesOfClass(Player.class, axisalignedbb);
|
||||
+ // Paper start - optimize player lookup for beacons
|
||||
+ List<Player> list;
|
||||
+ if (d0 <= 128.0) {
|
||||
+ list = world.getEntitiesOfClass(Player.class, axisalignedbb);
|
||||
+ } else {
|
||||
+ list = (List)world.getNearbyPlayers(null, (double)blockposition.getX() + 0.5, (double)blockposition.getY() + 0.5, (double)blockposition.getZ() + 0.5, -1.0, (net.minecraft.world.entity.Entity entity) -> {
|
||||
+ return !entity.isSpectator() && entity.getBoundingBox().intersects(axisalignedbb);
|
||||
+ });
|
||||
+ }
|
||||
+ // Paper end - optimize player lookup for beacons
|
||||
|
||||
return list;
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Wed, 5 Apr 2023 20:15:47 +0100
|
||||
Subject: [PATCH] Prevent GameEvents being fired from unloaded chunks
|
||||
|
||||
|
||||
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 {
|
||||
|
||||
@Override
|
||||
public void gameEvent(GameEvent event, Vec3 emitterPos, GameEvent.Context emitter) {
|
||||
+ // Paper start
|
||||
+ if (this.getChunkIfLoadedImmediately((Mth.floor(emitterPos.x) >> 4), (Mth.floor(emitterPos.z) >> 4)) == null) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.gameEventDispatcher.post(event, emitterPos, emitter);
|
||||
}
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Mon, 3 Apr 2023 08:55:52 +0100
|
||||
Subject: [PATCH] Prevent causing expired keys from impacting new joins
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java
|
||||
@@ -0,0 +0,0 @@ public class ClientboundPlayerInfoUpdatePacket implements Packet<ClientGamePacke
|
||||
INITIALIZE_CHAT((serialized, buf) -> {
|
||||
serialized.chatSession = buf.readNullable(RemoteChatSession.Data::read);
|
||||
}, (buf, entry) -> {
|
||||
- buf.writeNullable(entry.chatSession, RemoteChatSession.Data::write);
|
||||
+ // Paper start
|
||||
+ RemoteChatSession.Data chatSession = entry.chatSession;
|
||||
+ if (chatSession != null && chatSession.profilePublicKey().hasExpired()) {
|
||||
+ chatSession = null;
|
||||
+ }
|
||||
+ buf.writeNullable(chatSession, RemoteChatSession.Data::write);
|
||||
+ // Paper end
|
||||
}),
|
||||
UPDATE_GAME_MODE((serialized, buf) -> {
|
||||
serialized.gameMode = GameType.byId(buf.readVarInt());
|
||||
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 implements ServerPlayerConnection, Tic
|
||||
private final AtomicReference<Instant> lastChatTimeStamp;
|
||||
@Nullable
|
||||
private RemoteChatSession chatSession;
|
||||
+ private boolean hasLoggedExpiry = false; // Paper
|
||||
private SignedMessageChain.Decoder signedMessageDecoder;
|
||||
private final LastSeenMessagesValidator lastSeenMessages;
|
||||
private final MessageSignatureCache messageSignatureCache;
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
this.disconnect(Component.translatable("multiplayer.disconnect.idling"), org.bukkit.event.player.PlayerKickEvent.Cause.IDLING); // Paper - kick event cause
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ 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
|
||||
+
|
||||
}
|
||||
|
||||
public void resetPosition() {
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
|
||||
private void resetPlayerChatState(RemoteChatSession session) {
|
||||
this.chatSession = session;
|
||||
+ this.hasLoggedExpiry = false; // Paper
|
||||
this.signedMessageDecoder = session.createMessageDecoder(this.player.getUUID());
|
||||
this.chatMessageChain.append((executor) -> {
|
||||
this.player.setChatSession(session);
|
||||
@@ -1,64 +0,0 @@
|
||||
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
|
||||
|
||||
This fixes the bug causing cancelling PlayerInteractEvent to cause items to continue to be used despite being cancelled on the server.
|
||||
|
||||
For example, items being consumed but never finishing, shields being put up, etc.
|
||||
The underlying issue of this is that the client modifies their synced data values, and so we have to (forcibly) resend
|
||||
them in order for the client to reset their using item state.
|
||||
|
||||
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 {
|
||||
}
|
||||
// Paper end - extend Player Interact cancellation
|
||||
player.getBukkitEntity().updateInventory(); // SPIGOT-2867
|
||||
+ this.player.resyncUsingItem(this.player); // Paper - Resend player's using item status
|
||||
enuminteractionresult = (event.useItemInHand() != Event.Result.ALLOW) ? InteractionResult.SUCCESS : InteractionResult.PASS;
|
||||
} else if (this.gameModeForPlayer == GameType.SPECTATOR) {
|
||||
MenuProvider itileinventory = iblockdata.getMenuProvider(world, blockposition);
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayerGameMode {
|
||||
|
||||
return enuminteractionresult1;
|
||||
}
|
||||
+ // Paper start - 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
|
||||
}
|
||||
return enuminteractionresult;
|
||||
// CraftBukkit end
|
||||
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 implements ServerPlayerConnection, Tic
|
||||
}
|
||||
|
||||
if (cancelled) {
|
||||
+ this.player.resyncUsingItem(this.player); // Paper - Resend player's using item status
|
||||
this.player.getBukkitEntity().updateInventory(); // SPIGOT-2524
|
||||
return;
|
||||
}
|
||||
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 {
|
||||
return ((Byte) this.entityData.get(LivingEntity.DATA_LIVING_ENTITY_FLAGS) & 2) > 0 ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public void resyncUsingItem(ServerPlayer serverPlayer) {
|
||||
+ this.getEntityData().resendPossiblyDesyncedDataValues(java.util.List.of(DATA_LIVING_ENTITY_FLAGS), serverPlayer);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
// Paper start - lag compensate eating
|
||||
protected long eatStartTime;
|
||||
protected int totalEatTimeTicks;
|
||||
@@ -1,85 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Tue, 30 May 2023 12:59:10 -0700
|
||||
Subject: [PATCH] Refresh ProjectileSource for projectiles
|
||||
|
||||
Makes sure the value returned by Projectile#getShooter in
|
||||
the API matches the owner UUID specified in the entity nbt.
|
||||
Previously, after the entity reloaded, Projectile#getShooter
|
||||
would return null, while the entity still had an owner.
|
||||
|
||||
Also fixes setting the shooter/owner to null actually
|
||||
clearing the owner.
|
||||
|
||||
Co-authored-by: Warrior <50800980+Warriorrrr@users.noreply.github.com>
|
||||
|
||||
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 Nameable, EntityAccess, CommandSource {
|
||||
public boolean valid;
|
||||
public boolean generation;
|
||||
public int maxAirTicks = this.getDefaultMaxAirSupply(); // CraftBukkit - SPIGOT-6907: re-implement LivingEntity#setMaximumAir()
|
||||
+ @Nullable // Paper
|
||||
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;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Projectile extends Entity implements TraceableEntity {
|
||||
this.ownerUUID = entity.getUUID();
|
||||
this.cachedOwner = entity;
|
||||
}
|
||||
- this.projectileSource = (entity != null && entity.getBukkitEntity() instanceof ProjectileSource) ? (ProjectileSource) entity.getBukkitEntity() : null; // CraftBukkit
|
||||
-
|
||||
+ // Paper start - Fix null owners not being handled
|
||||
+ else {
|
||||
+ this.ownerUUID = null;
|
||||
+ this.cachedOwner = null;
|
||||
+ this.projectileSource = null;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+ this.refreshProjectileSource(false); // Paper
|
||||
+ }
|
||||
+ // Paper start
|
||||
+ public void refreshProjectileSource(boolean fillCache) {
|
||||
+ if (fillCache) {
|
||||
+ this.getOwner();
|
||||
+ }
|
||||
+ if (this.cachedOwner != null && !this.cachedOwner.isRemoved() && this.projectileSource == null && this.cachedOwner.getBukkitEntity() instanceof ProjectileSource projSource) {
|
||||
+ this.projectileSource = projSource;
|
||||
+ }
|
||||
}
|
||||
+ // Paper end
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Entity getOwner() {
|
||||
if (this.cachedOwner != null && !this.cachedOwner.isRemoved()) {
|
||||
+ this.refreshProjectileSource(false); // Paper
|
||||
return this.cachedOwner;
|
||||
} else if (this.ownerUUID != null && this.level() instanceof ServerLevel) {
|
||||
this.cachedOwner = ((ServerLevel) this.level()).getEntity(this.ownerUUID);
|
||||
@@ -0,0 +0,0 @@ public abstract class Projectile extends Entity implements TraceableEntity {
|
||||
}
|
||||
}
|
||||
// Paper end
|
||||
+ this.refreshProjectileSource(false); // Paper
|
||||
return this.cachedOwner;
|
||||
} else {
|
||||
return null;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java b/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractProjectile extends CraftEntity implements Projecti
|
||||
|
||||
@Override
|
||||
public final org.bukkit.projectiles.ProjectileSource getShooter() {
|
||||
+ this.getHandle().refreshProjectileSource(true); // Paper
|
||||
return this.getHandle().projectileSource;
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Josh Roy <10731363+JRoy@users.noreply.github.com>
|
||||
Date: Mon, 23 Jan 2023 19:19:01 -0500
|
||||
Subject: [PATCH] Remove CraftItemStack#setAmount null assignment
|
||||
|
||||
This creates a problem with Paper's item serialization
|
||||
api where deserialized items, which are internally
|
||||
created as a CraftItemStack, will be completely lost if
|
||||
#setAmount(0) is invoked (since the underlying handle
|
||||
is set to null), while a regular Bukkit ItemStack
|
||||
simply sets the amount field to zero, retaining the
|
||||
item's data.
|
||||
|
||||
Vanilla treats items with zero amounts the same as items
|
||||
with less than zero amounts, so this code doesn't create
|
||||
a problem with operations on the vanilla ItemStack.
|
||||
|
||||
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.handle.setCount(amount);
|
||||
- if (amount == 0) {
|
||||
+ if (false && amount == 0) { // Paper - remove CraftItemStack#setAmount null assignment
|
||||
this.handle = null;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sun, 18 Jun 2023 13:48:11 +0100
|
||||
Subject: [PATCH] Temp: Pre-init PlayerChunkLoaderData in order to prepopulate
|
||||
the BFS lookup cache because potatos
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
@@ -0,0 +0,0 @@ public class Main {
|
||||
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());
|
||||
// Paper end
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Thu, 30 Mar 2023 03:13:58 +0100
|
||||
Subject: [PATCH] Treat sequence violations like they should be
|
||||
|
||||
|
||||
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 implements ServerPlayerConnection, Tic
|
||||
|
||||
public void ackBlockChangesUpTo(int sequence) {
|
||||
if (sequence < 0) {
|
||||
+ this.disconnect("Expected packet sequence nr >= 0", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper
|
||||
throw new IllegalArgumentException("Expected packet sequence nr >= 0");
|
||||
} else {
|
||||
this.ackBlockChangesUpTo = Math.max(sequence, this.ackBlockChangesUpTo);
|
||||
@@ -1,18 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
|
||||
Date: Sat, 18 Feb 2023 16:23:18 +0100
|
||||
Subject: [PATCH] Update the flag when a captured block state is outdated
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
blockstate = CapturedBlockState.getTreeBlockState(this, pos, flags);
|
||||
this.capturedBlockStates.put(pos.immutable(), blockstate);
|
||||
}
|
||||
+ blockstate.setFlag(flags); // Paper - update the flag also
|
||||
blockstate.setData(state);
|
||||
return true;
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Sauve <paul@technove.co>
|
||||
Date: Sun, 9 May 2021 16:49:49 -0500
|
||||
Subject: [PATCH] Use array for gamerule storage
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/GameRules.java b/src/main/java/net/minecraft/world/level/GameRules.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/GameRules.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/GameRules.java
|
||||
@@ -0,0 +0,0 @@ public class GameRules {
|
||||
public static final GameRules.Key<GameRules.BooleanValue> RULE_GLOBAL_SOUND_EVENTS = GameRules.register("globalSoundEvents", GameRules.Category.MISC, GameRules.BooleanValue.create(true));
|
||||
public static final GameRules.Key<GameRules.BooleanValue> RULE_DO_VINES_SPREAD = GameRules.register("doVinesSpread", GameRules.Category.UPDATES, GameRules.BooleanValue.create(true));
|
||||
private final Map<GameRules.Key<?>, GameRules.Value<?>> rules;
|
||||
+ private final GameRules.Value<?>[] gameruleArray; // Paper
|
||||
|
||||
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);
|
||||
@@ -0,0 +0,0 @@ public class GameRules {
|
||||
}
|
||||
|
||||
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
|
||||
+ this((Map) GameRules.GAME_RULE_TYPES.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, (entry) -> {
|
||||
return ((GameRules.Type) entry.getValue()).createRule();
|
||||
- }));
|
||||
+ })));
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
private GameRules(Map<GameRules.Key<?>, GameRules.Value<?>> rules) {
|
||||
this.rules = rules;
|
||||
+
|
||||
+ // Paper start
|
||||
+ int arraySize = rules.keySet().stream().mapToInt(key -> key.gameRuleIndex).max().orElse(-1) + 1;
|
||||
+ GameRules.Value<?>[] values = new GameRules.Value[arraySize];
|
||||
+
|
||||
+ for (Entry<GameRules.Key<?>, GameRules.Value<?>> entry : rules.entrySet()) {
|
||||
+ values[entry.getKey().gameRuleIndex] = entry.getValue();
|
||||
+ }
|
||||
+
|
||||
+ this.gameruleArray = values;
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
public CompoundTag createTag() {
|
||||
@@ -0,0 +0,0 @@ public class GameRules {
|
||||
}
|
||||
|
||||
public static final class Key<T extends GameRules.Value<T>> {
|
||||
+ // Paper start
|
||||
+ private static int lastGameRuleIndex = 0;
|
||||
+ public final int gameRuleIndex = lastGameRuleIndex++;
|
||||
+ // Paper end
|
||||
|
||||
final String id;
|
||||
private final GameRules.Category category;
|
||||
@@ -1,51 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 8 Jan 2023 17:38:28 -0800
|
||||
Subject: [PATCH] Use single player info update packet on join
|
||||
|
||||
|
||||
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 implements ServerPlayerConnection, Tic
|
||||
this.signedMessageDecoder = session.createMessageDecoder(this.player.getUUID());
|
||||
this.chatMessageChain.append((executor) -> {
|
||||
this.player.setChatSession(session);
|
||||
- this.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.INITIALIZE_CHAT), List.of(this.player)));
|
||||
+ this.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.INITIALIZE_CHAT), List.of(this.player)), this.player); // Paper
|
||||
return CompletableFuture.completedFuture((Object) null);
|
||||
});
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
|
||||
// CraftBukkit start - sendAll above replaced with this loop
|
||||
ClientboundPlayerInfoUpdatePacket packet = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player));
|
||||
|
||||
+ final List<ServerPlayer> onlinePlayers = Lists.newArrayListWithExpectedSize(this.players.size() - 1); // Paper - use single player info update packet
|
||||
for (int i = 0; i < this.players.size(); ++i) {
|
||||
ServerPlayer entityplayer1 = (ServerPlayer) this.players.get(i);
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
|
||||
entityplayer1.connection.send(packet);
|
||||
}
|
||||
|
||||
- if (!bukkitPlayer.canSee(entityplayer1.getBukkitEntity())) {
|
||||
+ if (entityplayer1 == player || !bukkitPlayer.canSee(entityplayer1.getBukkitEntity())) { // Paper - don't include joining player
|
||||
continue;
|
||||
}
|
||||
|
||||
- player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(entityplayer1)));
|
||||
+ onlinePlayers.add(entityplayer1); // Paper - use single player info update packet
|
||||
}
|
||||
+ // Paper start - use single player info update packet
|
||||
+ if (!onlinePlayers.isEmpty()) {
|
||||
+ player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(onlinePlayers));
|
||||
+ }
|
||||
+ // Paper end
|
||||
player.sentListPacket = true;
|
||||
player.supressTrackerForLogin = false; // Paper
|
||||
((ServerLevel)player.level()).getChunkSource().chunkMap.addEntity(player); // Paper - track entity now
|
||||
@@ -1,38 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lama06 <andreasprues36@gmail.com>
|
||||
Date: Sat, 21 Jan 2023 13:53:23 +0100
|
||||
Subject: [PATCH] Win Screen API
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.server.level.ServerPlayer seenCredits
|
||||
|
||||
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 {
|
||||
this.getHandle().connection.send(packet);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void showWinScreen() {
|
||||
+ if (getHandle().connection == null) return;
|
||||
+ var packet = new ClientboundGameEventPacket(ClientboundGameEventPacket.WIN_GAME, 1);
|
||||
+ getHandle().connection.send(packet);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasSeenWinScreen() {
|
||||
+ return getHandle().seenCredits;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setHasSeenWinScreen(boolean hasSeenWinScreen) {
|
||||
+ getHandle().seenCredits = hasSeenWinScreen;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void setRotation(float yaw, float pitch) {
|
||||
// Paper start - Teleport API
|
||||
@@ -1,24 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Wed, 15 Sep 2021 14:52:42 -0700
|
||||
Subject: [PATCH] config for disabling entity tag tags
|
||||
|
||||
|
||||
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
|
||||
if (world.isClientSide || !entity.onlyOpCanSetNbt() || player != null && minecraftserver.getPlayerList().isOp(player.getGameProfile())) {
|
||||
CompoundTag nbttagcompound1 = entity.saveWithoutId(new CompoundTag());
|
||||
UUID uuid = entity.getUUID();
|
||||
+ // Paper start - filter out protected tags
|
||||
+ if (player == null || !player.getBukkitEntity().hasPermission("minecraft.nbt.place")) {
|
||||
+ for (net.minecraft.commands.arguments.NbtPathArgument.NbtPath tag : world.paperConfig().entities.spawning.filteredEntityTagNbtPaths) {
|
||||
+ tag.remove(itemNbt.getCompound("EntityTag"));
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
nbttagcompound1.merge(itemNbt.getCompound("EntityTag"));
|
||||
entity.setUUID(uuid);
|
||||
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Wed, 14 Jun 2023 13:17:40 -0700
|
||||
Subject: [PATCH] fix MapLike spam for missing key 'selector'
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/gameevent/vibrations/VibrationSystem.java b/src/main/java/net/minecraft/world/level/gameevent/vibrations/VibrationSystem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/gameevent/vibrations/VibrationSystem.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/gameevent/vibrations/VibrationSystem.java
|
||||
@@ -0,0 +0,0 @@ public interface VibrationSystem {
|
||||
public static Codec<VibrationSystem.Data> CODEC = RecordCodecBuilder.create((instance) -> {
|
||||
return instance.group(VibrationInfo.CODEC.optionalFieldOf("event").forGetter((vibrationsystem_a) -> {
|
||||
return Optional.ofNullable(vibrationsystem_a.currentVibration);
|
||||
- }), VibrationSelector.CODEC.fieldOf("selector").forGetter(VibrationSystem.Data::getSelectionStrategy), ExtraCodecs.NON_NEGATIVE_INT.fieldOf("event_delay").orElse(0).forGetter(VibrationSystem.Data::getTravelTimeInTicks)).apply(instance, (optional, vibrationselector, integer) -> {
|
||||
+ }), Codec.optionalField("selector", VibrationSelector.CODEC).xmap(o -> o.orElseGet(VibrationSelector::new), Optional::of).forGetter(VibrationSystem.Data::getSelectionStrategy), ExtraCodecs.NON_NEGATIVE_INT.fieldOf("event_delay").orElse(0).forGetter(VibrationSystem.Data::getTravelTimeInTicks)).apply(instance, (optional, vibrationselector, integer) -> { // Paper - fix MapLike spam for missing "selector" in 1.19.2
|
||||
return new VibrationSystem.Data((VibrationInfo) optional.orElse(null), vibrationselector, integer, true); // CraftBukkit - decompile error
|
||||
});
|
||||
});
|
||||
@@ -1,74 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Tue, 11 Jul 2023 11:22:30 -0700
|
||||
Subject: [PATCH] fix item meta for tadpole buckets
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftItemFactory implements ItemFactory {
|
||||
case COD_BUCKET:
|
||||
case PUFFERFISH_BUCKET:
|
||||
case SALMON_BUCKET:
|
||||
+ case TADPOLE_BUCKET: // Paper
|
||||
case ITEM_FRAME:
|
||||
case GLOW_ITEM_FRAME:
|
||||
case PAINTING:
|
||||
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 {
|
||||
case COD_BUCKET:
|
||||
case PUFFERFISH_BUCKET:
|
||||
case SALMON_BUCKET:
|
||||
+ case TADPOLE_BUCKET: // Paper
|
||||
case ITEM_FRAME:
|
||||
case GLOW_ITEM_FRAME:
|
||||
case PAINTING:
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEntityTag.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEntityTag.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEntityTag.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEntityTag.java
|
||||
@@ -0,0 +0,0 @@ public class CraftMetaEntityTag extends CraftMetaItem {
|
||||
Material.COD_BUCKET,
|
||||
Material.PUFFERFISH_BUCKET,
|
||||
Material.SALMON_BUCKET,
|
||||
+ Material.TADPOLE_BUCKET, // Paper
|
||||
Material.ITEM_FRAME,
|
||||
Material.GLOW_ITEM_FRAME,
|
||||
Material.PAINTING
|
||||
diff --git a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
|
||||
+++ b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
|
||||
@@ -0,0 +0,0 @@ public class ItemMetaTest extends AbstractTestingBase {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - check entity tag metas
|
||||
+ private static final java.util.Set<Class<?>> ENTITY_TAG_METAS = java.util.Set.of(
|
||||
+ CraftMetaEntityTag.class,
|
||||
+ CraftMetaTropicalFishBucket.class,
|
||||
+ CraftMetaAxolotlBucket.class
|
||||
+ );
|
||||
+ @Test
|
||||
+ public void testEntityTagMeta() {
|
||||
+ for (final Item item : BuiltInRegistries.ITEM) {
|
||||
+ if (item instanceof net.minecraft.world.item.HangingEntityItem || item instanceof net.minecraft.world.item.MobBucketItem) {
|
||||
+ ItemStack stack = new ItemStack(CraftMagicNumbers.getMaterial(item));
|
||||
+ assertTrue("missing entity tag meta handling for " + item, ENTITY_TAG_METAS.contains(stack.getItemMeta().getClass()));
|
||||
+ stack = CraftItemStack.asNewCraftStack(net.minecraft.world.item.Items.STONE);
|
||||
+ stack.editMeta(meta -> meta.displayName(net.kyori.adventure.text.Component.text("hello")));
|
||||
+ stack.setType(CraftMagicNumbers.getMaterial(item));
|
||||
+ assertTrue("missing entity tag meta handling for " + item, ENTITY_TAG_METAS.contains(stack.getItemMeta().getClass()));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Test
|
||||
public void testEachExtraData() {
|
||||
final List<StackProvider> providers = Arrays.asList(
|
||||
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 1 Dec 2022 12:42:18 -0800
|
||||
Subject: [PATCH] remove duplicate animate packet for records
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/RecordItem.java b/src/main/java/net/minecraft/world/item/RecordItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/RecordItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/RecordItem.java
|
||||
@@ -0,0 +0,0 @@ public class RecordItem extends Item {
|
||||
ItemStack itemstack = context.getItemInHand();
|
||||
|
||||
if (!world.isClientSide) {
|
||||
- if (true) return InteractionResult.SUCCESS; // CraftBukkit - handled in ItemStack
|
||||
+ if (true) return InteractionResult.sidedSuccess(world.isClientSide); // CraftBukkit - handled in ItemStack // Paper - fix duplicate animate packet
|
||||
Player entityhuman = context.getPlayer();
|
||||
BlockEntity tileentity = world.getBlockEntity(blockposition);
|
||||
|
||||
Reference in New Issue
Block a user