[Game] Preserve hand card order when restoring connection (#7266)

When a player restores connection to a game, the client rebuilds each
zone from the cards the server sends in the game state. Non-coordinate
zones (hand, piles, stack) report x == 0 on every card, so inserting
each rebuilt card at that coordinate reversed the received order one
card at a time.

Append rebuilt cards in the order they arrive for zones without
coordinates; coordinate-based zones (table) keep using x/y.

Fixes #2759

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
BruebachL
2026-09-07 08:21:44 +02:00
committed by GitHub
parent 36f998e466
commit ebeae48652
2 changed files with 38 additions and 1 deletions

View File

@@ -175,7 +175,15 @@ void PlayerLogic::processPlayerInfo(const ServerInfo_Player &info)
const ServerInfo_Card &cardInfo = zoneInfo.card_list(j);
auto *card = new CardItem(this);
card->processCardInfo(cardInfo);
zone->addCard(card, false, cardInfo.x(), cardInfo.y());
// Zones without coordinates (hand, piles, stack) preserve the order
// they arrive in on the server in the positions of their cards list.
// The x coordinate of such cards is always 0, so inserting at it
// would reverse the list on reconnect. Append instead.
if (zoneInfo.with_coords()) {
zone->addCard(card, false, cardInfo.x(), cardInfo.y());
} else {
zone->addCard(card, false, -1);
}
}
}
if (zoneInfo.has_always_reveal_top_card()) {

View File

@@ -134,6 +134,35 @@ TEST_F(AddCardAlgorithmTest, MidListInsertionPreservesOrder)
EXPECT_EQ(knownList.at(2), &b);
}
// Reconnecting to a game rebuilds zones from a ServerInfo_Zone. Non-coordinate zones
// (hand, piles, stack) report x == 0 on every card, so inserting each rebuilt card at
// that index would reverse the received server order. Appending (-1) keeps it.
TEST_F(AddCardAlgorithmTest, RebuildInsertAtZeroReversesServerOrder)
{
MockCard a, b, c;
CardZoneAlgorithms::addCardToList(knownList, &a, 0, false);
CardZoneAlgorithms::addCardToList(knownList, &b, 0, false);
CardZoneAlgorithms::addCardToList(knownList, &c, 0, false);
EXPECT_EQ(knownList.size(), 3);
EXPECT_EQ(knownList.at(0), &c);
EXPECT_EQ(knownList.at(1), &b);
EXPECT_EQ(knownList.at(2), &a);
}
TEST_F(AddCardAlgorithmTest, RebuildAppendPreservesServerOrder)
{
MockCard a, b, c;
CardZoneAlgorithms::addCardToList(knownList, &a, -1, false);
CardZoneAlgorithms::addCardToList(knownList, &b, -1, false);
CardZoneAlgorithms::addCardToList(knownList, &c, -1, false);
EXPECT_EQ(knownList.size(), 3);
EXPECT_EQ(knownList.at(0), &a);
EXPECT_EQ(knownList.at(1), &b);
EXPECT_EQ(knownList.at(2), &c);
}
TEST_F(AddCardAlgorithmTest, KeepAnnotationsFalsePassedThrough)
{
MockCard card;