1.20.3: compiling protocol changes

This commit is contained in:
Konicai 2023-11-25 07:09:02 -05:00
parent 184a14d026
commit a89aa4e064
15 changed files with 147 additions and 64 deletions

View File

@ -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) {

View File

@ -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

View File

@ -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) {

View File

@ -118,8 +118,9 @@ public class BedrockBlockEntityDataTranslator extends PacketTranslator<BlockEnti
String pool = tag.getString("target_pool");
String finalState = tag.getString("final_state");
String joint = tag.getString("joint");
// last two parameters are priority values that Bedrock doesn't have (yet?)
ServerboundSetJigsawBlockPacket jigsawPacket = new ServerboundSetJigsawBlockPacket(pos, name, target, pool,
finalState, joint);
finalState, joint, 0, 0);
session.sendDownstreamGamePacket(jigsawPacket);
}

View File

@ -26,23 +26,23 @@
package org.geysermc.geyser.translator.protocol.java;
import com.github.steveice10.mc.protocol.data.game.ResourcePackStatus;
import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundResourcePackPacket;
import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundResourcePackPushPacket;
import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundResourcePackPacket;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator;
@Translator(packet = ClientboundResourcePackPacket.class)
public class JavaClientboundResourcePacksPacket extends PacketTranslator<ClientboundResourcePackPacket> {
@Translator(packet = ClientboundResourcePackPushPacket.class)
public class JavaClientboundResourcePackPushPacket extends PacketTranslator<ClientboundResourcePackPushPacket> {
@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));
}
}
}

View File

@ -81,7 +81,7 @@ public class JavaUpdateAdvancementsTranslator extends PacketTranslator<Clientbou
GeyserAdvancement advancement = session.getAdvancementsCache().getStoredAdvancements().get(advancementId);
if (advancement != null && advancement.getDisplayData() != null) {
if (advancement.getDisplayData().isShowToast() && session.getAdvancementsCache().isEarned(advancement)) {
String frameType = advancement.getDisplayData().getFrameType().toString().toLowerCase(Locale.ROOT);
String frameType = advancement.getDisplayData().getAdvancementType().toString().toLowerCase(Locale.ROOT);
String frameTitle = advancement.getDisplayColor() + MinecraftLocale.getLocaleString("advancements.toast." + frameType, session.locale());
String advancementName = MessageTranslator.convertMessage(advancement.getDisplayData().getTitle(), session.locale());

View File

@ -25,9 +25,11 @@
package org.geysermc.geyser.translator.protocol.java.entity.spawn;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
import com.github.steveice10.mc.protocol.data.game.entity.object.Direction;
import com.github.steveice10.mc.protocol.data.game.entity.object.FallingBlockData;
import com.github.steveice10.mc.protocol.data.game.entity.object.ProjectileData;
import com.github.steveice10.mc.protocol.data.game.entity.object.WardenData;
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddEntityPacket;
import org.cloudburstmc.math.vector.Vector3f;
@ -114,6 +116,14 @@ public class JavaAddEntityTranslator extends PacketTranslator<ClientboundAddEnti
entity = definition.factory().create(session, packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(),
packet.getUuid(), definition, position, motion, yaw, pitch, headYaw);
}
if (packet.getType() == EntityType.WARDEN) {
WardenData wardenData = (WardenData) packet.getData();
if (wardenData.isEmerging()) {
entity.setPose(Pose.EMERGING);
}
}
session.getEntityCache().spawnEntity(entity);
}
}

View File

@ -33,6 +33,7 @@ import org.cloudburstmc.nbt.NbtMapBuilder;
import org.cloudburstmc.protocol.bedrock.packet.BlockEntityDataPacket;
import org.cloudburstmc.protocol.bedrock.packet.BlockEventPacket;
import it.unimi.dsi.fastutil.objects.Object2IntMaps;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.util.PlatformType;
import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.level.physics.Direction;
@ -47,22 +48,25 @@ public class JavaBlockEventTranslator extends PacketTranslator<ClientboundBlockE
@Override
public void translate(GeyserSession session, ClientboundBlockEventPacket packet) {
BlockEventPacket blockEventPacket = new BlockEventPacket();
Vector3i position = packet.getPosition();
BlockValue value = packet.getValue();
BlockEventPacket blockEventPacket = new BlockEventPacket();
blockEventPacket.setBlockPosition(position);
if (packet.getValue() instanceof ChestValue value) {
if (value instanceof ChestValue chestValue) {
blockEventPacket.setEventType(1);
blockEventPacket.setEventData(value.getViewers() > 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<ClientboundBlockE
});
blockEntity.setAction(action);
}
} else if (packet.getValue() instanceof MobSpawnerValue) {
} else if (value instanceof MobSpawnerValue) {
blockEventPacket.setEventType(1);
session.sendUpstreamPacket(blockEventPacket);
} else if (packet.getValue() instanceof EndGatewayValue) {
blockEventPacket.setEventType(1);
session.sendUpstreamPacket(blockEventPacket);
} else if (packet.getValue() instanceof BellValue bellValue) {
} else if (value instanceof BellValue bellValue) {
// Bells - needed to show ring from other players
BlockEntityDataPacket blockEntityPacket = new BlockEntityDataPacket();
blockEntityPacket.setBlockPosition(position);
@ -127,6 +128,14 @@ public class JavaBlockEventTranslator extends PacketTranslator<ClientboundBlockE
blockEntityPacket.setData(builder.build());
session.sendUpstreamPacket(blockEntityPacket);
} else if (value instanceof DecoratedPotValue) {
// todo 1.20.3
} else if (value instanceof GenericBlockValue genericValue) {
if (genericValue.getValue() != 0) {
GeyserImpl.getInstance().getLogger().warning("Nonzero generic block value: " + packet);
}
} else {
GeyserImpl.getInstance().getLogger().warning("Unhandled non-generic block event: " + packet);
}
}
}

View File

@ -46,6 +46,7 @@ public class JavaExplodeTranslator extends PacketTranslator<ClientboundExplodePa
@Override
public void translate(GeyserSession session, ClientboundExplodePacket packet) {
// todo 1.20.3 handle the 4 new fields
LevelEventGenericPacket levelEventPacket = new LevelEventGenericPacket();
levelEventPacket.setType(LevelEvent.PARTICLE_BLOCK_EXPLOSION);
NbtMapBuilder builder = NbtMap.builder();

View File

@ -142,6 +142,7 @@ public class JavaGameEventTranslator extends PacketTranslator<ClientboundGameEve
}
break;
case AFFECTED_BY_ELDER_GUARDIAN:
// todo 1.20.3 does this play a sound? this game event has a value for audible or not
EntityEventPacket eventPacket = new EntityEventPacket();
eventPacket.setType(EntityEventType.ELDER_GUARDIAN_CURSE);
eventPacket.setData(0);
@ -167,6 +168,8 @@ public class JavaGameEventTranslator extends PacketTranslator<ClientboundGameEve
arrowSoundPacket.setPosition(entity.getPosition());
session.sendUpstreamPacket(arrowSoundPacket);
break;
case PUFFERFISH_STING_SOUND:
// todo 1.20.3 was this accidentally not implemented?
default:
break;
}

View File

@ -163,8 +163,12 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
soundEventPacket.setRelativeVolumeDisabled(false);
session.sendUpstreamPacket(soundEventPacket);
}
case SMOKE -> {
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<ClientboundLevelE
return;
}
default -> {
GeyserImpl.getInstance().getLogger().debug("Unhandled level event: " + packet.getEvent());
GeyserImpl.getInstance().getLogger().warning("Unhandled level event: " + packet.getEvent());
return;
}
}

View File

@ -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<ClientboundResetScorePacket> {
@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();
}
}
}

View File

@ -47,6 +47,7 @@ public class JavaSetObjectiveTranslator extends PacketTranslator<ClientboundSetO
@Override
public void translate(GeyserSession session, ClientboundSetObjectivePacket packet) {
// todo 1.20.3 unused NumberFormat ?
WorldCache worldCache = session.getWorldCache();
Scoreboard scoreboard = worldCache.getScoreboard();
int pps = worldCache.increaseAndGetScoreboardPacketsPerSecond();

View File

@ -25,7 +25,6 @@
package org.geysermc.geyser.translator.protocol.java.scoreboard;
import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardAction;
import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition;
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetScorePacket;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
@ -54,12 +53,13 @@ public class JavaSetScoreTranslator extends PacketTranslator<ClientboundSetScore
@Override
public void translate(GeyserSession session, ClientboundSetScorePacket packet) {
// todo 1.20.3 unused display and number format?
WorldCache worldCache = session.getWorldCache();
Scoreboard scoreboard = worldCache.getScoreboard();
int pps = worldCache.increaseAndGetScoreboardPacketsPerSecond();
Objective objective = scoreboard.getObjective(packet.getObjective());
if (objective == null && packet.getAction() != ScoreboardAction.REMOVE) {
if (objective == null) {
if (SHOW_SCOREBOARD_LOGS) {
logger.info(GeyserLocale.getLocaleStringLog("geyser.network.translator.score.failed_objective", packet.getObjective()));
}
@ -68,38 +68,12 @@ public class JavaSetScoreTranslator extends PacketTranslator<ClientboundSetScore
// 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.
boolean isBelowName = objective != null && objective == scoreboard.getObjectiveSlots().get(ScoreboardPosition.BELOW_NAME);
boolean isBelowName = objective == scoreboard.getObjectiveSlots().get(ScoreboardPosition.BELOW_NAME);
switch (packet.getAction()) {
case ADD_OR_UPDATE -> {
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<ClientboundSetScore
/**
* @param objective the objective that currently resides on the below name display slot
*/
private void setBelowName(GeyserSession session, Objective objective, String username, int count) {
PlayerEntity entity = getPlayerEntity(session, username);
protected static void setBelowName(GeyserSession session, Objective objective, String username, int count) {
PlayerEntity entity = getOtherPlayerEntity(session, username);
if (entity == null) {
return;
}
@ -128,7 +102,7 @@ public class JavaSetScoreTranslator extends PacketTranslator<ClientboundSetScore
session.sendUpstreamPacket(entityDataPacket);
}
private PlayerEntity getPlayerEntity(GeyserSession session, String username) {
private static PlayerEntity getOtherPlayerEntity(GeyserSession session, String username) {
// We don't care about the session player, because... they're not going to be seeing their own score
if (session.getPlayerEntity().getUsername().equals(username)) {
return null;

View File

@ -14,7 +14,7 @@ protocol-connection = "3.0.0.Beta1-20231107.190703-112"
raknet = "1.0.0.CR1-20230703.195238-9"
blockstateupdater="1.20.50-20231106.161340-1"
mcauthlib = "d9d773e"
mcprotocollib = "1.20.2-1-20231101.141901-7"
mcprotocollib = "00bce42"
adventure = "4.14.0"
adventure-platform = "4.3.0"
junit = "5.9.2"
@ -87,7 +87,7 @@ guava = { group = "com.google.guava", name = "guava", version.ref = "guava" }
gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" }
junit = { group = "org.junit.jupiter", name = "junit-jupiter", version.ref = "junit" }
mcauthlib = { group = "com.github.GeyserMC", name = "MCAuthLib", version.ref = "mcauthlib" }
mcprotocollib = { group = "com.github.steveice10", name = "mcprotocollib", version.ref = "mcprotocollib" }
mcprotocollib = { group = "com.github.GeyserMC", name = "MCProtocolLib", version.ref = "mcprotocollib" }
raknet = { group = "org.cloudburstmc.netty", name = "netty-transport-raknet", version.ref = "raknet" }
terminalconsoleappender = { group = "net.minecrell", name = "terminalconsoleappender", version.ref = "terminalconsoleappender" }
velocity-api = { group = "com.velocitypowered", name = "velocity-api", version.ref = "velocity" }