From 5f134afc4b8398038b97780c567d2f7b25240655 Mon Sep 17 00:00:00 2001 From: MrPowerGamerBR Date: Tue, 21 Nov 2023 12:16:39 -0300 Subject: [PATCH] Lazily create LootContext for criterions For each player on each tick, enter block triggers are invoked, and these create loot contexts that are promptly thrown away since the trigger doesn't pass the predicate To avoid this, we now lazily create the LootContext if the criterion passes the predicate AND if any of the listener triggers require a loot context instance --- .../critereon/SimpleCriterionTrigger.java.patch | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java.patch b/paper-server/patches/sources/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java.patch index 1b253028b..d08061600 100644 --- a/paper-server/patches/sources/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java.patch +++ b/paper-server/patches/sources/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java +++ b/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java -@@ -15,32 +15,32 @@ +@@ -15,41 +15,41 @@ import net.minecraft.world.level.storage.loot.LootContext; public abstract class SimpleCriterionTrigger implements CriterionTrigger { @@ -37,5 +37,16 @@ - Set> set = this.players.get(playerAdvancements); + Set> set = (Set) playerAdvancements.criterionData.get(this); // Paper - fix AdvancementDataPlayer leak if (set != null && !set.isEmpty()) { - LootContext lootContext = EntityPredicate.createContext(player, player); +- LootContext lootContext = EntityPredicate.createContext(player, player); ++ LootContext lootContext = null; // EntityPredicate.createContext(player, player); // Paper - Perf: lazily create LootContext for criterions List> list = null; + + for (CriterionTrigger.Listener listener : set) { + T simpleInstance = listener.trigger(); + if (predicate.test(simpleInstance)) { + Optional optional = simpleInstance.player(); +- if (optional.isEmpty() || optional.get().matches(lootContext)) { ++ if (optional.isEmpty() || optional.get().matches(lootContext = (lootContext == null ? EntityPredicate.createContext(player, player) : lootContext))) { // Paper - Perf: lazily create LootContext for criterions + if (list == null) { + list = Lists.newArrayList(); + }