From bce57808da430fc544a2eaff190b71d10d8e6739 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Sat, 30 Apr 2022 13:24:47 -0700 Subject: [PATCH] Couple fixes/improvements to PlayerSetSpawnEvent (#6754) --- patches/api/Add-PlayerSetSpawnEvent.patch | 4 +- patches/server/Add-PlayerSetSpawnEvent.patch | 46 +++++++++++++++++--- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/patches/api/Add-PlayerSetSpawnEvent.patch b/patches/api/Add-PlayerSetSpawnEvent.patch index 44dea43dac..2119863b80 100644 --- a/patches/api/Add-PlayerSetSpawnEvent.patch +++ b/patches/api/Add-PlayerSetSpawnEvent.patch @@ -58,7 +58,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + /** + * Gets the location that the spawn is set to. The yaw -+ * of this location is the spawn angle. ++ * of this location is the spawn angle. Mutating this location ++ * will change the resulting spawn point of the player. Use ++ * {@link Location#clone()} to get a copy of this location. + * + * @return the spawn location, or null if removing the location + */ diff --git a/patches/server/Add-PlayerSetSpawnEvent.patch b/patches/server/Add-PlayerSetSpawnEvent.patch index 3589a98d8d..45c32ff10e 100644 --- a/patches/server/Add-PlayerSetSpawnEvent.patch +++ b/patches/server/Add-PlayerSetSpawnEvent.patch @@ -9,14 +9,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/commands/SetSpawnCommand.java +++ b/src/main/java/net/minecraft/server/commands/SetSpawnCommand.java @@ -0,0 +0,0 @@ public class SetSpawnCommand { + private static int setSpawn(CommandSourceStack source, Collection targets, BlockPos pos, float angle) { ResourceKey resourceKey = source.getLevel().dimension(); ++ final Collection actualTargets = new java.util.ArrayList<>(); // Paper for(ServerPlayer serverPlayer : targets) { - serverPlayer.setRespawnPosition(resourceKey, pos, angle, true, false); -+ serverPlayer.setRespawnPosition(resourceKey, pos, angle, true, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.COMMAND); // Paper - PlayerSetSpawnEvent ++ // Paper start - PlayerSetSpawnEvent ++ if (serverPlayer.setRespawnPosition(resourceKey, pos, angle, true, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.COMMAND)) { ++ actualTargets.add(serverPlayer); ++ } ++ // Paper end } ++ // Paper start ++ if (actualTargets.isEmpty()) { ++ return 0; ++ } else { ++ targets = actualTargets; ++ } ++ // Paper end String string = resourceKey.location().toString(); + if (targets.size() == 1) { diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -39,7 +53,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start + this.setRespawnPosition(dimension, pos, angle, forced, sendMessage, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.UNKNOWN); + } -+ public void setRespawnPosition(ResourceKey dimension, @Nullable BlockPos pos, float angle, boolean forced, boolean sendMessage, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause cause) { ++ public boolean setRespawnPosition(ResourceKey dimension, @Nullable BlockPos pos, float angle, boolean forced, boolean sendMessage, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause cause) { + Location spawnLoc = null; + boolean willNotify = false; if (pos != null) { @@ -50,7 +64,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + com.destroystokyo.paper.event.player.PlayerSetSpawnEvent event = new com.destroystokyo.paper.event.player.PlayerSetSpawnEvent(this.getBukkitEntity(), cause, spawnLoc, forced, willNotify, willNotify ? net.kyori.adventure.text.Component.translatable("block.minecraft.set_spawn") : null); + if (!event.callEvent()) { -+ return; ++ return false; + } + if (event.getLocation() != null) { + dimension = event.getLocation().getWorld() != null ? ((CraftWorld) event.getLocation().getWorld()).getHandle().dimension() : dimension; @@ -66,6 +80,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } this.respawnPosition = pos; +@@ -0,0 +0,0 @@ public class ServerPlayer extends Player { + this.respawnForced = false; + } + ++ return true; // Paper + } + + public void trackChunk(ChunkPos chunkPos, Packet chunkDataPacket) { diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java @@ -79,6 +101,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 flag2 = !flag && flag3; isBedSpawn = true; location = new Location(worldserver1.getWorld(), vec3d.x, vec3d.y, vec3d.z, f1, 0.0F); + } else if (blockposition != null) { + entityplayer1.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.NO_RESPAWN_BLOCK_AVAILABLE, 0.0F)); +- entityplayer1.setRespawnPosition(null, null, 0f, false, false); // CraftBukkit - SPIGOT-5988: Clear respawn location when obstructed ++ entityplayer1.setRespawnPosition(null, null, 0f, false, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLAYER_RESPAWN); // CraftBukkit - SPIGOT-5988: Clear respawn location when obstructed // Paper - PlayerSetSpawnEvent + } + } + diff --git a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java @@ -88,10 +117,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 ServerPlayer serverPlayer = (ServerPlayer)player; if (serverPlayer.getRespawnDimension() != world.dimension() || !pos.equals(serverPlayer.getRespawnPosition())) { - serverPlayer.setRespawnPosition(world.dimension(), pos, 0.0F, false, true); -+ serverPlayer.setRespawnPosition(world.dimension(), pos, 0.0F, false, true, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.RESPAWN_ANCHOR); // Paper - PlayerSetSpawnEvent ++ if (serverPlayer.setRespawnPosition(world.dimension(), pos, 0.0F, false, true, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.RESPAWN_ANCHOR)) { // Paper - PlayerSetSpawnEvent world.playSound((Player)null, (double)pos.getX() + 0.5D, (double)pos.getY() + 0.5D, (double)pos.getZ() + 0.5D, SoundEvents.RESPAWN_ANCHOR_SET_SPAWN, SoundSource.BLOCKS, 1.0F, 1.0F); return InteractionResult.SUCCESS; ++ // Paper start - handle failed set spawn ++ } else { ++ return InteractionResult.FAIL; ++ } ++ // Paper end } + } + diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -104,7 +140,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.getHandle().setRespawnPosition(null, null, 0.0F, override, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLUGIN); // Paper - PlayerSetSpawnEvent } else { - this.getHandle().setRespawnPosition(((CraftWorld) location.getWorld()).getHandle().dimension(), new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), location.getYaw(), override, false); -+ this.getHandle().setRespawnPosition(((CraftWorld) location.getWorld()).getHandle().dimension(), new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), location.getYaw(), override, false); // Paper - PlayerSetSpawnEvent ++ this.getHandle().setRespawnPosition(((CraftWorld) location.getWorld()).getHandle().dimension(), new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), location.getYaw(), override, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLUGIN); // Paper - PlayerSetSpawnEvent } }