mirror of
https://github.com/PaperMC/Paper.git
synced 2024-10-30 23:39:58 +01:00
aa52bf9e33
Mojang made some changes to priorities in 1.17 and it seems that these changes conflict with the changes made in this patch, which in some cases appears to cause excessive rescheduling of tasks. This, however, is not confirmed as such but seems to be the behavior that we're seeing to cause this issue, if mojang has adopted the changes we suggested, then a good chunk of this patch may be unneeded, but, this needs a much better look than I'm currently able to do
83 lines
4.8 KiB
Diff
83 lines
4.8 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Spottedleaf <spottedleaf@spottedleaf.dev>
|
|
Date: Mon, 13 Jul 2020 06:22:54 -0700
|
|
Subject: [PATCH] Fix AdvancementDataPlayer leak due from quitting early in
|
|
login
|
|
|
|
Move the criterion storage to the AdvancementDataPlayer object
|
|
itself, so the criterion object stores no references - and thus
|
|
needs no cleanup.
|
|
|
|
diff --git a/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java b/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java
|
|
index 584f48aba7bfec07a75b5a37da4ba7439610543c..c25c1cfca010ed625b6faf310be2edeccd6667bc 100644
|
|
--- a/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java
|
|
+++ b/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java
|
|
@@ -14,22 +14,24 @@ import net.minecraft.server.level.ServerPlayer;
|
|
import net.minecraft.world.level.storage.loot.LootContext;
|
|
|
|
public abstract class SimpleCriterionTrigger<T extends AbstractCriterionTriggerInstance> implements CriterionTrigger<T> {
|
|
- private final Map<PlayerAdvancements, Set<CriterionTrigger.Listener<T>>> players = Maps.newIdentityHashMap();
|
|
+ //private final Map<PlayerAdvancements, Set<CriterionTrigger.Listener<T>>> players = Maps.newIdentityHashMap(); // Paper - moved into AdvancementDataPlayer to fix memory leak
|
|
+
|
|
+ public SimpleCriterionTrigger() {}
|
|
|
|
@Override
|
|
public final void addPlayerListener(PlayerAdvancements manager, CriterionTrigger.Listener<T> conditions) {
|
|
- this.players.computeIfAbsent(manager, (managerx) -> {
|
|
+ manager.criterionData.computeIfAbsent(this, (managerx) -> { // Paper - fix AdvancementDataPlayer leak
|
|
return Sets.newHashSet();
|
|
}).add(conditions);
|
|
}
|
|
|
|
@Override
|
|
public final void removePlayerListener(PlayerAdvancements manager, CriterionTrigger.Listener<T> conditions) {
|
|
- Set<CriterionTrigger.Listener<T>> set = this.players.get(manager);
|
|
+ Set<CriterionTrigger.Listener<T>> set = (Set) manager.criterionData.get(this); // Paper - fix AdvancementDataPlayer leak
|
|
if (set != null) {
|
|
set.remove(conditions);
|
|
if (set.isEmpty()) {
|
|
- this.players.remove(manager);
|
|
+ manager.criterionData.remove(this); // Paper - fix AdvancementDataPlayer leak
|
|
}
|
|
}
|
|
|
|
@@ -37,7 +39,7 @@ public abstract class SimpleCriterionTrigger<T extends AbstractCriterionTriggerI
|
|
|
|
@Override
|
|
public final void removePlayerListeners(PlayerAdvancements tracker) {
|
|
- this.players.remove(tracker);
|
|
+ tracker.criterionData.remove(this); // Paper - fix AdvancementDataPlayer leak
|
|
}
|
|
|
|
protected abstract T createInstance(JsonObject obj, EntityPredicate.Composite playerPredicate, DeserializationContext predicateDeserializer);
|
|
@@ -50,7 +52,7 @@ public abstract class SimpleCriterionTrigger<T extends AbstractCriterionTriggerI
|
|
|
|
protected void trigger(ServerPlayer player, Predicate<T> tester) {
|
|
PlayerAdvancements playerAdvancements = player.getAdvancements();
|
|
- Set<CriterionTrigger.Listener<T>> set = this.players.get(playerAdvancements);
|
|
+ Set<CriterionTrigger.Listener<T>> set = (Set) playerAdvancements.criterionData.get(this); // Paper - fix AdvancementDataPlayer leak
|
|
if (set != null && !set.isEmpty()) {
|
|
LootContext lootContext = EntityPredicate.createContext(player, player);
|
|
List<CriterionTrigger.Listener<T>> list = null;
|
|
diff --git a/src/main/java/net/minecraft/server/PlayerAdvancements.java b/src/main/java/net/minecraft/server/PlayerAdvancements.java
|
|
index ce02a467c1c3434f2cdb112ceb9794196069a820..e05e5710c81b7dbb648afbfe16f843e7ae310752 100644
|
|
--- a/src/main/java/net/minecraft/server/PlayerAdvancements.java
|
|
+++ b/src/main/java/net/minecraft/server/PlayerAdvancements.java
|
|
@@ -39,6 +39,7 @@ import net.minecraft.advancements.Criterion;
|
|
import net.minecraft.advancements.CriterionProgress;
|
|
import net.minecraft.advancements.CriterionTrigger;
|
|
import net.minecraft.advancements.CriterionTriggerInstance;
|
|
+import net.minecraft.advancements.critereon.SimpleCriterionTrigger;
|
|
import net.minecraft.network.chat.ChatType;
|
|
import net.minecraft.network.chat.TranslatableComponent;
|
|
import net.minecraft.network.protocol.game.ClientboundSelectAdvancementsTabPacket;
|
|
@@ -70,6 +71,8 @@ public class PlayerAdvancements {
|
|
private Advancement lastSelectedTab;
|
|
private boolean isFirstPacket = true;
|
|
|
|
+ public final Map<SimpleCriterionTrigger, Set<CriterionTrigger.Listener>> criterionData = Maps.newIdentityHashMap(); // Paper - fix advancement data player leakage
|
|
+
|
|
public PlayerAdvancements(DataFixer dataFixer, PlayerList playerManager, ServerAdvancementManager advancementLoader, File advancementFile, ServerPlayer owner) {
|
|
this.dataFixer = dataFixer;
|
|
this.playerList = playerManager;
|