From 36f998e46663432abe0bd4c8d564f3ea5c5c31ec Mon Sep 17 00:00:00 2001 From: BruebachL <44814898+BruebachL@users.noreply.github.com> Date: Mon, 7 Sep 2026 08:21:26 +0200 Subject: [PATCH] [Client] Fix pawn avatar cache key collision for players without a custom avatar (#4086) (#7264) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Player pawns are looked up in QPixmapCache under a key built from the rendered size, user level, and the avatar pixmap's cacheKey(). A null pixmap reports cacheKey() 0, so all players without a custom avatar collided: the first pawn rendered for a given size and user level was reused for the next one, showing the wrong player's pawn. Extend the key with the rendered height, the lowercased privlevel (matching UserLevelPixmapGenerator), and both pawn colors so that every visually distinct pawn gets its own cache entry. Co-authored-by: Lukas Brübach --- .../src/game_graphics/player/player_target.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cockatrice/src/game_graphics/player/player_target.cpp b/cockatrice/src/game_graphics/player/player_target.cpp index 63c060b02..d6c28370d 100644 --- a/cockatrice/src/game_graphics/player/player_target.cpp +++ b/cockatrice/src/game_graphics/player/player_target.cpp @@ -137,8 +137,18 @@ void PlayerTarget::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*o QRectF translatedRect = painter->combinedTransform().mapRect(avatarBoundingRect); QSize translatedSize = translatedRect.size().toSize(); QPixmap cachedPixmap; + // The key must cover everything the generated pawn depends on: the rendered + // size, the user level, and the pixmap being drawn. fullPixmap.cacheKey() is + // 0 for every null pixmap, so the default-pawn branch additionally needs the + // pawn's privlevel (lowercased, matching UserLevelPixmapGenerator) and colors + // in the key — otherwise two players without a custom avatar (and the same + // user level) would share one cached pawn. const QString cacheKey = "avatar" + QString::number(translatedSize.width()) + "_" + - QString::number(info->user_level()) + "_" + QString::number(fullPixmap.cacheKey()); + QString::number(translatedSize.height()) + "_" + QString::number(info->user_level()) + + "_" + QString::number(fullPixmap.cacheKey()) + "_" + + QString::fromStdString(info->privlevel()).toLower() + "_" + + QString::fromStdString(info->pawn_colors().left_side()) + "_" + + QString::fromStdString(info->pawn_colors().right_side()); if (!QPixmapCache::find(cacheKey, &cachedPixmap)) { cachedPixmap = QPixmap(translatedSize.width(), translatedSize.height());