/* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ package mage.cards.decks.importer; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import mage.cards.decks.DeckCardInfo; import mage.cards.decks.DeckCardLayout; import mage.cards.decks.DeckCardLists; import mage.cards.repository.CardInfo; import mage.cards.repository.CardRepository; /** * * @author North */ public class DckDeckImporter extends DeckImporter { private static final Pattern pattern = Pattern.compile("(SB:)?\\s*(\\d*)\\s*\\[([^]:]+):([^]:]+)\\]\\s*(.*)\\s*$"); private static final Pattern layoutPattern = Pattern.compile("LAYOUT (\\w+):\\((\\d+),(\\d+)\\)([^|]+)\\|(.*)$"); private static final Pattern layoutStackPattern = Pattern.compile("\\(([^)]*)\\)"); private static final Pattern layoutStackEntryPattern = Pattern.compile("\\[(\\w+):(\\w+)]"); @Override protected void readLine(String line, DeckCardLists deckList) { if (line.isEmpty() || line.startsWith("#")) { return; } Matcher m = pattern.matcher(line); if (m.matches()) { boolean sideboard = false; if ("SB:".equals(m.group(1))) { sideboard = true; } int count = Integer.parseInt(m.group(2)); String setCode = m.group(3); String cardNum = m.group(4); DeckCardInfo deckCardInfo = null; CardInfo cardInfo = CardRepository.instance.findCard(setCode, cardNum); if (cardInfo == null) { // Try alternate based on name String cardName = m.group(5); if (cardName != null && !cardName.isEmpty()) { cardInfo = CardRepository.instance.findPreferedCoreExpansionCard(cardName, false); sbMessage.append("Could not find card '").append(cardName).append("' in set ").append(setCode).append(" of number ").append(cardNum).append(".\n"); if (cardInfo != null) { sbMessage.append("Made substitution of ").append(cardInfo.getCardNumber()).append(", ").append(cardInfo.getCard().getExpansionSetCode()).append(" instead.\n"); } } } if (cardInfo != null) { deckCardInfo = new DeckCardInfo(cardInfo.getName(), cardInfo.getCardNumber(), cardInfo.getSetCode()); } if (deckCardInfo != null) { for (int i = 0; i < count; i++) { if (!sideboard) { deckList.getCards().add(deckCardInfo); } else { deckList.getSideboard().add(deckCardInfo); } } } else { sbMessage.append("Could not find card '").append("' at line ").append(lineCount).append(": ").append(line).append('\n'); } } else if (line.startsWith("NAME:")) { deckList.setName(line.substring(5, line.length())); } else if (line.startsWith("AUTHOR:")) { deckList.setAuthor(line.substring(7, line.length())); } else if (line.startsWith("LAYOUT")) { Matcher m2 = layoutPattern.matcher(line); if (m2.find()) { String target = m2.group(1); int rows = Integer.parseInt(m2.group(2)); int cols = Integer.parseInt(m2.group(3)); String settings = m2.group(4); String stackData = m2.group(5); Matcher stackMatcher = layoutStackPattern.matcher(stackData); // List<List<List<DeckCardInfo>>> grid = new ArrayList<>(); int totalCardCount = 0; for (int row = 0; row < rows; ++row) { List<List<DeckCardInfo>> rowData = new ArrayList<>(); grid.add(rowData); for (int col = 0; col < cols; ++col) { List<DeckCardInfo> stack = new ArrayList<>(); rowData.add(stack); if (stackMatcher.find()) { String thisStackData = stackMatcher.group(1); Matcher stackEntries = layoutStackEntryPattern.matcher(thisStackData); while (stackEntries.find()) { ++totalCardCount; stack.add(new DeckCardInfo("", stackEntries.group(2), stackEntries.group(1))); } } else { sbMessage.append("Missing stack\n."); } } } // DeckCardLayout layout = new DeckCardLayout(grid, settings); int expectedCount = 0; switch (target) { case "MAIN": deckList.setCardLayout(layout); expectedCount = deckList.getCards().size(); break; case "SIDEBOARD": deckList.setSideboardLayout(layout); expectedCount = deckList.getSideboard().size(); break; default: sbMessage.append("Bad target `").append(target).append("` for layout.\n"); break; } // if (totalCardCount != expectedCount) { sbMessage.append("Layout mismatch: Expected ").append(expectedCount).append(" cards, but got ").append(totalCardCount).append(" in layout `").append(target).append("`\n."); } } else { sbMessage.append("Malformed layout line"); } } } }