Cockatrice/libcockatrice_deck_list/libcockatrice/deck_list
Lukas Brübach 34e22df5ba [DeckSync] Match server rows by identity and hash the whole deck
Sync keyed local files to server rows by path, but the server names a row
after the deck, not after the file, so any deck whose file name and deck name
differ uploaded again on every run. A second pass then brought the server copy
back as an extra local file.

- Match by the sidecar's row id, then guid, then content, and only then by the
  server path, so renaming either side no longer duplicates a deck.
- Key the server tree by row id: the server allows several rows with the same
  name in one folder, and keying by path silently dropped all but one.
- Stop discarding rows whose name contains '/' ("U/W Control"). They stay
  matchable, and only the download file name is sanitised.
- Build the download path from the folder plus a sanitised row name, including
  every folder segment, so a hostile server name cannot escape the deck folder.
- Download a colliding server row under a unique name and count it, instead of
  skipping it without a trace.
- Hash the whole deck instead of the card hash: SHA-1 over the native deck
  string covers name, printings, banner, tokens and sideboard plans. The client
  and the server hash the exact bytes they exchange, so both agree.

Adds deck_content_hash_test for the client/server hashing invariant and for the
name-only change the card hash cannot see.
2026-11-05 12:51:01 +01:00
..
tree [Tooling] Apply include-what-you-use across the tree (#7396) 2026-10-08 11:13:50 +02:00
deck_diff.cpp [DeckDiff] Use namespace instead of static-only class per review 2026-11-05 12:50:48 +01:00
deck_diff.h [DeckDiff] Use namespace instead of static-only class per review 2026-11-05 12:50:48 +01:00
deck_file_format.cpp [Refactor] Move LoadedDeck and DeckFileFormat data types into libcockatrice_deck_list (#7424) 2026-10-31 18:44:11 +01:00
deck_file_format.h [Refactor] Move LoadedDeck and DeckFileFormat data types into libcockatrice_deck_list (#7424) 2026-10-31 18:44:11 +01:00
deck_list.cpp [DeckSync] Match server rows by identity and hash the whole deck 2026-11-05 12:51:01 +01:00
deck_list.h [DeckSync] Match server rows by identity and hash the whole deck 2026-11-05 12:51:01 +01:00
deck_list_history_manager.cpp [Tooling] Apply include-what-you-use across the tree (#7396) 2026-10-08 11:13:50 +02:00
deck_list_history_manager.h [Tooling] Apply include-what-you-use across the tree (#7396) 2026-10-08 11:13:50 +02:00
deck_list_memento.h [Fix-Warnings] Mark const getters as [[nodiscard]] (#6365) 2025-11-28 21:38:54 +01:00
deck_list_node_tree.cpp [Tooling] Apply include-what-you-use across the tree (#7396) 2026-10-08 11:13:50 +02:00
deck_list_node_tree.h [Tooling] Apply include-what-you-use across the tree (#7396) 2026-10-08 11:13:50 +02:00
deck_list_plain_text_parser.cpp Support tab-separated deck imports (#4222) (#7267) 2026-10-11 21:19:10 +02:00
deck_list_plain_text_parser.h [Tooling] Apply include-what-you-use across the tree (#7396) 2026-10-08 11:13:50 +02:00
loaded_deck.cpp [Refactor] Move LoadedDeck and DeckFileFormat data types into libcockatrice_deck_list (#7424) 2026-10-31 18:44:11 +01:00
loaded_deck.h [Refactor] Move LoadedDeck and DeckFileFormat data types into libcockatrice_deck_list (#7424) 2026-10-31 18:44:11 +01:00
playmat_resolver.cpp [Tooling] Apply include-what-you-use across the tree (#7396) 2026-10-08 11:13:50 +02:00
playmat_resolver.h [Tooling] Apply include-what-you-use across the tree (#7396) 2026-10-08 11:13:50 +02:00
sideboard_plan.cpp [Tooling] Apply include-what-you-use across the tree (#7396) 2026-10-08 11:13:50 +02:00
sideboard_plan.h [Tooling] Apply include-what-you-use across the tree (#7396) 2026-10-08 11:13:50 +02:00