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.recipe.Recipe;
import com.github.steveice10.mc.protocol.data.game.statistic.Statistic; 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.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.ClientPlayerPositionPacket;
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerPositionRotationPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerPositionRotationPacket;
import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientTeleportConfirmPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientTeleportConfirmPacket;
@ -381,18 +382,6 @@ public class GeyserSession implements CommandSender {
*/ */
private boolean flying = false; 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. * Caches current rain status.
*/ */
@ -1282,15 +1271,21 @@ public class GeyserSession implements CommandSender {
adventureSettingsPacket.setPlayerPermission(opPermissionLevel >= 2 ? PlayerPermission.OPERATOR : PlayerPermission.MEMBER); adventureSettingsPacket.setPlayerPermission(opPermissionLevel >= 2 ? PlayerPermission.OPERATOR : PlayerPermission.MEMBER);
// Update the noClip and worldImmutable values based on the current gamemode // Update the noClip and worldImmutable values based on the current gamemode
noClip = gameMode == GameMode.SPECTATOR; boolean spectator = gameMode == GameMode.SPECTATOR;
worldImmutable = gameMode == GameMode.ADVENTURE || gameMode == GameMode.SPECTATOR; boolean worldImmutable = gameMode == GameMode.ADVENTURE || spectator;
Set<AdventureSetting> flags = adventureSettingsPacket.getSettings(); Set<AdventureSetting> flags = adventureSettingsPacket.getSettings();
if (canFly) { if (canFly || spectator) {
flags.add(AdventureSetting.MAY_FLY); 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); flags.add(AdventureSetting.FLYING);
} }
@ -1298,7 +1293,7 @@ public class GeyserSession implements CommandSender {
flags.add(AdventureSetting.WORLD_IMMUTABLE); flags.add(AdventureSetting.WORLD_IMMUTABLE);
} }
if (noClip) { if (spectator) {
flags.add(AdventureSetting.NO_CLIP); flags.add(AdventureSetting.NO_CLIP);
} }

View File

@ -25,6 +25,7 @@
package org.geysermc.connector.network.translators.bedrock; 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.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerAbilitiesPacket;
import com.nukkitx.protocol.bedrock.data.AdventureSetting; import com.nukkitx.protocol.bedrock.data.AdventureSetting;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
@ -39,6 +40,12 @@ public class BedrockAdventureSettingsTranslator extends PacketTranslator<Adventu
@Override @Override
public void translate(AdventureSettingsPacket packet, GeyserSession session) { public void translate(AdventureSettingsPacket packet, GeyserSession session) {
boolean isFlying = packet.getSettings().contains(AdventureSetting.FLYING); 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); session.setFlying(isFlying);
ClientPlayerAbilitiesPacket abilitiesPacket = new ClientPlayerAbilitiesPacket(isFlying); ClientPlayerAbilitiesPacket abilitiesPacket = new ClientPlayerAbilitiesPacket(isFlying);
session.sendDownstreamPacket(abilitiesPacket); session.sendDownstreamPacket(abilitiesPacket);

View File

@ -51,8 +51,6 @@ public class JavaNotifyClientTranslator extends PacketTranslator<ServerNotifyCli
@Override @Override
public void translate(ServerNotifyClientPacket packet, GeyserSession session) { public void translate(ServerNotifyClientPacket packet, GeyserSession session) {
PlayerEntity entity = session.getPlayerEntity(); PlayerEntity entity = session.getPlayerEntity();
if (entity == null)
return;
switch (packet.getNotification()) { switch (packet.getNotification()) {
case START_RAIN: case START_RAIN:
@ -110,6 +108,18 @@ public class JavaNotifyClientTranslator extends PacketTranslator<ServerNotifyCli
session.sendAdventureSettings(); 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 // Update the crafting grid to add/remove barriers for creative inventory
PlayerInventoryTranslator.updateCraftingGrid(session, session.getPlayerInventory()); PlayerInventoryTranslator.updateCraftingGrid(session, session.getPlayerInventory());
break; break;