diff --git a/forge-gui-desktop/src/main/java/forge/util/SwingImageFetcher.java b/forge-gui-desktop/src/main/java/forge/util/SwingImageFetcher.java index 3299f887b9c..c3526b5ea94 100644 --- a/forge-gui-desktop/src/main/java/forge/util/SwingImageFetcher.java +++ b/forge-gui-desktop/src/main/java/forge/util/SwingImageFetcher.java @@ -28,7 +28,12 @@ public class SwingImageFetcher extends ImageFetcher { this.notifyObservers = notifyObservers; } - private void doFetch(String urlToDownload) throws IOException { + private boolean doFetch(String urlToDownload) throws IOException { + if (disableHostedDownload && urlToDownload.startsWith(ForgeConstants.URL_CARDFORGE) && !urlToDownload.contains("tokens")) { + // Don't try to download card images from cardforge servers + return false; + } + String newdespath = urlToDownload.contains(".fullborder.jpg") || urlToDownload.startsWith(ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD) ? TextUtil.fastReplace(destPath, ".full.jpg", ".fullborder.jpg") : destPath; if (!newdespath.contains(".full") && urlToDownload.startsWith(ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD)) @@ -48,6 +53,7 @@ public class SwingImageFetcher extends ImageFetcher { SwingUtilities.invokeLater(notifyObservers); } else { System.err.println("Failed to rename image to " + newdespath); + return false; } } else { System.err.println("Failed to save image from " + url + " as jpeg"); @@ -63,7 +69,10 @@ public class SwingImageFetcher extends ImageFetcher { } else { System.err.println("Failed to save image from " + url + " as png"); } + return false; } + + return true; } private String tofullBorder(String imageurl) { @@ -85,10 +94,13 @@ public class SwingImageFetcher extends ImageFetcher { } public void run() { + boolean success = false; for (String urlToDownload : downloadUrls) { try { - doFetch(tofullBorder(urlToDownload)); - break; + if (doFetch(tofullBorder(urlToDownload))) { + success = true; + break; + } } catch (IOException e) { System.err.println("Failed to download card [" + destPath + "] image: " + e.getMessage()); if (urlToDownload.contains("tokens")) { @@ -98,14 +110,17 @@ public class SwingImageFetcher extends ImageFetcher { String extension = urlToDownload.substring(typeIndex); urlToDownload = setlessFilename+extension; try { - doFetch(tofullBorder(urlToDownload)); - break; + if (doFetch(tofullBorder(urlToDownload))) { + success = true; + break; + } } catch (IOException t) { System.err.println("Failed to download setless token [" + destPath + "]: " + e.getMessage()); } } } } + // If all downloads fail, mark this image as unfetchable so we don't try again. } } diff --git a/forge-gui-mobile/src/forge/util/LibGDXImageFetcher.java b/forge-gui-mobile/src/forge/util/LibGDXImageFetcher.java index b67cb1d1806..02d2efea754 100644 --- a/forge-gui-mobile/src/forge/util/LibGDXImageFetcher.java +++ b/forge-gui-mobile/src/forge/util/LibGDXImageFetcher.java @@ -29,7 +29,12 @@ public class LibGDXImageFetcher extends ImageFetcher { this.notifyObservers = notifyObservers; } - private void doFetch(String urlToDownload) throws IOException { + private boolean doFetch(String urlToDownload) throws IOException { + if (disableHostedDownload && urlToDownload.startsWith(ForgeConstants.URL_CARDFORGE) && !urlToDownload.contains("tokens")) { + // Don't try to download card images from cardforge servers + return false; + } + String newdespath = urlToDownload.contains(".fullborder.") || urlToDownload.startsWith(ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD) ? TextUtil.fastReplace(destPath, ".full.", ".fullborder.") : destPath; if (!newdespath.contains(".full") && urlToDownload.startsWith(ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD)) @@ -54,6 +59,7 @@ public class LibGDXImageFetcher extends ImageFetcher { System.out.println("Saved image to " + newdespath); GuiBase.getInterface().invokeInEdtLater(notifyObservers); + return true; } private String tofullBorder(String imageurl) { @@ -75,14 +81,16 @@ public class LibGDXImageFetcher extends ImageFetcher { } public void run() { + boolean success = false; for (String urlToDownload : downloadUrls) { boolean isPlanechaseBG = urlToDownload.startsWith("https://downloads.cardforge.org/images/planes/"); try { if (isPlanechaseBG) { - doFetch(urlToDownload); - break; + success = doFetch(urlToDownload); } else { - doFetch(tofullBorder(urlToDownload)); + success = doFetch(tofullBorder(urlToDownload)); + } + if (success) { break; } } catch (IOException e) { @@ -97,8 +105,10 @@ public class LibGDXImageFetcher extends ImageFetcher { String extension = urlToDownload.substring(typeIndex); urlToDownload = setlessFilename + extension; try { - doFetch(tofullBorder(urlToDownload)); - break; + success = doFetch(tofullBorder(urlToDownload)); + if (success) { + break; + } } catch (IOException t) { System.out.println("Failed to download setless token [" + destPath + "]: " + e.getMessage()); } diff --git a/forge-gui/src/main/java/forge/localinstance/properties/ForgeConstants.java b/forge-gui/src/main/java/forge/localinstance/properties/ForgeConstants.java index cf42809704a..fdc1026b5ff 100644 --- a/forge-gui/src/main/java/forge/localinstance/properties/ForgeConstants.java +++ b/forge-gui/src/main/java/forge/localinstance/properties/ForgeConstants.java @@ -328,7 +328,7 @@ public final class ForgeConstants { CACHE_PLANECHASE_PICS_DIR }; // URLs - private static final String URL_CARDFORGE = "https://downloads.cardforge.org"; + public static final String URL_CARDFORGE = "https://downloads.cardforge.org"; private static final String GITHUB_ASSETS_BASE = "https://raw.githubusercontent.com/Card-Forge/forge-extras/refs/heads/main/"; public static final String URL_PIC_DOWNLOAD = URL_CARDFORGE + "/images/cards/"; diff --git a/forge-gui/src/main/java/forge/util/ImageFetcher.java b/forge-gui/src/main/java/forge/util/ImageFetcher.java index 45f87d9dfc8..63722f1df2a 100644 --- a/forge-gui/src/main/java/forge/util/ImageFetcher.java +++ b/forge-gui/src/main/java/forge/util/ImageFetcher.java @@ -22,6 +22,8 @@ public abstract class ImageFetcher { // see https://scryfall.com/docs/api/languages and // https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes private static final HashMap langCodeMap = new HashMap<>(); + protected static final boolean disableHostedDownload = true; + private static final HashSet fetching = new HashSet<>(); static { langCodeMap.put("en-US", "en"); @@ -92,9 +94,12 @@ public abstract class ImageFetcher { if (imageKey.length() < 2) return; + if (imageKey.equalsIgnoreCase("t:null")) + return; + //planechaseBG file... + final ArrayList downloadUrls = new ArrayList<>(); if (imageKey.startsWith("PLANECHASEBG:")) { - final ArrayList downloadUrls = new ArrayList<>(); final String filename = imageKey.substring("PLANECHASEBG:".length()); downloadUrls.add("https://downloads.cardforge.org/images/planes/" + filename); FileUtil.ensureDirectoryExists(ForgeConstants.CACHE_PLANECHASE_PICS_DIR); @@ -105,12 +110,9 @@ public abstract class ImageFetcher { setupObserver(destFile.getAbsolutePath(), callback, downloadUrls); return; } - if (imageKey.equalsIgnoreCase("t:null")) - return; boolean useArtCrop = "Crop".equals(FModel.getPreferences().getPref(ForgePreferences.FPref.UI_CARD_ART_FORMAT)); final String prefix = imageKey.substring(0, 2); - final ArrayList downloadUrls = new ArrayList<>(); File destFile = null; if (prefix.equals(ImageKeys.CARD_PREFIX)) { PaperCard paperCard = ImageUtil.getPaperCardFromImageKey(imageKey); @@ -266,10 +268,14 @@ public abstract class ImageFetcher { // Already in the queue, simply add the new observer. observers.add(callback); return; + } else if (fetching.contains(destPath)) { + // Already fetching, but somehow no observers? + return; } observers = new HashSet<>(); observers.add(callback); + fetching.add(destPath); currentFetches.put(destPath, observers); final Runnable notifyObservers = () -> {