mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-21 00:55:09 -07:00
[Doxygen] More picture docs (#7220)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [Doxygen] More picture docs Took 12 minutes Took 8 minutes * [Doxygen] Move custom card pictures page into card_pictures subfolder The actual cyclic dependency fix is converting the mutual @subpage reference from custom_card_pictures to fixing_card_pictures into a plain @ref, so the page hierarchy no longer loops back on itself. * [Doxygen] Correct card-picture docs per review * fix table layout * [Doxygen] Deduplicate placeholder table and document image overrides - Make custom_card_pictures.md the canonical home of the URL reference-point table; loading_card_pictures.md cross-references it through @ref instead of maintaining a second copy (unaddressed review comment). - Switch the remaining @subpage custom_card_pictures to @ref in fixing_card_pictures.md so the page keeps its single parent under user_reference. - Document the Image Overrides feature added in #7311/#7312 on the user page, loading_card_pictures.md and fixing_card_pictures.md: local override storage, the downloadedPics root lookup, exact file-name matching, and the set-folder vs flat export naming schemes. * Update doc/doxygen/extra-pages/user_documentation/card_pictures/custom_card_pictures.md Co-authored-by: tooomm <tooomm@users.noreply.github.com> --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de> Co-authored-by: tooomm <tooomm@users.noreply.github.com>
This commit is contained in:
parent
6823d54c1e
commit
12299abcc8
4 changed files with 313 additions and 7 deletions
|
|
@ -33,20 +33,178 @@ issue a load request, which will first look for local images on-disk and then co
|
||||||
found, use the stored binary data from the network cache to populate the in-memory pixmap cache under the card's cache
|
found, use the stored binary data from the network cache to populate the in-memory pixmap cache under the card's cache
|
||||||
key. If it is not found, it will then proceed with issuing a network request.
|
key. If it is not found, it will then proceed with issuing a network request.
|
||||||
|
|
||||||
The size of both of these caches can be configured by the user in the "Card Sources" settings page.
|
The size of both of these caches can be configured by the user on the "Storage" settings page.
|
||||||
|
|
||||||
# PixmapCacheKeys and ProviderIDs
|
# PixmapCacheKeys and ProviderIDs
|
||||||
|
|
||||||
TODO
|
Every card picture that is loaded ends up in the QPixmapCache under a key that identifies the exact printing it belongs
|
||||||
|
to. The key is produced by ExactCard::getPixmapCacheKey() and has the following shape:
|
||||||
|
|
||||||
|
```text
|
||||||
|
card_<card name>_<provider ID>
|
||||||
|
```
|
||||||
|
|
||||||
|
For example, the _Example Card_ printing with provider ID `0b23cdc8-d413-4fb1-8470-474221b10fe2` is stored
|
||||||
|
under `card_Example Card_0b23cdc8-d413-4fb1-8470-474221b10fe2`. If the printing has no provider ID, the key
|
||||||
|
drops the suffix and falls back to `card_<card name>`.
|
||||||
|
|
||||||
|
The **provider ID** is the Scryfall UUID of the printing. Oracle maps the `scryfallId` of every printing to the `uuid`
|
||||||
|
property when building the card database, and deck files persist it as the `uuid` attribute of each card entry. Because
|
||||||
|
the provider ID is part of the pixmap cache key, two different printings of the same card never share a cache entry.
|
||||||
|
This is exactly what allows the printing selector and exact-card lookups to display the picture of the precise printing
|
||||||
|
a card was added as.
|
||||||
|
|
||||||
|
The base key holds the full-size image. When a widget asks for a scaled version, the scaled pixmap is stored under an
|
||||||
|
additional key of the form `<key>_<width>x<height>`, with the size adjusted for the device pixel ratio of the screen,
|
||||||
|
so each widget size is only ever scaled once.
|
||||||
|
|
||||||
|
The cache key is also used for bookkeeping outside of the pixmap cache itself:
|
||||||
|
|
||||||
|
- CardPictureLoaderWorker keeps a set of keys that are currently being loaded so the same card is never queued twice.
|
||||||
|
- CardPictureLoader tracks, per key, the last time loading failed. A failed load stores a NULL pixmap under the key; as
|
||||||
|
long as that marker is present, subsequent requests for the card show the "failed" card back and are only re-queued
|
||||||
|
after the retry interval of 300 seconds has passed.
|
||||||
|
- When the CardInfo of a loaded card is destroyed, its cache entries and failure markers are removed.
|
||||||
|
|
||||||
# The Redirect Cache
|
# The Redirect Cache
|
||||||
|
|
||||||
TODO
|
Many picture URLs - in particular the Gatherer and Scryfall URLs from the default set of templates - redirect to a CDN
|
||||||
|
or to a different host. To avoid following the same redirect for every single card, CardPictureLoaderWorker remembers
|
||||||
|
redirects and applies them without an extra network round trip.
|
||||||
|
|
||||||
|
The redirect cache is a hash map from original URL to redirect URL plus timestamp. It is persisted to a `cache.ini`
|
||||||
|
file (Qt's INI format, under the `redirects` array) inside the redirect cache directory
|
||||||
|
(`SettingsCache::instance().paths().getRedirectCachePath()`, i.e. `<cache directory>/redirects/`). The cache is loaded when the worker
|
||||||
|
starts, pruned of entries older than the configured TTL, and written back to disk when the application quits.
|
||||||
|
|
||||||
|
Entries are added whenever a network reply reports a redirection (see below) and are consulted before any request is
|
||||||
|
made: both CardPictureLoaderWorker::queueRequest() and CardPictureLoaderWorker::makeRequest() check for a cached
|
||||||
|
redirect first and jump straight to the final URL.
|
||||||
|
|
||||||
|
The TTL is the "Redirect Cache TTL" setting on the "Storage" settings page and defaults to 30 days. Lowering it makes
|
||||||
|
Cockatrice re-resolve redirects sooner, which can help when a download URL changed its redirect target.
|
||||||
|
|
||||||
|
Because Cockatrice tracks redirects itself, the QNetworkAccessManager is configured with Qt's `ManualRedirectPolicy`.
|
||||||
|
Redirects found in a reply are handled manually:
|
||||||
|
|
||||||
|
- A recursive redirect (a URL redirecting to itself) is treated as a failed load.
|
||||||
|
- Otherwise the redirect is recorded in the redirect cache and the request is re-issued against the target URL.
|
||||||
|
- A successful reply with one of the redirect status codes 301, 302, 303, 305, 307 or 308 is handled the same way.
|
||||||
|
|
||||||
|
Clearing the network cache (CardPictureLoader::clearNetworkCache()) also clears the redirect cache.
|
||||||
|
|
||||||
# Local Image Loading
|
# Local Image Loading
|
||||||
|
|
||||||
TODO
|
Before any network request is issued, CardPictureLoaderWorker hands the ExactCard to CardPictureLoaderLocal, which
|
||||||
|
tries to find a matching picture on disk. If a local picture is found, it is used and no network request is made.
|
||||||
|
|
||||||
|
CardPictureLoaderLocal searches three locations:
|
||||||
|
|
||||||
|
- The **CUSTOM folder** (`<pictures directory>/CUSTOM/`). Every file in it is indexed recursively by its base name
|
||||||
|
(both `baseName` and `completeBaseName`, so a file named `ExampleCard.jpg` is indexed as `ExampleCard`). The index is rebuilt
|
||||||
|
every 10 seconds, so new files are picked up without restarting the
|
||||||
|
client (changing the configured pictures directory only reassigns the search paths; the next timer tick rebuilds the index).
|
||||||
|
- The **set-named subfolders** of the pictures directory: `<pictures directory>/<set code>/` and
|
||||||
|
`<pictures directory>/downloadedPics/<set code>/`.
|
||||||
|
- The **root of the `downloadedPics` folder** (`<pictures directory>/downloadedPics/`). The export naming schemes without a
|
||||||
|
set-folder part write their files straight into `downloadedPics/`, so this is where flat-scheme downloads and the
|
||||||
|
local overrides described below are matched.
|
||||||
|
|
||||||
|
For each candidate folder, the loader generates file-name variants from the card's corrected name, set code, collector
|
||||||
|
number and provider ID using the import naming schemes (Card Name + Provider ID, Card Name + Set + Collector,
|
||||||
|
Set + Collector + Card Name, Card Name + Set, Card Name), each tried with both `_` and `-` as separator. A file is
|
||||||
|
accepted when its name without the extension *equals* the variant exactly - the extension itself is free - and the
|
||||||
|
first variant that yields a readable image wins. For example, the file `Example Card_EXM_43.png` in the `EXM` set
|
||||||
|
folder matches the card with corrected name `Example Card`, set code `EXM` and collector number `43`.
|
||||||
|
|
||||||
|
\attention The file-name variants use the *corrected* card name, so split cards are stored under their joined name: the
|
||||||
|
"Example // Card" card is matched by a file named `ExampleCard.*`.
|
||||||
|
|
||||||
|
The naming schemes are also documented in the user-facing page @ref custom_card_pictures, which additionally covers
|
||||||
|
the CUSTOM folder workflow, `picurl` and download URL templates.
|
||||||
|
|
||||||
|
When the filesystem cache method is selected on the "Storage" settings page, downloaded images are additionally written
|
||||||
|
into `<pictures directory>/downloadedPics/` using the configured export naming scheme (as `.png` files). The two export
|
||||||
|
schemes with a set-folder part (`Set Folder / Name + Provider ID` and `Set Folder / Name + Set Name + Collector`) write
|
||||||
|
into `downloadedPics/<set code>/`; the three flat schemes write directly into `downloadedPics/`. Automatic cache writes
|
||||||
|
never overwrite an existing file, so a provider outage can permanently leave an outdated image in that folder until it
|
||||||
|
is deleted manually - the user-facing troubleshooting guide @ref fixing_card_pictures covers how to do this. Explicit
|
||||||
|
image overrides (see below) are the exception and always overwrite.
|
||||||
|
|
||||||
|
# Local Image Overrides
|
||||||
|
|
||||||
|
Beyond the generic on-disk lookup above, individual printings can be given explicit artwork that wins over every other
|
||||||
|
source without touching the CUSTOM folder or any download URL. This is the "Image Overrides" submenu of the context menu
|
||||||
|
that opens when you right-click a card in the deck editor's printing selector.
|
||||||
|
|
||||||
|
- **Load Custom Image...** asks for a picture file and installs it for the card through
|
||||||
|
CardPictureLoader::saveCardImageToLocalStorage() with `allowOverwrite == true`.
|
||||||
|
- **One entry per alternate printing** (labeled `<set> <collector number>`): selecting one hands the card to
|
||||||
|
CardPictureLoader::installPrintingOverride(), which resolves that printing's artwork - enqueueing a load and waiting
|
||||||
|
for the `CardInfo::pixmapUpdated` signal if it is not cached yet - and persists it for the card.
|
||||||
|
- **Clear Custom Image** calls CardPictureLoader::deleteAllLocalOverrides() to remove every stored override image of the
|
||||||
|
card, after which normal resolution resumes. The entry is only enabled while CardPictureLoader::hasLocalOverrides()
|
||||||
|
reports at least one stored file.
|
||||||
|
|
||||||
|
Overrides are stored as `.png` files in `downloadedPics/` under the export naming scheme configured on the "Storage"
|
||||||
|
settings page - which is exactly why the local matcher also looks into the `downloadedPics/` root (see above). They are
|
||||||
|
written with `allowOverwrite == true`, so an override always replaces whatever the filesystem cache previously saved for
|
||||||
|
that spelling; only *automatic* cache writes are prevented from clobbering it. Overriding a card with its own current
|
||||||
|
printing is a no-op (the UI omits it from the menu), and an override whose artwork fails to resolve surfaces the
|
||||||
|
"failed" card back instead of a silent no-op while any override already on disk is left in place and re-displayed.
|
||||||
|
|
||||||
# URL Generation and Resolution
|
# URL Generation and Resolution
|
||||||
|
|
||||||
TODO
|
When no local image is available and downloading is enabled, the network loader starts working through a list of
|
||||||
|
candidate URLs. This list is managed by CardPictureToLoad and is built in two steps.
|
||||||
|
|
||||||
|
First, CardPictureToLoad::extractSetsSorted() collects all sets the card has printings in and sorts them by set
|
||||||
|
priority. Unless the user disabled per-printing art ("Override all card art with personal set preference (Pre-ProviderID
|
||||||
|
change behavior)"), the set that
|
||||||
|
matches the requested printing's provider ID is moved to the front, so the exact printing is always attempted first.
|
||||||
|
|
||||||
|
For each set, CardPictureToLoad::populateSetUrls() builds an ordered URL list:
|
||||||
|
|
||||||
|
1. A custom URL defined for that printing via the `picurl` property in the card database, if present.
|
||||||
|
2. The configured download URL templates, in priority order (Deck Editor → "URL Download Priority").
|
||||||
|
|
||||||
|
URL templates are transformed into concrete URLs by CardPictureToLoad::transformUrl(), which substitutes reference
|
||||||
|
points. `!name!`, `!setcode!` and friends substitute card and printing data, while the `!set:<property>!` and
|
||||||
|
`!prop:<property>!` reference points resolve a property of the printing or of the card respectively. The canonical list
|
||||||
|
of all reference points with examples, including the `_fill_with_` and `_substr_` modifiers, lives in
|
||||||
|
@ref custom_card_pictures.
|
||||||
|
|
||||||
|
The `!set:...!` and `!prop:...!` reference points also support two modifiers:
|
||||||
|
|
||||||
|
- `_fill_with_<text>` pads the value with the given text, right-aligned, e.g. `!set:num_fill_with_000!` turns collector
|
||||||
|
number `1` into `001`. If the value is longer than the fill text, the template is invalidated.
|
||||||
|
- `_substr_<start>_<length>` extracts a substring, e.g. `!set:num_substr_2_2!` takes two characters starting at the
|
||||||
|
third. If the substring would extend past the end of the value, the template is invalidated.
|
||||||
|
|
||||||
|
Substituted values are percent-encoded. If a template asks for a property the card or printing does not have (or one of
|
||||||
|
the modifiers invalidates it), the template yields no URL and is skipped; the next template is tried instead.
|
||||||
|
|
||||||
|
\attention Custom URLs should start with `http://` or `https://`. The scheme is not validated before the URL is handed
|
||||||
|
to QNetworkAccessManager, so a template without an absolute scheme may silently fail to download; prefer HTTPS where the
|
||||||
|
provider allows it.
|
||||||
|
|
||||||
|
The resolution order is: for the current set, try each URL in the list; when all URLs for a set are exhausted, move to
|
||||||
|
the next set; when every set is exhausted, the load fails. A failed load is reported through the NULL-pixmap mechanism
|
||||||
|
described in the PixmapCacheKeys and ProviderIDs section above.
|
||||||
|
|
||||||
|
Several mechanisms influence the resolution process:
|
||||||
|
|
||||||
|
- **Rate limiting.** The worker allows roughly 10 requests per second globally. A server that answers with HTTP 429
|
||||||
|
gets its per-host allowance halved; the first 429 for a host is waited out (honoring the `Retry-After` header if
|
||||||
|
present) and the same URL retried, while a second 429 makes the loader fall through to the other configured sources.
|
||||||
|
When all sources are exhausted the request is deferred with some random jitter and retried once the back-off expires.
|
||||||
|
- **Redirects.** Replies with a redirect status (301, 302, 303, 305, 307, 308) are followed and recorded in the
|
||||||
|
redirect cache as described in the Redirect Cache section above.
|
||||||
|
- **Blacklisted images.** Gatherer returns the card back image for cards it does not know. A few known MD5 hashes of
|
||||||
|
that image are blacklisted, so such a "successful" download is treated as not found instead of being shown.
|
||||||
|
- **WebP.** Images detected as WebP (RIFF/WEBP header) are decoded through QMovie instead of QImageReader.
|
||||||
|
- **Downloads disabled.** When "Download card pictures on the fly" is disabled and the network cache method is active,
|
||||||
|
requests use Qt's `AlwaysCache` policy so that only previously cached images are served.
|
||||||
|
|
||||||
|
A user-facing reference for writing download URL templates, including more worked examples, is available at
|
||||||
|
@ref custom_card_pictures.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,135 @@
|
||||||
|
@page custom_card_pictures Custom Card Pictures
|
||||||
|
|
||||||
|
There are four ways to make Cockatrice use custom artwork for your cards:
|
||||||
|
|
||||||
|
- Placing image files in the **CUSTOM pictures folder**.
|
||||||
|
- Providing a **custom card database** that points each printing at a picture URL via the `picurl` property.
|
||||||
|
- Writing your **own download URL templates**.
|
||||||
|
- Setting an **image override** for a single card from inside the deck editor.
|
||||||
|
|
||||||
|
Each of these is described below. If pictures are missing or wrong, see @ref fixing_card_pictures instead.
|
||||||
|
|
||||||
|
# Custom Pictures Folder (CUSTOM)
|
||||||
|
|
||||||
|
Any image file placed in the CUSTOM folder is used as the card picture, and no download is attempted for cards that
|
||||||
|
match a file there.
|
||||||
|
|
||||||
|
- The folder is `<pictures directory>/CUSTOM/`. The pictures directory is configured on the 'General' settings tab,
|
||||||
|
under 'Directories' → 'Pictures directory'.
|
||||||
|
- Any image format Qt can decode is accepted (PNG, JPG/JPEG, WebP, GIF, BMP, ...); the file extension is not filtered,
|
||||||
|
so even an extension-less file is picked up if the decoder recognizes its content.
|
||||||
|
- Files are indexed by their name, so you can organize them into subfolders freely.
|
||||||
|
- New or changed files are picked up automatically within a few seconds — no client restart is required.
|
||||||
|
|
||||||
|
The file name must match the card using one of the naming schemes below. Both `_` and `-` are accepted as separators,
|
||||||
|
and the file extension is ignored when matching:
|
||||||
|
|
||||||
|
| Scheme | Example file name |
|
||||||
|
| --------------------------- | ------------------------------------------------------- |
|
||||||
|
| Card Name | `Example Card.png` |
|
||||||
|
| Card Name + Set | `Example Card_DDL.png` |
|
||||||
|
| Card Name + Set + Collector | `Example Card_DDL_43.png` |
|
||||||
|
| Set + Collector + Card Name | `DDL_43_Example Card.png` |
|
||||||
|
| Card Name + Provider ID | `Example Card_0b23cdc8-d413-4fb1-8470-474221b10fe2.png` |
|
||||||
|
|
||||||
|
The name used for matching is the *corrected* card name. Correction removes the split-card separator ` // ` and the
|
||||||
|
characters reserved in Windows file names (`* < > : " \ ?` and control characters), and turns `/` into a space, so the
|
||||||
|
"Example // Card" card is matched by a file named `ExampleCard.png`, not `Example // Card.png`. Most other punctuation
|
||||||
|
(commas, apostrophes, `!`, ...) is left untouched.
|
||||||
|
|
||||||
|
\attention A file in the CUSTOM folder always wins over downloaded pictures, even if it is the wrong image. Delete the
|
||||||
|
file if you want to see the downloaded artwork again.
|
||||||
|
|
||||||
|
The naming conventions are the same as those recognized in the set-named subfolders and in `downloadedPics`, and are
|
||||||
|
documented for developers in @ref loading_card_pictures.
|
||||||
|
|
||||||
|
# Custom Card Database (picurl)
|
||||||
|
|
||||||
|
If you maintain your own card database (see the
|
||||||
|
[Custom Cards & Sets](https://github.com/Cockatrice/Cockatrice/wiki/Custom-Cards-&-Sets) wiki), each printing's `<set>`
|
||||||
|
tag can carry a `picurl` attribute containing a full URL for that printing's picture:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<set picurl="https://example.com/cards/example-card.jpg" ...>
|
||||||
|
```
|
||||||
|
|
||||||
|
Cockatrice tries this URL **before** the configured download URL templates, so it is the most direct way to provide
|
||||||
|
custom artwork for a specific printing.
|
||||||
|
|
||||||
|
- The URL should start with `http://` or `https://`; the scheme is not validated, so make sure it is absolute or the
|
||||||
|
download may silently fail.
|
||||||
|
- When you change a `picurl` for a card whose picture was already downloaded and cached, delete the stored images
|
||||||
|
(Storage tab → 'Delete Saved Images' / 'Delete Cached Images') so Cockatrice fetches the new URL.
|
||||||
|
|
||||||
|
# Custom Download URL Templates
|
||||||
|
|
||||||
|
The built-in download URLs are templates: Cockatrice replaces reference points in the URL with information about the
|
||||||
|
card and its printing. You can write your own templates in 'Cockatrice → Settings' (Ctrl + Shift + P by default), on
|
||||||
|
the 'Deck Editor' tab, in the 'URL Download Priority' section.
|
||||||
|
|
||||||
|
The following reference points are available:
|
||||||
|
|
||||||
|
| Reference point | Description | Example |
|
||||||
|
| ------------------------------- | ------------------------------- | -------------- |
|
||||||
|
| `!name!` | Card name | `Example Card` |
|
||||||
|
| `!name_lower!` | Card name, lower case | `example card` |
|
||||||
|
| `!corrected_name!` | Corrected card name | `ExampleCard` (instead of "Example // Card") |
|
||||||
|
| `!corrected_name_lower!` | Corrected card name, lower case | `examplecard` |
|
||||||
|
| `!sflang!` | Scryfall language code for the current client language; defaults to English when the language has no localized images | `en`, `zhs` |
|
||||||
|
| `!setcode!` / `!setcode_lower!` | Set code | `EXM` / `exm` |
|
||||||
|
| `!setname!` / `!setname_lower!` | Full set name | `Exemplary Set` / `exemplary set` |
|
||||||
|
| `!set:<property>!` | A property of this printing, e.g. `muid` (Gatherer multiverse ID), `uuid` (Scryfall UUID), `num` (collector number), `rarity` | `373549` |
|
||||||
|
| `!prop:<property>!` | A property of the card, e.g. `side` (front/back), `colors`, `cmc`, `coloridentity`, `type`, `pt`, and the format legality statuses | `front` |
|
||||||
|
|
||||||
|
The `!set:...!` and `!prop:...!` reference points support two modifiers:
|
||||||
|
|
||||||
|
- `_fill_with_<text>` pads the value with the given text, right-aligned, e.g. `!set:num_fill_with_000!` turns collector
|
||||||
|
number `1` into `001`. If the value is longer than the fill text, the template is skipped.
|
||||||
|
- `_substr_<start>_<length>` extracts a substring, e.g. `!set:num_substr_2_2!` takes two characters starting at the
|
||||||
|
third. If the substring would extend past the end of the value, the template is skipped.
|
||||||
|
|
||||||
|
Substituted values are URL-encoded. A template that asks for a property the card or printing does not have is skipped,
|
||||||
|
and the next template in the list is tried instead.
|
||||||
|
|
||||||
|
\attention Custom URLs should start with `http://` or `https://`. As with `picurl`, the scheme is not validated before
|
||||||
|
the URL is handed to QNetworkAccessManager, so use an absolute URL or the download may silently fail.
|
||||||
|
|
||||||
|
Some working examples:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://cards.scryfall.io/large/!prop:side!/!set:uuid_substr_0_1!/!set:uuid_substr_1_1!/!set:uuid!.jpg
|
||||||
|
https://api.scryfall.com/cards/!set:uuid!?format=image&face=!prop:side!
|
||||||
|
https://api.scryfall.com/cards/multiverse/!set:muid!?format=image
|
||||||
|
https://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=!set:muid!&type=card
|
||||||
|
https://gatherer.wizards.com/Handlers/Image.ashx?name=!name!&type=card
|
||||||
|
```
|
||||||
|
|
||||||
|
See the [Custom Picture Download URLs](https://github.com/Cockatrice/Cockatrice/wiki/Custom-Picture-Download-URLs)
|
||||||
|
wiki for more examples and ideas.
|
||||||
|
|
||||||
|
\attention Keep in mind that templates using `!name!` or `!set:muid!` resolve by name or multiverse ID, not by the
|
||||||
|
exact printing. Only the Scryfall `!set:uuid!` templates always return the exact printing requested. See
|
||||||
|
@ref fixing_card_pictures for more on this.
|
||||||
|
|
||||||
|
# Image Overrides
|
||||||
|
|
||||||
|
The quickest way to give one card custom art is an image override: right-click the card in the deck editor's printing
|
||||||
|
selector and open the **Image Overrides** submenu of the context menu.
|
||||||
|
|
||||||
|
- **Load Custom Image...** — choose a picture file (the dialog suggests PNG, JPG/JPEG and WebP); it becomes that card's
|
||||||
|
artwork immediately.
|
||||||
|
- **One entry per alternate printing** of the card, labeled `<set> <collector number>` (hovering an entry previews that
|
||||||
|
printing's artwork). Selecting one makes the card use that exact printing's picture, so e.g. a basic land can be shown
|
||||||
|
with any of its artworks.
|
||||||
|
- **Clear Custom Image** — removes the stored override and returns the card to normal resolution. It is only available
|
||||||
|
while the card has a stored override.
|
||||||
|
|
||||||
|
Overrides are stored as `.png` files in `<pictures directory>/downloadedPics/`, under the "Naming scheme" configured on
|
||||||
|
the Storage settings page, and are matched the same way as downloaded images. Because local files are checked before any
|
||||||
|
URL is requested, an override always wins over downloaded artwork and `picurl` for that card. The override exists only on
|
||||||
|
the machine it was created on - it is not part of the deck file - so a card with a stored override shows normally on
|
||||||
|
another computer.
|
||||||
|
|
||||||
|
\attention If you also keep a matching file in the CUSTOM folder, that file is matched before the override. When you
|
||||||
|
change an override, use **Clear Custom Image** so the stored `.png` is replaced; manually deleting the file in
|
||||||
|
`downloadedPics/` has the same effect.
|
||||||
|
|
@ -11,6 +11,10 @@
|
||||||
|
|
||||||
- @subpage beta_release
|
- @subpage beta_release
|
||||||
|
|
||||||
|
## Card Pictures
|
||||||
|
|
||||||
|
- @subpage custom_card_pictures
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
- @subpage fixing_card_pictures
|
- @subpage fixing_card_pictures
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,8 @@ valid URLs. If you suspect the list has been modified or corrupted, press 'Reset
|
||||||
defaults.
|
defaults.
|
||||||
|
|
||||||
For information on how to add your own custom URL templates, see the 'How to add a custom URL' link in the same
|
For information on how to add your own custom URL templates, see the 'How to add a custom URL' link in the same
|
||||||
settings section.
|
settings section, or @ref custom_card_pictures for a full reference of the URL reference points, the CUSTOM
|
||||||
|
pictures folder, and custom card databases.
|
||||||
|
|
||||||
# Check Your Local Picture Folder
|
# Check Your Local Picture Folder
|
||||||
|
|
||||||
|
|
@ -41,8 +42,12 @@ Cockatrice checks the following locations, in order:
|
||||||
- The custom pictures folder (recursively indexed by file name).
|
- The custom pictures folder (recursively indexed by file name).
|
||||||
- `<pictures directory>/<set code>/<card file name>`
|
- `<pictures directory>/<set code>/<card file name>`
|
||||||
- `<pictures directory>/downloadedPics/<set code>/<card file name>`
|
- `<pictures directory>/downloadedPics/<set code>/<card file name>`
|
||||||
|
- `<pictures directory>/downloadedPics/<card file name>` (for export naming schemes without a set folder)
|
||||||
|
|
||||||
The following import naming schemes are recognized (using both `_` and `-` as separators):
|
A file only matches when its name without the extension equals one of the recognized scheme patterns exactly.
|
||||||
|
|
||||||
|
The following import naming schemes are recognized (using both `_` and `-` as separators). The canonical table with
|
||||||
|
concrete example file names is on @ref custom_card_pictures:
|
||||||
|
|
||||||
| Scheme | Pattern |
|
| Scheme | Pattern |
|
||||||
| --------------------------- | -------------------------- |
|
| --------------------------- | -------------------------- |
|
||||||
|
|
@ -56,6 +61,10 @@ If a picture you downloaded or placed manually is wrong, stale, or corrupted, de
|
||||||
attention to the `downloadedPics` subfolder: this is where the filesystem caching method writes downloaded images, and
|
attention to the `downloadedPics` subfolder: this is where the filesystem caching method writes downloaded images, and
|
||||||
after a provider outage it can permanently contain the wrong printing until you delete it manually.
|
after a provider outage it can permanently contain the wrong printing until you delete it manually.
|
||||||
|
|
||||||
|
If a card persistently shows artwork you assigned yourself, you may have an **image override** set for it. Right-click
|
||||||
|
the card in the deck editor's printing selector and use 'Image Overrides' → 'Clear Custom Image' to remove it (or
|
||||||
|
delete the stored `.png` in `downloadedPics/`). See @ref custom_card_pictures for details.
|
||||||
|
|
||||||
See @ref loading_card_pictures for details on how local images are loaded.
|
See @ref loading_card_pictures for details on how local images are loaded.
|
||||||
|
|
||||||
# Clear Caches
|
# Clear Caches
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue