Merge pull request #6190 from luziferius/refactor_promo_sets

[RFC] Refactor promo sets, add missing sets as listed on Scryfall
This commit is contained in:
Oleg Agafonov 2020-08-10 16:57:00 +02:00 committed by GitHub
commit b16d30b79b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
438 changed files with 14861 additions and 3880 deletions

View file

@ -1,8 +1,5 @@
package mage.cards;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.keyword.PartnerWithAbility;
@ -15,6 +12,10 @@ import mage.util.CardUtil;
import mage.util.RandomUtil;
import org.apache.log4j.Logger;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author BetaSteward_at_googlemail.com
*/
@ -135,6 +136,12 @@ public abstract class ExpansionSet implements Serializable {
return releaseDate;
}
public int getReleaseYear() {
Calendar cal = Calendar.getInstance();
cal.setTime(this.getReleaseDate());
return cal.get(Calendar.YEAR);
}
public ExpansionSet getParentSet() {
return parentSet;
}

View file

@ -1,5 +1,11 @@
package mage.cards.decks.importer;
import mage.cards.decks.DeckCardInfo;
import mage.cards.decks.DeckCardLists;
import mage.cards.repository.CardInfo;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
@ -7,68 +13,67 @@ import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import mage.cards.decks.DeckCardInfo;
import mage.cards.decks.DeckCardLists;
import mage.cards.repository.CardInfo;
public class CodDeckImporter extends XmlDeckImporter {
@Override
public DeckCardLists importDeck(String filename, StringBuilder errorMessages) {
try {
Document doc = getXmlDocument(filename);
DeckCardLists decklist = new DeckCardLists();
/**
* @param filename
* @param errorMessages
* @param saveAutoFixedFile do not supported for current format
* @return
*/
@Override
public DeckCardLists importDeck(String filename, StringBuilder errorMessages, boolean saveAutoFixedFile) {
try {
Document doc = getXmlDocument(filename);
DeckCardLists decklist = new DeckCardLists();
List<Node> mainCards = getNodes(doc, "/cockatrice_deck/zone[@name='main']/card");
decklist.setCards(mainCards.stream()
.flatMap(toDeckCardInfo(getCardLookup(), errorMessages))
.collect(Collectors.toList()));
List<Node> mainCards = getNodes(doc, "/cockatrice_deck/zone[@name='main']/card");
decklist.setCards(mainCards.stream()
.flatMap(toDeckCardInfo(getCardLookup(), errorMessages))
.collect(Collectors.toList()));
List<Node> sideboardCards = getNodes(doc, "/cockatrice_deck/zone[@name='side']/card");
decklist.setSideboard(sideboardCards.stream()
.flatMap(toDeckCardInfo(getCardLookup(), errorMessages))
.collect(Collectors.toList()));
List<Node> sideboardCards = getNodes(doc, "/cockatrice_deck/zone[@name='side']/card");
decklist.setSideboard(sideboardCards.stream()
.flatMap(toDeckCardInfo(getCardLookup(), errorMessages))
.collect(Collectors.toList()));
getNodes(doc, "/cockatrice_deck/deckname")
.forEach(n -> decklist.setName(n.getTextContent().trim()));
getNodes(doc, "/cockatrice_deck/deckname")
.forEach(n -> decklist.setName(n.getTextContent().trim()));
return decklist;
} catch (Exception e) {
logger.error("Error loading deck", e);
errorMessages.append("There was an error loading the deck.");
return new DeckCardLists();
return decklist;
} catch (Exception e) {
logger.error("Error loading deck", e);
errorMessages.append("There was an error loading the deck.");
return new DeckCardLists();
}
}
}
private static int getQuantityFromNode(Node node) {
Node numberNode = node.getAttributes().getNamedItem("number");
if (numberNode == null) {
return 1;
private static int getQuantityFromNode(Node node) {
Node numberNode = node.getAttributes().getNamedItem("number");
if (numberNode == null) {
return 1;
}
try {
return Math.min(100, Math.max(1, Integer.parseInt(numberNode.getNodeValue())));
} catch (NumberFormatException e) {
return 1;
}
}
try {
return Math.min(100, Math.max(1, Integer.parseInt(numberNode.getNodeValue())));
} catch (NumberFormatException e) {
return 1;
}
}
private static Function<Node, Stream<DeckCardInfo>> toDeckCardInfo(CardLookup lookup, StringBuilder errors) {
return node -> {
String name = node.getAttributes().getNamedItem("name").getNodeValue().trim();
Optional<CardInfo> cardInfo = lookup.lookupCardInfo(name);
if (cardInfo.isPresent()) {
CardInfo info = cardInfo.get();
return Collections.nCopies(
getQuantityFromNode(node),
new DeckCardInfo(info.getName(), info.getCardNumber(), info.getSetCode())).stream();
} else {
errors.append("Could not find card: '").append(name).append("'\n");
return Stream.empty();
}
};
}
private static Function<Node, Stream<DeckCardInfo>> toDeckCardInfo(CardLookup lookup, StringBuilder errors) {
return node -> {
String name = node.getAttributes().getNamedItem("name").getNodeValue().trim();
Optional<CardInfo> cardInfo = lookup.lookupCardInfo(name);
if (cardInfo.isPresent()) {
CardInfo info = cardInfo.get();
return Collections.nCopies(
getQuantityFromNode(node),
new DeckCardInfo(info.getName(), info.getCardNumber(), info.getSetCode())).stream();
} else {
errors.append("Could not find card: '").append(name).append("'\n");
return Stream.empty();
}
};
}
}

View file

@ -7,11 +7,15 @@ import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Original xmage's deck format (uses by deck editor)
*
* @author North
*/
public class DckDeckImporter extends PlainTextDeckImporter {
@ -24,13 +28,25 @@ public class DckDeckImporter extends PlainTextDeckImporter {
private static final Pattern layoutStackEntryPattern = Pattern.compile("\\[(\\w+[^:]*\\w*):(\\w+\\w*)]"); // test cases: [JR:64ab],[JR:64],[MPSAK1321:43],[MPSAKH:9],[MPS123-AKH:32],[MPS-13AKH:30],[MPS-AKH:49],[MPS-AKH:11], [PUMA:U16]
// possible fixes for card numbers: [code:123] -> [code:456]
// possible fixes for card numbers with name: [code:123] card1 -> [code:456] card2
private final Map<String, String> possibleFixes = new LinkedHashMap<>();
@Override
protected void readLine(String line, DeckCardLists deckList) {
protected void readLine(String line, DeckCardLists deckList, FixedInfo fixedInfo) {
if (line.isEmpty() || line.startsWith("#")) {
return;
}
// AUTO-FIX apply (if card number was fixed before then it can be replaced in layout or other lines too)
for (Map.Entry<String, String> fix : this.possibleFixes.entrySet()) {
if (line.contains(fix.getKey())) {
line = line.replace(fix.getKey(), fix.getValue());
}
}
fixedInfo.setFixedLine(line);
Matcher m = pattern.matcher(line);
if (m.matches()) {
boolean sideboard = false;
@ -46,13 +62,22 @@ public class DckDeckImporter extends PlainTextDeckImporter {
setCode = setCode == null ? "" : setCode.trim();
cardName = cardName == null ? "" : cardName.trim();
// search priority: set/code -> name
// text for auto-fix (don't work on extra spaces between numbers and name -- it's ok)
String originalNumbers = "";
String originalNumbersWithName = "";
if (!setCode.isEmpty() && !cardNum.isEmpty()) {
// [ISD:144] card_name
originalNumbers = "[" + setCode + ":" + cardNum + "]";
originalNumbersWithName = originalNumbers + " " + cardName;
}
// search priority: set/number -> name
// with bulletproof on card number or name changes
DeckCardInfo deckCardInfo = null;
// search by number
CardInfo foundedCard = CardRepository.instance.findCard(setCode, cardNum);
// search by set/number
CardInfo foundedCard = CardRepository.instance.findCard(setCode, cardNum, true);
boolean wasOutdated = false;
if ((foundedCard != null) && !foundedCard.getName().equals(cardName)) {
sbMessage.append("Line ").append(lineCount).append(": ").append("found outdated card number or name, will try to replace: ").append(line).append('\n');
@ -63,7 +88,7 @@ public class DckDeckImporter extends PlainTextDeckImporter {
// search by name
if (foundedCard == null) {
if (!wasOutdated) {
sbMessage.append("Line ").append(lineCount).append(": ").append("can't find card by number, will try ro replace: ").append(line).append('\n');
sbMessage.append("Line ").append(lineCount).append(": ").append("can't find card by number, will try to replace: ").append(line).append('\n');
}
if (!cardName.equals("")) {
@ -71,9 +96,24 @@ public class DckDeckImporter extends PlainTextDeckImporter {
}
if (foundedCard != null) {
sbMessage.append("Line ").append(lineCount).append(": ")
.append("replaced to [").append(foundedCard.getSetCode()).append(":").append(foundedCard.getCardNumberAsInt()).append("] ")
.append(foundedCard.getName()).append('\n');
if (foundedCard.isNightCard()) {
sbMessage.append("Line ").append(lineCount).append(": ").append("ERROR, you can't use night card in deck [").append(foundedCard.getName()).append("]").append('\n');
} else {
sbMessage.append("Line ").append(lineCount).append(": ")
.append("replaced to [").append(foundedCard.getSetCode()).append(":").append(foundedCard.getCardNumberAsInt()).append("] ")
.append(foundedCard.getName()).append('\n');
// AUTO-FIX POSSIBLE (apply and save it for another lines like layout)
// [ISD:144] card
String fixNumbers = "[" + foundedCard.getSetCode() + ":" + foundedCard.getCardNumber() + "]";
String fixNumbersWithName = fixNumbers + " " + foundedCard.getName();
this.possibleFixes.put(originalNumbersWithName, fixNumbersWithName); // name fix must goes first
this.possibleFixes.put(originalNumbers, fixNumbers);
String fixedLine = fixedInfo.getOriginalLine()
.replace(originalNumbersWithName, fixNumbersWithName)
.replace(originalNumbers, fixNumbers);
fixedInfo.setFixedLine(fixedLine);
}
} else {
sbMessage.append("Line ").append(lineCount).append(": ").append("ERROR, can't find card [").append(cardName).append("]").append('\n');
}

View file

@ -1,21 +1,19 @@
package mage.cards.decks.importer;
import java.util.Optional;
import mage.cards.decks.DeckCardInfo;
import mage.cards.decks.DeckCardLists;
import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
import java.util.Optional;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class DecDeckImporter extends PlainTextDeckImporter {
@Override
protected void readLine(String line, DeckCardLists deckList) {
protected void readLine(String line, DeckCardLists deckList, FixedInfo fixedInfo) {
if (line.isEmpty() || line.startsWith("//")) {
return;
}

View file

@ -1,95 +1,122 @@
package mage.cards.decks.importer;
import mage.cards.decks.DeckCardLists;
import org.apache.log4j.Logger;
import java.io.File;
import java.util.Locale;
import java.util.Optional;
import java.util.Scanner;
import mage.cards.decks.DeckCardLists;
import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
public abstract class DeckImporter {
protected static final Logger logger = Logger.getLogger(DeckImporter.class);
public class FixedInfo {
private final String originalLine;
private String fixedLine;
private Boolean canFix = true; // set false if deck have critical error and can't be auto-fixed
private static final String[] SIDEBOARD_MARKS = new String[]{"//sideboard", "sb: "};
public static DeckImporter getDeckImporter(String file) {
if (file == null) {
return null;
} if (file.toLowerCase(Locale.ENGLISH).endsWith("dec")) {
return new DecDeckImporter();
} else if (file.toLowerCase(Locale.ENGLISH).endsWith("mwdeck")) {
return new MWSDeckImporter();
} else if (file.toLowerCase(Locale.ENGLISH).endsWith("txt")) {
return new TxtDeckImporter(haveSideboardSection(file));
} else if (file.toLowerCase(Locale.ENGLISH).endsWith("dck")) {
return new DckDeckImporter();
} else if (file.toLowerCase(Locale.ENGLISH).endsWith("dek")) {
return new DekDeckImporter();
} else if (file.toLowerCase(Locale.ENGLISH).endsWith("cod")) {
return new CodDeckImporter();
} else if (file.toLowerCase(Locale.ENGLISH).endsWith("o8d")) {
return new O8dDeckImporter();
} else if (file.toLowerCase(Locale.ENGLISH).endsWith("json")) {
return new MtgjsonDeckImporter();
} else if (file.toLowerCase(Locale.ENGLISH).endsWith("draft")) {
return new DraftLogImporter();
} else if (file.toLowerCase(Locale.ENGLISH).endsWith("mtga")) {
return new MtgaImporter();
} else {
return null;
}
}
public static DeckCardLists importDeckFromFile(String file) {
return importDeckFromFile(file, new StringBuilder());
}
public static DeckCardLists importDeckFromFile(String file, StringBuilder errorMessages) {
DeckImporter deckImporter = getDeckImporter(file);
if (deckImporter != null) {
return deckImporter.importDeck(file, errorMessages);
} else {
return new DeckCardLists();
}
}
public abstract DeckCardLists importDeck(String file, StringBuilder errorMessages);
public DeckCardLists importDeck(String file) {
return importDeck(file, new StringBuilder());
}
public CardLookup getCardLookup() {
return CardLookup.instance;
}
private static boolean haveSideboardSection(String file) {
// search for sideboard section:
// or //sideboard
// or SB: 1 card name -- special deckstats.net
File f = new File(file);
try (Scanner scanner = new Scanner(f)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim().toLowerCase(Locale.ENGLISH);
for (String mark : SIDEBOARD_MARKS) {
if (line.startsWith(mark)) {
return true;
}
FixedInfo(String originalLine) {
this.originalLine = originalLine;
this.fixedLine = originalLine;
}
public String getOriginalLine() {
return originalLine;
}
public Boolean getCanFix() {
return canFix;
}
public void setCanFix(Boolean canFix) {
this.canFix = canFix;
}
public String getFixedLine() {
return fixedLine;
}
public void setFixedLine(String fixedLine) {
this.fixedLine = fixedLine;
}
}
} catch (Exception e) {
// ignore error, deckimporter will process it
}
// not found
return false;
}
protected static final Logger logger = Logger.getLogger(DeckImporter.class);
private static final String[] SIDEBOARD_MARKS = new String[]{"//sideboard", "sb: "};
public static DeckImporter getDeckImporter(String file) {
if (file == null) {
return null;
}
if (file.toLowerCase(Locale.ENGLISH).endsWith("dec")) {
return new DecDeckImporter();
} else if (file.toLowerCase(Locale.ENGLISH).endsWith("mwdeck")) {
return new MWSDeckImporter();
} else if (file.toLowerCase(Locale.ENGLISH).endsWith("txt")) {
return new TxtDeckImporter(haveSideboardSection(file));
} else if (file.toLowerCase(Locale.ENGLISH).endsWith("dck")) {
return new DckDeckImporter();
} else if (file.toLowerCase(Locale.ENGLISH).endsWith("dek")) {
return new DekDeckImporter();
} else if (file.toLowerCase(Locale.ENGLISH).endsWith("cod")) {
return new CodDeckImporter();
} else if (file.toLowerCase(Locale.ENGLISH).endsWith("o8d")) {
return new O8dDeckImporter();
} else if (file.toLowerCase(Locale.ENGLISH).endsWith("json")) {
return new MtgjsonDeckImporter();
} else if (file.toLowerCase(Locale.ENGLISH).endsWith("draft")) {
return new DraftLogImporter();
} else if (file.toLowerCase(Locale.ENGLISH).endsWith("mtga")) {
return new MtgaImporter();
} else {
return null;
}
}
public static DeckCardLists importDeckFromFile(String file, boolean saveAutoFixedFile) {
return importDeckFromFile(file, new StringBuilder(), saveAutoFixedFile);
}
public static DeckCardLists importDeckFromFile(String file, StringBuilder errorMessages, boolean saveAutoFixedFile) {
DeckImporter deckImporter = getDeckImporter(file);
if (deckImporter != null) {
return deckImporter.importDeck(file, errorMessages, saveAutoFixedFile);
} else {
return new DeckCardLists();
}
}
public abstract DeckCardLists importDeck(String file, StringBuilder errorMessages, boolean saveAutoFixedFile);
public DeckCardLists importDeck(String file, boolean saveAutoFixedFile) {
return importDeck(file, new StringBuilder(), saveAutoFixedFile);
}
public CardLookup getCardLookup() {
return CardLookup.instance;
}
private static boolean haveSideboardSection(String file) {
// search for sideboard section:
// or //sideboard
// or SB: 1 card name -- special deckstats.net
File f = new File(file);
try (Scanner scanner = new Scanner(f)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim().toLowerCase(Locale.ENGLISH);
for (String mark : SIDEBOARD_MARKS) {
if (line.startsWith(mark)) {
return true;
}
}
}
} catch (Exception e) {
// ignore error, deckimporter will process it
}
// not found
return false;
}
}

View file

@ -11,7 +11,7 @@ import mage.cards.repository.CardRepository;
public class DekDeckImporter extends PlainTextDeckImporter {
@Override
protected void readLine(String line, DeckCardLists deckList) {
protected void readLine(String line, DeckCardLists deckList, FixedInfo fixedInfo) {
if (line.isEmpty() || line.startsWith("#") || !line.contains("<Cards CatID")) {
return;
@ -27,24 +27,24 @@ public class DekDeckImporter extends PlainTextDeckImporter {
} else {
for (int i = 0; i < cardCount; i++) {
DeckCardInfo deckCardInfo = new DeckCardInfo(cardInfo.getName(), cardInfo.getCardNumber(), cardInfo.getSetCode());
if(isSideboard) {
if (isSideboard) {
deckList.getSideboard().add(deckCardInfo);
} else {
deckList.getCards().add(deckCardInfo);
}
}
}
}catch (NumberFormatException nfe) {
} catch (NumberFormatException nfe) {
sbMessage.append("Invalid number: ").append(extractAttribute(line, "Quantity")).append(" at line ").append(lineCount).append('\n');
}
}
private String extractAttribute(String line, String name) {
String searchString = name+"=\"";
int startDelim = line.indexOf(searchString)+searchString.length();
String searchString = name + "=\"";
int startDelim = line.indexOf(searchString) + searchString.length();
int endDelim = line.substring(startDelim).indexOf('\"');
return line.substring(startDelim, startDelim+endDelim);
return line.substring(startDelim, startDelim + endDelim);
}
}

View file

@ -11,13 +11,14 @@ import java.util.regex.Pattern;
public class DraftLogImporter extends PlainTextDeckImporter {
private static Pattern SET_PATTERN = Pattern.compile("------ (\\p{Alnum}+) ------$");
private static Pattern PICK_PATTERN = Pattern.compile("--> (.+)$");
private static final Pattern SET_PATTERN = Pattern.compile("------ (\\p{Alnum}+) ------$");
private static final Pattern PICK_PATTERN = Pattern.compile("--> (.+)$");
private String currentSet = null;
@Override
protected void readLine(String line, DeckCardLists deckList) {
protected void readLine(String line, DeckCardLists deckList, FixedInfo fixedInfo) {
Matcher setMatcher = SET_PATTERN.matcher(line);
if (setMatcher.matches()) {
currentSet = setMatcher.group(1);

View file

@ -1,14 +1,12 @@
package mage.cards.decks.importer;
import java.io.File;
import java.io.FileReader;
import org.json.simple.JSONArray;
import mage.cards.decks.DeckCardLists;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import mage.cards.decks.DeckCardLists;
import java.io.File;
import java.io.FileReader;
/**
* @author github: timhae
@ -18,12 +16,12 @@ public abstract class JsonDeckImporter extends DeckImporter {
protected StringBuilder sbMessage = new StringBuilder();
/**
*
* @param file file to import
* @param errorMessages you can setup output messages to showup to user
* @param file file to import
* @param errorMessages you can setup output messages to showup to user
* @param saveAutoFixedFile do not supported for that format
* @return decks list
*/
public DeckCardLists importDeck(String file, StringBuilder errorMessages) {
public DeckCardLists importDeck(String file, StringBuilder errorMessages, boolean saveAutoFixedFile) {
File f = new File(file);
DeckCardLists deckList = new DeckCardLists();
if (!f.exists()) {
@ -62,8 +60,8 @@ public abstract class JsonDeckImporter extends DeckImporter {
}
@Override
public DeckCardLists importDeck(String file) {
return importDeck(file, null);
public DeckCardLists importDeck(String file, boolean saveAutoFixedFile) {
return importDeck(file, null, saveAutoFixedFile);
}
protected abstract void readJson(JSONObject line, DeckCardLists decklist);

View file

@ -1,23 +1,21 @@
package mage.cards.decks.importer;
import java.util.List;
import mage.cards.decks.DeckCardInfo;
import mage.cards.decks.DeckCardLists;
import mage.cards.repository.CardCriteria;
import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
import mage.util.RandomUtil;
import java.util.List;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class MWSDeckImporter extends PlainTextDeckImporter {
@Override
protected void readLine(String line, DeckCardLists deckList) {
protected void readLine(String line, DeckCardLists deckList, FixedInfo fixedInfo) {
if (line.isEmpty() || line.startsWith("//")) {
return;
}
@ -47,7 +45,7 @@ public class MWSDeckImporter extends PlainTextDeckImporter {
if (!cards.isEmpty()) {
cardInfo = cards.get(RandomUtil.nextInt(cards.size()));
}
}
}
if (cardInfo == null) {
cardInfo = getCardLookup().lookupCardInfo(lineName).orElse(null);
}

View file

@ -4,7 +4,6 @@ import com.google.common.collect.ImmutableMap;
import mage.cards.decks.CardNameUtil;
import mage.cards.decks.DeckCardInfo;
import mage.cards.decks.DeckCardLists;
import mage.cards.repository.CardCriteria;
import mage.cards.repository.CardInfo;
import java.util.Collections;
@ -21,18 +20,19 @@ public class MtgaImporter extends PlainTextDeckImporter {
private static final Map<String, String> SET_REMAPPING = ImmutableMap.of("DAR", "DOM");
private static final Pattern MTGA_PATTERN = Pattern.compile(
"(\\p{Digit}+)" +
"\\p{javaWhitespace}+" +
"(" + CARD_NAME_PATTERN.pattern() + ")" +
"\\p{javaWhitespace}+" +
"\\((\\p{Alnum}+)\\)" +
"\\p{javaWhitespace}+" +
"(\\p{Digit}+)");
"\\p{javaWhitespace}+" +
"(" + CARD_NAME_PATTERN.pattern() + ")" +
"\\p{javaWhitespace}+" +
"\\((\\p{Alnum}+)\\)" +
"\\p{javaWhitespace}+" +
"(\\p{Digit}+)");
private final CardLookup lookup = getCardLookup();
private boolean sideboard = false;
@Override
protected void readLine(String line, DeckCardLists deckList) {
protected void readLine(String line, DeckCardLists deckList, FixedInfo fixedInfo) {
if (line.trim().equals("")) {
sideboard = true;
return;

View file

@ -1,5 +1,11 @@
package mage.cards.decks.importer;
import mage.cards.decks.DeckCardInfo;
import mage.cards.decks.DeckCardLists;
import mage.cards.repository.CardInfo;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
@ -7,65 +13,64 @@ import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import mage.cards.decks.DeckCardInfo;
import mage.cards.decks.DeckCardLists;
import mage.cards.repository.CardInfo;
public class O8dDeckImporter extends XmlDeckImporter {
@Override
public DeckCardLists importDeck(String filename, StringBuilder errorMessages) {
try {
Document doc = getXmlDocument(filename);
DeckCardLists decklist = new DeckCardLists();
/**
* @param filename
* @param errorMessages
* @param saveAutoFixedFile do not supported for current format
* @return
*/
@Override
public DeckCardLists importDeck(String filename, StringBuilder errorMessages, boolean saveAutoFixedFile) {
try {
Document doc = getXmlDocument(filename);
DeckCardLists decklist = new DeckCardLists();
List<Node> mainCards = getNodes(doc, "/deck/section[@name='Main']/card");
decklist.setCards(mainCards.stream()
.flatMap(toDeckCardInfo(getCardLookup(), errorMessages))
.collect(Collectors.toList()));
List<Node> mainCards = getNodes(doc, "/deck/section[@name='Main']/card");
decklist.setCards(mainCards.stream()
.flatMap(toDeckCardInfo(getCardLookup(), errorMessages))
.collect(Collectors.toList()));
List<Node> sideboardCards = getNodes(doc, "/deck/section[@name='Sideboard']/card");
decklist.setSideboard(sideboardCards.stream()
.flatMap(toDeckCardInfo(getCardLookup(), errorMessages))
.collect(Collectors.toList()));
List<Node> sideboardCards = getNodes(doc, "/deck/section[@name='Sideboard']/card");
decklist.setSideboard(sideboardCards.stream()
.flatMap(toDeckCardInfo(getCardLookup(), errorMessages))
.collect(Collectors.toList()));
return decklist;
} catch (Exception e) {
logger.error("Error loading deck", e);
errorMessages.append("There was an error loading the deck.");
return new DeckCardLists();
return decklist;
} catch (Exception e) {
logger.error("Error loading deck", e);
errorMessages.append("There was an error loading the deck.");
return new DeckCardLists();
}
}
}
private static int getQuantityFromNode(Node node) {
Node numberNode = node.getAttributes().getNamedItem("qty");
if (numberNode == null) {
return 1;
private static int getQuantityFromNode(Node node) {
Node numberNode = node.getAttributes().getNamedItem("qty");
if (numberNode == null) {
return 1;
}
try {
return Math.min(100, Math.max(1, Integer.parseInt(numberNode.getNodeValue())));
} catch (NumberFormatException e) {
return 1;
}
}
try {
return Math.min(100, Math.max(1, Integer.parseInt(numberNode.getNodeValue())));
} catch (NumberFormatException e) {
return 1;
}
}
private static Function<Node, Stream<DeckCardInfo>> toDeckCardInfo(CardLookup lookup, StringBuilder errors) {
return node -> {
String name = node.getTextContent();
Optional<CardInfo> cardInfo = lookup.lookupCardInfo(name);
if (cardInfo.isPresent()) {
CardInfo info = cardInfo.get();
return Collections.nCopies(
getQuantityFromNode(node),
new DeckCardInfo(info.getName(), info.getCardNumber(), info.getSetCode())).stream();
} else {
errors.append("Could not find card: '").append(name).append("'\n");
return Stream.empty();
}
};
}
private static Function<Node, Stream<DeckCardInfo>> toDeckCardInfo(CardLookup lookup, StringBuilder errors) {
return node -> {
String name = node.getTextContent();
Optional<CardInfo> cardInfo = lookup.lookupCardInfo(name);
if (cardInfo.isPresent()) {
CardInfo info = cardInfo.get();
return Collections.nCopies(
getQuantityFromNode(node),
new DeckCardInfo(info.getName(), info.getCardNumber(), info.getSetCode())).stream();
} else {
errors.append("Could not find card: '").append(name).append("'\n");
return Stream.empty();
}
};
}
}

View file

@ -1,14 +1,15 @@
package mage.cards.decks.importer;
import java.io.File;
import java.util.Scanner;
import mage.cards.decks.DeckCardLists;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public abstract class PlainTextDeckImporter extends DeckImporter {
@ -18,13 +19,17 @@ public abstract class PlainTextDeckImporter extends DeckImporter {
/**
* Import deck from text file
*
* @param file file to import
* @param errorMessages you can setup output messages to showup to user (set null for fatal exception on messages.count > 0)
* @param file file to import
* @param errorMessages you can setup output messages to showup to user (set null for fatal exception on messages.count > 0)
* @param saveAutoFixedFile save fixed deck file (if any fixes applied)
* @return decks list
*/
public DeckCardLists importDeck(String file, StringBuilder errorMessages) {
public DeckCardLists importDeck(String file, StringBuilder errorMessages, boolean saveAutoFixedFile) {
File f = new File(file);
List<String> originalFile = new ArrayList<>();
List<String> fixedFile = new ArrayList<>();
DeckCardLists deckList = new DeckCardLists();
if (!f.exists()) {
logger.warn("Deckfile " + file + " not found.");
@ -35,17 +40,33 @@ public abstract class PlainTextDeckImporter extends DeckImporter {
sbMessage.setLength(0);
try {
try (Scanner scanner = new Scanner(f)) {
Boolean canFix = true;
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
FixedInfo fixedInfo = new FixedInfo(line);
lineCount++;
readLine(line, deckList);
readLine(line, deckList, fixedInfo);
originalFile.add(line);
fixedFile.add(fixedInfo.getFixedLine());
canFix = canFix && fixedInfo.getCanFix();
}
// auto-fix
if (saveAutoFixedFile && canFix && !originalFile.equals(fixedFile)) {
logger.warn("WARNING, deck file contains errors, try to apply auto-fix and save: " + f.getAbsolutePath());
saveFixedDeckFile(fixedFile, f);
}
if (deckList.getCards().isEmpty() && deckList.getSideboard().isEmpty()) {
sbMessage.append("ERROR, unknown deck format, can't find any cards").append("\n");
}
if (sbMessage.length() > 0) {
if(errorMessages != null) {
if (errorMessages != null) {
// normal output for user
errorMessages.append(sbMessage);
}else{
} else {
// fatal error
logger.fatal(sbMessage);
}
@ -59,11 +80,30 @@ public abstract class PlainTextDeckImporter extends DeckImporter {
return deckList;
}
@Override
public DeckCardLists importDeck(String file) {
return importDeck(file, null);
private void saveFixedDeckFile(List<String> fixedfile, File file) {
try (FileOutputStream stream = new FileOutputStream(file)) {
PrintWriter out = new PrintWriter(stream);
for (String line : fixedfile) {
out.println(line);
}
out.close();
} catch (Exception e) {
logger.error("Can't save fixed deck file: " + file.getAbsolutePath() + ", reason: " + e.getMessage());
}
}
protected abstract void readLine(String line, DeckCardLists deckList);
@Override
public DeckCardLists importDeck(String file, boolean saveAutoFixedFile) {
return importDeck(file, null, saveAutoFixedFile);
}
/**
* Read one text line from file and convert it to card
*
* @param line original text line
* @param deckList deck list for new card
* @param fixedInfo fixed info that contains fixed line (if converter can auto-fix deck file, e.g. replace one card to another)
*/
protected abstract void readLine(String line, DeckCardLists deckList, FixedInfo fixedInfo);
}

View file

@ -31,7 +31,7 @@ public class TxtDeckImporter extends PlainTextDeckImporter {
}
@Override
protected void readLine(String line, DeckCardLists deckList) {
protected void readLine(String line, DeckCardLists deckList, FixedInfo fixedInfo) {
line = line.trim();

View file

@ -39,7 +39,7 @@ public enum CardRepository {
private static final long CARD_CONTENT_VERSION = 231;
private Dao<CardInfo, Object> cardDao;
private Set<String> classNames;
private RepositoryEventSource eventSource = new RepositoryEventSource();
private final RepositoryEventSource eventSource = new RepositoryEventSource();
CardRepository() {
File file = new File("db");
@ -180,6 +180,7 @@ public enum CardRepository {
public Boolean haveSnowLands(String setCode) {
return setCode.equals("CSP")
|| setCode.equals("MH1")
|| setCode.equals("SLD")
|| setCode.equals("ME2")
|| setCode.equals("ICE");
}
@ -334,11 +335,22 @@ public enum CardRepository {
}
public CardInfo findCard(String setCode, String cardNumber) {
return findCard(setCode, cardNumber, true);
}
public CardInfo findCard(String setCode, String cardNumber, boolean ignoreNightCards) {
try {
QueryBuilder<CardInfo, Object> queryBuilder = cardDao.queryBuilder();
queryBuilder.limit(1L).where().eq("setCode", new SelectArg(setCode))
.and().eq("cardNumber", new SelectArg(cardNumber))
.and().eq("nightCard", new SelectArg(false));
if (ignoreNightCards) {
queryBuilder.limit(1L).where()
.eq("setCode", new SelectArg(setCode))
.and().eq("cardNumber", new SelectArg(cardNumber))
.and().eq("nightCard", new SelectArg(false));
} else {
queryBuilder.limit(1L).where()
.eq("setCode", new SelectArg(setCode))
.and().eq("cardNumber", new SelectArg(cardNumber));
}
List<CardInfo> result = cardDao.query(queryBuilder.prepare());
if (!result.isEmpty()) {
return result.get(0);

View file

@ -35,7 +35,7 @@ public final class BeastToken extends TokenImpl {
if (getOriginalExpansionSetCode() != null && getOriginalExpansionSetCode().equals("CMD")) {
this.setTokenType(2);
}
if (getOriginalExpansionSetCode() != null && getOriginalExpansionSetCode().equals("DD3GVL")) {
if (getOriginalExpansionSetCode() != null && getOriginalExpansionSetCode().equals("GVL")) {
this.setTokenType(2);
}

View file

@ -16,7 +16,7 @@ public final class BeastToken2 extends TokenImpl {
static final private List<String> tokenImageSets = new ArrayList<>();
static {
tokenImageSets.addAll(Arrays.asList("ZEN", "C14", "DDD", "C15", "DD3GVL", "MM3", "CMA", "E01", "C19", "C20"));
tokenImageSets.addAll(Arrays.asList("ZEN", "C14", "DDD", "C15", "GVL", "MM3", "CMA", "E01", "C19", "C20"));
}
public BeastToken2() {
@ -50,7 +50,7 @@ public final class BeastToken2 extends TokenImpl {
@Override
public void setExpansionSetCodeForImage(String code) {
super.setExpansionSetCodeForImage(code);
if (getOriginalExpansionSetCode().equals("C14") || getOriginalExpansionSetCode().equals("DDD") || getOriginalExpansionSetCode().equals("DD3GVL") || getOriginalExpansionSetCode().equals("MM3")) {
if (getOriginalExpansionSetCode().equals("C14") || getOriginalExpansionSetCode().equals("DDD") || getOriginalExpansionSetCode().equals("GVL") || getOriginalExpansionSetCode().equals("MM3")) {
this.setTokenType(2);
}
}

View file

@ -19,7 +19,7 @@ public final class CatToken extends TokenImpl {
power = new MageInt(2);
toughness = new MageInt(2);
availableImageSetCodes = Arrays.asList("MBP", "C14", "C15", "C17", "C18", "M13", "M14", "MBS", "SOM");
availableImageSetCodes = Arrays.asList("PMEI", "C14", "C15", "C17", "C18", "M13", "M14", "MBS", "SOM");
}
public CatToken(final CatToken token) {

View file

@ -18,7 +18,7 @@ public final class ElementalShamanToken extends TokenImpl {
static final private List<String> tokenImageSets = new ArrayList<>();
static {
tokenImageSets.addAll(Arrays.asList("C15", "DD3JVC", "DD2", "LRW"));
tokenImageSets.addAll(Arrays.asList("C15", "JVC", "DD2", "LRW"));
}
public ElementalShamanToken(boolean withHaste) {

View file

@ -21,7 +21,7 @@ public final class ElementalTokenWithHaste extends TokenImpl {
toughness = new MageInt(1);
this.addAbility(HasteAbility.getInstance());
availableImageSetCodes = Arrays.asList("C20", "MBP", "OGW", "SOK", "MRD");
availableImageSetCodes = Arrays.asList("C20", "PMEI", "OGW", "SOK", "MRD");
}
public ElementalTokenWithHaste(final ElementalTokenWithHaste token) {

View file

@ -16,7 +16,7 @@ public final class ElephantToken extends TokenImpl {
static final private List<String> tokenImageSets = new ArrayList<>();
static {
tokenImageSets.addAll(Arrays.asList("C14", "CNS", "DDD", "MM2", "WWK", "OGW", "C15", "DD3GVL", "MM3", "CMA", "MH1"));
tokenImageSets.addAll(Arrays.asList("C14", "CNS", "DDD", "MM2", "WWK", "OGW", "C15", "GVL", "MM3", "CMA", "MH1"));
}
public ElephantToken() {

View file

@ -18,7 +18,7 @@ public final class GoblinToken extends TokenImpl {
static {
tokenImageSets.addAll(Arrays.asList("10E", "ALA", "SOM", "M10", "NPH", "M13", "RTR",
"MMA", "M15", "C14", "KTK", "EVG", "DTK", "ORI", "DDG", "DDN", "DD3EVG", "MM2",
"MMA", "M15", "C14", "KTK", "EVG", "DTK", "ORI", "DDG", "DDN", "EVG", "MM2",
"MM3", "EMA", "C16", "DOM", "ANA", "RNA", "WAR", "MH1"));
}

View file

@ -1,40 +1,39 @@
package mage.cards.decks.importer;
import mage.cards.decks.DeckCardLists;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import mage.cards.decks.DeckCardLists;
public class CodDeckImportTest {
private static final FakeCardLookup LOOKUP = new FakeCardLookup(false)
.addCard("Forest")
.addCard("Razorverge Thicket")
.addCard("Avacyn's Pilgrim")
.addCard("War Priest of Thune");
private static final FakeCardLookup LOOKUP = new FakeCardLookup(false)
.addCard("Forest")
.addCard("Razorverge Thicket")
.addCard("Avacyn's Pilgrim")
.addCard("War Priest of Thune");
@Test
public void testImport() {
CodDeckImporter importer = new CodDeckImporter() {
@Override
public CardLookup getCardLookup() {
return LOOKUP;
}
};
StringBuilder errors = new StringBuilder();
DeckCardLists deck = importer.importDeck(
"src/test/java/mage/cards/decks/importer/samples/testdeck.cod", errors);
assertEquals("Deck Name", deck.getName());
@Test
public void testImport() {
CodDeckImporter importer = new CodDeckImporter() {
@Override
public CardLookup getCardLookup() {
return LOOKUP;
}
};
StringBuilder errors = new StringBuilder();
DeckCardLists deck = importer.importDeck(
"src/test/java/mage/cards/decks/importer/samples/testdeck.cod", errors, false);
assertEquals("Deck Name", deck.getName());
TestDeckChecker.checker()
.addMain("Forest", 12)
.addMain("Razorverge Thicket", 100)
.addMain("Avacyn's Pilgrim", 1)
.addSide("War Priest of Thune", 3)
.verify(deck, 113, 3);
TestDeckChecker.checker()
.addMain("Forest", 12)
.addMain("Razorverge Thicket", 100)
.addMain("Avacyn's Pilgrim", 1)
.addSide("War Priest of Thune", 3)
.verify(deck, 113, 3);
assertEquals("Could not find card: '@#$NOT A REAL CARD NAME@#$'\n", errors.toString());
}
assertEquals("Could not find card: '@#$NOT A REAL CARD NAME@#$'\n", errors.toString());
}
}

View file

@ -1,52 +1,51 @@
package mage.cards.decks.importer;
import mage.cards.decks.DeckCardLists;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import mage.cards.decks.DeckCardLists;
public class DecDeckImportTest {
private static final FakeCardLookup LOOKUP = new FakeCardLookup();
private static final FakeCardLookup LOOKUP = new FakeCardLookup();
@Test
public void testImport() {
StringBuilder errors = new StringBuilder();
DecDeckImporter importer = new DecDeckImporter() {
@Override
public CardLookup getCardLookup() {
return LOOKUP;
}
};
DeckCardLists deck = importer.importDeck(
"src/test/java/mage/cards/decks/importer/samples/testdeck.dec", errors);
@Test
public void testImport() {
StringBuilder errors = new StringBuilder();
DecDeckImporter importer = new DecDeckImporter() {
@Override
public CardLookup getCardLookup() {
return LOOKUP;
}
};
DeckCardLists deck = importer.importDeck(
"src/test/java/mage/cards/decks/importer/samples/testdeck.dec", errors, false);
TestDeckChecker.checker()
.addMain("Masticore", 4)
.addMain("Metalworker", 4)
.addMain("Phyrexian Colossus", 1)
.addMain("Crumbling Sanctuary", 1)
.addMain("Grim Monolith", 4)
.addMain("Mishra's Helix", 1)
.addMain("Phyrexian Processor", 4)
.addMain("Tangle Wire", 4)
.addMain("Thran Dynamo", 4)
.addMain("Voltaic Key", 4)
.addMain("Tinker", 4)
.addMain("Brainstorm", 4)
.addMain("Crystal Vein", 4)
.addMain("Island", 9)
.addMain("Rishadan Port", 4)
.addMain("Saprazzan Skerry", 4)
.addSide("Annul", 4)
.addSide("Chill", 4)
.addSide("Miscalculation", 4)
.addSide("Mishra's Helix", 1)
.addSide("Rising Waters", 2)
.verify(deck, 60, 15);
TestDeckChecker.checker()
.addMain("Masticore", 4)
.addMain("Metalworker", 4)
.addMain("Phyrexian Colossus", 1)
.addMain("Crumbling Sanctuary", 1)
.addMain("Grim Monolith", 4)
.addMain("Mishra's Helix", 1)
.addMain("Phyrexian Processor", 4)
.addMain("Tangle Wire", 4)
.addMain("Thran Dynamo", 4)
.addMain("Voltaic Key", 4)
.addMain("Tinker", 4)
.addMain("Brainstorm", 4)
.addMain("Crystal Vein", 4)
.addMain("Island", 9)
.addMain("Rishadan Port", 4)
.addMain("Saprazzan Skerry", 4)
.addSide("Annul", 4)
.addSide("Chill", 4)
.addSide("Miscalculation", 4)
.addSide("Mishra's Helix", 1)
.addSide("Rising Waters", 2)
.verify(deck, 60, 15);
assertEquals("", errors.toString());
}
assertEquals("", errors.toString());
}
}

View file

@ -3,7 +3,7 @@ package mage.cards.decks.importer;
import mage.cards.decks.DeckCardLists;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
public class DraftLogImporterTest {
@ -19,7 +19,7 @@ public class DraftLogImporterTest {
}
};
DeckCardLists deck = importer.importDeck(
"src/test/java/mage/cards/decks/importer/samples/testdeck.draft", errors);
"src/test/java/mage/cards/decks/importer/samples/testdeck.draft", errors, false);
TestDeckChecker.checker()
.addMain("Raging Ravine", 1)

View file

@ -3,9 +3,7 @@ package mage.cards.decks.importer;
import mage.cards.decks.DeckCardLists;
import org.junit.Test;
import java.io.File;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
public class MtgaImporterTest {
@ -21,7 +19,7 @@ public class MtgaImporterTest {
};
StringBuilder errors = new StringBuilder();
DeckCardLists deck = importer.importDeck(
"src/test/java/mage/cards/decks/importer/samples/testdeck.mtga", errors);
"src/test/java/mage/cards/decks/importer/samples/testdeck.mtga", errors, false);
TestDeckChecker.checker()
.addMain("Niv-Mizzet Reborn", 1)

View file

@ -1,57 +1,56 @@
package mage.cards.decks.importer;
import mage.cards.decks.DeckCardLists;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import mage.cards.decks.DeckCardLists;
public class MtgjsonDeckImportTest {
private static final FakeCardLookup LOOKUP = new FakeCardLookup();
private static final FakeCardLookup LOOKUP = new FakeCardLookup();
@Test
public void testImport() {
StringBuilder errors = new StringBuilder();
MtgjsonDeckImporter importer = new MtgjsonDeckImporter() {
@Override
public CardLookup getCardLookup() {
return LOOKUP;
}
};
DeckCardLists deck = importer.importDeck(
"src/test/java/mage/cards/decks/importer/samples/testdeck.json", errors);
assertEquals("Arcane Tempo", deck.getName());
@Test
public void testImport() {
StringBuilder errors = new StringBuilder();
MtgjsonDeckImporter importer = new MtgjsonDeckImporter() {
@Override
public CardLookup getCardLookup() {
return LOOKUP;
}
};
DeckCardLists deck = importer.importDeck(
"src/test/java/mage/cards/decks/importer/samples/testdeck.json", errors, false);
assertEquals("Arcane Tempo", deck.getName());
TestDeckChecker.checker()
.addMain("Goblin Electromancer", 4)
.addMain("Crackling Drake", 4)
.addMain("Murmuring Mystic", 2)
.addMain("Arclight Phoenix", 1)
.addMain("Niv-Mizzet, Parun", 2)
.addMain("Chart a Course", 4)
.addMain("Lava Coil", 4)
.addMain("Beacon Bolt", 1)
.addMain("Opt", 4)
.addMain("Radical Idea", 4)
.addMain("Shock", 4)
.addMain("Dive Down", 2)
.addMain("Blink of an Eye", 1)
.addMain("The Mirari Conjecture", 1)
.addMain("Sulfur Falls", 3)
.addMain("Izzet Guildgate", 4)
.addMain("Island", 8)
.addMain("Mountain", 7)
.addSide("The Mirari Conjecture", 1)
.addSide("Beacon Bolt", 1)
.addSide("Negate", 3)
.addSide("Entrancing Melody", 3)
.addSide("Fiery Cannonade", 3)
.addSide("Shivan Fire", 2)
.addSide("Disdainful Stroke", 2)
.verify(deck, 60, 15);
TestDeckChecker.checker()
.addMain("Goblin Electromancer", 4)
.addMain("Crackling Drake", 4)
.addMain("Murmuring Mystic", 2)
.addMain("Arclight Phoenix", 1)
.addMain("Niv-Mizzet, Parun", 2)
.addMain("Chart a Course", 4)
.addMain("Lava Coil", 4)
.addMain("Beacon Bolt", 1)
.addMain("Opt", 4)
.addMain("Radical Idea", 4)
.addMain("Shock", 4)
.addMain("Dive Down", 2)
.addMain("Blink of an Eye", 1)
.addMain("The Mirari Conjecture", 1)
.addMain("Sulfur Falls", 3)
.addMain("Izzet Guildgate", 4)
.addMain("Island", 8)
.addMain("Mountain", 7)
.addSide("The Mirari Conjecture", 1)
.addSide("Beacon Bolt", 1)
.addSide("Negate", 3)
.addSide("Entrancing Melody", 3)
.addSide("Fiery Cannonade", 3)
.addSide("Shivan Fire", 2)
.addSide("Disdainful Stroke", 2)
.verify(deck, 60, 15);
assertEquals("", errors.toString());
}
assertEquals("", errors.toString());
}
}

View file

@ -1,57 +1,51 @@
package mage.cards.decks.importer;
import mage.cards.decks.DeckCardLists;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
import mage.cards.decks.DeckCardLists;
import mage.cards.repository.CardCriteria;
import mage.cards.repository.CardInfo;
public class MwsDeckImportTest {
private static final FakeCardLookup LOOKUP = new FakeCardLookup();
private static final FakeCardLookup LOOKUP = new FakeCardLookup();
@Test
public void testImport() {
MWSDeckImporter importer = new MWSDeckImporter() {
@Override
public CardLookup getCardLookup() {
return LOOKUP;
}
};
StringBuilder errors = new StringBuilder();
DeckCardLists deck = importer.importDeck(
"src/test/java/mage/cards/decks/importer/samples/testdeck.mwDeck", errors);
@Test
public void testImport() {
MWSDeckImporter importer = new MWSDeckImporter() {
@Override
public CardLookup getCardLookup() {
return LOOKUP;
}
};
StringBuilder errors = new StringBuilder();
DeckCardLists deck = importer.importDeck(
"src/test/java/mage/cards/decks/importer/samples/testdeck.mwDeck", errors, false);
TestDeckChecker.checker()
.addMain("Mutavault", 4)
.addMain("Plains", 18)
.addMain("Daring Skyjek", 2)
.addMain("Azorius Arrester", 4)
.addMain("Banisher Priest", 4)
.addMain("Boros Elite", 4)
.addMain("Dryad Militant", 4)
.addMain("Imposing Sovereign", 4)
.addMain("Precinct Captain", 4)
.addMain("Soldier of the Pantheon", 4)
.addMain("Spear of Heliod", 3)
.addMain("Rootborn Defenses", 1)
.addMain("Brave the Elements", 4)
TestDeckChecker.checker()
.addMain("Mutavault", 4)
.addMain("Plains", 18)
.addMain("Daring Skyjek", 2)
.addMain("Azorius Arrester", 4)
.addMain("Banisher Priest", 4)
.addMain("Boros Elite", 4)
.addMain("Dryad Militant", 4)
.addMain("Imposing Sovereign", 4)
.addMain("Precinct Captain", 4)
.addMain("Soldier of the Pantheon", 4)
.addMain("Spear of Heliod", 3)
.addMain("Rootborn Defenses", 1)
.addMain("Brave the Elements", 4)
.addSide("Wear/Tear", 1)
.addSide("Glare of Heresy", 2)
.addSide("Fiendslayer Paladin", 3)
.addSide("Riot Control", 3)
.addSide("Ajani, Caller of the Pride", 3)
.addSide("Rootborn Defenses", 3)
.addSide("Wear/Tear", 1)
.addSide("Glare of Heresy", 2)
.addSide("Fiendslayer Paladin", 3)
.addSide("Riot Control", 3)
.addSide("Ajani, Caller of the Pride", 3)
.addSide("Rootborn Defenses", 3)
.verify(deck, 60, 15);
.verify(deck, 60, 15);
assertEquals("", errors.toString());
}
assertEquals("", errors.toString());
}
}

View file

@ -1,33 +1,32 @@
package mage.cards.decks.importer;
import mage.cards.decks.DeckCardLists;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import mage.cards.decks.DeckCardLists;
public class O8dDeckImportTest {
private static final FakeCardLookup LOOKUP = new FakeCardLookup();
private static final FakeCardLookup LOOKUP = new FakeCardLookup();
@Test
public void testImport() {
O8dDeckImporter importer = new O8dDeckImporter() {
@Override
public CardLookup getCardLookup() {
return LOOKUP;
}
};
StringBuilder errors = new StringBuilder();
DeckCardLists deck = importer.importDeck(
"src/test/java/mage/cards/decks/importer/samples/testdeck.o8d", errors);
@Test
public void testImport() {
O8dDeckImporter importer = new O8dDeckImporter() {
@Override
public CardLookup getCardLookup() {
return LOOKUP;
}
};
StringBuilder errors = new StringBuilder();
DeckCardLists deck = importer.importDeck(
"src/test/java/mage/cards/decks/importer/samples/testdeck.o8d", errors, false);
TestDeckChecker.checker()
.addMain("Forest", 1)
.addSide("Island", 2)
.verify(deck, 1, 2);
TestDeckChecker.checker()
.addMain("Forest", 1)
.addSide("Island", 2)
.verify(deck, 1, 2);
assertEquals("", errors.toString());
}
assertEquals("", errors.toString());
}
}