Paper/patches/server/0233-Vanished-players-don-t-have-rights.patch
Jason bc127ea819
Updated Upstream (Bukkit/CraftBukkit/Spigot) (#6222)
Upstream has released updates that appear to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

Bukkit Changes:
eec4aab0 SPIGOT-6657: Add getPlayer to SheepDyeWoolEvent
205213c6 SPIGOT-6656: CauldronLevelChangeEvent is not fired correctly when dripstone fills the cauldron

CraftBukkit Changes:
b8c522d5 SPIGOT-6657: Add getPlayer to SheepDyeWoolEvent
f04a77dc SPIGOT-6656: CauldronLevelChangeEvent is not fired correctly when dripstone fills the cauldron
d1dbcebc SPIGOT-6653: Canceling snow bucket placement removes snow from bucket
4f34a67b #891: Fix scheduler task ID overflow and duplication issues

Spigot Changes:
d03d7f12 BUILDTOOLS-604: Rebuild patches
2021-07-18 09:41:53 +02:00

120 lines
6.9 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hugo Manrique <hugmanrique@gmail.com>
Date: Mon, 23 Jul 2018 14:22:26 +0200
Subject: [PATCH] Vanished players don't have rights
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 b09f52330b50879d5594b21302e70ca676b60951..d7d4aa7ed2f321df8099adb97a3c699ed38ae6fc 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
@@ -209,7 +209,14 @@ public abstract class Projectile extends Entity {
if (!entity.isSpectator() && entity.isAlive() && entity.isPickable()) {
Entity entity1 = this.getOwner();
+ // Paper start - Cancel hit for vanished players
+ if (entity1 instanceof net.minecraft.server.level.ServerPlayer && entity instanceof net.minecraft.server.level.ServerPlayer) {
+ org.bukkit.entity.Player collided = (org.bukkit.entity.Player) entity.getBukkitEntity();
+ org.bukkit.entity.Player shooter = (org.bukkit.entity.Player) entity1.getBukkitEntity();
+ if (!shooter.canSee(collided)) return false;
+ }
return entity1 == null || this.leftOwner || !entity1.isPassengerOfSameVehicle(entity);
+ // Paper end
} else {
return false;
}
diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java
index b65736c8395c04b29f97d460a8559c2e44ed3a4f..8e6df16568c0dab482e10ad1b38920d77f6e684f 100644
--- a/src/main/java/net/minecraft/world/item/BlockItem.java
+++ b/src/main/java/net/minecraft/world/item/BlockItem.java
@@ -195,7 +195,8 @@ public class BlockItem extends Item {
Player entityhuman = context.getPlayer();
CollisionContext voxelshapecollision = entityhuman == null ? CollisionContext.empty() : CollisionContext.of((Entity) entityhuman);
// CraftBukkit start - store default return
- boolean defaultReturn = (!this.mustSurvive() || state.canSurvive(context.getLevel(), context.getClickedPos())) && context.getLevel().isUnobstructed(state, context.getClickedPos(), voxelshapecollision);
+ Level world = context.getLevel(); // Paper
+ boolean defaultReturn = (!this.mustSurvive() || state.canSurvive(context.getLevel(), context.getClickedPos())) && world.checkEntityCollision(state, entityhuman, voxelshapecollision, context.getClickedPos(), true); // Paper
org.bukkit.entity.Player player = (context.getPlayer() instanceof ServerPlayer) ? (org.bukkit.entity.Player) context.getPlayer().getBukkitEntity() : null;
BlockCanBuildEvent event = new BlockCanBuildEvent(CraftBlock.at(context.getLevel(), context.getClickedPos()), player, CraftBlockData.fromData(state), defaultReturn);
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index a84c8e135511eed9db5895bdf7fc68b3952a5521..1fef077a6d5efc8bdc171b5c6e2a49129f8589ce 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -71,6 +71,10 @@ import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
import net.minecraft.world.level.storage.LevelData;
import net.minecraft.world.level.storage.WritableLevelData;
import net.minecraft.world.phys.AABB;
+import net.minecraft.world.phys.shapes.BooleanOp;
+import net.minecraft.world.phys.shapes.CollisionContext;
+import net.minecraft.world.phys.shapes.Shapes;
+import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.world.scores.Scoreboard;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -249,6 +253,45 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
this.tileLimiter = new org.spigotmc.TickLimiter(spigotConfig.tileMaxTickTime);
}
+ // Paper start
+ // ret true if no collision
+ public final boolean checkEntityCollision(BlockState data, Entity source, CollisionContext voxelshapedcollision,
+ BlockPos position, boolean checkCanSee) {
+ // Copied from IWorldReader#a(IBlockData, BlockPosition, VoxelShapeCollision) & EntityAccess#a(Entity, VoxelShape)
+ VoxelShape voxelshape = data.getCollisionShape(this, position, voxelshapedcollision);
+ if (voxelshape.isEmpty()) {
+ return true;
+ }
+
+ voxelshape = voxelshape.move((double) position.getX(), (double) position.getY(), (double) position.getZ());
+ if (voxelshape.isEmpty()) {
+ return true;
+ }
+
+ List<Entity> entities = this.getEntities(null, voxelshape.bounds());
+ for (int i = 0, len = entities.size(); i < len; ++i) {
+ Entity entity = entities.get(i);
+
+ if (checkCanSee && source instanceof net.minecraft.server.level.ServerPlayer && entity instanceof net.minecraft.server.level.ServerPlayer
+ && !((net.minecraft.server.level.ServerPlayer) source).getBukkitEntity().canSee(((net.minecraft.server.level.ServerPlayer) entity).getBukkitEntity())) {
+ continue;
+ }
+
+ // !entity1.dead && entity1.i && (entity == null || !entity1.x(entity));
+ // elide the last check since vanilla calls with entity = null
+ // only we care about the source for the canSee check
+ if (entity.isRemoved() || !entity.blocksBuilding) {
+ continue;
+ }
+
+ if (Shapes.joinIsNotEmpty(voxelshape, Shapes.create(entity.getBoundingBox()), BooleanOp.AND)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ // Paper end
@Override
public boolean isClientSide() {
return this.isClientSide;
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index 7fab5ae695763350669fb20e3c765c947098d74e..5ea27e14b42336d60fa689f73e952aac76f0867c 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -1221,6 +1221,14 @@ public class CraftEventFactory {
Projectile projectile = (Projectile) entity.getBukkitEntity();
org.bukkit.entity.Entity collided = position.getEntity().getBukkitEntity();
com.destroystokyo.paper.event.entity.ProjectileCollideEvent event = new com.destroystokyo.paper.event.entity.ProjectileCollideEvent(projectile, collided);
+
+ if (projectile.getShooter() instanceof Player && collided instanceof Player) {
+ if (!((Player) projectile.getShooter()).canSee((Player) collided)) {
+ event.setCancelled(true);
+ return event;
+ }
+ }
+
Bukkit.getPluginManager().callEvent(event);
return event;
}