Merge pull request #5503 from hitch17/add-cockatrice-deck-format-5493

Adding o8d deck format.
This commit is contained in:
Oleg Agafonov 2019-01-11 08:14:38 +04:00 committed by GitHub
commit c3848b7530
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 391 additions and 118 deletions

View file

@ -1,7 +1,9 @@
package mage.cards.decks.importer;
import java.util.List;
import java.util.Optional;
import mage.cards.repository.CardCriteria;
import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
@ -13,4 +15,8 @@ public class CardLookup {
return Optional.ofNullable(CardRepository.instance.findPreferedCoreExpansionCard(name, true));
}
public List<CardInfo> lookupCardInfo(CardCriteria criteria) {
return CardRepository.instance.findCards(criteria);
}
}

View file

@ -1,10 +1,5 @@
package mage.cards.decks.importer;
import static javax.xml.xpath.XPathConstants.NODESET;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
@ -12,26 +7,14 @@ import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import mage.cards.decks.DeckCardInfo;
import mage.cards.decks.DeckCardLists;
import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
public class CodDeckImporter extends DeckImporter {
private XPathFactory xpathFactory = XPathFactory.newInstance();
private DocumentBuilder builder = getDocumentBuilder();
public class CodDeckImporter extends XmlDeckImporter {
@Override
public DeckCardLists importDeck(String filename, StringBuilder errorMessages) {
@ -88,30 +71,4 @@ public class CodDeckImporter extends DeckImporter {
};
}
private List<Node> getNodes(Document doc, String xpathExpression) throws XPathExpressionException {
NodeList nodes = (NodeList) xpathFactory.newXPath().evaluate(xpathExpression, doc, NODESET);
ArrayList<Node> list = new ArrayList<>();
for (int i = 0; i < nodes.getLength(); i++) {
list.add(nodes.item(i));
}
return list;
}
private DocumentBuilder getDocumentBuilder() {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
return factory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
throw new RuntimeException();
}
}
protected Document getXmlDocument(String filename) throws IOException {
try {
return builder.parse(new File(filename));
} catch (SAXException e) {
throw new IOException(e);
}
}
}

View file

@ -32,6 +32,8 @@ public abstract class DeckImporter {
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 {
return null;
}

View file

@ -43,13 +43,13 @@ public class MWSDeckImporter extends PlainTextDeckImporter {
CardCriteria criteria = new CardCriteria();
criteria.name(lineName);
criteria.setCodes(setCode);
List<CardInfo> cards = CardRepository.instance.findCards(criteria);
List<CardInfo> cards = getCardLookup().lookupCardInfo(criteria);
if (!cards.isEmpty()) {
cardInfo = cards.get(RandomUtil.nextInt(cards.size()));
}
}
if (cardInfo == null) {
cardInfo = CardRepository.instance.findPreferedCoreExpansionCard(lineName, true);
cardInfo = getCardLookup().lookupCardInfo(lineName).orElse(null);
}
if (cardInfo == null) {

View file

@ -0,0 +1,71 @@
package mage.cards.decks.importer;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
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();
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()));
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;
}
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();
}
};
}
}

View file

@ -0,0 +1,52 @@
package mage.cards.decks.importer;
import static javax.xml.xpath.XPathConstants.NODESET;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public abstract class XmlDeckImporter extends DeckImporter {
private XPathFactory xpathFactory = XPathFactory.newInstance();
private DocumentBuilder builder = getDocumentBuilder();
protected List<Node> getNodes(Document doc, String xpathExpression) throws XPathExpressionException {
NodeList nodes = (NodeList) xpathFactory.newXPath().evaluate(xpathExpression, doc, NODESET);
ArrayList<Node> list = new ArrayList<>();
for (int i = 0; i < nodes.getLength(); i++) {
list.add(nodes.item(i));
}
return list;
}
private DocumentBuilder getDocumentBuilder() {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
return factory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
throw new RuntimeException();
}
}
protected Document getXmlDocument(String filename) throws IOException {
try {
return builder.parse(new File(filename));
} catch (SAXException e) {
throw new IOException(e);
}
}
}

View file

@ -309,4 +309,97 @@ public class CardCriteria {
qb.orderBy(sortBy, true);
}
}
public String getName() {
return name;
}
public String getNameExact() {
return nameExact;
}
public String getRules() {
return rules;
}
public List<String> getSetCodes() {
return setCodes;
}
public List<CardType> getTypes() {
return types;
}
public List<CardType> getNotTypes() {
return notTypes;
}
public List<String> getSupertypes() {
return supertypes;
}
public List<String> getNotSupertypes() {
return notSupertypes;
}
public List<String> getSubtypes() {
return subtypes;
}
public List<Rarity> getRarities() {
return rarities;
}
public Boolean getDoubleFaced() {
return doubleFaced;
}
public boolean isBlack() {
return black;
}
public boolean isBlue() {
return blue;
}
public boolean isGreen() {
return green;
}
public boolean isRed() {
return red;
}
public boolean isWhite() {
return white;
}
public boolean isColorless() {
return colorless;
}
public Integer getConvertedManaCost() {
return convertedManaCost;
}
public String getSortBy() {
return sortBy;
}
public Long getStart() {
return start;
}
public Long getCount() {
return count;
}
public int getMinCardNumber() {
return minCardNumber;
}
public int getMaxCardNumber() {
return maxCardNumber;
}
}