diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java index 357ecda0c6..06b6e34aad 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java @@ -1414,14 +1414,15 @@ class ImportFilter extends FileFilter { || ext.equalsIgnoreCase("txt") || ext.equalsIgnoreCase("dek") || ext.equalsIgnoreCase("cod") - || ext.equalsIgnoreCase("o8d"); + || ext.equalsIgnoreCase("o8d") + || ext.equalsIgnoreCase("draft"); } return false; } @Override public String getDescription() { - return "All formats (*.dec; *.mwDeck; *.txt; *.dek; *.cod; *.o8d)"; + return "All formats (*.dec; *.mwDeck; *.txt; *.dek; *.cod; *.o8d; *.draft)"; } } diff --git a/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java b/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java index 9cbff6f1cd..d5b41eb9e0 100644 --- a/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java +++ b/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java @@ -136,7 +136,7 @@ public class DraftPanel extends javax.swing.JPanel { if (isLogging()) { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss"); - String logFilename = "Draft_" + sdf.format(new Date()) + '_' + draftId + ".txt"; + String logFilename = "Draft_" + sdf.format(new Date()) + '_' + draftId + ".draft"; draftLogger = new DraftPickLogger(new File("gamelogs"), logFilename); } else { draftLogger = new DraftPickLogger(); diff --git a/Mage/src/main/java/mage/cards/decks/importer/DeckImporter.java b/Mage/src/main/java/mage/cards/decks/importer/DeckImporter.java index 2e20ded641..b7ba7f8059 100644 --- a/Mage/src/main/java/mage/cards/decks/importer/DeckImporter.java +++ b/Mage/src/main/java/mage/cards/decks/importer/DeckImporter.java @@ -34,6 +34,8 @@ public abstract class DeckImporter { return new CodDeckImporter(); } else if (file.toLowerCase(Locale.ENGLISH).endsWith("o8d")) { return new O8dDeckImporter(); + } else if (file.toLowerCase(Locale.ENGLISH).endsWith("draft")) { + return new DraftLogImporter(); } else { return null; } diff --git a/Mage/src/main/java/mage/cards/decks/importer/DraftLogImporter.java b/Mage/src/main/java/mage/cards/decks/importer/DraftLogImporter.java new file mode 100644 index 0000000000..5914165f1c --- /dev/null +++ b/Mage/src/main/java/mage/cards/decks/importer/DraftLogImporter.java @@ -0,0 +1,46 @@ +package mage.cards.decks.importer; + +import mage.cards.decks.DeckCardInfo; +import mage.cards.decks.DeckCardLists; +import mage.cards.repository.CardCriteria; +import mage.cards.repository.CardInfo; + +import java.util.List; +import java.util.regex.Matcher; +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 String currentSet = null; + + @Override + protected void readLine(String line, DeckCardLists deckList) { + Matcher setMatcher = SET_PATTERN.matcher(line); + if (setMatcher.matches()) { + currentSet = setMatcher.group(1); + return; + } + + Matcher pickMatcher = PICK_PATTERN.matcher(line); + if (pickMatcher.matches()) { + String name = pickMatcher.group(1); + List cards = getCardLookup().lookupCardInfo(new CardCriteria().setCodes(currentSet).name(name)); + CardInfo card = null; + if (!cards.isEmpty()) { + card = cards.get(0); + } else { + card = getCardLookup().lookupCardInfo(name).orElse(null); + } + + if (card != null) { + deckList.getCards().add(new DeckCardInfo(card.getName(), card.getCardNumber(), card.getSetCode())); + } else { + sbMessage.append("couldn't find: \"").append(name).append("\"\n"); + } + } + } + +} diff --git a/Mage/src/test/java/mage/cards/decks/importer/DraftLogImporterTest.java b/Mage/src/test/java/mage/cards/decks/importer/DraftLogImporterTest.java new file mode 100644 index 0000000000..7c64308dd4 --- /dev/null +++ b/Mage/src/test/java/mage/cards/decks/importer/DraftLogImporterTest.java @@ -0,0 +1,75 @@ +package mage.cards.decks.importer; + +import mage.cards.decks.DeckCardLists; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class DraftLogImporterTest { + + private static final FakeCardLookup LOOKUP = new FakeCardLookup(); + + @Test + public void testImport() { + StringBuilder errors = new StringBuilder(); + DraftLogImporter importer = new DraftLogImporter() { + @Override + public CardLookup getCardLookup() { + return LOOKUP; + } + }; + DeckCardLists deck = importer.importDeck( + "src/test/java/mage/cards/decks/importer/samples/testdeck.draft", errors); + + TestDeckChecker.checker() + .addMain("Raging Ravine", 1) + .addMain("Fiery Temper", 1) + .addMain("Wild Mongrel", 1) + .addMain("Wild Mongrel", 1) + .addMain("Shielding Plax", 1) + .addMain("Wild Mongrel", 1) + .addMain("Basking Rootwalla", 1) + .addMain("Wild Mongrel", 1) + .addMain("Arena Athlete", 1) + .addMain("Undying Rage", 1) + .addMain("Molten Birth", 1) + .addMain("Shed Weakness", 1) + .addMain("Pulse of Murasa", 1) + .addMain("Just the Wind", 1) + .addMain("Stitcher's Apprentice", 1) + .addMain("Life from the Loam", 1) + .addMain("Satyr Wayfinder", 1) + .addMain("Mad Prophet", 1) + .addMain("Wild Mongrel", 1) + .addMain("Wickerbough Elder", 1) + .addMain("Basking Rootwalla", 1) + .addMain("Satyr Wayfinder", 1) + .addMain("Brawn", 1) + .addMain("Myr Servitor", 1) + .addMain("Terramorphic Expanse", 1) + .addMain("Foil", 1) + .addMain("Flight of Fancy", 1) + .addMain("Mark of the Vampire", 1) + .addMain("Repel the Darkness", 1) + .addMain("Golgari Charm", 1) + .addMain("Raid Bombardment", 1) + .addMain("Reckless Wurm", 1) + .addMain("Satyr Wayfinder", 1) + .addMain("Kodama's Reach", 1) + .addMain("Last Gasp", 1) + .addMain("Wild Mongrel", 1) + .addMain("Myr Servitor", 1) + .addMain("Raid Bombardment", 1) + .addMain("Treasure Cruise", 1) + .addMain("Bloodflow Connoisseur", 1) + .addMain("Treasure Cruise", 1) + .addMain("Hyena Umbra", 1) + .addMain("Kodama's Reach", 1) + .addMain("Just the Wind", 1) + .addMain("Flight of Fancy", 1) + .verify(deck, 45, 0); + + assertEquals("", errors.toString()); + } + +} \ No newline at end of file diff --git a/Mage/src/test/java/mage/cards/decks/importer/samples/testdeck.draft b/Mage/src/test/java/mage/cards/decks/importer/samples/testdeck.draft new file mode 100644 index 0000000000..95aaf72cae --- /dev/null +++ b/Mage/src/test/java/mage/cards/decks/importer/samples/testdeck.draft @@ -0,0 +1,466 @@ +Event #: 8a74113b-27e5-4a29-85be-4b83f622af00 +Time: 4/11/2019 8:55:15 AM +Players: + Computer Player 4 + Computer Player 2 + Computer Player 6 + hitchyflav + Computer Player 5 + Computer Player 3 + +------ UMA ------ + +Pack 1 pick 1: + Deranged Assistant + Nightbird's Clutches + Groundskeeper + Sanitarium Skeleton + Skywing Aven + Foil + Tethmos High Priest + Kodama's Reach + Pulse of Murasa + Basking Rootwalla + Ulamog's Crusher + Vengeful Rebirth + Laboratory Maniac + Boneyard Wurm +--> Raging Ravine + +Pack 1 pick 2: + Deranged Assistant + Olivia's Dragoon + Sultai Skullkeeper +--> Fiery Temper + Wild Mongrel + Dimir Guildmage + Turn to Mist + Ingot Chewer + Just the Wind + Mad Prophet + Rakdos Shred-Freak + Firewing Phoenix + Vengeful Rebirth + Fecundity + +Pack 1 pick 3: + Death Denied + Stitcher's Apprentice + Archaeomancer + Arena Athlete + Lotus-Eye Mystics +--> Wild Mongrel + Spider Umbra + Martyr of Sands + Mad Prophet + Ghoulcaller's Accomplice + Safehold Elite + Malevolent Whispers + Devoted Druid + +Pack 1 pick 4: + Stitcher's Apprentice +--> Wild Mongrel + Ronom Unicorn + Death Denied + Flight of Fancy + Undying Rage + Grave Scrabbler + Wandering Champion + Angelic Renewal + Patchwork Gnomes + Wingsteed Rider + Mage-Ring Network + +Pack 1 pick 5: + Defy Gravity + Grave Scrabbler + Fume Spitter +--> Shielding Plax + Ghoulcaller's Accomplice + Rakdos Shred-Freak + Sparkspitter + Resurrection + Molten Birth + Slum Reaper + Grave Strength + +Pack 1 pick 6: + Terramorphic Expanse +--> Wild Mongrel + Shed Weakness + Tethmos High Priest + Angelic Renewal + Slum Reaper + Foil + Rune Snag + Wickerbough Elder + Frantic Search + +Pack 1 pick 7: + Deranged Assistant + Nightbird's Clutches + Groundskeeper + Skywing Aven + Foil + Kodama's Reach + Pulse of Murasa +--> Basking Rootwalla + Vengeful Rebirth + +Pack 1 pick 8: + Deranged Assistant + Olivia's Dragoon + Sultai Skullkeeper +--> Wild Mongrel + Dimir Guildmage + Turn to Mist + Just the Wind + Rakdos Shred-Freak + +Pack 1 pick 9: + Death Denied + Stitcher's Apprentice + Archaeomancer +--> Arena Athlete + Spider Umbra + Martyr of Sands + Ghoulcaller's Accomplice + +Pack 1 pick 10: + Stitcher's Apprentice + Ronom Unicorn + Flight of Fancy +--> Undying Rage + Wandering Champion + Angelic Renewal + +Pack 1 pick 11: + Defy Gravity + Fume Spitter + Ghoulcaller's Accomplice +--> Molten Birth + Slum Reaper + +Pack 1 pick 12: +--> Shed Weakness + Angelic Renewal + Rune Snag + Frantic Search + +Pack 1 pick 13: + Foil + Kodama's Reach +--> Pulse of Murasa + +Pack 1 pick 14: + Sultai Skullkeeper +--> Just the Wind + +Pack 1 pick 15: +--> Stitcher's Apprentice + +------ UMA ------ + +Pack 2 pick 1: + Reckless Wurm + Dark Dabbling + Lotus-Eye Mystics + Heliod's Pilgrim + Satyr Wayfinder + Moan of the Unhallowed + Akroan Crusader + Fire // Ice + Grave Scrabbler + Mark of the Vampire + Safehold Elite + Blast of Genius + Spirit Cairn + Shriekmaw +--> Life from the Loam + +Pack 2 pick 2: +--> Satyr Wayfinder + Shed Weakness + Rakdos Shred-Freak + Defy Gravity + Crow of Dark Tidings + Frantic Search + Walker of the Grove + Prey Upon + Repel the Darkness + Eel Umbra + Brawn + Stingerfling Spider + Forbidden Alchemy + Celestial Colonnade + +Pack 2 pick 3: + Deranged Assistant + Beckon Apparition + Bloodflow Connoisseur + Faith's Fetters +--> Mad Prophet + Myr Servitor + Shed Weakness + Dimir Guildmage + Ingot Chewer + Icatian Crier + Plumeveil + Golgari Charm + Visions of Beyond + +Pack 2 pick 4: + Defy Gravity + Conviction + Terramorphic Expanse +--> Wild Mongrel + Moan of the Unhallowed + Gurmag Angler + Vessel of Endless Rest + Hissing Iguanar + Mark of the Vampire + Martyr of Sands + Circular Logic + Rise from the Tides + +Pack 2 pick 5: + Slum Reaper + Icatian Crier +--> Wickerbough Elder + Mad Prophet + Defy Gravity + Gurmag Angler + Archaeomancer + Foil + Eel Umbra + Vessel of Endless Rest + Rally the Peasants + +Pack 2 pick 6: + Wandering Champion +--> Basking Rootwalla + Frantic Search + Angelic Renewal + Cathodion + Olivia's Dragoon + Flight of Fancy + Skyspear Cavalry + Thermo-Alchemist + Fume Spitter + +Pack 2 pick 7: + Dark Dabbling + Lotus-Eye Mystics + Heliod's Pilgrim +--> Satyr Wayfinder + Moan of the Unhallowed + Akroan Crusader + Grave Scrabbler + Mark of the Vampire + Blast of Genius + +Pack 2 pick 8: + Shed Weakness + Defy Gravity + Crow of Dark Tidings + Frantic Search + Walker of the Grove + Repel the Darkness + Eel Umbra +--> Brawn + +Pack 2 pick 9: + Deranged Assistant + Beckon Apparition + Bloodflow Connoisseur +--> Myr Servitor + Shed Weakness + Icatian Crier + Golgari Charm + +Pack 2 pick 10: + Defy Gravity + Conviction +--> Terramorphic Expanse + Moan of the Unhallowed + Mark of the Vampire + Circular Logic + +Pack 2 pick 11: + Icatian Crier + Defy Gravity +--> Foil + Eel Umbra + Vessel of Endless Rest + +Pack 2 pick 12: + Wandering Champion + Angelic Renewal +--> Flight of Fancy + Fume Spitter + +Pack 2 pick 13: + Dark Dabbling + Moan of the Unhallowed +--> Mark of the Vampire + +Pack 2 pick 14: +--> Repel the Darkness + Eel Umbra + +Pack 2 pick 15: +--> Golgari Charm + +------ UMA ------ + +Pack 3 pick 1: + Myr Servitor + Dimir Guildmage +--> Raid Bombardment + Kodama's Reach + Arena Athlete + Martyr of Sands + Shed Weakness + Skywing Aven + Wickerbough Elder + Hooting Mandrills + Sparkspitter + Desperate Ritual + Grave Strength + Dawn Charm + Reya Dawnbringer + +Pack 3 pick 2: + Pulse of Murasa + Crow of Dark Tidings + Raid Bombardment +--> Reckless Wurm + Hyena Umbra + Just the Wind + Verdant Eidolon + Groundskeeper + Double Cleave + Repel the Darkness + Stitcher's Apprentice + Sleight of Hand + Living Lore + Artisan of Kozilek + +Pack 3 pick 3: + Moan of the Unhallowed + Thermo-Alchemist + Stitcher's Apprentice + Bloodflow Connoisseur + Sparkspitter + Mark of the Vampire + Treasure Cruise + Flight of Fancy + Unholy Hunger + Staunch-Hearted Warrior +--> Satyr Wayfinder + Spirit Cairn + Blast of Genius + +Pack 3 pick 4: + Bloodflow Connoisseur + Grave Scrabbler + Hyena Umbra + Slum Reaper +--> Kodama's Reach + Sparkspitter + Sanitarium Skeleton + Stitched Drake + Pulse of Murasa + Mammoth Umbra + Olivia's Dragoon + Vengeful Rebirth + +Pack 3 pick 5: + Beckon Apparition + Turn to Mist + Spider Umbra + Bloodflow Connoisseur +--> Last Gasp + Terramorphic Expanse + Treasure Cruise + Miming Slime + Emancipation Angel + Warleader's Helix + Snapcaster Mage + +Pack 3 pick 6: + Ingot Chewer + Defy Gravity + Mammoth Umbra +--> Wild Mongrel + Reckless Charge + Fume Spitter + Skywing Aven + Hyena Umbra + Twins of Maurer Estate + Urban Evolution + +Pack 3 pick 7: +--> Myr Servitor + Kodama's Reach + Arena Athlete + Martyr of Sands + Shed Weakness + Skywing Aven + Wickerbough Elder + Sparkspitter + Dawn Charm + +Pack 3 pick 8: + Pulse of Murasa +--> Raid Bombardment + Hyena Umbra + Just the Wind + Repel the Darkness + Stitcher's Apprentice + Sleight of Hand + Living Lore + +Pack 3 pick 9: + Moan of the Unhallowed + Thermo-Alchemist + Stitcher's Apprentice + Sparkspitter + Mark of the Vampire +--> Treasure Cruise + Flight of Fancy + +Pack 3 pick 10: +--> Bloodflow Connoisseur + Hyena Umbra + Sanitarium Skeleton + Stitched Drake + Mammoth Umbra + Olivia's Dragoon + +Pack 3 pick 11: + Spider Umbra + Terramorphic Expanse +--> Treasure Cruise + Miming Slime + Warleader's Helix + +Pack 3 pick 12: + Defy Gravity + Skywing Aven +--> Hyena Umbra + Urban Evolution + +Pack 3 pick 13: +--> Kodama's Reach + Martyr of Sands + Shed Weakness + +Pack 3 pick 14: + Hyena Umbra +--> Just the Wind + +Pack 3 pick 15: +--> Flight of Fancy +