mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-25 02:43:02 -07:00
When a player left, GameScene::removePlayer iterated zoneViews while close() synchronously removed the current view from that list. A judge with several open views of the departing player (e.g. library and hand) only had the first one closed; the remaining views were skipped and left pointing at a player that was about to be deleted, crashing the client on the next access. - GameScene::removePlayer: iterate over a copy of zoneViews - GameScene::toggleZoneView: same fix for the identical iteration bug Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
6cdeb0c428
commit
9b0d62c152
1 changed files with 10 additions and 2 deletions
|
|
@ -221,7 +221,12 @@ void GameScene::removePlayer(PlayerLogic *player)
|
||||||
|
|
||||||
clearArrowsForPlayer(player->getPlayerInfo()->getId());
|
clearArrowsForPlayer(player->getPlayerInfo()->getId());
|
||||||
|
|
||||||
for (ZoneViewWidget *zone : zoneViews) {
|
// Closing a view removes it from zoneViews synchronously, so iterate over a
|
||||||
|
// copy: otherwise a player with several open views (e.g. library and hand)
|
||||||
|
// only has the first one closed here and the remaining views are left
|
||||||
|
// pointing at a player that is about to be deleted.
|
||||||
|
const QList<ZoneViewWidget *> zoneViewCopy = zoneViews;
|
||||||
|
for (ZoneViewWidget *zone : zoneViewCopy) {
|
||||||
if (zone->getPlayer() == player) {
|
if (zone->getPlayer() == player) {
|
||||||
zone->close();
|
zone->close();
|
||||||
}
|
}
|
||||||
|
|
@ -664,7 +669,10 @@ CardItem *GameScene::findTopmostCardInZone(const QList<QGraphicsItem *> &items,
|
||||||
*/
|
*/
|
||||||
void GameScene::toggleZoneView(PlayerLogic *player, const QString &zoneName, int numberCards, bool isReversed)
|
void GameScene::toggleZoneView(PlayerLogic *player, const QString &zoneName, int numberCards, bool isReversed)
|
||||||
{
|
{
|
||||||
for (auto &view : zoneViews) {
|
// Closing a view removes it from zoneViews synchronously, so iterate over a
|
||||||
|
// copy to make sure every already-open matching view is closed.
|
||||||
|
const QList<ZoneViewWidget *> zoneViewCopy = zoneViews;
|
||||||
|
for (auto *view : zoneViewCopy) {
|
||||||
ZoneViewZone *temp = view->getZone();
|
ZoneViewZone *temp = view->getZone();
|
||||||
if (temp->getLogic()->getName() == zoneName && temp->getLogic()->getPlayer() == player &&
|
if (temp->getLogic()->getName() == zoneName && temp->getLogic()->getPlayer() == player &&
|
||||||
qobject_cast<ZoneViewZoneLogic *>(temp->getLogic())->getNumberCards() == numberCards) {
|
qobject_cast<ZoneViewZoneLogic *>(temp->getLogic())->getNumberCards() == numberCards) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue