Ensure players aren't floating in their beds; improve Bedrock sleeping notifications

This commit is contained in:
Camotoy 2024-08-30 22:16:45 -04:00
parent 63e60bc93c
commit 8935b34365
No known key found for this signature in database
GPG key ID: 7EEFB66FE798081F
5 changed files with 50 additions and 12 deletions

View file

@ -42,7 +42,11 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.cloudburstmc.protocol.bedrock.packet.*;
import org.cloudburstmc.protocol.bedrock.packet.AddPlayerPacket;
import org.cloudburstmc.protocol.bedrock.packet.MovePlayerPacket;
import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket;
import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket;
import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket;
import org.geysermc.geyser.api.entity.type.player.GeyserPlayerEntity;
import org.geysermc.geyser.entity.EntityDefinitions;
import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
@ -278,7 +282,13 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity {
@Override
public void setPosition(Vector3f position) {
super.setPosition(position.add(0, definition.offset(), 0));
if (this.bedPosition != null) {
// As of Bedrock 1.21.22 and Fabric 1.21.1
// Messes with Bedrock if we send this to the client itself, though.
super.setPosition(position.up(0.2f));
} else {
super.setPosition(position.add(0, definition.offset(), 0));
}
}
@Override

View file

@ -140,7 +140,7 @@ public class SessionPlayerEntity extends PlayerEntity {
if (valid) { // Don't update during session init
session.getCollisionManager().updatePlayerBoundingBox(position);
}
super.setPosition(position);
this.position = position.add(0, definition.offset(), 0);
}
/**

View file

@ -29,7 +29,6 @@ import io.netty.buffer.Unpooled;
import org.cloudburstmc.protocol.bedrock.BedrockDisconnectReasons;
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec;
import org.cloudburstmc.protocol.bedrock.codec.compat.BedrockCompat;
import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622;
import org.cloudburstmc.protocol.bedrock.data.ExperimentData;
import org.cloudburstmc.protocol.bedrock.data.PacketCompressionAlgorithm;
import org.cloudburstmc.protocol.bedrock.data.ResourcePackType;

View file

@ -61,7 +61,7 @@ public class BedrockMovePlayerTranslator extends PacketTranslator<MovePlayerPack
if (entity.getBedPosition() != null) {
// https://github.com/GeyserMC/Geyser/issues/5001
// Bedrock 1.20.22 started sending a MovePlayerPacket as soon as it got into a bed.
// Bedrock 1.21.22 started sending a MovePlayerPacket as soon as it got into a bed.
// This trips up Fabric.
return;
}

View file

@ -25,8 +25,10 @@
package org.geysermc.geyser.translator.protocol.java;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundSystemChatPacket;
import net.kyori.adventure.text.TranslatableComponent;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
import org.cloudburstmc.protocol.bedrock.packet.LevelEventGenericPacket;
import org.cloudburstmc.protocol.bedrock.packet.TextPacket;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.ChatColor;
@ -34,18 +36,45 @@ import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator;
import org.geysermc.geyser.translator.text.MessageTranslator;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundSystemChatPacket;
@Translator(packet = ClientboundSystemChatPacket.class)
public class JavaSystemChatTranslator extends PacketTranslator<ClientboundSystemChatPacket> {
@Override
public void translate(GeyserSession session, ClientboundSystemChatPacket packet) {
if (packet.getContent() instanceof TranslatableComponent component && component.key().equals("chat.disabled.missingProfileKey")) {
// We likely got this message as a response to a player trying to chat
// As there SHOULD be no false flags for this, print every time it shows up in chat.
if (Boolean.parseBoolean(System.getProperty("Geyser.PrintSecureChatInformation", "true"))) {
session.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.chat.secure_info_1", session.locale()));
session.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.chat.secure_info_2", session.locale(), "https://geysermc.link/secure-chat"));
if (packet.getContent() instanceof TranslatableComponent component) {
if (component.key().equals("chat.disabled.missingProfileKey")) {
// We likely got this message as a response to a player trying to chat
// As there SHOULD be no false flags for this, print every time it shows up in chat.
if (Boolean.parseBoolean(System.getProperty("Geyser.PrintSecureChatInformation", "true"))) {
session.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.chat.secure_info_1", session.locale()));
session.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.chat.secure_info_2", session.locale(), "https://geysermc.link/secure-chat"));
}
} else if (component.key().equals("sleep.players_sleeping")) {
if (component.arguments().size() == 2) {
// Hack FYI, but it allows Bedrock players to easily understand this information
// without it being covered up or saying the night is being slept through.
int numPlayersSleeping = ((Number) component.arguments().get(0).value()).intValue();
int totalPlayersNeeded = ((Number) component.arguments().get(1).value()).intValue();
LevelEventGenericPacket sleepInfoPacket = new LevelEventGenericPacket();
sleepInfoPacket.setType(LevelEvent.SLEEPING_PLAYERS);
sleepInfoPacket.setTag(NbtMap.builder()
.putInt("ableToSleep", totalPlayersNeeded)
.putInt("overworldPlayerCount", totalPlayersNeeded)
.putInt("sleepingPlayerCount", numPlayersSleeping)
.build());
session.sendUpstreamPacket(sleepInfoPacket);
}
} else if (component.key().equals("sleep.skipping_night")) {
LevelEventGenericPacket sleepInfoPacket = new LevelEventGenericPacket();
sleepInfoPacket.setType(LevelEvent.SLEEPING_PLAYERS);
sleepInfoPacket.setTag(NbtMap.builder()
.putInt("ableToSleep", 1)
.putInt("overworldPlayerCount", 1)
.putInt("sleepingPlayerCount", 1)
.build());
session.sendUpstreamPacket(sleepInfoPacket);
}
}