Fix attributes not being fully sent for the first player login

This commit is contained in:
themode 2021-01-06 21:09:27 +01:00
parent 459e65da72
commit 84fd568c0c
4 changed files with 24 additions and 12 deletions

View File

@ -13,6 +13,10 @@ public class Attribute {
private static final Map<String, Attribute> ATTRIBUTES = new HashMap<>(); private static final Map<String, Attribute> ATTRIBUTES = new HashMap<>();
static {
Attributes.init();
}
private final String key; private final String key;
private final float defaultValue; private final float defaultValue;
private final float maxValue; private final float maxValue;

View File

@ -24,6 +24,7 @@ public class AttributeInstance {
this.attribute = attribute; this.attribute = attribute;
this.propertyChangeListener = listener; this.propertyChangeListener = listener;
this.baseValue = attribute.getDefaultValue(); this.baseValue = attribute.getDefaultValue();
refreshCachedValue();
} }
/** /**
@ -90,6 +91,7 @@ public class AttributeInstance {
* *
* @return the modifiers. * @return the modifiers.
*/ */
@NotNull
public Collection<AttributeModifier> getModifiers() { public Collection<AttributeModifier> getModifiers() {
return modifiers.values(); return modifiers.values();
} }
@ -107,18 +109,19 @@ public class AttributeInstance {
* Recalculate the value of this attribute instance using the modifiers. * Recalculate the value of this attribute instance using the modifiers.
*/ */
protected void refreshCachedValue() { protected void refreshCachedValue() {
final Collection<AttributeModifier> modifiers = getModifiers();
float base = getBaseValue(); float base = getBaseValue();
for (var modifier : modifiers.values().stream().filter(mod -> mod.getOperation() == AttributeOperation.ADDITION).toArray(AttributeModifier[]::new)) { for (var modifier : modifiers.stream().filter(mod -> mod.getOperation() == AttributeOperation.ADDITION).toArray(AttributeModifier[]::new)) {
base += modifier.getAmount(); base += modifier.getAmount();
} }
float result = base; float result = base;
for (var modifier : modifiers.values().stream().filter(mod -> mod.getOperation() == AttributeOperation.MULTIPLY_BASE).toArray(AttributeModifier[]::new)) { for (var modifier : modifiers.stream().filter(mod -> mod.getOperation() == AttributeOperation.MULTIPLY_BASE).toArray(AttributeModifier[]::new)) {
result += (base * modifier.getAmount()); result += (base * modifier.getAmount());
} }
for (var modifier : modifiers.values().stream().filter(mod -> mod.getOperation() == AttributeOperation.MULTIPLY_TOTAL).toArray(AttributeModifier[]::new)) { for (var modifier : modifiers.stream().filter(mod -> mod.getOperation() == AttributeOperation.MULTIPLY_TOTAL).toArray(AttributeModifier[]::new)) {
result *= (1.0f + modifier.getAmount()); result *= (1.0f + modifier.getAmount());
} }

View File

@ -4,6 +4,7 @@ package net.minestom.server.attribute;
* The Minecraft, vanilla, standards attributes. * The Minecraft, vanilla, standards attributes.
*/ */
public final class Attributes { public final class Attributes {
public static final Attribute MAX_HEALTH = (new Attribute("generic.max_health", true, 20, 1024)).register(); public static final Attribute MAX_HEALTH = (new Attribute("generic.max_health", true, 20, 1024)).register();
public static final Attribute FOLLOW_RANGE = (new Attribute("generic.follow_range", true, 32, 2048)).register(); public static final Attribute FOLLOW_RANGE = (new Attribute("generic.follow_range", true, 32, 2048)).register();
public static final Attribute KNOCKBACK_RESISTANCE = (new Attribute("generic.knockback_resistance", true, 0, 1)).register(); public static final Attribute KNOCKBACK_RESISTANCE = (new Attribute("generic.knockback_resistance", true, 0, 1)).register();
@ -21,4 +22,8 @@ public final class Attributes {
private Attributes() throws IllegalAccessException { private Attributes() throws IllegalAccessException {
throw new IllegalAccessException("Cannot instantiate a static class"); throw new IllegalAccessException("Cannot instantiate a static class");
} }
protected static void init() {
// Empty, here to register all the vanilla attributes
}
} }

View File

@ -31,11 +31,7 @@ import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.*;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -507,12 +503,15 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
*/ */
@NotNull @NotNull
protected EntityPropertiesPacket getPropertiesPacket() { protected EntityPropertiesPacket getPropertiesPacket() {
// Get all the attributes which should be sent to the client
final AttributeInstance[] instances = attributeModifiers.values().stream()
.filter(i -> i.getAttribute().isShared())
.toArray(AttributeInstance[]::new);
EntityPropertiesPacket propertiesPacket = new EntityPropertiesPacket(); EntityPropertiesPacket propertiesPacket = new EntityPropertiesPacket();
propertiesPacket.entityId = getEntityId(); propertiesPacket.entityId = getEntityId();
AttributeInstance[] instances = attributeModifiers.values().stream()
.filter(i -> i.getAttribute().isShared())
.toArray(AttributeInstance[]::new);
EntityPropertiesPacket.Property[] properties = new EntityPropertiesPacket.Property[instances.length]; EntityPropertiesPacket.Property[] properties = new EntityPropertiesPacket.Property[instances.length];
for (int i = 0; i < properties.length; ++i) { for (int i = 0; i < properties.length; ++i) {
EntityPropertiesPacket.Property property = new EntityPropertiesPacket.Property(); EntityPropertiesPacket.Property property = new EntityPropertiesPacket.Property();
@ -535,7 +534,8 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
*/ */
private void setupAttributes() { private void setupAttributes() {
for (Attribute attribute : Attribute.values()) { for (Attribute attribute : Attribute.values()) {
attributeModifiers.put(attribute.getKey(), new AttributeInstance(attribute, this::onAttributeChanged)); final AttributeInstance attributeInstance = new AttributeInstance(attribute, this::onAttributeChanged);
this.attributeModifiers.put(attribute.getKey(), attributeInstance);
} }
} }