aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorShane Freeder <[email protected]>2024-11-04 22:03:13 +0000
committerBjarne Koll <[email protected]>2024-11-09 23:28:57 +0100
commit35bebb7d618fe020890966bddd96ca52743660f0 (patch)
tree0c673cd9340bed96496a4c0fb4414dcf0903b063
parent59b79c8bbb1f518676d52156d36bda66f84c7fea (diff)
downloadPaper-35bebb7d618fe020890966bddd96ca52743660f0.tar.gz
Paper-35bebb7d618fe020890966bddd96ca52743660f0.zip
Manually reset attribute map on restoring player instance
Spigots reuse of the entity instances causes the server to try to copy a players existing attributes back onto itself, which causes an error. We'll manually clear the applicable attribute modifiers, but, in the long run, we should just revert out of the broken behavior of trying to reuse ServerPlayer instances.
-rw-r--r--patches/server/1060-Manually-reset-attribute-map-on-restoring-player-ins.patch68
1 files changed, 68 insertions, 0 deletions
diff --git a/patches/server/1060-Manually-reset-attribute-map-on-restoring-player-ins.patch b/patches/server/1060-Manually-reset-attribute-map-on-restoring-player-ins.patch
new file mode 100644
index 0000000000..92d9a8e8af
--- /dev/null
+++ b/patches/server/1060-Manually-reset-attribute-map-on-restoring-player-ins.patch
@@ -0,0 +1,68 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Shane Freeder <[email protected]>
+Date: Mon, 4 Nov 2024 20:23:02 +0000
+Subject: [PATCH] Manually reset attribute map on restoring player instance
+
+Spigots reuse of the entity instances causes the server to try to copy
+a players existing attributes back onto itself, which causes an error.
+
+We'll manually clear the applicable attribute modifiers, but, in the long run,
+we should just revert out of the broken behavior of trying to reuse ServerPlayer
+instances.
+
+diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
+index cffbd3300967e5d80b5973b35a76235bb2aa1b73..bce4a59c82c8fd90501a51d4dd45113256df225f 100644
+--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
++++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
+@@ -2285,8 +2285,11 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
+ this.gameMode.setGameModeForPlayer(oldPlayer.gameMode.getGameModeForPlayer(), oldPlayer.gameMode.getPreviousGameModeForPlayer());
+ this.onUpdateAbilities();
+ if (alive) {
+- this.getAttributes().assignBaseValues(oldPlayer.getAttributes());
+- this.getAttributes().assignPermanentModifiers(oldPlayer.getAttributes());
++ // Paper start - deal with upstream stupidity around attribute modifiers and recycling entity instances.
++ //this.getAttributes().assignBaseValues(oldPlayer.getAttributes());
++ //this.getAttributes().assignPermanentModifiers(oldPlayer.getAttributes());
++ this.getAttributes().removeAllTransientModifiers();
++ // Paper end
+ this.setHealth(oldPlayer.getHealth());
+ this.foodData = oldPlayer.foodData;
+ Iterator iterator = oldPlayer.getActiveEffects().iterator();
+@@ -2304,7 +2307,10 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
+ this.setScore(oldPlayer.getScore());
+ this.portalProcess = oldPlayer.portalProcess;
+ } else {
+- this.getAttributes().assignBaseValues(oldPlayer.getAttributes());
++ // Paper start - deal with upstream stupidity around attribute modifiers and recycling entity instances.
++ //this.getAttributes().assignBaseValues(oldPlayer.getAttributes());
++ this.getAttributes().removeAllModifiers();
++ // Paper end
+ // this.setHealth(this.getMaxHealth()); // CraftBukkit
+ if (this.serverLevel().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || oldPlayer.isSpectator()) {
+ this.getInventory().replaceWith(oldPlayer.getInventory());
+diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
+index 94d04a20f97405e02d7cccaabadc7a7e86e336f7..684392007e6fd1f0a328bc5f59929fcabe1f1a6e 100644
+--- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
++++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
+@@ -156,5 +156,21 @@ public class AttributeMap {
+ attributes.put(attributeBase, attributeModifiable);
+ }
+ // Paper - end - living entity allow attribute registration
++ // Paper start - deal with upstream stupidity around attribute modifiers and recycling entity instances.
++ public void removeAllModifiers() {
++ this.attributes.values().forEach(AttributeInstance::removeModifiers);
++ }
++
++ public void removeAllTransientModifiers() {
++ this.attributes.values().forEach(attributeInstance -> {
++ final Set<AttributeModifier> permanentModifiers = attributeInstance.getPermanentModifiers();
++ attributeInstance.getModifiers().forEach(modifier -> {
++ if (!permanentModifiers.contains(modifier)) {
++ attributeInstance.removeModifier(modifier.id());
++ }
++ });
++ });
++ }
++ // Paper end
+
+ }