Fix spectator gamemode movement

- Don't allow the player to toggle flight status in spectator mode
- Fix weird flight movement when player was previously on the ground
- The player is always flying in spectator mode, no exceptions
This commit is contained in:
Camotoy 2021-07-28 13:21:18 -04:00
parent e0e6605fb6
commit 5529a1cc1c
No known key found for this signature in database
GPG Key ID: 7EEFB66FE798081F
3 changed files with 31 additions and 19 deletions

View File

@ -40,6 +40,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
import com.github.steveice10.mc.protocol.data.game.recipe.Recipe;
import com.github.steveice10.mc.protocol.data.game.statistic.Statistic;
import com.github.steveice10.mc.protocol.packet.handshake.client.HandshakePacket;
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerAbilitiesPacket;
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerPositionPacket;
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerPositionRotationPacket;
import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientTeleportConfirmPacket;
@ -381,18 +382,6 @@ public class GeyserSession implements CommandSender {
*/
private boolean flying = false;
/**
* If the current player is in noclip
*/
@Setter
private boolean noClip = false;
/**
* If the current player can not interact with the world
*/
@Setter
private boolean worldImmutable = false;
/**
* Caches current rain status.
*/
@ -1282,15 +1271,21 @@ public class GeyserSession implements CommandSender {
adventureSettingsPacket.setPlayerPermission(opPermissionLevel >= 2 ? PlayerPermission.OPERATOR : PlayerPermission.MEMBER);
// Update the noClip and worldImmutable values based on the current gamemode
noClip = gameMode == GameMode.SPECTATOR;
worldImmutable = gameMode == GameMode.ADVENTURE || gameMode == GameMode.SPECTATOR;
boolean spectator = gameMode == GameMode.SPECTATOR;
boolean worldImmutable = gameMode == GameMode.ADVENTURE || spectator;
Set<AdventureSetting> flags = adventureSettingsPacket.getSettings();
if (canFly) {
if (canFly || spectator) {
flags.add(AdventureSetting.MAY_FLY);
}
if (flying) {
if (flying || spectator) {
if (spectator && !flying) {
// We're "flying locked" in this gamemode
flying = true;
ClientPlayerAbilitiesPacket abilitiesPacket = new ClientPlayerAbilitiesPacket(true);
sendDownstreamPacket(abilitiesPacket);
}
flags.add(AdventureSetting.FLYING);
}
@ -1298,7 +1293,7 @@ public class GeyserSession implements CommandSender {
flags.add(AdventureSetting.WORLD_IMMUTABLE);
}
if (noClip) {
if (spectator) {
flags.add(AdventureSetting.NO_CLIP);
}

View File

@ -25,6 +25,7 @@
package org.geysermc.connector.network.translators.bedrock;
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerAbilitiesPacket;
import com.nukkitx.protocol.bedrock.data.AdventureSetting;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
@ -39,6 +40,12 @@ public class BedrockAdventureSettingsTranslator extends PacketTranslator<Adventu
@Override
public void translate(AdventureSettingsPacket packet, GeyserSession session) {
boolean isFlying = packet.getSettings().contains(AdventureSetting.FLYING);
if (!isFlying && session.getGameMode() == GameMode.SPECTATOR) {
// We should always be flying in spectator mode
session.sendAdventureSettings();
return;
}
session.setFlying(isFlying);
ClientPlayerAbilitiesPacket abilitiesPacket = new ClientPlayerAbilitiesPacket(isFlying);
session.sendDownstreamPacket(abilitiesPacket);

View File

@ -51,8 +51,6 @@ public class JavaNotifyClientTranslator extends PacketTranslator<ServerNotifyCli
@Override
public void translate(ServerNotifyClientPacket packet, GeyserSession session) {
PlayerEntity entity = session.getPlayerEntity();
if (entity == null)
return;
switch (packet.getNotification()) {
case START_RAIN:
@ -110,6 +108,18 @@ public class JavaNotifyClientTranslator extends PacketTranslator<ServerNotifyCli
session.sendAdventureSettings();
if (session.getPlayerEntity().isOnGround() && gameMode == GameMode.SPECTATOR) {
// Fix a bug where the player has glitched movement and thinks they are still on the ground
MovePlayerPacket movePlayerPacket = new MovePlayerPacket();
movePlayerPacket.setRuntimeEntityId(entity.getGeyserId());
movePlayerPacket.setPosition(entity.getPosition());
movePlayerPacket.setRotation(entity.getBedrockRotation());
movePlayerPacket.setOnGround(false);
movePlayerPacket.setMode(MovePlayerPacket.Mode.TELEPORT);
movePlayerPacket.setTeleportationCause(MovePlayerPacket.TeleportationCause.UNKNOWN);
session.sendUpstreamPacket(movePlayerPacket);
}
// Update the crafting grid to add/remove barriers for creative inventory
PlayerInventoryTranslator.updateCraftingGrid(session, session.getPlayerInventory());
break;