9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-25 09:59:15 +00:00

fix a regression caused by advencement fixing for PWT

This commit is contained in:
Taiyou06
2025-04-05 16:30:48 +02:00
parent 96c6601300
commit 15237645d5

View File

@@ -424,7 +424,7 @@ index c50a301a0c2365c2052aefc6a23fcf6fa82e1b9d..ac751d460ae0c8dbb858c4047c459a11
}
// CraftBukkit end
diff --git a/net/minecraft/server/PlayerAdvancements.java b/net/minecraft/server/PlayerAdvancements.java
index d2159a747fe42aa95cfc6bca0e55e3f4485847bb..8b74e9abba806a311f52b82732ce3c92638d50c4 100644
index d2159a747fe42aa95cfc6bca0e55e3f4485847bb..a7e1c9979897a12a7a8f417545ae96f703a1b248 100644
--- a/net/minecraft/server/PlayerAdvancements.java
+++ b/net/minecraft/server/PlayerAdvancements.java
@@ -19,6 +19,7 @@ import java.nio.file.Path;
@@ -435,94 +435,141 @@ index d2159a747fe42aa95cfc6bca0e55e3f4485847bb..8b74e9abba806a311f52b82732ce3c92
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
@@ -53,7 +54,8 @@ public class PlayerAdvancements {
@@ -53,8 +54,9 @@ public class PlayerAdvancements {
private AdvancementTree tree;
private final Map<AdvancementHolder, AdvancementProgress> progress = new LinkedHashMap<>();
private final Set<AdvancementHolder> visible = new HashSet<>();
- private final Set<AdvancementHolder> progressChanged = new HashSet<>();
+ private final Set<AdvancementHolder> progressChanged = new HashSet<>(); // Default implementation
+ private final Set<AdvancementHolder> progressChangedConcurrent = ConcurrentHashMap.newKeySet(); // Thread-safe implementation for parallel world ticking
private final Set<AdvancementNode> rootsToUpdate = new HashSet<>();
- private final Set<AdvancementNode> rootsToUpdate = new HashSet<>();
+ private final Set<AdvancementHolder> progressChanged = new HashSet<>(); // Used when PWT is disabled
+ private final Set<AdvancementHolder> progressChangedConcurrent = ConcurrentHashMap.newKeySet(); // Used when PWT is enabled
+ private final Set<AdvancementNode> rootsToUpdate = new HashSet<>(); // Always managed on player tick thread
private ServerPlayer player;
@Nullable
@@ -184,7 +186,13 @@ public class PlayerAdvancements {
private AdvancementHolder lastSelectedTab;
@@ -88,6 +90,8 @@ public class PlayerAdvancements {
this.visible.clear();
this.rootsToUpdate.clear();
this.progressChanged.clear();
+ // PWT Fix: Also clear concurrent set on reload
+ this.progressChangedConcurrent.clear();
this.isFirstPacket = true;
this.lastSelectedTab = null;
this.tree = manager.tree();
@@ -151,6 +155,7 @@ public class PlayerAdvancements {
if (org.galemc.gale.configuration.GaleGlobalConfiguration.get().logToConsole.ignoredAdvancements) LOGGER.warn("Ignored advancement '{}' in progress file {} - it doesn't exist anymore?", path, this.playerSavePath); // Gale - Purpur - do not log ignored advancements
} else {
this.startProgress(advancementHolder, progress);
+ // PWT Fix: Always add to non-concurrent set during load, flushDirty will handle sync
this.progressChanged.add(advancementHolder);
this.markForVisibilityUpdate(advancementHolder);
}
@@ -183,25 +188,25 @@ public class PlayerAdvancements {
return false;
}
// Paper end - Add PlayerAdvancementCriterionGrantEvent
this.unregisterListeners(advancement);
- this.unregisterListeners(advancement);
- this.progressChanged.add(advancement);
+
+ if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) {
+ this.progressChangedConcurrent.add(advancement);
+ } else {
+ this.progressChanged.add(advancement);
+ }
+
flag = true;
if (!isDone && orStartProgress.isDone()) {
- flag = true;
- if (!isDone && orStartProgress.isDone()) {
+ this.unregisterListeners(advancement); // Must unregister criteria listeners
+ (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled ? this.progressChangedConcurrent : this.progressChanged).add(advancement);
+ flag = true; // Mark progress changed
+ if (!isDone && orStartProgress.isDone()) { // If the advancement was just completed
// Paper start - Add Adventure message to PlayerAdvancementDoneEvent
@@ -221,7 +229,11 @@ public class PlayerAdvancements {
- final net.kyori.adventure.text.Component message = advancement.value().display().flatMap(info -> {
- return java.util.Optional.ofNullable(
- info.shouldAnnounceChat() ? io.papermc.paper.adventure.PaperAdventure.asAdventure(info.getType().createAnnouncement(advancement, this.player)) : null
- );
- }).orElse(null);
- final org.bukkit.event.player.PlayerAdvancementDoneEvent event = new org.bukkit.event.player.PlayerAdvancementDoneEvent(this.player.getBukkitEntity(), advancement.toBukkit(), message);
+ final net.kyori.adventure.text.Component message = advancement.value().display().flatMap(info -> { // Paper - Add Adventure message to PlayerAdvancementDoneEvent
+ return java.util.Optional.ofNullable( // Paper - Add Adventure message to PlayerAdvancementDoneEvent
+ info.shouldAnnounceChat() ? io.papermc.paper.adventure.PaperAdventure.asAdventure(info.getType().createAnnouncement(advancement, this.player)) : null // Paper - Add Adventure message to PlayerAdvancementDoneEvent
+ ); // Paper - Add Adventure message to PlayerAdvancementDoneEvent
+ }).orElse(null); // Paper - Add Adventure message to PlayerAdvancementDoneEvent
+ final org.bukkit.event.player.PlayerAdvancementDoneEvent event = new org.bukkit.event.player.PlayerAdvancementDoneEvent(this.player.getBukkitEntity(), advancement.toBukkit(), message); // Paper - Add Adventure message to PlayerAdvancementDoneEvent
this.player.level().getCraftServer().getPluginManager().callEvent(event); // CraftBukkit
// Paper end
advancement.value().rewards().grant(this.player);
advancement.value().display().ifPresent(displayInfo -> {
// Paper start - Add Adventure message to PlayerAdvancementDoneEvent
- if (event.message() != null && this.player.serverLevel().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) {
- if (org.purpurmc.purpur.PurpurConfig.advancementOnlyBroadcastToAffectedPlayer) this.player.sendMessage(message); else // Purpur - Configurable broadcast settings
- this.playerList.broadcastSystemMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.message()), false);
+ if (event.message() != null && this.player.serverLevel().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) { // Paper - Add Adventure message to PlayerAdvancementDoneEvent
+ if (org.purpurmc.purpur.PurpurConfig.advancementOnlyBroadcastToAffectedPlayer) this.player.sendMessage(message); else // Purpur - Configurable broadcast settings // Paper - Add Adventure message to PlayerAdvancementDoneEvent
+ this.playerList.broadcastSystemMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.message()), false); // Paper - Add Adventure message to PlayerAdvancementDoneEvent
// Paper end
}
});
@@ -220,12 +225,12 @@ public class PlayerAdvancements {
AdvancementProgress orStartProgress = this.getOrStartProgress(advancement);
boolean isDone = orStartProgress.isDone();
if (orStartProgress.revokeProgress(criterionKey)) {
this.registerListeners(advancement);
- this.registerListeners(advancement);
- this.progressChanged.add(advancement);
+ if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) {
+ this.progressChangedConcurrent.add(advancement);
+ } else {
+ this.progressChanged.add(advancement);
+ }
+ this.registerListeners(advancement); // Re-register listeners if it's no longer done
+ (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled ? this.progressChangedConcurrent : this.progressChanged).add(advancement);
flag = true;
}
@@ -271,7 +283,11 @@ public class PlayerAdvancements {
- if (isDone && !orStartProgress.isDone()) {
+ if (isDone && !orStartProgress.isDone()) { // If the advancement was just un-completed
this.markForVisibilityUpdate(advancement);
}
@@ -271,7 +276,9 @@ public class PlayerAdvancements {
}
public void flushDirty(ServerPlayer serverPlayer) {
- if (this.isFirstPacket || !this.rootsToUpdate.isEmpty() || !this.progressChanged.isEmpty()) {
+ boolean hasProgressChanges = org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled
+ ? !this.progressChangedConcurrent.isEmpty()
+ : !this.progressChanged.isEmpty();
+
+ if (this.isFirstPacket || !this.rootsToUpdate.isEmpty() || hasProgressChanges) {
+ final boolean useConcurrent = org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled;
+ final Set<AdvancementHolder> relevantProgressSet = useConcurrent ? this.progressChangedConcurrent : this.progressChanged;
+ if (this.isFirstPacket || !this.rootsToUpdate.isEmpty() || !relevantProgressSet.isEmpty()) {
Map<ResourceLocation, AdvancementProgress> map = new HashMap<>();
Set<AdvancementHolder> set = new java.util.TreeSet<>(java.util.Comparator.comparing(adv -> adv.id().toString())); // Paper - Changed from HashSet to TreeSet ordered alphabetically.
Set<ResourceLocation> set1 = new HashSet<>();
@@ -280,6 +296,19 @@ public class PlayerAdvancements {
@@ -279,16 +286,23 @@ public class PlayerAdvancements {
for (AdvancementNode advancementNode : this.rootsToUpdate) {
this.updateTreeVisibility(advancementNode, set, set1);
}
+ this.rootsToUpdate.clear(); // Roots processed, clear the set
+ // Process advancements with changed progress
+ if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) {
+ // Using concurrent set - create a copy to avoid possible ConcurrentModificationException
+ // during visualization and packet sending
+ Set<AdvancementHolder> copy = new HashSet<>(this.progressChangedConcurrent);
+ for (AdvancementHolder advancementHolder : copy) {
+ if (this.visible.contains(advancementHolder)) {
- this.rootsToUpdate.clear();
+ if (!relevantProgressSet.isEmpty()) {
+ Set<AdvancementHolder> toProcess = useConcurrent ? new HashSet<>(relevantProgressSet) : relevantProgressSet;
- for (AdvancementHolder advancementHolder : this.progressChanged) {
- if (this.visible.contains(advancementHolder)) {
- map.put(advancementHolder.id(), this.progress.get(advancementHolder));
+ for (AdvancementHolder advancementHolder : toProcess) {
+ if (this.visible.contains(advancementHolder)) { // Only include progress for visible advancements
+ map.put(advancementHolder.id(), this.progress.get(advancementHolder));
+ }
}
- }
- this.progressChanged.clear();
+ if (useConcurrent) {
+ this.progressChangedConcurrent.removeAll(toProcess); // Remove processed items from concurrent set
+ } else {
+ this.progressChanged.clear(); // Clear the regular set
+ }
+ this.progressChangedConcurrent.removeAll(copy);
+ } else {
+ // Original logic using non-concurrent set
this.rootsToUpdate.clear();
for (AdvancementHolder advancementHolder : this.progressChanged) {
@@ -289,6 +318,7 @@ public class PlayerAdvancements {
}
this.progressChanged.clear();
+ }
if (!map.isEmpty() || !set.isEmpty() || !set1.isEmpty()) {
serverPlayer.connection.send(new ClientboundUpdateAdvancementsPacket(this.isFirstPacket, set, set1, map));
}
@@ -334,6 +364,11 @@ public class PlayerAdvancements {
advancementOutput.add(advancementHolder);
@@ -331,9 +345,10 @@ public class PlayerAdvancements {
AdvancementHolder advancementHolder = node.holder();
if (visible) {
if (this.visible.add(advancementHolder)) {
- advancementOutput.add(advancementHolder);
+ advancementOutput.add(advancementHolder); // Add to visible set for packet
if (this.progress.containsKey(advancementHolder)) {
this.progressChanged.add(advancementHolder);
+ if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) {
+ this.progressChangedConcurrent.add(advancementHolder);
+ } else {
+ this.progressChanged.add(advancementHolder);
+ }
- this.progressChanged.add(advancementHolder);
+ // If progress exists, mark it changed so the progress data is sent
+ (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled ? this.progressChangedConcurrent : this.progressChanged).add(advancementHolder);
}
}
} else if (this.visible.remove(advancementHolder)) {