From 258d6aadb436c29b0ea969c52564b571983c9c02 Mon Sep 17 00:00:00 2001 From: chris Date: Sat, 27 Jul 2024 00:39:45 +0200 Subject: [PATCH] Fix: Bedrock players being able to always eat food while in peaceful difficulty (#4904) --- .../BedrockServerSettingsRequestTranslator.java | 10 ++++++++++ .../java/JavaChangeDifficultyTranslator.java | 14 +++++++++++--- .../org/geysermc/geyser/util/SettingsUtils.java | 15 +++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockServerSettingsRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockServerSettingsRequestTranslator.java index aa7a2e40f..c7475e5d0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockServerSettingsRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockServerSettingsRequestTranslator.java @@ -27,12 +27,14 @@ package org.geysermc.geyser.translator.protocol.bedrock; import org.cloudburstmc.protocol.bedrock.packet.ServerSettingsRequestPacket; import org.cloudburstmc.protocol.bedrock.packet.ServerSettingsResponsePacket; +import org.cloudburstmc.protocol.bedrock.packet.SetDifficultyPacket; import org.geysermc.cumulus.form.CustomForm; import org.geysermc.cumulus.form.impl.FormDefinitions; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.SettingsUtils; +import org.geysermc.mcprotocollib.protocol.data.game.setting.Difficulty; import java.util.concurrent.TimeUnit; @@ -47,6 +49,14 @@ public class BedrockServerSettingsRequestTranslator extends PacketTranslator { @Override public void translate(GeyserSession session, ClientboundChangeDifficultyPacket packet) { + Difficulty difficulty = packet.getDifficulty(); + session.getWorldCache().setDifficulty(difficulty); + + // Peaceful difficulty allows always eating food - hence, we just do not send it to Bedrock. + if (difficulty == Difficulty.PEACEFUL) { + difficulty = Difficulty.EASY; + } + SetDifficultyPacket setDifficultyPacket = new SetDifficultyPacket(); - setDifficultyPacket.setDifficulty(packet.getDifficulty().ordinal()); + setDifficultyPacket.setDifficulty(difficulty.ordinal()); session.sendUpstreamPacket(setDifficultyPacket); - session.getWorldCache().setDifficulty(packet.getDifficulty()); } } diff --git a/core/src/main/java/org/geysermc/geyser/util/SettingsUtils.java b/core/src/main/java/org/geysermc/geyser/util/SettingsUtils.java index ed97408b9..6f46b191c 100644 --- a/core/src/main/java/org/geysermc/geyser/util/SettingsUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/SettingsUtils.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.util; +import org.cloudburstmc.protocol.bedrock.packet.SetDifficultyPacket; import org.geysermc.cumulus.component.DropdownComponent; import org.geysermc.cumulus.form.CustomForm; import org.geysermc.geyser.GeyserImpl; @@ -33,6 +34,7 @@ import org.geysermc.geyser.level.WorldManager; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.GeyserLocale; import org.geysermc.geyser.text.MinecraftLocale; +import org.geysermc.mcprotocollib.protocol.data.game.setting.Difficulty; public class SettingsUtils { /** @@ -96,6 +98,7 @@ public class SettingsUtils { } builder.validResultHandler((response) -> { + applyDifficultyFix(session); if (showClientSettings) { // Client can only see its coordinates if reducedDebugInfo is disabled and coordinates are enabled in geyser config. if (showCoordinates) { @@ -134,9 +137,21 @@ public class SettingsUtils { } }); + builder.closedOrInvalidResultHandler($ -> applyDifficultyFix(session)); + return builder.build(); } + private static void applyDifficultyFix(GeyserSession session) { + // Peaceful difficulty allows always eating food - hence, we just do not send it to Bedrock. + // Since we sent the real difficulty before opening the server settings form, let's restore it to our workaround here + if (session.getWorldCache().getDifficulty() == Difficulty.PEACEFUL) { + SetDifficultyPacket setDifficultyPacket = new SetDifficultyPacket(); + setDifficultyPacket.setDifficulty(Difficulty.EASY.ordinal()); + session.sendUpstreamPacket(setDifficultyPacket); + } + } + private static String translateEntry(String key, String locale) { if (key.startsWith("%")) { // Bedrock will translate