Skip to content

Commit

Permalink
Fix: Bedrock players being able to always eat food while in peaceful …
Browse files Browse the repository at this point in the history
…difficulty (GeyserMC#4904)
  • Loading branch information
onebeastchris authored Jul 26, 2024
1 parent 663e3af commit 258d6aa
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@

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;

Expand All @@ -47,6 +49,14 @@ public void translate(GeyserSession session, ServerSettingsRequestPacket packet)
return;
}

// Peaceful difficulty allows always eating food - hence, we just do not send it to Bedrock.
// However, in order for server settings to show it properly, let's revert while we are in the menu!
if (session.getWorldCache().getDifficulty() == Difficulty.PEACEFUL) {
SetDifficultyPacket setDifficultyPacket = new SetDifficultyPacket();
setDifficultyPacket.setDifficulty(Difficulty.PEACEFUL.ordinal());
session.sendUpstreamPacket(setDifficultyPacket);
}

CustomForm form = SettingsUtils.buildForm(session);
int formId = session.getFormCache().addForm(form);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,29 @@

package org.geysermc.geyser.translator.protocol.java;

import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundChangeDifficultyPacket;
import org.cloudburstmc.protocol.bedrock.packet.SetDifficultyPacket;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator;
import org.geysermc.mcprotocollib.protocol.data.game.setting.Difficulty;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundChangeDifficultyPacket;

@Translator(packet = ClientboundChangeDifficultyPacket.class)
public class JavaChangeDifficultyTranslator extends PacketTranslator<ClientboundChangeDifficultyPacket> {

@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());
}
}
15 changes: 15 additions & 0 deletions core/src/main/java/org/geysermc/geyser/util/SettingsUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -33,6 +34,7 @@
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 {
/**
Expand Down Expand Up @@ -96,6 +98,7 @@ public static CustomForm buildForm(GeyserSession session) {
}

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) {
Expand Down Expand Up @@ -134,9 +137,21 @@ public static CustomForm buildForm(GeyserSession session) {
}
});

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
Expand Down

0 comments on commit 258d6aa

Please sign in to comment.