Mirror von
https://github.com/PaperMC/Paper.git
synchronisiert 2024-11-15 04:20:04 +01:00
ef823cbc25
Do not break API modifier expectations of lasting through death.
106 Zeilen
6.3 KiB
Diff
106 Zeilen
6.3 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Shane Freeder <theboyetronic@gmail.com>
|
|
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.
|
|
|
|
== AT ==
|
|
protected net.minecraft.world.entity.LivingEntity lastHandItemStacks
|
|
protected net.minecraft.world.entity.LivingEntity lastArmorItemStacks
|
|
protected net.minecraft.world.entity.LivingEntity lastBodyItemStack
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
|
index cffbd3300967e5d80b5973b35a76235bb2aa1b73..88de7566297b0be7d5f7d8868f76a0b5ac42dfcf 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(); Currently not implemented as it would loose API added attribute modifiers, awaiting addition of new API
|
|
+ // 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(); // Currently not implemented as it would loose API added attribute modifiers, awaiting addition of new API
|
|
+ // Paper end
|
|
// this.setHealth(this.getMaxHealth()); // CraftBukkit
|
|
if (this.serverLevel().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || oldPlayer.isSpectator()) {
|
|
this.getInventory().replaceWith(oldPlayer.getInventory());
|
|
@@ -2328,6 +2334,15 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
|
|
this.setShoulderEntityLeft(oldPlayer.getShoulderEntityLeft());
|
|
this.setShoulderEntityRight(oldPlayer.getShoulderEntityRight());
|
|
this.setLastDeathLocation(oldPlayer.getLastDeathLocation());
|
|
+ // Paper start - deal with upstream stupidity around attribute modifiers and recycling entity instances.
|
|
+ /*
|
|
+ Currently not implemented as modifiers are *not* actually removed, deviating from vanilla.
|
|
+ this.lastArmorItemStacks.clear();
|
|
+ this.lastHandItemStacks.clear();
|
|
+ this.lastBodyItemStack = ItemStack.EMPTY;
|
|
+ this.skipNextCollectEquipmentEvent = false; // Implement
|
|
+ */
|
|
+ // Paper end - deal with upstream stupidity around attribute modifiers and recycling entity instances.
|
|
}
|
|
|
|
@Override
|
|
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
|
index 1a93006d252ebfe5571904d8be1ceb62079db35a..5c40dfbb920cc3d83c27657784f3e2f5f5f9de5d 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
|
@@ -3369,6 +3369,11 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
|
|
|
@Nullable
|
|
private Map<EquipmentSlot, ItemStack> collectEquipmentChanges() {
|
|
+ // Paper start - deal with upstream stupidity around attribute modifiers and recycling entity instances.
|
|
+ return collectEquipmentChanges(true);
|
|
+ }
|
|
+ protected Map<EquipmentSlot, ItemStack> collectEquipmentChanges(boolean fireEvent) {
|
|
+ // Paper end - deal with upstream stupidity around attribute modifiers and recycling entity instances.
|
|
Map<EquipmentSlot, ItemStack> map = null;
|
|
Iterator iterator = EquipmentSlot.VALUES.iterator();
|
|
|
|
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
|
|
|
|
}
|