Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-25 15:50:14 +01:00
Fix some regressions in swim handling
Dieser Commit ist enthalten in:
Ursprung
b134dd3b1c
Commit
68c13c08fa
@ -65,6 +65,8 @@ import java.util.concurrent.TimeUnit;
|
|||||||
|
|
||||||
@Getter @Setter
|
@Getter @Setter
|
||||||
public class PlayerEntity extends LivingEntity {
|
public class PlayerEntity extends LivingEntity {
|
||||||
|
public static final float SNEAKING_POSE_HEIGHT = 1.5f;
|
||||||
|
|
||||||
private GameProfile profile;
|
private GameProfile profile;
|
||||||
private String username;
|
private String username;
|
||||||
private boolean playerList = true; // Player is in the player list
|
private boolean playerList = true; // Player is in the player list
|
||||||
@ -381,7 +383,7 @@ public class PlayerEntity extends LivingEntity {
|
|||||||
protected void setDimensions(Pose pose) {
|
protected void setDimensions(Pose pose) {
|
||||||
float height;
|
float height;
|
||||||
switch (pose) {
|
switch (pose) {
|
||||||
case SNEAKING -> height = 1.5f;
|
case SNEAKING -> height = SNEAKING_POSE_HEIGHT;
|
||||||
case FALL_FLYING, SPIN_ATTACK, SWIMMING -> height = 0.6f;
|
case FALL_FLYING, SPIN_ATTACK, SWIMMING -> height = 0.6f;
|
||||||
default -> {
|
default -> {
|
||||||
super.setDimensions(pose);
|
super.setDimensions(pose);
|
||||||
|
@ -28,21 +28,17 @@ package org.geysermc.geyser.entity.type.player;
|
|||||||
import com.github.steveice10.mc.auth.data.GameProfile;
|
import com.github.steveice10.mc.auth.data.GameProfile;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.attribute.Attribute;
|
import com.github.steveice10.mc.protocol.data.game.entity.attribute.Attribute;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeType;
|
import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeType;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
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.ByteEntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.AttributeData;
|
import com.nukkitx.protocol.bedrock.data.AttributeData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket;
|
|
||||||
import com.nukkitx.protocol.bedrock.packet.RespawnPacket;
|
|
||||||
import com.nukkitx.protocol.bedrock.packet.UpdateAttributesPacket;
|
import com.nukkitx.protocol.bedrock.packet.UpdateAttributesPacket;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
|
import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.text.GeyserLocale;
|
|
||||||
import org.geysermc.geyser.util.AttributeUtils;
|
import org.geysermc.geyser.util.AttributeUtils;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -112,12 +108,7 @@ public class SessionPlayerEntity extends PlayerEntity {
|
|||||||
@Override
|
@Override
|
||||||
public void setFlags(ByteEntityMetadata entityMetadata) {
|
public void setFlags(ByteEntityMetadata entityMetadata) {
|
||||||
super.setFlags(entityMetadata);
|
super.setFlags(entityMetadata);
|
||||||
// Swimming/crawling is controlled by the Java server
|
session.setSwimmingInWater((entityMetadata.getPrimitiveValue() & 0x10) == 0x10 && getFlag(EntityFlag.SPRINTING));
|
||||||
boolean swimming = (entityMetadata.getPrimitiveValue() & 0x10) == 0x10;
|
|
||||||
if (swimming) {
|
|
||||||
setPose(Pose.SWIMMING);
|
|
||||||
}
|
|
||||||
session.setSwimmingInWater(swimming && getFlag(EntityFlag.SPRINTING));
|
|
||||||
refreshSpeed = true;
|
refreshSpeed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,7 +362,22 @@ public class CollisionManager {
|
|||||||
* @return true if the block located at the player's floor position plus 1 would intersect with the player,
|
* @return true if the block located at the player's floor position plus 1 would intersect with the player,
|
||||||
* were they not sneaking
|
* were they not sneaking
|
||||||
*/
|
*/
|
||||||
public boolean isUnderSlab() {
|
public boolean mustPlayerSneakHere() {
|
||||||
|
return checkPose(EntityDefinitions.PLAYER.height());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if the block located at the player's floor position plus 1 would intersect with the player,
|
||||||
|
* were they not crawling
|
||||||
|
*/
|
||||||
|
public boolean mustPlayerCrawlHere() {
|
||||||
|
return checkPose(PlayerEntity.SNEAKING_POSE_HEIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param height check and see if this height is invalid in the current player position
|
||||||
|
*/
|
||||||
|
private boolean checkPose(float height) {
|
||||||
Vector3i position = session.getPlayerEntity().getPosition().toInt();
|
Vector3i position = session.getPlayerEntity().getPosition().toInt();
|
||||||
BlockCollision collision = BlockUtils.getCollisionAt(session, position);
|
BlockCollision collision = BlockUtils.getCollisionAt(session, position);
|
||||||
if (collision != null) {
|
if (collision != null) {
|
||||||
@ -370,7 +385,7 @@ public class CollisionManager {
|
|||||||
// at the current location.
|
// at the current location.
|
||||||
double originalY = playerBoundingBox.getMiddleY();
|
double originalY = playerBoundingBox.getMiddleY();
|
||||||
double originalHeight = playerBoundingBox.getSizeY();
|
double originalHeight = playerBoundingBox.getSizeY();
|
||||||
double standingY = originalY - (originalHeight / 2.0) + (EntityDefinitions.PLAYER.height() / 2.0);
|
double standingY = originalY - (originalHeight / 2.0) + (height / 2.0);
|
||||||
|
|
||||||
playerBoundingBox.setSizeY(EntityDefinitions.PLAYER.height());
|
playerBoundingBox.setSizeY(EntityDefinitions.PLAYER.height());
|
||||||
playerBoundingBox.setMiddleY(standingY);
|
playerBoundingBox.setMiddleY(standingY);
|
||||||
|
@ -1069,6 +1069,18 @@ public class GeyserSession implements GeyserConnection, CommandSender {
|
|||||||
playerEntity.setFlag(EntityFlag.SNEAKING, sneaking);
|
playerEntity.setFlag(EntityFlag.SNEAKING, sneaking);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSwimming(boolean swimming) {
|
||||||
|
if (swimming) {
|
||||||
|
this.pose = Pose.SWIMMING;
|
||||||
|
playerEntity.setBoundingBoxHeight(0.6f);
|
||||||
|
} else {
|
||||||
|
this.pose = Pose.STANDING;
|
||||||
|
playerEntity.setBoundingBoxHeight(playerEntity.getDefinition().height());
|
||||||
|
}
|
||||||
|
playerEntity.setFlag(EntityFlag.SWIMMING, swimming);
|
||||||
|
playerEntity.updateBedrockMetadata();
|
||||||
|
}
|
||||||
|
|
||||||
public void setFlying(boolean flying) {
|
public void setFlying(boolean flying) {
|
||||||
this.flying = flying;
|
this.flying = flying;
|
||||||
|
|
||||||
@ -1087,7 +1099,7 @@ public class GeyserSession implements GeyserConnection, CommandSender {
|
|||||||
public AttributeData adjustSpeed() {
|
public AttributeData adjustSpeed() {
|
||||||
AttributeData currentPlayerSpeed = playerEntity.getAttributes().get(GeyserAttributeType.MOVEMENT_SPEED);
|
AttributeData currentPlayerSpeed = playerEntity.getAttributes().get(GeyserAttributeType.MOVEMENT_SPEED);
|
||||||
if (currentPlayerSpeed != null) {
|
if (currentPlayerSpeed != null) {
|
||||||
if ((pose.equals(Pose.SNEAKING) && !sneaking && collisionManager.isUnderSlab()) ||
|
if ((pose.equals(Pose.SNEAKING) && !sneaking && collisionManager.mustPlayerSneakHere()) ||
|
||||||
(!swimmingInWater && playerEntity.getFlag(EntityFlag.SWIMMING) && !collisionManager.isPlayerInWater())) {
|
(!swimmingInWater && playerEntity.getFlag(EntityFlag.SWIMMING) && !collisionManager.isPlayerInWater())) {
|
||||||
// Either of those conditions means that Bedrock goes zoom when they shouldn't be
|
// Either of those conditions means that Bedrock goes zoom when they shouldn't be
|
||||||
AttributeData speedAttribute = GeyserAttributeType.MOVEMENT_SPEED.getAttribute(originalSpeedAttribute / 3.32f);
|
AttributeData speedAttribute = GeyserAttributeType.MOVEMENT_SPEED.getAttribute(originalSpeedAttribute / 3.32f);
|
||||||
|
@ -44,6 +44,11 @@ public class BedrockAdventureSettingsTranslator extends PacketTranslator<Adventu
|
|||||||
// We should always be flying in spectator mode
|
// We should always be flying in spectator mode
|
||||||
session.sendAdventureSettings();
|
session.sendAdventureSettings();
|
||||||
return;
|
return;
|
||||||
|
} else if (isFlying && session.getPlayerEntity().getFlag(EntityFlag.SWIMMING) && session.getCollisionManager().isPlayerInWater()) {
|
||||||
|
// As of 1.18.1, Java Edition cannot fly while in water, but it can fly while crawling
|
||||||
|
// If this isn't present, swimming on a 1.13.2 server and then attempting to fly will put you into a flying/swimming state that is invalid on JE
|
||||||
|
session.sendAdventureSettings();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
session.setFlying(isFlying);
|
session.setFlying(isFlying);
|
||||||
|
@ -77,16 +77,20 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
|
|||||||
session.sendUpstreamPacket(attributesPacket);
|
session.sendUpstreamPacket(attributesPacket);
|
||||||
break;
|
break;
|
||||||
case START_SWIMMING:
|
case START_SWIMMING:
|
||||||
if (!session.getPlayerEntity().getFlag(EntityFlag.SWIMMING)) {
|
if (!entity.getFlag(EntityFlag.SWIMMING)) {
|
||||||
ServerboundPlayerCommandPacket startSwimPacket = new ServerboundPlayerCommandPacket(entity.getEntityId(), PlayerState.START_SPRINTING);
|
ServerboundPlayerCommandPacket startSwimPacket = new ServerboundPlayerCommandPacket(entity.getEntityId(), PlayerState.START_SPRINTING);
|
||||||
session.sendDownstreamPacket(startSwimPacket);
|
session.sendDownstreamPacket(startSwimPacket);
|
||||||
|
|
||||||
|
session.setSwimming(true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STOP_SWIMMING:
|
case STOP_SWIMMING:
|
||||||
// Prevent packet spam when Bedrock players are crawling near the edge of a block
|
// Prevent packet spam when Bedrock players are crawling near the edge of a block
|
||||||
if (session.isSwimmingInWater()) {
|
if (!session.getCollisionManager().mustPlayerCrawlHere()) {
|
||||||
ServerboundPlayerCommandPacket stopSwimPacket = new ServerboundPlayerCommandPacket(entity.getEntityId(), PlayerState.STOP_SPRINTING);
|
ServerboundPlayerCommandPacket stopSwimPacket = new ServerboundPlayerCommandPacket(entity.getEntityId(), PlayerState.STOP_SPRINTING);
|
||||||
session.sendDownstreamPacket(stopSwimPacket);
|
session.sendDownstreamPacket(stopSwimPacket);
|
||||||
|
|
||||||
|
session.setSwimming(false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case START_GLIDE:
|
case START_GLIDE:
|
||||||
@ -135,14 +139,14 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
|
|||||||
session.setSneaking(false);
|
session.setSneaking(false);
|
||||||
break;
|
break;
|
||||||
case START_SPRINT:
|
case START_SPRINT:
|
||||||
if (!session.getPlayerEntity().getFlag(EntityFlag.SWIMMING)) {
|
if (!entity.getFlag(EntityFlag.SWIMMING)) {
|
||||||
ServerboundPlayerCommandPacket startSprintPacket = new ServerboundPlayerCommandPacket(entity.getEntityId(), PlayerState.START_SPRINTING);
|
ServerboundPlayerCommandPacket startSprintPacket = new ServerboundPlayerCommandPacket(entity.getEntityId(), PlayerState.START_SPRINTING);
|
||||||
session.sendDownstreamPacket(startSprintPacket);
|
session.sendDownstreamPacket(startSprintPacket);
|
||||||
session.setSprinting(true);
|
session.setSprinting(true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STOP_SPRINT:
|
case STOP_SPRINT:
|
||||||
if (!session.getPlayerEntity().getFlag(EntityFlag.SWIMMING)) {
|
if (!entity.getFlag(EntityFlag.SWIMMING)) {
|
||||||
ServerboundPlayerCommandPacket stopSprintPacket = new ServerboundPlayerCommandPacket(entity.getEntityId(), PlayerState.STOP_SPRINTING);
|
ServerboundPlayerCommandPacket stopSprintPacket = new ServerboundPlayerCommandPacket(entity.getEntityId(), PlayerState.STOP_SPRINTING);
|
||||||
session.sendDownstreamPacket(stopSprintPacket);
|
session.sendDownstreamPacket(stopSprintPacket);
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren