From 66d0ef4b35013ac2460c582913f2e5ee8d30bc28 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Fri, 24 Mar 2023 06:44:11 +0400 Subject: [PATCH] Refactor cards and token images code (#10139): - removed outdated token store format (example: BIRD.W.BIRD.CREATURE.1.1.full.jpg) - removed duplicated cache images code; - removed duplicated set code fields; - removed outdated auto-generated thumb files (also all *.thumb.zip files will be deleted on startup); --- .../mage/client/cards/CardIconsPanel.java | 6 +- .../java/mage/client/constants/Constants.java | 1 - .../plugins/adapters/MageActionCallback.java | 6 +- .../card/arcane/CardPanelRenderModeImage.java | 28 +- .../card/arcane/CardPanelRenderModeMTGO.java | 15 +- .../org/mage/plugins/card/CardPluginImpl.java | 2 +- .../plugins/card/images/CardDownloadData.java | 71 +-- .../card/images/DownloadPicturesService.java | 28 +- .../mage/plugins/card/images/ImageCache.java | 482 ++++++------------ .../plugins/card/images/ImageCacheData.java | 28 + .../plugins/card/utils/CardImageUtils.java | 174 ++----- .../client/game/TokensMtgImageSourceTest.java | 8 +- .../src/main/java/mage/view/CardView.java | 14 +- .../src/main/java/mage/view/LookedAtView.java | 2 +- .../main/java/mage/view/PermanentView.java | 3 +- .../main/java/mage/view/SimpleCardView.java | 21 +- .../main/java/mage/view/SimpleCardsView.java | 3 +- .../mage/test/serverside/TokenImagesTest.java | 35 ++ .../base/impl/CardTestPlayerAPIImpl.java | 2 +- Mage/src/main/java/mage/cards/Card.java | 5 - Mage/src/main/java/mage/cards/CardImpl.java | 14 - .../mage/game/permanent/PermanentToken.java | 1 - .../java/mage/game/permanent/token/Token.java | 2 - .../mage/game/permanent/token/TokenImpl.java | 6 - Mage/src/main/java/mage/game/stack/Spell.java | 10 - 25 files changed, 333 insertions(+), 634 deletions(-) create mode 100644 Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCacheData.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/serverside/TokenImagesTest.java diff --git a/Mage.Client/src/main/java/mage/client/cards/CardIconsPanel.java b/Mage.Client/src/main/java/mage/client/cards/CardIconsPanel.java index edbf75fb9b..9e73f25b25 100644 --- a/Mage.Client/src/main/java/mage/client/cards/CardIconsPanel.java +++ b/Mage.Client/src/main/java/mage/client/cards/CardIconsPanel.java @@ -293,7 +293,11 @@ public class CardIconsPanel extends JPanel { //BufferedImage iconImage = ImageManagerImpl.instance.getCardIcon(icon.getIconType().getResourceName(), this.halfSize * 2); // cached call - BufferedImage iconImageCached = ImageCache.getCardIconImage(icon.getIconType().getResourceName(), this.halfSize * 2, color.toString()); + BufferedImage iconImageCached = ImageCache.getCardIconImage( + icon.getIconType().getResourceName(), + this.halfSize * 2, + color.toString() + ).getImage(); if (iconImageCached != null && this.font != null) { BufferedImage iconImageWithText = ImageManagerImpl.deepCopy(iconImageCached); // must copy cached value before modify diff --git a/Mage.Client/src/main/java/mage/client/constants/Constants.java b/Mage.Client/src/main/java/mage/client/constants/Constants.java index 66be09514f..9ca0b5597e 100644 --- a/Mage.Client/src/main/java/mage/client/constants/Constants.java +++ b/Mage.Client/src/main/java/mage/client/constants/Constants.java @@ -51,7 +51,6 @@ public final class Constants { // cards render public static final Rectangle CARD_SIZE_FULL = new Rectangle(101, 149); - public static final Rectangle THUMBNAIL_SIZE_FULL = new Rectangle(102, 146); // resources - default images public static final String RESOURCE_PATH_DEFAULT_IMAGES = File.separator + "default"; diff --git a/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java b/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java index a83ba5ebdb..7b87897257 100644 --- a/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java +++ b/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java @@ -677,7 +677,7 @@ public class MageActionCallback implements ActionCallback { switch (enlargeMode) { case COPY: if (cardView instanceof PermanentView) { - image = ImageCache.getImageOriginal(((PermanentView) cardView).getOriginal()); + image = ImageCache.getImageOriginal(((PermanentView) cardView).getOriginal()).getImage(); } break; case ALTERNATE: @@ -686,9 +686,9 @@ public class MageActionCallback implements ActionCallback { && !cardView.isFlipCard() && !cardView.canTransform() && ((PermanentView) cardView).isCopy()) { - image = ImageCache.getImageOriginal(((PermanentView) cardView).getOriginal()); + image = ImageCache.getImageOriginal(((PermanentView) cardView).getOriginal()).getImage(); } else { - image = ImageCache.getImageOriginalAlternateName(cardView); + image = ImageCache.getImageOriginalAlternateName(cardView).getImage(); displayCard = displayCard.getSecondCardFace(); } } diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderModeImage.java b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderModeImage.java index 8b281ccb26..a69be37a6f 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderModeImage.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderModeImage.java @@ -3,7 +3,6 @@ package org.mage.card.arcane; import mage.MageInt; import mage.cards.MageCardLocation; import mage.cards.action.ActionCallback; -import mage.client.constants.Constants; import mage.client.dialog.PreferencesDialog; import mage.client.util.ImageCaches; import mage.client.util.ImageHelper; @@ -19,6 +18,7 @@ import mage.view.PermanentView; import mage.view.StackAbilityView; import org.jdesktop.swingx.graphics.GraphicsUtilities; import org.mage.plugins.card.images.ImageCache; +import org.mage.plugins.card.images.ImageCacheData; import org.mage.plugins.card.utils.impl.ImageManagerImpl; import javax.swing.*; @@ -466,9 +466,9 @@ public class CardPanelRenderModeImage extends CardPanel { public Image getImage() { if (this.hasImage) { if (getGameCard().isFaceDown()) { - return getFaceDownImage(); + return getFaceDownImage().getImage(); } else { - return ImageCache.getImageOriginal(getGameCard()); + return ImageCache.getImageOriginal(getGameCard()).getImage(); } } return null; @@ -629,27 +629,27 @@ public class CardPanelRenderModeImage extends CardPanel { setTappedAngle(isTapped() ? CardPanel.TAPPED_ANGLE : 0); setFlippedAngle(isFlipped() ? CardPanel.FLIPPED_ANGLE : 0); - //final CardView gameCard = this.gameCard; final int stamp = ++updateArtImageStamp; Util.threadPool.submit(() -> { try { - final BufferedImage srcImage; + final ImageCacheData data; if (getGameCard().isFaceDown()) { - srcImage = getFaceDownImage(); - } else if (getCardWidth() > Constants.THUMBNAIL_SIZE_FULL.width) { - srcImage = ImageCache.getImage(getGameCard(), getCardWidth(), getCardHeight()); + data = getFaceDownImage(); } else { - srcImage = ImageCache.getThumbnail(getGameCard()); + data = ImageCache.getImage(getGameCard(), getCardWidth(), getCardHeight()); } - if (srcImage == null) { - setFullPath(ImageCache.getFilePath(getGameCard(), getCardWidth())); + + // show path on miss image + if (data.getImage() == null) { + setFullPath(data.getPath()); } + UI.invokeLater(() -> { if (stamp == updateArtImageStamp) { - hasImage = srcImage != null; + hasImage = data.getImage() != null; setTitle(getGameCard()); - setImage(srcImage); + setImage(data.getImage()); } }); } catch (Exception | Error e) { @@ -658,7 +658,7 @@ public class CardPanelRenderModeImage extends CardPanel { }); } - private BufferedImage getFaceDownImage() { + private ImageCacheData getFaceDownImage() { // TODO: add download default images if (isPermanent() && getGameCard() instanceof PermanentView) { if (((PermanentView) getGameCard()).isMorphed()) { diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderModeMTGO.java b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderModeMTGO.java index a5811a367a..2eadd185b5 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderModeMTGO.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderModeMTGO.java @@ -3,7 +3,6 @@ package org.mage.card.arcane; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import mage.cards.action.ActionCallback; -import mage.client.constants.Constants; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; @@ -13,6 +12,7 @@ import mage.view.PermanentView; import mage.view.StackAbilityView; import org.jdesktop.swingx.graphics.GraphicsUtilities; import org.mage.plugins.card.images.ImageCache; +import org.mage.plugins.card.images.ImageCacheData; import java.awt.*; import java.awt.image.BufferedImage; @@ -194,9 +194,9 @@ public class CardPanelRenderModeMTGO extends CardPanel { return null; } if (getGameCard().isFaceDown()) { - return getFaceDownImage(); + return getFaceDownImage().getImage(); } else { - return ImageCache.getImageOriginal(getGameCard()); + return ImageCache.getImageOriginal(getGameCard()).getImage(); } } @@ -319,12 +319,9 @@ public class CardPanelRenderModeMTGO extends CardPanel { // Nothing to do srcImage = null; faceArtSrcImage = null; - } else if (getCardWidth() > Constants.THUMBNAIL_SIZE_FULL.width) { - srcImage = ImageCache.getImage(getGameCard(), getCardWidth(), getCardHeight()); - faceArtSrcImage = ImageCache.getFaceImage(getGameCard(), getCardWidth(), getCardHeight()); } else { - srcImage = ImageCache.getThumbnail(getGameCard()); - faceArtSrcImage = ImageCache.getFaceImage(getGameCard(), getCardWidth(), getCardHeight()); + srcImage = ImageCache.getImage(getGameCard(), getCardWidth(), getCardHeight()).getImage(); + faceArtSrcImage = ImageCache.getFaceImage(getGameCard(), getCardWidth(), getCardHeight()).getImage(); } UI.invokeLater(() -> { @@ -352,7 +349,7 @@ public class CardPanelRenderModeMTGO extends CardPanel { return new CardPanelAttributes(getCardWidth(), getCardHeight(), isChoosable(), isSelected(), isTransformed()); } - private BufferedImage getFaceDownImage() { + private ImageCacheData getFaceDownImage() { // TODO: add download default images if (isPermanent() && getGameCard() instanceof PermanentView) { if (((PermanentView) getGameCard()).isMorphed()) { diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java b/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java index c5246b1bd0..fc5cd5f437 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java @@ -710,6 +710,6 @@ public class CardPluginImpl implements CardPlugin { @Override public BufferedImage getOriginalImage(CardView card) { - return ImageCache.getImageOriginal(card); + return ImageCache.getImageOriginal(card).getImage(); } } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/CardDownloadData.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/CardDownloadData.java index 6755f978ea..971618bbb9 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/CardDownloadData.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/CardDownloadData.java @@ -2,7 +2,6 @@ package org.mage.plugins.card.images; import mage.util.CardUtil; -import java.util.Locale; import java.util.Objects; /** @@ -14,8 +13,6 @@ public class CardDownloadData { private String downloadName; private String fileName = ""; private String set; - private String tokenSetCode; - private String tokenDescriptor; private final String collectorId; private final Integer type; private boolean token; @@ -28,55 +25,51 @@ public class CardDownloadData { private String tokenClassName; private boolean isType2; - public CardDownloadData(String name, String set, String collectorId, boolean usesVariousArt, Integer type, String tokenSetCode, String tokenDescriptor) { - this(name, set, collectorId, usesVariousArt, type, tokenSetCode, tokenDescriptor, false, ""); + public CardDownloadData(String name, String setCode, String collectorId, boolean usesVariousArt, Integer type) { + this(name, setCode, collectorId, usesVariousArt, type, false, ""); } - public CardDownloadData(String name, String set, String collectorId, boolean usesVariousArt, Integer type, String tokenSetCode, String tokenDescriptor, boolean token) { - this(name, set, collectorId, usesVariousArt, type, tokenSetCode, tokenDescriptor, token, false, false, ""); + public CardDownloadData(String name, String setCode, String collectorId, boolean usesVariousArt, Integer type, boolean token) { + this(name, setCode, collectorId, usesVariousArt, type, token, false, false, ""); } - public CardDownloadData(String name, String set, String collectorId, boolean usesVariousArt, Integer type, String tokenSetCode, String tokenDescriptor, boolean token, String fileName) { - this(name, set, collectorId, usesVariousArt, type, tokenSetCode, tokenDescriptor, token, false, false, ""); + public CardDownloadData(String name, String setCode, String collectorId, boolean usesVariousArt, Integer type, boolean token, String fileName) { + this(name, setCode, collectorId, usesVariousArt, type, token, false, false, ""); this.fileName = fileName; } - public CardDownloadData(String name, String set, String collectorId, boolean usesVariousArt, Integer type, String tokenSetCode, String tokenDescriptor, boolean token, boolean twoFacedCard, boolean secondSide) { - this(name, set, collectorId, usesVariousArt, type, tokenSetCode, tokenDescriptor, token, twoFacedCard, secondSide, ""); + public CardDownloadData(String name, String setCode, String collectorId, boolean usesVariousArt, Integer type, boolean token, boolean twoFacedCard, boolean secondSide) { + this(name, setCode, collectorId, usesVariousArt, type, token, twoFacedCard, secondSide, ""); } - public CardDownloadData(String name, String set, String collectorId, boolean usesVariousArt, Integer type, String tokenSetCode, String tokenDescriptor, boolean token, boolean twoFacedCard, boolean secondSide, String tokenClassName) { + public CardDownloadData(String name, String setCode, String collectorId, boolean usesVariousArt, Integer type, boolean token, boolean twoFacedCard, boolean secondSide, String tokenClassName) { this.name = name; - this.set = set; + this.set = setCode; this.collectorId = collectorId; this.usesVariousArt = usesVariousArt; this.type = type; this.token = token; this.twoFacedCard = twoFacedCard; this.secondSide = secondSide; - this.tokenSetCode = tokenSetCode; - this.tokenDescriptor = tokenDescriptor; this.tokenClassName = tokenClassName; - - if (this.tokenDescriptor == null || this.tokenDescriptor.equalsIgnoreCase("")) { - this.tokenDescriptor = lastDitchTokenDescriptor(); - } } public CardDownloadData(final CardDownloadData card) { this.name = card.name; + this.downloadName = card.downloadName; + this.fileName = card.fileName; this.set = card.set; this.collectorId = card.collectorId; + this.type = card.type; this.token = card.token; this.twoFacedCard = card.twoFacedCard; this.secondSide = card.secondSide; - this.type = card.type; + this.flipCard = card.flipCard; + this.flippedSide = card.flippedSide; + this.splitCard = card.splitCard; this.usesVariousArt = card.usesVariousArt; - this.tokenSetCode = card.tokenSetCode; - this.tokenDescriptor = card.tokenDescriptor; this.tokenClassName = card.tokenClassName; - this.fileName = card.fileName; - + this.isType2 = card.isType2; } @Override @@ -94,7 +87,7 @@ public class CardDownloadData { if (!Objects.equals(this.set, other.set)) { return false; } - if (!Objects.equals(this.collectorId, other.collectorId) && (this.collectorId == null || !this.collectorId.equals(other.collectorId))) { + if (!Objects.equals(this.collectorId, other.collectorId)) { return false; } if (this.token != other.token) { @@ -123,6 +116,11 @@ public class CardDownloadData { return hash; } + @Override + public String toString() { + return String.format("%s - %s", this.getSet(), this.getName()); + } + public String getCollectorId() { return collectorId; } @@ -171,18 +169,6 @@ public class CardDownloadData { this.set = set; } - public String getTokenSetCode() { - return tokenSetCode; - } - - public void setTokenSetCode(String tokenSetCode) { - this.tokenSetCode = tokenSetCode; - } - - public String getTokenDescriptor() { - return tokenDescriptor; - } - public void setTokenClassName(String tokenClassName) { this.tokenClassName = tokenClassName; } @@ -191,17 +177,6 @@ public class CardDownloadData { return tokenClassName; } - public void setTokenDescriptor(String tokenDescriptor) { - this.tokenDescriptor = tokenDescriptor; - } - - private String lastDitchTokenDescriptor() { - String tmpName = this.name.replaceAll("[^a-zA-Z0-9]", ""); - String descriptor = tmpName + "...."; - descriptor = descriptor.toUpperCase(Locale.ENGLISH); - return descriptor; - } - public boolean isToken() { return token; } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java index 87f84cb141..d34a3a7b02 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java @@ -444,7 +444,7 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements if (!card.getCardNumber().isEmpty() && !"0".equals(card.getCardNumber()) && !card.getSetCode().isEmpty()) { String cardName = card.getName(); boolean isType2 = type2SetsFilter.contains(card.getSetCode()); - CardDownloadData url = new CardDownloadData(cardName, card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), 0, "", "", false, card.isDoubleFaced(), card.isNightCard()); + CardDownloadData url = new CardDownloadData(cardName, card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), 0, false, card.isDoubleFaced(), card.isNightCard()); // variations must have diff file names with additional postfix if (url.getUsesVariousArt()) { @@ -475,7 +475,7 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements card.getSetCode(), secondSideCard.getCardNumber(), card.usesVariousArt(), - 0, "", "", false, card.isDoubleFaced(), true); + 0, false, card.isDoubleFaced(), true); url.setType2(isType2); allCardsUrls.add(url); } @@ -488,7 +488,7 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), - 0, "", "", false, card.isDoubleFaced(), card.isNightCard()); + 0, false, card.isDoubleFaced(), card.isNightCard()); cardDownloadData.setFlipCard(true); cardDownloadData.setFlippedSide(true); cardDownloadData.setType2(isType2); @@ -510,7 +510,7 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements card.getSetCode(), meldsToCard.getCardNumber(), card.usesVariousArt(), - 0, "", "", false, false, false); + 0, false, false, false); url.setType2(isType2); allCardsUrls.add(url); } @@ -523,7 +523,7 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), - 0, "", "", false, true, true); + 0, false, true, true); cardDownloadData.setType2(isType2); allCardsUrls.add(cardDownloadData); } @@ -549,7 +549,7 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements cardsToDownload.add(card); } else { // need missing cards - File file = new TFile(CardImageUtils.buildImagePathToCard(card)); + File file = new TFile(CardImageUtils.buildImagePathToCardOrToken(card)); if (!file.exists()) { cardsToDownload.add(card); } @@ -592,32 +592,32 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements if (params[1].toLowerCase(Locale.ENGLISH).equals("generate") && params[2].startsWith("TOK:")) { String set = params[2].substring(4); - CardDownloadData card = new CardDownloadData(params[3], set, "0", false, type, "", "", true); + CardDownloadData card = new CardDownloadData(params[3], set, "0", false, type,true); card.setTokenClassName(tokenClassName); list.add(card); } else if (params[1].toLowerCase(Locale.ENGLISH).equals("generate") && params[2].startsWith("EMBLEM:")) { String set = params[2].substring(7); - CardDownloadData card = new CardDownloadData("Emblem " + params[3], set, "0", false, type, "", "", true, fileName); + CardDownloadData card = new CardDownloadData("Emblem " + params[3], set, "0", false, type, true, fileName); card.setTokenClassName(tokenClassName); list.add(card); } else if (params[1].toLowerCase(Locale.ENGLISH).equals("generate") && params[2].startsWith("EMBLEM-:")) { String set = params[2].substring(8); - CardDownloadData card = new CardDownloadData(params[3] + " Emblem", set, "0", false, type, "", "", true, fileName); + CardDownloadData card = new CardDownloadData(params[3] + " Emblem", set, "0", false, type,true, fileName); card.setTokenClassName(tokenClassName); list.add(card); } else if (params[1].toLowerCase(Locale.ENGLISH).equals("generate") && params[2].startsWith("EMBLEM!:")) { String set = params[2].substring(8); - CardDownloadData card = new CardDownloadData(params[3], set, "0", false, type, "", "", true, fileName); + CardDownloadData card = new CardDownloadData(params[3], set, "0", false, type, true, fileName); card.setTokenClassName(tokenClassName); list.add(card); } else if (params[1].toLowerCase(Locale.ENGLISH).equals("generate") && params[2].startsWith("PLANE:")) { String set = params[2].substring(6); - CardDownloadData card = new CardDownloadData(params[3], set, "0", false, type, "", "", true, fileName); + CardDownloadData card = new CardDownloadData(params[3], set, "0", false, type, true, fileName); card.setTokenClassName(tokenClassName); list.add(card); } else if (params[1].toLowerCase(Locale.ENGLISH).equals("generate") && params[2].startsWith("DUNGEON:")) { String set = params[2].substring(8); - CardDownloadData card = new CardDownloadData(params[3], set, "0", false, type, "", "", true, fileName); + CardDownloadData card = new CardDownloadData(params[3], set, "0", false, type, true, fileName); card.setTokenClassName(tokenClassName); list.add(card); } else { @@ -833,7 +833,7 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements destFile = new TFile(CardImageUtils.buildImagePathToTokens() + actualFilename + ".jpg"); } } else { - destFile = new TFile(CardImageUtils.buildImagePathToCard(card)); + destFile = new TFile(CardImageUtils.buildImagePathToCardOrToken(card)); } // FILE already exists (in zip or in dir) @@ -1008,7 +1008,7 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements // finished List downloadedCards = Collections.synchronizedList(new ArrayList<>()); DownloadPicturesService.this.cardsMissing.parallelStream().forEach(cardDownloadData -> { - TFile file = new TFile(CardImageUtils.buildImagePathToCard(cardDownloadData)); + TFile file = new TFile(CardImageUtils.buildImagePathToCardOrToken(cardDownloadData)); if (file.exists()) { downloadedCards.add(cardDownloadData); } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java index 2a3a16e688..55fc80ff2f 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java @@ -1,16 +1,13 @@ package org.mage.plugins.card.images; -import com.google.common.base.Function; import com.google.common.collect.ComputationException; import mage.abilities.icon.CardIconColor; import mage.client.constants.Constants; -import mage.client.dialog.PreferencesDialog; import mage.client.util.SoftValuesLoadingCache; import mage.client.util.TransformedImageCache; import mage.view.CardView; import net.java.truevfs.access.TFile; import net.java.truevfs.access.TFileInputStream; -import net.java.truevfs.access.TFileOutputStream; import org.apache.log4j.Logger; import org.mage.plugins.card.dl.sources.DirectLinksForDownload; import org.mage.plugins.card.utils.CardImageUtils; @@ -20,7 +17,6 @@ import javax.imageio.ImageIO; import java.awt.*; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; -import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -29,165 +25,113 @@ import java.util.regex.Pattern; * that the images may be garbage collected when they are not needed any more, * but will be kept as long as possible. *

- * Key format: "[cardname]#[setname]#[type]#[collectorID]#[param]" - *

- * where param is: - *

+ * + * @author JayDi85 */ public final class ImageCache { private static final Logger LOGGER = Logger.getLogger(ImageCache.class); - private static final SoftValuesLoadingCache IMAGE_CACHE; - private static final SoftValuesLoadingCache FACE_IMAGE_CACHE; - private static final SoftValuesLoadingCache CARD_ICONS_CACHE; + private static final SoftValuesLoadingCache IMAGE_CACHE; // cards and tokens + private static final SoftValuesLoadingCache FACE_IMAGE_CACHE; + private static final SoftValuesLoadingCache CARD_ICONS_CACHE; /** * Common pattern for keys. See ImageCache.getKey for structure info */ - private static final Pattern KEY_PATTERN = Pattern.compile("(.*)#(.*)#(.*)#(.*)#(.*)#(.*)"); + private static final Pattern KEY_PATTERN = Pattern.compile("(.*)#(.*)#(.*)#(.*)#(.*)"); private static final Pattern CARD_ICON_KEY_PATTERN = Pattern.compile("(.*)#(.*)#(.*)"); static { // softValues() = Specifies that each value (not key) stored in the map should be wrapped in a SoftReference // (by default, strong references are used). Softly-referenced objects will be garbage-collected in a // globally least-recently-used manner, in response to memory demand. - IMAGE_CACHE = SoftValuesLoadingCache.from(new Function() { - @Override - public BufferedImage apply(String key) { - try { - boolean usesVariousArt = false; - if (key.matches(".*#usesVariousArt.*")) { - usesVariousArt = true; - key = key.replace("#usesVariousArt", ""); + IMAGE_CACHE = SoftValuesLoadingCache.from(key -> { + try { + boolean usesVariousArt = false; + if (key.matches(".*#usesVariousArt.*")) { + usesVariousArt = true; + key = key.replace("#usesVariousArt", ""); + } + Matcher m = KEY_PATTERN.matcher(key); + + if (m.matches()) { + String name = m.group(1); + String setCode = m.group(2); + Integer type = Integer.parseInt(m.group(3)); + String collectorId = m.group(4); + if (collectorId.equals("null")) { + collectorId = "0"; } - boolean thumbnail = false; - if (key.matches(".*#thumb.*")) { - thumbnail = true; - key = key.replace("#thumb", ""); - } - Matcher m = KEY_PATTERN.matcher(key); - if (m.matches()) { - String name = m.group(1); - String set = m.group(2); - Integer type = Integer.parseInt(m.group(3)); - String collectorId = m.group(4); - if (collectorId.equals("null")) { - collectorId = "0"; - } - String tokenSetCode = m.group(5); - String tokenDescriptor = m.group(6); + CardDownloadData info = new CardDownloadData(name, setCode, collectorId, usesVariousArt, type); - CardDownloadData info = new CardDownloadData(name, set, collectorId, usesVariousArt, type, tokenSetCode, tokenDescriptor); + boolean cardback = false; + String path; + if (collectorId.isEmpty() || "0".equals(collectorId)) { + // TOKEN + // can be a normal token or a token from card (see embalm ability) + info.setToken(true); + TFile tokenFile; - boolean cardback = false; - String path; - if (collectorId.isEmpty() || "0".equals(collectorId) || !tokenDescriptor.isEmpty()) { // tokenDescriptor for embalm ability - info.setToken(true); - path = CardImageUtils.generateTokenImagePath(info); - if (path == null) { - cardback = true; - // try token image from card - CardDownloadData newInfo = new CardDownloadData(info); - newInfo.setToken(false); - path = CardImageUtils.buildImagePathToCard(newInfo); - TFile tokenFile = getTFile(path); - if (tokenFile == null || !tokenFile.exists()) { - // token empty token image - // TODO: replace empty token by other default card, not cardback - path = CardImageUtils.buildImagePathToDefault(DirectLinksForDownload.cardbackFilename); - } - } - } else { - path = CardImageUtils.buildImagePathToCard(info); + // try normal token + path = CardImageUtils.buildImagePathToCardOrToken(info); + tokenFile = getTFile(path); + + // try token from card + if (tokenFile == null || !tokenFile.exists()) { + CardDownloadData tempInfo = new CardDownloadData(info); + tempInfo.setToken(false); + path = CardImageUtils.buildImagePathToCardOrToken(info); + tokenFile = getTFile(path); } - if (path == null) { - return null; - } - TFile file = getTFile(path); - if (file == null) { - return null; - } - - if (thumbnail && path.endsWith(".jpg")) { - // need thumbnail image - String thumbnailPath = buildThumbnailPath(path); - TFile thumbnailFile = null; - try { - thumbnailFile = new TFile(thumbnailPath); - } catch (Exception ex) { - } - boolean exists = false; - if (thumbnailFile != null) { - try { - exists = thumbnailFile.exists(); - } catch (Exception ex) { - exists = false; - } - } - if (exists) { - LOGGER.debug("loading thumbnail for " + key + ", path=" + thumbnailPath); - BufferedImage thumbnailImage = loadImage(thumbnailFile); - if (thumbnailImage == null) { // thumbnail exists but broken for some reason - LOGGER.warn("failed loading thumbnail for " + key + ", path=" + thumbnailPath - + ", thumbnail file is probably broken, attempting to recreate it..."); - thumbnailImage = makeThumbnailByFile(key, file, thumbnailPath); - } - - if (cardback) { - // unknown tokens on opponent desk - thumbnailImage = getRoundCorner(thumbnailImage); - } - - return thumbnailImage; - } else { - return makeThumbnailByFile(key, file, thumbnailPath); - } - } else { - if (cardback) { - // need cardback image - BufferedImage image = loadImage(file); - image = getRoundCorner(image); - return image; - } else { - // need normal card image - BufferedImage image = loadImage(file); - image = getWizardsCard(image); - image = getRoundCorner(image); - return image; - } + // try unknown token image + if (tokenFile == null || !tokenFile.exists()) { + // TODO: replace empty token by other default card, not cardback + cardback = true; + path = CardImageUtils.buildImagePathToDefault(DirectLinksForDownload.cardbackFilename); } } else { - throw new RuntimeException( - "Requested image doesn't fit the requirement for key (##): " + key); + // CARD + path = CardImageUtils.buildImagePathToCardOrToken(info); } - } catch (Exception ex) { - if (ex instanceof ComputationException) { - throw (ComputationException) ex; - } else { - throw new ComputationException(ex); - } - } - } - public BufferedImage makeThumbnailByFile(String key, TFile file, String thumbnailPath) { - BufferedImage image = loadImage(file); - image = getWizardsCard(image); - image = getRoundCorner(image); - if (image == null) { - return null; + TFile file = getTFile(path); + if (file == null) { + return new ImageCacheData(path, null); + } + + if (cardback) { + // TODO: is there any different in images styles? Cardback must be from scryfall, not wizards + // need cardback image + BufferedImage image = loadImage(file); + image = getRoundCorner(image); + return new ImageCacheData(path, image); + } else { + // need normal card image + BufferedImage image = loadImage(file); + image = getWizardsCard(image); + image = getRoundCorner(image); + return new ImageCacheData(path, image); + } + } else { + throw new RuntimeException( + "Requested image doesn't fit the requirement for key (##): " + key); + } + } catch (Exception ex) { + if (ex instanceof ComputationException) { + throw (ComputationException) ex; + } else { + throw new ComputationException(ex); } - LOGGER.debug("creating thumbnail for " + key); - return makeThumbnail(image, thumbnailPath); } }); @@ -197,22 +141,18 @@ public final class ImageCache { if (m.matches()) { String name = m.group(1); - String set = m.group(2); - //Integer artid = Integer.parseInt(m.group(2)); + String setCode = m.group(2); + // skip type + // skip collectorId - String path; - path = CardImageUtils.generateFaceImagePath(name, set); - - if (path == null) { - return null; - } + String path = CardImageUtils.generateFaceImagePath(name, setCode); TFile file = getTFile(path); if (file == null) { - return null; + return new ImageCacheData(path, null); } BufferedImage image = loadImage(file); - return image; + return new ImageCacheData(path, image); } else { throw new RuntimeException( "Requested face image doesn't fit the requirement for key (##: " + key); @@ -235,7 +175,7 @@ public final class ImageCache { String resourceName = m.group(2); CardIconColor cardIconColor = CardIconColor.valueOf(m.group(3)); BufferedImage image = ImageManagerImpl.instance.getCardIcon(resourceName, cardSize, cardIconColor); - return image; + return new ImageCacheData(resourceName, image); } else { throw new RuntimeException("Wrong card icons image key format: " + key); } @@ -255,109 +195,38 @@ public final class ImageCache { CARD_ICONS_CACHE.invalidateAll(); } - public static String getFilePath(CardView card, int width) { - String key = getKey(card, card.getName(), Integer.toString(width)); - boolean usesVariousArt = false; - if (key.matches(".*#usesVariousArt.*")) { - usesVariousArt = true; - key = key.replace("#usesVariousArt", ""); - } - boolean thumbnail = false; - if (key.matches(".*#thumb.*")) { - thumbnail = true; - key = key.replace("#thumb", ""); - } - Matcher m = KEY_PATTERN.matcher(key); - - if (m.matches()) { - String name = m.group(1); - String set = m.group(2); - Integer type = Integer.parseInt(m.group(3)); - String collectorId = m.group(4); - if (collectorId.equals("null")) { - collectorId = "0"; - } - String tokenSetCode = m.group(5); - String tokenDescriptor = m.group(6); - - CardDownloadData info = new CardDownloadData(name, set, collectorId, usesVariousArt, type, tokenSetCode, tokenDescriptor); - - String path; - if (collectorId.isEmpty() || "0".equals(collectorId) || !tokenDescriptor.isEmpty()) { // tokenDescriptor for embalm ability - info.setToken(true); - path = CardImageUtils.generateTokenImagePath(info); - if (path == null) { - // try token image from card - CardDownloadData newInfo = new CardDownloadData(info); - newInfo.setToken(false); - path = CardImageUtils.buildImagePathToCard(newInfo); - TFile tokenFile = getTFile(path); - if (tokenFile == null || !tokenFile.exists()) { - // token empty token image - // TODO: replace empty token by other default card, not cardback - path = CardImageUtils.buildImagePathToDefault(DirectLinksForDownload.cardbackFilename); - } - } - } else { - path = CardImageUtils.buildImagePathToCard(info); - } - - if (thumbnail && path.endsWith(".jpg")) { - return buildThumbnailPath(path); - } - return path; - } - - return ""; - } - private ImageCache() { } - public static BufferedImage getCardbackImage() { - BufferedImage image = ImageCache.loadImage(new TFile(CardImageUtils.buildImagePathToDefault(DirectLinksForDownload.cardbackFilename))); + public static ImageCacheData getCardbackImage() { + String path = CardImageUtils.buildImagePathToDefault(DirectLinksForDownload.cardbackFilename); + BufferedImage image = ImageCache.loadImage(getTFile(path)); image = getRoundCorner(image); - return image; + return new ImageCacheData(path, image); } - public static BufferedImage getMorphImage() { - // TODO: replace by morth image - CardDownloadData info = new CardDownloadData("Morph", "KTK", "0", false, 0, "KTK", ""); + public static ImageCacheData getMorphImage() { + // TODO: replace by downloadable morth image + CardDownloadData info = new CardDownloadData("Morph", "KTK", "0", false, 0); info.setToken(true); - String path = CardImageUtils.generateTokenImagePath(info); - if (path == null) { - return null; - } - TFile file = getTFile(path); + String path = CardImageUtils.buildImagePathToCardOrToken(info); + TFile file = getTFile(path); BufferedImage image = loadImage(file); image = getRoundCorner(image); - return image; + return new ImageCacheData(path, image); } - public static BufferedImage getManifestImage() { - // TODO: replace by manifestest image - CardDownloadData info = new CardDownloadData("Manifest", "FRF", "0", false, 0, "FRF", ""); + public static ImageCacheData getManifestImage() { + // TODO: replace by downloadable manifestest image + CardDownloadData info = new CardDownloadData("Manifest", "FRF", "0", false, 0); info.setToken(true); - String path = CardImageUtils.generateTokenImagePath(info); - if (path == null) { - return null; - } - TFile file = getTFile(path); + String path = CardImageUtils.buildImagePathToCardOrToken(info); + TFile file = getTFile(path); BufferedImage image = loadImage(file); image = getRoundCorner(image); - return image; - } - - private static String buildThumbnailPath(String path) { - String thumbnailPath; - if (PreferencesDialog.isSaveImagesToZip()) { - thumbnailPath = path.replace(".zip", ".thumb.zip"); - } else { - thumbnailPath = path.replace(".jpg", ".thumb.jpg"); - } - return thumbnailPath; + return new ImageCacheData(path, image); } public static BufferedImage getRoundCorner(BufferedImage image) { @@ -387,6 +256,7 @@ public final class ImageCache { } public static BufferedImage getWizardsCard(BufferedImage image) { + // TODO: can be removed? if (image != null && image.getWidth() == 265 && image.getHeight() == 370) { BufferedImage crop = new BufferedImage(256, 360, BufferedImage.TYPE_INT_RGB); Graphics2D graphics2D = crop.createGraphics(); @@ -398,80 +268,61 @@ public final class ImageCache { } } - public static boolean isFaceImagePresent(CardView card) { - String path; - path = CardImageUtils.generateFaceImagePath(card.getName(), card.getExpansionSetCode()); - - if (path == null) { - return false; - } - TFile file = getTFile(path); - if (file == null) { - return false; - } - return file.exists(); + public static ImageCacheData getImageOriginal(CardView card) { + return getImage(getKey(card, card.getName(), 0)); } - public static BufferedImage getThumbnail(CardView card) { - return getImage(getKey(card, card.getName(), "#thumb")); + public static ImageCacheData getImageOriginalAlternateName(CardView card) { + return getImage(getKey(card, card.getAlternateName(), 0)); } - public static BufferedImage tryGetThumbnail(CardView card) { - return tryGetImage(getKey(card, card.getName(), "#thumb")); - } - - public static BufferedImage getImageOriginal(CardView card) { - return getImage(getKey(card, card.getName(), "")); - } - - public static BufferedImage getImageOriginalAlternateName(CardView card) { - return getImage(getKey(card, card.getAlternateName(), "")); - } - - public static BufferedImage getCardIconImage(String resourceName, int iconSize, String cardColorName) { + public static ImageCacheData getCardIconImage(String resourceName, int iconSize, String cardColorName) { return getCardIconImage(getCardIconKey(resourceName, iconSize, cardColorName)); } /** * Returns the Image corresponding to the key */ - private static BufferedImage getImage(String key) { + private static ImageCacheData getImage(String key) { try { - return IMAGE_CACHE.getOrNull(key); + ImageCacheData data = IMAGE_CACHE.getOrNull(key); + return data != null ? data : new ImageCacheData("ERROR: key - " + key, null); } catch (ComputationException ex) { // too low memory if (ex.getCause() instanceof NullPointerException) { - return null; + return new ImageCacheData("ERROR: low memory?", null); } LOGGER.error(ex, ex); - return null; + return new ImageCacheData("ERROR: see logs", null); } } /** * Returns the Image corresponding to the key */ - private static BufferedImage getFaceImage(String key) { + private static ImageCacheData getFaceImage(String key) { try { - return FACE_IMAGE_CACHE.getOrNull(key); + ImageCacheData data = FACE_IMAGE_CACHE.getOrNull(key); + return data != null ? data : new ImageCacheData("ERROR: key " + key, null); } catch (ComputationException ex) { if (ex.getCause() instanceof NullPointerException) { - return null; + return new ImageCacheData("ERROR: low memory?", null); } LOGGER.error(ex, ex); - return null; + return new ImageCacheData("ERROR: see logs", null); } } - private static BufferedImage getCardIconImage(String key) { + private static ImageCacheData getCardIconImage(String key) { try { - return CARD_ICONS_CACHE.getOrNull(key); + ImageCacheData data = CARD_ICONS_CACHE.getOrNull(key); + return data != null ? data : new ImageCacheData("ERROR: key - " + key, null); } catch (ComputationException ex) { if (ex.getCause() instanceof NullPointerException) { - return null; + return new ImageCacheData("ERROR: low memory?", null); } LOGGER.error(ex, ex); - return null; + return new ImageCacheData("ERROR: see logs", null); } } @@ -479,22 +330,24 @@ public final class ImageCache { * Returns the Image corresponding to the key only if it already exists in * the cache. */ - private static BufferedImage tryGetImage(String key) { + private static ImageCacheData tryGetImage(String key) { return IMAGE_CACHE.peekIfPresent(key); } /** - * Returns the map key for a card, without any suffixes for the image size. + * Generate key for images cache (it must contain all info to search and load image from the disk) + * + * @param card + * @param cardName - can be alternative name + * @param imageSize - size info, 0 to use original image (with max size) */ - private static String getKey(CardView card, String name, String suffix) { - return (card.isToken() ? name.replace(" Token", "") : name) + private static String getKey(CardView card, String cardName, int imageSize) { + return (card.isToken() ? cardName.replace(" Token", "") : cardName) + '#' + card.getExpansionSetCode() + '#' + card.getType() + '#' + card.getCardNumber() - + '#' + (card.getTokenSetCode() == null ? "" : card.getTokenSetCode()) - + suffix - + (card.getUsesVariousArt() ? "#usesVariousArt" : "") - + '#' + (card.getTokenDescriptor() != null ? card.getTokenDescriptor() : ""); + + '#' + imageSize + + (card.getUsesVariousArt() ? "#usesVariousArt" : ""); } /** @@ -534,24 +387,6 @@ public final class ImageCache { return image; } - public static BufferedImage makeThumbnail(BufferedImage original, String path) { - BufferedImage image = TransformedImageCache.getResizedImage(original, Constants.THUMBNAIL_SIZE_FULL.width, Constants.THUMBNAIL_SIZE_FULL.height); - TFile imageFile = getTFile(path); - if (imageFile == null) { - return null; - } - try { - try (TFileOutputStream outputStream = new TFileOutputStream(imageFile)) { - String format = image.getColorModel().getNumComponents() > 3 ? "png" : "jpg"; - ImageIO.write(image, format, outputStream); - } - } catch (IOException e) { - LOGGER.error(e.getMessage(), e); - imageFile.delete(); - } - return image; - } - /** * Returns an image scaled to the size given * @@ -584,23 +419,22 @@ public final class ImageCache { * @param height * @return */ - public static BufferedImage getImage(CardView card, int width, int height) { - if (Constants.THUMBNAIL_SIZE_FULL.width + 10 > width) { - return getThumbnail(card); - } - String key = getKey(card, card.getName(), Integer.toString(width)); - BufferedImage original = getImage(key); - if (original == null) { - LOGGER.debug(key + " not found"); - return null; + public static ImageCacheData getImage(CardView card, int width, int height) { + String key = getKey(card, card.getName(), width); + ImageCacheData data = getImage(key); + if (data.getImage() == null) { + LOGGER.debug("Image doesn't exists in the cache: " + key); + return data; } - double scale = Math.min((double) width / original.getWidth(), (double) height / original.getHeight()); + double scale = Math.min((double) width / data.getImage().getWidth(), (double) height / data.getImage().getHeight()); if (scale >= 1) { - return original; + return data; } - return TransformedImageCache.getResizedImage(original, (int) (original.getWidth() * scale), (int) (original.getHeight() * scale)); + BufferedImage newImage = TransformedImageCache.getResizedImage(data.getImage(), (int) (data.getImage().getWidth() * scale), (int) (data.getImage().getHeight() * scale)); + data.setImage(newImage); + return data; } /** @@ -611,15 +445,13 @@ public final class ImageCache { * @param height * @return */ - public static BufferedImage getFaceImage(CardView card, int width, int height) { + public static ImageCacheData getFaceImage(CardView card, int width, int height) { String key = getFaceKey(card, card.getName(), card.getExpansionSetCode()); - BufferedImage original = getFaceImage(key); - if (original == null) { + ImageCacheData data = getFaceImage(key); + if (data.getImage() == null) { LOGGER.debug(key + " (faceimage) not found"); - return null; } - - return original; + return data; } /** @@ -632,29 +464,31 @@ public final class ImageCache { * @param height * @return */ - public static BufferedImage tryGetImage(CardView card, int width, int height) { - if (Constants.THUMBNAIL_SIZE_FULL.width + 10 > width) { - return tryGetThumbnail(card); - } - String key = getKey(card, card.getName(), Integer.toString(width)); - BufferedImage original = tryGetImage(key); - if (original == null) { + public static ImageCacheData tryGetImage(CardView card, int width, int height) { + String key = getKey(card, card.getName(), width); + ImageCacheData data = tryGetImage(key); + if (data.getImage() == null) { LOGGER.debug(key + " not found"); - return null; + return data; } - double scale = Math.min((double) width / original.getWidth(), (double) height / original.getHeight()); + double scale = Math.min((double) width / data.getImage().getWidth(), (double) height / data.getImage().getHeight()); if (scale >= 1) { - return original; + return data; } - return TransformedImageCache.getResizedImage(original, (int) (original.getWidth() * scale), (int) (original.getHeight() * scale)); + BufferedImage newImage = TransformedImageCache.getResizedImage(data.getImage(), (int) (data.getImage().getWidth() * scale), (int) (data.getImage().getHeight() * scale)); + data.setImage(newImage); + return data; } public static TFile getTFile(String path) { try { - return new TFile(path); + if (path != null) { + return new TFile(path); + } } catch (NullPointerException ex) { + // TODO: raise error on path == null -- is it actual?! LOGGER.warn("Imagefile does not exist: " + path); } return null; diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCacheData.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCacheData.java new file mode 100644 index 0000000000..208de22181 --- /dev/null +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCacheData.java @@ -0,0 +1,28 @@ +package org.mage.plugins.card.images; + +import java.awt.image.BufferedImage; + +/** + * @author JayDi85 + */ +public class ImageCacheData { + String path; + BufferedImage image; + + public ImageCacheData(String path, BufferedImage image) { + this.path = path; + this.image = image; + } + + public String getPath() { + return path; + } + + public BufferedImage getImage() { + return image; + } + + public void setImage(BufferedImage image) { + this.image = image; + } +} diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java b/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java index b6573b0295..73fb163a15 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java @@ -5,7 +5,6 @@ import mage.client.constants.Constants; import mage.client.dialog.PreferencesDialog; import mage.remote.Connection; import mage.remote.Connection.ProxyType; -import net.java.truevfs.access.TFile; import org.apache.log4j.Logger; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; @@ -26,87 +25,13 @@ import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; import java.util.Locale; import java.util.prefs.Preferences; public final class CardImageUtils { - private static final HashMap pathCache = new HashMap<>(); private static final Logger LOGGER = Logger.getLogger(CardImageUtils.class); - /** - * @param card - * @return String if image exists, else null - */ - public static String generateTokenImagePath(CardDownloadData card) { - if (card.isToken()) { - String filePath = getTokenImagePath(card); - if (pathCache.containsKey(card)) { - if (filePath.equals(pathCache.get(card))) { - return pathCache.get(card); - } - } - TFile file = new TFile(filePath); - - if (!file.exists() && card.getTokenSetCode() != null) { - filePath = searchForCardImage(card); - file = new TFile(filePath); - } - - if (file.exists()) { - pathCache.put(card, filePath); - return filePath; - } - - //log.warn("Token image file not found. Set: " + card.getSet() + " Token Set Code: " + card.getTokenSetCode() + " Name: " + card.getName() + " File path: " + getTokenImagePath(card)); - } else { - LOGGER.warn("Trying to get token path for non token card. Set: " + card.getSet() + " Set Code: " + card.getTokenSetCode() + " Name: " + card.getName()); - } - return null; - } - - /** - * @param card - * @return String regardless of whether image exists - */ - public static String generateFullTokenImagePath(CardDownloadData card) { - if (card.isToken()) { - return getTokenImagePath(card); - } - return ""; - } - - private static String getTokenImagePath(CardDownloadData card) { - String filename = buildImagePathToCard(card); - - TFile file = new TFile(filename); - if (!file.exists()) { - String tokenDescriptorfilename = generateTokenDescriptorImagePath(card); - if (!tokenDescriptorfilename.isEmpty()) { - file = new TFile(filename); - if (file.exists()) { - return tokenDescriptorfilename; - } - } - } - return filename; - } - - private static String searchForCardImage(CardDownloadData card) { - TFile file; - String path; - CardDownloadData c = new CardDownloadData(card); - c.setSet(card.getTokenSetCode()); - path = getTokenImagePath(c); - file = new TFile(path); - if (file.exists()) { - pathCache.put(card, path); - return path; - } - return generateTokenDescriptorImagePath(card); - } - public static String prepareCardNameForFile(String cardName) { return cardName .replace(":", "") @@ -141,12 +66,12 @@ public final class CardImageUtils { return getImagesDir() + Constants.RESOURCE_PATH_DEFAULT_IMAGES + File.separator + defaultFileName; } - public static String fixSetNameForWindows(String set) { + public static String fixSetNameForWindows(String setCode) { // windows can't create con folders - if (set.equals("CON") || set.equals("con")) { + if (setCode.equals("CON") || setCode.equals("con")) { return "COX"; } else { - return set; + return setCode; } } @@ -160,40 +85,34 @@ public final class CardImageUtils { } } - private static String buildImagePathToTokenDescriptor(CardDownloadData card) { - return buildImagePathToTokens() + card.getTokenDescriptor() + ".full.jpg"; - } - public static String buildImagePathToSet(CardDownloadData card) { - if (card.getSet() == null) { throw new IllegalArgumentException("Card " + card.getName() + " have empty set."); } - - String set = card.getSet().toUpperCase(Locale.ENGLISH); + String setCode = card.getSet().toUpperCase(Locale.ENGLISH); if (card.isToken()) { - return buildImagePathToSetAsToken(set); + return buildImagePathToSetAsToken(setCode); } else { - return buildImagePathToSetAsCard(set); + return buildImagePathToSetAsCard(setCode); } } - private static String buildImagePathToSetAsCard(String set) { + private static String buildImagePathToSetAsCard(String setCode) { String imagesPath = getImagesDir() + File.separator; if (PreferencesDialog.isSaveImagesToZip()) { - return imagesPath + fixSetNameForWindows(set) + ".zip" + File.separator + fixSetNameForWindows(set) + File.separator; + return imagesPath + fixSetNameForWindows(setCode) + ".zip" + File.separator + fixSetNameForWindows(setCode) + File.separator; } else { - return imagesPath + fixSetNameForWindows(set) + File.separator; + return imagesPath + fixSetNameForWindows(setCode) + File.separator; } } - private static String buildImagePathToSetAsToken(String set) { - return buildImagePathToTokens() + fixSetNameForWindows(set) + File.separator; + private static String buildImagePathToSetAsToken(String setCode) { + return buildImagePathToTokens() + fixSetNameForWindows(setCode) + File.separator; } - public static String buildImagePathToCard(CardDownloadData card) { + public static String buildImagePathToCardOrToken(CardDownloadData card) { String setPath = buildImagePathToSet(card); @@ -207,7 +126,7 @@ public final class CardImageUtils { cardName = prepareCardNameForFile(card.getName()); } - String finalFileName = ""; + String finalFileName; if (card.getUsesVariousArt()) { // different arts uses name + collector id finalFileName = cardName + prefixType + '.' + card.getCollectorIdAsFileName() + ".full.jpg"; @@ -216,54 +135,11 @@ public final class CardImageUtils { finalFileName = cardName + prefixType + ".full.jpg"; } - /* 2019-01-12: no needs in name corrections, all files must be same and auto-downloaded - // if image file exists, correct name (for case sensitive systems) - // use TFile for zips - TFile dirFile = new TFile(setPath); - TFile imageFile = new TFile(setPath + finalFileName); - // warning, zip files can be broken - try { - if (dirFile.exists() && !imageFile.exists()) { - // search like names - for (String fileName : dirFile.list()) { - if (fileName.toLowerCase(Locale.ENGLISH).equals(finalFileName.toLowerCase(Locale.ENGLISH))) { - finalFileName = fileName; - break; - } - } - } - } catch (Exception ex) { - log.error("Can't read card name from file, may be it broken: " + setPath); - } - */ - return setPath + finalFileName; } - public static String generateFaceImagePath(String cardname, String set) { - return getImagesDir() + File.separator + "FACE" + File.separator + fixSetNameForWindows(set) + File.separator + prepareCardNameForFile(cardname) + ".jpg"; - } - - public static String generateTokenDescriptorImagePath(CardDownloadData card) { - - String straightImageFile = buildImagePathToTokenDescriptor(card); - TFile file = new TFile(straightImageFile); - if (file.exists()) { - return straightImageFile; - } - - straightImageFile = straightImageFile.replaceFirst("\\.[0-9]+\\.[0-9]+", ".X.X"); - file = new TFile(straightImageFile); - if (file.exists()) { - return straightImageFile; - } - - straightImageFile = straightImageFile.replaceFirst("\\.X\\.X", ".S.S"); - file = new TFile(straightImageFile); - if (file.exists()) { - return straightImageFile; - } - return ""; + public static String generateFaceImagePath(String cardName, String setCode) { + return getImagesDir() + File.separator + "FACE" + File.separator + fixSetNameForWindows(setCode) + File.separator + prepareCardNameForFile(cardName) + ".jpg"; } public static Proxy getProxyFromPreferences() { @@ -305,8 +181,7 @@ public final class CardImageUtils { } public static void checkAndFixImageFiles() { - // search broken files and delete it (zero size files) - // search temp files and delete it (.tmp files from zip library) + // search broken, temp or outdated files and delete it Path rootPath = new File(CardImageUtils.getImagesDir()).toPath(); if (!Files.exists(rootPath)) { return; @@ -314,6 +189,7 @@ public final class CardImageUtils { Collection brokenFilesList = new ArrayList<>(); Collection tempFilesList = new ArrayList<>(); + Collection outdatedFilesList = new ArrayList<>(); try { Files.walkFileTree(rootPath, new SimpleFileVisitor() { @Override @@ -329,6 +205,11 @@ public final class CardImageUtils { tempFilesList.add(file); } + // 3. outdated files delete without warning + if (file.toString().endsWith(".thumb.zip")) { + outdatedFilesList.add(file); + } + return FileVisitResult.CONTINUE; } }); @@ -336,10 +217,13 @@ public final class CardImageUtils { LOGGER.error("Can't load files list from images folder: " + rootPath.toAbsolutePath().toString(), e); } - // temp files must be deleted without errors - for (Path tempFile : tempFilesList) { + // temp and outdated files must be deleted without errors + Collection list = new ArrayList<>(); + list.addAll(tempFilesList); + list.addAll(outdatedFilesList); + for (Path path : list) { try { - Files.delete(tempFile); + Files.delete(path); } catch (Throwable e) { // ignore any error (e.g. it opened by xmage app) } @@ -353,7 +237,7 @@ public final class CardImageUtils { Files.delete(brokenFile); } catch (Throwable e) { // stop clean on any error - LOGGER.error("Images check: ERROR, can't delete broken file: " + brokenFile.toAbsolutePath().toString(), e); + LOGGER.error("Images check: ERROR, can't delete broken file: " + brokenFile.toAbsolutePath(), e); break; } } diff --git a/Mage.Client/src/test/java/mage/client/game/TokensMtgImageSourceTest.java b/Mage.Client/src/test/java/mage/client/game/TokensMtgImageSourceTest.java index 6ec7139d3e..4b6100a76b 100644 --- a/Mage.Client/src/test/java/mage/client/game/TokensMtgImageSourceTest.java +++ b/Mage.Client/src/test/java/mage/client/game/TokensMtgImageSourceTest.java @@ -18,16 +18,16 @@ public class TokensMtgImageSourceTest { public void generateTokenUrlTest() throws Exception { CardImageSource imageSource = TokensMtgImageSource.instance; - CardImageUrls url = imageSource.generateTokenUrl(new CardDownloadData("Thopter", "ORI", "0", false, 1, "ORI", "")); + CardImageUrls url = imageSource.generateTokenUrl(new CardDownloadData("Thopter", "ORI", "0", false, 1)); Assert.assertEquals("https://tokens.mtg.onl/tokens/ORI_010-Thopter.jpg", url.baseUrl); - url = imageSource.generateTokenUrl(new CardDownloadData("Thopter", "ORI", "0", false, 2, "ORI", "")); + url = imageSource.generateTokenUrl(new CardDownloadData("Thopter", "ORI", "0", false, 2)); Assert.assertEquals("https://tokens.mtg.onl/tokens/ORI_011-Thopter.jpg", url.baseUrl); - url = imageSource.generateTokenUrl(new CardDownloadData("Ashaya, the Awoken World", "ORI", "0", false, 0, "ORI", "")); + url = imageSource.generateTokenUrl(new CardDownloadData("Ashaya, the Awoken World", "ORI", "0", false, 0)); Assert.assertEquals("https://tokens.mtg.onl/tokens/ORI_007-Ashaya,-the-Awoken-World.jpg", url.baseUrl); - url = imageSource.generateTokenUrl(new CardDownloadData("Emblem Gideon, Ally of Zendikar", "BFZ", "0", false, 0, null, "")); + url = imageSource.generateTokenUrl(new CardDownloadData("Emblem Gideon, Ally of Zendikar", "BFZ", "0", false, 0)); Assert.assertEquals("https://tokens.mtg.onl/tokens/BFZ_012-Gideon-Emblem.jpg", url.baseUrl); } } diff --git a/Mage.Common/src/main/java/mage/view/CardView.java b/Mage.Common/src/main/java/mage/view/CardView.java index fe792aff71..0966540a30 100644 --- a/Mage.Common/src/main/java/mage/view/CardView.java +++ b/Mage.Common/src/main/java/mage/view/CardView.java @@ -273,7 +273,7 @@ public class CardView extends SimpleCardView { * @param storeZone if true the card zone will be set in the zone attribute. */ public CardView(Card card, Game game, boolean controlled, boolean showFaceDownCard, boolean storeZone) { - super(card.getId(), card.getExpansionSetCode(), card.getCardNumber(), card.getUsesVariousArt(), card.getTokenSetCode(), game != null, card.getTokenDescriptor()); + super(card.getId(), card.getExpansionSetCode(), card.getCardNumber(), card.getUsesVariousArt(), game != null); this.originalCard = card; // no information available for face down cards as long it's not a controlled face down morph card @@ -487,7 +487,6 @@ public class CardView extends SimpleCardView { } else { // a created token this.expansionSetCode = card.getExpansionSetCode(); - this.tokenDescriptor = card.getTokenDescriptor(); } // // set code and card number for token copies to get the image @@ -600,7 +599,7 @@ public class CardView extends SimpleCardView { } public CardView(MageObject object, Game game) { - super(object.getId(), "", "0", false, "", true, ""); + super(object.getId(), "", "0", false, true); this.originalCard = null; this.name = object.getName(); @@ -674,7 +673,7 @@ public class CardView extends SimpleCardView { } protected CardView() { - super(null, "", "0", false, "", true, ""); + super(null, "", "0", false, true); } public CardView(EmblemView emblem) { @@ -739,7 +738,7 @@ public class CardView extends SimpleCardView { } public CardView(boolean empty) { - super(null, "", "0", false, "", ""); + super(null, "", "0", false); if (!empty) { throw new IllegalArgumentException("Not supported."); } @@ -793,9 +792,10 @@ public class CardView extends SimpleCardView { } CardView(Token token, Game game) { - super(token.getId(), "", "0", false, "", ""); + super(token.getId(), "", "0", false); this.isToken = true; this.id = token.getId(); + this.expansionSetCode = token.getOriginalExpansionSetCode(); this.name = token.getName(); this.displayName = token.getName(); this.displayFullName = token.getName(); @@ -814,8 +814,6 @@ public class CardView extends SimpleCardView { this.manaCostRightStr = ""; this.rarity = Rarity.SPECIAL; this.type = token.getTokenType(); - this.tokenDescriptor = token.getTokenDescriptor(); - this.tokenSetCode = token.getOriginalExpansionSetCode(); } protected final void addTargets(Targets targets, Effects effects, Ability source, Game game) { diff --git a/Mage.Common/src/main/java/mage/view/LookedAtView.java b/Mage.Common/src/main/java/mage/view/LookedAtView.java index e49b376471..17af1a0e8a 100644 --- a/Mage.Common/src/main/java/mage/view/LookedAtView.java +++ b/Mage.Common/src/main/java/mage/view/LookedAtView.java @@ -20,7 +20,7 @@ public class LookedAtView implements Serializable { public LookedAtView(String name, Cards cards, Game game) { this.name = name; for (Card card: cards.getCards(game)) { - this.cards.put(card.getId(), new SimpleCardView(card.getId(), card.getExpansionSetCode(), card.getCardNumber(), card.getUsesVariousArt(), card.getTokenSetCode(), card.getTokenDescriptor())); + this.cards.put(card.getId(), new SimpleCardView(card.getId(), card.getExpansionSetCode(), card.getCardNumber(), card.getUsesVariousArt())); } } diff --git a/Mage.Common/src/main/java/mage/view/PermanentView.java b/Mage.Common/src/main/java/mage/view/PermanentView.java index b6f92f95c9..b1a6ef27b0 100644 --- a/Mage.Common/src/main/java/mage/view/PermanentView.java +++ b/Mage.Common/src/main/java/mage/view/PermanentView.java @@ -54,8 +54,7 @@ public class PermanentView extends CardView { if (isToken()) { original = new CardView(((PermanentToken) permanent).getToken().copy(), (Game) null); original.expansionSetCode = permanent.getExpansionSetCode(); - tokenSetCode = original.getTokenSetCode(); - tokenDescriptor = original.getTokenDescriptor(); + expansionSetCode = permanent.getExpansionSetCode(); } else { if (card != null) { // original may not be face down diff --git a/Mage.Common/src/main/java/mage/view/SimpleCardView.java b/Mage.Common/src/main/java/mage/view/SimpleCardView.java index 4fc6cf2063..d9b45476e8 100644 --- a/Mage.Common/src/main/java/mage/view/SimpleCardView.java +++ b/Mage.Common/src/main/java/mage/view/SimpleCardView.java @@ -13,8 +13,6 @@ public class SimpleCardView implements Serializable, SelectableObjectView { @Expose protected UUID id; protected String expansionSetCode; - protected String tokenSetCode; - protected String tokenDescriptor; protected String cardNumber; protected boolean usesVariousArt; protected boolean gameObject; @@ -26,28 +24,23 @@ public class SimpleCardView implements Serializable, SelectableObjectView { public SimpleCardView(final SimpleCardView view) { this.id = view.id; this.expansionSetCode = view.expansionSetCode; - this.tokenSetCode = view.tokenSetCode; - this.tokenDescriptor = view.tokenDescriptor; this.cardNumber = view.cardNumber; this.usesVariousArt = view.usesVariousArt; this.gameObject = view.gameObject; - this.isChoosable = view.isChoosable; this.isSelected = view.isSelected; this.playableStats = view.playableStats.copy(); } - public SimpleCardView(UUID id, String expansionSetCode, String cardNumber, boolean usesVariousArt, String tokenSetCode, String tokenDescriptor) { - this(id, expansionSetCode, cardNumber, usesVariousArt, tokenSetCode, false, tokenDescriptor); + public SimpleCardView(UUID id, String expansionSetCode, String cardNumber, boolean usesVariousArt) { + this(id, expansionSetCode, cardNumber, usesVariousArt, false); } - public SimpleCardView(UUID id, String expansionSetCode, String cardNumber, boolean usesVariousArt, String tokenSetCode, boolean isGameObject, String tokenDescriptor) { + public SimpleCardView(UUID id, String expansionSetCode, String cardNumber, boolean usesVariousArt, boolean isGameObject) { this.id = id; this.expansionSetCode = expansionSetCode; - this.tokenDescriptor = tokenDescriptor; this.cardNumber = cardNumber; this.usesVariousArt = usesVariousArt; - this.tokenSetCode = tokenSetCode; this.gameObject = isGameObject; } @@ -67,14 +60,6 @@ public class SimpleCardView implements Serializable, SelectableObjectView { return usesVariousArt; } - public String getTokenSetCode() { - return tokenSetCode; - } - - public String getTokenDescriptor() { - return tokenDescriptor; - } - public boolean isGameObject() { return gameObject; } diff --git a/Mage.Common/src/main/java/mage/view/SimpleCardsView.java b/Mage.Common/src/main/java/mage/view/SimpleCardsView.java index 5c11f93da4..c5c7e7a2c4 100644 --- a/Mage.Common/src/main/java/mage/view/SimpleCardsView.java +++ b/Mage.Common/src/main/java/mage/view/SimpleCardsView.java @@ -18,8 +18,7 @@ public class SimpleCardsView extends LinkedHashMap { public SimpleCardsView(Collection cards, boolean isGameObject) { for (Card card: cards) { - this.put(card.getId(), new SimpleCardView(card.getId(), card.getExpansionSetCode(), card.getCardNumber(), card.getUsesVariousArt(), card.getTokenSetCode(), isGameObject, - card.getTokenDescriptor())); + this.put(card.getId(), new SimpleCardView(card.getId(), card.getExpansionSetCode(), card.getCardNumber(), card.getUsesVariousArt(), isGameObject)); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/TokenImagesTest.java b/Mage.Tests/src/test/java/org/mage/test/serverside/TokenImagesTest.java new file mode 100644 index 0000000000..57faeb431c --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/TokenImagesTest.java @@ -0,0 +1,35 @@ +package org.mage.test.serverside; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.game.permanent.PermanentToken; +import org.junit.Assert; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author JayDi85 + */ +public class TokenImagesTest extends CardTestPlayerBase { + + @Test + public void test_TokenMustGetSameSetCodeAsSourceCard() { + //{3}{W}, {T}, Sacrifice Memorial to Glory: Create two 1/1 white Soldier creature tokens. + addCard(Zone.BATTLEFIELD, playerA, "40K:Memorial to Glory"); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{3}{W}, {T}, Sacrifice"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerA, "Soldier Token", 2); + currentGame.getBattlefield().getAllPermanents().stream() + .filter(card -> card.getName().equals("Soldier Token")) + .forEach(card -> { + Assert.assertEquals("40K", card.getExpansionSetCode()); + Assert.assertEquals("40K", ((PermanentToken) card).getToken().getOriginalExpansionSetCode()); + }); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java index 0362f8ffb6..afdfc0396a 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java @@ -622,7 +622,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement Assert.fail("Can't add card " + cardName + " - alias " + aliasName + " already exists for " + player.getName()); } - // set code for + // set code for card String setCode = ""; String setLookup = CardUtil.substring(cardName, CardUtil.TESTS_SET_CODE_LOOKUP_LENGTH); if (setLookup.contains(":")) { diff --git a/Mage/src/main/java/mage/cards/Card.java b/Mage/src/main/java/mage/cards/Card.java index 71ddf58ef0..347dc12462 100644 --- a/Mage/src/main/java/mage/cards/Card.java +++ b/Mage/src/main/java/mage/cards/Card.java @@ -49,11 +49,6 @@ public interface Card extends MageObject { List getRules(Game game); // gets card rules + in game modifications String getExpansionSetCode(); - - String getTokenSetCode(); - - String getTokenDescriptor(); - void checkForCountersToAdd(Permanent permanent, Ability source, Game game); void setFaceDown(boolean value, Game game); diff --git a/Mage/src/main/java/mage/cards/CardImpl.java b/Mage/src/main/java/mage/cards/CardImpl.java index 9e98afb524..d73cd16ca9 100644 --- a/Mage/src/main/java/mage/cards/CardImpl.java +++ b/Mage/src/main/java/mage/cards/CardImpl.java @@ -42,8 +42,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card { protected UUID ownerId; protected String cardNumber; protected String expansionSetCode; - protected String tokenSetCode; - protected String tokenDescriptor; protected Rarity rarity; protected Class secondSideCardClazz; protected Class meldsWithClazz; @@ -121,8 +119,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card { ownerId = card.ownerId; cardNumber = card.cardNumber; expansionSetCode = card.expansionSetCode; - tokenSetCode = card.tokenSetCode; - tokenDescriptor = card.tokenDescriptor; rarity = card.rarity; secondSideCardClazz = card.secondSideCardClazz; @@ -378,16 +374,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card { return expansionSetCode; } - @Override - public String getTokenSetCode() { - return tokenSetCode; - } - - @Override - public String getTokenDescriptor() { - return tokenDescriptor; - } - @Override public List getMana() { List mana = new ArrayList<>(); diff --git a/Mage/src/main/java/mage/game/permanent/PermanentToken.java b/Mage/src/main/java/mage/game/permanent/PermanentToken.java index 416e8ef439..c3e759146a 100644 --- a/Mage/src/main/java/mage/game/permanent/PermanentToken.java +++ b/Mage/src/main/java/mage/game/permanent/PermanentToken.java @@ -87,7 +87,6 @@ public class PermanentToken extends PermanentImpl { this.supertype.clear(); this.supertype.addAll(token.getSuperType()); this.subtype.copyFrom(token.getSubtype(game)); - this.tokenDescriptor = token.getTokenDescriptor(); this.startingLoyalty = token.getStartingLoyalty(); // workaround for entersTheBattlefield replacement effects if (this.abilities.containsClass(ChangelingAbility.class)) { diff --git a/Mage/src/main/java/mage/game/permanent/token/Token.java b/Mage/src/main/java/mage/game/permanent/token/Token.java index c93f0c6223..c1203d52d1 100644 --- a/Mage/src/main/java/mage/game/permanent/token/Token.java +++ b/Mage/src/main/java/mage/game/permanent/token/Token.java @@ -17,8 +17,6 @@ public interface Token extends MageObject { @Override Token copy(); - String getTokenDescriptor(); - String getDescription(); List getLastAddedTokenIds(); diff --git a/Mage/src/main/java/mage/game/permanent/token/TokenImpl.java b/Mage/src/main/java/mage/game/permanent/token/TokenImpl.java index 3589e3e702..424eb930ec 100644 --- a/Mage/src/main/java/mage/game/permanent/token/TokenImpl.java +++ b/Mage/src/main/java/mage/game/permanent/token/TokenImpl.java @@ -85,12 +85,6 @@ public abstract class TokenImpl extends MageObjectImpl implements Token { this.tokenDescriptor = tokenDescriptor(); } - @Override - public String getTokenDescriptor() { - this.tokenDescriptor = tokenDescriptor(); - return tokenDescriptor; - } - private String tokenDescriptor() { String strName = this.name.replaceAll("[^a-zA-Z0-9]", ""); String strColor = this.color.toString().replaceAll("[^a-zA-Z0-9]", ""); diff --git a/Mage/src/main/java/mage/game/stack/Spell.java b/Mage/src/main/java/mage/game/stack/Spell.java index c21b50b77f..6c210beed2 100644 --- a/Mage/src/main/java/mage/game/stack/Spell.java +++ b/Mage/src/main/java/mage/game/stack/Spell.java @@ -697,16 +697,6 @@ public class Spell extends StackObjectImpl implements Card { return card.getExpansionSetCode(); } - @Override - public String getTokenSetCode() { - return card.getTokenSetCode(); - } - - @Override - public String getTokenDescriptor() { - return card.getTokenDescriptor(); - } - @Override public void setFaceDown(boolean value, Game game) { faceDown = value;