mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-03 05:26:50 +01:00
89d51d5f29
Because this exploit has been widely known for years and has not been fixed by Mojang, we decided that it was worth allowing people to toggle it on/off due to how easy it is to make it configurable. It should be noted that this decision does not promise all future exploits will be configurable.
116 lines
8.3 KiB
Diff
116 lines
8.3 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: TonytheMacaroni <tonythemacaroni123@gmail.com>
|
|
Date: Wed, 6 Sep 2023 19:24:16 -0400
|
|
Subject: [PATCH] Add predicate for blocks when raytracing
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/level/BlockGetter.java b/src/main/java/net/minecraft/world/level/BlockGetter.java
|
|
index c978f3b2d42f512e982f289e76c2422e41b7eec6..bb8e962e63c7a2d931f9bd7f7c002aa35cfa5fd3 100644
|
|
--- a/src/main/java/net/minecraft/world/level/BlockGetter.java
|
|
+++ b/src/main/java/net/minecraft/world/level/BlockGetter.java
|
|
@@ -70,6 +70,12 @@ public interface BlockGetter extends LevelHeightAccessor {
|
|
|
|
// CraftBukkit start - moved block handling into separate method for use by Block#rayTrace
|
|
default BlockHitResult clip(ClipContext raytrace1, BlockPos blockposition) {
|
|
+ // Paper start - Add predicate for blocks when raytracing
|
|
+ return clip(raytrace1, blockposition, null);
|
|
+ }
|
|
+
|
|
+ default BlockHitResult clip(ClipContext raytrace1, BlockPos blockposition, java.util.function.Predicate<? super org.bukkit.block.Block> canCollide) {
|
|
+ // Paper end - Add predicate for blocks when raytracing
|
|
// Paper start - Prevent raytrace from loading chunks
|
|
BlockState iblockdata = this.getBlockStateIfLoaded(blockposition);
|
|
if (iblockdata == null) {
|
|
@@ -79,7 +85,7 @@ public interface BlockGetter extends LevelHeightAccessor {
|
|
return BlockHitResult.miss(raytrace1.getTo(), Direction.getNearest(vec3d.x, vec3d.y, vec3d.z), BlockPos.containing(raytrace1.getTo()));
|
|
}
|
|
// Paper end - Prevent raytrace from loading chunks
|
|
- if (iblockdata.isAir()) return null; // Paper - Perf: optimise air cases
|
|
+ if (iblockdata.isAir() || (canCollide != null && this instanceof LevelAccessor levelAccessor && !canCollide.test(org.bukkit.craftbukkit.block.CraftBlock.at(levelAccessor, blockposition)))) return null; // Paper - Perf: optimise air cases & check canCollide predicate
|
|
FluidState fluid = iblockdata.getFluidState(); // Paper - Perf: don't need to go to world state again
|
|
Vec3 vec3d = raytrace1.getFrom();
|
|
Vec3 vec3d1 = raytrace1.getTo();
|
|
@@ -95,8 +101,14 @@ public interface BlockGetter extends LevelHeightAccessor {
|
|
// CraftBukkit end
|
|
|
|
default BlockHitResult clip(ClipContext context) {
|
|
+ // Paper start - Add predicate for blocks when raytracing
|
|
+ return clip(context, (java.util.function.Predicate<org.bukkit.block.Block>) null);
|
|
+ }
|
|
+
|
|
+ default BlockHitResult clip(ClipContext context, java.util.function.Predicate<? super org.bukkit.block.Block> canCollide) {
|
|
+ // Paper end - Add predicate for blocks when raytracing
|
|
return (BlockHitResult) BlockGetter.traverseBlocks(context.getFrom(), context.getTo(), context, (raytrace1, blockposition) -> {
|
|
- return this.clip(raytrace1, blockposition); // CraftBukkit - moved into separate method
|
|
+ return this.clip(raytrace1, blockposition, canCollide); // CraftBukkit - moved into separate method // Paper - Add predicate for blocks when raytracing
|
|
}, (raytrace1) -> {
|
|
Vec3 vec3d = raytrace1.getFrom().subtract(raytrace1.getTo());
|
|
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
|
index 457d5cdb510a11a069ac7f54a8ed95a74527bff3..be4fc09f9e30cb4bb5aaad49c23a19fd84f029bc 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
|
@@ -1105,9 +1105,15 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
|
|
|
@Override
|
|
public RayTraceResult rayTraceEntities(Location start, Vector direction, double maxDistance, double raySize, Predicate<? super Entity> filter) {
|
|
+ // Paper start - Add predicate for blocks when raytracing
|
|
+ return rayTraceEntities((io.papermc.paper.math.Position) start, direction, maxDistance, raySize, filter);
|
|
+ }
|
|
+
|
|
+ public RayTraceResult rayTraceEntities(io.papermc.paper.math.Position start, Vector direction, double maxDistance, double raySize, Predicate<? super Entity> filter) {
|
|
Preconditions.checkArgument(start != null, "Location start cannot be null");
|
|
- Preconditions.checkArgument(this.equals(start.getWorld()), "Location start cannot be in a different world");
|
|
- start.checkFinite();
|
|
+ Preconditions.checkArgument(!(start instanceof Location location) || this.equals(location.getWorld()), "Location start cannot be in a different world");
|
|
+ Preconditions.checkArgument(start.isFinite(), "Location start is not finite");
|
|
+ // Paper end - Add predicate for blocks when raytracing
|
|
|
|
Preconditions.checkArgument(direction != null, "Vector direction cannot be null");
|
|
direction.checkFinite();
|
|
@@ -1157,9 +1163,16 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
|
|
|
@Override
|
|
public RayTraceResult rayTraceBlocks(Location start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks) {
|
|
+ // Paper start - Add predicate for blocks when raytracing
|
|
+ return this.rayTraceBlocks(start, direction, maxDistance, fluidCollisionMode, ignorePassableBlocks, null);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public RayTraceResult rayTraceBlocks(io.papermc.paper.math.Position start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, Predicate<? super Block> canCollide) {
|
|
Preconditions.checkArgument(start != null, "Location start cannot be null");
|
|
- Preconditions.checkArgument(this.equals(start.getWorld()), "Location start cannot be in a different world");
|
|
- start.checkFinite();
|
|
+ Preconditions.checkArgument(!(start instanceof Location location) || this.equals(location.getWorld()), "Location start cannot be in a different world");
|
|
+ Preconditions.checkArgument(start.isFinite(), "Location start is not finite");
|
|
+ // Paper end - Add predicate for blocks when raytracing
|
|
|
|
Preconditions.checkArgument(direction != null, "Vector direction cannot be null");
|
|
direction.checkFinite();
|
|
@@ -1172,16 +1185,23 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
|
}
|
|
|
|
Vector dir = direction.clone().normalize().multiply(maxDistance);
|
|
- Vec3 startPos = CraftLocation.toVec3D(start);
|
|
+ Vec3 startPos = io.papermc.paper.util.MCUtil.toVec3(start); // Paper - Add predicate for blocks when raytracing
|
|
Vec3 endPos = startPos.add(dir.getX(), dir.getY(), dir.getZ());
|
|
- HitResult nmsHitResult = this.getHandle().clip(new ClipContext(startPos, endPos, ignorePassableBlocks ? ClipContext.Block.COLLIDER : ClipContext.Block.OUTLINE, CraftFluidCollisionMode.toNMS(fluidCollisionMode), CollisionContext.empty()));
|
|
+ HitResult nmsHitResult = this.getHandle().clip(new ClipContext(startPos, endPos, ignorePassableBlocks ? ClipContext.Block.COLLIDER : ClipContext.Block.OUTLINE, CraftFluidCollisionMode.toNMS(fluidCollisionMode), CollisionContext.empty()), canCollide); // Paper - Add predicate for blocks when raytracing
|
|
|
|
return CraftRayTraceResult.fromNMS(this, nmsHitResult);
|
|
}
|
|
|
|
@Override
|
|
public RayTraceResult rayTrace(Location start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, double raySize, Predicate<? super Entity> filter) {
|
|
- RayTraceResult blockHit = this.rayTraceBlocks(start, direction, maxDistance, fluidCollisionMode, ignorePassableBlocks);
|
|
+ // Paper start - Add predicate for blocks when raytracing
|
|
+ return this.rayTrace(start, direction, maxDistance, fluidCollisionMode, ignorePassableBlocks, raySize, filter, null);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public RayTraceResult rayTrace(io.papermc.paper.math.Position start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, double raySize, Predicate<? super Entity> filter, Predicate<? super Block> canCollide) {
|
|
+ RayTraceResult blockHit = this.rayTraceBlocks(start, direction, maxDistance, fluidCollisionMode, ignorePassableBlocks, canCollide);
|
|
+ // Paper end - Add predicate for blocks when raytracing
|
|
Vector startVec = null;
|
|
double blockHitDistance = maxDistance;
|
|
|