mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2026-01-04 15:41:40 +00:00
fix attribute crash server
This commit is contained in:
@@ -58,6 +58,18 @@ index dd2509996bfd08e8c3f9f2be042229eac6d7692d..a35e9fae8f8da0c42f0616c4f78dc396
|
||||
|
||||
private static final byte CHUNK_TICKET_STAGE_NONE = 0;
|
||||
private static final byte CHUNK_TICKET_STAGE_LOADING = 1;
|
||||
diff --git a/net/minecraft/network/protocol/game/ClientboundUpdateAttributesPacket.java b/net/minecraft/network/protocol/game/ClientboundUpdateAttributesPacket.java
|
||||
index 9c0c99b936b4a82ebfe924866e53ec71f7bbe9ad..2ccff968cb2065d34fad4d27573f9e3081edb2f2 100644
|
||||
--- a/net/minecraft/network/protocol/game/ClientboundUpdateAttributesPacket.java
|
||||
+++ b/net/minecraft/network/protocol/game/ClientboundUpdateAttributesPacket.java
|
||||
@@ -32,6 +32,7 @@ public class ClientboundUpdateAttributesPacket implements Packet<ClientGamePacke
|
||||
this.attributes = Lists.newArrayList();
|
||||
|
||||
for (AttributeInstance attributeInstance : attributes) {
|
||||
+ if (attributeInstance == null) continue; // Leaf - Multithreaded tracker
|
||||
this.attributes
|
||||
.add(
|
||||
new ClientboundUpdateAttributesPacket.AttributeSnapshot(
|
||||
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
||||
index 5d9d233e3a568aa6297ed9c703fa450f98158602..47a7bf7c38600a2ad547bbd2b7fe632e96e9a139 100644
|
||||
--- a/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -319,7 +331,7 @@ index f106373ef3ac4a8685c2939c9e8361688a285913..51ae390c68e7a3aa193329cc3bc47ca6
|
||||
public boolean visible = true;
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java
|
||||
index 1dee20436fc29537319ee456756a8e8f7b6fe66a..bcd569e7d12d4f453c64bf12933a72c3ca362329 100644
|
||||
index 1dee20436fc29537319ee456756a8e8f7b6fe66a..5351d373aa0f4450386a6b50f88052c031949f5b 100644
|
||||
--- a/net/minecraft/server/level/ServerEntity.java
|
||||
+++ b/net/minecraft/server/level/ServerEntity.java
|
||||
@@ -110,8 +110,16 @@ public class ServerEntity {
|
||||
@@ -350,38 +362,15 @@ index 1dee20436fc29537319ee456756a8e8f7b6fe66a..bcd569e7d12d4f453c64bf12933a72c3
|
||||
final ServerPlayer serverPlayer = connection.getPlayer(); // Paper
|
||||
savedData.tickCarriedBy(serverPlayer, item);
|
||||
Packet<?> updatePacket = savedData.getUpdatePacket(mapId, serverPlayer);
|
||||
@@ -433,15 +441,30 @@ public class ServerEntity {
|
||||
}
|
||||
|
||||
if (this.entity instanceof LivingEntity) {
|
||||
- Set<AttributeInstance> attributesToSync = ((LivingEntity)this.entity).getAttributes().getAttributesToSync();
|
||||
+ // Leaf start - Multithreaded tracker
|
||||
+ var attributeMap = ((LivingEntity)this.entity).getAttributes();
|
||||
+ Set<AttributeInstance> attributesToSync = attributeMap.getAttributesToSync();
|
||||
if (!attributesToSync.isEmpty()) {
|
||||
+ if (org.dreeam.leaf.config.modules.async.MultithreadedTracker.enabled) {
|
||||
+ synchronized (attributeMap) {
|
||||
+ // CraftBukkit start - Send scaled max health
|
||||
+ if (this.entity instanceof ServerPlayer serverPlayer) {
|
||||
+ serverPlayer.getBukkitEntity().injectScaledMaxHealth(attributesToSync, false);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), attributesToSync));
|
||||
+
|
||||
+ }
|
||||
+ } else {
|
||||
// CraftBukkit start - Send scaled max health
|
||||
if (this.entity instanceof ServerPlayer serverPlayer) {
|
||||
serverPlayer.getBukkitEntity().injectScaledMaxHealth(attributesToSync, false);
|
||||
}
|
||||
// CraftBukkit end
|
||||
@@ -443,7 +451,7 @@ public class ServerEntity {
|
||||
this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), attributesToSync));
|
||||
+ }
|
||||
}
|
||||
+ // Leaf end - Multithreaded tracker
|
||||
|
||||
attributesToSync.clear();
|
||||
- attributesToSync.clear();
|
||||
+ // attributesToSync.clear(); // Leaf - Multithreaded tracker
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 275b640f4536366152f59acf071dd4eba15696c8..a669a59a42f814480879a52d2da5e04c636720de 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -418,39 +407,50 @@ index 327b3bc89920c4ab02c1126dc63bca05ce3abefe..1415043bee5fbbfcf9dab9184a9418d5
|
||||
if (this.player.isRemoved()) {
|
||||
LOGGER.info("Attempt to teleport removed player {} restricted", player.getScoreboardName());
|
||||
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||
index d502325d693539842fd6f5485365e0e9b786b7aa..324f8952a921a3897f4ff48145f0f8645c690318 100644
|
||||
index d502325d693539842fd6f5485365e0e9b786b7aa..a99527409e9aae6c8b321a5ed100b2645151087e 100644
|
||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -1311,13 +1311,26 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
@@ -1311,13 +1311,13 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
}
|
||||
|
||||
private void refreshDirtyAttributes() {
|
||||
- Set<AttributeInstance> attributesToUpdate = this.getAttributes().getAttributesToUpdate();
|
||||
+ // Leaf start - Multithreaded tracker
|
||||
+ var attributeMap = this.getAttributes();
|
||||
+ Set<AttributeInstance> attributesToUpdate = attributeMap.getAttributesToUpdate();
|
||||
+
|
||||
+ if (org.dreeam.leaf.config.modules.async.MultithreadedTracker.enabled) {
|
||||
+ synchronized (attributeMap) {
|
||||
+ for (AttributeInstance attributeInstance : attributesToUpdate) {
|
||||
+ this.onAttributeUpdated(attributeInstance.getAttribute());
|
||||
+ }
|
||||
+ int[] attributesToUpdate = this.getAttributes().getAttributesToUpdateIds();
|
||||
|
||||
+ attributesToUpdate.clear();
|
||||
+ }
|
||||
+ } else {
|
||||
for (AttributeInstance attributeInstance : attributesToUpdate) {
|
||||
this.onAttributeUpdated(attributeInstance.getAttribute());
|
||||
- for (AttributeInstance attributeInstance : attributesToUpdate) {
|
||||
- this.onAttributeUpdated(attributeInstance.getAttribute());
|
||||
+ for (int attribute : attributesToUpdate) {
|
||||
+ this.onAttributeUpdated(net.minecraft.core.registries.BuiltInRegistries.ATTRIBUTE.get(attribute).orElseThrow());
|
||||
}
|
||||
|
||||
attributesToUpdate.clear();
|
||||
+ }
|
||||
-
|
||||
- attributesToUpdate.clear();
|
||||
+ // Leaf end - Multithreaded tracker
|
||||
}
|
||||
|
||||
protected void onAttributeUpdated(Holder<Attribute> attribute) {
|
||||
diff --git a/net/minecraft/world/entity/ai/attributes/Attribute.java b/net/minecraft/world/entity/ai/attributes/Attribute.java
|
||||
index f8419dde44ebc7324e783f8bee42132d5ec973c3..406767c60ec1a324faaf5d3658b161647497f99b 100644
|
||||
--- a/net/minecraft/world/entity/ai/attributes/Attribute.java
|
||||
+++ b/net/minecraft/world/entity/ai/attributes/Attribute.java
|
||||
@@ -16,10 +16,15 @@ public class Attribute {
|
||||
private boolean syncable;
|
||||
private final String descriptionId;
|
||||
private Attribute.Sentiment sentiment = Attribute.Sentiment.POSITIVE;
|
||||
+ // Leaf start - Optimize AttributeMap
|
||||
+ public final int uid;
|
||||
+ private static final java.util.concurrent.atomic.AtomicInteger SIZE = new java.util.concurrent.atomic.AtomicInteger();
|
||||
+ // Leaf end - Optimize AttributeMap
|
||||
|
||||
protected Attribute(String descriptionId, double defaultValue) {
|
||||
this.defaultValue = defaultValue;
|
||||
this.descriptionId = descriptionId;
|
||||
+ this.uid = SIZE.getAndAdd(1); // Leaf - Optimize AttributeMap
|
||||
}
|
||||
|
||||
public double getDefaultValue() {
|
||||
diff --git a/net/minecraft/world/entity/ai/attributes/AttributeInstance.java b/net/minecraft/world/entity/ai/attributes/AttributeInstance.java
|
||||
index 8013594bb4844e7a8abf28123958e7f632d39341..93b375f39f10568f6b222607890a9ce67db0e9bb 100644
|
||||
index 8013594bb4844e7a8abf28123958e7f632d39341..b502c4a0f3695cc5bee8954f937f64584df1584d 100644
|
||||
--- a/net/minecraft/world/entity/ai/attributes/AttributeInstance.java
|
||||
+++ b/net/minecraft/world/entity/ai/attributes/AttributeInstance.java
|
||||
@@ -24,8 +24,24 @@ public class AttributeInstance {
|
||||
@@ -495,21 +495,21 @@ index 8013594bb4844e7a8abf28123958e7f632d39341..93b375f39f10568f6b222607890a9ce6
|
||||
}
|
||||
|
||||
public Set<AttributeModifier> getModifiers() {
|
||||
@@ -174,6 +196,13 @@ public class AttributeInstance {
|
||||
}
|
||||
@@ -142,8 +164,12 @@ public class AttributeInstance {
|
||||
|
||||
public void replaceFrom(AttributeInstance instance) {
|
||||
+ // Leaf start - Multithreaded tracker
|
||||
+ synchronized (instance) {
|
||||
+ this.replaceFrom0(instance);
|
||||
+ }
|
||||
+ }
|
||||
+ public void replaceFrom0(AttributeInstance instance) {
|
||||
+ // Leaf end - Multithreaded tracker
|
||||
this.baseValue = instance.baseValue;
|
||||
this.modifierById.clear();
|
||||
this.modifierById.putAll(instance.modifierById);
|
||||
@@ -195,9 +224,19 @@ public class AttributeInstance {
|
||||
public double getValue() {
|
||||
if (this.dirty) {
|
||||
- this.cachedValue = this.calculateValue();
|
||||
+ // Leaf start - Multithreaded tracker
|
||||
+ double value = this.calculateValue();
|
||||
+ this.cachedValue = value;
|
||||
this.dirty = false;
|
||||
+ return value;
|
||||
+ // Leaf end - Multithreaded tracker
|
||||
}
|
||||
|
||||
return this.cachedValue;
|
||||
@@ -195,9 +221,19 @@ public class AttributeInstance {
|
||||
if (!this.permanentModifiers.isEmpty()) {
|
||||
ListTag listTag = new ListTag();
|
||||
|
||||
@@ -532,65 +532,112 @@ index 8013594bb4844e7a8abf28123958e7f632d39341..93b375f39f10568f6b222607890a9ce6
|
||||
compoundTag.put("modifiers", listTag);
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
||||
index 89f4c5b2d61e27acd48063f9f24ce9ea91898b8b..c0a09b615e9b6c4ec72b8b77a78e7da374d4498b 100644
|
||||
index 89f4c5b2d61e27acd48063f9f24ce9ea91898b8b..0bc846721b1af44904a705f5c4aef897a03824e0 100644
|
||||
--- a/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
||||
+++ b/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
||||
@@ -21,8 +21,19 @@ public class AttributeMap {
|
||||
@@ -20,12 +20,14 @@ import org.slf4j.Logger;
|
||||
public class AttributeMap {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
// Gale start - Lithium - replace AI attributes with optimized collections
|
||||
private final Map<Holder<Attribute>, AttributeInstance> attributes = new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(0);
|
||||
- private final Map<Holder<Attribute>, AttributeInstance> attributes = new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(0);
|
||||
- private final Set<AttributeInstance> attributesToSync = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(0);
|
||||
- private final Set<AttributeInstance> attributesToUpdate = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(0);
|
||||
+ // Leaf start - Multithreaded tracker
|
||||
+ private final Set<AttributeInstance> attributesToSync;
|
||||
+ private final Set<AttributeInstance> attributesToUpdate;
|
||||
+ {
|
||||
+ if (org.dreeam.leaf.config.modules.async.MultithreadedTracker.enabled) {
|
||||
+ attributesToSync = it.unimi.dsi.fastutil.objects.ReferenceSets.synchronize(new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(0), this);
|
||||
+ attributesToUpdate = it.unimi.dsi.fastutil.objects.ReferenceSets.synchronize(new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(0), this);
|
||||
+ } else {
|
||||
+ attributesToSync = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(0);
|
||||
+ attributesToUpdate = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(0);
|
||||
+ }
|
||||
+ }
|
||||
+ private final Map<Holder<Attribute>, AttributeInstance> attributes = new org.dreeam.leaf.util.map.AttributeInstanceArrayMap();
|
||||
+ private final org.dreeam.leaf.util.map.AttributeInstanceSet attributesToSync = new org.dreeam.leaf.util.map.AttributeInstanceSet((org.dreeam.leaf.util.map.AttributeInstanceArrayMap) attributes);
|
||||
+ private final org.dreeam.leaf.util.map.AttributeInstanceSet attributesToUpdate = new org.dreeam.leaf.util.map.AttributeInstanceSet((org.dreeam.leaf.util.map.AttributeInstanceArrayMap) attributes);
|
||||
+ // Leaf end - Multithreaded tracker
|
||||
// Gale end - Lithium - replace AI attributes with optimized collections
|
||||
private final AttributeSupplier supplier;
|
||||
private final java.util.function.Function<Holder<Attribute>, AttributeInstance> createInstance; // Gale - Airplane - reduce entity allocations
|
||||
@@ -60,7 +71,13 @@ public class AttributeMap {
|
||||
- private final java.util.function.Function<Holder<Attribute>, AttributeInstance> createInstance; // Gale - Airplane - reduce entity allocations
|
||||
+ //private final java.util.function.Function<Holder<Attribute>, AttributeInstance> createInstance; // Gale - Airplane - reduce entity allocations // Leaf - Optimize AttributeMap
|
||||
private final net.minecraft.world.entity.LivingEntity entity; // Purpur - Ridables
|
||||
|
||||
public AttributeMap(AttributeSupplier supplier) {
|
||||
@@ -36,31 +38,54 @@ public class AttributeMap {
|
||||
this.entity = entity;
|
||||
// Purpur end - Ridables
|
||||
this.supplier = defaultAttributes;
|
||||
- this.createInstance = holder -> this.supplier.createInstance(this::onAttributeModified, holder); // Gale - Airplane - reduce entity allocations
|
||||
+ //this.createInstance = holder -> this.supplier.createInstance(this::onAttributeModified, holder); // Gale - Airplane - reduce entity allocations // Leaf - Optimize AttributeMap
|
||||
}
|
||||
|
||||
- private void onAttributeModified(AttributeInstance instance) {
|
||||
+ // Leaf start - Multithreaded tracker
|
||||
+ private synchronized void onAttributeModified(AttributeInstance instance) {
|
||||
this.attributesToUpdate.add(instance);
|
||||
if (instance.getAttribute().value().isClientSyncable() && (entity == null || entity.shouldSendAttribute(instance.getAttribute().value()))) { // Purpur - Ridables
|
||||
this.attributesToSync.add(instance);
|
||||
}
|
||||
}
|
||||
|
||||
- public Set<AttributeInstance> getAttributesToSync() {
|
||||
- return this.attributesToSync;
|
||||
+ private static final AttributeInstance[] EMPTY_ATTRIBUTE_INSTANCE = new AttributeInstance[0];
|
||||
+ public synchronized Set<AttributeInstance> getAttributesToSync() {
|
||||
+ var clone = it.unimi.dsi.fastutil.objects.ReferenceArraySet.ofUnchecked(attributesToSync.toArray(EMPTY_ATTRIBUTE_INSTANCE));
|
||||
+ this.attributesToSync.clear();
|
||||
+ return clone;
|
||||
}
|
||||
|
||||
- public Set<AttributeInstance> getAttributesToUpdate() {
|
||||
- return this.attributesToUpdate;
|
||||
+ public synchronized Set<AttributeInstance> getAttributesToUpdate() {
|
||||
+ var clone = it.unimi.dsi.fastutil.objects.ReferenceArraySet.ofUnchecked(attributesToUpdate.toArray(EMPTY_ATTRIBUTE_INSTANCE));
|
||||
+ this.attributesToUpdate.clear();
|
||||
+ return clone;
|
||||
}
|
||||
|
||||
+ public synchronized int[] getAttributesToUpdateIds() {
|
||||
+ int[] clone = attributesToUpdate.inner.toIntArray();
|
||||
+ this.attributesToUpdate.clear();
|
||||
+ return clone;
|
||||
+ }
|
||||
+ // Leaf end - Multithreaded tracker
|
||||
+
|
||||
public Collection<AttributeInstance> getSyncableAttributes() {
|
||||
return this.attributes.values().stream().filter(instance -> instance.getAttribute().value().isClientSyncable() && (entity == null || entity.shouldSendAttribute(instance.getAttribute().value()))).collect(Collectors.toList()); // Purpur - Ridables
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public AttributeInstance getInstance(Holder<Attribute> attribute) {
|
||||
- return this.attributes.computeIfAbsent(attribute, this.createInstance); // Gale - Airplane - reduce entity allocations - cache lambda, as for some reason java allocates it anyways
|
||||
+ if (org.dreeam.leaf.config.modules.async.MultithreadedTracker.enabled) {
|
||||
+ synchronized (this) {
|
||||
+ return this.attributes.computeIfAbsent(attribute, holder -> this.supplier.createInstance(this::onAttributeModified, (Holder<Attribute>) holder));
|
||||
+ // Leaf start - Multithreaded tracker
|
||||
+ AttributeInstance v;
|
||||
+ if ((v = this.attributes.get(attribute)) == null) {
|
||||
+ AttributeInstance newValue;
|
||||
+ if ((newValue = this.supplier.createInstance(this::onAttributeModified, attribute)) != null) {
|
||||
+ attributes.put(attribute, newValue);
|
||||
+ return newValue;
|
||||
+ }
|
||||
+ } else {
|
||||
+ return this.attributes.computeIfAbsent(attribute, holder -> this.supplier.createInstance(this::onAttributeModified, (Holder<Attribute>) holder));
|
||||
+ }
|
||||
+ return v;
|
||||
+ // Leaf end - Multithreaded tracker
|
||||
}
|
||||
|
||||
public boolean hasAttribute(Holder<Attribute> attribute) {
|
||||
@@ -176,8 +193,17 @@ public class AttributeMap {
|
||||
diff --git a/net/minecraft/world/entity/ai/attributes/AttributeSupplier.java b/net/minecraft/world/entity/ai/attributes/AttributeSupplier.java
|
||||
index 24710041ccbc70e5506d8d89ae34f0141977f209..05de8a77b389691dd6986f36b4cb8cc0935e21e4 100644
|
||||
--- a/net/minecraft/world/entity/ai/attributes/AttributeSupplier.java
|
||||
+++ b/net/minecraft/world/entity/ai/attributes/AttributeSupplier.java
|
||||
@@ -11,7 +11,7 @@ public class AttributeSupplier {
|
||||
private final Map<Holder<Attribute>, AttributeInstance> instances;
|
||||
|
||||
// Paper - start - living entity allow attribute registration
|
||||
public void registerAttribute(Holder<Attribute> attributeBase) {
|
||||
+ // Leaf start - Multithreaded tracker
|
||||
AttributeInstance attributeModifiable = new AttributeInstance(attributeBase, AttributeInstance::getAttribute);
|
||||
- attributes.put(attributeBase, attributeModifiable);
|
||||
+ if (org.dreeam.leaf.config.modules.async.MultithreadedTracker.enabled) {
|
||||
+ synchronized (this) {
|
||||
+ attributes.put(attributeBase, attributeModifiable);
|
||||
+
|
||||
+ }
|
||||
+ } else {
|
||||
+ attributes.put(attributeBase, attributeModifiable);
|
||||
+ }
|
||||
+ // Leaf end - Multithreaded tracker
|
||||
AttributeSupplier(Map<Holder<Attribute>, AttributeInstance> instances) {
|
||||
- this.instances = instances;
|
||||
+ this.instances = new org.dreeam.leaf.util.map.AttributeInstanceArrayMap(instances); // Leaf - Optimize AttributeMap
|
||||
}
|
||||
// Paper - end - living entity allow attribute registration
|
||||
|
||||
public AttributeInstance getAttributeInstance(Holder<Attribute> attribute) {
|
||||
@@ -41,7 +41,7 @@ public class AttributeSupplier {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
- public AttributeInstance createInstance(Consumer<AttributeInstance> onDirty, Holder<Attribute> attribute) {
|
||||
+ public AttributeInstance createInstance(Consumer<AttributeInstance> onDirty, Holder<Attribute> attribute) { // Leaf - Multithreaded tracker
|
||||
AttributeInstance attributeInstance = this.instances.get(attribute);
|
||||
if (attributeInstance == null) {
|
||||
return null;
|
||||
diff --git a/net/minecraft/world/entity/item/PrimedTnt.java b/net/minecraft/world/entity/item/PrimedTnt.java
|
||||
index c96f458994818392857642282ec3d492124885da..d345afd14ef6fe2f0a584df5dfa080fd7ab3f47e 100644
|
||||
--- a/net/minecraft/world/entity/item/PrimedTnt.java
|
||||
|
||||
Reference in New Issue
Block a user