diff --git a/patches/api/0019-Add-PlayerPreRespawnEvent.patch b/patches/api/0019-Add-PlayerPreRespawnEvent.patch index 2073edba3..545d9d75e 100644 --- a/patches/api/0019-Add-PlayerPreRespawnEvent.patch +++ b/patches/api/0019-Add-PlayerPreRespawnEvent.patch @@ -6,29 +6,34 @@ Subject: [PATCH] Add PlayerPreRespawnEvent diff --git a/src/main/java/io/papermc/paper/event/player/PlayerPreRespawnEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerPreRespawnEvent.java new file mode 100644 -index 0000000000000000000000000000000000000000..c98a1e76e565d4b95b5fe31f734f8ab496348ecb +index 0000000000000000000000000000000000000000..53b830c7a349d58b1bb8b242b3edd144c6dcbdb0 --- /dev/null +++ b/src/main/java/io/papermc/paper/event/player/PlayerPreRespawnEvent.java -@@ -0,0 +1,54 @@ +@@ -0,0 +1,76 @@ +package io.papermc.paper.event.player; + +import org.apache.commons.lang3.Validate; +import org.bukkit.Location; +import org.bukkit.entity.Player; ++import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; ++import org.bukkit.event.player.PlayerRespawnEvent; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Called before a player's respawn location is determined. + */ -+public class PlayerPreRespawnEvent extends PlayerEvent { ++public class PlayerPreRespawnEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); ++ private final PlayerRespawnEvent.RespawnReason respawnReason; + private Location respawnLocation; ++ private boolean cancelled; + -+ public PlayerPreRespawnEvent(@NotNull final Player respawnPlayer) { ++ public PlayerPreRespawnEvent(@NotNull final Player respawnPlayer, PlayerRespawnEvent.RespawnReason respawnReason) { + super(respawnPlayer); ++ this.respawnReason = respawnReason; + } + + /** @@ -53,6 +58,13 @@ index 0000000000000000000000000000000000000000..c98a1e76e565d4b95b5fe31f734f8ab4 + this.respawnLocation = respawnLocation; + } + ++ /** ++ * @return Returns the reason the player was respawned. ++ */ ++ public PlayerRespawnEvent.RespawnReason getRespawnReason() { ++ return respawnReason; ++ } ++ + @NotNull + @Override + public HandlerList getHandlers() { @@ -63,4 +75,14 @@ index 0000000000000000000000000000000000000000..c98a1e76e565d4b95b5fe31f734f8ab4 + public static HandlerList getHandlerList() { + return handlers; + } ++ ++ @Override ++ public boolean isCancelled() { ++ return cancelled; ++ } ++ ++ @Override ++ public void setCancelled(boolean cancel) { ++ this.cancelled = cancel; ++ } +} diff --git a/patches/server/0029-Add-PlayerPreRespawnEvent.patch b/patches/server/0029-Add-PlayerPreRespawnEvent.patch index 16a2e93d4..43638551c 100644 --- a/patches/server/0029-Add-PlayerPreRespawnEvent.patch +++ b/patches/server/0029-Add-PlayerPreRespawnEvent.patch @@ -5,62 +5,45 @@ Subject: [PATCH] Add PlayerPreRespawnEvent diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 46f060f33fcbc6a4568a7fcfba29e83a4d192578..3f2f5673663b812cba05c058a7afd3598eb4685a 100644 +index 46f060f33fcbc6a4568a7fcfba29e83a4d192578..28b1ec198970b88515b37ef651c90916f3aef347 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -807,25 +807,37 @@ public abstract class PlayerList { - boolean isRespawn = false; +@@ -808,19 +808,31 @@ public abstract class PlayerList { // Paper end - Add PlayerPostRespawnEvent -- // CraftBukkit start - fire PlayerRespawnEvent + // CraftBukkit start - fire PlayerRespawnEvent - TeleportTransition teleporttransition; -- if (location == null) { ++ TeleportTransition teleporttransition = null; + if (location == null) { - teleporttransition = entityplayer.findRespawnPositionAndUseSpawnBlock(!flag, TeleportTransition.DO_NOTHING, reason); -- -- if (!flag) entityplayer.reset(); // SPIGOT-4785 ++ // Slice start ++ io.papermc.paper.event.player.PlayerPreRespawnEvent preRespawnEvent = new io.papermc.paper.event.player.PlayerPreRespawnEvent(entityplayer.getBukkitEntity(), reason); ++ if (!preRespawnEvent.callEvent()) return entityplayer; ++ ++ Location respawnLocation = preRespawnEvent.getRespawnLocation(); ++ if (respawnLocation != null) { ++ location = respawnLocation; ++ teleporttransition = new TeleportTransition(((CraftWorld) respawnLocation.getWorld()).getHandle(), CraftLocation.toVec3D(respawnLocation), Vec3.ZERO, respawnLocation.getYaw(), respawnLocation.getPitch(), TeleportTransition.DO_NOTHING); ++ } else { ++ teleporttransition = entityplayer.findRespawnPositionAndUseSpawnBlock(!flag, TeleportTransition.DO_NOTHING, reason); ++ } ++ // Slice end + + if (!flag) entityplayer.reset(); // SPIGOT-4785 - // Paper start - Add PlayerPostRespawnEvent - if (teleporttransition == null) return entityplayer; // Early exit, mirrors belows early return for disconnected players in respawn event - isRespawn = true; - location = CraftLocation.toBukkit(teleporttransition.position(), teleporttransition.newLevel().getWorld(), teleporttransition.yRot(), teleporttransition.xRot()); - // Paper end - Add PlayerPostRespawnEvent -- } else { -- teleporttransition = new TeleportTransition(((CraftWorld) location.getWorld()).getHandle(), CraftLocation.toVec3D(location), Vec3.ZERO, location.getYaw(), location.getPitch(), TeleportTransition.DO_NOTHING); -- } -- // Spigot Start -- if (teleporttransition == null) { // Paper - Add PlayerPostRespawnEvent - diff on change - spigot early returns if respawn pos is null, that is how they handle disconnected player in respawn event -- return entityplayer; -+ // Slice start -+ TeleportTransition teleporttransition = null; -+ io.papermc.paper.event.player.PlayerPreRespawnEvent preRespawnEvent = new io.papermc.paper.event.player.PlayerPreRespawnEvent(entityplayer.getBukkitEntity()); -+ preRespawnEvent.callEvent(); -+ Location respawnLocation = preRespawnEvent.getRespawnLocation(); -+ if (respawnLocation != null) { -+ teleporttransition = new TeleportTransition(((CraftWorld) respawnLocation.getWorld()).getHandle(), CraftLocation.toVec3D(respawnLocation), Vec3.ZERO, respawnLocation.getYaw(), respawnLocation.getPitch(), TeleportTransition.DO_NOTHING); -+ } -+ // Slice end -+ -+ if (teleporttransition == null) { -+ // CraftBukkit start - fire PlayerRespawnEvent -+ if (location == null) { -+ teleporttransition = entityplayer.findRespawnPositionAndUseSpawnBlock(!flag, TeleportTransition.DO_NOTHING, reason); -+ -+ if (!flag) entityplayer.reset(); // SPIGOT-4785 -+ // Paper start - Add PlayerPostRespawnEvent -+ if (teleporttransition == null) return entityplayer; // Early exit, mirrors belows early return for disconnected players in respawn event -+ isRespawn = true; -+ location = CraftLocation.toBukkit(teleporttransition.position(), teleporttransition.newLevel().getWorld(), teleporttransition.yRot(), teleporttransition.xRot()); -+ // Paper end - Add PlayerPostRespawnEvent -+ } else { -+ teleporttransition = new TeleportTransition(((CraftWorld) location.getWorld()).getHandle(), CraftLocation.toVec3D(location), Vec3.ZERO, location.getYaw(), location.getPitch(), TeleportTransition.DO_NOTHING); -+ } -+ -+ // Spigot Start -+ if (teleporttransition == null) { // Paper - Add PlayerPostRespawnEvent - diff on change - spigot early returns if respawn pos is null, that is how they handle disconnected player in respawn event -+ return entityplayer; -+ } -+ // Spigot End ++ // Paper start - Add PlayerPostRespawnEvent ++ if (teleporttransition == null || entityplayer.connection.isDisconnected()) return entityplayer; // Early exit, mirrors belows early return for disconnected players in respawn event ++ isRespawn = true; ++ location = CraftLocation.toBukkit(teleporttransition.position(), teleporttransition.newLevel().getWorld(), teleporttransition.yRot(), teleporttransition.xRot()); ++ // Paper end - Add PlayerPostRespawnEvent + } else { + teleporttransition = new TeleportTransition(((CraftWorld) location.getWorld()).getHandle(), CraftLocation.toVec3D(location), Vec3.ZERO, location.getYaw(), location.getPitch(), TeleportTransition.DO_NOTHING); } -- // Spigot End - ServerLevel worldserver = teleporttransition.newLevel(); - entityplayer1.spawnIn(worldserver); - entityplayer1.unsetRemoved(); ++ + // Spigot Start + if (teleporttransition == null) { // Paper - Add PlayerPostRespawnEvent - diff on change - spigot early returns if respawn pos is null, that is how they handle disconnected player in respawn event + return entityplayer; diff --git a/patches/server/0030-Fix-authorless-book-loading.patch b/patches/server/0030-Fix-authorless-book-loading.patch new file mode 100644 index 000000000..522d526aa --- /dev/null +++ b/patches/server/0030-Fix-authorless-book-loading.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Cryptite +Date: Sun, 29 Dec 2024 09:09:41 -0600 +Subject: [PATCH] Fix authorless book loading + + +diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +index 507f908916cbeb592496f963b46e4c2121a7b5e3..429eea868c749c5aece3e1afb96da760c154cfe1 100644 +--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java ++++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +@@ -24,6 +24,7 @@ import net.minecraft.commands.Commands; + import net.minecraft.commands.arguments.item.ItemParser; + import net.minecraft.core.registries.BuiltInRegistries; + import net.minecraft.core.registries.Registries; ++import net.minecraft.nbt.CompoundTag; + import net.minecraft.nbt.NbtOps; + import net.minecraft.nbt.StringTag; + import net.minecraft.nbt.Tag; +@@ -524,6 +525,15 @@ public final class CraftMagicNumbers implements UnsafeValues { + net.minecraft.nbt.CompoundTag compound = deserializeNbtFromBytes(data); + final int dataVersion = compound.getInt("DataVersion"); + compound = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ITEM_STACK, compound, dataVersion, this.getDataVersion()); // Paper - replace data conversion system ++ ++ CompoundTag components = compound.getCompound("components"); ++ if (!components.isEmpty()) { ++ CompoundTag bookContent = components.getCompound("minecraft:written_book_content"); ++ if (!bookContent.isEmpty() && !bookContent.getAllKeys().contains("author")) { ++ bookContent.putString("author", ""); ++ } ++ } ++ + return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.parse(MinecraftServer.getServer().registryAccess(), compound).orElseThrow()); + } +