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:
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user