diff --git a/forge-core/src/main/java/forge/deck/DeckRecognizer.java b/forge-core/src/main/java/forge/deck/DeckRecognizer.java index d9db912ef47..68e27bef163 100644 --- a/forge-core/src/main/java/forge/deck/DeckRecognizer.java +++ b/forge-core/src/main/java/forge/deck/DeckRecognizer.java @@ -206,7 +206,13 @@ public class DeckRecognizer { REX_CARD_COUNT, REX_CARD_NAME, REX_COLL_NUMBER, REX_SET_CODE, REX_FOIL_MTGGOLDFISH); public static final Pattern CARD_COLLNO_SET_PATTERN = Pattern.compile(REX_FULL_REQUEST_CARD_COLLNO_SET); - // 6. Card-Only Request (Amount?) + // 6. XMage format (Amount?, [Set:Collector Number] Card Name) + public static final String REX_FULL_REQUEST_XMAGE = String.format( + "^(%s\\s)?\\s*(\\[)?%s:%s(\\])\\s+%s\\s*%s$", + REX_CARD_COUNT, REX_SET_CODE, REX_COLL_NUMBER, REX_CARD_NAME, REX_FOIL_MTGGOLDFISH); + public static final Pattern SET_COLLNO_CARD_XMAGE_PATTERN = Pattern.compile(REX_FULL_REQUEST_XMAGE); + + // 7. Card-Only Request (Amount?) public static final String REX_CARDONLY = String.format( "(%s\\s)?\\s*%s\\s*%s", REX_CARD_COUNT, REX_CARD_NAME, REX_FOIL_MTGGOLDFISH); public static final Pattern CARD_ONLY_PATTERN = Pattern.compile(REX_CARDONLY); @@ -382,7 +388,8 @@ public class DeckRecognizer { Pattern[] patternsWithCollNumber = new Pattern[] { CARD_SET_COLLNO_PATTERN, SET_CARD_COLLNO_PATTERN, - CARD_COLLNO_SET_PATTERN + CARD_COLLNO_SET_PATTERN, + SET_COLLNO_CARD_XMAGE_PATTERN }; for (Pattern pattern : patternsWithCollNumber) { Matcher matcher = pattern.matcher(line); diff --git a/forge-gui-desktop/src/test/java/forge/deck/DeckRecognizerTest.java b/forge-gui-desktop/src/test/java/forge/deck/DeckRecognizerTest.java index 20f52b7a44b..94f7d5433bc 100644 --- a/forge-gui-desktop/src/test/java/forge/deck/DeckRecognizerTest.java +++ b/forge-gui-desktop/src/test/java/forge/deck/DeckRecognizerTest.java @@ -1208,7 +1208,7 @@ public class DeckRecognizerTest extends ForgeCardMockTestCase { assertEquals(counterSpellCard.getEdition(), "MMQ"); } - @Test void testInvalidCardRequestWhenReleaseDAteConstraintsAreUp(){ + @Test void testInvalidCardRequestWhenReleaseDateConstraintsAreUp(){ StaticData magicDb = FModel.getMagicDb(); CardDb db = magicDb.getCommonCards(); CardDb altDb = magicDb.getVariantCards(); @@ -1234,6 +1234,12 @@ public class DeckRecognizerTest extends ForgeCardMockTestCase { assertNull(cardToken.getCard()); } + /*================================== + * TEST RECOGNISE CARD EXTRA FORMATS + * ================================= + */ + + // === MTG Goldfish @Test void testFoilRequestInMTGGoldfishExportFormat(){ String mtgGoldfishRequest = "18 Forest <254> [THB]"; Pattern target = DeckRecognizer.CARD_COLLNO_SET_PATTERN; @@ -1313,6 +1319,7 @@ public class DeckRecognizerTest extends ForgeCardMockTestCase { assertTrue(forestCard.isFoil()); } + // === TappedOut Markdown Format @Test void testPurgeLinksInLineRequests(){ String line = "* 1 [Ancestral Recall](http://tappedout.nethttp://tappedout.net/mtg-card/ancestral-recall/)"; String expected = "* 1 [Ancestral Recall]"; @@ -1341,4 +1348,61 @@ public class DeckRecognizerTest extends ForgeCardMockTestCase { assertEquals(ancestralRecallCard.getName(), "Ancestral Recall"); assertEquals(ancestralRecallCard.getEdition(), "VMA"); } + + // === XMage Format + @Test void testMatchCardRequestXMageFormat(){ + String xmageFormatRequest = "1 [LRW:51] Amoeboid Changeling"; + Pattern target = DeckRecognizer.SET_COLLNO_CARD_XMAGE_PATTERN; + Matcher matcher = target.matcher(xmageFormatRequest); + assertTrue(matcher.matches()); + assertEquals(matcher.group(DeckRecognizer.REGRP_CARDNO), "1"); + assertEquals(matcher.group(DeckRecognizer.REGRP_CARD), "Amoeboid Changeling"); // TRIM + assertEquals(matcher.group(DeckRecognizer.REGRP_SET), "LRW"); + assertEquals(matcher.group(DeckRecognizer.REGRP_COLLNR), "51"); + assertNull(matcher.group(DeckRecognizer.REGRP_FOIL_GFISH)); + + // Test that this line matches only with this pattern + + target = DeckRecognizer.CARD_SET_PATTERN; + matcher = target.matcher(xmageFormatRequest); + assertFalse(matcher.matches()); + + target = DeckRecognizer.SET_CARD_PATTERN; + matcher = target.matcher(xmageFormatRequest); + assertFalse(matcher.matches()); + + target = DeckRecognizer.CARD_SET_COLLNO_PATTERN; + matcher = target.matcher(xmageFormatRequest); + assertFalse(matcher.matches()); + + target = DeckRecognizer.SET_CARD_COLLNO_PATTERN; + matcher = target.matcher(xmageFormatRequest); + assertFalse(matcher.matches()); + + target = DeckRecognizer.CARD_COLLNO_SET_PATTERN; + matcher = target.matcher(xmageFormatRequest); + assertFalse(matcher.matches()); + + target = DeckRecognizer.CARD_ONLY_PATTERN; + matcher = target.matcher(xmageFormatRequest); + assertFalse(matcher.matches()); + } + + @Test void testRecognizeCardTokenInXMageFormatRequest(){ + StaticData magicDb = FModel.getMagicDb(); + CardDb db = magicDb.getCommonCards(); + CardDb altDb = magicDb.getVariantCards(); + DeckRecognizer recognizer = new DeckRecognizer(db, altDb); + + String xmageFormatRequest = "1 [LRW:51] Amoeboid Changeling"; + Token xmageCardToken = recognizer.recogniseCardToken(xmageFormatRequest); + assertNotNull(xmageCardToken); + assertEquals(xmageCardToken.getType(), TokenType.LEGAL_CARD_REQUEST); + assertEquals(xmageCardToken.getNumber(), 1); + assertNotNull(xmageCardToken.getCard()); + PaperCard acCard = xmageCardToken.getCard(); + assertEquals(acCard.getName(), "Amoeboid Changeling"); + assertEquals(acCard.getEdition(), "LRW"); + assertEquals(acCard.getCollectorNumber(), "51"); + } } diff --git a/forge-gui/res/languages/en-US.properties b/forge-gui/res/languages/en-US.properties index ac949307ce7..43e9fb0afdf 100644 --- a/forge-gui/res/languages/en-US.properties +++ b/forge-gui/res/languages/en-US.properties @@ -2676,7 +2676,7 @@ lblGuideTipsDeckSection={0}: Similarly, the Card List can be organised by Deck S lblGuideTipsDeckName={0}: Assign a name to your card list. Just type "Deck" or "Name", followed by the name you want. \ This will be used as (new) name for the Deck. lblGuideTipsDeckFormats={0}: The following Deck formats are supported for immediate import: MTG Arena; \ - MTG Goldfish (all export); TappedOut (all export, but CSV); DeckStats.net; Deck ".dec" files. + MTGO, XMage, MTG Goldfish (all export); TappedOut (all export, but CSV); DeckStats.net; Deck ".dec" files. lblGuideTipsTitleCount=Card Amount lblGuideTipsTitleSet=Card Art lblGuideTipsTitleCardType=Card Types