1
0
mirror of https://github.com/GeyserMC/Geyser.git synced 2025-12-28 19:29:14 +00:00

Fix: waypoint and vault stack traces, bump Adventure (#5735)

* Catch class cast exception when the server sends us incorrect waypoint data

* Replace vault item component translation failure stacktrace with log message

* Bump adventure, update text component hashers

* Only send vault item component warning message once, do instanceof checks in GeyserWaypoint subclasses

* Revert vault item component error message to warning
This commit is contained in:
Eclipse
2025-08-01 22:35:18 +00:00
committed by GitHub
parent 57eb3b7c27
commit 9b04d7e019
7 changed files with 44 additions and 16 deletions

View File

@@ -73,12 +73,21 @@ public interface ComponentHasher {
MinecraftHasher<ClickEvent.Action> CLICK_EVENT_ACTION = MinecraftHasher.STRING.cast(ClickEvent.Action::toString);
MinecraftHasher<ClickEvent.Payload.Text> CLICK_EVENT_TEXT_PAYLOAD = MinecraftHasher.STRING.cast(ClickEvent.Payload.Text::value);
MinecraftHasher<ClickEvent.Payload.Int> CLICK_EVENT_INT_PAYLOAD = MinecraftHasher.INT.cast(ClickEvent.Payload.Int::integer);
// Both dialog and custom click event types are not possible to hash within Geyser, because:
// - Dialog has no proper implementation within Adventure yet. Once it does, we'd probably only hash dialog holders with a resource location, because setting up
// hashers for the full dialog structure can be a lot of work.
// - Custom uses BinaryTagHolder to store NBT data, which essentially only stores a string representation. This won't work with hashing, we need a NBT tag to hash.
MinecraftHasher<ClickEvent> CLICK_EVENT = CLICK_EVENT_ACTION.dispatch("action", ClickEvent::action, action -> switch (action) {
case OPEN_URL -> builder -> builder.accept("url", MinecraftHasher.STRING, ClickEvent::value);
case OPEN_FILE -> builder -> builder.accept("path", MinecraftHasher.STRING, ClickEvent::value);
case RUN_COMMAND, SUGGEST_COMMAND -> builder -> builder.accept("command", MinecraftHasher.STRING, ClickEvent::value);
case CHANGE_PAGE -> builder -> builder.accept("page", MinecraftHasher.STRING, ClickEvent::value);
case COPY_TO_CLIPBOARD -> builder -> builder.accept("value", MinecraftHasher.STRING, ClickEvent::value);
case OPEN_URL -> builder -> builder.accept("url", CLICK_EVENT_TEXT_PAYLOAD, event -> (ClickEvent.Payload.Text) event.payload());
case OPEN_FILE -> builder -> builder.accept("path", CLICK_EVENT_TEXT_PAYLOAD, event -> (ClickEvent.Payload.Text) event.payload());
case RUN_COMMAND, SUGGEST_COMMAND -> builder -> builder.accept("command", CLICK_EVENT_TEXT_PAYLOAD, event -> (ClickEvent.Payload.Text) event.payload());
case CHANGE_PAGE -> builder -> builder.accept("page", CLICK_EVENT_INT_PAYLOAD, event -> (ClickEvent.Payload.Int) event.payload());
case COPY_TO_CLIPBOARD -> builder -> builder.accept("value", CLICK_EVENT_TEXT_PAYLOAD, event -> (ClickEvent.Payload.Text) event.payload());
case SHOW_DIALOG, CUSTOM -> MapBuilder.unit();
});
MinecraftHasher<HoverEvent.Action<?>> HOVER_EVENT_ACTION = MinecraftHasher.STRING.cast(HoverEvent.Action::toString);

View File

@@ -1283,15 +1283,14 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
}
this.bundleCache.tick();
this.dialogManager.tick();
this.waypointCache.tick();
if (spawned && protocol.getOutboundState() == ProtocolState.GAME) {
// Could move this to the PlayerAuthInput translator, in the event the player lags
// but this will work once we implement matching Java custom tick cycles
sendDownstreamGamePacket(ServerboundClientTickEndPacket.INSTANCE);
}
dialogManager.tick();
waypointCache.tick();
} catch (Throwable throwable) {
throwable.printStackTrace();
}

View File

@@ -50,8 +50,12 @@ public class AzimuthWaypoint extends GeyserWaypoint implements TickingWaypoint {
@Override
public void setData(WaypointData data) {
angle = ((AzimuthWaypointData) data).angle();
updatePosition();
if (data instanceof AzimuthWaypointData azimuthData) {
angle = azimuthData.angle();
updatePosition();
} else {
session.getGeyser().getLogger().warning("Received incorrect waypoint data " + data.getClass() + " for azimuth waypoint");
}
}
@Override

View File

@@ -43,8 +43,11 @@ public class ChunkWaypoint extends GeyserWaypoint {
@Override
public void setData(WaypointData data) {
ChunkWaypointData chunk = (ChunkWaypointData) data;
// Set position in centre of chunk
position = Vector3f.from(chunk.chunkX() * 16.0F + 8.0F, session.getPlayerEntity().position().getY(), chunk.chunkZ() * 16.0F + 8.0F);
if (data instanceof ChunkWaypointData chunkData) {
// Set position in centre of chunk
position = Vector3f.from(chunkData.chunkX() * 16.0F + 8.0F, session.getPlayerEntity().position().getY(), chunkData.chunkZ() * 16.0F + 8.0F);
} else {
session.getGeyser().getLogger().warning("Received incorrect waypoint data " + data.getClass() + " for chunk waypoint");
}
}
}

View File

@@ -42,6 +42,10 @@ public class CoordinatesWaypoint extends GeyserWaypoint {
@Override
public void setData(WaypointData data) {
position = ((Vec3iWaypointData) data).vector().toFloat();
if (data instanceof Vec3iWaypointData vec3iData) {
position = vec3iData.vector().toFloat();
} else {
session.getGeyser().getLogger().warning("Received incorrect waypoint data " + data.getClass() + " for coordinates waypoint");
}
}
}

View File

@@ -57,6 +57,8 @@ import java.util.UUID;
@BlockEntity(type = BlockEntityType.VAULT)
public class VaultBlockEntityTranslator extends BlockEntityTranslator {
private static boolean loggedComponentTranslationFailure = false;
// Bedrock 1.21 does not send the position nor ID in the tag.
@Override
public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, BlockState blockState) {
@@ -88,7 +90,14 @@ public class VaultBlockEntityTranslator extends BlockEntityTranslator {
for (Map.Entry<String, Object> entry : componentsTag.entrySet()) {
var consumer = DATA_COMPONENT_DECODERS.get(entry.getKey());
if (consumer != null) {
consumer.accept(session, (NbtMap) entry.getValue(), components);
try {
consumer.accept(session, (NbtMap) entry.getValue(), components);
} catch (RuntimeException exception) {
if (!loggedComponentTranslationFailure) {
session.getGeyser().getLogger().warning("Failed to translate vault item component data for " + entry.getKey() + "! Did the component structure change?");
loggedComponentTranslationFailure = true;
}
}
}
}
ItemData bedrockItem = ItemTranslator.translateToBedrock(session, mapping.getJavaItem(), mapping, count, components).build();

View File

@@ -15,7 +15,7 @@ protocol-codec = "3.0.0.Beta7-20250730.214113-17"
raknet = "1.0.0.CR3-20250218.160705-18"
minecraftauth = "4.1.1"
mcprotocollib = "1.21.7-20250725.134643-4"
adventure = "4.21.0"
adventure = "4.24.0"
adventure-platform = "4.3.0"
junit = "5.9.2"
checkerframework = "3.19.0"