moooore
This commit is contained in:
parent
6456b5dea8
commit
cb79de80c4
59 changed files with 373 additions and 380 deletions
|
@ -1,42 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 24 Oct 2021 20:58:43 -0700
|
||||
Subject: [PATCH] Entity powdered snow API
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.monster.Skeleton inPowderSnowTime
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
index 6fab713531665298d3b03e7960a17ecb1471a6d7..4ed5647101bbace0005b1ebfb824e4aed48e43cb 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -1099,6 +1099,13 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
}
|
||||
// Paper end - raw entity serialization API
|
||||
|
||||
+ // Paper start - entity powdered snow API
|
||||
+ @Override
|
||||
+ public boolean isInPowderedSnow() {
|
||||
+ return getHandle().isInPowderSnow || getHandle().wasInPowderSnow; // depending on the location in the entity "tick" either could be needed.
|
||||
+ }
|
||||
+ // Paper end - entity powdered snow API
|
||||
+
|
||||
// Paper start - missing entity api
|
||||
@Override
|
||||
public boolean isInvisible() { // Paper - moved up from LivingEntity
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java
|
||||
index a0ea54181de6c6685deef265cbe9f66aabbca42b..6f98da9be6aef35e3b5c940188b872459a383c8e 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java
|
||||
@@ -45,4 +45,11 @@ public class CraftSkeleton extends CraftAbstractSkeleton implements Skeleton {
|
||||
public SkeletonType getSkeletonType() {
|
||||
return SkeletonType.NORMAL;
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int inPowderedSnowTime() {
|
||||
+ return getHandle().inPowderSnowTime;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sat, 28 Aug 2021 09:00:45 -0700
|
||||
Subject: [PATCH] Add API for item entity health
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.item.ItemEntity health
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
|
||||
index 4a15c3786edbfeae3367c0b20fb6aee11d62aea6..1a291dd8a287db30e71dcb315599fc4b038764c4 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
|
||||
@@ -98,6 +98,21 @@ public class CraftItem extends CraftEntity implements Item {
|
||||
public void setWillAge(boolean willAge) {
|
||||
this.getHandle().age = willAge ? 0 : NO_AGE_TIME;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public int getHealth() {
|
||||
+ return this.getHandle().health;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setHealth(int health) {
|
||||
+ if (health <= 0) {
|
||||
+ this.getHandle().getItem().onDestroyed(this.getHandle());
|
||||
+ this.getHandle().discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.PLUGIN);
|
||||
+ } else {
|
||||
+ this.getHandle().health = health;
|
||||
+ }
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
@Override
|
|
@ -1,19 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nassim Jahnke <nassim@njahnke.dev>
|
||||
Date: Thu, 16 Dec 2021 09:40:39 +0100
|
||||
Subject: [PATCH] Configurable max block light for monster spawning
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Monster.java b/src/main/java/net/minecraft/world/entity/monster/Monster.java
|
||||
index f73604d762efbac400d40f536ec1782fca584efa..e7bfce0534c7ef3a1480a1082ae8514caf78778b 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Monster.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Monster.java
|
||||
@@ -91,7 +91,7 @@ public abstract class Monster extends PathfinderMob implements Enemy {
|
||||
return false;
|
||||
} else {
|
||||
DimensionType dimensionType = world.dimensionType();
|
||||
- int i = dimensionType.monsterSpawnBlockLightLimit();
|
||||
+ int i = world.getLevel().paperConfig().entities.spawning.monsterSpawnMaxLightLevel.or(dimensionType.monsterSpawnBlockLightLimit()); // Paper - Configurable max block light for monster spawning
|
||||
if (i < 15 && world.getBrightness(LightLayer.BLOCK, pos) > i) {
|
||||
return false;
|
||||
} else {
|
|
@ -1,85 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Wed, 22 Dec 2021 09:51:48 -0800
|
||||
Subject: [PATCH] Fix sticky pistons and BlockPistonRetractEvent
|
||||
|
||||
There is an explicit check in the handling code for empty pistons that
|
||||
prevents sticky pistons from firing the event. However when we look back
|
||||
at the history we see that this check was originally added so that ONLY
|
||||
sticky pistons would fire the retract event. I'm not sure why.
|
||||
https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/commits/1092acbddf07edfa4100bc6824504ac75088e913
|
||||
|
||||
Over the course of several updates, the meaning of that field appears to
|
||||
have changed from "is NOT sticky" to "is sticky". So now its having the
|
||||
opposite effect. Only normal pistons fire the retraction event. And like
|
||||
all things in CB, it's just been carried around since.
|
||||
|
||||
If we are to believe the history, the correct fix for this issue is to
|
||||
flip it so it only fires for sticky pistons, but that puts us in a
|
||||
bind. It's already firing for non-sticky pistons, changing it now would
|
||||
likely result in breakage. Furthermore, there is little documentation as
|
||||
to WHY that was ever intended to be the case.
|
||||
|
||||
Instead we opt to remove the check entirely so that the event fires for
|
||||
all piston types.
|
||||
|
||||
Co-authored-by: Zach Brown <zach@zachbr.io>
|
||||
Co-authored-by: Madeline Miller <mnmiller1@me.com>
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
|
||||
index 2f2c9fb65d4cc8bd40303216e03c5c1956305ff4..e6bfbe2588e0c2a1be14e38d654e889d392ad4db 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
|
||||
@@ -160,15 +160,15 @@ public class PistonBaseBlock extends DirectionalBlock {
|
||||
}
|
||||
|
||||
// CraftBukkit start
|
||||
- if (!this.isSticky) {
|
||||
- org.bukkit.block.Block block = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ());
|
||||
- BlockPistonRetractEvent event = new BlockPistonRetractEvent(block, ImmutableList.<org.bukkit.block.Block>of(), CraftBlock.notchToBlockFace(enumdirection));
|
||||
- world.getCraftServer().getPluginManager().callEvent(event);
|
||||
-
|
||||
- if (event.isCancelled()) {
|
||||
- return;
|
||||
- }
|
||||
- }
|
||||
+ // if (!this.isSticky) { // Paper - Fix sticky pistons and BlockPistonRetractEvent; Move further down
|
||||
+ // org.bukkit.block.Block block = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ());
|
||||
+ // BlockPistonRetractEvent event = new BlockPistonRetractEvent(block, ImmutableList.<org.bukkit.block.Block>of(), CraftBlock.notchToBlockFace(enumdirection));
|
||||
+ // world.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ //
|
||||
+ // if (event.isCancelled()) {
|
||||
+ // return;
|
||||
+ // }
|
||||
+ // }
|
||||
// PAIL: checkME - what happened to setTypeAndData?
|
||||
// CraftBukkit end
|
||||
world.blockEvent(pos, this, b0, enumdirection.get3DDataValue());
|
||||
@@ -245,6 +245,13 @@ public class PistonBaseBlock extends DirectionalBlock {
|
||||
|
||||
BlockState iblockdata2 = (BlockState) ((BlockState) Blocks.MOVING_PISTON.defaultBlockState().setValue(MovingPistonBlock.FACING, enumdirection)).setValue(MovingPistonBlock.TYPE, this.isSticky ? PistonType.STICKY : PistonType.DEFAULT);
|
||||
|
||||
+ // Paper start - Fix sticky pistons and BlockPistonRetractEvent; Move empty piston retract call to fix multiple event fires
|
||||
+ if (!this.isSticky) {
|
||||
+ if (!new BlockPistonRetractEvent(CraftBlock.at(world, pos), java.util.Collections.emptyList(), CraftBlock.notchToBlockFace(enumdirection)).callEvent()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Fix sticky pistons and BlockPistonRetractEvent
|
||||
world.setBlock(pos, iblockdata2, 20);
|
||||
world.setBlockEntity(MovingPistonBlock.newMovingBlockEntity(pos, iblockdata2, (BlockState) this.defaultBlockState().setValue(PistonBaseBlock.FACING, Direction.from3DDataValue(data & 7)), enumdirection, false, true));
|
||||
world.blockUpdated(pos, iblockdata2.getBlock());
|
||||
@@ -271,6 +278,13 @@ public class PistonBaseBlock extends DirectionalBlock {
|
||||
if (type == 1 && !iblockdata3.isAir() && PistonBaseBlock.isPushable(iblockdata3, world, blockposition1, enumdirection.getOpposite(), false, enumdirection) && (iblockdata3.getPistonPushReaction() == PushReaction.NORMAL || iblockdata3.is(Blocks.PISTON) || iblockdata3.is(Blocks.STICKY_PISTON))) {
|
||||
this.moveBlocks(world, pos, enumdirection, false);
|
||||
} else {
|
||||
+ // Paper start - Fix sticky pistons and BlockPistonRetractEvent; fire BlockPistonRetractEvent for sticky pistons retracting nothing (air)
|
||||
+ if (type == TRIGGER_CONTRACT && iblockdata2.isAir()) {
|
||||
+ if (!new BlockPistonRetractEvent(CraftBlock.at(world, pos), java.util.Collections.emptyList(), CraftBlock.notchToBlockFace(enumdirection)).callEvent()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Fix sticky pistons and BlockPistonRetractEvent
|
||||
world.removeBlock(pos.relative(enumdirection), false);
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <blake.galbreath@gmail.com>
|
||||
Date: Thu, 23 Dec 2021 15:32:50 -0600
|
||||
Subject: [PATCH] Expose isFuel and canSmelt methods to FurnaceInventory
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryFurnace.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryFurnace.java
|
||||
index 29a8cd7667860c4598a556e6ef3af39c731683db..bd370f5c856d75b7210ef26036aedaa859c570be 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryFurnace.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryFurnace.java
|
||||
@@ -40,6 +40,20 @@ public class CraftInventoryFurnace extends CraftInventory implements FurnaceInve
|
||||
this.setItem(0, stack);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean isFuel(ItemStack stack) {
|
||||
+ return stack != null && !stack.getType().isEmpty() && AbstractFurnaceBlockEntity.isFuel(CraftItemStack.asNMSCopy(stack));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean canSmelt(ItemStack stack) {
|
||||
+ // data packs are always loaded in the main world
|
||||
+ net.minecraft.server.level.ServerLevel world = ((org.bukkit.craftbukkit.CraftWorld) org.bukkit.Bukkit.getWorlds().get(0)).getHandle();
|
||||
+ return stack != null && !stack.getType().isEmpty() && world.getRecipeManager().getRecipeFor(((AbstractFurnaceBlockEntity) this.inventory).recipeType, new net.minecraft.world.item.crafting.SingleRecipeInput(CraftItemStack.asNMSCopy(stack)), world).isPresent();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public Furnace getHolder() {
|
||||
return (Furnace) this.inventory.getOwner();
|
|
@ -1,69 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Sun, 26 Dec 2021 14:03:17 -0500
|
||||
Subject: [PATCH] Bucketable API
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/entity/PaperBucketable.java b/src/main/java/io/papermc/paper/entity/PaperBucketable.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..d3fc2e5db9f3c20120b403bf03c3c340b9956cbd
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/entity/PaperBucketable.java
|
||||
@@ -0,0 +1,31 @@
|
||||
+package io.papermc.paper.entity;
|
||||
+
|
||||
+import org.bukkit.Sound;
|
||||
+import org.bukkit.craftbukkit.CraftSound;
|
||||
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
+import org.bukkit.inventory.ItemStack;
|
||||
+
|
||||
+public interface PaperBucketable extends Bucketable {
|
||||
+
|
||||
+ net.minecraft.world.entity.animal.Bucketable getHandle();
|
||||
+
|
||||
+ @Override
|
||||
+ default boolean isFromBucket() {
|
||||
+ return this.getHandle().fromBucket();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default void setFromBucket(boolean fromBucket) {
|
||||
+ this.getHandle().setFromBucket(fromBucket);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default ItemStack getBaseBucketItem() {
|
||||
+ return CraftItemStack.asBukkitCopy(this.getHandle().getBucketItemStack());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default Sound getPickupSound() {
|
||||
+ return CraftSound.minecraftToBukkit(this.getHandle().getPickupSound());
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAxolotl.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAxolotl.java
|
||||
index e730292edca4624400bdb89d555922c5f61db7a5..cbfca242f820d238b112f8ce64e9de8398c48a1c 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAxolotl.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAxolotl.java
|
||||
@@ -4,7 +4,7 @@ import com.google.common.base.Preconditions;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Axolotl;
|
||||
|
||||
-public class CraftAxolotl extends CraftAnimals implements Axolotl {
|
||||
+public class CraftAxolotl extends CraftAnimals implements Axolotl, io.papermc.paper.entity.PaperBucketable { // Paper - Bucketable API
|
||||
|
||||
public CraftAxolotl(CraftServer server, net.minecraft.world.entity.animal.axolotl.Axolotl entity) {
|
||||
super(server, entity);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFish.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFish.java
|
||||
index da5150f4ca0397bf10053aab0c3ff18af5bc3f3c..eb10f94d5ed8ca89d3786138647dd43357609a6c 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFish.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFish.java
|
||||
@@ -4,7 +4,7 @@ import net.minecraft.world.entity.animal.AbstractFish;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Fish;
|
||||
|
||||
-public class CraftFish extends CraftWaterMob implements Fish {
|
||||
+public class CraftFish extends CraftWaterMob implements Fish, io.papermc.paper.entity.PaperBucketable { // Paper - Bucketable API
|
||||
|
||||
public CraftFish(CraftServer server, AbstractFish entity) {
|
||||
super(server, entity);
|
|
@ -1,76 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Sat, 1 Jan 2022 05:19:37 -0800
|
||||
Subject: [PATCH] Validate usernames
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
index e0a10f1d8bf2c0df66e62bdf2a174ce6a66bbd6d..9c343b579d9735dc59c8c74fde030d981a673c4f 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -90,6 +90,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
private final String serverId;
|
||||
private final boolean transferred;
|
||||
private ServerPlayer player; // CraftBukkit
|
||||
+ public boolean iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation = false; // Paper - username validation overriding
|
||||
|
||||
public ServerLoginPacketListenerImpl(MinecraftServer server, Connection connection, boolean transferred) {
|
||||
this.state = ServerLoginPacketListenerImpl.State.HELLO;
|
||||
@@ -171,7 +172,13 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
@Override
|
||||
public void handleHello(ServerboundHelloPacket packet) {
|
||||
Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet", new Object[0]);
|
||||
- Validate.validState(StringUtil.isValidPlayerName(packet.name()), "Invalid characters in username", new Object[0]);
|
||||
+ // Paper start - Validate usernames
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode()
|
||||
+ && io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.performUsernameValidation
|
||||
+ && !this.iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation) {
|
||||
+ Validate.validState(StringUtil.isReasonablePlayerName(packet.name()), "Invalid characters in username", new Object[0]);
|
||||
+ }
|
||||
+ // Paper end - Validate usernames
|
||||
this.requestedUsername = packet.name();
|
||||
GameProfile gameprofile = this.server.getSingleplayerProfile();
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index c7dc335d6da208c224d94256eab11b2c3c63745f..cff45afb90b232a236683bd569d50aab6b701149 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -670,7 +670,7 @@ public abstract class PlayerList {
|
||||
|
||||
for (int i = 0; i < this.players.size(); ++i) {
|
||||
entityplayer = (ServerPlayer) this.players.get(i);
|
||||
- if (entityplayer.getUUID().equals(uuid)) {
|
||||
+ if (entityplayer.getUUID().equals(uuid) || (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode() && entityplayer.getGameProfile().getName().equalsIgnoreCase(gameprofile.getName()))) { // Paper - validate usernames
|
||||
list.add(entityplayer);
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/util/StringUtil.java b/src/main/java/net/minecraft/util/StringUtil.java
|
||||
index d3fc549a08993376c76c4ebebb788fea3f4ddf69..0bd191acb9596d3aa21c337230d26f09d26f6888 100644
|
||||
--- a/src/main/java/net/minecraft/util/StringUtil.java
|
||||
+++ b/src/main/java/net/minecraft/util/StringUtil.java
|
||||
@@ -67,6 +67,25 @@ public class StringUtil {
|
||||
return name.length() <= 16 && name.chars().filter(c -> c <= 32 || c >= 127).findAny().isEmpty();
|
||||
}
|
||||
|
||||
+ // Paper start - Username validation
|
||||
+ public static boolean isReasonablePlayerName(final String name) {
|
||||
+ if (name.isEmpty() || name.length() > 16) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ for (int i = 0, len = name.length(); i < len; ++i) {
|
||||
+ final char c = name.charAt(i);
|
||||
+ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || (c == '_' || c == '.')) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end - Username validation
|
||||
+
|
||||
public static String filterText(String string) {
|
||||
return filterText(string, false);
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brokkonaut <hannos17@gmx.de>
|
||||
Date: Sat, 18 Dec 2021 08:26:55 +0100
|
||||
Subject: [PATCH] Make water animal spawn height configurable
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/WaterAnimal.java b/src/main/java/net/minecraft/world/entity/animal/WaterAnimal.java
|
||||
index ad86b129ffdb9c6358f451fbcc0ae000eb81141d..c9cabb061ebc9172647304431cc3fb2593dd47ba 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/WaterAnimal.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/WaterAnimal.java
|
||||
@@ -67,6 +67,10 @@ public abstract class WaterAnimal extends PathfinderMob {
|
||||
) {
|
||||
int i = world.getSeaLevel();
|
||||
int j = i - 13;
|
||||
+ // Paper start - Make water animal spawn height configurable
|
||||
+ i = world.getMinecraftWorld().paperConfig().entities.spawning.wateranimalSpawnHeight.maximum.or(i);
|
||||
+ j = world.getMinecraftWorld().paperConfig().entities.spawning.wateranimalSpawnHeight.minimum.or(j);
|
||||
+ // Paper end - Make water animal spawn height configurable
|
||||
return pos.getY() >= j && pos.getY() <= i && world.getFluidState(pos.below()).is(FluidTags.WATER) && world.getBlockState(pos.above()).is(Blocks.WATER);
|
||||
}
|
||||
}
|
|
@ -1,177 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
Date: Thu, 6 Jan 2022 15:59:06 -0800
|
||||
Subject: [PATCH] Expose vanilla BiomeProvider from WorldInfo
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 56589fee8dd09783e01f2ae290ffacb5dff3f05f..718b653a118a1c64d07efab93192f10dfcbf414e 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -611,7 +611,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
List<CustomSpawner> list = ImmutableList.of(new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(iworlddataserver));
|
||||
LevelStem worlddimension = (LevelStem) dimensions.get(dimensionKey);
|
||||
|
||||
- org.bukkit.generator.WorldInfo worldInfo = new org.bukkit.craftbukkit.generator.CraftWorldInfo(iworlddataserver, worldSession, org.bukkit.World.Environment.getEnvironment(dimension), worlddimension.type().value());
|
||||
+ org.bukkit.generator.WorldInfo worldInfo = new org.bukkit.craftbukkit.generator.CraftWorldInfo(iworlddataserver, worldSession, org.bukkit.World.Environment.getEnvironment(dimension), worlddimension.type().value(), worlddimension.generator(), this.registryAccess()); // Paper - Expose vanilla BiomeProvider from WorldInfo
|
||||
if (biomeProvider == null && gen != null) {
|
||||
biomeProvider = gen.getDefaultBiomeProvider(worldInfo);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index a473993ea48afd05a884e3ffcbdd15abe74580d2..a87a0c9672b53db0e06292c339b3b1e163901942 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -369,7 +369,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
this.serverLevelData.setWorld(this);
|
||||
|
||||
if (biomeProvider != null) {
|
||||
- BiomeSource worldChunkManager = new CustomWorldChunkManager(this.getWorld(), biomeProvider, this.server.registryAccess().registryOrThrow(Registries.BIOME));
|
||||
+ BiomeSource worldChunkManager = new CustomWorldChunkManager(this.getWorld(), biomeProvider, this.server.registryAccess().registryOrThrow(Registries.BIOME), chunkgenerator.getBiomeSource()); // Paper - add vanillaBiomeProvider
|
||||
if (chunkgenerator instanceof NoiseBasedChunkGenerator cga) {
|
||||
chunkgenerator = new NoiseBasedChunkGenerator(worldChunkManager, cga.settings);
|
||||
} else if (chunkgenerator instanceof FlatLevelSource cpf) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index b638ccf0e46eeb375a59a42d6f29edd3f084fa17..bb232cd338f94b03f2add34766927ecae019e388 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -1308,7 +1308,7 @@ public final class CraftServer implements Server {
|
||||
List<CustomSpawner> list = ImmutableList.of(new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(worlddata));
|
||||
LevelStem worlddimension = iregistry.get(actualDimension);
|
||||
|
||||
- WorldInfo worldInfo = new CraftWorldInfo(worlddata, worldSession, creator.environment(), worlddimension.type().value());
|
||||
+ WorldInfo worldInfo = new CraftWorldInfo(worlddata, worldSession, creator.environment(), worlddimension.type().value(), worlddimension.generator(), this.getHandle().getServer().registryAccess()); // Paper - Expose vanilla BiomeProvider from WorldInfo
|
||||
if (biomeProvider == null && generator != null) {
|
||||
biomeProvider = generator.getDefaultBiomeProvider(worldInfo);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 838ffddba99964748dfe95d68ca93b578bc3292b..bb837f7fa46a7f5926a67ce3f725a328b9bff415 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -212,6 +212,39 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
public int getPlayerCount() {
|
||||
return world.players().size();
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public BiomeProvider vanillaBiomeProvider() {
|
||||
+ net.minecraft.server.level.ServerChunkCache serverCache = this.getHandle().chunkSource;
|
||||
+
|
||||
+ final net.minecraft.world.level.chunk.ChunkGenerator gen = serverCache.getGenerator();
|
||||
+ net.minecraft.world.level.biome.BiomeSource biomeSource;
|
||||
+ if (gen instanceof org.bukkit.craftbukkit.generator.CustomChunkGenerator custom) {
|
||||
+ biomeSource = custom.getDelegate().getBiomeSource();
|
||||
+ } else {
|
||||
+ biomeSource = gen.getBiomeSource();
|
||||
+ }
|
||||
+ if (biomeSource instanceof org.bukkit.craftbukkit.generator.CustomWorldChunkManager customBiomeSource) {
|
||||
+ biomeSource = customBiomeSource.vanillaBiomeSource;
|
||||
+ }
|
||||
+ final net.minecraft.world.level.biome.BiomeSource finalBiomeSource = biomeSource;
|
||||
+ final net.minecraft.world.level.biome.Climate.Sampler sampler = serverCache.randomState().sampler();
|
||||
+
|
||||
+ final List<Biome> possibleBiomes = finalBiomeSource.possibleBiomes().stream()
|
||||
+ .map(CraftBiome::minecraftHolderToBukkit)
|
||||
+ .toList();
|
||||
+ return new BiomeProvider() {
|
||||
+ @Override
|
||||
+ public Biome getBiome(final org.bukkit.generator.WorldInfo worldInfo, final int x, final int y, final int z) {
|
||||
+ return CraftBiome.minecraftHolderToBukkit(finalBiomeSource.getNoiseBiome(x >> 2, y >> 2, z >> 2, sampler));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public List<Biome> getBiomes(final org.bukkit.generator.WorldInfo worldInfo) {
|
||||
+ return possibleBiomes;
|
||||
+ }
|
||||
+ };
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
private static final Random rand = new Random();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CraftWorldInfo.java b/src/main/java/org/bukkit/craftbukkit/generator/CraftWorldInfo.java
|
||||
index 5d655d6cd3e23e0287069f8bdf77601487e862fd..c81455a4ee9a3185f125ebf8cec325f4ed2e501d 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/generator/CraftWorldInfo.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/generator/CraftWorldInfo.java
|
||||
@@ -17,8 +17,14 @@ public class CraftWorldInfo implements WorldInfo {
|
||||
private final long seed;
|
||||
private final int minHeight;
|
||||
private final int maxHeight;
|
||||
+ // Paper start
|
||||
+ private final net.minecraft.world.level.chunk.ChunkGenerator vanillaChunkGenerator;
|
||||
+ private final net.minecraft.core.RegistryAccess.Frozen registryAccess;
|
||||
|
||||
- public CraftWorldInfo(ServerLevelData worldDataServer, LevelStorageSource.LevelStorageAccess session, World.Environment environment, DimensionType dimensionManager) {
|
||||
+ public CraftWorldInfo(PrimaryLevelData worldDataServer, LevelStorageSource.LevelStorageAccess session, World.Environment environment, DimensionType dimensionManager, net.minecraft.world.level.chunk.ChunkGenerator chunkGenerator, net.minecraft.core.RegistryAccess.Frozen registryAccess) {
|
||||
+ this.registryAccess = registryAccess;
|
||||
+ this.vanillaChunkGenerator = chunkGenerator;
|
||||
+ // Paper end
|
||||
this.name = worldDataServer.getLevelName();
|
||||
this.uuid = WorldUUID.getUUID(session.levelDirectory.path().toFile());
|
||||
this.environment = environment;
|
||||
@@ -27,15 +33,6 @@ public class CraftWorldInfo implements WorldInfo {
|
||||
this.maxHeight = dimensionManager.minY() + dimensionManager.height();
|
||||
}
|
||||
|
||||
- public CraftWorldInfo(String name, UUID uuid, World.Environment environment, long seed, int minHeight, int maxHeight) {
|
||||
- this.name = name;
|
||||
- this.uuid = uuid;
|
||||
- this.environment = environment;
|
||||
- this.seed = seed;
|
||||
- this.minHeight = minHeight;
|
||||
- this.maxHeight = maxHeight;
|
||||
- }
|
||||
-
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.name;
|
||||
@@ -65,4 +62,34 @@ public class CraftWorldInfo implements WorldInfo {
|
||||
public int getMaxHeight() {
|
||||
return this.maxHeight;
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public org.bukkit.generator.BiomeProvider vanillaBiomeProvider() {
|
||||
+ final net.minecraft.world.level.levelgen.RandomState randomState;
|
||||
+ if (vanillaChunkGenerator instanceof net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator noiseBasedChunkGenerator) {
|
||||
+ randomState = net.minecraft.world.level.levelgen.RandomState.create(noiseBasedChunkGenerator.generatorSettings().value(),
|
||||
+ registryAccess.lookupOrThrow(net.minecraft.core.registries.Registries.NOISE), getSeed());
|
||||
+ } else {
|
||||
+ randomState = net.minecraft.world.level.levelgen.RandomState.create(net.minecraft.world.level.levelgen.NoiseGeneratorSettings.dummy(),
|
||||
+ registryAccess.lookupOrThrow(net.minecraft.core.registries.Registries.NOISE), getSeed());
|
||||
+ }
|
||||
+
|
||||
+ final java.util.List<org.bukkit.block.Biome> possibleBiomes = CraftWorldInfo.this.vanillaChunkGenerator.getBiomeSource().possibleBiomes().stream()
|
||||
+ .map(biome -> org.bukkit.craftbukkit.block.CraftBiome.minecraftHolderToBukkit(biome))
|
||||
+ .toList();
|
||||
+ return new org.bukkit.generator.BiomeProvider() {
|
||||
+ @Override
|
||||
+ public org.bukkit.block.Biome getBiome(final WorldInfo worldInfo, final int x, final int y, final int z) {
|
||||
+ return org.bukkit.craftbukkit.block.CraftBiome.minecraftHolderToBukkit(
|
||||
+ CraftWorldInfo.this.vanillaChunkGenerator.getBiomeSource().getNoiseBiome(x >> 2, y >> 2, z >> 2, randomState.sampler()));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public java.util.List<org.bukkit.block.Biome> getBiomes(final org.bukkit.generator.WorldInfo worldInfo) {
|
||||
+ return possibleBiomes;
|
||||
+ }
|
||||
+ };
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CustomWorldChunkManager.java b/src/main/java/org/bukkit/craftbukkit/generator/CustomWorldChunkManager.java
|
||||
index 0063c4c17d05a77adf81164fb9307a29860cbe12..0bac128d6faff0063b03f595b82deea78d1ae161 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/generator/CustomWorldChunkManager.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/generator/CustomWorldChunkManager.java
|
||||
@@ -31,7 +31,11 @@ public class CustomWorldChunkManager extends BiomeSource {
|
||||
return biomeBases;
|
||||
}
|
||||
|
||||
- public CustomWorldChunkManager(WorldInfo worldInfo, BiomeProvider biomeProvider, Registry<net.minecraft.world.level.biome.Biome> registry) {
|
||||
+ // Paper start - add vanillaBiomeProvider
|
||||
+ public final BiomeSource vanillaBiomeSource;
|
||||
+ public CustomWorldChunkManager(WorldInfo worldInfo, BiomeProvider biomeProvider, Registry<net.minecraft.world.level.biome.Biome> registry, BiomeSource vanillaBiomeSource) {
|
||||
+ this.vanillaBiomeSource = vanillaBiomeSource;
|
||||
+ // Paper end - add vanillaBiomeProvider
|
||||
this.worldInfo = worldInfo;
|
||||
this.biomeProvider = biomeProvider;
|
||||
this.registry = registry;
|
|
@ -1,28 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 2 Jan 2022 22:34:51 -0800
|
||||
Subject: [PATCH] Add config option for worlds affected by time cmd
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/commands/TimeCommand.java b/src/main/java/net/minecraft/server/commands/TimeCommand.java
|
||||
index db9317f813244c3cd895bdf9c4eb2218f68c4f1d..44fcd43a466fb47d31ab05e44bafbef3c4cae63f 100644
|
||||
--- a/src/main/java/net/minecraft/server/commands/TimeCommand.java
|
||||
+++ b/src/main/java/net/minecraft/server/commands/TimeCommand.java
|
||||
@@ -53,7 +53,7 @@ public class TimeCommand {
|
||||
}
|
||||
|
||||
public static int setTime(CommandSourceStack source, int time) {
|
||||
- Iterator iterator = com.google.common.collect.Iterators.singletonIterator(source.getLevel()); // CraftBukkit - SPIGOT-6496: Only set the time for the world the command originates in
|
||||
+ Iterator iterator = io.papermc.paper.configuration.GlobalConfiguration.get().commands.timeCommandAffectsAllWorlds ? source.getServer().getAllLevels().iterator() : com.google.common.collect.Iterators.singletonIterator(source.getLevel()); // CraftBukkit - SPIGOT-6496: Only set the time for the world the command originates in // Paper - add config option for spigot's change
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
ServerLevel worldserver = (ServerLevel) iterator.next();
|
||||
@@ -74,7 +74,7 @@ public class TimeCommand {
|
||||
}
|
||||
|
||||
public static int addTime(CommandSourceStack source, int time) {
|
||||
- Iterator iterator = com.google.common.collect.Iterators.singletonIterator(source.getLevel()); // CraftBukkit - SPIGOT-6496: Only set the time for the world the command originates in
|
||||
+ Iterator iterator = io.papermc.paper.configuration.GlobalConfiguration.get().commands.timeCommandAffectsAllWorlds ? source.getServer().getAllLevels().iterator() : com.google.common.collect.Iterators.singletonIterator(source.getLevel()); // CraftBukkit - SPIGOT-6496: Only set the time for the world the command originates in // Paper - add config option for spigot's change
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
ServerLevel worldserver = (ServerLevel) iterator.next();
|
|
@ -1,18 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: u9g <winworkswow@gmail.com>
|
||||
Date: Mon, 3 Jan 2022 23:32:42 -0500
|
||||
Subject: [PATCH] Add missing IAE check for PersistentDataContainer#has
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
|
||||
index 3001bb0e3d4af9b16645a0136093db594b89ab01..984e988a47aa55a3fd92198e379d0f92f511daef 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
|
||||
@@ -57,6 +57,7 @@ public class CraftPersistentDataContainer implements PersistentDataContainer {
|
||||
|
||||
@Override
|
||||
public boolean has(NamespacedKey key) {
|
||||
+ Preconditions.checkArgument(key != null, "The provided key for the custom value was null"); // Paper
|
||||
return this.customDataTags.get(key.toString()) != null;
|
||||
}
|
||||
|
|
@ -1,125 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cryptite <cryptite@gmail.com>
|
||||
Date: Tue, 21 Sep 2021 18:17:33 -0500
|
||||
Subject: [PATCH] Multiple Entries with Scoreboards
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java
|
||||
index 1d0c473442b5c72245c356054440323e3c5d4711..f8fe125f12a6a00899d1d6acfa448be882b81557 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java
|
||||
@@ -58,6 +58,11 @@ public class ClientboundSetPlayerTeamPacket implements Packet<ClientGamePacketLi
|
||||
);
|
||||
}
|
||||
|
||||
+ // Paper start - Multiple Entries with Scoreboards
|
||||
+ public static ClientboundSetPlayerTeamPacket createMultiplePlayerPacket(PlayerTeam team, Collection<String> players, ClientboundSetPlayerTeamPacket.Action operation) {
|
||||
+ return new ClientboundSetPlayerTeamPacket(team.getName(), operation == ClientboundSetPlayerTeamPacket.Action.ADD ? 3 : 4, Optional.empty(), players);
|
||||
+ }
|
||||
+ // Paper end - Multiple Entries with Scoreboards
|
||||
private ClientboundSetPlayerTeamPacket(RegistryFriendlyByteBuf buf) {
|
||||
this.name = buf.readUtf();
|
||||
this.method = buf.readByte();
|
||||
diff --git a/src/main/java/net/minecraft/server/ServerScoreboard.java b/src/main/java/net/minecraft/server/ServerScoreboard.java
|
||||
index 65a206c9969d5c7eee6bd185e398244365b5a809..f180001493146ef0d54079a8b2b47ad7decc24ca 100644
|
||||
--- a/src/main/java/net/minecraft/server/ServerScoreboard.java
|
||||
+++ b/src/main/java/net/minecraft/server/ServerScoreboard.java
|
||||
@@ -106,6 +106,25 @@ public class ServerScoreboard extends Scoreboard {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Multiple Entries with Scoreboards
|
||||
+ public boolean addPlayersToTeam(java.util.Collection<String> players, PlayerTeam team) {
|
||||
+ boolean anyAdded = false;
|
||||
+ for (String playerName : players) {
|
||||
+ if (super.addPlayerToTeam(playerName, team)) {
|
||||
+ anyAdded = true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (anyAdded) {
|
||||
+ this.broadcastAll(ClientboundSetPlayerTeamPacket.createMultiplePlayerPacket(team, players, ClientboundSetPlayerTeamPacket.Action.ADD));
|
||||
+ this.setDirty();
|
||||
+ return true;
|
||||
+ } else {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Multiple Entries with Scoreboards
|
||||
+
|
||||
@Override
|
||||
public void removePlayerFromTeam(String scoreHolderName, PlayerTeam team) {
|
||||
super.removePlayerFromTeam(scoreHolderName, team);
|
||||
@@ -113,6 +132,17 @@ public class ServerScoreboard extends Scoreboard {
|
||||
this.setDirty();
|
||||
}
|
||||
|
||||
+ // Paper start - Multiple Entries with Scoreboards
|
||||
+ public void removePlayersFromTeam(java.util.Collection<String> players, PlayerTeam team) {
|
||||
+ for (String playerName : players) {
|
||||
+ super.removePlayerFromTeam(playerName, team);
|
||||
+ }
|
||||
+
|
||||
+ this.broadcastAll(ClientboundSetPlayerTeamPacket.createMultiplePlayerPacket(team, players, ClientboundSetPlayerTeamPacket.Action.REMOVE));
|
||||
+ this.setDirty();
|
||||
+ }
|
||||
+ // Paper end - Multiple Entries with Scoreboards
|
||||
+
|
||||
@Override
|
||||
public void onObjectiveAdded(Objective objective) {
|
||||
super.onObjectiveAdded(objective);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java
|
||||
index 27219bf2f16aed64c78623d44c3cc84aa9f47065..2b335c750ce5f9ccc2651a8701497ca9b8f46704 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java
|
||||
@@ -229,6 +229,21 @@ final class CraftTeam extends CraftScoreboardComponent implements Team {
|
||||
scoreboard.board.addPlayerToTeam(entry, this.team);
|
||||
}
|
||||
|
||||
+ // Paper start - Multiple Entries with Scoreboards
|
||||
+ @Override
|
||||
+ public void addEntities(java.util.Collection<org.bukkit.entity.Entity> entities) throws IllegalStateException, IllegalArgumentException {
|
||||
+ this.addEntries(entities.stream().map(entity -> ((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle().getScoreboardName()).toList());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void addEntries(java.util.Collection<String> entries) throws IllegalStateException, IllegalArgumentException {
|
||||
+ Preconditions.checkArgument(entries != null, "Entries cannot be null");
|
||||
+ CraftScoreboard scoreboard = this.checkState();
|
||||
+
|
||||
+ ((net.minecraft.server.ServerScoreboard) scoreboard.board).addPlayersToTeam(entries, this.team);
|
||||
+ }
|
||||
+ // Paper end - Multiple Entries with Scoreboards
|
||||
+
|
||||
@Override
|
||||
public boolean removePlayer(OfflinePlayer player) {
|
||||
Preconditions.checkArgument(player != null, "OfflinePlayer cannot be null");
|
||||
@@ -248,6 +263,28 @@ final class CraftTeam extends CraftScoreboardComponent implements Team {
|
||||
return true;
|
||||
}
|
||||
|
||||
+ // Paper start - Multiple Entries with Scoreboards
|
||||
+ @Override
|
||||
+ public boolean removeEntities(java.util.Collection<org.bukkit.entity.Entity> entities) throws IllegalStateException, IllegalArgumentException {
|
||||
+ return this.removeEntries(entities.stream().map(entity -> ((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle().getScoreboardName()).toList());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean removeEntries(java.util.Collection<String> entries) throws IllegalStateException, IllegalArgumentException {
|
||||
+ Preconditions.checkArgument(entries != null, "Entry cannot be null");
|
||||
+ CraftScoreboard scoreboard = this.checkState();
|
||||
+
|
||||
+ for (String entry : entries) {
|
||||
+ if (this.team.getPlayers().contains(entry)) {
|
||||
+ ((net.minecraft.server.ServerScoreboard) scoreboard.board).removePlayersFromTeam(entries, this.team);
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Paper end - Multiple Entries with Scoreboards
|
||||
+
|
||||
@Override
|
||||
public boolean hasPlayer(OfflinePlayer player) throws IllegalArgumentException, IllegalStateException {
|
||||
Preconditions.checkArgument(player != null, "OfflinePlayer cannot be null");
|
|
@ -1,39 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nassim Jahnke <nassim@njahnke.dev>
|
||||
Date: Fri, 7 Jan 2022 11:45:15 +0100
|
||||
Subject: [PATCH] Reset placed block on exception
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java
|
||||
index cee3f1200af602b5dfd0b27d05eb01826c5bbb1d..7d76cdc59984b156628273c8357485eb10046007 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/BlockItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/BlockItem.java
|
||||
@@ -77,6 +77,7 @@ public class BlockItem extends Item {
|
||||
if (this instanceof PlaceOnWaterBlockItem || this instanceof SolidBucketItem) {
|
||||
blockstate = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(blockactioncontext1.getLevel(), blockactioncontext1.getClickedPos());
|
||||
}
|
||||
+ final org.bukkit.block.BlockState oldBlockstate = blockstate != null ? blockstate : org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(blockactioncontext1.getLevel(), blockactioncontext1.getClickedPos()); // Paper - Reset placed block on exception
|
||||
// CraftBukkit end
|
||||
|
||||
if (iblockdata == null) {
|
||||
@@ -92,8 +93,20 @@ public class BlockItem extends Item {
|
||||
|
||||
if (iblockdata1.is(iblockdata.getBlock())) {
|
||||
iblockdata1 = this.updateBlockStateFromTag(blockposition, world, itemstack, iblockdata1);
|
||||
+ // Paper start - Reset placed block on exception
|
||||
+ try {
|
||||
this.updateCustomBlockEntityTag(blockposition, world, entityhuman, itemstack, iblockdata1);
|
||||
BlockItem.updateBlockEntityComponents(world, blockposition, itemstack);
|
||||
+ } catch (Exception e) {
|
||||
+ oldBlockstate.update(true, false);
|
||||
+ if (entityhuman instanceof ServerPlayer player) {
|
||||
+ org.apache.logging.log4j.LogManager.getLogger().error("Player {} tried placing invalid block", player.getScoreboardName(), e);
|
||||
+ player.getBukkitEntity().kickPlayer("Packet processing error");
|
||||
+ return InteractionResult.FAIL;
|
||||
+ }
|
||||
+ throw e; // Rethrow exception if not placed by a player
|
||||
+ }
|
||||
+ // Paper end - Reset placed block on exception
|
||||
iblockdata1.getBlock().setPlacedBy(world, blockposition, iblockdata1, entityhuman, itemstack);
|
||||
// CraftBukkit start
|
||||
if (blockstate != null) {
|
|
@ -1,35 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Doc <nachito94@msn.com>
|
||||
Date: Mon, 2 Aug 2021 11:24:39 -0400
|
||||
Subject: [PATCH] Add configurable height for slime spawn
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
index b54c30ba73b6ab069c0c7c1cd2b193090da79667..adebb66e550f805f444bec22e9a4dd575a642b43 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
@@ -348,7 +348,11 @@ public class Slime extends Mob implements Enemy {
|
||||
return checkMobSpawnRules(type, world, spawnReason, pos, random);
|
||||
}
|
||||
|
||||
- if (world.getBiome(pos).is(BiomeTags.ALLOWS_SURFACE_SLIME_SPAWNS) && pos.getY() > 50 && pos.getY() < 70 && random.nextFloat() < 0.5F && random.nextFloat() < world.getMoonBrightness() && world.getMaxLocalRawBrightness(pos) <= random.nextInt(8)) {
|
||||
+ // Paper start - Replace rules for Height in Swamp Biome
|
||||
+ final double maxHeightSwamp = world.getMinecraftWorld().paperConfig().entities.spawning.slimeSpawnHeight.surfaceBiome.maximum;
|
||||
+ final double minHeightSwamp = world.getMinecraftWorld().paperConfig().entities.spawning.slimeSpawnHeight.surfaceBiome.minimum;
|
||||
+ if (world.getBiome(pos).is(BiomeTags.ALLOWS_SURFACE_SLIME_SPAWNS) && pos.getY() > minHeightSwamp && pos.getY() < maxHeightSwamp && random.nextFloat() < 0.5F && random.nextFloat() < world.getMoonBrightness() && world.getMaxLocalRawBrightness(pos) <= random.nextInt(8)) {
|
||||
+ // Paper end - Replace rules for Height in Swamp Biome
|
||||
return checkMobSpawnRules(type, world, spawnReason, pos, random);
|
||||
}
|
||||
|
||||
@@ -359,7 +363,10 @@ public class Slime extends Mob implements Enemy {
|
||||
ChunkPos chunkcoordintpair = new ChunkPos(pos);
|
||||
boolean flag = world.getMinecraftWorld().paperConfig().entities.spawning.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(chunkcoordintpair.x, chunkcoordintpair.z, ((WorldGenLevel) world).getSeed(), world.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper
|
||||
|
||||
- if (random.nextInt(10) == 0 && flag && pos.getY() < 40) {
|
||||
+ // Paper start - Replace rules for Height in Slime Chunks
|
||||
+ final double maxHeightSlimeChunk = world.getMinecraftWorld().paperConfig().entities.spawning.slimeSpawnHeight.slimeChunk.maximum;
|
||||
+ if (random.nextInt(10) == 0 && flag && pos.getY() < maxHeightSlimeChunk) {
|
||||
+ // Paper end - Replace rules for Height in Slime Chunks
|
||||
return checkMobSpawnRules(type, world, spawnReason, pos, random);
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 16 Jan 2022 10:34:02 -0800
|
||||
Subject: [PATCH] Fix xp reward for baby zombies
|
||||
|
||||
The field that tracks the xpReward was not
|
||||
getting reset if the death was cancelled
|
||||
so this resets it after each call to
|
||||
Zombie#getExperienceReward
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
|
||||
index fd304e7d8305877d56de7a38b8664e5a70bf0c33..2280004638fd19ed018cb3e77d53a018b34ec516 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
|
||||
@@ -176,11 +176,16 @@ public class Zombie extends Monster {
|
||||
|
||||
@Override
|
||||
protected int getBaseExperienceReward() {
|
||||
+ final int previousReward = this.xpReward; // Paper - store previous value to reset after calculating XP reward
|
||||
if (this.isBaby()) {
|
||||
this.xpReward = (int) ((double) this.xpReward * 2.5D);
|
||||
}
|
||||
|
||||
- return super.getBaseExperienceReward();
|
||||
+ // Paper start - store previous value to reset after calculating XP reward
|
||||
+ int reward = super.getBaseExperienceReward();
|
||||
+ this.xpReward = previousReward;
|
||||
+ return reward;
|
||||
+ // Paper end - store previous value to reset after calculating XP reward
|
||||
}
|
||||
|
||||
@Override
|
|
@ -1,62 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brody Beckwith <brody@beckwith.dev>
|
||||
Date: Fri, 14 Jan 2022 00:41:11 -0500
|
||||
Subject: [PATCH] Multi Block Change API Implementation
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java
|
||||
index 926ff9be3d9e3f5d620e4c7ccb22b9f64865ff8c..1a37654aff9a9c86c9f7af10a1cf721371f0c5ec 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java
|
||||
@@ -62,6 +62,14 @@ public class ClientboundSectionBlocksUpdatePacket implements Packet<ClientGamePa
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start - Multi Block Change API
|
||||
+ public ClientboundSectionBlocksUpdatePacket(SectionPos sectionPos, it.unimi.dsi.fastutil.shorts.Short2ObjectMap<BlockState> blockChanges) {
|
||||
+ this.sectionPos = sectionPos;
|
||||
+ this.positions = blockChanges.keySet().toShortArray();
|
||||
+ this.states = blockChanges.values().toArray(new BlockState[0]);
|
||||
+ }
|
||||
+ // Paper end - Multi Block Change API
|
||||
+
|
||||
private void write(FriendlyByteBuf buf) {
|
||||
buf.writeLong(this.sectionPos.asLong());
|
||||
buf.writeVarInt(this.positions.length);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index bc0d63f90e352ad4158d1dcc0f21a34954279095..ef289dba67db65a5e43104a4ca68bc03c8c5e4cb 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -930,6 +930,32 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
this.getHandle().connection.send(packet);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void sendMultiBlockChange(final Map<? extends io.papermc.paper.math.Position, BlockData> blockChanges) {
|
||||
+ if (this.getHandle().connection == null) return;
|
||||
+
|
||||
+ Map<SectionPos, it.unimi.dsi.fastutil.shorts.Short2ObjectMap<net.minecraft.world.level.block.state.BlockState>> sectionMap = new HashMap<>();
|
||||
+
|
||||
+ for (Map.Entry<? extends io.papermc.paper.math.Position, BlockData> entry : blockChanges.entrySet()) {
|
||||
+ BlockData blockData = entry.getValue();
|
||||
+ BlockPos blockPos = io.papermc.paper.util.MCUtil.toBlockPos(entry.getKey());
|
||||
+ SectionPos sectionPos = SectionPos.of(blockPos);
|
||||
+
|
||||
+ it.unimi.dsi.fastutil.shorts.Short2ObjectMap<net.minecraft.world.level.block.state.BlockState> sectionData = sectionMap.computeIfAbsent(sectionPos, key -> new it.unimi.dsi.fastutil.shorts.Short2ObjectArrayMap<>());
|
||||
+ sectionData.put(SectionPos.sectionRelativePos(blockPos), ((CraftBlockData) blockData).getState());
|
||||
+ }
|
||||
+
|
||||
+ for (Map.Entry<SectionPos, it.unimi.dsi.fastutil.shorts.Short2ObjectMap<net.minecraft.world.level.block.state.BlockState>> entry : sectionMap.entrySet()) {
|
||||
+ SectionPos sectionPos = entry.getKey();
|
||||
+ it.unimi.dsi.fastutil.shorts.Short2ObjectMap<net.minecraft.world.level.block.state.BlockState> blockData = entry.getValue();
|
||||
+
|
||||
+ net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket packet = new net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket(sectionPos, blockData);
|
||||
+ this.getHandle().connection.send(packet);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void sendBlockChanges(Collection<BlockState> blocks) {
|
||||
Preconditions.checkArgument(blocks != null, "blocks must not be null");
|
|
@ -1,54 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kieran Wallbanks <kieran.wallbanks@gmail.com>
|
||||
Date: Mon, 21 Jun 2021 14:23:50 +0100
|
||||
Subject: [PATCH] Fix NotePlayEvent
|
||||
|
||||
== AT ==
|
||||
public org.bukkit.craftbukkit.block.data.CraftBlockData toNMS(Ljava/lang/Enum;Ljava/lang/Class;)Ljava/lang/Enum;
|
||||
|
||||
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 6215f096849f48843d6e25875b8b71f6827ec0a5..f77d51d10e01fc4eaf5516c05c8be0ef7a425893 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/NoteBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/NoteBlock.java
|
||||
@@ -94,11 +94,12 @@ public class NoteBlock extends Block {
|
||||
private void playNote(@Nullable Entity entity, BlockState state, Level world, BlockPos pos) {
|
||||
if (((NoteBlockInstrument) state.getValue(NoteBlock.INSTRUMENT)).worksAboveNoteBlock() || world.getBlockState(pos.above()).isAir()) {
|
||||
// CraftBukkit start
|
||||
- org.bukkit.event.block.NotePlayEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callNotePlayEvent(world, pos, state.getValue(NoteBlock.INSTRUMENT), state.getValue(NoteBlock.NOTE));
|
||||
- if (event.isCancelled()) {
|
||||
- return;
|
||||
- }
|
||||
+ // org.bukkit.event.block.NotePlayEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callNotePlayEvent(world, pos, state.getValue(NoteBlock.INSTRUMENT), state.getValue(NoteBlock.NOTE));
|
||||
+ // if (event.isCancelled()) {
|
||||
+ // return;
|
||||
+ // }
|
||||
// CraftBukkit end
|
||||
+ // Paper - move NotePlayEvent call to fix instrument/note changes; TODO any way to cancel the game event?
|
||||
world.blockEvent(pos, this, 0, 0);
|
||||
world.gameEvent(entity, (Holder) GameEvent.NOTE_BLOCK_PLAY, pos);
|
||||
}
|
||||
@@ -138,10 +139,14 @@ public class NoteBlock extends Block {
|
||||
@Override
|
||||
protected boolean triggerEvent(BlockState state, Level world, BlockPos pos, int type, int data) {
|
||||
NoteBlockInstrument blockpropertyinstrument = (NoteBlockInstrument) state.getValue(NoteBlock.INSTRUMENT);
|
||||
+ // Paper start - move NotePlayEvent call to fix instrument/note changes
|
||||
+ org.bukkit.event.block.NotePlayEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callNotePlayEvent(world, pos, blockpropertyinstrument, state.getValue(NOTE));
|
||||
+ if (event.isCancelled()) return false;
|
||||
+ // Paper end - move NotePlayEvent call to fix instrument/note changes
|
||||
float f;
|
||||
|
||||
if (blockpropertyinstrument.isTunable()) {
|
||||
- int k = (Integer) state.getValue(NoteBlock.NOTE);
|
||||
+ int k = event.getNote().getId(); // Paper - move NotePlayEvent call to fix instrument/note changes
|
||||
|
||||
f = NoteBlock.getPitchFromNote(k);
|
||||
world.addParticle(ParticleTypes.NOTE, (double) pos.getX() + 0.5D, (double) pos.getY() + 1.2D, (double) pos.getZ() + 0.5D, (double) k / 24.0D, 0.0D, 0.0D);
|
||||
@@ -160,7 +165,7 @@ public class NoteBlock extends Block {
|
||||
|
||||
holder = Holder.direct(SoundEvent.createVariableRangeEvent(minecraftkey));
|
||||
} else {
|
||||
- holder = blockpropertyinstrument.getSoundEvent();
|
||||
+ holder = org.bukkit.craftbukkit.block.data.CraftBlockData.toNMS(event.getInstrument(), NoteBlockInstrument.class).getSoundEvent(); // Paper - move NotePlayEvent call to fix instrument/note changes
|
||||
}
|
||||
|
||||
world.playSeededSound((Player) null, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, holder, SoundSource.RECORDS, 3.0F, f, world.random.nextLong());
|
|
@ -1,82 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Sun, 26 Dec 2021 20:27:43 -0500
|
||||
Subject: [PATCH] Freeze Tick Lock API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 9f40cc481ded9279319d92fe5a0a9278a3f5d9c2..7d9ebc71b794d40246cbd43ff4de5795970e7ebe 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -411,6 +411,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
private org.bukkit.util.Vector origin;
|
||||
@javax.annotation.Nullable
|
||||
private UUID originWorld;
|
||||
+ public boolean freezeLocked = false; // Paper - Freeze Tick Lock API
|
||||
|
||||
public void setOrigin(@javax.annotation.Nonnull Location location) {
|
||||
this.origin = location.toVector();
|
||||
@@ -751,7 +752,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
this.setRemainingFireTicks(this.remainingFireTicks - 1);
|
||||
}
|
||||
|
||||
- if (this.getTicksFrozen() > 0) {
|
||||
+ if (this.getTicksFrozen() > 0 && !freezeLocked) { // Paper - Freeze Tick Lock API
|
||||
this.setTicksFrozen(0);
|
||||
this.level().levelEvent((Player) null, 1009, this.blockPosition, 1);
|
||||
}
|
||||
@@ -2312,6 +2313,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
if (fromNetherPortal) {
|
||||
nbttagcompound.putBoolean("Paper.FromNetherPortal", true);
|
||||
}
|
||||
+ if (freezeLocked) {
|
||||
+ nbttagcompound.putBoolean("Paper.FreezeLock", true);
|
||||
+ }
|
||||
// Paper end
|
||||
return nbttagcompound;
|
||||
} catch (Throwable throwable) {
|
||||
@@ -2456,6 +2460,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
if (spawnReason == null) {
|
||||
spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT;
|
||||
}
|
||||
+ if (nbt.contains("Paper.FreezeLock")) {
|
||||
+ freezeLocked = nbt.getBoolean("Paper.FreezeLock");
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
} catch (Throwable throwable) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index ee7bb1a01bf027eb7b28e3795950a17e5f686815..01a6e91f1b8f619e99d9bccde12f6e91e6ab5eb8 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3497,7 +3497,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
|
||||
this.level().getProfiler().pop();
|
||||
this.level().getProfiler().push("freezing");
|
||||
- if (!this.level().isClientSide && !this.isDeadOrDying()) {
|
||||
+ if (!this.level().isClientSide && !this.isDeadOrDying() && !this.freezeLocked) { // Paper - Freeze Tick Lock API
|
||||
int i = this.getTicksFrozen();
|
||||
|
||||
if (this.isInPowderSnow && this.canFreeze()) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
index 4ed5647101bbace0005b1ebfb824e4aed48e43cb..4c09f2529dd8eb7ac7d260d177f5292ff2339442 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -323,6 +323,17 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
return this.getHandle().isFullyFrozen();
|
||||
}
|
||||
|
||||
+ // Paper start - Freeze Tick Lock API
|
||||
+ @Override
|
||||
+ public boolean isFreezeTickingLocked() {
|
||||
+ return this.entity.freezeLocked;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void lockFreezeTicks(boolean locked) {
|
||||
+ this.entity.freezeLocked = locked;
|
||||
+ }
|
||||
+ // Paper end - Freeze Tick Lock API
|
||||
@Override
|
||||
public void remove() {
|
||||
this.entity.pluginRemoved = true;
|
|
@ -1,98 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 27 May 2021 21:58:24 -0700
|
||||
Subject: [PATCH] More PotionEffectType API
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.effect.MobEffect attributeModifiers
|
||||
public net.minecraft.world.effect.MobEffect$AttributeTemplate
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionEffectType.java b/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionEffectType.java
|
||||
index 21d4224c8993f521d6004d708ecbf71fa6d09306..6cf790c9fa23ea313423fdaeb7c181bf530828c6 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionEffectType.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionEffectType.java
|
||||
@@ -129,6 +129,48 @@ public class CraftPotionEffectType extends PotionEffectType implements Handleabl
|
||||
return this.handle.getDescriptionId();
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public java.util.Map<org.bukkit.attribute.Attribute, org.bukkit.attribute.AttributeModifier> getEffectAttributes() {
|
||||
+ // re-create map each time because a nms MobEffect can have its attributes modified
|
||||
+ final java.util.Map<org.bukkit.attribute.Attribute, org.bukkit.attribute.AttributeModifier> attributeMap = new java.util.HashMap<>();
|
||||
+ this.handle.attributeModifiers.forEach((attribute, attributeModifier) -> {
|
||||
+ attributeMap.put(
|
||||
+ org.bukkit.craftbukkit.attribute.CraftAttribute.minecraftHolderToBukkit(attribute),
|
||||
+ // use zero as amplifier to get the base amount, as it is amount = base * (amplifier + 1)
|
||||
+ org.bukkit.craftbukkit.attribute.CraftAttributeInstance.convert(attributeModifier.create(0))
|
||||
+ );
|
||||
+ });
|
||||
+ return java.util.Map.copyOf(attributeMap);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public double getAttributeModifierAmount(org.bukkit.attribute.Attribute attribute, int effectAmplifier) {
|
||||
+ com.google.common.base.Preconditions.checkArgument(effectAmplifier >= 0, "effectAmplifier must be greater than or equal to 0");
|
||||
+ Holder<net.minecraft.world.entity.ai.attributes.Attribute> nmsAttribute = org.bukkit.craftbukkit.attribute.CraftAttribute.bukkitToMinecraftHolder(attribute);
|
||||
+ com.google.common.base.Preconditions.checkArgument(this.handle.attributeModifiers.containsKey(nmsAttribute), attribute + " is not present on " + this.getKey());
|
||||
+ return this.handle.attributeModifiers.get(nmsAttribute).create(effectAmplifier).amount();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public PotionEffectType.Category getEffectCategory() {
|
||||
+ return fromNMS(handle.getCategory());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String translationKey() {
|
||||
+ return this.handle.getDescriptionId();
|
||||
+ }
|
||||
+
|
||||
+ public static PotionEffectType.Category fromNMS(net.minecraft.world.effect.MobEffectCategory mobEffectInfo) {
|
||||
+ return switch (mobEffectInfo) {
|
||||
+ case BENEFICIAL -> PotionEffectType.Category.BENEFICIAL;
|
||||
+ case HARMFUL -> PotionEffectType.Category.HARMFUL;
|
||||
+ case NEUTRAL -> PotionEffectType.Category.NEUTRAL;
|
||||
+ };
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
diff --git a/src/test/java/io/papermc/paper/effects/EffectCategoryTest.java b/src/test/java/io/papermc/paper/effects/EffectCategoryTest.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..a57e8fdc35efc7e0353d4f36c91578390ee4572e
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/io/papermc/paper/effects/EffectCategoryTest.java
|
||||
@@ -0,0 +1,30 @@
|
||||
+package io.papermc.paper.effects;
|
||||
+
|
||||
+import io.papermc.paper.adventure.PaperAdventure;
|
||||
+import net.minecraft.world.effect.MobEffectCategory;
|
||||
+import org.bukkit.craftbukkit.potion.CraftPotionEffectType;
|
||||
+import org.bukkit.potion.PotionEffectType;
|
||||
+import org.bukkit.support.environment.AllFeatures;
|
||||
+import org.junit.jupiter.api.Test;
|
||||
+
|
||||
+import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
+import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
+
|
||||
+@AllFeatures
|
||||
+public class EffectCategoryTest {
|
||||
+
|
||||
+ @Test
|
||||
+ public void testEffectCategoriesExist() {
|
||||
+ for (MobEffectCategory mobEffectInfo : MobEffectCategory.values()) {
|
||||
+ assertNotNull(CraftPotionEffectType.fromNMS(mobEffectInfo), mobEffectInfo + " is missing a bukkit equivalent");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testCategoryHasEquivalentColors() {
|
||||
+ for (MobEffectCategory mobEffectInfo : MobEffectCategory.values()) {
|
||||
+ PotionEffectType.Category bukkitEffectCategory = CraftPotionEffectType.fromNMS(mobEffectInfo);
|
||||
+ assertEquals(bukkitEffectCategory.getColor(), PaperAdventure.asAdventure(mobEffectInfo.getTooltipFormatting()), mobEffectInfo.getTooltipFormatting().name() + " doesn't equal " + bukkitEffectCategory.getColor());
|
||||
+ }
|
||||
+ }
|
||||
+}
|
|
@ -1,20 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Mon, 12 Jul 2021 12:28:29 +0100
|
||||
Subject: [PATCH] Use a CHM for StructureTemplate.Pallete cache
|
||||
|
||||
fixes a CME due to this collection being shared across threads
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
|
||||
index 02b493435509f7a84a2c26050ca0c732ecf00ca0..33564e62e3181d28b18a957e28b8ec5152d8339f 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
|
||||
@@ -859,7 +859,7 @@ public class StructureTemplate {
|
||||
public static final class Palette {
|
||||
|
||||
private final List<StructureTemplate.StructureBlockInfo> blocks;
|
||||
- private final Map<Block, List<StructureTemplate.StructureBlockInfo>> cache = Maps.newHashMap();
|
||||
+ private final Map<Block, List<StructureTemplate.StructureBlockInfo>> cache = Maps.newConcurrentMap(); // Paper - Fix CME due to this collection being shared across threads
|
||||
|
||||
Palette(List<StructureTemplate.StructureBlockInfo> infos) {
|
||||
this.blocks = infos;
|
|
@ -1,170 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
Date: Tue, 1 Feb 2022 15:51:55 -0700
|
||||
Subject: [PATCH] API for creating command sender which forwards feedback
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/commands/FeedbackForwardingSender.java b/src/main/java/io/papermc/paper/commands/FeedbackForwardingSender.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e3a5f1ec376319bdfda87fa27ae217bff3914292
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/commands/FeedbackForwardingSender.java
|
||||
@@ -0,0 +1,111 @@
|
||||
+package io.papermc.paper.commands;
|
||||
+
|
||||
+import io.papermc.paper.adventure.PaperAdventure;
|
||||
+import java.util.UUID;
|
||||
+import java.util.function.Consumer;
|
||||
+import net.kyori.adventure.audience.MessageType;
|
||||
+import net.kyori.adventure.identity.Identity;
|
||||
+import net.kyori.adventure.text.Component;
|
||||
+import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
+import net.minecraft.commands.CommandSource;
|
||||
+import net.minecraft.commands.CommandSourceStack;
|
||||
+import net.minecraft.server.level.ServerLevel;
|
||||
+import net.minecraft.world.phys.Vec2;
|
||||
+import net.minecraft.world.phys.Vec3;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+import org.bukkit.craftbukkit.CraftServer;
|
||||
+import org.bukkit.craftbukkit.command.ServerCommandSender;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public final class FeedbackForwardingSender extends ServerCommandSender {
|
||||
+ private final Consumer<? super Component> feedback;
|
||||
+ private final CraftServer server;
|
||||
+
|
||||
+ public FeedbackForwardingSender(final Consumer<? super Component> feedback, final CraftServer server) {
|
||||
+ super(((ServerCommandSender) server.getConsoleSender()).perm);
|
||||
+ this.server = server;
|
||||
+ this.feedback = feedback;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void sendMessage(final String message) {
|
||||
+ this.sendMessage(LegacyComponentSerializer.legacySection().deserialize(message));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void sendMessage(final String... messages) {
|
||||
+ for (final String message : messages) {
|
||||
+ this.sendMessage(message);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void sendMessage(final Identity identity, final Component message, final MessageType type) {
|
||||
+ this.feedback.accept(message);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String getName() {
|
||||
+ return "FeedbackForwardingSender";
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Component name() {
|
||||
+ return Component.text(this.getName());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isOp() {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setOp(final boolean value) {
|
||||
+ throw new UnsupportedOperationException("Cannot change operator status of " + this.getClass().getName());
|
||||
+ }
|
||||
+
|
||||
+ public CommandSourceStack asVanilla() {
|
||||
+ final @Nullable ServerLevel overworld = this.server.getServer().overworld();
|
||||
+ return new CommandSourceStack(
|
||||
+ new Source(this),
|
||||
+ overworld == null ? Vec3.ZERO : Vec3.atLowerCornerOf(overworld.getSharedSpawnPos()),
|
||||
+ Vec2.ZERO,
|
||||
+ overworld,
|
||||
+ 4,
|
||||
+ this.getName(),
|
||||
+ net.minecraft.network.chat.Component.literal(this.getName()),
|
||||
+ this.server.getServer(),
|
||||
+ null
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
+ private record Source(FeedbackForwardingSender sender) implements CommandSource {
|
||||
+ @Override
|
||||
+ public void sendSystemMessage(final net.minecraft.network.chat.Component message) {
|
||||
+ this.sender.sendMessage(Identity.nil(), PaperAdventure.asAdventure(message));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean acceptsSuccess() {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean acceptsFailure() {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean shouldInformAdmins() {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public CommandSender getBukkitSender(final CommandSourceStack stack) {
|
||||
+ return this.sender;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index bb232cd338f94b03f2add34766927ecae019e388..c0eca359919c55ba7b33520277c124eb54d935d7 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -2162,6 +2162,13 @@ public final class CraftServer implements Server {
|
||||
return this.console.console;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public CommandSender createCommandSender(final java.util.function.Consumer<? super net.kyori.adventure.text.Component> feedback) {
|
||||
+ return new io.papermc.paper.commands.FeedbackForwardingSender(feedback, this);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public EntityMetadataStore getEntityMetadata() {
|
||||
return this.entityMetadata;
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java b/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java
|
||||
index 7f22950ae61436e91a59cd29a345809c42bbe739..1e3091687735b461d3b6a313ab8761127981d3e8 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java
|
||||
@@ -12,7 +12,7 @@ import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public abstract class ServerCommandSender implements CommandSender {
|
||||
- private final PermissibleBase perm;
|
||||
+ public final PermissibleBase perm; // Paper
|
||||
private net.kyori.adventure.pointer.Pointers adventure$pointers; // Paper - implement pointers
|
||||
|
||||
protected ServerCommandSender() {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
|
||||
index 98d314cd293d462ef109e952f3239e08e14dda59..2ee33c55890fa659f6d251e486264c85d9e89802 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
|
||||
@@ -81,6 +81,11 @@ public final class VanillaCommandWrapper extends BukkitCommand {
|
||||
if (sender instanceof ProxiedCommandSender) {
|
||||
return ((ProxiedNativeCommandSender) sender).getHandle();
|
||||
}
|
||||
+ // Paper start
|
||||
+ if (sender instanceof io.papermc.paper.commands.FeedbackForwardingSender feedback) {
|
||||
+ return feedback.asVanilla();
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
throw new IllegalArgumentException("Cannot make " + sender + " a vanilla command listener");
|
||||
}
|
|
@ -1,399 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 13 Jan 2022 23:05:53 -0800
|
||||
Subject: [PATCH] Add missing structure set seed configs
|
||||
|
||||
The 4 missing structure set seed configs are strongholds, mineshafts,
|
||||
buried treasure, and ancient cities.
|
||||
|
||||
Strongholds use a ring placement scheme which isn't random so they
|
||||
utilize the world seed by default, this adds a config to override it
|
||||
for just generating the ring positions.
|
||||
|
||||
Mineshafts and Buried Treasure structure sets are special cases
|
||||
where the "salt" that can be defined for them via datapacks has 0
|
||||
effect because the difference between the spacing and separation is 1
|
||||
which is used as the upper bound in the random with salt. So the random
|
||||
always returns the same int (0) so the salt has no effect. This adds
|
||||
seeds/salts to the frequency reducer which has a similar effect.
|
||||
|
||||
Co-authored-by: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||
index c5dd3aac54aa5936da4bd9f54f0e76ecf8141d27..102de569415ef011dacdca9a6ea8134d0ef62454 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||
@@ -573,7 +573,7 @@ public abstract class ChunkGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
- if (structureplacement.isStructureChunk(placementCalculator, chunkcoordintpair.x, chunkcoordintpair.z)) {
|
||||
+ if (structureplacement.isStructureChunk(placementCalculator, chunkcoordintpair.x, chunkcoordintpair.z, structureplacement instanceof net.minecraft.world.level.chunk.ChunkGeneratorStructureState.KeyedRandomSpreadStructurePlacement keyed ? keyed.key : null)) { // Paper - Add missing structure set seed configs
|
||||
if (list.size() == 1) {
|
||||
this.tryGenerateStructure((StructureSet.StructureSelectionEntry) list.get(0), structureAccessor, registryManager, randomstate, structureTemplateManager, placementCalculator.getLevelSeed(), chunk, chunkcoordintpair, sectionposition);
|
||||
} else {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java
|
||||
index e6c59f986ae89022bd76463209dfa550a3d4fb59..a6b6e5ea191c0e2cd7a2e4f01b89d8af40a83c1b 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java
|
||||
@@ -50,13 +50,14 @@ public class ChunkGeneratorStructureState {
|
||||
private final Map<ConcentricRingsStructurePlacement, CompletableFuture<List<ChunkPos>>> ringPositions = new Object2ObjectArrayMap();
|
||||
private boolean hasGeneratedPositions;
|
||||
private final List<Holder<StructureSet>> possibleStructureSets;
|
||||
+ public final SpigotWorldConfig conf; // Paper - Add missing structure set seed configs
|
||||
|
||||
public static ChunkGeneratorStructureState createForFlat(RandomState randomstate, long i, BiomeSource worldchunkmanager, Stream<Holder<StructureSet>> stream, SpigotWorldConfig conf) { // Spigot
|
||||
List<Holder<StructureSet>> list = stream.filter((holder) -> {
|
||||
return ChunkGeneratorStructureState.hasBiomesForStructureSet((StructureSet) holder.value(), worldchunkmanager);
|
||||
}).toList();
|
||||
|
||||
- return new ChunkGeneratorStructureState(randomstate, worldchunkmanager, i, 0L, ChunkGeneratorStructureState.injectSpigot(list, conf)); // Spigot
|
||||
+ return new ChunkGeneratorStructureState(randomstate, worldchunkmanager, i, 0L, ChunkGeneratorStructureState.injectSpigot(list, conf), conf); // Spigot
|
||||
}
|
||||
|
||||
public static ChunkGeneratorStructureState createForNormal(RandomState randomstate, long i, BiomeSource worldchunkmanager, HolderLookup<StructureSet> holderlookup, SpigotWorldConfig conf) { // Spigot
|
||||
@@ -64,14 +65,24 @@ public class ChunkGeneratorStructureState {
|
||||
return ChunkGeneratorStructureState.hasBiomesForStructureSet((StructureSet) holder_c.value(), worldchunkmanager);
|
||||
}).collect(Collectors.toUnmodifiableList());
|
||||
|
||||
- return new ChunkGeneratorStructureState(randomstate, worldchunkmanager, i, i, ChunkGeneratorStructureState.injectSpigot(list, conf)); // Spigot
|
||||
+ return new ChunkGeneratorStructureState(randomstate, worldchunkmanager, i, i, ChunkGeneratorStructureState.injectSpigot(list, conf), conf); // Spigot
|
||||
}
|
||||
+ // Paper start - Add missing structure set seed configs; horrible hack because spigot creates a ton of direct Holders which lose track of the identifying key
|
||||
+ public static final class KeyedRandomSpreadStructurePlacement extends RandomSpreadStructurePlacement {
|
||||
+ public final net.minecraft.resources.ResourceKey<StructureSet> key;
|
||||
+ public KeyedRandomSpreadStructurePlacement(net.minecraft.resources.ResourceKey<StructureSet> key, net.minecraft.core.Vec3i locateOffset, FrequencyReductionMethod frequencyReductionMethod, float frequency, int salt, java.util.Optional<StructurePlacement.ExclusionZone> exclusionZone, int spacing, int separation, net.minecraft.world.level.levelgen.structure.placement.RandomSpreadType spreadType) {
|
||||
+ super(locateOffset, frequencyReductionMethod, frequency, salt, exclusionZone, spacing, separation, spreadType);
|
||||
+ this.key = key;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Add missing structure set seed configs
|
||||
|
||||
// Spigot start
|
||||
private static List<Holder<StructureSet>> injectSpigot(List<Holder<StructureSet>> list, SpigotWorldConfig conf) {
|
||||
return list.stream().map((holder) -> {
|
||||
StructureSet structureset = holder.value();
|
||||
- if (structureset.placement() instanceof RandomSpreadStructurePlacement randomConfig) {
|
||||
+ final Holder<StructureSet> newHolder; // Paper - Add missing structure set seed configs
|
||||
+ if (structureset.placement() instanceof RandomSpreadStructurePlacement randomConfig && holder.unwrapKey().orElseThrow().location().getNamespace().equals(net.minecraft.resources.ResourceLocation.DEFAULT_NAMESPACE)) { // Paper - Add missing structure set seed configs; check namespace cause datapacks could add structure sets with the same path
|
||||
String name = holder.unwrapKey().orElseThrow().location().getPath();
|
||||
int seed = randomConfig.salt;
|
||||
|
||||
@@ -118,11 +129,27 @@ public class ChunkGeneratorStructureState {
|
||||
case "villages":
|
||||
seed = conf.villageSeed;
|
||||
break;
|
||||
+ // Paper start - Add missing structure set seed configs
|
||||
+ case "ancient_cities":
|
||||
+ seed = conf.ancientCitySeed;
|
||||
+ break;
|
||||
+ case "trail_ruins":
|
||||
+ seed = conf.trailRuinsSeed;
|
||||
+ break;
|
||||
+ case "trial_chambers":
|
||||
+ seed = conf.trialChambersSeed;
|
||||
+ break;
|
||||
+ // Paper end - Add missing structure set seed configs
|
||||
}
|
||||
|
||||
- structureset = new StructureSet(structureset.structures(), new RandomSpreadStructurePlacement(randomConfig.locateOffset, randomConfig.frequencyReductionMethod, randomConfig.frequency, seed, randomConfig.exclusionZone, randomConfig.spacing(), randomConfig.separation(), randomConfig.spreadType()));
|
||||
+ // Paper start - Add missing structure set seed configs
|
||||
+ structureset = new StructureSet(structureset.structures(), new KeyedRandomSpreadStructurePlacement(holder.unwrapKey().orElseThrow(), randomConfig.locateOffset, randomConfig.frequencyReductionMethod, randomConfig.frequency, seed, randomConfig.exclusionZone, randomConfig.spacing(), randomConfig.separation(), randomConfig.spreadType()));
|
||||
+ newHolder = Holder.direct(structureset); // I really wish we didn't have to do this here
|
||||
+ } else {
|
||||
+ newHolder = holder;
|
||||
}
|
||||
- return Holder.direct(structureset);
|
||||
+ return newHolder;
|
||||
+ // Paper end - Add missing structure set seed configs
|
||||
}).collect(Collectors.toUnmodifiableList());
|
||||
}
|
||||
// Spigot end
|
||||
@@ -139,12 +166,13 @@ public class ChunkGeneratorStructureState {
|
||||
return stream.anyMatch(set::contains);
|
||||
}
|
||||
|
||||
- private ChunkGeneratorStructureState(RandomState noiseConfig, BiomeSource biomeSource, long structureSeed, long concentricRingSeed, List<Holder<StructureSet>> structureSets) {
|
||||
+ private ChunkGeneratorStructureState(RandomState noiseConfig, BiomeSource biomeSource, long structureSeed, long concentricRingSeed, List<Holder<StructureSet>> structureSets, SpigotWorldConfig conf) { // Paper - Add missing structure set seed configs
|
||||
this.randomState = noiseConfig;
|
||||
this.levelSeed = structureSeed;
|
||||
this.biomeSource = biomeSource;
|
||||
this.concentricRingsSeed = concentricRingSeed;
|
||||
this.possibleStructureSets = structureSets;
|
||||
+ this.conf = conf; // Paper - Add missing structure set seed configs
|
||||
}
|
||||
|
||||
public List<Holder<StructureSet>> possibleStructureSets() {
|
||||
@@ -198,7 +226,13 @@ public class ChunkGeneratorStructureState {
|
||||
HolderSet<Biome> holderset = placement.preferredBiomes();
|
||||
RandomSource randomsource = RandomSource.create();
|
||||
|
||||
+ // Paper start - Add missing structure set seed configs
|
||||
+ if (this.conf.strongholdSeed != null && structureSetEntry.is(net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.STRONGHOLDS)) {
|
||||
+ randomsource.setSeed(this.conf.strongholdSeed);
|
||||
+ } else {
|
||||
+ // Paper end - Add missing structure set seed configs
|
||||
randomsource.setSeed(this.concentricRingsSeed);
|
||||
+ } // Paper - Add missing structure set seed configs
|
||||
double d0 = randomsource.nextDouble() * Math.PI * 2.0D;
|
||||
int l = 0;
|
||||
int i1 = 0;
|
||||
@@ -275,7 +309,7 @@ public class ChunkGeneratorStructureState {
|
||||
|
||||
for (int l = centerChunkX - chunkCount; l <= centerChunkX + chunkCount; ++l) {
|
||||
for (int i1 = centerChunkZ - chunkCount; i1 <= centerChunkZ + chunkCount; ++i1) {
|
||||
- if (structureplacement.isStructureChunk(this, l, i1)) {
|
||||
+ if (structureplacement.isStructureChunk(this, l, i1, structureplacement instanceof KeyedRandomSpreadStructurePlacement keyed ? keyed.key : null)) { // Paper - Add missing structure set seed configs
|
||||
return true;
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java b/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java
|
||||
index aae73586265593ee7830fb8dd5c2e3d7560057f0..c6181e14d85d454506534f9bbe856156c0d4a062 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java
|
||||
@@ -74,6 +74,20 @@ public class StructureCheck {
|
||||
this.fixerUpper = dataFixer;
|
||||
}
|
||||
|
||||
+ // Paper start - add missing structure salt configs
|
||||
+ @Nullable
|
||||
+ private Integer getSaltOverride(Structure type) {
|
||||
+ if (this.heightAccessor instanceof net.minecraft.server.level.ServerLevel serverLevel) {
|
||||
+ if (type instanceof net.minecraft.world.level.levelgen.structure.structures.MineshaftStructure) {
|
||||
+ return serverLevel.spigotConfig.mineshaftSeed;
|
||||
+ } else if (type instanceof net.minecraft.world.level.levelgen.structure.structures.BuriedTreasureStructure) {
|
||||
+ return serverLevel.spigotConfig.buriedTreasureSeed;
|
||||
+ }
|
||||
+ }
|
||||
+ return null;
|
||||
+ }
|
||||
+ // Paper end - add missing structure seed configs
|
||||
+
|
||||
public StructureCheckResult checkStart(ChunkPos pos, Structure type, StructurePlacement placement, boolean skipReferencedStructures) {
|
||||
long l = pos.toLong();
|
||||
Object2IntMap<Structure> object2IntMap = this.loadedChunks.get(l);
|
||||
@@ -83,7 +97,7 @@ public class StructureCheck {
|
||||
StructureCheckResult structureCheckResult = this.tryLoadFromStorage(pos, type, skipReferencedStructures, l);
|
||||
if (structureCheckResult != null) {
|
||||
return structureCheckResult;
|
||||
- } else if (!placement.applyAdditionalChunkRestrictions(pos.x, pos.z, this.seed)) {
|
||||
+ } else if (!placement.applyAdditionalChunkRestrictions(pos.x, pos.z, this.seed, this.getSaltOverride(type))) { // Paper - add missing structure seed configs
|
||||
return StructureCheckResult.START_NOT_PRESENT;
|
||||
} else {
|
||||
boolean bl = this.featureChecks
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java b/src/main/java/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java
|
||||
index a4c34e9415632354d33668a38d06453ada4d3c77..cbf13e4f2da6a27619e9bc9a7cd73bb6e69cad2a 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java
|
||||
@@ -79,14 +79,30 @@ public abstract class StructurePlacement {
|
||||
return this.exclusionZone;
|
||||
}
|
||||
|
||||
+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - Add missing structure set seed configs
|
||||
public boolean isStructureChunk(ChunkGeneratorStructureState calculator, int chunkX, int chunkZ) {
|
||||
+ // Paper start - Add missing structure set seed configs
|
||||
+ return this.isStructureChunk(calculator, chunkX, chunkZ, null);
|
||||
+ }
|
||||
+ public boolean isStructureChunk(ChunkGeneratorStructureState calculator, int chunkX, int chunkZ, @org.jetbrains.annotations.Nullable net.minecraft.resources.ResourceKey<StructureSet> structureSetKey) {
|
||||
+ Integer saltOverride = null;
|
||||
+ if (structureSetKey != null) {
|
||||
+ if (structureSetKey == net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.MINESHAFTS) {
|
||||
+ saltOverride = calculator.conf.mineshaftSeed;
|
||||
+ } else if (structureSetKey == net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.BURIED_TREASURES) {
|
||||
+ saltOverride = calculator.conf.buriedTreasureSeed;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Add missing structure set seed configs
|
||||
return this.isPlacementChunk(calculator, chunkX, chunkZ)
|
||||
- && this.applyAdditionalChunkRestrictions(chunkX, chunkZ, calculator.getLevelSeed())
|
||||
+ && this.applyAdditionalChunkRestrictions(chunkX, chunkZ, calculator.getLevelSeed(), saltOverride) // Paper - Add missing structure set seed configs
|
||||
&& this.applyInteractionsWithOtherStructures(calculator, chunkX, chunkZ);
|
||||
}
|
||||
|
||||
- public boolean applyAdditionalChunkRestrictions(int chunkX, int chunkZ, long seed) {
|
||||
- return !(this.frequency < 1.0F) || this.frequencyReductionMethod.shouldGenerate(seed, this.salt, chunkX, chunkZ, this.frequency);
|
||||
+ // Paper start - Add missing structure set seed configs
|
||||
+ public boolean applyAdditionalChunkRestrictions(int chunkX, int chunkZ, long seed, @org.jetbrains.annotations.Nullable Integer saltOverride) {
|
||||
+ return !(this.frequency < 1.0F) || this.frequencyReductionMethod.shouldGenerate(seed, this.salt, chunkX, chunkZ, this.frequency, saltOverride);
|
||||
+ // Paper end - Add missing structure set seed configs
|
||||
}
|
||||
|
||||
public boolean applyInteractionsWithOtherStructures(ChunkGeneratorStructureState calculator, int centerChunkX, int centerChunkZ) {
|
||||
@@ -101,25 +117,31 @@ public abstract class StructurePlacement {
|
||||
|
||||
public abstract StructurePlacementType<?> type();
|
||||
|
||||
- private static boolean probabilityReducer(long seed, int salt, int chunkX, int chunkZ, float frequency) {
|
||||
+ private static boolean probabilityReducer(long seed, int salt, int chunkX, int chunkZ, float frequency, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs; ignore here
|
||||
WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
|
||||
worldgenRandom.setLargeFeatureWithSalt(seed, salt, chunkX, chunkZ);
|
||||
return worldgenRandom.nextFloat() < frequency;
|
||||
}
|
||||
|
||||
- private static boolean legacyProbabilityReducerWithDouble(long seed, int salt, int chunkX, int chunkZ, float frequency) {
|
||||
+ private static boolean legacyProbabilityReducerWithDouble(long seed, int salt, int chunkX, int chunkZ, float frequency, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs
|
||||
WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
|
||||
+ if (saltOverride == null) { // Paper - Add missing structure set seed configs
|
||||
worldgenRandom.setLargeFeatureSeed(seed, chunkX, chunkZ);
|
||||
+ // Paper start - Add missing structure set seed configs
|
||||
+ } else {
|
||||
+ worldgenRandom.setLargeFeatureWithSalt(seed, chunkX, chunkZ, saltOverride);
|
||||
+ }
|
||||
+ // Paper end - Add missing structure set seed configs
|
||||
return worldgenRandom.nextDouble() < (double)frequency;
|
||||
}
|
||||
|
||||
- private static boolean legacyArbitrarySaltProbabilityReducer(long seed, int salt, int chunkX, int chunkZ, float frequency) {
|
||||
+ private static boolean legacyArbitrarySaltProbabilityReducer(long seed, int salt, int chunkX, int chunkZ, float frequency, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs
|
||||
WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
|
||||
- worldgenRandom.setLargeFeatureWithSalt(seed, chunkX, chunkZ, 10387320);
|
||||
+ worldgenRandom.setLargeFeatureWithSalt(seed, chunkX, chunkZ, saltOverride != null ? saltOverride : HIGHLY_ARBITRARY_RANDOM_SALT); // Paper - Add missing structure set seed configs
|
||||
return worldgenRandom.nextFloat() < frequency;
|
||||
}
|
||||
|
||||
- private static boolean legacyPillagerOutpostReducer(long seed, int salt, int chunkX, int chunkZ, float frequency) {
|
||||
+ private static boolean legacyPillagerOutpostReducer(long seed, int salt, int chunkX, int chunkZ, float frequency, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs; ignore here
|
||||
int i = chunkX >> 4;
|
||||
int j = chunkZ >> 4;
|
||||
WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
|
||||
@@ -147,7 +169,7 @@ public abstract class StructurePlacement {
|
||||
|
||||
@FunctionalInterface
|
||||
public interface FrequencyReducer {
|
||||
- boolean shouldGenerate(long seed, int salt, int chunkX, int chunkZ, float chance);
|
||||
+ boolean shouldGenerate(long seed, int salt, int chunkX, int chunkZ, float chance, @org.jetbrains.annotations.Nullable Integer saltOverride); // Paper - Add missing structure set seed configs
|
||||
}
|
||||
|
||||
public static enum FrequencyReductionMethod implements StringRepresentable {
|
||||
@@ -167,8 +189,8 @@ public abstract class StructurePlacement {
|
||||
this.reducer = generationPredicate;
|
||||
}
|
||||
|
||||
- public boolean shouldGenerate(long seed, int salt, int chunkX, int chunkZ, float chance) {
|
||||
- return this.reducer.shouldGenerate(seed, salt, chunkX, chunkZ, chance);
|
||||
+ public boolean shouldGenerate(long seed, int salt, int chunkX, int chunkZ, float chance, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs
|
||||
+ return this.reducer.shouldGenerate(seed, salt, chunkX, chunkZ, chance, saltOverride); // Paper - Add missing structure set seed configs
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
index e76f96a5c48d1eda2f9bbb3e11dd79f23f9ab75c..2b263246135c85aa225120519e9702a628773935 100644
|
||||
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
@@ -322,6 +322,18 @@ public class SpigotWorldConfig
|
||||
public int mansionSeed;
|
||||
public int fossilSeed;
|
||||
public int portalSeed;
|
||||
+ // Paper start - add missing structure set configs
|
||||
+ public int ancientCitySeed;
|
||||
+ public int trailRuinsSeed;
|
||||
+ public int trialChambersSeed;
|
||||
+ public int buriedTreasureSeed;
|
||||
+ public Integer mineshaftSeed;
|
||||
+ public Long strongholdSeed;
|
||||
+ private <N extends Number> N getSeed(String path, java.util.function.Function<String, N> toNumberFunc) {
|
||||
+ final String value = this.getString(path, "default");
|
||||
+ return org.apache.commons.lang3.math.NumberUtils.isParsable(value) ? toNumberFunc.apply(value) : null;
|
||||
+ }
|
||||
+ // Paper end
|
||||
private void initWorldGenSeeds()
|
||||
{
|
||||
this.villageSeed = this.getInt( "seed-village", 10387312 );
|
||||
@@ -339,6 +351,14 @@ public class SpigotWorldConfig
|
||||
this.mansionSeed = this.getInt( "seed-mansion", 10387319 );
|
||||
this.fossilSeed = this.getInt( "seed-fossil", 14357921 );
|
||||
this.portalSeed = this.getInt( "seed-portal", 34222645 );
|
||||
+ // Paper start - add missing structure set configs
|
||||
+ this.ancientCitySeed = this.getInt("seed-ancientcity", 20083232);
|
||||
+ this.trailRuinsSeed = this.getInt("seed-trailruins", 83469867);
|
||||
+ this.trialChambersSeed = this.getInt("seed-trialchambers", 94251327);
|
||||
+ this.buriedTreasureSeed = this.getInt("seed-buriedtreasure", 10387320); // StructurePlacement#HIGHLY_ARBITRARY_RANDOM_SALT
|
||||
+ this.mineshaftSeed = this.getSeed("seed-mineshaft", Integer::parseInt);
|
||||
+ this.strongholdSeed = this.getSeed("seed-stronghold", Long::parseLong);
|
||||
+ // Paper end
|
||||
this.log( "Custom Map Seeds: Village: " + this.villageSeed + " Desert: " + this.desertSeed + " Igloo: " + this.iglooSeed + " Jungle: " + this.jungleSeed + " Swamp: " + this.swampSeed + " Monument: " + this.monumentSeed
|
||||
+ " Ocean: " + this.oceanSeed + " Shipwreck: " + this.shipwreckSeed + " End City: " + this.endCitySeed + " Slime: " + this.slimeSeed + " Nether: " + this.netherSeed + " Mansion: " + this.mansionSeed + " Fossil: " + this.fossilSeed + " Portal: " + this.portalSeed );
|
||||
}
|
||||
diff --git a/src/test/java/io/papermc/paper/world/structure/StructureSeedConfigTest.java b/src/test/java/io/papermc/paper/world/structure/StructureSeedConfigTest.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..c77345f7e0c9bf179b8b35a8b300085f31fd45af
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/io/papermc/paper/world/structure/StructureSeedConfigTest.java
|
||||
@@ -0,0 +1,77 @@
|
||||
+package io.papermc.paper.world.structure;
|
||||
+
|
||||
+import io.papermc.paper.configuration.PaperConfigurations;
|
||||
+import java.io.File;
|
||||
+import java.lang.reflect.Field;
|
||||
+import net.minecraft.core.Registry;
|
||||
+import net.minecraft.core.registries.Registries;
|
||||
+import net.minecraft.resources.ResourceKey;
|
||||
+import net.minecraft.resources.ResourceLocation;
|
||||
+import net.minecraft.world.level.levelgen.structure.BuiltinStructureSets;
|
||||
+import net.minecraft.world.level.levelgen.structure.StructureSet;
|
||||
+import net.minecraft.world.level.levelgen.structure.placement.StructurePlacement;
|
||||
+import org.bukkit.configuration.file.YamlConfiguration;
|
||||
+import org.bukkit.support.RegistryHelper;
|
||||
+import org.bukkit.support.environment.AllFeatures;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.junit.jupiter.api.Test;
|
||||
+import org.spigotmc.SpigotConfig;
|
||||
+import org.spigotmc.SpigotWorldConfig;
|
||||
+
|
||||
+import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
+
|
||||
+@AllFeatures
|
||||
+public class StructureSeedConfigTest {
|
||||
+
|
||||
+ @Test
|
||||
+ public void checkStructureSeedDefaults() throws ReflectiveOperationException {
|
||||
+ SpigotConfig.config = new YamlConfiguration() {
|
||||
+ @Override
|
||||
+ public void save(final @NotNull File file) {
|
||||
+ // no-op
|
||||
+ }
|
||||
+ };
|
||||
+ final SpigotWorldConfig config = PaperConfigurations.SPIGOT_WORLD_DEFAULTS.get();
|
||||
+
|
||||
+
|
||||
+ final Registry<StructureSet> structureSets = RegistryHelper.getRegistry().registryOrThrow(Registries.STRUCTURE_SET);
|
||||
+ for (final ResourceKey<StructureSet> setKey : structureSets.registryKeySet()) {
|
||||
+ assertEquals(ResourceLocation.DEFAULT_NAMESPACE, setKey.location().getNamespace());
|
||||
+ final StructureSet set = structureSets.getOrThrow(setKey);
|
||||
+ if (setKey == BuiltinStructureSets.STRONGHOLDS) { // special case due to seed matching world seed
|
||||
+ assertEquals(0, set.placement().salt);
|
||||
+ continue;
|
||||
+ }
|
||||
+ int salt = switch (setKey.location().getPath()) {
|
||||
+ case "villages" -> config.villageSeed;
|
||||
+ case "desert_pyramids" -> config.desertSeed;
|
||||
+ case "igloos" -> config.iglooSeed;
|
||||
+ case "jungle_temples" -> config.jungleSeed;
|
||||
+ case "swamp_huts" -> config.swampSeed;
|
||||
+ case "pillager_outposts" -> config.outpostSeed;
|
||||
+ case "ocean_monuments" -> config.monumentSeed;
|
||||
+ case "woodland_mansions" -> config.mansionSeed;
|
||||
+ case "buried_treasures" -> config.buriedTreasureSeed;
|
||||
+ case "mineshafts" -> config.mineshaftSeed == null ? 0 : config.mineshaftSeed; // mineshaft seed is set differently
|
||||
+ case "ruined_portals" -> config.portalSeed;
|
||||
+ case "shipwrecks" -> config.shipwreckSeed;
|
||||
+ case "ocean_ruins" -> config.oceanSeed;
|
||||
+ case "nether_complexes" -> config.netherSeed;
|
||||
+ case "nether_fossils" -> config.fossilSeed;
|
||||
+ case "end_cities" -> config.endCitySeed;
|
||||
+ case "ancient_cities" -> config.ancientCitySeed;
|
||||
+ case "trail_ruins" -> config.trailRuinsSeed;
|
||||
+ case "trial_chambers" -> config.trialChambersSeed;
|
||||
+ default -> throw new AssertionError("Missing structure set seed in SpigotWorldConfig for " + setKey);
|
||||
+ };
|
||||
+ if (setKey == BuiltinStructureSets.BURIED_TREASURES) {
|
||||
+ final Field field = StructurePlacement.class.getDeclaredField("HIGHLY_ARBITRARY_RANDOM_SALT");
|
||||
+ field.trySetAccessible();
|
||||
+ assertEquals(0, set.placement().salt);
|
||||
+ assertEquals(field.get(null), salt, "Mismatched default seed for " + setKey + ". Should be " + field.get(null));
|
||||
+ continue;
|
||||
+ }
|
||||
+ assertEquals(set.placement().salt, salt, "Mismatched default seed for " + setKey + ". Should be " + set.placement().salt);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
|
@ -1,31 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Fri, 8 Oct 2021 13:12:58 -0700
|
||||
Subject: [PATCH] Fix cancelled powdered snow bucket placement
|
||||
|
||||
Cancelling the placement of powdered snow from the powdered
|
||||
snow bucket didn't revert grass that became snowy because of the
|
||||
placement.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
index ad1cb11245108b5cb187b686ed7e6bc769193b52..ec3be7fb4eb4560fe0106ac127f17d7437612157 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
@@ -422,7 +422,7 @@ public final class ItemStack implements DataComponentHolder {
|
||||
int oldCount = this.getCount();
|
||||
ServerLevel world = (ServerLevel) context.getLevel();
|
||||
|
||||
- if (!(item instanceof BucketItem || item instanceof SolidBucketItem)) { // if not bucket
|
||||
+ if (!(item instanceof BucketItem/* || item instanceof SolidBucketItem*/)) { // if not bucket // Paper - Fix cancelled powdered snow bucket placement
|
||||
world.captureBlockStates = true;
|
||||
// special case bonemeal
|
||||
if (item == Items.BONE_MEAL) {
|
||||
@@ -482,7 +482,7 @@ public final class ItemStack implements DataComponentHolder {
|
||||
world.capturedBlockStates.clear();
|
||||
if (blocks.size() > 1) {
|
||||
placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockMultiPlaceEvent(world, entityhuman, enumhand, blocks, blockposition.getX(), blockposition.getY(), blockposition.getZ());
|
||||
- } else if (blocks.size() == 1) {
|
||||
+ } else if (blocks.size() == 1 && item != Items.POWDER_SNOW_BUCKET) { // Paper - Fix cancelled powdered snow bucket placement
|
||||
placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(world, entityhuman, enumhand, blocks.get(0), blockposition.getX(), blockposition.getY(), blockposition.getZ());
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
Date: Sat, 12 Feb 2022 12:40:50 -0700
|
||||
Subject: [PATCH] Add missing Validate calls to CraftServer#getSpawnLimit
|
||||
|
||||
Copies appropriate checks from CraftWorld#getSpawnLimit
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index c0eca359919c55ba7b33520277c124eb54d935d7..1a2081267e85ef5c1edd4808fbda5bb442a00252 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -2339,6 +2339,8 @@ public final class CraftServer implements Server {
|
||||
@Override
|
||||
public int getSpawnLimit(SpawnCategory spawnCategory) {
|
||||
// Paper start - Add mobcaps commands
|
||||
+ Preconditions.checkArgument(spawnCategory != null, "SpawnCategory cannot be null");
|
||||
+ Preconditions.checkArgument(CraftSpawnCategory.isValidForLimits(spawnCategory), "SpawnCategory." + spawnCategory + " does not have a spawn limit.");
|
||||
return this.getSpawnLimitUnsafe(spawnCategory);
|
||||
}
|
||||
public int getSpawnLimitUnsafe(final SpawnCategory spawnCategory) {
|
|
@ -1,81 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 3 Jan 2021 20:03:35 -0800
|
||||
Subject: [PATCH] Add GameEvent tags
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/CraftGameEventTag.java b/src/main/java/io/papermc/paper/CraftGameEventTag.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e7d9fd2702a1ce96596580fff8f5ee4fd3d22b5b
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/CraftGameEventTag.java
|
||||
@@ -0,0 +1,35 @@
|
||||
+package io.papermc.paper;
|
||||
+
|
||||
+import net.minecraft.core.registries.BuiltInRegistries;
|
||||
+import net.minecraft.core.registries.Registries;
|
||||
+import net.minecraft.resources.ResourceKey;
|
||||
+import net.minecraft.tags.TagKey;
|
||||
+import org.bukkit.GameEvent;
|
||||
+import org.bukkit.craftbukkit.tag.CraftTag;
|
||||
+import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+import java.util.Collections;
|
||||
+import java.util.IdentityHashMap;
|
||||
+import java.util.Map;
|
||||
+import java.util.Objects;
|
||||
+import java.util.Set;
|
||||
+import java.util.stream.Collectors;
|
||||
+
|
||||
+public class CraftGameEventTag extends CraftTag<net.minecraft.world.level.gameevent.GameEvent, GameEvent> {
|
||||
+
|
||||
+ public CraftGameEventTag(net.minecraft.core.Registry<net.minecraft.world.level.gameevent.GameEvent> registry, TagKey<net.minecraft.world.level.gameevent.GameEvent> tag) {
|
||||
+ super(registry, tag);
|
||||
+ }
|
||||
+
|
||||
+ private static final Map<GameEvent, ResourceKey<net.minecraft.world.level.gameevent.GameEvent>> KEY_CACHE = Collections.synchronizedMap(new IdentityHashMap<>());
|
||||
+ @Override
|
||||
+ public boolean isTagged(@NotNull GameEvent gameEvent) {
|
||||
+ return registry.getHolderOrThrow(KEY_CACHE.computeIfAbsent(gameEvent, event -> ResourceKey.create(Registries.GAME_EVENT, CraftNamespacedKey.toMinecraft(event.getKey())))).is(tag);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull Set<GameEvent> getValues() {
|
||||
+ return getHandle().stream().map((nms) -> Objects.requireNonNull(GameEvent.getByKey(CraftNamespacedKey.fromMinecraft(BuiltInRegistries.GAME_EVENT.getKey(nms.value()))), nms + " is not a recognized game event")).collect(Collectors.toUnmodifiableSet());
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 1a2081267e85ef5c1edd4808fbda5bb442a00252..8589b0218659ae5ddbaac5437316bf59265324dd 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -2688,6 +2688,15 @@ public final class CraftServer implements Server {
|
||||
return (org.bukkit.Tag<T>) new CraftEntityTag(BuiltInRegistries.ENTITY_TYPE, entityTagKey);
|
||||
}
|
||||
}
|
||||
+ // Paper start
|
||||
+ case org.bukkit.Tag.REGISTRY_GAME_EVENTS -> {
|
||||
+ Preconditions.checkArgument(clazz == org.bukkit.GameEvent.class, "Game Event namespace must have GameEvent type");
|
||||
+ TagKey<net.minecraft.world.level.gameevent.GameEvent> gameEventTagKey = TagKey.create(net.minecraft.core.registries.Registries.GAME_EVENT, key);
|
||||
+ if (net.minecraft.core.registries.BuiltInRegistries.GAME_EVENT.getTag(gameEventTagKey).isPresent()) {
|
||||
+ return (org.bukkit.Tag<T>) new io.papermc.paper.CraftGameEventTag(net.minecraft.core.registries.BuiltInRegistries.GAME_EVENT, gameEventTagKey);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
default -> throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
@@ -2720,6 +2729,13 @@ public final class CraftServer implements Server {
|
||||
net.minecraft.core.Registry<EntityType<?>> entityTags = BuiltInRegistries.ENTITY_TYPE;
|
||||
return entityTags.getTags().map(pair -> (org.bukkit.Tag<T>) new CraftEntityTag(entityTags, pair.getFirst())).collect(ImmutableList.toImmutableList());
|
||||
}
|
||||
+ // Paper start
|
||||
+ case org.bukkit.Tag.REGISTRY_GAME_EVENTS -> {
|
||||
+ Preconditions.checkArgument(clazz == org.bukkit.GameEvent.class);
|
||||
+ net.minecraft.core.Registry<net.minecraft.world.level.gameevent.GameEvent> gameEvents = net.minecraft.core.registries.BuiltInRegistries.GAME_EVENT;
|
||||
+ return gameEvents.getTags().map(pair -> (org.bukkit.Tag<T>) new io.papermc.paper.CraftGameEventTag(gameEvents, pair.getFirst())).collect(ImmutableList.toImmutableList());
|
||||
+ }
|
||||
+ // Paper end
|
||||
default -> throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Tue, 28 Dec 2021 07:19:01 -0800
|
||||
Subject: [PATCH] Execute chunk tasks fairly for worlds while waiting for next
|
||||
tick
|
||||
|
||||
Currently, only the first world would have had tasks executed.
|
||||
This might result in chunks loading far slower in the nether,
|
||||
for example.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 718b653a118a1c64d07efab93192f10dfcbf414e..d45f234fe389ade739bb13f824a1f650709220b8 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1369,6 +1369,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
if (super.pollTask()) {
|
||||
return true;
|
||||
} else {
|
||||
+ boolean ret = false; // Paper - force execution of all worlds, do not just bias the first
|
||||
if (this.tickRateManager.isSprinting() || this.haveTime()) {
|
||||
Iterator iterator = this.getAllLevels().iterator();
|
||||
|
||||
@@ -1376,12 +1377,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
ServerLevel worldserver = (ServerLevel) iterator.next();
|
||||
|
||||
if (worldserver.getChunkSource().pollTask()) {
|
||||
- return true;
|
||||
+ ret = true; // Paper - force execution of all worlds, do not just bias the first
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- return false;
|
||||
+ return ret; // Paper - force execution of all worlds, do not just bias the first
|
||||
}
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 13 Jan 2022 15:20:47 -0800
|
||||
Subject: [PATCH] Furnace RecipesUsed API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java b/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java
|
||||
index ddbbf977c8f536a156ff6b2462353f7be5ab5742..677d8bc8fcfbb987378b4fbe1a57935786b612fb 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java
|
||||
@@ -104,5 +104,37 @@ public abstract class CraftFurnace<T extends AbstractFurnaceBlockEntity> extends
|
||||
snapshot.cookSpeedMultiplier = multiplier;
|
||||
snapshot.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(this.isPlaced() ? this.world.getHandle() : null, snapshot.recipeType, snapshot, snapshot.cookSpeedMultiplier); // Update the snapshot's current total cook time to scale with the newly set multiplier
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public int getRecipeUsedCount(org.bukkit.NamespacedKey furnaceRecipe) {
|
||||
+ return this.getSnapshot().getRecipesUsed().getInt(org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(furnaceRecipe));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasRecipeUsedCount(org.bukkit.NamespacedKey furnaceRecipe) {
|
||||
+ return this.getSnapshot().getRecipesUsed().containsKey(org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(furnaceRecipe));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setRecipeUsedCount(org.bukkit.inventory.CookingRecipe<?> furnaceRecipe, int count) {
|
||||
+ final net.minecraft.resources.ResourceLocation location = org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(furnaceRecipe.getKey());
|
||||
+ java.util.Optional<net.minecraft.world.item.crafting.RecipeHolder<?>> nmsRecipe = (this.isPlaced() ? this.world.getHandle().getRecipeManager() : net.minecraft.server.MinecraftServer.getServer().getRecipeManager()).byKey(location);
|
||||
+ com.google.common.base.Preconditions.checkArgument(nmsRecipe.isPresent() && nmsRecipe.get().value() instanceof net.minecraft.world.item.crafting.AbstractCookingRecipe, furnaceRecipe.getKey() + " is not recognized as a valid and registered furnace recipe");
|
||||
+ if (count > 0) {
|
||||
+ this.getSnapshot().getRecipesUsed().put(location, count);
|
||||
+ } else {
|
||||
+ this.getSnapshot().getRecipesUsed().removeInt(location);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setRecipesUsed(java.util.Map<org.bukkit.inventory.CookingRecipe<?>, Integer> recipesUsed) {
|
||||
+ this.getSnapshot().getRecipesUsed().clear();
|
||||
+ recipesUsed.forEach((recipe, integer) -> {
|
||||
+ if (integer != null) {
|
||||
+ this.setRecipeUsedCount(recipe, integer);
|
||||
+ }
|
||||
+ });
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 19 Aug 2021 18:45:42 -0700
|
||||
Subject: [PATCH] Configurable sculk sensor listener range
|
||||
|
||||
== AT ==
|
||||
public-f net.minecraft.world.level.gameevent.vibrations.VibrationListener listenerRange
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/CalibratedSculkSensorBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/CalibratedSculkSensorBlockEntity.java
|
||||
index 41ccbee5fc7767a7d5e1cdca0ec7d9a17ee80a90..1d28f117965da22694b12018923a5f1347905085 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/CalibratedSculkSensorBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/CalibratedSculkSensorBlockEntity.java
|
||||
@@ -20,6 +20,12 @@ public class CalibratedSculkSensorBlockEntity extends SculkSensorBlockEntity {
|
||||
public VibrationSystem.User createVibrationUser() {
|
||||
return new CalibratedSculkSensorBlockEntity.VibrationUser(this.getBlockPos());
|
||||
}
|
||||
+ // Paper start - Configurable sculk sensor listener range
|
||||
+ @Override
|
||||
+ protected void saveRangeOverride(final net.minecraft.nbt.CompoundTag nbt) {
|
||||
+ if (this.rangeOverride != null && this.rangeOverride != 16) nbt.putInt(PAPER_LISTENER_RANGE_NBT_KEY, this.rangeOverride); // only save if it's different from the default
|
||||
+ }
|
||||
+ // Paper end - Configurable sculk sensor listener range
|
||||
|
||||
protected class VibrationUser extends SculkSensorBlockEntity.VibrationUser {
|
||||
public VibrationUser(final BlockPos pos) {
|
||||
@@ -28,6 +34,7 @@ public class CalibratedSculkSensorBlockEntity extends SculkSensorBlockEntity {
|
||||
|
||||
@Override
|
||||
public int getListenerRadius() {
|
||||
+ if (CalibratedSculkSensorBlockEntity.this.rangeOverride != null) return CalibratedSculkSensorBlockEntity.this.rangeOverride; // Paper - Configurable sculk sensor listener range
|
||||
return 16;
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java
|
||||
index bbaffdac7c2d3bd646133b36c5d450cba9fc0c07..a943ed46a5f593dfe612c9c797dc961e3e020506 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java
|
||||
@@ -26,6 +26,7 @@ public class SculkSensorBlockEntity extends BlockEntity implements GameEventList
|
||||
private final VibrationSystem.Listener vibrationListener;
|
||||
private final VibrationSystem.User vibrationUser = this.createVibrationUser();
|
||||
public int lastVibrationFrequency;
|
||||
+ @Nullable public Integer rangeOverride = null; // Paper - Configurable sculk sensor listener range
|
||||
|
||||
protected SculkSensorBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||
super(type, pos, state);
|
||||
@@ -52,8 +53,16 @@ public class SculkSensorBlockEntity extends BlockEntity implements GameEventList
|
||||
.resultOrPartial(string -> LOGGER.error("Failed to parse vibration listener for Sculk Sensor: '{}'", string))
|
||||
.ifPresent(listener -> this.vibrationData = listener);
|
||||
}
|
||||
+ // Paper start - Configurable sculk sensor listener range
|
||||
+ if (nbt.contains(PAPER_LISTENER_RANGE_NBT_KEY)) {
|
||||
+ this.rangeOverride = nbt.getInt(PAPER_LISTENER_RANGE_NBT_KEY);
|
||||
+ } else {
|
||||
+ this.rangeOverride = null;
|
||||
+ }
|
||||
+ // Paper end - Configurable sculk sensor listener range
|
||||
}
|
||||
|
||||
+ protected static final String PAPER_LISTENER_RANGE_NBT_KEY = "Paper.ListenerRange"; // Paper - Configurable sculk sensor listener range
|
||||
@Override
|
||||
protected void saveAdditional(CompoundTag nbt, HolderLookup.Provider registryLookup) {
|
||||
super.saveAdditional(nbt, registryLookup);
|
||||
@@ -63,7 +72,13 @@ public class SculkSensorBlockEntity extends BlockEntity implements GameEventList
|
||||
.encodeStart(registryOps, this.vibrationData)
|
||||
.resultOrPartial(string -> LOGGER.error("Failed to encode vibration listener for Sculk Sensor: '{}'", string))
|
||||
.ifPresent(listenerNbt -> nbt.put("listener", listenerNbt));
|
||||
+ this.saveRangeOverride(nbt); // Paper - Configurable sculk sensor listener range
|
||||
+ }
|
||||
+ // Paper start - Configurable sculk sensor listener range
|
||||
+ protected void saveRangeOverride(CompoundTag nbt) {
|
||||
+ if (this.rangeOverride != null && this.rangeOverride != VibrationUser.LISTENER_RANGE) nbt.putInt(PAPER_LISTENER_RANGE_NBT_KEY, this.rangeOverride); // only save if it's different from the default
|
||||
}
|
||||
+ // Paper end - Configurable sculk sensor listener range
|
||||
|
||||
@Override
|
||||
public VibrationSystem.Data getVibrationData() {
|
||||
@@ -100,6 +115,7 @@ public class SculkSensorBlockEntity extends BlockEntity implements GameEventList
|
||||
|
||||
@Override
|
||||
public int getListenerRadius() {
|
||||
+ if (SculkSensorBlockEntity.this.rangeOverride != null) return SculkSensorBlockEntity.this.rangeOverride; // Paper - Configurable sculk sensor listener range
|
||||
return 8;
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftSculkSensor.java b/src/main/java/org/bukkit/craftbukkit/block/CraftSculkSensor.java
|
||||
index 70d85dbfcaae7ee632a4f541334302b46615a254..6ba229afb0219ff229fd794c59d7585f010742ee 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftSculkSensor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftSculkSensor.java
|
||||
@@ -36,4 +36,17 @@ public class CraftSculkSensor<T extends SculkSensorBlockEntity> extends CraftBlo
|
||||
public CraftSculkSensor<T> copy(Location location) {
|
||||
return new CraftSculkSensor<>(this, location);
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getListenerRange() {
|
||||
+ return this.getSnapshot().getListener().getListenerRadius();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setListenerRange(int range) {
|
||||
+ Preconditions.checkArgument(range > 0, "Vibration listener range must be greater than 0");
|
||||
+ this.getSnapshot().rangeOverride = range;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -1,214 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sat, 16 Oct 2021 22:57:31 -0700
|
||||
Subject: [PATCH] Add missing block data API
|
||||
|
||||
General purpose patch adding missing getters/setters to BlockData and
|
||||
its child types.
|
||||
|
||||
Co-authored-by: SoSeDiK <mrsosedik@gmail.com>
|
||||
Co-authored-by: Fabrizio La Rosa <lr.fabrizio@gmail.com>
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftBed.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftBed.java
|
||||
index 2ccf3fbe3f991b7a014cff3bcd424e6a81bc310a..e5450d3511389bf3bd6461fb6ec65ea82e4ae9f0 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftBed.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftBed.java
|
||||
@@ -51,4 +51,11 @@ public final class CraftBed extends org.bukkit.craftbukkit.block.data.CraftBlock
|
||||
public java.util.Set<org.bukkit.block.BlockFace> getFaces() {
|
||||
return this.getValues(CraftBed.FACING, org.bukkit.block.BlockFace.class);
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void setOccupied(boolean occupied) {
|
||||
+ set(CraftBed.OCCUPIED, occupied);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftCandle.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftCandle.java
|
||||
index 2230160d5e04e979467a56346600436c1e5dd70c..08436bfeba2f35fb11b16c4f71f76e13c0d44b1a 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftCandle.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftCandle.java
|
||||
@@ -31,6 +31,12 @@ public final class CraftCandle extends org.bukkit.craftbukkit.block.data.CraftBl
|
||||
public int getMaximumCandles() {
|
||||
return getMax(CraftCandle.CANDLES);
|
||||
}
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getMinimumCandles() {
|
||||
+ return getMin(CraftCandle.CANDLES);
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
// org.bukkit.craftbukkit.block.data.CraftLightable
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftCherryLeaves.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftCherryLeaves.java
|
||||
index af29ff861eb2c504ef31cc3236adf1e7f6b46049..bc32c5d4c7568ed4392e4bdb5872066846aa62b6 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftCherryLeaves.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftCherryLeaves.java
|
||||
@@ -51,4 +51,16 @@ public final class CraftCherryLeaves extends org.bukkit.craftbukkit.block.data.C
|
||||
public void setWaterlogged(boolean waterlogged) {
|
||||
this.set(CraftCherryLeaves.WATERLOGGED, waterlogged);
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getMaximumDistance() {
|
||||
+ return getMax(DISTANCE);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getMinimumDistance() {
|
||||
+ return getMin(DISTANCE);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftComposter.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftComposter.java
|
||||
index 7ce2e8b733bcd496dcfccb1ddfcb7c5c1b64052e..5ae27fc8f9d18bae949d335ea53e7e70917f0e80 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftComposter.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftComposter.java
|
||||
@@ -31,4 +31,11 @@ public final class CraftComposter extends org.bukkit.craftbukkit.block.data.Craf
|
||||
public int getMaximumLevel() {
|
||||
return getMax(CraftComposter.LEVEL);
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getMinimumLevel() {
|
||||
+ return getMin(CraftComposter.LEVEL);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftDecoratedPot.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftDecoratedPot.java
|
||||
index 356230b9b266974e36d0508f8c239714d673504d..b7ea9a6fba6b4fc157dfcc4bee099871b8ad7380 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftDecoratedPot.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftDecoratedPot.java
|
||||
@@ -45,4 +45,18 @@ public final class CraftDecoratedPot extends org.bukkit.craftbukkit.block.data.C
|
||||
public void setWaterlogged(boolean waterlogged) {
|
||||
this.set(CraftDecoratedPot.WATERLOGGED, waterlogged);
|
||||
}
|
||||
+
|
||||
+ // Paper start - add missing block data api
|
||||
+ private static final net.minecraft.world.level.block.state.properties.BooleanProperty CRACKED = getBoolean(net.minecraft.world.level.block.DecoratedPotBlock.class, "cracked");
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCracked() {
|
||||
+ return this.get(CraftDecoratedPot.CRACKED);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCracked(final boolean cracked) {
|
||||
+ this.set(CraftDecoratedPot.CRACKED, cracked);
|
||||
+ }
|
||||
+ // Paper end - add missing block data api
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftFluids.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftFluids.java
|
||||
index 70d734fc71a4499bbf569b3908aa5fbbdf19e6a0..1af5fe48c5861077555e6bdeb6312859b7b37eb2 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftFluids.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftFluids.java
|
||||
@@ -31,4 +31,11 @@ public final class CraftFluids extends org.bukkit.craftbukkit.block.data.CraftBl
|
||||
public int getMaximumLevel() {
|
||||
return getMax(CraftFluids.LEVEL);
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getMinimumLevel() {
|
||||
+ return getMin(CraftFluids.LEVEL);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLayeredCauldron.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLayeredCauldron.java
|
||||
index bf0d53f65f8a672c385b2e798b109a9662725f9e..c0e0cbceb0b5c36f4ac4672f217027a5898900a6 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLayeredCauldron.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLayeredCauldron.java
|
||||
@@ -31,4 +31,11 @@ public final class CraftLayeredCauldron extends org.bukkit.craftbukkit.block.dat
|
||||
public int getMaximumLevel() {
|
||||
return getMax(CraftLayeredCauldron.LEVEL);
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getMinimumLevel() {
|
||||
+ return getMin(CraftLayeredCauldron.LEVEL);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLeaves.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLeaves.java
|
||||
index 33d9a950ed678595fe2573e9f89a8d1716040503..ab336b400c1937ff86b681b27b1550e4b7f1ab79 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLeaves.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLeaves.java
|
||||
@@ -51,4 +51,16 @@ public final class CraftLeaves extends org.bukkit.craftbukkit.block.data.CraftBl
|
||||
public void setWaterlogged(boolean waterlogged) {
|
||||
this.set(CraftLeaves.WATERLOGGED, waterlogged);
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getMaximumDistance() {
|
||||
+ return getMax(CraftLeaves.DISTANCE);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getMinimumDistance() {
|
||||
+ return getMin(CraftLeaves.DISTANCE);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLight.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLight.java
|
||||
index 49f314b1447212a1a5a7623d2302b5960a44ce6e..8c936a95effa84ba0337d2aaf880cc561591fb33 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLight.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLight.java
|
||||
@@ -32,6 +32,13 @@ public final class CraftLight extends org.bukkit.craftbukkit.block.data.CraftBlo
|
||||
return getMax(CraftLight.LEVEL);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getMinimumLevel() {
|
||||
+ return getMin(CraftLight.LEVEL);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
// org.bukkit.craftbukkit.block.data.CraftWaterlogged
|
||||
|
||||
private static final net.minecraft.world.level.block.state.properties.BooleanProperty WATERLOGGED = getBoolean(net.minecraft.world.level.block.LightBlock.class, "waterlogged");
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftMangroveLeaves.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftMangroveLeaves.java
|
||||
index 7a1f2fd2f7f8f1b46352fe2c4d0cdf23a88020fd..8b621aaeadcf2cc6e2ccdbab92f4ae2b89a6ca08 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftMangroveLeaves.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftMangroveLeaves.java
|
||||
@@ -51,4 +51,16 @@ public final class CraftMangroveLeaves extends org.bukkit.craftbukkit.block.data
|
||||
public void setWaterlogged(boolean waterlogged) {
|
||||
this.set(CraftMangroveLeaves.WATERLOGGED, waterlogged);
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getMinimumDistance() {
|
||||
+ return getMin(CraftMangroveLeaves.DISTANCE);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getMaximumDistance() {
|
||||
+ return getMax(CraftMangroveLeaves.DISTANCE);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftPinkPetals.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftPinkPetals.java
|
||||
index 78b220a6f460cd91ad1574c0d32f3e4288eaf431..0f7df1b4c58ba731832958043ba345ec77737e54 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftPinkPetals.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftPinkPetals.java
|
||||
@@ -27,6 +27,13 @@ public final class CraftPinkPetals extends org.bukkit.craftbukkit.block.data.Cra
|
||||
this.set(CraftPinkPetals.FLOWER_AMOUNT, flower_amount);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getMinimumFlowerAmount() {
|
||||
+ return getMin(CraftPinkPetals.FLOWER_AMOUNT);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public int getMaximumFlowerAmount() {
|
||||
return getMax(CraftPinkPetals.FLOWER_AMOUNT);
|
|
@ -1,32 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sat, 19 Feb 2022 20:15:41 -0800
|
||||
Subject: [PATCH] Option to have default CustomSpawners in custom worlds
|
||||
|
||||
By default, only LevelStem's that specifically match the ResourceKey for
|
||||
OVERWORLD will have the 5 (currently) impls of CustomSpawner (for
|
||||
phantoms, wandering traders, etc.). This adds an option to instead of
|
||||
just looking at the LevelStem key, look at the DimensionType key which
|
||||
is one level below that. Defaults to off to keep vanilla behavior.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index d45f234fe389ade739bb13f824a1f650709220b8..413a37991d1df6314dd9938e5eb5f28f5b69efb8 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -631,7 +631,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.commandStorage = new CommandStorage(worldpersistentdata);
|
||||
} else {
|
||||
ChunkProgressListener worldloadlistener = this.progressListenerFactory.create(this.worldData.getGameRules().getInt(GameRules.RULE_SPAWN_CHUNK_RADIUS));
|
||||
- world = new ServerLevel(this, this.executor, worldSession, iworlddataserver, worldKey, worlddimension, worldloadlistener, flag, j, ImmutableList.of(), true, this.overworld().getRandomSequences(), org.bukkit.World.Environment.getEnvironment(dimension), gen, biomeProvider);
|
||||
+ // Paper start - option to use the dimension_type to check if spawners should be added. I imagine mojang will add some datapack-y way of managing this in the future.
|
||||
+ final List<CustomSpawner> spawners;
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.useDimensionTypeForCustomSpawners && this.registryAccess().registryOrThrow(Registries.DIMENSION_TYPE).getResourceKey(worlddimension.type().value()).orElseThrow() == net.minecraft.world.level.dimension.BuiltinDimensionTypes.OVERWORLD) {
|
||||
+ spawners = list;
|
||||
+ } else {
|
||||
+ spawners = Collections.emptyList();
|
||||
+ }
|
||||
+ world = new ServerLevel(this, this.executor, worldSession, iworlddataserver, worldKey, worlddimension, worldloadlistener, flag, j, spawners, true, this.overworld().getRandomSequences(), org.bukkit.World.Environment.getEnvironment(dimension), gen, biomeProvider);
|
||||
+ // Paper end - option to use the dimension_type to check if spawners should be added
|
||||
}
|
||||
|
||||
worlddata.setModdedInfo(this.getServerModName(), this.getModdedStatus().shouldReportAsModified());
|
|
@ -1,41 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Tue, 22 Feb 2022 14:21:35 -0800
|
||||
Subject: [PATCH] Put world into worldlist before initing the world
|
||||
|
||||
Some parts of legacy conversion will need the overworld
|
||||
to get the legacy structure data storage
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 413a37991d1df6314dd9938e5eb5f28f5b69efb8..e7d6f4e6ac41b183c702d5195e4f94136c22b000 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -643,9 +643,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
worlddata.setModdedInfo(this.getServerModName(), this.getModdedStatus().shouldReportAsModified());
|
||||
+ this.addLevel(world); // Paper - Put world into worldlist before initing the world; move up
|
||||
this.initWorld(world, worlddata, this.worldData, worldoptions);
|
||||
|
||||
- this.addLevel(world);
|
||||
+ // Paper - Put world into worldlist before initing the world; move up
|
||||
this.getPlayerList().addWorldborderListener(world);
|
||||
|
||||
if (worlddata.getCustomBossEvents() != null) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 8589b0218659ae5ddbaac5437316bf59265324dd..74d2f6df5a4cdab8a24ca1769c7b7d98ef87bcfe 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -1334,10 +1334,11 @@ public final class CraftServer implements Server {
|
||||
return null;
|
||||
}
|
||||
|
||||
+ this.console.addLevel(internal); // Paper - Put world into worldlist before initing the world; move up
|
||||
this.console.initWorld(internal, worlddata, worlddata, worlddata.worldGenOptions());
|
||||
|
||||
internal.setSpawnSettings(true, true);
|
||||
- this.console.addLevel(internal);
|
||||
+ // Paper - Put world into worldlist before initing the world; move up
|
||||
|
||||
this.getServer().prepareLevels(internal.getChunkSource().chunkMap.progressListener, internal);
|
||||
internal.entityManager.tick(); // SPIGOT-6526: Load pending entities so they are available to the API
|
|
@ -1,329 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 7 Oct 2021 14:34:55 -0700
|
||||
Subject: [PATCH] Custom Potion Mixes
|
||||
|
||||
== AT ==
|
||||
public-f net.minecraft.server.MinecraftServer potionBrewing
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/potion/PaperPotionBrewer.java b/src/main/java/io/papermc/paper/potion/PaperPotionBrewer.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..d9390227a2bba4e03aa9ee592ca157127633c41b
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/potion/PaperPotionBrewer.java
|
||||
@@ -0,0 +1,56 @@
|
||||
+package io.papermc.paper.potion;
|
||||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+import java.util.Collection;
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
+import org.bukkit.NamespacedKey;
|
||||
+import org.bukkit.potion.PotionBrewer;
|
||||
+import org.bukkit.potion.PotionEffect;
|
||||
+import org.bukkit.potion.PotionType;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public class PaperPotionBrewer implements PotionBrewer {
|
||||
+
|
||||
+ private final MinecraftServer minecraftServer;
|
||||
+
|
||||
+ public PaperPotionBrewer(final MinecraftServer minecraftServer) {
|
||||
+ this.minecraftServer = minecraftServer;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ @Deprecated(forRemoval = true)
|
||||
+ public Collection<PotionEffect> getEffects(PotionType type, boolean upgraded, boolean extended) {
|
||||
+ final org.bukkit.NamespacedKey key = type.getKey();
|
||||
+
|
||||
+ Preconditions.checkArgument(!key.getKey().startsWith("strong_"), "Strong potion type cannot be used directly, got %s", key);
|
||||
+ Preconditions.checkArgument(!key.getKey().startsWith("long_"), "Extended potion type cannot be used directly, got %s", key);
|
||||
+
|
||||
+ org.bukkit.NamespacedKey effectiveKey = key;
|
||||
+ if (upgraded) {
|
||||
+ effectiveKey = new org.bukkit.NamespacedKey(key.namespace(), "strong_" + key.key());
|
||||
+ } else if (extended) {
|
||||
+ effectiveKey = new org.bukkit.NamespacedKey(key.namespace(), "long_" + key.key());
|
||||
+ }
|
||||
+
|
||||
+ final org.bukkit.potion.PotionType effectivePotionType = org.bukkit.Registry.POTION.get(effectiveKey);
|
||||
+ Preconditions.checkNotNull(type, "Unknown potion type from data " + effectiveKey.asMinimalString()); // Legacy error message in 1.20.4
|
||||
+ return effectivePotionType.getPotionEffects();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void addPotionMix(final PotionMix potionMix) {
|
||||
+ this.minecraftServer.potionBrewing().addPotionMix(potionMix);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void removePotionMix(final NamespacedKey key) {
|
||||
+ this.minecraftServer.potionBrewing.removePotionMix(key);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void resetPotionMixes() {
|
||||
+ this.minecraftServer.potionBrewing = this.minecraftServer.potionBrewing().reload(this.minecraftServer.getWorldData().enabledFeatures());
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/potion/PaperPotionMix.java b/src/main/java/io/papermc/paper/potion/PaperPotionMix.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..7ea357ac2f3a93db4ebdf24b5072be7d1cad3e33
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/potion/PaperPotionMix.java
|
||||
@@ -0,0 +1,21 @@
|
||||
+package io.papermc.paper.potion;
|
||||
+
|
||||
+import java.util.function.Predicate;
|
||||
+import net.minecraft.world.item.ItemStack;
|
||||
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
+import org.bukkit.craftbukkit.inventory.CraftRecipe;
|
||||
+import org.bukkit.inventory.RecipeChoice;
|
||||
+
|
||||
+public record PaperPotionMix(ItemStack result, Predicate<ItemStack> input, Predicate<ItemStack> ingredient) {
|
||||
+
|
||||
+ public PaperPotionMix(PotionMix potionMix) {
|
||||
+ this(CraftItemStack.asNMSCopy(potionMix.getResult()), convert(potionMix.getInput()), convert(potionMix.getIngredient()));
|
||||
+ }
|
||||
+
|
||||
+ static Predicate<ItemStack> convert(final RecipeChoice choice) {
|
||||
+ if (choice instanceof PredicateRecipeChoice predicateRecipeChoice) {
|
||||
+ return stack -> predicateRecipeChoice.test(CraftItemStack.asBukkitCopy(stack));
|
||||
+ }
|
||||
+ return CraftRecipe.toIngredient(choice, true);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index e7d6f4e6ac41b183c702d5195e4f94136c22b000..94aa901b77b19445a33d5b2b24ba2e947d2a6aef 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -2158,6 +2158,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
this.worldData.setDataConfiguration(worlddataconfiguration);
|
||||
this.resources.managers.updateRegistryTags();
|
||||
+ this.potionBrewing = this.potionBrewing.reload(this.worldData.enabledFeatures()); // Paper - Custom Potion Mixes
|
||||
this.getPlayerList().saveAll();
|
||||
this.getPlayerList().reloadResources();
|
||||
this.functionManager.replaceLibrary(this.resources.managers.getFunctionLibrary());
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/BrewingStandMenu.java b/src/main/java/net/minecraft/world/inventory/BrewingStandMenu.java
|
||||
index 302e3fba89bc0f2f36448a7be1178710f5ea4d35..68c529cb38d61cd3a0f39bef0f666057fc219c9b 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/BrewingStandMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/BrewingStandMenu.java
|
||||
@@ -53,9 +53,11 @@ public class BrewingStandMenu extends AbstractContainerMenu {
|
||||
this.brewingStandData = propertyDelegate;
|
||||
PotionBrewing potionbrewer = playerInventory.player.level().potionBrewing();
|
||||
|
||||
- this.addSlot(new BrewingStandMenu.PotionSlot(inventory, 0, 56, 51));
|
||||
- this.addSlot(new BrewingStandMenu.PotionSlot(inventory, 1, 79, 58));
|
||||
- this.addSlot(new BrewingStandMenu.PotionSlot(inventory, 2, 102, 51));
|
||||
+ // Paper start - custom potion mixes
|
||||
+ this.addSlot(new BrewingStandMenu.PotionSlot(inventory, 0, 56, 51, potionbrewer));
|
||||
+ this.addSlot(new BrewingStandMenu.PotionSlot(inventory, 1, 79, 58, potionbrewer));
|
||||
+ this.addSlot(new BrewingStandMenu.PotionSlot(inventory, 2, 102, 51, potionbrewer));
|
||||
+ // Paper end - custom potion mixes
|
||||
this.ingredientSlot = this.addSlot(new BrewingStandMenu.IngredientsSlot(potionbrewer, inventory, 3, 79, 17));
|
||||
this.addSlot(new BrewingStandMenu.FuelSlot(inventory, 4, 17, 17));
|
||||
this.addDataSlots(propertyDelegate);
|
||||
@@ -98,7 +100,7 @@ public class BrewingStandMenu extends AbstractContainerMenu {
|
||||
if (!this.moveItemStackTo(itemstack1, 3, 4, false)) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
- } else if (BrewingStandMenu.PotionSlot.mayPlaceItem(itemstack)) {
|
||||
+ } else if (BrewingStandMenu.PotionSlot.mayPlaceItem(itemstack, this.player.player.level().potionBrewing())) { // Paper - custom potion mixes
|
||||
if (!this.moveItemStackTo(itemstack1, 0, 3, false)) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
@@ -147,13 +149,15 @@ public class BrewingStandMenu extends AbstractContainerMenu {
|
||||
|
||||
private static class PotionSlot extends Slot {
|
||||
|
||||
- public PotionSlot(Container inventory, int index, int x, int y) {
|
||||
+ private final PotionBrewing potionBrewing; // Paper - custom potion mixes
|
||||
+ public PotionSlot(Container inventory, int index, int x, int y, PotionBrewing potionBrewing) { // Paper - custom potion mixes
|
||||
super(inventory, index, x, y);
|
||||
+ this.potionBrewing = potionBrewing; // Paper - custom potion mixes
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack stack) {
|
||||
- return PotionSlot.mayPlaceItem(stack);
|
||||
+ return PotionSlot.mayPlaceItem(stack, this.potionBrewing); // Paper - custom potion mixes
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -172,8 +176,8 @@ public class BrewingStandMenu extends AbstractContainerMenu {
|
||||
super.onTake(player, stack);
|
||||
}
|
||||
|
||||
- public static boolean mayPlaceItem(ItemStack stack) {
|
||||
- return stack.is(Items.POTION) || stack.is(Items.SPLASH_POTION) || stack.is(Items.LINGERING_POTION) || stack.is(Items.GLASS_BOTTLE);
|
||||
+ public static boolean mayPlaceItem(ItemStack stack, PotionBrewing potionBrewing) { // Paper - custom potion mixes
|
||||
+ return stack.is(Items.POTION) || stack.is(Items.SPLASH_POTION) || stack.is(Items.LINGERING_POTION) || stack.is(Items.GLASS_BOTTLE) || potionBrewing.isCustomInput(stack); // Paper - Custom Potion Mixes
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/alchemy/PotionBrewing.java b/src/main/java/net/minecraft/world/item/alchemy/PotionBrewing.java
|
||||
index 50e81e3babd331077eda8daa769eb2b3f99e8ca2..ca01f3344005b295c7ae98f6d5b03f79513b12a4 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/alchemy/PotionBrewing.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/alchemy/PotionBrewing.java
|
||||
@@ -19,6 +19,7 @@ public class PotionBrewing {
|
||||
private final List<Ingredient> containers;
|
||||
private final List<PotionBrewing.Mix<Potion>> potionMixes;
|
||||
private final List<PotionBrewing.Mix<Item>> containerMixes;
|
||||
+ private final it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap<org.bukkit.NamespacedKey, io.papermc.paper.potion.PaperPotionMix> customMixes = new it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap<>(); // Paper - Custom Potion Mixes
|
||||
|
||||
PotionBrewing(List<Ingredient> potionTypes, List<PotionBrewing.Mix<Potion>> potionRecipes, List<PotionBrewing.Mix<Item>> itemRecipes) {
|
||||
this.containers = potionTypes;
|
||||
@@ -27,7 +28,7 @@ public class PotionBrewing {
|
||||
}
|
||||
|
||||
public boolean isIngredient(ItemStack stack) {
|
||||
- return this.isContainerIngredient(stack) || this.isPotionIngredient(stack);
|
||||
+ return this.isContainerIngredient(stack) || this.isPotionIngredient(stack) || this.isCustomIngredient(stack); // Paper - Custom Potion Mixes
|
||||
}
|
||||
|
||||
private boolean isContainer(ItemStack stack) {
|
||||
@@ -71,6 +72,11 @@ public class PotionBrewing {
|
||||
}
|
||||
|
||||
public boolean hasMix(ItemStack input, ItemStack ingredient) {
|
||||
+ // Paper start - Custom Potion Mixes
|
||||
+ if (this.hasCustomMix(input, ingredient)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end - Custom Potion Mixes
|
||||
return this.isContainer(input) && (this.hasContainerMix(input, ingredient) || this.hasPotionMix(input, ingredient));
|
||||
}
|
||||
|
||||
@@ -103,6 +109,13 @@ public class PotionBrewing {
|
||||
if (input.isEmpty()) {
|
||||
return input;
|
||||
} else {
|
||||
+ // Paper start - Custom Potion Mixes
|
||||
+ for (io.papermc.paper.potion.PaperPotionMix mix : this.customMixes.values()) {
|
||||
+ if (mix.input().test(input) && mix.ingredient().test(ingredient)) {
|
||||
+ return mix.result().copy();
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Custom Potion Mixes
|
||||
Optional<Holder<Potion>> optional = input.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY).potion();
|
||||
if (optional.isEmpty()) {
|
||||
return input;
|
||||
@@ -190,6 +203,50 @@ public class PotionBrewing {
|
||||
builder.addMix(Potions.SLOW_FALLING, Items.REDSTONE, Potions.LONG_SLOW_FALLING);
|
||||
}
|
||||
|
||||
+ // Paper start - Custom Potion Mixes
|
||||
+ public boolean isCustomIngredient(ItemStack stack) {
|
||||
+ for (io.papermc.paper.potion.PaperPotionMix mix : this.customMixes.values()) {
|
||||
+ if (mix.ingredient().test(stack)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ public boolean isCustomInput(ItemStack stack) {
|
||||
+ for (io.papermc.paper.potion.PaperPotionMix mix : this.customMixes.values()) {
|
||||
+ if (mix.input().test(stack)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ private boolean hasCustomMix(ItemStack input, ItemStack ingredient) {
|
||||
+ for (io.papermc.paper.potion.PaperPotionMix mix : this.customMixes.values()) {
|
||||
+ if (mix.input().test(input) && mix.ingredient().test(ingredient)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ public void addPotionMix(io.papermc.paper.potion.PotionMix mix) {
|
||||
+ if (this.customMixes.containsKey(mix.getKey())) {
|
||||
+ throw new IllegalArgumentException("Duplicate recipe ignored with ID " + mix.getKey());
|
||||
+ }
|
||||
+ this.customMixes.putAndMoveToFirst(mix.getKey(), new io.papermc.paper.potion.PaperPotionMix(mix));
|
||||
+ }
|
||||
+
|
||||
+ public boolean removePotionMix(org.bukkit.NamespacedKey key) {
|
||||
+ return this.customMixes.remove(key) != null;
|
||||
+ }
|
||||
+
|
||||
+ public PotionBrewing reload(FeatureFlagSet flags) {
|
||||
+ return bootstrap(flags);
|
||||
+ }
|
||||
+ // Paper end - Custom Potion Mixes
|
||||
+
|
||||
public static class Builder {
|
||||
private final List<Ingredient> containers = new ArrayList<>();
|
||||
private final List<PotionBrewing.Mix<Potion>> potionMixes = new ArrayList<>();
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java
|
||||
index c8f9972ad1c2330908cc840d426f29c20b242ca8..a2fafef89d5354e2cb02f5672810909950a57777 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java
|
||||
@@ -315,12 +315,12 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements
|
||||
|
||||
@Override
|
||||
public boolean canPlaceItem(int slot, ItemStack stack) {
|
||||
+ PotionBrewing potionbrewer = this.level != null ? this.level.potionBrewing() : PotionBrewing.EMPTY; // Paper - move up
|
||||
if (slot == 3) {
|
||||
- PotionBrewing potionbrewer = this.level != null ? this.level.potionBrewing() : PotionBrewing.EMPTY;
|
||||
|
||||
return potionbrewer.isIngredient(stack);
|
||||
} else {
|
||||
- return slot == 4 ? stack.is(Items.BLAZE_POWDER) : (stack.is(Items.POTION) || stack.is(Items.SPLASH_POTION) || stack.is(Items.LINGERING_POTION) || stack.is(Items.GLASS_BOTTLE)) && this.getItem(slot).isEmpty();
|
||||
+ return slot == 4 ? stack.is(Items.BLAZE_POWDER) : (stack.is(Items.POTION) || stack.is(Items.SPLASH_POTION) || stack.is(Items.LINGERING_POTION) || stack.is(Items.GLASS_BOTTLE) || potionbrewer.isCustomInput(stack)) && this.getItem(slot).isEmpty(); // Paper - Custom Potion Mixes
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 74d2f6df5a4cdab8a24ca1769c7b7d98ef87bcfe..566ed56de6fcb4dc64e504310b46295466917eee 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -308,6 +308,7 @@ public final class CraftServer implements Server {
|
||||
private final io.papermc.paper.datapack.PaperDatapackManager datapackManager; // Paper
|
||||
public static Exception excessiveVelEx; // Paper - Velocity warnings
|
||||
private final io.papermc.paper.logging.SysoutCatcher sysoutCatcher = new io.papermc.paper.logging.SysoutCatcher(); // Paper
|
||||
+ private final io.papermc.paper.potion.PaperPotionBrewer potionBrewer; // Paper - Custom Potion Mixes
|
||||
|
||||
static {
|
||||
ConfigurationSerialization.registerClass(CraftOfflinePlayer.class);
|
||||
@@ -392,6 +393,7 @@ public final class CraftServer implements Server {
|
||||
if (this.configuration.getBoolean("settings.use-map-color-cache")) {
|
||||
MapPalette.setMapColorCache(new CraftMapColorCache(this.logger));
|
||||
}
|
||||
+ this.potionBrewer = new io.papermc.paper.potion.PaperPotionBrewer(console); // Paper - custom potion mixes
|
||||
datapackManager = new io.papermc.paper.datapack.PaperDatapackManager(console.getPackRepository()); // Paper
|
||||
}
|
||||
|
||||
@@ -3048,5 +3050,9 @@ public final class CraftServer implements Server {
|
||||
return datapackManager;
|
||||
}
|
||||
|
||||
+ @Override
|
||||
+ public io.papermc.paper.potion.PaperPotionBrewer getPotionBrewer() {
|
||||
+ return this.potionBrewer;
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
|
||||
index 139dff90561ac6c51954c6289918a07aeea13a1b..6ba29875d78ede4aa7978ff689e588f7fed11528 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
|
||||
@@ -15,6 +15,11 @@ public interface CraftRecipe extends Recipe {
|
||||
void addToCraftingManager();
|
||||
|
||||
default Ingredient toNMS(RecipeChoice bukkit, boolean requireNotEmpty) {
|
||||
+ // Paper start
|
||||
+ return toIngredient(bukkit, requireNotEmpty);
|
||||
+ }
|
||||
+ static Ingredient toIngredient(RecipeChoice bukkit, boolean requireNotEmpty) {
|
||||
+ // Paper end
|
||||
Ingredient stack;
|
||||
|
||||
if (bukkit == null) {
|
|
@ -1,32 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nassim Jahnke <nassim@njahnke.dev>
|
||||
Date: Wed, 2 Mar 2022 09:45:56 +0100
|
||||
Subject: [PATCH] Force close world loading screen
|
||||
|
||||
Dead players would be stuck in the world loading screen and other players may
|
||||
miss messages and similar sent in the join event if chunk loading is slow.
|
||||
Paper already circumvents falling through the world before chunks are loaded,
|
||||
so we do not need that. The client only needs the chunk it is currently in to
|
||||
be loaded to close the loading screen, so we just send an empty one.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index cff45afb90b232a236683bd569d50aab6b701149..e30ad8c7e85c25f3133bbd23dcbe59ae4c2f8db5 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -394,6 +394,16 @@ public abstract class PlayerList {
|
||||
this.sendActivePlayerEffects(player);
|
||||
// Paper start - Fire PlayerJoinEvent when Player is actually ready; move vehicle into method so it can be called above - short circuit around that code
|
||||
this.onPlayerJoinFinish(player, worldserver1, s1);
|
||||
+ // Paper start - Send empty chunk, so players aren't stuck in the world loading screen with our chunk system not sending chunks when dead
|
||||
+ if (player.isDeadOrDying()) {
|
||||
+ net.minecraft.core.Holder<net.minecraft.world.level.biome.Biome> plains = worldserver1.registryAccess().registryOrThrow(net.minecraft.core.registries.Registries.BIOME)
|
||||
+ .getHolderOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS);
|
||||
+ player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket(
|
||||
+ new net.minecraft.world.level.chunk.EmptyLevelChunk(worldserver1, player.chunkPosition(), plains),
|
||||
+ worldserver1.getLightEngine(), (java.util.BitSet)null, (java.util.BitSet) null)
|
||||
+ );
|
||||
+ }
|
||||
+ // Paper end - Send empty chunk
|
||||
}
|
||||
private void mountSavedVehicle(ServerPlayer player, ServerLevel worldserver1, Optional<CompoundTag> optional) {
|
||||
// Paper end - Fire PlayerJoinEvent when Player is actually ready
|
|
@ -1,57 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nassim Jahnke <nassim@njahnke.dev>
|
||||
Date: Fri, 4 Mar 2022 20:35:19 +0100
|
||||
Subject: [PATCH] Fix falling block spawn methods
|
||||
|
||||
Restores the API behavior from previous versions of the server
|
||||
- Do not call API events
|
||||
- Do not replace the existing block in the world
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.item.FallingBlockEntity <init>(Lnet/minecraft/world/level/Level;DDDLnet/minecraft/world/level/block/state/BlockState;)V
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index ba011d3b56ed0e5019da61ccfec687042d863beb..20a954c8637c2cf9cc6c0c823e33a44f668cc4f6 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -1395,7 +1395,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
Preconditions.checkArgument(material != null, "Material cannot be null");
|
||||
Preconditions.checkArgument(material.isBlock(), "Material.%s must be a block", material);
|
||||
|
||||
- FallingBlockEntity entity = FallingBlockEntity.fall(this.world, BlockPos.containing(location.getX(), location.getY(), location.getZ()), CraftBlockType.bukkitToMinecraft(material).defaultBlockState(), SpawnReason.CUSTOM);
|
||||
+ // Paper start - restore API behavior for spawning falling blocks
|
||||
+ FallingBlockEntity entity = new FallingBlockEntity(this.world, location.getX(), location.getY(), location.getZ(), CraftBlockType.bukkitToMinecraft(material).defaultBlockState()); // Paper
|
||||
+ entity.time = 1;
|
||||
+
|
||||
+ this.world.addFreshEntity(entity, SpawnReason.CUSTOM);
|
||||
+ // Paper end - restore API behavior for spawning falling blocks
|
||||
return (FallingBlock) entity.getBukkitEntity();
|
||||
}
|
||||
|
||||
@@ -1404,7 +1409,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
Preconditions.checkArgument(location != null, "Location cannot be null");
|
||||
Preconditions.checkArgument(data != null, "BlockData cannot be null");
|
||||
|
||||
- FallingBlockEntity entity = FallingBlockEntity.fall(this.world, BlockPos.containing(location.getX(), location.getY(), location.getZ()), ((CraftBlockData) data).getState(), SpawnReason.CUSTOM);
|
||||
+ // Paper start - restore API behavior for spawning falling blocks
|
||||
+ FallingBlockEntity entity = new FallingBlockEntity(this.world, location.getX(), location.getY(), location.getZ(), ((CraftBlockData) data).getState());
|
||||
+ entity.time = 1;
|
||||
+
|
||||
+ this.world.addFreshEntity(entity, SpawnReason.CUSTOM);
|
||||
+ // Paper end - restore API behavior for spawning falling blocks
|
||||
return (FallingBlock) entity.getBukkitEntity();
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java
|
||||
index 481f0c62fcd4435d655cfe2f94f46262b24a7144..37527713b0afa6db19eefd57aaffcb2fe3544ce6 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java
|
||||
@@ -387,7 +387,7 @@ public final class CraftEntityTypes {
|
||||
register(new EntityTypeData<>(EntityType.TNT, TNTPrimed.class, CraftTNTPrimed::new, spawnData -> new PrimedTnt(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), null)));
|
||||
register(new EntityTypeData<>(EntityType.FALLING_BLOCK, FallingBlock.class, CraftFallingBlock::new, spawnData -> {
|
||||
BlockPos pos = BlockPos.containing(spawnData.x(), spawnData.y(), spawnData.z());
|
||||
- return FallingBlockEntity.fall(spawnData.minecraftWorld(), pos, spawnData.world().getBlockState(pos));
|
||||
+ return new FallingBlockEntity(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), spawnData.world().getBlockState(pos)); // Paper - create falling block entities correctly
|
||||
}));
|
||||
register(new EntityTypeData<>(EntityType.FIREWORK_ROCKET, Firework.class, CraftFirework::new, spawnData -> new FireworkRocketEntity(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), net.minecraft.world.item.ItemStack.EMPTY)));
|
||||
register(new EntityTypeData<>(EntityType.EVOKER_FANGS, EvokerFangs.class, CraftEvokerFangs::new, spawnData -> new net.minecraft.world.entity.projectile.EvokerFangs(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), (float) Math.toRadians(spawnData.yaw()), 0, null)));
|
|
@ -1,40 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: EpicKnarvik97 <kristian.knarvik@knett.no>
|
||||
Date: Sat, 5 Mar 2022 20:58:46 +0100
|
||||
Subject: [PATCH] Expose furnace minecart push values
|
||||
|
||||
Adds methods for getting and setting a furnace minecart's push values
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java
|
||||
index 53042b75b45093535d6572239b34c3ff9a72f648..1b41026ab638bb2764b19429706eb0aded5aad12 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java
|
||||
@@ -27,6 +27,28 @@ public class CraftMinecartFurnace extends CraftMinecart implements PoweredMineca
|
||||
this.getHandle().fuel = fuel;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public double getPushX() {
|
||||
+ return getHandle().xPush;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public double getPushZ() {
|
||||
+ return getHandle().zPush;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setPushX(double xPush) {
|
||||
+ getHandle().xPush = xPush;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setPushZ(double zPush) {
|
||||
+ getHandle().zPush = zPush;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftMinecartFurnace";
|
|
@ -1,40 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sat, 19 Feb 2022 19:05:59 -0800
|
||||
Subject: [PATCH] Fix cancelling ProjectileHitEvent for piercing arrows
|
||||
|
||||
Piercing arrows search for multiple entities inside a while
|
||||
loop that is checking the projectile entity's removed state.
|
||||
If the hit event is cancelled on the first entity, the event will
|
||||
be called over and over again inside that while loop until the event
|
||||
is not cancelled. The solution here, is to make use of an
|
||||
already-existing field on AbstractArrow for tracking entities hit by
|
||||
piercing arrows to avoid duplicate damage being applied.
|
||||
|
||||
== AT ==
|
||||
protected net.minecraft.world.entity.projectile.Projectile hitCancelled
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
index 57ebb96707748e90810dc07471f9769f1317df9d..10d30304c8c89b1f2a55be8529035311d1424e44 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
@@ -329,6 +329,19 @@ public abstract class AbstractArrow extends Projectile {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Fix cancelling ProjectileHitEvent for piercing arrows
|
||||
+ @Override
|
||||
+ public ProjectileDeflection preHitTargetOrDeflectSelf(HitResult hitResult) {
|
||||
+ if (hitResult instanceof EntityHitResult entityHitResult && this.hitCancelled && this.getPierceLevel() > 0) {
|
||||
+ if (this.piercingIgnoreEntityIds == null) {
|
||||
+ this.piercingIgnoreEntityIds = new IntOpenHashSet(5);
|
||||
+ }
|
||||
+ this.piercingIgnoreEntityIds.add(entityHitResult.getEntity().getId());
|
||||
+ }
|
||||
+ return super.preHitTargetOrDeflectSelf(hitResult);
|
||||
+ }
|
||||
+ // Paper end - Fix cancelling ProjectileHitEvent for piercing arrows
|
||||
+
|
||||
@Override
|
||||
protected double getDefaultGravity() {
|
||||
return 0.05D;
|
|
@ -1,929 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Tue, 22 Jun 2021 23:41:11 -0400
|
||||
Subject: [PATCH] More Projectile API
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.projectile.FishingHook timeUntilLured
|
||||
public net.minecraft.world.entity.projectile.FishingHook fishAngle
|
||||
public net.minecraft.world.entity.projectile.ShulkerBullet targetDeltaX
|
||||
public net.minecraft.world.entity.projectile.ShulkerBullet targetDeltaY
|
||||
public net.minecraft.world.entity.projectile.ShulkerBullet targetDeltaZ
|
||||
public net.minecraft.world.entity.projectile.ShulkerBullet currentMoveDirection
|
||||
public net.minecraft.world.entity.projectile.ShulkerBullet flightSteps
|
||||
public net.minecraft.world.entity.projectile.AbstractArrow soundEvent
|
||||
public net.minecraft.world.entity.projectile.AbstractArrow setPickupItemStack(Lnet/minecraft/world/item/ItemStack;)V
|
||||
public net.minecraft.world.entity.projectile.ThrownTrident dealtDamage
|
||||
public net.minecraft.world.entity.projectile.Arrow NO_EFFECT_COLOR
|
||||
public net.minecraft.world.entity.projectile.Projectile hasBeenShot
|
||||
public net.minecraft.world.entity.projectile.Projectile leftOwner
|
||||
public net.minecraft.world.entity.projectile.Projectile preOnHit(Lnet/minecraft/world/phys/HitResult;)V
|
||||
public net.minecraft.world.entity.projectile.Projectile canHitEntity(Lnet/minecraft/world/entity/Entity;)Z
|
||||
public net.minecraft.world.entity.projectile.FireworkRocketEntity getDefaultItem()Lnet/minecraft/world/item/ItemStack;
|
||||
public net.minecraft.world.item.CrossbowItem FIREWORK_POWER
|
||||
|
||||
Co-authored-by: Nassim Jahnke <nassim@njahnke.dev>
|
||||
Co-authored-by: SoSeDiK <mrsosedik@gmail.com>
|
||||
Co-authored-by: MelnCat <melncatuwu@gmail.com>
|
||||
Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
index 5b7734020b496ade3740d92908ad2d399bfd55e6..e70ca1b2e6fbbc1f20e65429298d01b4ebd2dd29 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
@@ -414,13 +414,18 @@ public class FishingHook extends Projectile {
|
||||
}
|
||||
} else {
|
||||
// CraftBukkit start - logic to modify fishing wait time
|
||||
- this.timeUntilLured = Mth.nextInt(this.random, this.minWaitTime, this.maxWaitTime);
|
||||
- this.timeUntilLured -= (this.applyLure) ? (this.lureSpeed >= this.maxWaitTime ? this.timeUntilLured - 1 : this.lureSpeed ) : 0; // Paper - Fix Lure infinite loop
|
||||
+ this.resetTimeUntilLured(); // Paper - more projectile api - extract time until lured reset logic
|
||||
// CraftBukkit end
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+ // Paper start - more projectile api - extract time until lured reset logic
|
||||
+ public void resetTimeUntilLured() {
|
||||
+ this.timeUntilLured = Mth.nextInt(this.random, this.minWaitTime, this.maxWaitTime);
|
||||
+ this.timeUntilLured -= (this.applyLure) ? (this.lureSpeed >= this.maxWaitTime ? this.timeUntilLured - 1 : this.lureSpeed ) : 0; // Paper - Fix Lure infinite loop
|
||||
+ }
|
||||
+ // Paper end - more projectile api - extract time until lured reset logic
|
||||
|
||||
public boolean calculateOpenWater(BlockPos pos) {
|
||||
FishingHook.OpenWaterType entityfishinghook_waterposition = FishingHook.OpenWaterType.INVALID;
|
||||
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 d27e17ebf25cd842a943cf82bde05b2248c74414..06ca07edef062f21c51860146086297ca345104d 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
|
||||
@@ -190,7 +190,7 @@ public abstract class Projectile extends Entity implements TraceableEntity {
|
||||
}
|
||||
|
||||
// CraftBukkit start - call projectile hit event
|
||||
- protected ProjectileDeflection preHitTargetOrDeflectSelf(HitResult movingobjectposition) {
|
||||
+ public ProjectileDeflection preHitTargetOrDeflectSelf(HitResult movingobjectposition) { // Paper - protected -> public
|
||||
org.bukkit.event.entity.ProjectileHitEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition);
|
||||
this.hitCancelled = event != null && event.isCancelled();
|
||||
if (movingobjectposition.getType() == HitResult.Type.BLOCK || !this.hitCancelled) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
|
||||
index cb34cc9443da56c0497c7a0192c8b8363c3426fe..58dc69fe319027c2b9ecfb9caf272368e81081df 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
|
||||
@@ -102,6 +102,11 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
|
||||
@Override
|
||||
protected void onHit(HitResult hitResult) {
|
||||
super.onHit(hitResult);
|
||||
+ // Paper start - More projectile API
|
||||
+ this.splash(hitResult);
|
||||
+ }
|
||||
+ public void splash(@Nullable HitResult hitResult) {
|
||||
+ // Paper end - More projectile API
|
||||
if (!this.level().isClientSide) {
|
||||
ItemStack itemstack = this.getItem();
|
||||
PotionContents potioncontents = (PotionContents) itemstack.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY);
|
||||
@@ -113,7 +118,7 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
|
||||
if (this.isLingering()) {
|
||||
showParticles = this.makeAreaOfEffectCloud(potioncontents, hitResult); // CraftBukkit - Pass MovingObjectPosition // Paper
|
||||
} else {
|
||||
- showParticles = this.applySplash(potioncontents.getAllEffects(), hitResult.getType() == HitResult.Type.ENTITY ? ((EntityHitResult) hitResult).getEntity() : null, hitResult); // CraftBukkit - Pass MovingObjectPosition // Paper
|
||||
+ showParticles = this.applySplash(potioncontents.getAllEffects(), hitResult != null && hitResult.getType() == HitResult.Type.ENTITY ? ((EntityHitResult) hitResult).getEntity() : null, hitResult); // CraftBukkit - Pass MovingObjectPosition // Paper - More projectile API
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,7 +180,7 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
|
||||
|
||||
}
|
||||
|
||||
- private boolean applySplash(Iterable<MobEffectInstance> iterable, @Nullable Entity entity, HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - Fix potions splash events
|
||||
+ private boolean applySplash(Iterable<MobEffectInstance> iterable, @Nullable Entity entity, @Nullable HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - Fix potions splash events & More projectile API
|
||||
AABB axisalignedbb = this.getBoundingBox().inflate(4.0D, 2.0D, 4.0D);
|
||||
List<net.minecraft.world.entity.LivingEntity> list = this.level().getEntitiesOfClass(net.minecraft.world.entity.LivingEntity.class, axisalignedbb);
|
||||
Map<LivingEntity, Double> affected = new HashMap<LivingEntity, Double>(); // CraftBukkit
|
||||
@@ -253,7 +258,7 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
|
||||
|
||||
}
|
||||
|
||||
- private boolean makeAreaOfEffectCloud(PotionContents potioncontents, HitResult position) { // CraftBukkit - Pass MovingObjectPosition
|
||||
+ private boolean makeAreaOfEffectCloud(PotionContents potioncontents, @Nullable HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - More projectile API
|
||||
AreaEffectCloud entityareaeffectcloud = new AreaEffectCloud(this.level(), this.getX(), this.getY(), this.getZ());
|
||||
Entity entity = this.getOwner();
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java b/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java
|
||||
index 91c2d0b40d3fca86938cd454e1415a4eea3df7c7..de4fb2654c7895cfd83ad694455ee56cb708c2f2 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java
|
||||
@@ -17,4 +17,65 @@ public abstract class AbstractProjectile extends CraftEntity implements Projecti
|
||||
@Override
|
||||
public void setBounce(boolean doesBounce) {}
|
||||
|
||||
+ // Paper start - More projectile API
|
||||
+ @Override
|
||||
+ public boolean hasLeftShooter() {
|
||||
+ return this.getHandle().leftOwner;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setHasLeftShooter(boolean leftShooter) {
|
||||
+ this.getHandle().leftOwner = leftShooter;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasBeenShot() {
|
||||
+ return this.getHandle().hasBeenShot;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setHasBeenShot(boolean beenShot) {
|
||||
+ this.getHandle().hasBeenShot = beenShot;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean canHitEntity(org.bukkit.entity.Entity entity) {
|
||||
+ return this.getHandle().canHitEntity(((CraftEntity) entity).getHandle());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void hitEntity(org.bukkit.entity.Entity entity) {
|
||||
+ this.getHandle().preHitTargetOrDeflectSelf(new net.minecraft.world.phys.EntityHitResult(((CraftEntity) entity).getHandle()));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void hitEntity(org.bukkit.entity.Entity entity, org.bukkit.util.Vector vector) {
|
||||
+ this.getHandle().preHitTargetOrDeflectSelf(new net.minecraft.world.phys.EntityHitResult(((CraftEntity) entity).getHandle(), new net.minecraft.world.phys.Vec3(vector.getX(), vector.getY(), vector.getZ())));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public net.minecraft.world.entity.projectile.Projectile getHandle() {
|
||||
+ return (net.minecraft.world.entity.projectile.Projectile) entity;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public final org.bukkit.projectiles.ProjectileSource getShooter() {
|
||||
+ return this.getHandle().projectileSource;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public final void setShooter(org.bukkit.projectiles.ProjectileSource shooter) {
|
||||
+ if (shooter instanceof CraftEntity craftEntity) {
|
||||
+ this.getHandle().setOwner(craftEntity.getHandle());
|
||||
+ } else {
|
||||
+ this.getHandle().setOwner(null);
|
||||
+ }
|
||||
+ this.getHandle().projectileSource = shooter;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public java.util.UUID getOwnerUniqueId() {
|
||||
+ return this.getHandle().ownerUUID;
|
||||
+ }
|
||||
+ // Paper end - More projectile API
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java
|
||||
index 329ca9c743a7f2feeabbfb769ff9a71f60165006..faa08ad912fa43e7a6c5a2359e23c04c059c5edf 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java
|
||||
@@ -58,20 +58,7 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr
|
||||
this.getHandle().setCritArrow(critical);
|
||||
}
|
||||
|
||||
- @Override
|
||||
- public ProjectileSource getShooter() {
|
||||
- return this.getHandle().projectileSource;
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public void setShooter(ProjectileSource shooter) {
|
||||
- if (shooter instanceof Entity) {
|
||||
- this.getHandle().setOwner(((CraftEntity) shooter).getHandle());
|
||||
- } else {
|
||||
- this.getHandle().setOwner(null);
|
||||
- }
|
||||
- this.getHandle().projectileSource = shooter;
|
||||
- }
|
||||
+ // Paper - moved to AbstractProjectile
|
||||
|
||||
@Override
|
||||
public boolean isInBlock() {
|
||||
@@ -130,6 +117,7 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr
|
||||
|
||||
@Override
|
||||
public ItemStack getWeapon() {
|
||||
+ if (this.getHandle().getWeaponItem() == null) return null; // Paper - fix NPE
|
||||
return CraftItemStack.asBukkitCopy(this.getHandle().getWeaponItem());
|
||||
}
|
||||
|
||||
@@ -149,4 +137,37 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr
|
||||
public String toString() {
|
||||
return "CraftArrow";
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public CraftItemStack getItemStack() {
|
||||
+ return CraftItemStack.asCraftMirror(this.getHandle().getPickupItem());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setItemStack(final ItemStack stack) {
|
||||
+ Preconditions.checkArgument(stack != null, "ItemStack cannot be null");
|
||||
+ this.getHandle().setPickupItemStack(CraftItemStack.asNMSCopy(stack));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setLifetimeTicks(int ticks) {
|
||||
+ this.getHandle().life = ticks;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getLifetimeTicks() {
|
||||
+ return this.getHandle().life;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.Sound getHitSound() {
|
||||
+ return org.bukkit.craftbukkit.CraftSound.minecraftToBukkit(this.getHandle().soundEvent);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setHitSound(org.bukkit.Sound sound) {
|
||||
+ this.getHandle().setSoundEvent(org.bukkit.craftbukkit.CraftSound.bukkitToMinecraft(sound));
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java
|
||||
index 81f5e1d866128af8fb2acc13aca715580fdf9886..88f2a9f310f30a08893f3fa68af13a54cf72fa7f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java
|
||||
@@ -125,7 +125,7 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud
|
||||
|
||||
@Override
|
||||
public Color getColor() {
|
||||
- return Color.fromRGB(this.getHandle().potionContents.getColor());
|
||||
+ return Color.fromRGB(this.getHandle().potionContents.getColor() & 0x00FFFFFF); // Paper - skip alpha channel
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -143,7 +143,7 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud
|
||||
this.removeCustomEffect(effect.getType());
|
||||
}
|
||||
this.getHandle().addEffect(CraftPotionUtil.fromBukkit(effect));
|
||||
- this.getHandle().updateColor();
|
||||
+ // this.getHandle().updateColor(); // Paper - already done above
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud
|
||||
public void clearCustomEffects() {
|
||||
PotionContents old = this.getHandle().potionContents;
|
||||
this.getHandle().setPotionContents(new PotionContents(old.potion(), old.customColor(), List.of()));
|
||||
- this.getHandle().updateColor();
|
||||
+ // this.getHandle().updateColor(); // Paper - already done above
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java
|
||||
index 5232fbef0d014edd32a5d18d4a1500ab215313f5..071be344c3265a0cd52b31ffbb02ff7a70bdf231 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java
|
||||
@@ -43,7 +43,7 @@ public class CraftArrow extends CraftAbstractArrow implements Arrow {
|
||||
this.removeCustomEffect(effect.getType());
|
||||
}
|
||||
this.getHandle().addEffect(CraftPotionUtil.fromBukkit(effect));
|
||||
- this.getHandle().updateColor();
|
||||
+ // this.getHandle().updateColor(); // Paper - already done above
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public class CraftArrow extends CraftAbstractArrow implements Arrow {
|
||||
public void clearCustomEffects() {
|
||||
PotionContents old = this.getHandle().getPotionContents();
|
||||
this.getHandle().setPotionContents(new PotionContents(old.potion(), old.customColor(), List.of()));
|
||||
- this.getHandle().updateColor();
|
||||
+ // this.getHandle().updateColor(); // Paper - already done above
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -117,16 +117,17 @@ public class CraftArrow extends CraftAbstractArrow implements Arrow {
|
||||
|
||||
@Override
|
||||
public void setColor(Color color) {
|
||||
- int colorRGB = (color == null) ? -1 : color.asRGB();
|
||||
+ int colorRGB = (color == null) ? net.minecraft.world.entity.projectile.Arrow.NO_EFFECT_COLOR : color.asARGB(); // Paper
|
||||
PotionContents old = this.getHandle().getPotionContents();
|
||||
this.getHandle().setPotionContents(new PotionContents(old.potion(), Optional.of(colorRGB), old.customEffects()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor() {
|
||||
- if (this.getHandle().getColor() <= -1) {
|
||||
+ int color = this.getHandle().getColor(); // Paper
|
||||
+ if (color == net.minecraft.world.entity.projectile.Arrow.NO_EFFECT_COLOR) { // Paper
|
||||
return null;
|
||||
}
|
||||
- return Color.fromRGB(this.getHandle().getColor());
|
||||
+ return Color.fromARGB(color); // Paper
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java
|
||||
index 37527713b0afa6db19eefd57aaffcb2fe3544ce6..46a4f31e2b6eee6f8dc5f8fccd7de4c48a698b61 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java
|
||||
@@ -389,7 +389,7 @@ public final class CraftEntityTypes {
|
||||
BlockPos pos = BlockPos.containing(spawnData.x(), spawnData.y(), spawnData.z());
|
||||
return new FallingBlockEntity(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), spawnData.world().getBlockState(pos)); // Paper - create falling block entities correctly
|
||||
}));
|
||||
- register(new EntityTypeData<>(EntityType.FIREWORK_ROCKET, Firework.class, CraftFirework::new, spawnData -> new FireworkRocketEntity(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), net.minecraft.world.item.ItemStack.EMPTY)));
|
||||
+ register(new EntityTypeData<>(EntityType.FIREWORK_ROCKET, Firework.class, CraftFirework::new, spawnData -> new FireworkRocketEntity(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), FireworkRocketEntity.getDefaultItem()))); // Paper - pass correct default to rocket for data storage
|
||||
register(new EntityTypeData<>(EntityType.EVOKER_FANGS, EvokerFangs.class, CraftEvokerFangs::new, spawnData -> new net.minecraft.world.entity.projectile.EvokerFangs(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), (float) Math.toRadians(spawnData.yaw()), 0, null)));
|
||||
register(new EntityTypeData<>(EntityType.COMMAND_BLOCK_MINECART, CommandMinecart.class, CraftMinecartCommand::new, spawnData -> new MinecartCommandBlock(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z())));
|
||||
register(new EntityTypeData<>(EntityType.MINECART, RideableMinecart.class, CraftMinecartRideable::new, spawnData -> new Minecart(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z())));
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java
|
||||
index 1b084d63bdbb24dad45d28eed1693eb6e26e24dc..43d7bea201a52cfeacf60c75caa28dfd2c4ff164 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java
|
||||
@@ -34,20 +34,7 @@ public class CraftFireball extends AbstractProjectile implements Fireball {
|
||||
this.getHandle().bukkitYield = yield;
|
||||
}
|
||||
|
||||
- @Override
|
||||
- public ProjectileSource getShooter() {
|
||||
- return this.getHandle().projectileSource;
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public void setShooter(ProjectileSource shooter) {
|
||||
- if (shooter instanceof CraftLivingEntity) {
|
||||
- this.getHandle().setOwner(((CraftLivingEntity) shooter).getHandle());
|
||||
- } else {
|
||||
- this.getHandle().setOwner(null);
|
||||
- }
|
||||
- this.getHandle().projectileSource = shooter;
|
||||
- }
|
||||
+ // Paper - moved to AbstractProjectile
|
||||
|
||||
@Override
|
||||
public Vector getDirection() {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
|
||||
index c9e15a9d82dee935293b2e7e233f5b9b2d822448..2d54cf6f3d9696c55335f0a2057025e2034d4e13 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
|
||||
@@ -15,24 +15,26 @@ import org.bukkit.inventory.meta.FireworkMeta;
|
||||
public class CraftFirework extends CraftProjectile implements Firework {
|
||||
|
||||
private final Random random = new Random();
|
||||
- private final CraftItemStack item;
|
||||
+ //private CraftItemStack item; // Paper - Remove usage, not accurate representation of current item.
|
||||
|
||||
public CraftFirework(CraftServer server, FireworkRocketEntity entity) {
|
||||
super(server, entity);
|
||||
|
||||
- ItemStack item = this.getHandle().getEntityData().get(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM);
|
||||
-
|
||||
- if (item.isEmpty()) {
|
||||
- item = new ItemStack(Items.FIREWORK_ROCKET);
|
||||
- this.getHandle().getEntityData().set(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM, item);
|
||||
- }
|
||||
-
|
||||
- this.item = CraftItemStack.asCraftMirror(item);
|
||||
-
|
||||
- // Ensure the item is a firework...
|
||||
- if (this.item.getType() != Material.FIREWORK_ROCKET) {
|
||||
- this.item.setType(Material.FIREWORK_ROCKET);
|
||||
- }
|
||||
+ // Paper start - Expose firework item directly
|
||||
+// ItemStack item = this.getHandle().getEntityData().get(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM);
|
||||
+//
|
||||
+// if (item.isEmpty()) {
|
||||
+// item = new ItemStack(Items.FIREWORK_ROCKET);
|
||||
+// this.getHandle().getEntityData().set(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM, item);
|
||||
+// }
|
||||
+//
|
||||
+// this.item = CraftItemStack.asCraftMirror(item);
|
||||
+//
|
||||
+// // Ensure the item is a firework...
|
||||
+// if (this.item.getType() != Material.FIREWORK_ROCKET) {
|
||||
+// this.item.setType(Material.FIREWORK_ROCKET);
|
||||
+// }
|
||||
+ // Paper end - Expose firework item directly
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -47,12 +49,12 @@ public class CraftFirework extends CraftProjectile implements Firework {
|
||||
|
||||
@Override
|
||||
public FireworkMeta getFireworkMeta() {
|
||||
- return (FireworkMeta) this.item.getItemMeta();
|
||||
+ return (FireworkMeta) CraftItemStack.getItemMeta(this.getHandle().getEntityData().get(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM), org.bukkit.inventory.ItemType.FIREWORK_ROCKET); // Paper - Expose firework item directly
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFireworkMeta(FireworkMeta meta) {
|
||||
- this.item.setItemMeta(meta);
|
||||
+ applyFireworkEffect(meta); // Paper - Expose firework item directly
|
||||
|
||||
// Copied from EntityFireworks constructor, update firework lifetime/power
|
||||
this.getHandle().lifetime = 10 * (1 + meta.getPower()) + this.random.nextInt(6) + this.random.nextInt(7);
|
||||
@@ -136,4 +138,46 @@ public class CraftFirework extends CraftProjectile implements Firework {
|
||||
return getHandle().spawningEntity;
|
||||
}
|
||||
// Paper end
|
||||
+ // Paper start - Expose firework item directly + manually setting flight
|
||||
+ @Override
|
||||
+ public org.bukkit.inventory.ItemStack getItem() {
|
||||
+ return CraftItemStack.asBukkitCopy(this.getHandle().getItem());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setItem(org.bukkit.inventory.ItemStack itemStack) {
|
||||
+ FireworkMeta meta = getFireworkMeta();
|
||||
+ ItemStack nmsItem = itemStack == null ? FireworkRocketEntity.getDefaultItem() : CraftItemStack.asNMSCopy(itemStack);
|
||||
+ this.getHandle().getEntityData().set(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM, nmsItem);
|
||||
+
|
||||
+ applyFireworkEffect(meta);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getTicksFlown() {
|
||||
+ return this.getHandle().life;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setTicksFlown(int ticks) {
|
||||
+ this.getHandle().life = ticks;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getTicksToDetonate() {
|
||||
+ return this.getHandle().lifetime;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setTicksToDetonate(int ticks) {
|
||||
+ this.getHandle().lifetime = ticks;
|
||||
+ }
|
||||
+
|
||||
+ void applyFireworkEffect(FireworkMeta meta) {
|
||||
+ ItemStack item = this.getHandle().getItem();
|
||||
+ CraftItemStack.applyMetaToItem(item, meta);
|
||||
+
|
||||
+ this.getHandle().getEntityData().set(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM, item);
|
||||
+ }
|
||||
+ // Paper end - Expose firework item directly + manually setting flight
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java
|
||||
index 6e2f91423371ead9890095cf4b1e2299c4dcba28..9d8f4b7176e60180565e3134a14ecf19060f2621 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java
|
||||
@@ -196,4 +196,42 @@ public class CraftFishHook extends CraftProjectile implements FishHook {
|
||||
public HookState getState() {
|
||||
return HookState.values()[this.getHandle().currentState.ordinal()];
|
||||
}
|
||||
+ // Paper start - More FishHook API
|
||||
+ @Override
|
||||
+ public int getWaitTime() {
|
||||
+ return this.getHandle().timeUntilLured;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setWaitTime(int ticks) {
|
||||
+ this.getHandle().timeUntilLured = ticks;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getTimeUntilBite() {
|
||||
+ return this.getHandle().timeUntilHooked;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setTimeUntilBite(final int ticks) {
|
||||
+ com.google.common.base.Preconditions.checkArgument(ticks >= 1, "Cannot set time until bite to less than 1 (%s<1)", ticks);
|
||||
+ final FishingHook hook = this.getHandle();
|
||||
+
|
||||
+ // Reset the fish angle hook only when this call "enters" the fish into the lure stage.
|
||||
+ final boolean alreadyInLuringPhase = hook.timeUntilHooked > 0 && hook.timeUntilLured <= 0;
|
||||
+ if (!alreadyInLuringPhase) {
|
||||
+ hook.fishAngle = net.minecraft.util.Mth.nextFloat(hook.random, hook.minLureAngle, hook.maxLureAngle);
|
||||
+ hook.timeUntilLured = 0;
|
||||
+ }
|
||||
+
|
||||
+ hook.timeUntilHooked = ticks;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void resetFishingState() {
|
||||
+ final FishingHook hook = this.getHandle();
|
||||
+ hook.resetTimeUntilLured();
|
||||
+ hook.timeUntilHooked = 0; // Reset time until hooked, will be repopulated once lured time is ticked down.
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index 0ed2910e64b6efdb4180c5bc23a146aced87c3d9..6350d4729fa3fbd9b15f1150cb4322f1c685044a 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -570,8 +570,15 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
- @SuppressWarnings("unchecked")
|
||||
public <T extends Projectile> T launchProjectile(Class<? extends T> projectile, Vector velocity) {
|
||||
+ // Paper start - launchProjectile consumer
|
||||
+ return this.launchProjectile(projectile, velocity, null);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ @SuppressWarnings("unchecked")
|
||||
+ public <T extends Projectile> T launchProjectile(Class<? extends T> projectile, Vector velocity, java.util.function.Consumer<? super T> function) {
|
||||
+ // Paper end - launchProjectile consumer
|
||||
Preconditions.checkState(!this.getHandle().generation, "Cannot launch projectile during world generation");
|
||||
|
||||
net.minecraft.world.level.Level world = ((CraftWorld) this.getWorld()).getHandle();
|
||||
@@ -597,7 +604,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
} else {
|
||||
launch = new net.minecraft.world.entity.projectile.Arrow(world, this.getHandle(), new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.ARROW), null);
|
||||
}
|
||||
- ((net.minecraft.world.entity.projectile.AbstractArrow) launch).shootFromRotation(this.getHandle(), this.getHandle().getXRot(), this.getHandle().getYRot(), 0.0F, 3.0F, 1.0F); // ItemBow
|
||||
+ ((net.minecraft.world.entity.projectile.AbstractArrow) launch).shootFromRotation(this.getHandle(), this.getHandle().getXRot(), this.getHandle().getYRot(), 0.0F, Trident.class.isAssignableFrom(projectile) ? net.minecraft.world.item.TridentItem.SHOOT_POWER : 3.0F, 1.0F); // ItemBow // Paper - see TridentItem
|
||||
} else if (ThrownPotion.class.isAssignableFrom(projectile)) {
|
||||
if (LingeringPotion.class.isAssignableFrom(projectile)) {
|
||||
launch = new net.minecraft.world.entity.projectile.ThrownPotion(world, this.getHandle());
|
||||
@@ -656,8 +663,26 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
} else if (Firework.class.isAssignableFrom(projectile)) {
|
||||
Location location = this.getEyeLocation();
|
||||
|
||||
- launch = new FireworkRocketEntity(world, net.minecraft.world.item.ItemStack.EMPTY, this.getHandle());
|
||||
- launch.moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
+ // Paper start - see CrossbowItem
|
||||
+ launch = new FireworkRocketEntity(world, FireworkRocketEntity.getDefaultItem(), this.getHandle(), location.getX(), location.getY() - 0.15F, location.getZ(), true); // Paper - pass correct default to rocket for data storage & see CrossbowItem for regular launch without elytra boost
|
||||
+
|
||||
+ // Lifted from net.minecraft.world.item.ProjectileWeaponItem.shoot
|
||||
+ float f2 = /* net.minecraft.world.item.enchantment.EnchantmentHelper.processProjectileSpread((ServerLevel) world, new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.CROSSBOW), this.getHandle(), 0.0F); */ 0; // Just shortcut this to 0, no need to do any calculations on a non existing stack
|
||||
+ int projectileSize = 1;
|
||||
+ int i = 0;
|
||||
+
|
||||
+ float f3 = projectileSize == 1 ? 0.0F : 2.0F * f2 / (float) (projectileSize - 1);
|
||||
+ float f4 = (float) ((projectileSize - 1) % 2) * f3 / 2.0F;
|
||||
+ float f5 = 1.0F;
|
||||
+ float yaw = f4 + f5 * (float) ((i + 1) / 2) * f3;
|
||||
+
|
||||
+ // Lifted from net.minecraft.world.item.CrossbowItem.shootProjectile
|
||||
+ Vec3 vec3 = this.getHandle().getUpVector(1.0F);
|
||||
+ org.joml.Quaternionf quaternionf = new org.joml.Quaternionf().setAngleAxis((double)(yaw * (float) (Math.PI / 180.0)), vec3.x, vec3.y, vec3.z);
|
||||
+ Vec3 vec32 = this.getHandle().getViewVector(1.0F);
|
||||
+ org.joml.Vector3f vector3f = vec32.toVector3f().rotate(quaternionf);
|
||||
+ ((FireworkRocketEntity) launch).shoot((double)vector3f.x(), (double)vector3f.y(), (double)vector3f.z(), net.minecraft.world.item.CrossbowItem.FIREWORK_POWER, 1.0F);
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
Preconditions.checkArgument(launch != null, "Projectile (%s) not supported", projectile.getName());
|
||||
@@ -665,6 +690,11 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
if (velocity != null) {
|
||||
((T) launch.getBukkitEntity()).setVelocity(velocity);
|
||||
}
|
||||
+ // Paper start - launchProjectile consumer
|
||||
+ if (function != null) {
|
||||
+ function.accept((T) launch.getBukkitEntity());
|
||||
+ }
|
||||
+ // Paper end - launchProjectile consumer
|
||||
|
||||
world.addFreshEntity(launch);
|
||||
return (T) launch.getBukkitEntity();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlamaSpit.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlamaSpit.java
|
||||
index 70cbc6c668c60e9d608ca7013b72f9b916c05c2d..47633f05b4fab1dcabc2117e7645fe6d6949622a 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlamaSpit.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlamaSpit.java
|
||||
@@ -20,13 +20,5 @@ public class CraftLlamaSpit extends AbstractProjectile implements LlamaSpit {
|
||||
return "CraftLlamaSpit";
|
||||
}
|
||||
|
||||
- @Override
|
||||
- public ProjectileSource getShooter() {
|
||||
- return (this.getHandle().getOwner() != null) ? (ProjectileSource) this.getHandle().getOwner().getBukkitEntity() : null;
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public void setShooter(ProjectileSource source) {
|
||||
- this.getHandle().setOwner((source != null) ? ((CraftLivingEntity) source).getHandle() : null);
|
||||
- }
|
||||
+ // Paper - moved to AbstractProjectile
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftProjectile.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftProjectile.java
|
||||
index 696fdfa723aa896a67946f862d7c6890f7f7ab17..4f1fa7dec78970bdfc184d3c1f1632dc9d75a574 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftProjectile.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftProjectile.java
|
||||
@@ -10,20 +10,7 @@ public abstract class CraftProjectile extends AbstractProjectile implements Proj
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
- @Override
|
||||
- public ProjectileSource getShooter() {
|
||||
- return this.getHandle().projectileSource;
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public void setShooter(ProjectileSource shooter) {
|
||||
- if (shooter instanceof CraftLivingEntity) {
|
||||
- this.getHandle().setOwner((LivingEntity) ((CraftLivingEntity) shooter).entity);
|
||||
- } else {
|
||||
- this.getHandle().setOwner(null);
|
||||
- }
|
||||
- this.getHandle().projectileSource = shooter;
|
||||
- }
|
||||
+ // Paper - moved to AbstractProjectile
|
||||
|
||||
@Override
|
||||
public net.minecraft.world.entity.projectile.Projectile getHandle() {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java
|
||||
index d685d09cae5f862c0004f148298c800736d2139e..b3797a43eeee11cb7ae0774d61bd5f195d0aa3ad 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java
|
||||
@@ -12,31 +12,56 @@ public class CraftShulkerBullet extends AbstractProjectile implements ShulkerBul
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
+ // Paper - moved to AbstractProjectile
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.entity.Entity getTarget() {
|
||||
+ return this.getHandle().getTarget() != null ? this.getHandle().getTarget().getBukkitEntity() : null;
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
- public ProjectileSource getShooter() {
|
||||
- return this.getHandle().projectileSource;
|
||||
+ public void setTarget(org.bukkit.entity.Entity target) {
|
||||
+ Preconditions.checkState(!this.getHandle().generation, "Cannot set target during world generation");
|
||||
+
|
||||
+ this.getHandle().setTarget(target == null ? null : ((CraftEntity) target).getHandle());
|
||||
}
|
||||
|
||||
@Override
|
||||
- public void setShooter(ProjectileSource shooter) {
|
||||
- if (shooter instanceof Entity) {
|
||||
- this.getHandle().setOwner(((CraftEntity) shooter).getHandle());
|
||||
- } else {
|
||||
- this.getHandle().setOwner(null);
|
||||
+ public org.bukkit.util.Vector getTargetDelta() {
|
||||
+ net.minecraft.world.entity.projectile.ShulkerBullet bullet = this.getHandle();
|
||||
+ return new org.bukkit.util.Vector(bullet.targetDeltaX, bullet.targetDeltaY, bullet.targetDeltaZ);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setTargetDelta(org.bukkit.util.Vector vector) {
|
||||
+ net.minecraft.world.entity.projectile.ShulkerBullet bullet = this.getHandle();
|
||||
+ bullet.targetDeltaX = vector.getX();
|
||||
+ bullet.targetDeltaY = vector.getY();
|
||||
+ bullet.targetDeltaZ = vector.getZ();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.block.BlockFace getCurrentMovementDirection() {
|
||||
+ net.minecraft.core.Direction dir = this.getHandle().currentMoveDirection;
|
||||
+ if (dir == null) {
|
||||
+ return null; // random dir
|
||||
}
|
||||
- this.getHandle().projectileSource = shooter;
|
||||
+ return org.bukkit.craftbukkit.block.CraftBlock.notchToBlockFace(dir);
|
||||
}
|
||||
|
||||
@Override
|
||||
- public org.bukkit.entity.Entity getTarget() {
|
||||
- return this.getHandle().getTarget() != null ? this.getHandle().getTarget().getBukkitEntity() : null;
|
||||
+ public void setCurrentMovementDirection(org.bukkit.block.BlockFace movementDirection) {
|
||||
+ this.getHandle().currentMoveDirection = org.bukkit.craftbukkit.block.CraftBlock.blockFaceToNotch(movementDirection);
|
||||
}
|
||||
|
||||
@Override
|
||||
- public void setTarget(org.bukkit.entity.Entity target) {
|
||||
- Preconditions.checkState(!this.getHandle().generation, "Cannot set target during world generation");
|
||||
+ public int getFlightSteps() {
|
||||
+ return this.getHandle().flightSteps;
|
||||
+ }
|
||||
|
||||
- this.getHandle().setTarget(target == null ? null : ((CraftEntity) target).getHandle());
|
||||
+ @Override
|
||||
+ public void setFlightSteps(int steps) {
|
||||
+ this.getHandle().flightSteps = steps;
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java
|
||||
index d67a80161b3e7c1fe02a6ed9d341c00dc7c2847a..f6fa6f1ac50b757dd3bc9a8dee9f6085446182c8 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java
|
||||
@@ -36,11 +36,31 @@ public class CraftThrownPotion extends CraftThrowableProjectile implements Throw
|
||||
@Override
|
||||
public void setItem(ItemStack item) {
|
||||
Preconditions.checkArgument(item != null, "ItemStack cannot be null");
|
||||
- Preconditions.checkArgument(item.getType() == Material.LINGERING_POTION || item.getType() == Material.SPLASH_POTION, "ItemStack material must be Material.LINGERING_POTION or Material.SPLASH_POTION but was Material.%s", item.getType());
|
||||
+ // Preconditions.checkArgument(item.getType() == Material.LINGERING_POTION || item.getType() == Material.SPLASH_POTION, "ItemStack material must be Material.LINGERING_POTION or Material.SPLASH_POTION but was Material.%s", item.getType()); // Paper - Projectile API
|
||||
+ org.bukkit.inventory.meta.PotionMeta meta = (item.getType() == Material.LINGERING_POTION || item.getType() == Material.SPLASH_POTION) ? null : this.getPotionMeta(); // Paper - Projectile API
|
||||
|
||||
this.getHandle().setItem(CraftItemStack.asNMSCopy(item));
|
||||
+ if (meta != null) this.setPotionMeta(meta); // Paper - Projectile API
|
||||
}
|
||||
|
||||
+ // Paper start - Projectile API
|
||||
+ @Override
|
||||
+ public org.bukkit.inventory.meta.PotionMeta getPotionMeta() {
|
||||
+ return (org.bukkit.inventory.meta.PotionMeta) CraftItemStack.getItemMeta(this.getHandle().getItem(), org.bukkit.inventory.ItemType.SPLASH_POTION);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setPotionMeta(org.bukkit.inventory.meta.PotionMeta meta) {
|
||||
+ net.minecraft.world.item.ItemStack item = this.getHandle().getItem();
|
||||
+ CraftItemStack.applyMetaToItem(item, meta);
|
||||
+ this.getHandle().setItem(item); // Reset item
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void splash() {
|
||||
+ this.getHandle().splash(null);
|
||||
+ }
|
||||
+ // Paper end
|
||||
@Override
|
||||
public net.minecraft.world.entity.projectile.ThrownPotion getHandle() {
|
||||
return (net.minecraft.world.entity.projectile.ThrownPotion) this.entity;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java
|
||||
index e374b9f40eddca13b30855d25a2030f8df98138f..4fc893378fb0568ddcffc7593d66df6bfe23f659 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java
|
||||
@@ -53,5 +53,15 @@ public class CraftTrident extends CraftAbstractArrow implements Trident {
|
||||
com.google.common.base.Preconditions.checkArgument(loyaltyLevel >= 0 && loyaltyLevel <= 127, "The loyalty level has to be between 0 and 127");
|
||||
this.getHandle().setLoyalty((byte) loyaltyLevel);
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasDealtDamage() {
|
||||
+ return this.getHandle().dealtDamage;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setHasDealtDamage(boolean hasDealtDamage) {
|
||||
+ this.getHandle().dealtDamage = hasDealtDamage;
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 5fc6ef13cdc9df11b0fd2b0baf3cec862ccb5e37..eeb326a115020f571e96f3ec85408950b5eb56fb 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -843,19 +843,19 @@ public class CraftEventFactory {
|
||||
/**
|
||||
* PotionSplashEvent
|
||||
*/
|
||||
- public static PotionSplashEvent callPotionSplashEvent(net.minecraft.world.entity.projectile.ThrownPotion potion, HitResult position, Map<LivingEntity, Double> affectedEntities) {
|
||||
+ public static PotionSplashEvent callPotionSplashEvent(net.minecraft.world.entity.projectile.ThrownPotion potion, @Nullable HitResult position, Map<LivingEntity, Double> affectedEntities) { // Paper - nullable hitResult
|
||||
ThrownPotion thrownPotion = (ThrownPotion) potion.getBukkitEntity();
|
||||
|
||||
Block hitBlock = null;
|
||||
BlockFace hitFace = null;
|
||||
- if (position.getType() == HitResult.Type.BLOCK) {
|
||||
+ if (position != null && position.getType() == HitResult.Type.BLOCK) { // Paper - nullable hitResult
|
||||
BlockHitResult positionBlock = (BlockHitResult) position;
|
||||
hitBlock = CraftBlock.at(potion.level(), positionBlock.getBlockPos());
|
||||
hitFace = CraftBlock.notchToBlockFace(positionBlock.getDirection());
|
||||
}
|
||||
|
||||
org.bukkit.entity.Entity hitEntity = null;
|
||||
- if (position.getType() == HitResult.Type.ENTITY) {
|
||||
+ if (position != null && position.getType() == HitResult.Type.ENTITY) { // Paper - nullable hitResult
|
||||
hitEntity = ((EntityHitResult) position).getEntity().getBukkitEntity();
|
||||
}
|
||||
|
||||
@@ -864,20 +864,20 @@ public class CraftEventFactory {
|
||||
return event;
|
||||
}
|
||||
|
||||
- public static LingeringPotionSplashEvent callLingeringPotionSplashEvent(net.minecraft.world.entity.projectile.ThrownPotion potion, HitResult position, net.minecraft.world.entity.AreaEffectCloud cloud) {
|
||||
+ public static LingeringPotionSplashEvent callLingeringPotionSplashEvent(net.minecraft.world.entity.projectile.ThrownPotion potion, @Nullable HitResult position, net.minecraft.world.entity.AreaEffectCloud cloud) { // Paper - nullable hitResult
|
||||
ThrownPotion thrownPotion = (ThrownPotion) potion.getBukkitEntity();
|
||||
AreaEffectCloud effectCloud = (AreaEffectCloud) cloud.getBukkitEntity();
|
||||
|
||||
Block hitBlock = null;
|
||||
BlockFace hitFace = null;
|
||||
- if (position.getType() == HitResult.Type.BLOCK) {
|
||||
+ if (position != null && position.getType() == HitResult.Type.BLOCK) { // Paper
|
||||
BlockHitResult positionBlock = (BlockHitResult) position;
|
||||
hitBlock = CraftBlock.at(potion.level(), positionBlock.getBlockPos());
|
||||
hitFace = CraftBlock.notchToBlockFace(positionBlock.getDirection());
|
||||
}
|
||||
|
||||
org.bukkit.entity.Entity hitEntity = null;
|
||||
- if (position.getType() == HitResult.Type.ENTITY) {
|
||||
+ if (position != null && position.getType() == HitResult.Type.ENTITY) { // Paper
|
||||
hitEntity = ((EntityHitResult) position).getEntity().getBukkitEntity();
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
index e8a455eb5e17bcfcae3f03664f2b47773fbdf37e..08178a88ba7d0881a6c2843eef24a846cf07adb4 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
@@ -329,12 +329,23 @@ public final class CraftItemStack extends ItemStack {
|
||||
public ItemMeta getItemMeta() {
|
||||
return CraftItemStack.getItemMeta(this.handle);
|
||||
}
|
||||
+ // Paper start
|
||||
+ public static void applyMetaToItem(net.minecraft.world.item.ItemStack itemStack, ItemMeta itemMeta) {
|
||||
+ final CraftMetaItem.Applicator tag = new CraftMetaItem.Applicator();
|
||||
+ ((CraftMetaItem) itemMeta).applyToItem(tag);
|
||||
+ itemStack.applyComponents(tag.build());
|
||||
+ }
|
||||
|
||||
public static ItemMeta getItemMeta(net.minecraft.world.item.ItemStack item) {
|
||||
+ return getItemMeta(item, null);
|
||||
+ }
|
||||
+ public static ItemMeta getItemMeta(net.minecraft.world.item.ItemStack item, org.bukkit.inventory.ItemType metaForType) {
|
||||
+ // Paper end
|
||||
if (!CraftItemStack.hasItemMeta(item)) {
|
||||
return CraftItemFactory.instance().getItemMeta(CraftItemStack.getType(item));
|
||||
}
|
||||
|
||||
+ if (metaForType != null) { return ((CraftItemType<?>) metaForType).getItemMeta(item); } // Paper
|
||||
return ((CraftItemType<?>) CraftItemType.minecraftToBukkitNew(item.getItem())).getItemMeta(item);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java b/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java
|
||||
index 93b9e6b32798e32026492fa3f80de9d4a7b3d9a5..d2329ebf12dbea922fab481cd6822b36682f3461 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java
|
||||
@@ -55,7 +55,15 @@ public class CraftBlockProjectileSource implements BlockProjectileSource {
|
||||
|
||||
@Override
|
||||
public <T extends Projectile> T launchProjectile(Class<? extends T> projectile, Vector velocity) {
|
||||
+ // Paper start - launchProjectile consumer
|
||||
+ return this.launchProjectile(projectile, velocity, null);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public <T extends Projectile> T launchProjectile(Class<? extends T> projectile, Vector velocity, java.util.function.Consumer<? super T> function) {
|
||||
+ // Paper end - launchProjectile consumer
|
||||
Preconditions.checkArgument(this.getBlock().getType() == Material.DISPENSER, "Block is no longer dispenser");
|
||||
+
|
||||
// Copied from BlockDispenser.dispense()
|
||||
BlockSource sourceblock = new BlockSource((ServerLevel) this.dispenserBlock.getLevel(), this.dispenserBlock.getBlockPos(), this.dispenserBlock.getBlockState(), this.dispenserBlock);
|
||||
// Copied from DispenseBehaviorProjectile
|
||||
@@ -67,7 +75,7 @@ public class CraftBlockProjectileSource implements BlockProjectileSource {
|
||||
item = Items.SNOWBALL;
|
||||
} else if (Egg.class.isAssignableFrom(projectile)) {
|
||||
item = Items.EGG;
|
||||
- } else if (EnderPearl.class.isAssignableFrom(projectile)) {
|
||||
+ } else if (false && EnderPearl.class.isAssignableFrom(projectile)) { // Paper - more projectile API - disallow enderpearl, it is not a projectile item
|
||||
item = Items.ENDER_PEARL;
|
||||
} else if (ThrownExpBottle.class.isAssignableFrom(projectile)) {
|
||||
item = Items.EXPERIENCE_BOTTLE;
|
||||
@@ -82,20 +90,20 @@ public class CraftBlockProjectileSource implements BlockProjectileSource {
|
||||
item = Items.TIPPED_ARROW;
|
||||
} else if (SpectralArrow.class.isAssignableFrom(projectile)) {
|
||||
item = Items.SPECTRAL_ARROW;
|
||||
- } else {
|
||||
+ } else if (org.bukkit.entity.Arrow.class.isAssignableFrom(projectile)) { // Paper - more projectile API - disallow trident
|
||||
item = Items.ARROW;
|
||||
}
|
||||
} else if (Fireball.class.isAssignableFrom(projectile)) {
|
||||
- if (AbstractWindCharge.class.isAssignableFrom(projectile)) {
|
||||
+ if (org.bukkit.entity.WindCharge.class.isAssignableFrom(projectile)) { // Paper - more projectile API - only allow wind charge not breeze wind charge
|
||||
item = Items.WIND_CHARGE;
|
||||
- } else {
|
||||
+ } else if (org.bukkit.entity.SmallFireball.class.isAssignableFrom(projectile)) { // Paper - more projectile API - only allow firing fire charges.
|
||||
item = Items.FIRE_CHARGE;
|
||||
}
|
||||
} else if (Firework.class.isAssignableFrom(projectile)) {
|
||||
item = Items.FIREWORK_ROCKET;
|
||||
}
|
||||
|
||||
- Preconditions.checkArgument(item instanceof ProjectileItem, "Projectile not supported");
|
||||
+ Preconditions.checkArgument(item instanceof ProjectileItem, "Projectile '%s' not supported", projectile.getSimpleName()); // Paper - more projectile API - include simple name in exception
|
||||
|
||||
ItemStack itemstack = new ItemStack(item);
|
||||
ProjectileItem projectileItem = (ProjectileItem) item;
|
||||
@@ -104,7 +112,7 @@ public class CraftBlockProjectileSource implements BlockProjectileSource {
|
||||
Position iposition = dispenseConfig.positionFunction().getDispensePosition(sourceblock, enumdirection);
|
||||
net.minecraft.world.entity.projectile.Projectile launch = projectileItem.asProjectile(world, iposition, itemstack, enumdirection);
|
||||
|
||||
- if (Fireball.class.isAssignableFrom(projectile)) {
|
||||
+ if (false && Fireball.class.isAssignableFrom(projectile)) { // Paper - more project API - dispensers cannot launch anything but fire charges.
|
||||
AbstractHurtingProjectile customFireball = null;
|
||||
if (WitherSkull.class.isAssignableFrom(projectile)) {
|
||||
launch = customFireball = EntityType.WITHER_SKULL.create(world);
|
||||
@@ -129,7 +137,7 @@ public class CraftBlockProjectileSource implements BlockProjectileSource {
|
||||
}
|
||||
}
|
||||
|
||||
- if (launch instanceof net.minecraft.world.entity.projectile.AbstractArrow arrow) {
|
||||
+ if (false && launch instanceof net.minecraft.world.entity.projectile.AbstractArrow arrow) { // Paper - more projectile API - this is set by the respective ArrowItem when constructing the projectile
|
||||
arrow.pickup = net.minecraft.world.entity.projectile.AbstractArrow.Pickup.ALLOWED;
|
||||
}
|
||||
launch.projectileSource = this;
|
||||
@@ -138,6 +146,11 @@ public class CraftBlockProjectileSource implements BlockProjectileSource {
|
||||
if (velocity != null) {
|
||||
((T) launch.getBukkitEntity()).setVelocity(velocity);
|
||||
}
|
||||
+ // Paper start
|
||||
+ if (function != null) {
|
||||
+ function.accept((T) launch.getBukkitEntity());
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
world.addFreshEntity(launch);
|
||||
return (T) launch.getBukkitEntity();
|
|
@ -1,64 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Sat, 12 Mar 2022 06:31:13 -0800
|
||||
Subject: [PATCH] Fix swamp hut cat generation deadlock
|
||||
|
||||
The worldgen thread will attempt to get structure references
|
||||
via the world's getChunkAt method, which is fine if the gen is
|
||||
not cancelled - but if the chunk was unloaded, the call will block
|
||||
indefinitely. Instead of using the world state, we use the already
|
||||
supplied ServerLevelAccessor which will always have the chunk available.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Cat.java b/src/main/java/net/minecraft/world/entity/animal/Cat.java
|
||||
index f0e5428394f8de8f7ac05b8cbc34826d153eeaef..d44807c16712afd37efdbf434d1afb12a7c3d343 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Cat.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Cat.java
|
||||
@@ -357,7 +357,7 @@ public class Cat extends TamableAnimal implements VariantHolder<Holder<CatVarian
|
||||
BuiltInRegistries.CAT_VARIANT.getRandomElementOf(tagkey, world.getRandom()).ifPresent(this::setVariant);
|
||||
ServerLevel worldserver = world.getLevel();
|
||||
|
||||
- if (worldserver.structureManager().getStructureWithPieceAt(this.blockPosition(), StructureTags.CATS_SPAWN_AS_BLACK).isValid()) {
|
||||
+ if (worldserver.structureManager().getStructureWithPieceAt(this.blockPosition(), StructureTags.CATS_SPAWN_AS_BLACK, world).isValid()) { // Paper - Fix swamp hut cat generation deadlock
|
||||
this.setVariant((Holder) BuiltInRegistries.CAT_VARIANT.getHolderOrThrow(CatVariant.ALL_BLACK));
|
||||
this.setPersistenceRequired();
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/StructureManager.java b/src/main/java/net/minecraft/world/level/StructureManager.java
|
||||
index ceec33ced3d0b65a3e800378e250d0166d0c195f..54972cce2314eff774250101df43a9b7074e9604 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/StructureManager.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/StructureManager.java
|
||||
@@ -48,7 +48,12 @@ public class StructureManager {
|
||||
}
|
||||
|
||||
public List<StructureStart> startsForStructure(ChunkPos pos, Predicate<Structure> predicate) {
|
||||
- Map<Structure, LongSet> map = this.level.getChunk(pos.x, pos.z, ChunkStatus.STRUCTURE_REFERENCES).getAllReferences();
|
||||
+ // Paper start - Fix swamp hut cat generation deadlock
|
||||
+ return this.startsForStructure(pos, predicate, null);
|
||||
+ }
|
||||
+ public List<StructureStart> startsForStructure(ChunkPos pos, Predicate<Structure> predicate, @Nullable ServerLevelAccessor levelAccessor) {
|
||||
+ Map<Structure, LongSet> map = (levelAccessor == null ? this.level : levelAccessor).getChunk(pos.x, pos.z, ChunkStatus.STRUCTURE_REFERENCES).getAllReferences();
|
||||
+ // Paper end - Fix swamp hut cat generation deadlock
|
||||
Builder<StructureStart> builder = ImmutableList.builder();
|
||||
|
||||
for (Entry<Structure, LongSet> entry : map.entrySet()) {
|
||||
@@ -116,10 +121,20 @@ public class StructureManager {
|
||||
}
|
||||
|
||||
public StructureStart getStructureWithPieceAt(BlockPos pos, Predicate<Holder<Structure>> predicate) {
|
||||
+ // Paper start - Fix swamp hut cat generation deadlock
|
||||
+ return this.getStructureWithPieceAt(pos, predicate, null);
|
||||
+ }
|
||||
+
|
||||
+ public StructureStart getStructureWithPieceAt(BlockPos pos, TagKey<Structure> tag, @Nullable ServerLevelAccessor levelAccessor) {
|
||||
+ return this.getStructureWithPieceAt(pos, structure -> structure.is(tag), levelAccessor);
|
||||
+ }
|
||||
+
|
||||
+ public StructureStart getStructureWithPieceAt(BlockPos pos, Predicate<Holder<Structure>> predicate, @Nullable ServerLevelAccessor levelAccessor) {
|
||||
+ // Paper end - Fix swamp hut cat generation deadlock
|
||||
Registry<Structure> registry = this.registryAccess().registryOrThrow(Registries.STRUCTURE);
|
||||
|
||||
for (StructureStart structureStart : this.startsForStructure(
|
||||
- new ChunkPos(pos), structure -> registry.getHolder(registry.getId(structure)).map(predicate::test).orElse(false)
|
||||
+ new ChunkPos(pos), structure -> registry.getHolder(registry.getId(structure)).map(predicate::test).orElse(false), levelAccessor // Paper - Fix swamp hut cat generation deadlock
|
||||
)) {
|
||||
if (this.structureHasPieceAt(pos, structureStart)) {
|
||||
return structureStart;
|
|
@ -1,24 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Mon, 14 Mar 2022 12:35:37 -0700
|
||||
Subject: [PATCH] Don't allow vehicle movement from players while teleporting
|
||||
|
||||
Bring the vehicle move packet behavior in line with the
|
||||
regular player move packet.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 1e806fd16ca5f90bdb4f71dea008d7936eb82562..76c9feb5e1389eb929571de74ececd4a4f384453 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -484,6 +484,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
this.disconnect((Component) Component.translatable("multiplayer.disconnect.invalid_vehicle_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_VEHICLE_MOVEMENT); // Paper - kick event cause
|
||||
} else if (!this.updateAwaitingTeleport()) {
|
||||
Entity entity = this.player.getRootVehicle();
|
||||
+ // Paper start - Don't allow vehicle movement from players while teleporting
|
||||
+ if (this.awaitingPositionFromClient != null || this.player.isImmobile() || entity.isRemoved()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Don't allow vehicle movement from players while teleporting
|
||||
|
||||
if (entity != this.player && entity.getControllingPassenger() == this.player && entity == this.lastVehicle) {
|
||||
ServerLevel worldserver = this.player.serverLevel();
|
|
@ -1,61 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
Date: Mon, 14 Mar 2022 22:46:05 -0700
|
||||
Subject: [PATCH] Implement getComputedBiome API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
index 5d137f8c42356359701e1bea7525f82c018b502c..f6dd8665b9f6e2a8ff396deba8a021e695bedf7e 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
@@ -77,6 +77,13 @@ public abstract class CraftRegionAccessor implements RegionAccessor {
|
||||
return CraftBiome.minecraftHolderToBukkit(this.getHandle().getNoiseBiome(x >> 2, y >> 2, z >> 2));
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public Biome getComputedBiome(int x, int y, int z) {
|
||||
+ return CraftBiome.minecraftHolderToBukkit(this.getHandle().getBiome(new BlockPos(x, y, z)));
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void setBiome(Location location, Biome biome) {
|
||||
this.setBiome(location.getBlockX(), location.getBlockY(), location.getBlockZ(), biome);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
index 068b3735b6c50a7a2053c7dc39856f728fb7218a..6d10396347b69d9243ab902ecc68ede93fa17b7d 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
@@ -340,6 +340,13 @@ public class CraftBlock implements Block {
|
||||
return this.getWorld().getBiome(this.getX(), this.getY(), this.getZ());
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public Biome getComputedBiome() {
|
||||
+ return this.getWorld().getComputedBiome(this.getX(), this.getY(), this.getZ());
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void setBiome(Biome bio) {
|
||||
this.getWorld().setBiome(this.getX(), this.getY(), this.getZ(), bio);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java b/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java
|
||||
index 7d6ee60b1d3e023e1eabc59eb591c3ae3d8ac043..eaa9ba70b0b80d86eb376a0641420093a7c9dfdb 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java
|
||||
@@ -165,6 +165,14 @@ public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRe
|
||||
return super.getBiome(x, y, z);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public Biome getComputedBiome(int x, int y, int z) {
|
||||
+ Preconditions.checkArgument(this.isInRegion(x, y, z), "Coordinates %s, %s, %s are not in the region", x, y, z);
|
||||
+ return super.getComputedBiome(x, y, z);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void setBiome(int x, int y, int z, Holder<net.minecraft.world.level.biome.Biome> biomeBase) {
|
||||
Preconditions.checkArgument(this.isInRegion(x, y, z), "Coordinates %s, %s, %s are not in the region", x, y, z);
|
|
@ -1,28 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Tue, 15 Mar 2022 01:38:15 -0700
|
||||
Subject: [PATCH] Make some itemstacks nonnull
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java
|
||||
index 972fe4237461f07f78b60845b2ebfefb06698ded..9d74577af071954e1e37201a96368c1360076209 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java
|
||||
@@ -155,13 +155,13 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i
|
||||
case OFF_HAND:
|
||||
return this.getItemInOffHand();
|
||||
case FEET:
|
||||
- return this.getBoots();
|
||||
+ return java.util.Objects.requireNonNullElseGet(this.getBoots(), () -> new ItemStack(org.bukkit.Material.AIR)); // Paper - make nonnull
|
||||
case LEGS:
|
||||
- return this.getLeggings();
|
||||
+ return java.util.Objects.requireNonNullElseGet(this.getLeggings(), () -> new ItemStack(org.bukkit.Material.AIR)); // Paper - make nonnull
|
||||
case CHEST:
|
||||
- return this.getChestplate();
|
||||
+ return java.util.Objects.requireNonNullElseGet(this.getChestplate(), () -> new ItemStack(org.bukkit.Material.AIR)); // Paper - make nonnull
|
||||
case HEAD:
|
||||
- return this.getHelmet();
|
||||
+ return java.util.Objects.requireNonNullElseGet(this.getHelmet(), () -> new ItemStack(org.bukkit.Material.AIR)); // Paper - make nonnull
|
||||
default:
|
||||
throw new IllegalArgumentException("Not implemented. This is a bug");
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
Date: Wed, 16 Mar 2022 20:35:21 -0700
|
||||
Subject: [PATCH] Implement enchantWithLevels API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
index 803a19063c03627dbea79cb1c395ae35aaef2834..fef91dbede067f1ab99a9c7d463a2c55cc6cae3a 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
@@ -302,4 +302,47 @@ public final class CraftItemFactory implements ItemFactory {
|
||||
return eggItem == null ? null : new net.minecraft.world.item.ItemStack(eggItem).asBukkitMirror();
|
||||
}
|
||||
// Paper end - old getSpawnEgg API
|
||||
+ // Paper start - enchantWithLevels API
|
||||
+ @Override
|
||||
+ public ItemStack enchantWithLevels(ItemStack itemStack, int levels, boolean allowTreasure, java.util.Random random) {
|
||||
+ return enchantWithLevels(
|
||||
+ itemStack,
|
||||
+ levels,
|
||||
+ allowTreasure
|
||||
+ ? Optional.empty()
|
||||
+ // While IN_ENCHANTING_TABLE is not logically the same as all but TREASURE, the tag is defined as
|
||||
+ // NON_TREASURE, which does contain all enchantments not in the treasure tag.
|
||||
+ // Additionally, the allowTreasure boolean is more intended to configure this method to behave like
|
||||
+ // an enchanting table.
|
||||
+ : net.minecraft.server.MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.ENCHANTMENT).getTag(EnchantmentTags.IN_ENCHANTING_TABLE),
|
||||
+ random
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
+ @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
+ private ItemStack enchantWithLevels(
|
||||
+ ItemStack itemStack,
|
||||
+ int levels,
|
||||
+ Optional<? extends net.minecraft.core.HolderSet<net.minecraft.world.item.enchantment.Enchantment>> possibleEnchantments,
|
||||
+ java.util.Random random
|
||||
+ ) {
|
||||
+ Preconditions.checkArgument(itemStack != null, "Argument 'itemStack' must not be null");
|
||||
+ Preconditions.checkArgument(!itemStack.isEmpty(), "Argument 'itemStack' cannot be empty");
|
||||
+ Preconditions.checkArgument(levels > 0 && levels <= 30, "Argument 'levels' must be in range [1, 30] (attempted " + levels + ")");
|
||||
+ Preconditions.checkArgument(random != null, "Argument 'random' must not be null");
|
||||
+ final net.minecraft.world.item.ItemStack internalStack = CraftItemStack.asNMSCopy(itemStack);
|
||||
+ if (internalStack.isEnchanted()) {
|
||||
+ internalStack.set(net.minecraft.core.component.DataComponents.ENCHANTMENTS, net.minecraft.world.item.enchantment.ItemEnchantments.EMPTY);
|
||||
+ }
|
||||
+ final net.minecraft.core.RegistryAccess registryAccess = net.minecraft.server.MinecraftServer.getServer().registryAccess();
|
||||
+ final net.minecraft.world.item.ItemStack enchanted = net.minecraft.world.item.enchantment.EnchantmentHelper.enchantItem(
|
||||
+ new org.bukkit.craftbukkit.util.RandomSourceWrapper(random),
|
||||
+ internalStack,
|
||||
+ levels,
|
||||
+ registryAccess,
|
||||
+ possibleEnchantments
|
||||
+ );
|
||||
+ return CraftItemStack.asCraftMirror(enchanted);
|
||||
+ }
|
||||
+ // Paper end - enchantWithLevels API
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Philip Kelley <philip@thoriumcube.org>
|
||||
Date: Wed, 16 Mar 2022 12:05:59 +0000
|
||||
Subject: [PATCH] Fix saving in unloadWorld
|
||||
|
||||
Change savingDisabled to false to ensure ServerLevel's saving logic gets called when unloadWorld is called with save = true
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 566ed56de6fcb4dc64e504310b46295466917eee..183d9672ad60e2b7db48c283b1ca863df01ad658 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -1383,7 +1383,7 @@ public final class CraftServer implements Server {
|
||||
|
||||
try {
|
||||
if (save) {
|
||||
- handle.save(null, true, true);
|
||||
+ handle.save(null, true, false); // Paper - Fix saving in unloadWorld
|
||||
}
|
||||
|
||||
handle.getChunkSource().close(save);
|
|
@ -1,42 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sat, 19 Mar 2022 12:12:22 +0000
|
||||
Subject: [PATCH] Buffer OOB setBlock calls
|
||||
|
||||
lets debug mode throw a trace in order to potentially see where
|
||||
such calls are cascading from easier, but, generally, if you see one setBlock
|
||||
call, you're gonna see more, and this just potentially causes a flood of logs
|
||||
which can cause issues for slower terminals, etc.
|
||||
|
||||
We can limit the flood by just allowing one for a single gen region,
|
||||
we'll also only gen a trace for the first one, I see no real pressing need
|
||||
to generate more, given that that would *massively* negate this patch otherwise
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/WorldGenRegion.java b/src/main/java/net/minecraft/server/level/WorldGenRegion.java
|
||||
index 421f146ea9c35b852251c0ddb29856c13e11aef3..13229388ddce668061a34c787ab9586d41854d8a 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/WorldGenRegion.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/WorldGenRegion.java
|
||||
@@ -284,6 +284,7 @@ public class WorldGenRegion implements WorldGenLevel {
|
||||
}
|
||||
}
|
||||
|
||||
+ private boolean hasSetFarWarned = false; // Paper - Buffer OOB setBlock calls
|
||||
@Override
|
||||
public boolean ensureCanWrite(BlockPos pos) {
|
||||
int i = SectionPos.blockToSectionCoord(pos.getX());
|
||||
@@ -303,7 +304,15 @@ public class WorldGenRegion implements WorldGenLevel {
|
||||
|
||||
return true;
|
||||
} else {
|
||||
+ // Paper start - Buffer OOB setBlock calls
|
||||
+ if (!hasSetFarWarned) {
|
||||
Util.logAndPauseIfInIde("Detected setBlock in a far chunk [" + i + ", " + j + "], pos: " + String.valueOf(pos) + ", status: " + String.valueOf(this.generatingStep.targetStatus()) + (this.currentlyGenerating == null ? "" : ", currently generating: " + (String) this.currentlyGenerating.get()));
|
||||
+ hasSetFarWarned = true;
|
||||
+ if (this.getServer() != null && this.getServer().isDebugging()) {
|
||||
+ io.papermc.paper.util.TraceUtil.dumpTraceForThread("far setBlock call");
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Buffer OOB setBlock calls
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Mon, 21 Jun 2021 21:24:45 -0400
|
||||
Subject: [PATCH] Add TameableDeathMessageEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/TamableAnimal.java b/src/main/java/net/minecraft/world/entity/TamableAnimal.java
|
||||
index 7b7bc1a205dfacbe5709011b6b6799e75af9e4cc..4c5b0b1a71ec5ba0e8dcd5ef52bf667e9bb30be9 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/TamableAnimal.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/TamableAnimal.java
|
||||
@@ -241,7 +241,12 @@ public abstract class TamableAnimal extends Animal implements OwnableEntity {
|
||||
@Override
|
||||
public void die(DamageSource damageSource) {
|
||||
if (!this.level().isClientSide && this.level().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES) && this.getOwner() instanceof ServerPlayer) {
|
||||
- this.getOwner().sendSystemMessage(this.getCombatTracker().getDeathMessage());
|
||||
+ // Paper start - Add TameableDeathMessageEvent
|
||||
+ io.papermc.paper.event.entity.TameableDeathMessageEvent event = new io.papermc.paper.event.entity.TameableDeathMessageEvent((org.bukkit.entity.Tameable) getBukkitEntity(), io.papermc.paper.adventure.PaperAdventure.asAdventure(this.getCombatTracker().getDeathMessage()));
|
||||
+ if (event.callEvent()) {
|
||||
+ this.getOwner().sendSystemMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.deathMessage()));
|
||||
+ }
|
||||
+ // Paper end - Add TameableDeathMessageEvent
|
||||
}
|
||||
|
||||
super.die(damageSource);
|
|
@ -1,215 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: SoSeDiK <mrsosedik@gmail.com>
|
||||
Date: Mon, 21 Mar 2022 20:00:53 +0200
|
||||
Subject: [PATCH] Fix new block data for EntityChangeBlockEvent
|
||||
|
||||
Also standardizes how to handle EntityChangeBlockEvent before a removeBlock or destroyBlock
|
||||
call. Always use 'state.getFluidState().createLegacyBlock()' to get the new state instead of
|
||||
just using the 'air' state.
|
||||
|
||||
Also fixes the new block data for EntityBreakDoorEvent (a sub-event from
|
||||
EntityChangeBlockEvent)
|
||||
|
||||
Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
|
||||
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java b/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java
|
||||
index 6a7052cd6ec88ed4aaea2fef0ebc750060d1dec0..2ade08d1466660ee1787fa97908002ef56389712 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java
|
||||
@@ -108,7 +108,7 @@ public class HarvestFarmland extends Behavior<Villager> {
|
||||
Block block1 = world.getBlockState(this.aboveFarmlandPos.below()).getBlock();
|
||||
|
||||
if (block instanceof CropBlock && ((CropBlock) block).isMaxAge(iblockdata)) {
|
||||
- if (CraftEventFactory.callEntityChangeBlockEvent(entity, this.aboveFarmlandPos, Blocks.AIR.defaultBlockState())) { // CraftBukkit
|
||||
+ if (CraftEventFactory.callEntityChangeBlockEvent(entity, this.aboveFarmlandPos, iblockdata.getFluidState().createLegacyBlock())) { // CraftBukkit // Paper - fix wrong block state
|
||||
world.destroyBlock(this.aboveFarmlandPos, true, entity);
|
||||
} // CraftBukkit
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java
|
||||
index 4253b3b1263a7ae5a2f5f3a34674dfea615a81ea..784a894688f98f9d0368a36d456c5c94e1ee3695 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java
|
||||
@@ -72,7 +72,7 @@ public class BreakDoorGoal extends DoorInteractGoal {
|
||||
|
||||
if (this.breakTime == this.getDoorBreakTime() && this.isValidDifficulty(this.mob.level().getDifficulty())) {
|
||||
// CraftBukkit start
|
||||
- if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreakDoorEvent(this.mob, this.doorPos).isCancelled()) {
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreakDoorEvent(this.mob, this.doorPos, this.mob.level().getFluidState(this.doorPos).createLegacyBlock()).isCancelled()) { // Paper - fix wrong block state
|
||||
this.start();
|
||||
return;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java
|
||||
index f4bc556e245179d0a4710e5255dd289aaafdceb7..d802985f1431be4332c07f0dab88feebedea4ce2 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java
|
||||
@@ -67,8 +67,9 @@ public class EatBlockGoal extends Goal {
|
||||
if (this.eatAnimationTick == this.adjustedTickDelay(4)) {
|
||||
BlockPos blockposition = this.mob.blockPosition();
|
||||
|
||||
- if (EatBlockGoal.IS_TALL_GRASS.test(this.level.getBlockState(blockposition))) {
|
||||
- if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition, Blocks.AIR.defaultBlockState(), !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit
|
||||
+ final BlockState blockState = this.level.getBlockState(blockposition); // Paper - fix wrong block state
|
||||
+ if (EatBlockGoal.IS_TALL_GRASS.test(blockState)) { // Paper - fix wrong block state
|
||||
+ if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition, blockState.getFluidState().createLegacyBlock(), !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Paper - fix wrong block state
|
||||
this.level.destroyBlock(blockposition, false);
|
||||
}
|
||||
|
||||
@@ -77,7 +78,7 @@ public class EatBlockGoal extends Goal {
|
||||
BlockPos blockposition1 = blockposition.below();
|
||||
|
||||
if (this.level.getBlockState(blockposition1).is(Blocks.GRASS_BLOCK)) {
|
||||
- if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition1, Blocks.AIR.defaultBlockState(), !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit
|
||||
+ if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition1, Blocks.DIRT.defaultBlockState(), !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Paper - Fix wrong block state
|
||||
this.level.levelEvent(2001, blockposition1, Block.getId(Blocks.GRASS_BLOCK.defaultBlockState()));
|
||||
this.level.setBlock(blockposition1, Blocks.DIRT.defaultBlockState(), 2);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Rabbit.java b/src/main/java/net/minecraft/world/entity/animal/Rabbit.java
|
||||
index e5bd3039ef698fcea80a270b6111c2a663e5075c..0109c8ed8bf6a053674456fa4473934e028ca418 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Rabbit.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Rabbit.java
|
||||
@@ -581,7 +581,7 @@ public class Rabbit extends Animal implements VariantHolder<Rabbit.Variant> {
|
||||
|
||||
if (i == 0) {
|
||||
// CraftBukkit start
|
||||
- if (!CraftEventFactory.callEntityChangeBlockEvent(this.rabbit, blockposition, Blocks.AIR.defaultBlockState())) {
|
||||
+ if (!CraftEventFactory.callEntityChangeBlockEvent(this.rabbit, blockposition, iblockdata.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state
|
||||
return;
|
||||
}
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
||||
index 3cd4a744c3e3aeba90f342de9dea67ef2f3de626..1b49090a466bc74d9e5f2815314955b6dfbb83dc 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
||||
@@ -377,7 +377,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
|
||||
|
||||
if (WitherBoss.canDestroy(iblockdata)) {
|
||||
// CraftBukkit start
|
||||
- if (!CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, Blocks.AIR.defaultBlockState())) {
|
||||
+ if (!CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, iblockdata.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state
|
||||
continue;
|
||||
}
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
index 7caa5469a4daa5d0c569f446ff2d597a9f10e8ac..828c51477cd8f35d591367b30bf4feef6a250292 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
@@ -565,7 +565,7 @@ public class EnderMan extends Monster implements NeutralMob {
|
||||
boolean flag = movingobjectpositionblock.getBlockPos().equals(blockposition);
|
||||
|
||||
if (iblockdata.is(BlockTags.ENDERMAN_HOLDABLE) && flag) {
|
||||
- if (CraftEventFactory.callEntityChangeBlockEvent(this.enderman, blockposition, Blocks.AIR.defaultBlockState())) { // CraftBukkit - Place event
|
||||
+ if (CraftEventFactory.callEntityChangeBlockEvent(this.enderman, blockposition, iblockdata.getFluidState().createLegacyBlock())) { // CraftBukkit - Place event // Paper - fix wrong block state
|
||||
world.removeBlock(blockposition, false);
|
||||
world.gameEvent((Holder) GameEvent.BLOCK_DESTROY, blockposition, GameEvent.Context.of(this.enderman, iblockdata));
|
||||
this.enderman.setCarriedBlock(iblockdata.getBlock().defaultBlockState());
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Ravager.java b/src/main/java/net/minecraft/world/entity/monster/Ravager.java
|
||||
index aa4111eef22546f8aa630228c51ef5761c9b373b..212d341425c0f93bba0376de69bea61ffcf4dbd6 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Ravager.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Ravager.java
|
||||
@@ -151,7 +151,7 @@ public class Ravager extends Raider {
|
||||
|
||||
if (block instanceof LeavesBlock) {
|
||||
// CraftBukkit start
|
||||
- if (!CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, net.minecraft.world.level.block.Blocks.AIR.defaultBlockState())) {
|
||||
+ if (!CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, iblockdata.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state
|
||||
continue;
|
||||
}
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Silverfish.java b/src/main/java/net/minecraft/world/entity/monster/Silverfish.java
|
||||
index 9ff42b0ae2b82dc3092e38e1439d89b4ab554b17..860e385fc83f9787dca92efe35d21fd69c4dd635 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Silverfish.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Silverfish.java
|
||||
@@ -162,7 +162,8 @@ public class Silverfish extends Monster {
|
||||
|
||||
if (block instanceof InfestedBlock) {
|
||||
// CraftBukkit start
|
||||
- if (!CraftEventFactory.callEntityChangeBlockEvent(this.silverfish, blockposition1, net.minecraft.world.level.block.Blocks.AIR.defaultBlockState())) {
|
||||
+ BlockState afterState = world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ? iblockdata.getFluidState().createLegacyBlock() : ((InfestedBlock) block).hostStateByInfested(world.getBlockState(blockposition1)); // Paper - fix wrong block state
|
||||
+ if (!CraftEventFactory.callEntityChangeBlockEvent(this.silverfish, blockposition1, afterState)) { // Paper - fix wrong block state
|
||||
continue;
|
||||
}
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
|
||||
index 58dc69fe319027c2b9ecfb9caf272368e81081df..5c6cb752f61c3f3c2960a337173fb7dfe86cc1d3 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
|
||||
@@ -292,7 +292,7 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
|
||||
|
||||
if (iblockdata.is(BlockTags.FIRE)) {
|
||||
// CraftBukkit start
|
||||
- if (CraftEventFactory.callEntityChangeBlockEvent(this, pos, Blocks.AIR.defaultBlockState())) {
|
||||
+ if (CraftEventFactory.callEntityChangeBlockEvent(this, pos, iblockdata.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state
|
||||
this.level().destroyBlock(pos, false, this);
|
||||
}
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/ChorusFlowerBlock.java b/src/main/java/net/minecraft/world/level/block/ChorusFlowerBlock.java
|
||||
index bb1487dd2c8e4374f75a102ab5e17ce9b2d31114..6709cb6b657a8612781c2fe4dd76ee38f329c5ba 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/ChorusFlowerBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/ChorusFlowerBlock.java
|
||||
@@ -284,7 +284,7 @@ public class ChorusFlowerBlock extends Block {
|
||||
|
||||
if (!world.isClientSide && projectile.mayInteract(world, blockposition) && projectile.mayBreak(world)) {
|
||||
// CraftBukkit
|
||||
- if (!CraftEventFactory.callEntityChangeBlockEvent(projectile, blockposition, Blocks.AIR.defaultBlockState())) {
|
||||
+ if (!CraftEventFactory.callEntityChangeBlockEvent(projectile, blockposition, state.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state
|
||||
return;
|
||||
}
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java b/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java
|
||||
index ec9190abe3edf7c3845156bb967dddf6ae7c30ff..95cb7492ac691a8e8aa9894f701b802a7eda5446 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java
|
||||
@@ -134,7 +134,7 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate
|
||||
|
||||
if (projectile.mayInteract(world, blockposition) && projectile.mayBreak(world) && projectile instanceof ThrownTrident && projectile.getDeltaMovement().length() > 0.6D) {
|
||||
// CraftBukkit start
|
||||
- if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(projectile, blockposition, Blocks.AIR.defaultBlockState())) {
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(projectile, blockposition, state.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state
|
||||
return;
|
||||
}
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/TntBlock.java b/src/main/java/net/minecraft/world/level/block/TntBlock.java
|
||||
index 4896ddca849646135ae101236e534ab8f59bd617..a3525ae6d83591664e1456f20d9732a8de0ec326 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/TntBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/TntBlock.java
|
||||
@@ -158,7 +158,7 @@ public class TntBlock extends Block {
|
||||
|
||||
if (projectile.isOnFire() && projectile.mayInteract(world, blockposition)) {
|
||||
// CraftBukkit start
|
||||
- if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(projectile, blockposition, Blocks.AIR.defaultBlockState()) || !CraftEventFactory.callTNTPrimeEvent(world, blockposition, PrimeCause.PROJECTILE, projectile, null)) {
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(projectile, blockposition, state.getFluidState().createLegacyBlock()) || !CraftEventFactory.callTNTPrimeEvent(world, blockposition, PrimeCause.PROJECTILE, projectile, null)) { // Paper - fix wrong block state
|
||||
return;
|
||||
}
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/WaterlilyBlock.java b/src/main/java/net/minecraft/world/level/block/WaterlilyBlock.java
|
||||
index edc20745649b0837f1371c8d29e71fc0c8e5528f..932831bb5632ead5850842fc77192c841571162e 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/WaterlilyBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/WaterlilyBlock.java
|
||||
@@ -37,7 +37,7 @@ public class WaterlilyBlock extends BushBlock {
|
||||
if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
|
||||
if (world instanceof ServerLevel && entity instanceof Boat) {
|
||||
// CraftBukkit start
|
||||
- if (!CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState())) {
|
||||
+ if (!CraftEventFactory.callEntityChangeBlockEvent(entity, pos, state.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state
|
||||
return;
|
||||
}
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index eeb326a115020f571e96f3ec85408950b5eb56fb..ba1599b733946bef468a9b006411f8827844e791 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -1380,11 +1380,11 @@ public class CraftEventFactory {
|
||||
return event;
|
||||
}
|
||||
|
||||
- public static EntityBreakDoorEvent callEntityBreakDoorEvent(Entity entity, BlockPos pos) {
|
||||
+ public static EntityBreakDoorEvent callEntityBreakDoorEvent(Entity entity, BlockPos pos, net.minecraft.world.level.block.state.BlockState newState) { // Paper
|
||||
org.bukkit.entity.Entity entity1 = entity.getBukkitEntity();
|
||||
Block block = CraftBlock.at(entity.level(), pos);
|
||||
|
||||
- EntityBreakDoorEvent event = new EntityBreakDoorEvent((LivingEntity) entity1, block);
|
||||
+ EntityBreakDoorEvent event = new EntityBreakDoorEvent((LivingEntity) entity1, block, newState.createCraftBlockData()); // Paper
|
||||
entity1.getServer().getPluginManager().callEvent(event);
|
||||
|
||||
return event;
|
|
@ -1,25 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Tue, 22 Mar 2022 09:50:40 -0700
|
||||
Subject: [PATCH] fix player loottables running when mob loot gamerule is false
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 25ca370c0b19eca529fc2c980c50e899013f0897..f31eb944465e9011d8aad398eb60bafb44203ad5 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -959,12 +959,14 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
|
||||
}
|
||||
}
|
||||
}
|
||||
+ if (this.shouldDropLoot() && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Paper - fix player loottables running when mob loot gamerule is false
|
||||
// SPIGOT-5071: manually add player loot tables (SPIGOT-5195 - ignores keepInventory rule)
|
||||
this.dropFromLootTable(damageSource, this.lastHurtByPlayerTime > 0);
|
||||
this.dropCustomDeathLoot(this.serverLevel(), damageSource, flag);
|
||||
|
||||
loot.addAll(this.drops);
|
||||
this.drops.clear(); // SPIGOT-5188: make sure to clear
|
||||
+ } // Paper - fix player loottables running when mob loot gamerule is false
|
||||
|
||||
Component defaultMessage = this.getCombatTracker().getDeathMessage();
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Thu, 31 Mar 2022 05:11:37 -0700
|
||||
Subject: [PATCH] Ensure entity passenger world matches ridden entity
|
||||
|
||||
Bad plugins doing this would cause some obvious problems...
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 7d9ebc71b794d40246cbd43ff4de5795970e7ebe..3bb7e0f6a02b9b1726b8c878271d89a9c6d56c12 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -2687,7 +2687,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
}
|
||||
|
||||
public boolean startRiding(Entity entity, boolean force) {
|
||||
- if (entity == this.vehicle) {
|
||||
+ if (entity == this.vehicle || entity.level != this.level) { // Paper - Ensure entity passenger world matches ridden entity (bad plugins)
|
||||
return false;
|
||||
} else if (!entity.couldAcceptPassenger()) {
|
||||
return false;
|
|
@ -1,66 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 20 Mar 2022 22:06:47 -0700
|
||||
Subject: [PATCH] Cache resource keys and optimize reference Holder tags set
|
||||
|
||||
TagKeys are always interned, so we can use a reference hash set for them
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/core/Holder.java b/src/main/java/net/minecraft/core/Holder.java
|
||||
index d7bbf60ba94ecd85f991a0c5c70c34fdb00ec9d5..4d2231868b786da9071c3dff2c073b478a486e8a 100644
|
||||
--- a/src/main/java/net/minecraft/core/Holder.java
|
||||
+++ b/src/main/java/net/minecraft/core/Holder.java
|
||||
@@ -221,7 +221,7 @@ public interface Holder<T> {
|
||||
}
|
||||
|
||||
void bindTags(Collection<TagKey<T>> tags) {
|
||||
- this.tags = Set.copyOf(tags);
|
||||
+ this.tags = java.util.Collections.unmodifiableSet(new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(tags)); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBiome.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBiome.java
|
||||
index 95b956802f83b583a823fcd24808363775a56842..33d2e89ac40465b0c4633f9c51378b80f7c397a9 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBiome.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBiome.java
|
||||
@@ -3,6 +3,7 @@ package org.bukkit.craftbukkit.block;
|
||||
import com.google.common.base.Preconditions;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
+import net.minecraft.resources.ResourceKey;
|
||||
import org.bukkit.Registry;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
@@ -27,13 +28,14 @@ public class CraftBiome {
|
||||
return CraftBiome.minecraftToBukkit(minecraft.value());
|
||||
}
|
||||
|
||||
+ private static final java.util.Map<org.bukkit.block.Biome, ResourceKey<net.minecraft.world.level.biome.Biome>> BIOME_KEY_CACHE = java.util.Collections.synchronizedMap(new java.util.EnumMap<>(Biome.class)); // Paper
|
||||
public static net.minecraft.world.level.biome.Biome bukkitToMinecraft(Biome bukkit) {
|
||||
if (bukkit == null || bukkit == Biome.CUSTOM) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return CraftRegistry.getMinecraftRegistry(Registries.BIOME)
|
||||
- .getOptional(CraftNamespacedKey.toMinecraft(bukkit.getKey())).orElseThrow();
|
||||
+ .getOptional(BIOME_KEY_CACHE.computeIfAbsent(bukkit, b -> ResourceKey.create(Registries.BIOME, CraftNamespacedKey.toMinecraft(b.getKey())))).orElseThrow();
|
||||
}
|
||||
|
||||
public static Holder<net.minecraft.world.level.biome.Biome> bukkitToMinecraftHolder(Biome bukkit) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityType.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityType.java
|
||||
index fd1aaf8e18d6e3425639b60ce21c5aaf36e0b42a..266b616419a47f518a43b990cc7cbb4516beda03 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityType.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityType.java
|
||||
@@ -24,11 +24,11 @@ public class CraftEntityType {
|
||||
return bukkit;
|
||||
}
|
||||
|
||||
+ private static final java.util.Map<EntityType, net.minecraft.resources.ResourceKey<net.minecraft.world.entity.EntityType<?>>> KEY_CACHE = java.util.Collections.synchronizedMap(new java.util.EnumMap<>(EntityType.class)); // Paper
|
||||
public static net.minecraft.world.entity.EntityType<?> bukkitToMinecraft(EntityType bukkit) {
|
||||
Preconditions.checkArgument(bukkit != null);
|
||||
-
|
||||
return CraftRegistry.getMinecraftRegistry(Registries.ENTITY_TYPE)
|
||||
- .getOptional(CraftNamespacedKey.toMinecraft(bukkit.getKey())).orElseThrow();
|
||||
+ .getOptional(KEY_CACHE.computeIfAbsent(bukkit, type -> net.minecraft.resources.ResourceKey.create(Registries.ENTITY_TYPE, CraftNamespacedKey.toMinecraft(type.getKey())))).orElseThrow();
|
||||
}
|
||||
|
||||
public static String bukkitToString(EntityType bukkit) {
|
|
@ -1,151 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Doc <nachito94@msn.com>
|
||||
Date: Sun, 3 Apr 2022 11:31:42 -0400
|
||||
Subject: [PATCH] Allow changing the EnderDragon podium
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
index a2cde7b1b316e43382cb1639ffccf29d89f5ebfc..6306f7925ac4852d8eed7508a11764c636dd7d36 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
@@ -104,6 +104,10 @@ public class EnderDragon extends Mob implements Enemy {
|
||||
private final int[] nodeAdjacency;
|
||||
private final BinaryHeap openSet;
|
||||
private final Explosion explosionSource; // CraftBukkit - reusable source for CraftTNTPrimed.getSource()
|
||||
+ // Paper start - Allow changing the EnderDragon podium
|
||||
+ @Nullable
|
||||
+ private BlockPos podium;
|
||||
+ // Paper end - Allow changing the EnderDragon podium
|
||||
|
||||
public EnderDragon(EntityType<? extends EnderDragon> entitytypes, Level world) {
|
||||
super(EntityType.ENDER_DRAGON, world);
|
||||
@@ -144,6 +148,19 @@ public class EnderDragon extends Mob implements Enemy {
|
||||
return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 200.0D);
|
||||
}
|
||||
|
||||
+ // Paper start - Allow changing the EnderDragon podium
|
||||
+ public BlockPos getPodium() {
|
||||
+ if (this.podium == null) {
|
||||
+ return EndPodiumFeature.getLocation(this.getFightOrigin());
|
||||
+ }
|
||||
+ return this.podium;
|
||||
+ }
|
||||
+
|
||||
+ public void setPodium(@Nullable BlockPos blockPos) {
|
||||
+ this.podium = blockPos;
|
||||
+ }
|
||||
+ // Paper end - Allow changing the EnderDragon podium
|
||||
+
|
||||
@Override
|
||||
public boolean isFlapping() {
|
||||
float f = Mth.cos(this.flapTime * 6.2831855F);
|
||||
@@ -1009,7 +1026,7 @@ public class EnderDragon extends Mob implements Enemy {
|
||||
d0 = segment2[1] - segment1[1];
|
||||
}
|
||||
} else {
|
||||
- BlockPos blockposition = this.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.getLocation(this.fightOrigin));
|
||||
+ BlockPos blockposition = this.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.getPodium()); // Paper - Allow changing the EnderDragon podium
|
||||
double d1 = Math.max(Math.sqrt(blockposition.distToCenterSqr(this.position())) / 4.0D, 1.0D);
|
||||
|
||||
d0 = (double) segmentOffset / d1;
|
||||
@@ -1036,7 +1053,7 @@ public class EnderDragon extends Mob implements Enemy {
|
||||
vec3d = this.getViewVector(tickDelta);
|
||||
}
|
||||
} else {
|
||||
- BlockPos blockposition = this.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.getLocation(this.fightOrigin));
|
||||
+ BlockPos blockposition = this.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.getPodium()); // Paper - Allow changing the EnderDragon podium
|
||||
|
||||
f1 = Math.max((float) Math.sqrt(blockposition.distToCenterSqr(this.position())) / 4.0F, 1.0F);
|
||||
float f3 = 6.0F / f1;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonDeathPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonDeathPhase.java
|
||||
index 803d227281d70606691eed95c4b10a27ca5d1125..5663f2ff1eba4a5e00c76c9d735cb553faae6a04 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonDeathPhase.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonDeathPhase.java
|
||||
@@ -43,7 +43,7 @@ public class DragonDeathPhase extends AbstractDragonPhaseInstance {
|
||||
if (this.targetLocation == null) {
|
||||
BlockPos blockPos = this.dragon
|
||||
.level()
|
||||
- .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, EndPodiumFeature.getLocation(this.dragon.getFightOrigin()));
|
||||
+ .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, this.dragon.getPodium()); // Paper - Allow changing the EnderDragon podium
|
||||
this.targetLocation = Vec3.atBottomCenterOf(blockPos);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonHoldingPatternPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonHoldingPatternPhase.java
|
||||
index 707ef45ccd7fbcbe1947c8941846277f19ee54c9..ddf668205a7cb29b9018bf9eea49667b5fd2d471 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonHoldingPatternPhase.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonHoldingPatternPhase.java
|
||||
@@ -54,7 +54,7 @@ public class DragonHoldingPatternPhase extends AbstractDragonPhaseInstance {
|
||||
if (this.currentPath != null && this.currentPath.isDone()) {
|
||||
BlockPos blockPos = this.dragon
|
||||
.level()
|
||||
- .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, new BlockPos(EndPodiumFeature.getLocation(this.dragon.getFightOrigin())));
|
||||
+ .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, new BlockPos(this.dragon.getPodium())); // Paper - Allow changing the EnderDragon podium
|
||||
int i = this.dragon.getDragonFight() == null ? 0 : this.dragon.getDragonFight().getCrystalsAlive();
|
||||
if (this.dragon.getRandom().nextInt(i + 3) == 0) {
|
||||
this.dragon.getPhaseManager().setPhase(EnderDragonPhase.LANDING_APPROACH);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingApproachPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingApproachPhase.java
|
||||
index e731d0f74692615ce5f42f690e36bd906a39c1dd..557de8a8e21e7f049b6acf27b4ec927ef5a9f9cb 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingApproachPhase.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingApproachPhase.java
|
||||
@@ -53,7 +53,7 @@ public class DragonLandingApproachPhase extends AbstractDragonPhaseInstance {
|
||||
int i = this.dragon.findClosestNode();
|
||||
BlockPos blockPos = this.dragon
|
||||
.level()
|
||||
- .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.getLocation(this.dragon.getFightOrigin()));
|
||||
+ .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.dragon.getPodium()); // Paper - Allow changing the EnderDragon podium
|
||||
Player player = this.dragon
|
||||
.level()
|
||||
.getNearestPlayer(NEAR_EGG_TARGETING, this.dragon, (double)blockPos.getX(), (double)blockPos.getY(), (double)blockPos.getZ());
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingPhase.java
|
||||
index d913147d692e7e58bec4fac44c7e93a1822e8f65..3b960060f152d0352c2f8cdc1c71543cd7fa0dbd 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingPhase.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingPhase.java
|
||||
@@ -41,7 +41,7 @@ public class DragonLandingPhase extends AbstractDragonPhaseInstance {
|
||||
public void doServerTick() {
|
||||
if (this.targetLocation == null) {
|
||||
this.targetLocation = Vec3.atBottomCenterOf(
|
||||
- this.dragon.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.getLocation(this.dragon.getFightOrigin()))
|
||||
+ this.dragon.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.dragon.getPodium()) // Paper - Allow changing the EnderDragon podium
|
||||
);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonTakeoffPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonTakeoffPhase.java
|
||||
index 8d66284eb96cfc0392c211842e87875a095c3ca2..718bf877179f85ee3f0de384ca3a8aaebaa067a5 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonTakeoffPhase.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonTakeoffPhase.java
|
||||
@@ -25,7 +25,7 @@ public class DragonTakeoffPhase extends AbstractDragonPhaseInstance {
|
||||
if (!this.firstTick && this.currentPath != null) {
|
||||
BlockPos blockPos = this.dragon
|
||||
.level()
|
||||
- .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.getLocation(this.dragon.getFightOrigin()));
|
||||
+ .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.dragon.getPodium()); // Paper - Allow changing the EnderDragon podium
|
||||
if (!blockPos.closerToCenterThan(this.dragon.position(), 10.0)) {
|
||||
this.dragon.getPhaseManager().setPhase(EnderDragonPhase.HOLDING_PATTERN);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java
|
||||
index 25b3d889a1742c347e60725df8d6f6c1cee264c7..7b7b89e67d53ed70efae714192c5fa32977f3d9c 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java
|
||||
@@ -73,4 +73,22 @@ public class CraftEnderDragon extends CraftMob implements EnderDragon, CraftEnem
|
||||
public int getDeathAnimationTicks() {
|
||||
return this.getHandle().dragonDeathTime;
|
||||
}
|
||||
+
|
||||
+ // Paper start - Allow changing the EnderDragon podium
|
||||
+ @Override
|
||||
+ public org.bukkit.Location getPodium() {
|
||||
+ net.minecraft.core.BlockPos blockPosOrigin = this.getHandle().getPodium();
|
||||
+ return new org.bukkit.Location(getWorld(), blockPosOrigin.getX(), blockPosOrigin.getY(), blockPosOrigin.getZ());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setPodium(org.bukkit.Location location) {
|
||||
+ if (location == null) {
|
||||
+ this.getHandle().setPodium(null);
|
||||
+ } else {
|
||||
+ org.apache.commons.lang.Validate.isTrue(location.getWorld() == null || location.getWorld().equals(getWorld()), "You cannot set a podium in a different world to where the dragon is");
|
||||
+ this.getHandle().setPodium(io.papermc.paper.util.MCUtil.toBlockPos(location));
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Allow changing the EnderDragon podium
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: etil2jz <blanchot.arthur@protonmail.ch>
|
||||
Date: Sat, 2 Apr 2022 23:29:24 +0200
|
||||
Subject: [PATCH] Fix NBT pieces overriding a block entity during worldgen
|
||||
deadlock
|
||||
|
||||
By checking if the world passed into StructureTemplate's placeInWorld
|
||||
is not a WorldGenRegion, we can bypass the deadlock entirely.
|
||||
See https://bugs.mojang.com/browse/MC-246262
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
|
||||
index 33564e62e3181d28b18a957e28b8ec5152d8339f..cf8258e8d46ca7286a66c38fa24af369bd9a279f 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
|
||||
@@ -279,7 +279,11 @@ public class StructureTemplate {
|
||||
|
||||
if (definedstructure_blockinfo.nbt != null) {
|
||||
tileentity = world.getBlockEntity(blockposition2);
|
||||
- Clearable.tryClear(tileentity);
|
||||
+ // Paper start - Fix NBT pieces overriding a block entity during worldgen deadlock
|
||||
+ if (!(world instanceof net.minecraft.world.level.WorldGenLevel)) {
|
||||
+ Clearable.tryClear(tileentity);
|
||||
+ }
|
||||
+ // Paper end - Fix NBT pieces overriding a block entity during worldgen deadlock
|
||||
world.setBlock(blockposition2, Blocks.BARRIER.defaultBlockState(), 20);
|
||||
}
|
||||
// CraftBukkit start
|
||||
@@ -406,7 +410,11 @@ public class StructureTemplate {
|
||||
if (pair1.getSecond() != null) {
|
||||
tileentity = world.getBlockEntity(blockposition6);
|
||||
if (tileentity != null) {
|
||||
- tileentity.setChanged();
|
||||
+ // Paper start - Fix NBT pieces overriding a block entity during worldgen deadlock
|
||||
+ if (!(world instanceof net.minecraft.world.level.WorldGenLevel)) {
|
||||
+ tileentity.setChanged();
|
||||
+ }
|
||||
+ // Paper end - Fix NBT pieces overriding a block entity during worldgen deadlock
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Wed, 13 Apr 2022 08:25:42 +0100
|
||||
Subject: [PATCH] Prevent tile entity copies loading chunks
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 76c9feb5e1389eb929571de74ececd4a4f384453..7c1a94980cf49d37be442e1b62de36d4395bcf2a 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -3200,7 +3200,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
BlockPos blockposition = BlockEntity.getPosFromTag(customdata.getUnsafe());
|
||||
|
||||
if (this.player.level().isLoaded(blockposition)) {
|
||||
- BlockEntity tileentity = this.player.level().getBlockEntity(blockposition);
|
||||
+ // Paper start - Prevent tile entity copies loading chunks
|
||||
+ BlockEntity tileentity = null;
|
||||
+ if (this.player.distanceToSqr(blockposition.getX(), blockposition.getY(), blockposition.getZ()) < 32 * 32 && this.player.serverLevel().isLoadedAndInBounds(blockposition)) {
|
||||
+ tileentity = this.player.level().getBlockEntity(blockposition);
|
||||
+ }
|
||||
+ // Paper end - Prevent tile entity copies loading chunks
|
||||
|
||||
if (tileentity != null) {
|
||||
tileentity.saveToItem(itemstack, this.player.level().registryAccess());
|
|
@ -1,20 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Doc <nachito94@msn.com>
|
||||
Date: Fri, 15 Apr 2022 17:40:30 -0400
|
||||
Subject: [PATCH] Use username instead of display name in
|
||||
PlayerList#getPlayerStats
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 06bcc9974b4a63c174c51df332ff9ddd7eb6a159..0bded2c55d6c826e2f3dcb89995712c92348a3c7 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -1394,7 +1394,7 @@ public abstract class PlayerList {
|
||||
// CraftBukkit start
|
||||
public ServerStatsCounter getPlayerStats(ServerPlayer entityhuman) {
|
||||
ServerStatsCounter serverstatisticmanager = entityhuman.getStats();
|
||||
- return serverstatisticmanager == null ? this.getPlayerStats(entityhuman.getUUID(), entityhuman.getDisplayName().getString()) : serverstatisticmanager;
|
||||
+ return serverstatisticmanager == null ? this.getPlayerStats(entityhuman.getUUID(), entityhuman.getGameProfile().getName()) : serverstatisticmanager; // Paper - use username and not display name
|
||||
}
|
||||
|
||||
public ServerStatsCounter getPlayerStats(UUID uuid, String displayName) {
|
|
@ -1,23 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: HexedHero <6012891+HexedHero@users.noreply.github.com>
|
||||
Date: Sun, 10 Apr 2022 06:26:32 +0100
|
||||
Subject: [PATCH] Expand PlayerItemDamageEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
index ec3be7fb4eb4560fe0106ac127f17d7437612157..bee59df6a8f30416f94c1a4fbd5e2629336e842f 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
@@ -650,10 +650,11 @@ public final class ItemStack implements DataComponentHolder {
|
||||
if (this.isDamageableItem()) {
|
||||
if (player == null || !player.hasInfiniteMaterials()) {
|
||||
if (amount > 0) {
|
||||
+ int originalDamage = amount; // Paper - Expand PlayerItemDamageEvent
|
||||
amount = EnchantmentHelper.processDurabilityChange(world, this, amount);
|
||||
// CraftBukkit start
|
||||
if (player instanceof ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent
|
||||
- PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), amount); // Paper - Add EntityDamageItemEvent
|
||||
+ PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), amount, originalDamage); // Paper - Add EntityDamageItemEvent & Expand PlayerItemDamageEvent
|
||||
event.getPlayer().getServer().getPluginManager().callEvent(event);
|
||||
|
||||
if (amount != event.getDamage() || event.isCancelled()) {
|
|
@ -1,19 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sat, 3 Jul 2021 21:18:28 +0100
|
||||
Subject: [PATCH] WorldCreator#keepSpawnLoaded
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 183d9672ad60e2b7db48c283b1ca863df01ad658..cfdfb81bc81382b71131c037ebd56f24573d4e34 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -1326,7 +1326,7 @@ public final class CraftServer implements Server {
|
||||
}
|
||||
|
||||
// If set to not keep spawn in memory (changed from default) then adjust rule accordingly
|
||||
- if (!creator.keepSpawnInMemory()) {
|
||||
+ if (creator.keepSpawnLoaded() == net.kyori.adventure.util.TriState.FALSE) { // Paper
|
||||
worlddata.getGameRules().getRule(GameRules.RULE_SPAWN_CHUNK_RADIUS).set(0, null);
|
||||
}
|
||||
ServerLevel internal = (ServerLevel) new ServerLevel(this.console, this.console.executor, worldSession, worlddata, worldKey, worlddimension, this.getServer().progressListenerFactory.create(worlddata.getGameRules().getInt(GameRules.RULE_SPAWN_CHUNK_RADIUS)),
|
|
@ -1,19 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Gero <gecam59@gmail.com>
|
||||
Date: Sat, 2 Oct 2021 20:08:30 +0200
|
||||
Subject: [PATCH] Fix CME in CraftPersistentDataTypeRegistry
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataTypeRegistry.java b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataTypeRegistry.java
|
||||
index 71dc4a2285ddc86e7aa65ba1a211997ffa8fcce4..20c53aac0aef180ee12de919a8000e4b4bc619ff 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataTypeRegistry.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataTypeRegistry.java
|
||||
@@ -121,7 +121,7 @@ public final class CraftPersistentDataTypeRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
- private final Map<Class, TagAdapter> adapters = new HashMap<>();
|
||||
+ private final Map<Class, TagAdapter> adapters = new java.util.concurrent.ConcurrentHashMap<>(); // Paper - Replace HashMap with ConcurrentHashMap to avoid CME
|
||||
|
||||
/**
|
||||
* Creates a suitable adapter instance for the primitive class type.
|
Loading…
Add table
Add a link
Reference in a new issue