mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
Fix client bug when updating absorption and health in the same tick
This commit is contained in:
parent
14e7145503
commit
f91a6f8b80
4 changed files with 25 additions and 6 deletions
|
@ -51,7 +51,7 @@ public enum GeyserAttributeType {
|
|||
MAX_HEALTH("minecraft:generic.max_health", null, 0f, 1024f, 20f),
|
||||
|
||||
// Bedrock Attributes
|
||||
ABSORPTION(null, "minecraft:absorption", 0f, Float.MAX_VALUE, 0f),
|
||||
ABSORPTION(null, "minecraft:absorption", 0f, 1024f, 0f),
|
||||
EXHAUSTION(null, "minecraft:player.exhaustion", 0f, 5f, 0f),
|
||||
EXPERIENCE(null, "minecraft:player.experience", 0f, 1f, 0f),
|
||||
EXPERIENCE_LEVEL(null, "minecraft:player.level", 0f, 24791.00f, 0f),
|
||||
|
@ -66,6 +66,10 @@ public enum GeyserAttributeType {
|
|||
private final float maximum;
|
||||
private final float defaultValue;
|
||||
|
||||
public AttributeData getAttribute() {
|
||||
return getAttribute(defaultValue);
|
||||
}
|
||||
|
||||
public AttributeData getAttribute(float value) {
|
||||
return getAttribute(value, maximum);
|
||||
}
|
||||
|
|
|
@ -284,7 +284,7 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity {
|
|||
attributesPacket.setRuntimeEntityId(geyserId);
|
||||
// Setting to a higher maximum since plugins/datapacks can probably extend the Bedrock soft limit
|
||||
attributesPacket.setAttributes(Collections.singletonList(
|
||||
GeyserAttributeType.ABSORPTION.getAttribute(entityMetadata.getPrimitiveValue(), 1024f)));
|
||||
GeyserAttributeType.ABSORPTION.getAttribute(entityMetadata.getPrimitiveValue())));
|
||||
session.sendUpstreamPacket(attributesPacket);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeTyp
|
|||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.GlobalPos;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import lombok.Getter;
|
||||
|
@ -255,6 +256,14 @@ public class SessionPlayerEntity extends PlayerEntity {
|
|||
return session.getAuthData().uuid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAbsorptionHearts(FloatEntityMetadata entityMetadata) {
|
||||
// The bedrock client can glitch when sending a health and absorption attribute in the same tick
|
||||
// This can happen when switching servers. Resending the absorption attribute fixes the issue
|
||||
attributes.put(GeyserAttributeType.ABSORPTION, GeyserAttributeType.ABSORPTION.getAttribute(entityMetadata.getPrimitiveValue()));
|
||||
super.setAbsorptionHearts(entityMetadata);
|
||||
}
|
||||
|
||||
public void resetMetadata() {
|
||||
// Reset all metadata to their default values
|
||||
// This is used when a player respawns
|
||||
|
@ -268,10 +277,12 @@ public class SessionPlayerEntity extends PlayerEntity {
|
|||
setParrot(null, true);
|
||||
setParrot(null, false);
|
||||
|
||||
// Absorption is metadata in java edition
|
||||
attributes.remove(GeyserAttributeType.ABSORPTION);
|
||||
UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket();
|
||||
attributesPacket.setRuntimeEntityId(geyserId);
|
||||
attributesPacket.setAttributes(Collections.singletonList(
|
||||
GeyserAttributeType.ABSORPTION.getAttribute(0f, 1024f)));
|
||||
GeyserAttributeType.ABSORPTION.getAttribute(0f)));
|
||||
session.sendUpstreamPacket(attributesPacket);
|
||||
|
||||
dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, 0);
|
||||
|
@ -284,8 +295,12 @@ public class SessionPlayerEntity extends PlayerEntity {
|
|||
public void resetAttributes() {
|
||||
attributes.clear();
|
||||
maxHealth = GeyserAttributeType.MAX_HEALTH.getDefaultValue();
|
||||
// Relying on the server to resend speed attribute
|
||||
// Armor attribute reset would go here
|
||||
|
||||
UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket();
|
||||
attributesPacket.setRuntimeEntityId(geyserId);
|
||||
attributesPacket.setAttributes(Collections.singletonList(
|
||||
GeyserAttributeType.MOVEMENT_SPEED.getAttribute()));
|
||||
session.sendUpstreamPacket(attributesPacket);
|
||||
}
|
||||
|
||||
public void resetAir() {
|
||||
|
|
|
@ -712,7 +712,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||
// Default move speed
|
||||
// Bedrock clients move very fast by default until they get an attribute packet correcting the speed
|
||||
attributesPacket.setAttributes(Collections.singletonList(
|
||||
new AttributeData("minecraft:movement", 0.0f, 1024f, 0.1f, 0.1f)));
|
||||
GeyserAttributeType.MOVEMENT_SPEED.getAttribute()));
|
||||
upstream.sendPacket(attributesPacket);
|
||||
|
||||
GameRulesChangedPacket gamerulePacket = new GameRulesChangedPacket();
|
||||
|
|
Loading…
Reference in a new issue