From f4ecbe7360fc36c1adb7e44060beeb505fee26b0 Mon Sep 17 00:00:00 2001 From: FlowerDevelops <257856104+FlowerDevelops@users.noreply.github.com> Date: Sun, 1 Nov 2026 01:09:26 +0100 Subject: [PATCH 1/9] Add 2 events regarding advancements being revoked --- ...PlayerAdvancementCriterionRevokeEvent.java | 61 +++++++++++++++++++ .../player/PlayerAdvancementRevokeEvent.java | 55 +++++++++++++++++ .../commands/AdvancementCommands.java.patch | 45 ++++++++++++++ 3 files changed, 161 insertions(+) create mode 100644 paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementCriterionRevokeEvent.java create mode 100644 paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementRevokeEvent.java create mode 100644 paper-server/patches/sources/net/minecraft/server/commands/AdvancementCommands.java.patch diff --git a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementCriterionRevokeEvent.java b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementCriterionRevokeEvent.java new file mode 100644 index 000000000000..53d3c53553d5 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementCriterionRevokeEvent.java @@ -0,0 +1,61 @@ +package io.papermc.paper.event.player; + +import org.bukkit.advancement.Advancement; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +/** + * An event fired when a {@link Player} has an advancement revoked + */ +@NullMarked +public final class PlayerAdvancementCriterionRevokeEvent extends Event implements Cancellable { + + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private boolean cancelled; + + private final Player player; + private final Advancement advancement; + private final String criterion; + + @ApiStatus.Internal + public PlayerAdvancementCriterionRevokeEvent(final Player player, Advancement advancement, String criterion) { + this.player = player; + this.advancement = advancement; + this.criterion = criterion; + } + + public Player getPlayer() + { + return this.player; + } + + public Advancement getAdvancement() { + return this.advancement; + } + + public String getCriterion() { + return this.criterion; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public boolean isCancelled() { + return this.cancelled; + } + + public void setCancelled(final boolean cancel) { + this.cancelled = cancel; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementRevokeEvent.java b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementRevokeEvent.java new file mode 100644 index 000000000000..0b7ba756b309 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementRevokeEvent.java @@ -0,0 +1,55 @@ +package io.papermc.paper.event.player; + +import org.bukkit.advancement.Advancement; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +/** + * An event fired when a {@link Player} has an advancement revoked + */ +@NullMarked +public final class PlayerAdvancementRevokeEvent extends Event implements Cancellable { + + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private boolean cancelled; + + private final Player player; + private final Advancement advancement; + + @ApiStatus.Internal + public PlayerAdvancementRevokeEvent(final Player player, Advancement advancement) { + this.player = player; + this.advancement = advancement; + } + + public Player getPlayer() + { + return this.player; + } + + public Advancement getAdvancement() { + return this.advancement; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public boolean isCancelled() { + return this.cancelled; + } + + public void setCancelled(final boolean cancel) { + this.cancelled = cancel; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/paper-server/patches/sources/net/minecraft/server/commands/AdvancementCommands.java.patch b/paper-server/patches/sources/net/minecraft/server/commands/AdvancementCommands.java.patch new file mode 100644 index 000000000000..e0062e05515b --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/server/commands/AdvancementCommands.java.patch @@ -0,0 +1,45 @@ +--- a/net/minecraft/server/commands/AdvancementCommands.java ++++ b/net/minecraft/server/commands/AdvancementCommands.java +@@ -338,6 +_,22 @@ + REVOKE("revoke") { + @Override + protected boolean perform(final ServerPlayer player, final AdvancementHolder advancement) { ++ // Paper start - Add PlayerAdvancementRevokeEvent ++ io.papermc.paper.event.player.PlayerAdvancementRevokeEvent event = ++ new io.papermc.paper.event.player.PlayerAdvancementRevokeEvent( ++ player.getBukkitEntity(), ++ advancement.toBukkit() ++ ); ++ ++ if (!event.callEvent()) { ++ return false; ++ } ++ ++ if (event.isCancelled()) { ++ return false; ++ } ++ // Paper end ++ + AdvancementProgress progress = player.getAdvancements().getOrStartProgress(advancement); + if (!progress.hasProgress()) { + return false; +@@ -352,6 +_,19 @@ + + @Override + protected boolean performCriterion(final ServerPlayer player, final AdvancementHolder advancement, final String criterion) { ++ // Paper start - Add PlayerAdvancementCriterionRevokeEvent ++ io.papermc.paper.event.player.PlayerAdvancementCriterionRevokeEvent event = ++ new io.papermc.paper.event.player.PlayerAdvancementCriterionRevokeEvent( ++ player.getBukkitEntity(), ++ advancement.toBukkit(), ++ criterion ++ ); ++ ++ if (!event.callEvent()) { ++ return false; ++ } ++ // Paper end ++ + return player.getAdvancements().revoke(advancement, criterion); + } + }; From 2b78b1c43876709cef95a20e0a2f9db732b696fd Mon Sep 17 00:00:00 2001 From: FlowerDevelops <257856104+FlowerDevelops@users.noreply.github.com> Date: Sun, 1 Nov 2026 08:52:34 +0100 Subject: [PATCH 2/9] Cleaned up the code --- ...PlayerAdvancementCriterionRevokeEvent.java | 12 ++----- .../player/PlayerAdvancementRevokeEvent.java | 12 ++----- .../server/PlayerAdvancements.java.patch | 33 ------------------- 3 files changed, 6 insertions(+), 51 deletions(-) diff --git a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementCriterionRevokeEvent.java b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementCriterionRevokeEvent.java index 53d3c53553d5..f84a342ca828 100644 --- a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementCriterionRevokeEvent.java +++ b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementCriterionRevokeEvent.java @@ -3,8 +3,8 @@ import org.bukkit.advancement.Advancement; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; -import org.bukkit.event.Event; import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; @@ -12,28 +12,22 @@ * An event fired when a {@link Player} has an advancement revoked */ @NullMarked -public final class PlayerAdvancementCriterionRevokeEvent extends Event implements Cancellable { +public final class PlayerAdvancementCriterionRevokeEvent extends PlayerEvent implements Cancellable { private static final HandlerList HANDLER_LIST = new HandlerList(); private boolean cancelled; - private final Player player; private final Advancement advancement; private final String criterion; @ApiStatus.Internal public PlayerAdvancementCriterionRevokeEvent(final Player player, Advancement advancement, String criterion) { - this.player = player; + super(player); this.advancement = advancement; this.criterion = criterion; } - public Player getPlayer() - { - return this.player; - } - public Advancement getAdvancement() { return this.advancement; } diff --git a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementRevokeEvent.java b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementRevokeEvent.java index 0b7ba756b309..9ad92d798f39 100644 --- a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementRevokeEvent.java +++ b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementRevokeEvent.java @@ -3,8 +3,8 @@ import org.bukkit.advancement.Advancement; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; -import org.bukkit.event.Event; import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; @@ -12,26 +12,20 @@ * An event fired when a {@link Player} has an advancement revoked */ @NullMarked -public final class PlayerAdvancementRevokeEvent extends Event implements Cancellable { +public final class PlayerAdvancementRevokeEvent extends PlayerEvent implements Cancellable { private static final HandlerList HANDLER_LIST = new HandlerList(); private boolean cancelled; - private final Player player; private final Advancement advancement; @ApiStatus.Internal public PlayerAdvancementRevokeEvent(final Player player, Advancement advancement) { - this.player = player; + super(player); this.advancement = advancement; } - public Player getPlayer() - { - return this.player; - } - public Advancement getAdvancement() { return this.advancement; } diff --git a/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch b/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch index 03e35ed5d3d2..4d586468390b 100644 --- a/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch @@ -25,39 +25,6 @@ LOGGER.warn("Ignored advancement '{}' in progress file {} - it doesn't exist anymore?", id, this.playerSavePath); } else { this.startProgress(advancement, progress); -@@ -169,14 +_,30 @@ - AdvancementProgress progress = this.getOrStartProgress(holder); - boolean wasDone = progress.isDone(); - if (progress.grantProgress(criterion)) { -+ // Paper start - Add PlayerAdvancementCriterionGrantEvent -+ if (!new com.destroystokyo.paper.event.player.PlayerAdvancementCriterionGrantEvent(this.player.getBukkitEntity(), holder.toBukkit(), criterion).callEvent()) { -+ progress.revokeProgress(criterion); -+ return false; -+ } -+ // Paper end - Add PlayerAdvancementCriterionGrantEvent - this.unregisterListeners(holder); - this.progressChanged.add(holder); - result = true; - if (!wasDone && progress.isDone()) { -+ // Paper start - Add Adventure message to PlayerAdvancementDoneEvent -+ final net.kyori.adventure.text.Component message = holder.value().display() -+ .filter(net.minecraft.advancements.DisplayInfo::announceToChat) -+ .map(display -> io.papermc.paper.adventure.PaperAdventure.asAdventure(display.type().createAnnouncement(holder, this.player))) -+ .orElse(null); -+ final org.bukkit.event.player.PlayerAdvancementDoneEvent event = new org.bukkit.event.player.PlayerAdvancementDoneEvent(this.player.getBukkitEntity(), holder.toBukkit(), message); -+ this.player.level().getCraftServer().getPluginManager().callEvent(event); // CraftBukkit -+ // Paper end - holder.value().rewards().grant(this.player); - holder.value().display().ifPresent(display -> { -- if (display.announceToChat() && this.player.level().getGameRules().get(GameRules.SHOW_ADVANCEMENT_MESSAGES)) { -- this.playerList.broadcastSystemMessage(display.type().createAnnouncement(holder, this.player), false); -+ // Paper start - Add Adventure message to PlayerAdvancementDoneEvent -+ if (event.message() != null && this.player.level().getGameRules().get(GameRules.SHOW_ADVANCEMENT_MESSAGES)) { -+ this.playerList.broadcastSystemMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.message()), false); -+ // Paper end - } - }); - } @@ -239,7 +_,7 @@ public void flushDirty(final ServerPlayer player, final boolean showAdvancements) { if (this.isFirstPacket || !this.rootsToUpdate.isEmpty() || !this.progressChanged.isEmpty()) { From d15c87ff23e0db8aceccdba0fe2cfcd9b4882ef7 Mon Sep 17 00:00:00 2001 From: FlowerDevelops <257856104+FlowerDevelops@users.noreply.github.com> Date: Sun, 1 Nov 2026 08:54:56 +0100 Subject: [PATCH 3/9] Readd accidentaly removed patch-code --- .../server/PlayerAdvancements.java.patch | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch b/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch index 4d586468390b..800d6b993e23 100644 --- a/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch @@ -25,6 +25,39 @@ LOGGER.warn("Ignored advancement '{}' in progress file {} - it doesn't exist anymore?", id, this.playerSavePath); } else { this.startProgress(advancement, progress); +@@ -169,14 +_,30 @@ + AdvancementProgress progress = this.getOrStartProgress(holder); + boolean wasDone = progress.isDone(); + if (progress.grantProgress(criterion)) { ++ // Paper start - Add PlayerAdvancementCriterionGrantEvent ++ if (!new com.destroystokyo.paper.event.player.PlayerAdvancementCriterionGrantEvent(this.player.getBukkitEntity(), holder.toBukkit(), criterion).callEvent()) { ++ progress.revokeProgress(criterion); ++ return false; ++ } ++ // Paper end - Add PlayerAdvancementCriterionGrantEvent + this.unregisterListeners(holder); + this.progressChanged.add(holder); + result = true; + if (!wasDone && progress.isDone()) { ++ // Paper start - Add Adventure message to PlayerAdvancementDoneEvent ++ final net.kyori.adventure.text.Component message = holder.value().display() ++ .filter(net.minecraft.advancements.DisplayInfo::announceToChat) ++ .map(display -> io.papermc.paper.adventure.PaperAdventure.asAdventure(display.type().createAnnouncement(holder, this.player))) ++ .orElse(null); ++ final org.bukkit.event.player.PlayerAdvancementDoneEvent event = new org.bukkit.event.player.PlayerAdvancementDoneEvent(this.player.getBukkitEntity(), holder.toBukkit(), message); ++ this.player.level().getCraftServer().getPluginManager().callEvent(event); // CraftBukkit ++ // Paper end + holder.value().rewards().grant(this.player); + holder.value().display().ifPresent(display -> { +- if (display.announceToChat() && this.player.level().getGameRules().get(GameRules.SHOW_ADVANCEMENT_MESSAGES)) { +- this.playerList.broadcastSystemMessage(display.type().createAnnouncement(holder, this.player), false); ++ // Paper start - Add Adventure message to PlayerAdvancementDoneEvent ++ if (event.message() != null && this.player.level().getGameRules().get(GameRules.SHOW_ADVANCEMENT_MESSAGES)) { ++ this.playerList.broadcastSystemMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.message()), false); ++ // Paper end + } + }); + } @@ -239,7 +_,7 @@ public void flushDirty(final ServerPlayer player, final boolean showAdvancements) { if (this.isFirstPacket || !this.rootsToUpdate.isEmpty() || !this.progressChanged.isEmpty()) { From 5c287c172c6025fd871e729b40794393730db5a6 Mon Sep 17 00:00:00 2001 From: FlowerDevelops <257856104+FlowerDevelops@users.noreply.github.com> Date: Sun, 1 Nov 2026 10:10:28 +0100 Subject: [PATCH 4/9] Moved firing logic of event --- .../commands/AdvancementCommands.java.patch | 45 ------------------- 1 file changed, 45 deletions(-) delete mode 100644 paper-server/patches/sources/net/minecraft/server/commands/AdvancementCommands.java.patch diff --git a/paper-server/patches/sources/net/minecraft/server/commands/AdvancementCommands.java.patch b/paper-server/patches/sources/net/minecraft/server/commands/AdvancementCommands.java.patch deleted file mode 100644 index e0062e05515b..000000000000 --- a/paper-server/patches/sources/net/minecraft/server/commands/AdvancementCommands.java.patch +++ /dev/null @@ -1,45 +0,0 @@ ---- a/net/minecraft/server/commands/AdvancementCommands.java -+++ b/net/minecraft/server/commands/AdvancementCommands.java -@@ -338,6 +_,22 @@ - REVOKE("revoke") { - @Override - protected boolean perform(final ServerPlayer player, final AdvancementHolder advancement) { -+ // Paper start - Add PlayerAdvancementRevokeEvent -+ io.papermc.paper.event.player.PlayerAdvancementRevokeEvent event = -+ new io.papermc.paper.event.player.PlayerAdvancementRevokeEvent( -+ player.getBukkitEntity(), -+ advancement.toBukkit() -+ ); -+ -+ if (!event.callEvent()) { -+ return false; -+ } -+ -+ if (event.isCancelled()) { -+ return false; -+ } -+ // Paper end -+ - AdvancementProgress progress = player.getAdvancements().getOrStartProgress(advancement); - if (!progress.hasProgress()) { - return false; -@@ -352,6 +_,19 @@ - - @Override - protected boolean performCriterion(final ServerPlayer player, final AdvancementHolder advancement, final String criterion) { -+ // Paper start - Add PlayerAdvancementCriterionRevokeEvent -+ io.papermc.paper.event.player.PlayerAdvancementCriterionRevokeEvent event = -+ new io.papermc.paper.event.player.PlayerAdvancementCriterionRevokeEvent( -+ player.getBukkitEntity(), -+ advancement.toBukkit(), -+ criterion -+ ); -+ -+ if (!event.callEvent()) { -+ return false; -+ } -+ // Paper end -+ - return player.getAdvancements().revoke(advancement, criterion); - } - }; From 55deb130932e39a1b366e9a28b26d7019052bacc Mon Sep 17 00:00:00 2001 From: FlowerDevelops <257856104+FlowerDevelops@users.noreply.github.com> Date: Sun, 1 Nov 2026 11:48:54 +0100 Subject: [PATCH 5/9] Actual patch now --- .../server/PlayerAdvancements.java.patch | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch b/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch index 800d6b993e23..653deca58787 100644 --- a/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch @@ -46,7 +46,7 @@ + .orElse(null); + final org.bukkit.event.player.PlayerAdvancementDoneEvent event = new org.bukkit.event.player.PlayerAdvancementDoneEvent(this.player.getBukkitEntity(), holder.toBukkit(), message); + this.player.level().getCraftServer().getPluginManager().callEvent(event); // CraftBukkit -+ // Paper end ++ // Paper end holder.value().rewards().grant(this.player); holder.value().display().ifPresent(display -> { - if (display.announceToChat() && this.player.level().getGameRules().get(GameRules.SHOW_ADVANCEMENT_MESSAGES)) { @@ -58,6 +58,32 @@ } }); } +@@ -193,10 +_,25 @@ + boolean result = false; + AdvancementProgress progress = this.getOrStartProgress(advancement); + boolean wasDone = progress.isDone(); ++ + if (progress.revokeProgress(criterion)) { ++ // Paper start - Add PlayerAdvancementCriterionRevokeEvent ++ if (!new io.papermc.paper.event.player.PlayerAdvancementCriterionRevokeEvent(this.player.getBukkitEntity(), advancement.toBukkit(), criterion).callEvent()) { ++ progress.grantProgress(criterion); ++ return false; ++ } ++ // Paper end - Add PlayerAdvancementCriterionRevokeEvent ++ + this.registerListeners(advancement); + this.progressChanged.add(advancement); + result = true; ++ ++ if (wasDone && !progress.isDone()) { ++ // Paper start - Add PlayerAdvancementRevokeEvent ++ final io.papermc.paper.event.player.PlayerAdvancementRevokeEvent event = new io.papermc.paper.event.player.PlayerAdvancementRevokeEvent(this.player.getBukkitEntity(), advancement.toBukkit()); ++ this.player.level().getCraftServer().getPluginManager().callEvent(event); ++ // Paper end - Add PlayerAdvancementRevokeEvent ++ } + } + + if (wasDone && !progress.isDone()) { @@ -239,7 +_,7 @@ public void flushDirty(final ServerPlayer player, final boolean showAdvancements) { if (this.isFirstPacket || !this.rootsToUpdate.isEmpty() || !this.progressChanged.isEmpty()) { From 57ce87ea0ecc4847139b1daa06a38720b924833d Mon Sep 17 00:00:00 2001 From: FlowerDevelops <257856104+FlowerDevelops@users.noreply.github.com> Date: Sun, 1 Nov 2026 18:06:32 +0100 Subject: [PATCH 6/9] Added a cancelled condition --- .../net/minecraft/server/PlayerAdvancements.java.patch | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch b/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch index 653deca58787..a36c051898c7 100644 --- a/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch @@ -58,7 +58,7 @@ } }); } -@@ -193,10 +_,25 @@ +@@ -193,10 +_,30 @@ boolean result = false; AdvancementProgress progress = this.getOrStartProgress(advancement); boolean wasDone = progress.isDone(); @@ -79,6 +79,11 @@ + // Paper start - Add PlayerAdvancementRevokeEvent + final io.papermc.paper.event.player.PlayerAdvancementRevokeEvent event = new io.papermc.paper.event.player.PlayerAdvancementRevokeEvent(this.player.getBukkitEntity(), advancement.toBukkit()); + this.player.level().getCraftServer().getPluginManager().callEvent(event); ++ ++ if (!event.callEvent()) { // Cancelled ++ progress.grantProgress(criterion); ++ return false; ++ } + // Paper end - Add PlayerAdvancementRevokeEvent + } } From 9c19ac1d6cd7d74ee356ed94741129d09e18c983 Mon Sep 17 00:00:00 2001 From: FlowerDevelops <257856104+FlowerDevelops@users.noreply.github.com> Date: Sun, 1 Nov 2026 19:29:24 +0100 Subject: [PATCH 7/9] Added Javadocs --- .../player/PlayerAdvancementCriterionRevokeEvent.java | 10 ++++++++++ .../event/player/PlayerAdvancementRevokeEvent.java | 5 +++++ 2 files changed, 15 insertions(+) diff --git a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementCriterionRevokeEvent.java b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementCriterionRevokeEvent.java index f84a342ca828..c55ebc33bb43 100644 --- a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementCriterionRevokeEvent.java +++ b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementCriterionRevokeEvent.java @@ -28,10 +28,20 @@ public PlayerAdvancementCriterionRevokeEvent(final Player player, Advancement ad this.criterion = criterion; } + /** + * Gets the advancement associated with this event. + * + * @return the advancement being revoked + */ public Advancement getAdvancement() { return this.advancement; } + /** + * Gets the criterion associated with this event. + * + * @return the criterion being revoked + */ public String getCriterion() { return this.criterion; } diff --git a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementRevokeEvent.java b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementRevokeEvent.java index 9ad92d798f39..e3bdc935f5db 100644 --- a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementRevokeEvent.java +++ b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementRevokeEvent.java @@ -26,6 +26,11 @@ public PlayerAdvancementRevokeEvent(final Player player, Advancement advancement this.advancement = advancement; } + /** + * Gets the advancement associated with this event. + * + * @return the advancement being revoked + */ public Advancement getAdvancement() { return this.advancement; } From 0ca2fbe93ffd97f389fa709641cb1290a2bed349 Mon Sep 17 00:00:00 2001 From: Doc Date: Sun, 1 Nov 2026 22:27:28 -0300 Subject: [PATCH 8/9] Remove double call of event --- .../net/minecraft/server/PlayerAdvancements.java.patch | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch b/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch index a36c051898c7..ccaeb23aea8e 100644 --- a/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch @@ -58,7 +58,7 @@ } }); } -@@ -193,10 +_,30 @@ +@@ -193,10 +_,28 @@ boolean result = false; AdvancementProgress progress = this.getOrStartProgress(advancement); boolean wasDone = progress.isDone(); @@ -78,9 +78,7 @@ + if (wasDone && !progress.isDone()) { + // Paper start - Add PlayerAdvancementRevokeEvent + final io.papermc.paper.event.player.PlayerAdvancementRevokeEvent event = new io.papermc.paper.event.player.PlayerAdvancementRevokeEvent(this.player.getBukkitEntity(), advancement.toBukkit()); -+ this.player.level().getCraftServer().getPluginManager().callEvent(event); -+ -+ if (!event.callEvent()) { // Cancelled ++ if (!event.callEvent()) { + progress.grantProgress(criterion); + return false; + } From 60df984851b98b7470e8b3363dc7d34d90e6d383 Mon Sep 17 00:00:00 2001 From: Doc Date: Sun, 1 Nov 2026 22:41:17 -0300 Subject: [PATCH 9/9] Improvements for the events Based in the grant/done events --- ...PlayerAdvancementCriterionRevokeEvent.java | 35 +++++++++++++------ .../player/PlayerAdvancementRevokeEvent.java | 22 ++++++------ 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementCriterionRevokeEvent.java b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementCriterionRevokeEvent.java index c55ebc33bb43..4b7ddecdca6b 100644 --- a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementCriterionRevokeEvent.java +++ b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementCriterionRevokeEvent.java @@ -1,6 +1,7 @@ package io.papermc.paper.event.player; import org.bukkit.advancement.Advancement; +import org.bukkit.advancement.AdvancementProgress; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; @@ -9,46 +10,53 @@ import org.jspecify.annotations.NullMarked; /** - * An event fired when a {@link Player} has an advancement revoked + * An event fired when a {@link Player} has an advancement revoked. + * If cancelled the criteria will be granted. */ @NullMarked public final class PlayerAdvancementCriterionRevokeEvent extends PlayerEvent implements Cancellable { private static final HandlerList HANDLER_LIST = new HandlerList(); - private boolean cancelled; - private final Advancement advancement; private final String criterion; + private final AdvancementProgress advancementProgress; + + private boolean cancelled; @ApiStatus.Internal - public PlayerAdvancementCriterionRevokeEvent(final Player player, Advancement advancement, String criterion) { + public PlayerAdvancementCriterionRevokeEvent(final Player player, final Advancement advancement, final String criterion) { super(player); this.advancement = advancement; this.criterion = criterion; + this.advancementProgress = player.getAdvancementProgress(advancement); } /** - * Gets the advancement associated with this event. + * Get the advancement which has been affected. * - * @return the advancement being revoked + * @return affected advancement */ public Advancement getAdvancement() { return this.advancement; } /** - * Gets the criterion associated with this event. + * Get the criterion which has been revoked. * - * @return the criterion being revoked + * @return revoked criterion */ public String getCriterion() { return this.criterion; } - @Override - public HandlerList getHandlers() { - return HANDLER_LIST; + /** + * Gets the current AdvancementProgress. + * + * @return advancement progress + */ + public AdvancementProgress getAdvancementProgress() { + return this.advancementProgress; } public boolean isCancelled() { @@ -59,6 +67,11 @@ public void setCancelled(final boolean cancel) { this.cancelled = cancel; } + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + public static HandlerList getHandlerList() { return HANDLER_LIST; } diff --git a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementRevokeEvent.java b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementRevokeEvent.java index e3bdc935f5db..0c0cfe625bd2 100644 --- a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementRevokeEvent.java +++ b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerAdvancementRevokeEvent.java @@ -9,37 +9,32 @@ import org.jspecify.annotations.NullMarked; /** - * An event fired when a {@link Player} has an advancement revoked + * An event fired when a {@link Player} has an advancement revoked. */ @NullMarked public final class PlayerAdvancementRevokeEvent extends PlayerEvent implements Cancellable { private static final HandlerList HANDLER_LIST = new HandlerList(); - private boolean cancelled; - private final Advancement advancement; + private boolean cancelled; + @ApiStatus.Internal - public PlayerAdvancementRevokeEvent(final Player player, Advancement advancement) { + public PlayerAdvancementRevokeEvent(final Player player, final Advancement advancement) { super(player); this.advancement = advancement; } /** - * Gets the advancement associated with this event. + * Get the advancement which has been revoked. * - * @return the advancement being revoked + * @return revoked advancement */ public Advancement getAdvancement() { return this.advancement; } - @Override - public HandlerList getHandlers() { - return HANDLER_LIST; - } - public boolean isCancelled() { return this.cancelled; } @@ -48,6 +43,11 @@ public void setCancelled(final boolean cancel) { this.cancelled = cancel; } + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + public static HandlerList getHandlerList() { return HANDLER_LIST; }