diff --git a/core/src/main/java/org/geysermc/geyser/level/GeyserAdvancement.java b/core/src/main/java/org/geysermc/geyser/level/GeyserAdvancement.java index e09cad19c..f51e7b2ab 100644 --- a/core/src/main/java/org/geysermc/geyser/level/GeyserAdvancement.java +++ b/core/src/main/java/org/geysermc/geyser/level/GeyserAdvancement.java @@ -26,6 +26,8 @@ package org.geysermc.geyser.level; import com.github.steveice10.mc.protocol.data.game.advancement.Advancement; +import com.github.steveice10.mc.protocol.data.game.advancement.Advancement.DisplayData; +import com.github.steveice10.mc.protocol.data.game.advancement.Advancement.DisplayData.AdvancementType; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.session.cache.AdvancementsCache; import org.geysermc.geyser.text.ChatColor; @@ -61,7 +63,7 @@ public class GeyserAdvancement { return this.advancement.getParentId(); } - public Advancement.DisplayData getDisplayData() { + public DisplayData getDisplayData() { return this.advancement.getDisplayData(); } @@ -69,8 +71,8 @@ public class GeyserAdvancement { * @return Purple for challenges and green for normal advancements */ public String getDisplayColor() { - Advancement.DisplayData displayData = getDisplayData(); - return displayData != null && displayData.getFrameType() == Advancement.DisplayData.FrameType.CHALLENGE ? ChatColor.LIGHT_PURPLE : ChatColor.GREEN; + DisplayData displayData = getDisplayData(); + return displayData != null && displayData.getAdvancementType() == AdvancementType.CHALLENGE ? ChatColor.LIGHT_PURPLE : ChatColor.GREEN; } public @NonNull String getRootId(AdvancementsCache advancementsCache) { diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java index 3562f0d4d..3bc661c16 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java @@ -231,7 +231,7 @@ public class AdvancementsCache { } public String getColorFromAdvancementFrameType(GeyserAdvancement advancement) { - if (advancement.getDisplayData().getFrameType() == Advancement.DisplayData.FrameType.CHALLENGE) { + if (advancement.getDisplayData().getAdvancementType() == Advancement.DisplayData.AdvancementType.CHALLENGE) { return ChatColor.DARK_PURPLE; } return ChatColor.GREEN; // Used for types TASK and GOAL diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java index 1774d9c76..9ff864101 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java @@ -44,6 +44,7 @@ public class DecoratedPotBlockEntityTranslator extends BlockEntityTranslator { if (tag == null) { return; } + // todo 1.20.3 maybe // exact same format if (tag.get("sherds") instanceof ListTag sherds) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockEntityDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockEntityDataTranslator.java index bab5e59a5..239bf9616 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockEntityDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockEntityDataTranslator.java @@ -118,8 +118,9 @@ public class BedrockBlockEntityDataTranslator extends PacketTranslator { +@Translator(packet = ClientboundResourcePackPushPacket.class) +public class JavaClientboundResourcePackPushPacket extends PacketTranslator { @Override - public void translate(GeyserSession session, ClientboundResourcePackPacket packet) { + public void translate(GeyserSession session, ClientboundResourcePackPushPacket packet) { // We need to "answer" this to avoid timeout issues related to resource packs // If packs are required, we need to lie to the server that we accepted them, as we get kicked otherwise. if (packet.isRequired()) { - session.sendDownstreamPacket(new ServerboundResourcePackPacket(ResourcePackStatus.SUCCESSFULLY_LOADED)); + session.sendDownstreamPacket(new ServerboundResourcePackPacket(packet.getId(), ResourcePackStatus.SUCCESSFULLY_LOADED)); } else { - session.sendDownstreamPacket(new ServerboundResourcePackPacket(ResourcePackStatus.DECLINED)); + session.sendDownstreamPacket(new ServerboundResourcePackPacket(packet.getId(), ResourcePackStatus.DECLINED)); } } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateAdvancementsTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateAdvancementsTranslator.java index e98e5c1ec..a7efdbefa 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateAdvancementsTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateAdvancementsTranslator.java @@ -81,7 +81,7 @@ public class JavaUpdateAdvancementsTranslator extends PacketTranslator 0 ? 1 : 0); + blockEventPacket.setEventData(chestValue.getViewers() > 0 ? 1 : 0); session.sendUpstreamPacket(blockEventPacket); - } else if (packet.getValue() instanceof EndGatewayValue) { + } else if (value instanceof EndGatewayValue) { blockEventPacket.setEventType(1); session.sendUpstreamPacket(blockEventPacket); - } else if (packet.getValue() instanceof NoteBlockValue) { + } else if (value instanceof NoteBlockValue) { session.getGeyser().getWorldManager().getBlockAtAsync(session, position).thenAccept(blockState -> { blockEventPacket.setEventData(BlockStateValues.getNoteblockPitch(blockState)); session.sendUpstreamPacket(blockEventPacket); }); - } else if (packet.getValue() instanceof PistonValue pistonValue) { + } else if (value instanceof PistonValue pistonValue) { PistonValueType action = (PistonValueType) packet.getType(); Direction direction = Direction.fromPistonValue(pistonValue.getDirection()); PistonCache pistonCache = session.getPistonCache(); @@ -98,13 +102,10 @@ public class JavaBlockEventTranslator extends PacketTranslator { - effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_SHOOT); + case SMOKE, WHITE_SMOKE -> { + if (levelEvent == LevelEventType.SMOKE) { + effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_SHOOT); + } else { + effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_SHOOT_WHITE_SMOKE); + } SmokeEventData smokeEventData = (SmokeEventData) packet.getData(); int data = 0; @@ -332,7 +336,7 @@ public class JavaLevelEventTranslator extends PacketTranslator { - GeyserImpl.getInstance().getLogger().debug("Unhandled level event: " + packet.getEvent()); + GeyserImpl.getInstance().getLogger().warning("Unhandled level event: " + packet.getEvent()); return; } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaResetScorePacket.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaResetScorePacket.java new file mode 100644 index 000000000..418037760 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaResetScorePacket.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.translator.protocol.java.scoreboard; + +import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition; +import com.github.steveice10.mc.protocol.packet.ingame.clientbound.scoreboard.ClientboundResetScorePacket; +import org.geysermc.geyser.scoreboard.Objective; +import org.geysermc.geyser.scoreboard.Scoreboard; +import org.geysermc.geyser.scoreboard.ScoreboardUpdater; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.WorldCache; +import org.geysermc.geyser.translator.protocol.PacketTranslator; +import org.geysermc.geyser.translator.protocol.Translator; + +@Translator(packet = ClientboundResetScorePacket.class) +public class JavaResetScorePacket extends PacketTranslator { + + @Override + public void translate(GeyserSession session, ClientboundResetScorePacket packet) { + WorldCache worldCache = session.getWorldCache(); + Scoreboard scoreboard = worldCache.getScoreboard(); + int pps = worldCache.increaseAndGetScoreboardPacketsPerSecond(); + + Objective belowName = scoreboard.getObjectiveSlots().get(ScoreboardPosition.BELOW_NAME); + + if (packet.getObjective() == null) { + // No objective name means all scores are reset for that player (/scoreboard players reset PLAYERNAME) + for (Objective otherObjective : scoreboard.getObjectives()) { + otherObjective.removeScore(packet.getOwner()); + } + + // as described below + if (belowName != null) { + JavaSetScoreTranslator.setBelowName(session, belowName, packet.getOwner(), 0); + } + } else { + Objective objective = scoreboard.getObjective(packet.getObjective()); + objective.removeScore(packet.getOwner()); + + // If this is the objective that is in use to show the below name text, we need to update the player + // attached to this score. + if (objective == belowName) { + // Update the score on this player to now reflect 0 + JavaSetScoreTranslator.setBelowName(session, objective, packet.getOwner(), 0); + } + } + + // ScoreboardUpdater will handle it for us if the packets per second + // (for score and team packets) is higher than the first threshold + if (pps < ScoreboardUpdater.FIRST_SCORE_PACKETS_PER_SECOND_THRESHOLD) { + scoreboard.onUpdate(); + } + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetObjectiveTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetObjectiveTranslator.java index 3b009a2a5..cef94c98e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetObjectiveTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetObjectiveTranslator.java @@ -47,6 +47,7 @@ public class JavaSetObjectiveTranslator extends PacketTranslator { - objective.setScore(packet.getEntry(), packet.getValue()); - if (isBelowName) { - // Update the below name score on this player - setBelowName(session, objective, packet.getEntry(), packet.getValue()); - } - } - case REMOVE -> { - if (packet.getObjective().isEmpty()) { - // An empty objective name means all scores are reset for that player (/scoreboard players reset PLAYERNAME) - Objective belowName = scoreboard.getObjectiveSlots().get(ScoreboardPosition.BELOW_NAME); - if (belowName != null) { - setBelowName(session, belowName, packet.getEntry(), 0); - } - } - - if (objective != null) { - objective.removeScore(packet.getEntry()); - - if (isBelowName) { - // Update the score on this player to now reflect 0 - setBelowName(session, objective, packet.getEntry(), 0); - } - } else { - for (Objective objective1 : scoreboard.getObjectives()) { - objective1.removeScore(packet.getEntry()); - } - } - } + objective.setScore(packet.getOwner(), packet.getValue()); + if (isBelowName) { + // Update the below name score on this player + setBelowName(session, objective, packet.getOwner(), packet.getValue()); } // ScoreboardUpdater will handle it for us if the packets per second @@ -112,8 +86,8 @@ public class JavaSetScoreTranslator extends PacketTranslator