mirror of
https://github.com/GeyserMC/Geyser.git
synced 2025-12-19 14:59:27 +00:00
Fix: Input processing on mobile devices with classic D-Pad control mode
This commit is contained in:
@@ -29,6 +29,7 @@ import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.cloudburstmc.math.vector.Vector2f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.InputInteractionModel;
|
||||
import org.cloudburstmc.protocol.bedrock.data.InputMode;
|
||||
import org.cloudburstmc.protocol.bedrock.data.PlayerAuthInputData;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.PlayerAuthInputPacket;
|
||||
@@ -61,14 +62,54 @@ public final class InputCache {
|
||||
var oldInputPacket = this.inputPacket;
|
||||
this.inputMode = packet.getInputMode();
|
||||
|
||||
/*
|
||||
Brief introduction to how Bedrock sends movement inputs! It's mainly based on the following:
|
||||
(as of 1.21.111)
|
||||
1. inputmode:
|
||||
- MOUSE: same as Java edition; will send up/down/left/right inputs via input flags
|
||||
- GAMEPAD: indicates the use of a controller with joysticks, sends an "analogue movement vector" instead
|
||||
- TOUCH: see interaction model!
|
||||
- MOTION_CONTROLLER: what even is this
|
||||
|
||||
2. Interaction model (here, only really relevant for us when the inputmode is "touch"):
|
||||
- CLASSIC: shows "wasd" keys on the client; like input-mode MOUSE would, additionally up_left / up_right / down_left / down_right
|
||||
- CROSSHAIR / TOUCH: NO wasd, analogue movement vector instead
|
||||
|
||||
Hence, we'll also need to check for this fun edge-case!
|
||||
*/
|
||||
boolean isMobileAndClassicMovement = inputMode == InputMode.TOUCH && packet.getInputInteractionModel() == InputInteractionModel.CLASSIC;
|
||||
|
||||
boolean up, down, left, right;
|
||||
if (this.inputMode == InputMode.MOUSE) {
|
||||
if (this.inputMode == InputMode.MOUSE || isMobileAndClassicMovement) {
|
||||
up = bedrockInput.contains(PlayerAuthInputData.UP);
|
||||
down = bedrockInput.contains(PlayerAuthInputData.DOWN);
|
||||
left = bedrockInput.contains(PlayerAuthInputData.LEFT);
|
||||
right = bedrockInput.contains(PlayerAuthInputData.RIGHT);
|
||||
|
||||
if (isMobileAndClassicMovement) {
|
||||
// These are the buttons in the corners of the touch area
|
||||
if (bedrockInput.contains(PlayerAuthInputData.UP_LEFT)) {
|
||||
up = true;
|
||||
left = true;
|
||||
}
|
||||
|
||||
if (bedrockInput.contains(PlayerAuthInputData.UP_RIGHT)) {
|
||||
up = true;
|
||||
right = true;
|
||||
}
|
||||
|
||||
if (bedrockInput.contains(PlayerAuthInputData.DOWN_LEFT)) {
|
||||
down = true;
|
||||
left = true;
|
||||
}
|
||||
|
||||
if (bedrockInput.contains(PlayerAuthInputData.DOWN_RIGHT)) {
|
||||
down = true;
|
||||
right = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// The above flags don't fire TODO test console
|
||||
// The above flags don't fire
|
||||
Vector2f analogMovement = packet.getAnalogMoveVector();
|
||||
up = analogMovement.getY() > 0;
|
||||
down = analogMovement.getY() < 0;
|
||||
@@ -78,7 +119,6 @@ public final class InputCache {
|
||||
|
||||
boolean sneaking = isSneaking(bedrockInput);
|
||||
|
||||
// TODO when is UP_LEFT, etc. used?
|
||||
this.inputPacket = this.inputPacket
|
||||
.withForward(up)
|
||||
.withBackward(down)
|
||||
@@ -133,7 +173,7 @@ public final class InputCache {
|
||||
public boolean isSneaking(Set<PlayerAuthInputData> authInputData) {
|
||||
// Flying doesn't send start / stop fly cases; might as well return early
|
||||
if (session.isFlying()) {
|
||||
// Of course e.g. mobile handles it differently with a descend case, while
|
||||
// Of course e.g. mobile devices handle it differently with a descend case, while
|
||||
// e.g. Win10 sends SNEAK_DOWN. Why? We'll never know.
|
||||
return authInputData.contains(PlayerAuthInputData.DESCEND) || authInputData.contains(PlayerAuthInputData.SNEAK_DOWN);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user