net.minecraft.world.level.portal

This commit is contained in:
Jake Potrebic
2024-12-14 11:20:46 -08:00
parent 7b75c1b42e
commit 3cce21ddce
6 changed files with 349 additions and 446 deletions

View File

@@ -0,0 +1,115 @@
--- a/net/minecraft/world/level/portal/PortalForcer.java
+++ b/net/minecraft/world/level/portal/PortalForcer.java
@@ -38,18 +_,32 @@
this.level = level;
}
+ @io.papermc.paper.annotation.DoNotUse // Paper
public Optional<BlockPos> findClosestPortalPosition(BlockPos exitPos, boolean isNether, WorldBorder worldBorder) {
+ // CraftBukkit start
+ return this.findClosestPortalPosition(exitPos, worldBorder, isNether ? 16 : 128); // Search Radius
+ }
+
+ public Optional<BlockPos> findClosestPortalPosition(BlockPos exitPos, WorldBorder worldBorder, int i) {
PoiManager poiManager = this.level.getPoiManager();
- int i = isNether ? 16 : 128;
+ // int i = isNether ? 16 : 128;
+ // CraftBukkit end
poiManager.ensureLoadedAndValid(this.level, exitPos, i);
return poiManager.getInSquare(holder -> holder.is(PoiTypes.NETHER_PORTAL), exitPos, i, PoiManager.Occupancy.ANY)
.map(PoiRecord::getPos)
.filter(worldBorder::isWithinBounds)
+ .filter(pos -> !(this.level.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.NETHER && this.level.paperConfig().environment.netherCeilingVoidDamageHeight.test(v -> pos.getY() >= v))) // Paper - Configurable nether ceiling damage
.filter(blockPos -> this.level.getBlockState(blockPos).hasProperty(BlockStateProperties.HORIZONTAL_AXIS))
.min(Comparator.<BlockPos>comparingDouble(blockPos -> blockPos.distSqr(exitPos)).thenComparingInt(Vec3i::getY));
}
public Optional<BlockUtil.FoundRectangle> createPortal(BlockPos pos, Direction.Axis axis) {
+ // CraftBukkit start
+ return this.createPortal(pos, axis, null, 16);
+ }
+
+ public Optional<BlockUtil.FoundRectangle> createPortal(BlockPos pos, Direction.Axis axis, net.minecraft.world.entity.Entity entity, int createRadius) {
+ // CraftBukkit end
Direction direction = Direction.get(Direction.AxisDirection.POSITIVE, axis);
double d = -1.0;
BlockPos blockPos = null;
@@ -57,10 +_,15 @@
BlockPos blockPos1 = null;
WorldBorder worldBorder = this.level.getWorldBorder();
int min = Math.min(this.level.getMaxY(), this.level.getMinY() + this.level.getLogicalHeight() - 1);
+ // Paper start - Configurable nether ceiling damage; make sure the max height doesn't exceed the void damage height
+ if (this.level.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.NETHER && this.level.paperConfig().environment.netherCeilingVoidDamageHeight.enabled()) {
+ min = Math.min(min, this.level.paperConfig().environment.netherCeilingVoidDamageHeight.intValue() - 1);
+ }
+ // Paper end - Configurable nether ceiling damage
int i = 1;
BlockPos.MutableBlockPos mutableBlockPos = pos.mutable();
- for (BlockPos.MutableBlockPos mutableBlockPos1 : BlockPos.spiralAround(pos, 16, Direction.EAST, Direction.SOUTH)) {
+ for (BlockPos.MutableBlockPos mutableBlockPos1 : BlockPos.spiralAround(pos, createRadius, Direction.EAST, Direction.SOUTH)) { // CraftBukkit
int min1 = Math.min(min, this.level.getHeight(Heightmap.Types.MOTION_BLOCKING, mutableBlockPos1.getX(), mutableBlockPos1.getZ()));
if (worldBorder.isWithinBounds(mutableBlockPos1) && worldBorder.isWithinBounds(mutableBlockPos1.move(direction, 1))) {
mutableBlockPos1.move(direction.getOpposite(), 1);
@@ -104,6 +_,7 @@
d = d1;
}
+ org.bukkit.craftbukkit.util.BlockStateListPopulator blockList = new org.bukkit.craftbukkit.util.BlockStateListPopulator(this.level); // CraftBukkit - Use BlockStateListPopulator
if (d == -1.0) {
int max = Math.max(this.level.getMinY() - -1, 70);
int i4 = min - 9;
@@ -122,7 +_,7 @@
mutableBlockPos.setWithOffset(
blockPos, i2 * direction.getStepX() + i1x * clockWise.getStepX(), i3, i2 * direction.getStepZ() + i1x * clockWise.getStepZ()
);
- this.level.setBlockAndUpdate(mutableBlockPos, blockState);
+ blockList.setBlock(mutableBlockPos, blockState, 3); // CraftBukkit
}
}
}
@@ -132,7 +_,7 @@
for (int i4 = -1; i4 < 4; i4++) {
if (max == -1 || max == 2 || i4 == -1 || i4 == 3) {
mutableBlockPos.setWithOffset(blockPos, max * direction.getStepX(), i4, max * direction.getStepZ());
- this.level.setBlock(mutableBlockPos, Blocks.OBSIDIAN.defaultBlockState(), 3);
+ blockList.setBlock(mutableBlockPos, Blocks.OBSIDIAN.defaultBlockState(), 3); // CraftBukkit
}
}
}
@@ -142,10 +_,20 @@
for (int i4x = 0; i4x < 2; i4x++) {
for (int min1 = 0; min1 < 3; min1++) {
mutableBlockPos.setWithOffset(blockPos, i4x * direction.getStepX(), min1, i4x * direction.getStepZ());
- this.level.setBlock(mutableBlockPos, blockState1, 18);
+ blockList.setBlock(mutableBlockPos, blockState1, 18); // CraftBukkit
}
}
+ // CraftBukkit start
+ org.bukkit.World bworld = this.level.getWorld();
+ org.bukkit.event.world.PortalCreateEvent event = new org.bukkit.event.world.PortalCreateEvent((java.util.List<org.bukkit.block.BlockState>) (java.util.List) blockList.getList(), bworld, (entity == null) ? null : entity.getBukkitEntity(), org.bukkit.event.world.PortalCreateEvent.CreateReason.NETHER_PAIR);
+
+ this.level.getCraftServer().getPluginManager().callEvent(event);
+ if (event.isCancelled()) {
+ return Optional.empty();
+ }
+ blockList.updateList();
+ // CraftBukkit end
return Optional.of(new BlockUtil.FoundRectangle(blockPos.immutable(), 2, 3));
}
@@ -165,6 +_,13 @@
i1,
direction.getStepZ() * i + clockWise.getStepZ() * offsetScale
);
+ // Paper start - Protect Bedrock and End Portal/Frames from being destroyed
+ if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits) {
+ if (!this.level.getBlockState(offsetPos).isDestroyable()) {
+ return false;
+ }
+ }
+ // Paper end - Protect Bedrock and End Portal/Frames from being destroyed
if (i1 < 0 && !this.level.getBlockState(offsetPos).isSolid()) {
return false;
}

View File

@@ -0,0 +1,154 @@
--- a/net/minecraft/world/level/portal/PortalShape.java
+++ b/net/minecraft/world/level/portal/PortalShape.java
@@ -37,8 +_,12 @@
private final BlockPos bottomLeft;
private final int height;
private final int width;
+ // CraftBukkit start - add field
+ private final org.bukkit.craftbukkit.util.BlockStateListPopulator blocks;
- private PortalShape(Direction.Axis axis, int numPortalBlocks, Direction rightDir, BlockPos bottomLeft, int width, int height) {
+ private PortalShape(Direction.Axis axis, int numPortalBlocks, Direction rightDir, BlockPos bottomLeft, int width, int height, org.bukkit.craftbukkit.util.BlockStateListPopulator blocks) {
+ this.blocks = blocks;
+ // CraftBukkit end
this.axis = axis;
this.numPortalBlocks = numPortalBlocks;
this.rightDir = rightDir;
@@ -62,24 +_,25 @@
}
public static PortalShape findAnyShape(BlockGetter level, BlockPos bottomLeft, Direction.Axis axis) {
+ org.bukkit.craftbukkit.util.BlockStateListPopulator blocks = new org.bukkit.craftbukkit.util.BlockStateListPopulator(((LevelAccessor) level).getMinecraftWorld()); // CraftBukkit
Direction direction = axis == Direction.Axis.X ? Direction.WEST : Direction.SOUTH;
- BlockPos blockPos = calculateBottomLeft(level, direction, bottomLeft);
+ BlockPos blockPos = calculateBottomLeft(level, direction, bottomLeft, blocks); // CraftBukkit
if (blockPos == null) {
- return new PortalShape(axis, 0, direction, bottomLeft, 0, 0);
+ return new PortalShape(axis, 0, direction, bottomLeft, 0, 0, blocks); // CraftBukkit
} else {
- int i = calculateWidth(level, blockPos, direction);
+ int i = calculateWidth(level, blockPos, direction, blocks); // CraftBukkit
if (i == 0) {
- return new PortalShape(axis, 0, direction, blockPos, 0, 0);
+ return new PortalShape(axis, 0, direction, blockPos, 0, 0, blocks); // CraftBukkit
} else {
MutableInt mutableInt = new MutableInt();
- int i1 = calculateHeight(level, blockPos, direction, i, mutableInt);
- return new PortalShape(axis, mutableInt.getValue(), direction, blockPos, i, i1);
+ int i1 = calculateHeight(level, blockPos, direction, i, mutableInt, blocks); // CraftBukkit
+ return new PortalShape(axis, mutableInt.getValue(), direction, blockPos, i, i1, blocks); // CraftBukkit
}
}
}
@Nullable
- private static BlockPos calculateBottomLeft(BlockGetter level, Direction direction, BlockPos pos) {
+ private static BlockPos calculateBottomLeft(BlockGetter level, Direction direction, BlockPos pos, org.bukkit.craftbukkit.util.BlockStateListPopulator blocks) { // CraftBukkit
int max = Math.max(level.getMinY(), pos.getY() - 21);
while (pos.getY() > max && isEmpty(level.getBlockState(pos.below()))) {
@@ -87,16 +_,16 @@
}
Direction opposite = direction.getOpposite();
- int i = getDistanceUntilEdgeAboveFrame(level, pos, opposite) - 1;
+ int i = getDistanceUntilEdgeAboveFrame(level, pos, opposite, blocks) - 1; // CraftBukkit
return i < 0 ? null : pos.relative(opposite, i);
}
- private static int calculateWidth(BlockGetter level, BlockPos bottomLeft, Direction direction) {
- int distanceUntilEdgeAboveFrame = getDistanceUntilEdgeAboveFrame(level, bottomLeft, direction);
+ private static int calculateWidth(BlockGetter level, BlockPos bottomLeft, Direction direction, org.bukkit.craftbukkit.util.BlockStateListPopulator blocks) { // CraftBukkit
+ int distanceUntilEdgeAboveFrame = getDistanceUntilEdgeAboveFrame(level, bottomLeft, direction, blocks); // CraftBukkit
return distanceUntilEdgeAboveFrame >= 2 && distanceUntilEdgeAboveFrame <= 21 ? distanceUntilEdgeAboveFrame : 0;
}
- private static int getDistanceUntilEdgeAboveFrame(BlockGetter level, BlockPos pos, Direction direction) {
+ private static int getDistanceUntilEdgeAboveFrame(BlockGetter level, BlockPos pos, Direction direction, org.bukkit.craftbukkit.util.BlockStateListPopulator blocks) { // CraftBukkit
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
for (int i = 0; i <= 21; i++) {
@@ -104,6 +_,7 @@
BlockState blockState = level.getBlockState(mutableBlockPos);
if (!isEmpty(blockState)) {
if (FRAME.test(blockState, level, mutableBlockPos)) {
+ blocks.setBlock(mutableBlockPos, blockState, 18); // CraftBukkit - lower left / right
return i;
}
break;
@@ -113,32 +_,34 @@
if (!FRAME.test(blockState1, level, mutableBlockPos)) {
break;
}
+ blocks.setBlock(mutableBlockPos, blockState1, 18); // CraftBukkit - bottom row
}
return 0;
}
- private static int calculateHeight(BlockGetter level, BlockPos pos, Direction direction, int width, MutableInt portalBlocks) {
+ private static int calculateHeight(BlockGetter level, BlockPos pos, Direction direction, int width, MutableInt portalBlocks, org.bukkit.craftbukkit.util.BlockStateListPopulator blocks) { // CraftBukkit
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
- int distanceUntilTop = getDistanceUntilTop(level, pos, direction, mutableBlockPos, width, portalBlocks);
- return distanceUntilTop >= 3 && distanceUntilTop <= 21 && hasTopFrame(level, pos, direction, mutableBlockPos, width, distanceUntilTop)
+ int distanceUntilTop = getDistanceUntilTop(level, pos, direction, mutableBlockPos, width, portalBlocks, blocks); // CraftBukkit
+ return distanceUntilTop >= 3 && distanceUntilTop <= 21 && hasTopFrame(level, pos, direction, mutableBlockPos, width, distanceUntilTop, blocks) // CraftBukkit
? distanceUntilTop
: 0;
}
- private static boolean hasTopFrame(BlockGetter level, BlockPos pos, Direction direction, BlockPos.MutableBlockPos checkPos, int width, int distanceUntilTop) {
+ private static boolean hasTopFrame(BlockGetter level, BlockPos pos, Direction direction, BlockPos.MutableBlockPos checkPos, int width, int distanceUntilTop, org.bukkit.craftbukkit.util.BlockStateListPopulator blocks) { // CraftBukkit
for (int i = 0; i < width; i++) {
BlockPos.MutableBlockPos mutableBlockPos = checkPos.set(pos).move(Direction.UP, distanceUntilTop).move(direction, i);
if (!FRAME.test(level.getBlockState(mutableBlockPos), level, mutableBlockPos)) {
return false;
}
+ blocks.setBlock(mutableBlockPos, level.getBlockState(mutableBlockPos), 18); // CraftBukkit - upper row
}
return true;
}
private static int getDistanceUntilTop(
- BlockGetter level, BlockPos pos, Direction direction, BlockPos.MutableBlockPos checkPos, int width, MutableInt portalBlocks
+ BlockGetter level, BlockPos pos, Direction direction, BlockPos.MutableBlockPos checkPos, int width, MutableInt portalBlocks, org.bukkit.craftbukkit.util.BlockStateListPopulator blocks // CraftBukkit
) {
for (int i = 0; i < 21; i++) {
checkPos.set(pos).move(Direction.UP, i).move(direction, -1);
@@ -162,6 +_,10 @@
portalBlocks.increment();
}
}
+ // CraftBukkit start - left and right
+ blocks.setBlock(checkPos.set(pos).move(Direction.UP, i).move(direction, -1), level.getBlockState(checkPos), 18);
+ blocks.setBlock(checkPos.set(pos).move(Direction.UP, i).move(direction, i), level.getBlockState(checkPos), 18);
+ // CraftBukkit end
}
return 21;
@@ -175,10 +_,23 @@
return this.width >= 2 && this.width <= 21 && this.height >= 3 && this.height <= 21;
}
- public void createPortalBlocks(LevelAccessor level) {
+ // CraftBukkit start - return boolean, add entity
+ public boolean createPortalBlocks(LevelAccessor level, Entity entity) {
+ org.bukkit.World bworld = level.getMinecraftWorld().getWorld();
+ // Copy below for loop
BlockState blockState = Blocks.NETHER_PORTAL.defaultBlockState().setValue(NetherPortalBlock.AXIS, this.axis);
BlockPos.betweenClosed(this.bottomLeft, this.bottomLeft.relative(Direction.UP, this.height - 1).relative(this.rightDir, this.width - 1))
+ .forEach(pos -> this.blocks.setBlock(pos, blockState, 18));
+ org.bukkit.event.world.PortalCreateEvent event = new org.bukkit.event.world.PortalCreateEvent((java.util.List<org.bukkit.block.BlockState>) (java.util.List) this.blocks.getList(), bworld, (entity == null) ? null : entity.getBukkitEntity(), org.bukkit.event.world.PortalCreateEvent.CreateReason.FIRE);
+ level.getMinecraftWorld().getServer().server.getPluginManager().callEvent(event);
+
+ if (event.isCancelled()) {
+ return false;
+ }
+ // CraftBukkit end
+ BlockPos.betweenClosed(this.bottomLeft, this.bottomLeft.relative(Direction.UP, this.height - 1).relative(this.rightDir, this.width - 1))
.forEach(pos -> level.setBlock(pos, blockState, 18));
+ return true; // CraftBukkit
}
public boolean isComplete() {

View File

@@ -0,0 +1,80 @@
--- a/net/minecraft/world/level/portal/TeleportTransition.java
+++ b/net/minecraft/world/level/portal/TeleportTransition.java
@@ -19,15 +_,34 @@
boolean asPassenger,
Set<Relative> relatives,
TeleportTransition.PostTeleportTransition postTeleportTransition
+ , org.bukkit.event.player.PlayerTeleportEvent.TeleportCause cause // CraftBukkit
) {
public static final TeleportTransition.PostTeleportTransition DO_NOTHING = entity -> {};
public static final TeleportTransition.PostTeleportTransition PLAY_PORTAL_SOUND = TeleportTransition::playPortalSound;
public static final TeleportTransition.PostTeleportTransition PLACE_PORTAL_TICKET = TeleportTransition::placePortalTicket;
+ // CraftBukkit start
+ public TeleportTransition(ServerLevel newLevel, Vec3 position, Vec3 deltaMovement, float yRot, float xRot, boolean missingRespawnBlock, boolean asPassenger, Set<Relative> relatives, TeleportTransition.PostTeleportTransition postTeleportTransition) {
+ this(newLevel, position, deltaMovement, yRot, xRot, missingRespawnBlock, asPassenger, relatives, postTeleportTransition, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.UNKNOWN);
+ }
+
+ public TeleportTransition(org.bukkit.event.player.PlayerTeleportEvent.TeleportCause cause) {
+ this(null, Vec3.ZERO, Vec3.ZERO, 0.0F, 0.0F, false, false, Set.of(), DO_NOTHING, cause);
+ }
+ // CraftBukkit end
+
public TeleportTransition(
ServerLevel newLevel, Vec3 position, Vec3 deltaMovement, float yRot, float xRot, TeleportTransition.PostTeleportTransition postTeleportTransition
) {
- this(newLevel, position, deltaMovement, yRot, xRot, Set.of(), postTeleportTransition);
+ // CraftBukkit start
+ this(newLevel, position, deltaMovement, yRot, xRot, postTeleportTransition, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.UNKNOWN);
+ }
+
+ public TeleportTransition(
+ ServerLevel newLevel, Vec3 position, Vec3 deltaMovement, float yRot, float xRot, TeleportTransition.PostTeleportTransition postTeleportTransition, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause cause
+ ) {
+ this(newLevel, position, deltaMovement, yRot, xRot, Set.of(), postTeleportTransition, cause);
+ // CraftBukkit end
}
public TeleportTransition(
@@ -39,11 +_,30 @@
Set<Relative> relatives,
TeleportTransition.PostTeleportTransition postTeleportTransition
) {
- this(newLevel, position, deltaMovement, yRot, xRot, false, false, relatives, postTeleportTransition);
+ // CraftBukkit start
+ this(newLevel, position, deltaMovement, yRot, xRot, relatives, postTeleportTransition, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.UNKNOWN);
+ }
+ public TeleportTransition(
+ ServerLevel newLevel,
+ Vec3 position,
+ Vec3 deltaMovement,
+ float yRot,
+ float xRot,
+ Set<Relative> relatives,
+ TeleportTransition.PostTeleportTransition postTeleportTransition,
+ org.bukkit.event.player.PlayerTeleportEvent.TeleportCause cause
+ ) {
+ this(newLevel, position, deltaMovement, yRot, xRot, false, false, relatives, postTeleportTransition, cause);
+ // CraftBukkit end
}
public TeleportTransition(ServerLevel level, Entity entity, TeleportTransition.PostTeleportTransition postTeleportTransition) {
- this(level, findAdjustedSharedSpawnPos(level, entity), Vec3.ZERO, 0.0F, 0.0F, false, false, Set.of(), postTeleportTransition);
+ // CraftBukkit start
+ this(level, entity, postTeleportTransition, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.UNKNOWN);
+ }
+ public TeleportTransition(ServerLevel level, Entity entity, TeleportTransition.PostTeleportTransition postTeleportTransition, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause cause) {
+ this(level, findAdjustedSharedSpawnPos(level, entity), Vec3.ZERO, level.getSharedSpawnAngle(), 0.0F, false, false, Set.of(), postTeleportTransition, cause); // Paper - MC-200092 - fix first spawn pos yaw being ignored
+ // CraftBukkit end
}
private static void playPortalSound(Entity entity) {
@@ -57,7 +_,7 @@
}
public static TeleportTransition missingRespawnBlock(ServerLevel level, Entity entity, TeleportTransition.PostTeleportTransition postTeleportTransition) {
- return new TeleportTransition(level, findAdjustedSharedSpawnPos(level, entity), Vec3.ZERO, 0.0F, 0.0F, true, false, Set.of(), postTeleportTransition);
+ return new TeleportTransition(level, findAdjustedSharedSpawnPos(level, entity), Vec3.ZERO, level.getSharedSpawnAngle(), 0.0F, true, false, Set.of(), postTeleportTransition); // Paper - MC-200092 - fix spawn pos yaw being ignored
}
private static Vec3 findAdjustedSharedSpawnPos(ServerLevel level, Entity entity) {