forked from External/mage
Merge pull request #70 from magefree/master
Merge https://github.com/magefree/mage
This commit is contained in:
commit
609cb2286b
2212 changed files with 47208 additions and 9150 deletions
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-root</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<groupId>org.mage</groupId>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
1 [C18:61] Ajani's Chosen
|
||||
1 [C18:81] Archetype of Imagination
|
||||
1 [C18:38] Arixmethes, Slumbering Isle
|
||||
1 [C18:128] Aura Gnarlid
|
||||
1 [C18:233] Azorius Chancery
|
||||
1 [C18:169] Bant Charm
|
||||
1 [C18:131] Bear Umbra
|
||||
1 [C18:237] Blossoming Sands
|
||||
1 [C18:132] Boon Satyr
|
||||
1 [C18:170] Bruna, Light of Alabaster
|
||||
1 [C18:64] Celestial Archon
|
||||
1 [C18:172] Cold-Eyed Selkie
|
||||
1 [C18:240] Command Tower
|
||||
1 [C18:137] Creeping Renaissance
|
||||
1 [C18:139] Dawn's Reflection
|
||||
1 [C18:173] Daxos of Meletis
|
||||
1 [C18:86] Dictate of Kruphix
|
||||
1 [C18:66] Dismantling Blow
|
||||
1 [C18:89] Eel Umbra
|
||||
1 [C18:140] Eidolon of Blossoms
|
||||
1 [C18:177] Elderwood Scion
|
||||
1 [C18:2] Empyrial Storm
|
||||
1 [C18:141] Enchantress's Presence
|
||||
1 [C18:142] Epic Proportions
|
||||
1 [C18:8] Estrid's Invocation
|
||||
1 [C18:9] Ever-Watching Threshold
|
||||
1 [C18:245] Evolving Wilds
|
||||
1 [C18:147] Fertile Ground
|
||||
1 [C18:180] Finest Hour
|
||||
1 [C18:58] Forge of Heroes
|
||||
1 [C18:30] Genesis Storm
|
||||
1 [C18:149] Ground Seal
|
||||
1 [C18:3] Heavenly Blademaster
|
||||
1 [C18:151] Herald of the Pantheon
|
||||
1 [C18:153] Hydra Omnivore
|
||||
1 [C18:42] Kestia, the Cultivator
|
||||
1 [C18:263] Krosan Verge
|
||||
1 [C18:155] Kruphix's Insight
|
||||
1 [C18:10] Loyal Drake
|
||||
1 [C18:31] Loyal Guardian
|
||||
1 [C18:4] Loyal Unicorn
|
||||
1 [C18:69] Martial Coup
|
||||
1 [C18:265] Meandering River
|
||||
1 [C18:267] Mosswort Bridge
|
||||
1 [C18:32] Myth Unbound
|
||||
1 [C18:33] Nylea's Colossus
|
||||
1 [C18:11] Octopus Umbra
|
||||
1 [C18:157] Overgrowth
|
||||
1 [C18:70] Phyrexian Rebirth
|
||||
1 [C18:34] Ravenous Slime
|
||||
1 [C18:159] Reclamation Sage
|
||||
1 [C18:188] Righteous Authority
|
||||
1 [C18:72] Sage's Reverie
|
||||
1 [C18:277] Seaside Citadel
|
||||
1 [C18:281] Selesnya Sanctuary
|
||||
1 [C18:74] Sigil of the Empty Throne
|
||||
1 [C18:75] Silent Sentinel
|
||||
1 [C18:282] Simic Growth Chamber
|
||||
1 [C18:162] Snake Umbra
|
||||
1 [C18:222] Sol Ring
|
||||
1 [C18:76] Soul Snare
|
||||
1 [C18:163] Spawning Grounds
|
||||
1 [C18:286] Terramorphic Expanse
|
||||
1 [C18:287] Thornwood Falls
|
||||
1 [C18:288] Tranquil Cove
|
||||
1 [C18:289] Tranquil Expanse
|
||||
1 [C18:47] Tuvasa the Sunlit
|
||||
1 [C18:192] Unflinching Courage
|
||||
1 [C18:78] Unquestioned Authority
|
||||
1 [C18:110] Vow of Flight
|
||||
1 [C18:164] Vow of Wildness
|
||||
1 [C18:112] Whitewater Naiads
|
||||
1 [C18:165] Wild Growth
|
||||
1 [C18:79] Winds of Rath
|
||||
1 [C18:292] Woodland Stream
|
||||
1 [C18:167] Yavimaya Enchantress
|
||||
2 [C18:307] Forest
|
||||
2 [C18:296] Island
|
||||
2 [C18:297] Island
|
||||
2 [C18:298] Island
|
||||
3 [C18:305] Forest
|
||||
3 [C18:306] Forest
|
||||
3 [C18:293] Plains
|
||||
3 [C18:294] Plains
|
||||
3 [C18:295] Plains
|
||||
SB:1 [C18:40] Estrid, the Masked
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
1 [C18:197] Blinkmoth Urn
|
||||
1 [C18:92] Into the Roil
|
||||
1 [C18:230] Worn Powerstone
|
||||
1 [C18:91] Inkwell Leviathan
|
||||
1 [C18:199] Chief of the Foundry
|
||||
1 [C18:90] Etherium Sculptor
|
||||
1 [C18:111] Whirler Rogue
|
||||
1 [C18:198] Bosh, Iron Golem
|
||||
1 [C18:278] Seat of the Synod
|
||||
1 [C18:58] Forge of Heroes
|
||||
1 [C18:57] Retrofitter Foundry
|
||||
1 [C18:13] Vedalken Humiliator
|
||||
1 [C18:56] Geode Golem
|
||||
1 [C18:55] Endless Atlas
|
||||
1 [C18:99] Reverse Engineer
|
||||
1 [C18:54] Coveted Jewel
|
||||
1 [C18:10] Loyal Drake
|
||||
1 [C18:53] Ancient Stone Idol
|
||||
1 [C18:239] Buried Ruin
|
||||
1 [C18:185] Maverick Thopterist
|
||||
1 [C18:100] Saheeli's Artistry
|
||||
1 [C18:223] Soul of New Phyrexia
|
||||
1 [C18:27] Treasure Nabber
|
||||
1 [C18:26] Saheeli's Directive
|
||||
1 [C18:101] Sharding Sphinx
|
||||
1 [C18:222] Sol Ring
|
||||
1 [C18:225] Swiftfoot Boots
|
||||
4 [C18:302] Mountain
|
||||
1 [C18:224] Steel Hellkite
|
||||
1 [C18:23] Loyal Apprentice
|
||||
1 [C18:106] Thirst for Knowledge
|
||||
1 [C18:227] Unstable Obelisk
|
||||
4 [C18:304] Mountain
|
||||
1 [C18:226] Thopter Assembly
|
||||
4 [C18:303] Mountain
|
||||
1 [C18:21] Enchanter's Bane
|
||||
1 [C18:108] Tidings
|
||||
1 [C18:229] Vessel of Endless Rest
|
||||
1 [C18:107] Thopter Spy Network
|
||||
1 [C18:228] Unwinding Clock
|
||||
1 [C18:28] Varchild, Betrayer of Kjeldor
|
||||
1 [C18:250] Great Furnace
|
||||
5 [C18:296] Island
|
||||
1 [C18:210] Mind Stone
|
||||
5 [C18:298] Island
|
||||
5 [C18:297] Island
|
||||
1 [C18:256] Izzet Boilerworks
|
||||
1 [C18:212] Myr Battlesphere
|
||||
1 [C18:255] Highland Lake
|
||||
1 [C18:211] Mirrorworks
|
||||
1 [C18:214] Pilgrim's Eye
|
||||
1 [C18:257] Izzet Guildgate
|
||||
1 [C18:216] Prototype Portal
|
||||
1 [C18:215] Prismatic Lens
|
||||
1 [C18:218] Scrabbling Claws
|
||||
1 [C18:217] Psychosis Crawler
|
||||
1 [C18:219] Scuttling Doom Engine
|
||||
1 [C18:7] Echo Storm
|
||||
1 [C18:39] Brudiclad, Telchor Engineer
|
||||
1 [C18:120] Blasphemous Act
|
||||
1 [C18:241] Darksteel Citadel
|
||||
1 [C18:80] Aether Gale
|
||||
1 [C18:240] Command Tower
|
||||
1 [C18:284] Swiftwater Cliffs
|
||||
1 [C18:122] Chaos Warp
|
||||
1 [C18:124] Hellkite Igniter
|
||||
1 [C18:200] Commander's Sphere
|
||||
1 [C18:126] Thopter Engineer
|
||||
1 [C18:202] Darksteel Juggernaut
|
||||
1 [C18:125] Magmaquake
|
||||
1 [C18:205] Duplicant
|
||||
1 [C18:45] Tawnos, Urza's Apprentice
|
||||
1 [C18:204] Dreamstone Hedron
|
||||
1 [C18:248] Foundry of the Consuls
|
||||
1 [C18:207] Izzet Signet
|
||||
1 [C18:206] Hedron Archive
|
||||
1 [C18:209] Mimic Vat
|
||||
1 [C18:208] Magnifying Glass
|
||||
SB: 1 [C18:44] Saheeli, the Gifted
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
1 [C18:114] Moonlight Bargain
|
||||
1 [C18:116] Retreat to Hagra
|
||||
1 [C18:117] Ruinous Path
|
||||
1 [C18:118] Soul of Innistrad
|
||||
1 [C18:119] Stitch Together
|
||||
1 [C18:121] Chain Reaction
|
||||
1 [C18:123] Flameblast Dragon
|
||||
1 [C18:127] Acidic Slime
|
||||
1 [C18:129] Avenger of Zendikar
|
||||
1 [C18:130] Baloth Woodcrasher
|
||||
1 [C18:133] Borderland Explorer
|
||||
1 [C18:134] Budoka Gardener
|
||||
1 [C18:135] Centaur Vinecrasher
|
||||
1 [C18:136] Consign to Dust
|
||||
1 [C18:138] Cultivate
|
||||
1 [C18:143] Explore
|
||||
1 [C18:144] Explosive Vegetation
|
||||
1 [C18:145] Far Wanderings
|
||||
1 [C18:146] Farhaven Elf
|
||||
1 [C18:148] Grapple with the Past
|
||||
1 [C18:14] Bloodtracker
|
||||
1 [C18:150] Harrow
|
||||
1 [C18:152] Hunting Wilds
|
||||
1 [C18:154] Khalni Heart Expedition
|
||||
1 [C18:156] Moldgraf Monstrosity
|
||||
1 [C18:158] Rampaging Baloths
|
||||
1 [C18:160] Sakura-Tribe Elder
|
||||
1 [C18:161] Scute Mob
|
||||
1 [C18:166] Yavimaya Elder
|
||||
1 [C18:16] Loyal Subordinate
|
||||
1 [C18:171] Charnelhoard Wurm
|
||||
1 [C18:174] Deathreap Ritual
|
||||
1 [C18:175] Decimate
|
||||
1 [C18:181] Gaze of Granite
|
||||
1 [C18:182] Grisly Salvage
|
||||
1 [C18:184] Lavalanche
|
||||
1 [C18:187] Putrefy
|
||||
1 [C18:189] Rubblehulk
|
||||
1 [C18:190] Savage Twister
|
||||
1 [C18:194] Worm Harvest
|
||||
1 [C18:195] Zendikar Incarnate
|
||||
1 [C18:221] Seer's Sundial
|
||||
1 [C18:222] Sol Ring
|
||||
1 [C18:22] Fury Storm
|
||||
1 [C18:231] Akoum Refuge
|
||||
1 [C18:235] Barren Moor
|
||||
1 [C18:236] Blighted Woodland
|
||||
1 [C18:238] Bojuka Bog
|
||||
1 [C18:23] Loyal Apprentice
|
||||
1 [C18:240] Command Tower
|
||||
1 [C18:245] Evolving Wilds
|
||||
1 [C18:246] Forgotten Cave
|
||||
1 [C18:249] Golgari Rot Farm
|
||||
1 [C18:24] Nesting Dragon
|
||||
1 [C18:251] Grim Backwoods
|
||||
1 [C18:252] Gruul Turf
|
||||
1 [C18:254] Haunted Fengraf
|
||||
1 [C18:258] Jund Panorama
|
||||
1 [C18:259] Jungle Hollow
|
||||
1 [C18:25] Reality Scramble
|
||||
1 [C18:261] Kazandu Refuge
|
||||
1 [C18:262] Khalni Garden
|
||||
1 [C18:268] Mountain Valley
|
||||
1 [C18:269] Myriad Landscape
|
||||
1 [C18:273] Rakdos Carnarium
|
||||
1 [C18:274] Rocky Tar Pit
|
||||
1 [C18:275] Savage Lands
|
||||
1 [C18:285] Temple of the False God
|
||||
1 [C18:286] Terramorphic Expanse
|
||||
1 [C18:290] Tranquil Thicket
|
||||
1 [C18:29] Crash of Rhino Beetles
|
||||
1 [C18:31] Loyal Guardian
|
||||
1 [C18:35] Turntimber Sower
|
||||
1 [C18:36] Whiptongue Hydra
|
||||
1 [C18:41] Gyrus, Waker of Corpses
|
||||
1 [C18:49] Windgrace's Judgment
|
||||
1 [C18:58] Forge of Heroes
|
||||
1 [C18:20] Emissary of Grudges
|
||||
1 [C18:46] Thantis, the Warweaver
|
||||
1 [C18:291] Warped Landscape
|
||||
1 [C18:50] Xantcha, Sleeper Agent
|
||||
2 [C18:299] Swamp
|
||||
2 [C18:300] Swamp
|
||||
2 [C18:301] Swamp
|
||||
2 [C18:302] Mountain
|
||||
2 [C18:303] Mountain
|
||||
1 [C18:304] Mountain
|
||||
2 [C18:306] Forest
|
||||
2 [C18:307] Forest
|
||||
3 [C18:305] Forest
|
||||
SB: 1 [C18:43] Lord Windgrace
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
1 [C18:102] Sigiled Starfish
|
||||
1 [C18:103] Sphinx of Jwar Isle
|
||||
1 [C18:104] Sphinx of Uthuun
|
||||
1 [C18:105] Telling Time
|
||||
1 [C18:109] Treasure Hunt
|
||||
1 [C18:113] Army of the Damned
|
||||
1 [C18:115] Phyrexian Delver
|
||||
1 [C18:12] Primordial Mist
|
||||
1 [C18:15] Entreat the Dead
|
||||
1 [C18:168] Aethermage's Touch
|
||||
1 [C18:16] Loyal Subordinate
|
||||
1 [C18:176] Duskmantle Seer
|
||||
1 [C18:178] Enigma Sphinx
|
||||
1 [C18:179] Esper Charm
|
||||
1 [C18:17] Night Incarnate
|
||||
1 [C18:183] High Priest of Penance
|
||||
1 [C18:186] Mortify
|
||||
1 [C18:18] Skull Storm
|
||||
1 [C18:191] Silent-Blade Oni
|
||||
1 [C18:193] Utter End
|
||||
1 [C18:196] Azorius Signet
|
||||
1 [C18:19] Sower of Discord
|
||||
1 [C18:1] Boreas Charger
|
||||
1 [C18:200] Commander's Sphere
|
||||
1 [C18:201] Crystal Ball
|
||||
1 [C18:203] Dimir Signet
|
||||
1 [C18:210] Mind Stone
|
||||
1 [C18:213] Orzhov Signet
|
||||
1 [C18:214] Pilgrim's Eye
|
||||
1 [C18:220] Seer's Lantern
|
||||
1 [C18:222] Sol Ring
|
||||
1 [C18:232] Arcane Sanctum
|
||||
1 [C18:233] Azorius Chancery
|
||||
1 [C18:234] Azorius Guildgate
|
||||
1 [C18:235] Barren Moor
|
||||
1 [C18:240] Command Tower
|
||||
1 [C18:242] Dimir Aqueduct
|
||||
1 [C18:243] Dimir Guildgate
|
||||
1 [C18:244] Dismal Backwater
|
||||
1 [C18:247] Forsaken Sanctuary
|
||||
1 [C18:253] Halimar Depths
|
||||
1 [C18:260] Jwar Isle Refuge
|
||||
1 [C18:264] Lonely Sandbar
|
||||
1 [C18:265] Meandering River
|
||||
1 [C18:266] Mortuary Mire
|
||||
1 [C18:270] New Benalia
|
||||
1 [C18:271] Orzhov Basilica
|
||||
1 [C18:272] Orzhov Guildgate
|
||||
1 [C18:276] Scoured Barrens
|
||||
1 [C18:279] Secluded Steppe
|
||||
1 [C18:280] Sejiri Refuge
|
||||
1 [C18:283] Submerged Boneyard
|
||||
1 [C18:48] Varina, Lich Queen
|
||||
1 [C18:4] Loyal Unicorn
|
||||
1 [C18:56] Geode Golem
|
||||
1 [C18:58] Forge of Heroes
|
||||
1 [C18:59] Isolated Watchtower
|
||||
1 [C18:5] Magus of the Balance
|
||||
1 [C18:60] Adarkar Valkyrie
|
||||
1 [C18:62] Akroma's Vengeance
|
||||
1 [C18:63] Banishing Stroke
|
||||
1 [C18:65] Crib Swap
|
||||
1 [C18:67] Entreat the Angels
|
||||
1 [C18:68] Lightform
|
||||
1 [C18:71] Return to Dust
|
||||
1 [C18:73] Serra Avatar
|
||||
1 [C18:77] Terminus
|
||||
1 [C18:82] Brainstorm
|
||||
1 [C18:83] Cloudform
|
||||
1 [C18:84] Conundrum Sphinx
|
||||
1 [C18:85] Devastation Tide
|
||||
1 [C18:87] Djinn of Wishes
|
||||
1 [C18:88] Dream Cache
|
||||
1 [C18:93] Jeskai Infiltrator
|
||||
1 [C18:94] Mulldrifter
|
||||
1 [C18:95] Ninja of the Deep Hours
|
||||
1 [C18:96] Ponder
|
||||
1 [C18:97] Portent
|
||||
1 [C18:98] Predict
|
||||
1 [C18:298] Island
|
||||
1 [C18:299] Swamp
|
||||
1 [C18:300] Swamp
|
||||
1 [C18:301] Swamp
|
||||
1 [C18:006] Aminatou's Augury
|
||||
1 [C18:288] Tranquil Cove
|
||||
1 [C18:51] Yennett, Cryptic Sovereign
|
||||
1 [C18:52] Yuriko, the Tiger's Shadow
|
||||
2 [C18:296] Island
|
||||
2 [C18:297] Island
|
||||
2 [C18:295] Plains
|
||||
3 [C18:293] Plains
|
||||
3 [C18:294] Plains
|
||||
SB: 1 [C18:37] Aminatou, the Fateshifter
|
||||
|
|
@ -1083,10 +1083,10 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
private void chooseMatching() {
|
||||
Collection<CardView> toMatch = dragCardList();
|
||||
|
||||
|
||||
for (DragCardGridListener l : listeners) {
|
||||
for (CardView card : allCards) {
|
||||
for (CardView aMatch : toMatch) {
|
||||
|
|
@ -1337,6 +1337,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
public void analyseDeck() {
|
||||
HashMap<String, Integer> qtys = new HashMap<>();
|
||||
HashMap<String, Integer> pips = new HashMap<>();
|
||||
HashMap<String, Integer> pips_at_cmcs = new HashMap<>();
|
||||
HashMap<String, Integer> sourcePips = new HashMap<>();
|
||||
HashMap<String, Integer> manaCounts = new HashMap<>();
|
||||
pips.put("#w}", 0);
|
||||
|
|
@ -1396,11 +1397,40 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
}
|
||||
mc = mc.replaceAll("\\{([WUBRG]).([WUBRG])\\}", "{$1}{$2}");
|
||||
mc = mc.replaceAll("\\{", "#");
|
||||
mc = mc.replaceAll("#2\\/", "#");
|
||||
mc = mc.replaceAll("p}", "}");
|
||||
mc = mc.toLowerCase(Locale.ENGLISH);
|
||||
int cmc = card.getConvertedManaCost();
|
||||
|
||||
// Do colorless mana pips
|
||||
Pattern regex = Pattern.compile("#([0-9]+)}");
|
||||
Matcher regexMatcher = regex.matcher(mc);
|
||||
while (regexMatcher.find()) {
|
||||
String val = regexMatcher.group(1);
|
||||
int colorless_val = Integer.parseInt(val);
|
||||
|
||||
int total_c_pip = 0;
|
||||
if (pips.get("#c}") != null) {
|
||||
total_c_pip = pips.get("#c}");
|
||||
}
|
||||
pips.put("#c}", colorless_val + total_c_pip);
|
||||
|
||||
int cmc_pip_value = 0;
|
||||
if (pips_at_cmcs.get(cmc + "##c}") != null) {
|
||||
cmc_pip_value = pips_at_cmcs.get(cmc + "##c}");
|
||||
}
|
||||
pips_at_cmcs.put(cmc + "##c}", colorless_val + cmc_pip_value);
|
||||
}
|
||||
|
||||
for (String pip : pips.keySet()) {
|
||||
int value = pips.get(pip);
|
||||
while (mc.toLowerCase(Locale.ENGLISH).contains(pip)) {
|
||||
pips.put(pip, ++value);
|
||||
int pip_value = 0;
|
||||
if (pips_at_cmcs.get(cmc + "#" + pip) != null) {
|
||||
pip_value = pips_at_cmcs.get(cmc + "#" + pip);
|
||||
}
|
||||
pips_at_cmcs.put(cmc + "#" + pip, ++pip_value);
|
||||
mc = mc.replaceFirst(pip, "");
|
||||
}
|
||||
}
|
||||
|
|
@ -1448,9 +1478,17 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
panel4.add(new JLabel("Mana sources found:"));
|
||||
panel4.add(chart3);
|
||||
|
||||
JPanel panel5 = new JPanel();
|
||||
panel5.setLayout(new BoxLayout(panel5, BoxLayout.Y_AXIS));
|
||||
ManaBarChart chart4 = new ManaBarChart(pips_at_cmcs);
|
||||
chart4.setMinimumSize(new Dimension(200, 200));
|
||||
panel5.add(new JLabel("Mana distribution:"));
|
||||
panel5.add(chart4);
|
||||
|
||||
panel.add(panel2);
|
||||
panel.add(panel3);
|
||||
panel.add(panel4);
|
||||
panel.add(panel5);
|
||||
|
||||
JFrame frame = new JFrame("JOptionPane showMessageDialog component example");
|
||||
JOptionPane.showMessageDialog(frame, panel, "This is the distribution of colors found", JOptionPane.INFORMATION_MESSAGE);
|
||||
|
|
@ -1719,7 +1757,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
JMenuItem invertSelection = new JMenuItem("Invert Selection");
|
||||
invertSelection.addActionListener(e2 -> invertSelection());
|
||||
menu.add(invertSelection);
|
||||
|
||||
|
||||
JMenuItem chooseMatching = new JMenuItem("Choose Matching");
|
||||
chooseMatching.addActionListener(e2 -> chooseMatching());
|
||||
menu.add(chooseMatching);
|
||||
|
|
|
|||
151
Mage.Client/src/main/java/mage/client/cards/ManaBarChart.java
Normal file
151
Mage.Client/src/main/java/mage/client/cards/ManaBarChart.java
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
package mage.client.cards;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Stroke;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.HashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
|
||||
public class ManaBarChart extends JComponent {
|
||||
|
||||
HashMap<String, Integer> pips_at_cmcs = new HashMap<String, Integer>();
|
||||
|
||||
ManaBarChart() {
|
||||
}
|
||||
|
||||
ManaBarChart(HashMap<String, Integer> pips_at_cmcs) {
|
||||
this.pips_at_cmcs = pips_at_cmcs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
Dimension preferred = super.getPreferredSize();
|
||||
Dimension minimum = getMinimumSize();
|
||||
Dimension maximum = getMaximumSize();
|
||||
preferred.width = Math.min(Math.max(preferred.width, minimum.width), maximum.width);
|
||||
preferred.height = Math.min(Math.max(preferred.height, minimum.height), maximum.height);
|
||||
return preferred;
|
||||
}
|
||||
|
||||
public void paint(Graphics g) {
|
||||
drawBar((Graphics2D) g, getBounds());
|
||||
}
|
||||
|
||||
void drawBar(Graphics2D g, Rectangle area) {
|
||||
Pattern regex = Pattern.compile("^([0-9]+)##(.)}");
|
||||
HashMap<Integer, Integer> totals_at_cmcs = new HashMap<Integer, Integer>();
|
||||
int max_num_pips = 0;
|
||||
int max_cmc = 0;
|
||||
|
||||
for (String key : pips_at_cmcs.keySet()) {
|
||||
Matcher regexMatcher = regex.matcher(key);
|
||||
int num_pips = pips_at_cmcs.get(key);
|
||||
while (regexMatcher.find()) {
|
||||
String cmc = regexMatcher.group(1);
|
||||
int cmc_num = Integer.parseInt(cmc);
|
||||
if (max_cmc < cmc_num) {
|
||||
max_cmc = cmc_num;
|
||||
}
|
||||
|
||||
int total_at_cmc = 0;
|
||||
if (totals_at_cmcs.get(cmc_num) != null) {
|
||||
total_at_cmc = totals_at_cmcs.get(cmc_num);
|
||||
}
|
||||
totals_at_cmcs.put(cmc_num, total_at_cmc + num_pips);
|
||||
if (max_num_pips < total_at_cmc + num_pips) {
|
||||
max_num_pips = total_at_cmc + num_pips;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (max_num_pips <= 0) {
|
||||
max_num_pips = 1;
|
||||
}
|
||||
int height_factor = 200 / max_num_pips;
|
||||
int width_factor = 200 / (max_cmc + 2);
|
||||
if (width_factor > 20) {
|
||||
width_factor = 20;
|
||||
}
|
||||
if (width_factor < 11) {
|
||||
width_factor = 11;
|
||||
}
|
||||
|
||||
g.setColor(new Color(130, 130, 130));
|
||||
for (int i = 0; i < max_num_pips; i++) {
|
||||
if (max_num_pips > 10) {
|
||||
if (i % 10 == 0) {
|
||||
g.drawLine(0, 200 - 1 - i * height_factor, 400, 200 - 1 - i * height_factor);
|
||||
} else if (i % 10 == 5) {
|
||||
Stroke dashed = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{5}, 0);
|
||||
Stroke oldstroke = g.getStroke();
|
||||
g.setStroke(dashed);
|
||||
g.drawLine(0, 200 - 1 - i * height_factor, 400, 200 - 1 - i * height_factor);
|
||||
g.setStroke(oldstroke);
|
||||
}
|
||||
} else if (i % 2 == 0) {
|
||||
g.drawLine(0, 200 - 1 - i * height_factor, 400, 200 - 1 - i * height_factor);
|
||||
} else if (i % 2 == 1) {
|
||||
Stroke dashed = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{5}, 0);
|
||||
Stroke oldstroke = g.getStroke();
|
||||
g.setStroke(dashed);
|
||||
g.drawLine(0, 200 - 1 - i * height_factor, 400, 200 - 1 - i * height_factor);
|
||||
g.setStroke(oldstroke);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 17; i++) {
|
||||
if (i % 5 == 0) {
|
||||
g.drawLine(width_factor * i, 200, width_factor * i, 190);
|
||||
} else {
|
||||
g.drawLine(width_factor * i, 200, width_factor * i, 195);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
HashMap<Integer, Integer> running_totals_at_cmcs = new HashMap<Integer, Integer>();
|
||||
for (String key : pips_at_cmcs.keySet()) {
|
||||
Matcher regexMatcher = regex.matcher(key);
|
||||
int num_pips = pips_at_cmcs.get(key);
|
||||
while (regexMatcher.find()) {
|
||||
String cmc = regexMatcher.group(1);
|
||||
int cmc_num = Integer.parseInt(cmc);
|
||||
String color = regexMatcher.group(2);
|
||||
|
||||
int total_at_cmc = 0;
|
||||
if (running_totals_at_cmcs.get(cmc_num) != null) {
|
||||
total_at_cmc = running_totals_at_cmcs.get(cmc_num);
|
||||
}
|
||||
|
||||
if (color.equalsIgnoreCase("w")) {
|
||||
g.setColor(Color.WHITE);
|
||||
}
|
||||
if (color.equalsIgnoreCase("u")) {
|
||||
g.setColor(Color.BLUE);
|
||||
}
|
||||
if (color.equalsIgnoreCase("b")) {
|
||||
g.setColor(Color.BLACK);
|
||||
}
|
||||
if (color.equalsIgnoreCase("r")) {
|
||||
g.setColor(Color.RED);
|
||||
}
|
||||
if (color.equalsIgnoreCase("g")) {
|
||||
g.setColor(Color.GREEN);
|
||||
}
|
||||
if (color.equalsIgnoreCase("c")) {
|
||||
g.setColor(Color.DARK_GRAY);
|
||||
}
|
||||
g.fill(new Rectangle2D.Double(cmc_num * width_factor, 200 - 1 - total_at_cmc - num_pips * height_factor, 10, num_pips * height_factor));
|
||||
running_totals_at_cmcs.put(cmc_num, total_at_cmc + num_pips * height_factor);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -325,6 +325,7 @@ public class DeckGeneratorDialog {
|
|||
// Generated deck has a nice unique name which corresponds to the timestamp at which it was created.
|
||||
String deckName = "Generated-Deck-" + dateFormat.format(new Date());
|
||||
File tmp = new File(tempDir + File.separator + deckName + ".dck");
|
||||
tmp.getParentFile().mkdirs();
|
||||
tmp.createNewFile();
|
||||
deck.setName(deckName);
|
||||
Sets.saveDeck(tmp.getAbsolutePath(), deck.getDeckCardLists());
|
||||
|
|
|
|||
|
|
@ -341,7 +341,7 @@
|
|||
<Image iconType="3" name="/flags/us.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="W"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="Connect to xmage.us (USA)"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="Connect to vaporservermtg.com (USA)"/>
|
||||
<Property name="actionCommand" type="java.lang.String" value="connectXmageus"/>
|
||||
<Property name="alignmentY" type="float" value="0.0"/>
|
||||
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
|
||||
|
||||
/*
|
||||
/*
|
||||
* ConnectDialog.java
|
||||
*
|
||||
* Created on 20-Jan-2010, 9:37:07 PM
|
||||
|
|
@ -17,7 +15,6 @@ import java.io.FileReader;
|
|||
import java.io.FileWriter;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Writer;
|
||||
import java.io.Closeable;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.net.SocketException;
|
||||
|
|
@ -273,8 +270,8 @@ public class ConnectDialog extends MageDialog {
|
|||
});
|
||||
|
||||
btnFind3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/flags/us.png"))); // NOI18N
|
||||
btnFind3.setText("U");
|
||||
btnFind3.setToolTipText("Connect to xmage.us (USA)");
|
||||
btnFind3.setText("W");
|
||||
btnFind3.setToolTipText("Connect to vaporservermtg.com (USA)");
|
||||
btnFind3.setActionCommand("connectXmageus");
|
||||
btnFind3.setAlignmentY(0.0F);
|
||||
btnFind3.setMargin(new java.awt.Insets(2, 2, 2, 2));
|
||||
|
|
@ -646,7 +643,6 @@ public class ConnectDialog extends MageDialog {
|
|||
}
|
||||
}//GEN-LAST:event_jButton1ActionPerformed
|
||||
|
||||
|
||||
private void jProxySettingsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jProxySettingsButtonActionPerformed
|
||||
PreferencesDialog.main(new String[]{PreferencesDialog.OPEN_CONNECTION_TAB});
|
||||
}//GEN-LAST:event_jProxySettingsButtonActionPerformed
|
||||
|
|
@ -691,54 +687,54 @@ public class ConnectDialog extends MageDialog {
|
|||
|
||||
}//GEN-LAST:event_btnFind2findPublicServerActionPerformed
|
||||
|
||||
private void connectXmageus(java.awt.event.ActionEvent evt) {
|
||||
String serverAddress = "xmage.us";
|
||||
private void connectXmageus(java.awt.event.ActionEvent evt) {
|
||||
String serverAddress = "vapormtgserver.com";
|
||||
this.txtServer.setText(serverAddress);
|
||||
this.txtPort.setText("17171");
|
||||
// Update userName and password according to the chosen server.
|
||||
this.txtUserName.setText(MagePreferences.getUserName(serverAddress));
|
||||
this.txtPassword.setText(MagePreferences.getPassword(serverAddress));
|
||||
}
|
||||
}
|
||||
|
||||
private void btnFlagSearchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFlagSearchActionPerformed
|
||||
doFastFlagSearch();
|
||||
}//GEN-LAST:event_btnFlagSearchActionPerformed
|
||||
|
||||
private void doFastFlagSearch(){
|
||||
private void doFastFlagSearch() {
|
||||
Choice choice = new ChoiceImpl(false);
|
||||
|
||||
// collect data from country combobox String[name][code]
|
||||
Map<String, String> choiceItems = new LinkedHashMap<>();
|
||||
DefaultComboBoxModel flagModel = (DefaultComboBoxModel)cbFlag.getModel();
|
||||
DefaultComboBoxModel flagModel = (DefaultComboBoxModel) cbFlag.getModel();
|
||||
String[] flagItem;
|
||||
|
||||
for(int i = 0; i < flagModel.getSize(); i++){
|
||||
flagItem = (String[])flagModel.getElementAt(i);
|
||||
|
||||
for (int i = 0; i < flagModel.getSize(); i++) {
|
||||
flagItem = (String[]) flagModel.getElementAt(i);
|
||||
choiceItems.put(flagItem[1], flagItem[0]);
|
||||
}
|
||||
|
||||
|
||||
choice.setKeyChoices(choiceItems);
|
||||
choice.setMessage("Select your country");
|
||||
|
||||
|
||||
// current selection value restore
|
||||
String needSelectValue = null;
|
||||
flagItem = (String[])flagModel.getSelectedItem();
|
||||
if (flagItem != null){
|
||||
needSelectValue = flagItem[1];
|
||||
flagItem = (String[]) flagModel.getSelectedItem();
|
||||
if (flagItem != null) {
|
||||
needSelectValue = flagItem[1];
|
||||
}
|
||||
|
||||
// ask for new value
|
||||
PickChoiceDialog dlg = new PickChoiceDialog();
|
||||
dlg.setWindowSize(300, 500);
|
||||
dlg.showDialog(choice, needSelectValue);
|
||||
if(choice.isChosen()){
|
||||
if (choice.isChosen()) {
|
||||
flagItem = new String[2];
|
||||
flagItem[0] = choice.getChoiceValue();
|
||||
flagItem[1] = choice.getChoiceKey();
|
||||
flagModel.setSelectedItem(flagItem);
|
||||
flagItem[1] = choice.getChoiceKey();
|
||||
flagModel.setSelectedItem(flagItem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String getServer() {
|
||||
return this.txtServer.getText();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ package mage.client.table;
|
|||
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.beans.PropertyVetoException;
|
||||
import java.io.File;
|
||||
import java.text.DateFormat;
|
||||
|
|
@ -316,6 +318,20 @@ public class TablesPanel extends javax.swing.JPanel {
|
|||
actionButton1 = new ButtonColumn(tableTables, openTableAction, tableTables.convertColumnIndexToView(TableTableModel.ACTION_COLUMN));
|
||||
actionButton2 = new ButtonColumn(tableCompleted, closedTableAction, tableCompleted.convertColumnIndexToView(MatchesTableModel.COLUMN_ACTION));
|
||||
// !!!!
|
||||
addTableDoubleClickListener(tableTables, openTableAction);
|
||||
addTableDoubleClickListener(tableCompleted, closedTableAction);
|
||||
}
|
||||
|
||||
private void addTableDoubleClickListener(JTable table, Action action) {
|
||||
table.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
int row = table.rowAtPoint(e.getPoint());
|
||||
if (e.getClickCount() == 2 && row != -1) {
|
||||
action.actionPerformed(new ActionEvent(e.getSource(), e.getID(), "" + row));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void cleanUp() {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import mage.view.CardView;
|
|||
*/
|
||||
public class CardViewEDHPowerLevelComparator implements Comparator<CardView> {
|
||||
|
||||
public int getPowerLevel(CardView card) {
|
||||
private int getPowerLevel(CardView card) {
|
||||
|
||||
int thisMaxPower = 0;
|
||||
|
||||
|
|
@ -306,7 +306,7 @@ public class CardViewEDHPowerLevelComparator implements Comparator<CardView> {
|
|||
thisMaxPower = Math.max(thisMaxPower, 1);
|
||||
}
|
||||
|
||||
if (card.getCardTypes().contains("Plainswalker")) {
|
||||
if (card.isPlanesWalker()) {
|
||||
if (card.getName().toLowerCase(Locale.ENGLISH).equals("jace, the mind sculptor")) {
|
||||
thisMaxPower = Math.max(thisMaxPower, 6);
|
||||
}
|
||||
|
|
@ -509,7 +509,7 @@ public class CardViewEDHPowerLevelComparator implements Comparator<CardView> {
|
|||
|
||||
@Override
|
||||
public int compare(CardView o1, CardView o2) {
|
||||
return Integer.valueOf(getPowerLevel(o1)).compareTo(getPowerLevel(o2));
|
||||
return Integer.compare(getPowerLevel(o1), getPowerLevel(o2));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ public final class SaveObjectUtil {
|
|||
String time = now(DATE_PATTERN);
|
||||
File f = new File("income" + File.separator + name + '_' + time + ".save");
|
||||
if (!f.exists()) {
|
||||
f.getParentFile().mkdirs();
|
||||
f.createNewFile();
|
||||
}
|
||||
oos = new ObjectOutputStream(new FileOutputStream(f));
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ import java.util.regex.Pattern;
|
|||
import java.util.stream.IntStream;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
|
||||
import mage.cards.repository.ExpansionRepository;
|
||||
import mage.client.MageFrame;
|
||||
import mage.client.constants.Constants;
|
||||
|
|
@ -56,6 +57,8 @@ import org.apache.batik.util.SVGConstants;
|
|||
import org.apache.log4j.Logger;
|
||||
import org.mage.plugins.card.utils.CardImageUtils;
|
||||
|
||||
import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir;
|
||||
|
||||
public final class ManaSymbols {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(ManaSymbols.class);
|
||||
|
|
@ -79,21 +82,59 @@ public final class ManaSymbols {
|
|||
|
||||
withoutSymbols.add("MPRP");
|
||||
}
|
||||
|
||||
private static final Map<String, Dimension> setImagesExist = new HashMap<>();
|
||||
private static final Pattern REPLACE_SYMBOLS_PATTERN = Pattern.compile("\\{([^}/]*)/?([^}]*)\\}");
|
||||
|
||||
|
||||
private static final String[] symbols = new String[]{"0", "1", "10", "11", "12", "15", "16", "2", "3", "4", "5", "6", "7", "8", "9",
|
||||
"B", "BG", "BR", "BP", "2B",
|
||||
"G", "GU", "GW", "GP", "2G",
|
||||
"R", "RG", "RW", "RP", "2R",
|
||||
"S", "T",
|
||||
"U", "UB", "UR", "UP", "2U",
|
||||
"W", "WB", "WU", "WP", "2W",
|
||||
"X", "C", "E"};
|
||||
"B", "BG", "BR", "BP", "2B",
|
||||
"G", "GU", "GW", "GP", "2G",
|
||||
"R", "RG", "RW", "RP", "2R",
|
||||
"S", "T",
|
||||
"U", "UB", "UR", "UP", "2U",
|
||||
"W", "WB", "WU", "WP", "2W",
|
||||
"X", "C", "E"};
|
||||
|
||||
private static final JLabel labelRender = new JLabel(); // render mana text
|
||||
|
||||
private static String getSvgPathToCss() {
|
||||
return getImagesDir() + File.separator + "temp" + File.separator + "batic-svg-settings.css";
|
||||
}
|
||||
|
||||
private static void prepareSvg(Boolean forceToCreateCss) {
|
||||
File f = new File(getSvgPathToCss());
|
||||
|
||||
if (forceToCreateCss || !f.exists()) {
|
||||
|
||||
// Rendering hints can't be set programatically, so
|
||||
// we override defaults with a temporary stylesheet.
|
||||
// These defaults emphasize quality and precision, and
|
||||
// are more similar to the defaults of other SVG viewers.
|
||||
// SVG documents can still override these defaults.
|
||||
String css = "svg {"
|
||||
+ "shape-rendering: geometricPrecision;"
|
||||
+ "text-rendering: geometricPrecision;"
|
||||
+ "color-rendering: optimizeQuality;"
|
||||
+ "image-rendering: optimizeQuality;"
|
||||
+ "}";
|
||||
|
||||
FileWriter w = null;
|
||||
try {
|
||||
f.getParentFile().mkdirs();
|
||||
f.createNewFile();
|
||||
w = new FileWriter(f);
|
||||
w.write(css);
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Can't create css file for svg", e);
|
||||
} finally {
|
||||
StreamUtils.closeQuietly(w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void loadImages() {
|
||||
LOGGER.info("Loading symbols...");
|
||||
|
||||
// TODO: delete files rename jpg->gif (it was for backward compatibility for one of the old version?)
|
||||
renameSymbols(getResourceSymbolsPath(ResourceSymbolSize.SMALL));
|
||||
renameSymbols(getResourceSymbolsPath(ResourceSymbolSize.MEDIUM));
|
||||
|
|
@ -101,6 +142,9 @@ public final class ManaSymbols {
|
|||
//renameSymbols(getSymbolsPath(ResourceSymbolSize.SVG)); // not need
|
||||
// TODO: remove medium sets files to "medium" folder like symbols above?
|
||||
|
||||
// prepare svg settings
|
||||
prepareSvg(true);
|
||||
|
||||
// preload symbol images
|
||||
loadSymbolImages(15);
|
||||
loadSymbolImages(25);
|
||||
|
|
@ -171,7 +215,7 @@ public final class ManaSymbols {
|
|||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// generate small size
|
||||
try {
|
||||
File file = new File(getResourceSetsPath(ResourceSetSize.MEDIUM));
|
||||
|
|
@ -181,7 +225,7 @@ public final class ManaSymbols {
|
|||
String pathRoot = getResourceSetsPath(ResourceSetSize.SMALL) + set;
|
||||
for (String code : codes) {
|
||||
File newFile = new File(pathRoot + '-' + code + ".png");
|
||||
if(!(MageFrame.isSkipSmallSymbolGenerationForExisting() && newFile.exists())){// skip if option enabled and file already exists
|
||||
if (!(MageFrame.isSkipSmallSymbolGenerationForExisting() && newFile.exists())) {// skip if option enabled and file already exists
|
||||
file = new File(getResourceSetsPath(ResourceSetSize.MEDIUM) + set + '-' + code + ".png");
|
||||
if (file.exists()) {
|
||||
continue;
|
||||
|
|
@ -243,26 +287,9 @@ public final class ManaSymbols {
|
|||
|
||||
final BufferedImage[] imagePointer = new BufferedImage[1];
|
||||
|
||||
// Rendering hints can't be set programatically, so
|
||||
// we override defaults with a temporary stylesheet.
|
||||
// These defaults emphasize quality and precision, and
|
||||
// are more similar to the defaults of other SVG viewers.
|
||||
// SVG documents can still override these defaults.
|
||||
String css = "svg {"
|
||||
+ "shape-rendering: geometricPrecision;"
|
||||
+ "text-rendering: geometricPrecision;"
|
||||
+ "color-rendering: optimizeQuality;"
|
||||
+ "image-rendering: optimizeQuality;"
|
||||
+ "}";
|
||||
|
||||
File cssFile = File.createTempFile("batik-default-override-", ".css");
|
||||
FileWriter w = null;
|
||||
try {
|
||||
w = new FileWriter(cssFile);
|
||||
w.write(css);
|
||||
} finally {
|
||||
StreamUtils.closeQuietly(w);
|
||||
}
|
||||
// css settings for svg
|
||||
prepareSvg(false);
|
||||
File cssFile = new File(getSvgPathToCss());
|
||||
|
||||
TranscodingHints transcoderHints = new TranscodingHints();
|
||||
|
||||
|
|
@ -275,7 +302,7 @@ public final class ManaSymbols {
|
|||
shadowY = 2 * Math.round(1f / 16f * resizeToHeight);
|
||||
resizeToWidth = resizeToWidth - shadowX;
|
||||
resizeToHeight = resizeToHeight - shadowY;
|
||||
};
|
||||
}
|
||||
|
||||
if (resizeToWidth > 0) {
|
||||
transcoderHints.put(ImageTranscoder.KEY_WIDTH, (float) resizeToWidth); //your image width
|
||||
|
|
@ -311,8 +338,6 @@ public final class ManaSymbols {
|
|||
t.transcode(input, null);
|
||||
} catch (Exception e) {
|
||||
throw new IOException("Couldn't convert svg file: " + svgFile + " , reason: " + e.getMessage());
|
||||
} finally {
|
||||
cssFile.delete();
|
||||
}
|
||||
|
||||
BufferedImage originImage = imagePointer[0];
|
||||
|
|
@ -432,10 +457,11 @@ public final class ManaSymbols {
|
|||
// priority: SVG -> GIF
|
||||
// gif remain for backward compatibility
|
||||
|
||||
//boolean fileErrors = false;
|
||||
int[] iconErrors = new int[2]; // 0 - svg, 1 - gif
|
||||
|
||||
AtomicBoolean fileErrors = new AtomicBoolean(false);
|
||||
Map<String, BufferedImage> sizedSymbols = new ConcurrentHashMap<>();
|
||||
IntStream.range(0, symbols.length).parallel().forEach(i-> {
|
||||
IntStream.range(0, symbols.length).parallel().forEach(i -> {
|
||||
String symbol = symbols[i];
|
||||
BufferedImage image = null;
|
||||
File file;
|
||||
|
|
@ -448,7 +474,8 @@ public final class ManaSymbols {
|
|||
|
||||
// gif
|
||||
if (image == null) {
|
||||
//LOGGER.info("SVG symbol can't be load: " + file.getPath());
|
||||
|
||||
iconErrors[0] += 1; // svg fail
|
||||
|
||||
file = getSymbolFileNameAsGIF(symbol, size);
|
||||
if (file.exists()) {
|
||||
|
|
@ -460,11 +487,27 @@ public final class ManaSymbols {
|
|||
if (image != null) {
|
||||
sizedSymbols.put(symbol, image);
|
||||
} else {
|
||||
iconErrors[1] += 1; // gif fail
|
||||
fileErrors.set(true);
|
||||
LOGGER.warn("SVG or GIF symbol can't be load: " + symbol);
|
||||
}
|
||||
});
|
||||
|
||||
// total errors
|
||||
String errorInfo = "";
|
||||
if (iconErrors[0] > 0) {
|
||||
errorInfo += "SVG fails - " + iconErrors[0];
|
||||
}
|
||||
if (iconErrors[1] > 0) {
|
||||
if (!errorInfo.isEmpty()) {
|
||||
errorInfo += ", ";
|
||||
}
|
||||
errorInfo += "GIF fails - " + iconErrors[1];
|
||||
}
|
||||
|
||||
if (!errorInfo.isEmpty()) {
|
||||
LOGGER.warn("Symbols can't be load for size " + size + ": " + errorInfo);
|
||||
}
|
||||
|
||||
manaImages.put(size, sizedSymbols);
|
||||
return !fileErrors.get();
|
||||
}
|
||||
|
|
@ -563,8 +606,8 @@ public final class ManaSymbols {
|
|||
public static void draw(Graphics g, String manaCost, int x, int y, int symbolWidth, Color symbolsTextColor, int symbolMarginX) {
|
||||
if (!manaImages.containsKey(symbolWidth)) {
|
||||
loadSymbolImages(symbolWidth);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TODO: replace with jlabel render (look at table rendere)?
|
||||
|
||||
/*
|
||||
|
|
@ -614,7 +657,7 @@ public final class ManaSymbols {
|
|||
return;
|
||||
}
|
||||
|
||||
manaCost = manaCost.replace("\\", "");
|
||||
manaCost = manaCost.replace("\\", "");
|
||||
manaCost = UI.getDisplayManaCost(manaCost);
|
||||
StringTokenizer tok = new StringTokenizer(manaCost, " ");
|
||||
while (tok.hasMoreTokens()) {
|
||||
|
|
@ -739,7 +782,7 @@ public final class ManaSymbols {
|
|||
|
||||
replaced = REPLACE_SYMBOLS_PATTERN.matcher(replaced).replaceAll(
|
||||
"<img src='" + filePathToUrl(htmlImagesPath) + "$1$2" + ".png' alt='$1$2' width="
|
||||
+ symbolSize + " height=" + symbolSize + '>');
|
||||
+ symbolSize + " height=" + symbolSize + '>');
|
||||
|
||||
// ignore data restore
|
||||
replaced = replaced
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ public class DownloadGui extends JPanel {
|
|||
b.addActionListener(e -> {
|
||||
switch(this.job.getState()) {
|
||||
case NEW:
|
||||
case PREPARING:
|
||||
case WORKING:
|
||||
this.job.setState(State.ABORTED);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,16 +23,16 @@ import org.mage.plugins.card.utils.CardImageUtils;
|
|||
* The class DownloadJob.
|
||||
*
|
||||
* @version V0.0 25.08.2010
|
||||
* @author Clemens Koza
|
||||
* @author Clemens Koza, JayDi85
|
||||
*/
|
||||
public class DownloadJob extends AbstractLaternaBean {
|
||||
|
||||
public enum State {
|
||||
NEW, WORKING, FINISHED, ABORTED
|
||||
NEW, PREPARING, WORKING, FINISHED, ABORTED
|
||||
}
|
||||
|
||||
private final String name;
|
||||
private final Source source;
|
||||
private Source source;
|
||||
private final Destination destination;
|
||||
private final Property<State> state = properties.property("state", State.NEW);
|
||||
private final Property<String> message = properties.property("message");
|
||||
|
|
@ -98,6 +98,36 @@ public class DownloadJob extends AbstractLaternaBean {
|
|||
this.message.setValue(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inner prepare cycle from new to working
|
||||
*/
|
||||
public void doPrepareAndStartWork() {
|
||||
if (this.state.getValue() != State.NEW) {
|
||||
setError("Can't call prepare at this point.");
|
||||
return;
|
||||
}
|
||||
|
||||
this.state.setValue(State.PREPARING);
|
||||
|
||||
try {
|
||||
onPreparing();
|
||||
} catch (Exception e) {
|
||||
setError("Prepare error: " + e.getMessage(), e);
|
||||
return;
|
||||
}
|
||||
|
||||
// change to working state on good prepare call
|
||||
this.state.setValue(State.WORKING);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prepare code to override in custom download tasks (it's calls before work start)
|
||||
*/
|
||||
public void onPreparing() throws Exception {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the job's message.
|
||||
*
|
||||
|
|
@ -131,6 +161,10 @@ public class DownloadJob extends AbstractLaternaBean {
|
|||
return source;
|
||||
}
|
||||
|
||||
public void setSource(Source source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public Destination getDestination() {
|
||||
return destination;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ public class Downloader extends AbstractLaternaBean implements Disposable {
|
|||
for (DownloadJob j : jobs) {
|
||||
switch (j.getState()) {
|
||||
case NEW:
|
||||
case PREPARING:
|
||||
case WORKING:
|
||||
j.setState(State.ABORTED);
|
||||
}
|
||||
|
|
@ -82,8 +83,11 @@ public class Downloader extends AbstractLaternaBean implements Disposable {
|
|||
}
|
||||
|
||||
public void add(DownloadJob job) {
|
||||
if (job.getState() == State.PREPARING) {
|
||||
throw new IllegalArgumentException("Job already preparing");
|
||||
}
|
||||
if (job.getState() == State.WORKING) {
|
||||
throw new IllegalArgumentException("Job already running");
|
||||
throw new IllegalArgumentException("Job already working");
|
||||
}
|
||||
if (job.getState() == State.FINISHED) {
|
||||
throw new IllegalArgumentException("Job already finished");
|
||||
|
|
@ -106,13 +110,22 @@ public class Downloader extends AbstractLaternaBean implements Disposable {
|
|||
|
||||
@Override
|
||||
public void onMessage(DownloadJob job) {
|
||||
//the job won't be processed by multiple threads
|
||||
|
||||
// start to work
|
||||
// the job won't be processed by multiple threads
|
||||
synchronized (job) {
|
||||
if (job.getState() != State.NEW) {
|
||||
return;
|
||||
}
|
||||
job.setState(State.WORKING);
|
||||
|
||||
job.doPrepareAndStartWork();
|
||||
|
||||
if (job.getState() != State.WORKING) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// download and save data
|
||||
try {
|
||||
Source src = job.getSource();
|
||||
Destination dst = job.getDestination();
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import java.io.IOException;
|
|||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author spjspj
|
||||
*/
|
||||
public enum AltMtgOnlTokensImageSource implements CardImageSource {
|
||||
|
|
@ -60,7 +59,7 @@ public enum AltMtgOnlTokensImageSource implements CardImageSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String generateURL(CardDownloadData card) throws Exception {
|
||||
public CardImageUrls generateURL(CardDownloadData card) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -122,7 +121,7 @@ public enum AltMtgOnlTokensImageSource implements CardImageSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String generateTokenUrl(CardDownloadData card) throws IOException {
|
||||
public CardImageUrls generateTokenUrl(CardDownloadData card) throws IOException {
|
||||
if (copyUrlToImage == null) {
|
||||
setupLinks();
|
||||
}
|
||||
|
|
@ -139,12 +138,12 @@ public enum AltMtgOnlTokensImageSource implements CardImageSource {
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isTokenSource() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void doPause(String httpImageUrl) {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ import org.mage.plugins.card.images.CardDownloadData;
|
|||
*/
|
||||
public interface CardImageSource {
|
||||
|
||||
String generateURL(CardDownloadData card) throws Exception;
|
||||
CardImageUrls generateURL(CardDownloadData card) throws Exception;
|
||||
|
||||
String generateTokenUrl(CardDownloadData card) throws Exception;
|
||||
CardImageUrls generateTokenUrl(CardDownloadData card) throws Exception;
|
||||
|
||||
String getNextHttpImageUrl();
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
package org.mage.plugins.card.dl.sources;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public class CardImageUrls {
|
||||
|
||||
public String baseUrl;
|
||||
public List<String> alternativeUrls;
|
||||
|
||||
public CardImageUrls() {
|
||||
this.baseUrl = null;
|
||||
this.alternativeUrls = new ArrayList<>();
|
||||
}
|
||||
|
||||
public CardImageUrls(String baseUrl) {
|
||||
this(baseUrl, null);
|
||||
}
|
||||
|
||||
public CardImageUrls(String baseUrl, String alternativeUrl) {
|
||||
this();
|
||||
|
||||
this.baseUrl = baseUrl;
|
||||
|
||||
if (alternativeUrl != null && !alternativeUrl.isEmpty()) {
|
||||
this.alternativeUrls.add(alternativeUrl);
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getDownloadList() {
|
||||
List<String> downloadUrls = new ArrayList<>();
|
||||
|
||||
if (this.baseUrl != null && !this.baseUrl.isEmpty()) {
|
||||
downloadUrls.add(this.baseUrl);
|
||||
}
|
||||
|
||||
// no needs in base url duplicate
|
||||
if (this.alternativeUrls != null) {
|
||||
for (String url : this.alternativeUrls) {
|
||||
if (!url.equals(this.baseUrl)) {
|
||||
downloadUrls.add(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return downloadUrls;
|
||||
}
|
||||
|
||||
public void addAlternativeUrl(String url) {
|
||||
if (url != null && !url.isEmpty()) {
|
||||
this.alternativeUrls.add(url);
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,255 @@
|
|||
package org.mage.plugins.card.dl.sources;
|
||||
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.swing.JOptionPane;
|
||||
import mage.cards.Sets;
|
||||
import org.mage.plugins.card.images.CardDownloadData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author spjspj
|
||||
*/
|
||||
public enum CopyPasteImageSource implements CardImageSource {
|
||||
|
||||
instance;
|
||||
|
||||
private Set<String> supportedSets = new LinkedHashSet<String>();
|
||||
private Set<String> missingCards = new LinkedHashSet<String>();
|
||||
HashMap<String, String> singleLinks = null;
|
||||
boolean loadedFromDialog = false;
|
||||
boolean viewMissingCards = true;
|
||||
HashMap<String, Integer> singleLinksDone = null;
|
||||
private static int maxTimes = 2;
|
||||
|
||||
@Override
|
||||
public String getSourceName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAverageSize() {
|
||||
return 260.7f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNextHttpImageUrl() {
|
||||
if (singleLinks == null) {
|
||||
setupLinks();
|
||||
}
|
||||
|
||||
for (String key : singleLinksDone.keySet()) {
|
||||
if (singleLinksDone.get(key) < maxTimes) {
|
||||
singleLinksDone.put(key, maxTimes);
|
||||
return key;
|
||||
}
|
||||
}
|
||||
if (maxTimes < 2) {
|
||||
maxTimes++;
|
||||
}
|
||||
for (String key : singleLinksDone.keySet()) {
|
||||
if (singleLinksDone.get(key) < maxTimes) {
|
||||
singleLinksDone.put(key, maxTimes);
|
||||
return key;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFileForHttpImage(String httpImageUrl) {
|
||||
String copy = httpImageUrl;
|
||||
if (copy != null) {
|
||||
return singleLinks.get(copy);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CardImageUrls generateURL(CardDownloadData card) throws Exception {
|
||||
if (singleLinks == null) {
|
||||
setupLinks();
|
||||
}
|
||||
String url = singleLinks.get(card.getSet() + "/" + card.getName());
|
||||
if (url != null && url.length() > 0) {
|
||||
return new CardImageUrls(url);
|
||||
}
|
||||
url = singleLinks.get(card.getSet() + "/" + card.getName() + "." + card.getCollectorId());
|
||||
if (url != null && url.length() > 0) {
|
||||
return new CardImageUrls(url);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
int ls_size_mc = 0;
|
||||
int ls_size_ss = 0;
|
||||
int ls_size_sl = 0;
|
||||
int num_nos = 0;
|
||||
|
||||
private boolean isDifferent() {
|
||||
boolean isdiff = false;
|
||||
if (ls_size_mc != missingCards.size()) {
|
||||
ls_size_mc = missingCards.size();
|
||||
isdiff = true;
|
||||
}
|
||||
if (ls_size_ss != supportedSets.size()) {
|
||||
ls_size_ss = supportedSets.size();
|
||||
isdiff = true;
|
||||
}
|
||||
if (ls_size_sl != singleLinks.size()) {
|
||||
ls_size_sl = singleLinks.size();
|
||||
isdiff = true;
|
||||
}
|
||||
num_nos++;
|
||||
if (num_nos > 2) {
|
||||
num_nos = 0;
|
||||
isdiff = true;
|
||||
}
|
||||
return isdiff;
|
||||
}
|
||||
|
||||
private void setupLinks() {
|
||||
if (singleLinks != null && loadedFromDialog) {
|
||||
if (!viewMissingCards) {
|
||||
if (isDifferent() && JOptionPane.showConfirmDialog(null,
|
||||
"View your missing cards and reset the list of card images to download again?",
|
||||
"View missing cards (found " + missingCards.size() + ") / Reset URLs to download ", JOptionPane.YES_NO_OPTION)
|
||||
== JOptionPane.YES_OPTION) {
|
||||
viewMissingCards = true;
|
||||
singleLinks.clear();
|
||||
loadedFromDialog = false;
|
||||
supportedSets.clear();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!(viewMissingCards && missingCards.size() > 0)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
singleLinks = new HashMap<>();
|
||||
loadedFromDialog = false;
|
||||
|
||||
final CopyPasteImageSourceDialog dialog = new CopyPasteImageSourceDialog();
|
||||
dialog.pack();
|
||||
int count = 0;
|
||||
if (viewMissingCards && missingCards.size() > 0 && singleLinks.size() == 0) {
|
||||
viewMissingCards = false;
|
||||
String displayMissingCardsStr = "Up to the first 20 cards are:\n";
|
||||
String missingCardsStr = "";
|
||||
if (this.missingCards != null) {
|
||||
for (String card : this.missingCards) {
|
||||
if (count < 20) {
|
||||
displayMissingCardsStr = displayMissingCardsStr + card + "\n";
|
||||
}
|
||||
missingCardsStr = missingCardsStr + card + "\n";
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
StringSelection stringSelection = new StringSelection(missingCardsStr);
|
||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
clipboard.setContents(stringSelection, null);
|
||||
|
||||
if (isDifferent() && JOptionPane.showConfirmDialog(null,
|
||||
displayMissingCardsStr + "\n\nReset the list again?\n(NB: The full list has been copied to the clipboard)",
|
||||
"Your missing cards (found " + missingCards.size() + "): ", JOptionPane.YES_NO_OPTION)
|
||||
== JOptionPane.YES_OPTION) {
|
||||
viewMissingCards = true;
|
||||
singleLinks.clear();
|
||||
loadedFromDialog = false;
|
||||
supportedSets.clear();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
dialog.setVisible(true);
|
||||
String[] lines = dialog.getPastedData().split(System.getProperty("line.separator"));
|
||||
|
||||
for (String line : lines) {
|
||||
// Break into >> "\1", "\2"
|
||||
Pattern regex = Pattern.compile("\\s*\"(.*?)/(.*?)\"\\s*,\\s*\"(.*?)\"");
|
||||
Matcher regexMatcher = regex.matcher(line);
|
||||
while (regexMatcher.find()) {
|
||||
String setCode = regexMatcher.group(1);
|
||||
String cardName = regexMatcher.group(2);
|
||||
String imageURL = regexMatcher.group(3);
|
||||
supportedSets.add(setCode);
|
||||
singleLinks.put(setCode + "/" + cardName, imageURL);
|
||||
isDifferent();
|
||||
}
|
||||
}
|
||||
|
||||
loadedFromDialog = true;
|
||||
if (lines.length == 0) {
|
||||
loadedFromDialog = false;
|
||||
viewMissingCards = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CardImageUrls generateTokenUrl(CardDownloadData card) throws IOException {
|
||||
try {
|
||||
return generateURL(card);
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalImages() {
|
||||
if (singleLinks == null) {
|
||||
setupLinks();
|
||||
}
|
||||
if (singleLinks != null) {
|
||||
return singleLinks.size();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTokenSource() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayList<String> getSupportedSets() {
|
||||
setupLinks();
|
||||
ArrayList<String> supportedSetsCopy = new ArrayList<>();
|
||||
if (supportedSets.size() == 0) {
|
||||
for (String setCode : Sets.getInstance().keySet()) {
|
||||
supportedSets.add(setCode);
|
||||
}
|
||||
}
|
||||
|
||||
supportedSetsCopy.addAll(supportedSets);
|
||||
return supportedSetsCopy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doPause(String httpImageUrl) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImageProvided(String setCode, String cardName) {
|
||||
missingCards.add(setCode + "/" + cardName);
|
||||
|
||||
if (singleLinks != null) {
|
||||
return singleLinks.containsKey(setCode + "/" + cardName) || singleLinks.containsKey(setCode + "/" + cardName + "-a");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSetSupportedComplete(String setCode) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.mage.plugins.card.dl.sources.CopyPasteImageSourceDialog">
|
||||
<grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="10" left="10" bottom="10" right="10"/>
|
||||
<constraints>
|
||||
<xy x="48" y="54" width="540" height="500"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<minimumSize width="540" height="450"/>
|
||||
</properties>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<grid id="94766" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<hspacer id="98af6">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
<grid id="9538f" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="true" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="e7465" class="javax.swing.JButton" binding="buttonOK">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Import"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="5723f" class="javax.swing.JButton" binding="buttonCancel">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Cancel"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="e3588" layout-manager="FormLayout">
|
||||
<rowspec value="center:d:grow"/>
|
||||
<colspec value="fill:d:noGrow"/>
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="f8bac" class="javax.swing.JEditorPane" binding="txtDeckList">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="50"/>
|
||||
</grid>
|
||||
<forms defaultalign-horz="false" defaultalign-vert="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<minimumSize width="250" height="400"/>
|
||||
<preferredSize width="550" height="400"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
|
|
@ -0,0 +1,182 @@
|
|||
package org.mage.plugins.card.dl.sources;
|
||||
|
||||
import mage.util.StreamUtils;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
import javax.swing.*;
|
||||
|
||||
public class CopyPasteImageSourceDialog extends JDialog {
|
||||
|
||||
private JPanel contentPane;
|
||||
private JButton buttonOK;
|
||||
private JButton buttonCancel;
|
||||
private JEditorPane txtDeckList;
|
||||
|
||||
private String tmpPath;
|
||||
|
||||
public CopyPasteImageSourceDialog() {
|
||||
initComponents();
|
||||
setContentPane(contentPane);
|
||||
setModal(true);
|
||||
getRootPane().setDefaultButton(buttonOK);
|
||||
|
||||
buttonOK.addActionListener(e -> onOK());
|
||||
buttonCancel.addActionListener(e -> onCancel());
|
||||
|
||||
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
|
||||
addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
onCancel();
|
||||
}
|
||||
});
|
||||
|
||||
// Close on "ESC"
|
||||
contentPane.registerKeyboardAction(e -> onCancel(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
|
||||
}
|
||||
|
||||
private void onOK() {
|
||||
BufferedWriter bw = null;
|
||||
try {
|
||||
File temp = File.createTempFile("import_images_from_url", ".txt");
|
||||
bw = new BufferedWriter(new FileWriter(temp));
|
||||
bw.write(txtDeckList.getText());
|
||||
tmpPath = temp.getPath();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
StreamUtils.closeQuietly(bw);
|
||||
}
|
||||
|
||||
dispose();
|
||||
}
|
||||
|
||||
private void onCancel() {
|
||||
dispose();
|
||||
}
|
||||
|
||||
public String getTmpPath() {
|
||||
return tmpPath;
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
contentPane = new JPanel();
|
||||
JPanel panel1 = new JPanel();
|
||||
JPanel panel2 = new JPanel();
|
||||
buttonOK = new JButton();
|
||||
buttonCancel = new JButton();
|
||||
JPanel panel3 = new JPanel();
|
||||
txtDeckList = new JEditorPane();
|
||||
|
||||
{
|
||||
contentPane.setMinimumSize(new Dimension(540, 450));
|
||||
|
||||
contentPane.setBorder(new javax.swing.border.CompoundBorder(
|
||||
new javax.swing.border.TitledBorder(new javax.swing.border.EmptyBorder(0, 0, 0, 0),
|
||||
"Download Images from Copy/Pasted Text", javax.swing.border.TitledBorder.CENTER,
|
||||
javax.swing.border.TitledBorder.TOP, new java.awt.Font("Dialog", java.awt.Font.PLAIN, 12),
|
||||
java.awt.Color.BLACK), contentPane.getBorder()));
|
||||
|
||||
contentPane.addPropertyChangeListener(e -> {
|
||||
if ("border".equals(e.getPropertyName())) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
});
|
||||
|
||||
contentPane.addPropertyChangeListener(e -> {
|
||||
if ("border".equals(e.getPropertyName())) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
});
|
||||
|
||||
contentPane.setLayout(new GridBagLayout());
|
||||
((GridBagLayout) contentPane.getLayout()).columnWidths = new int[]{0, 0};
|
||||
((GridBagLayout) contentPane.getLayout()).rowHeights = new int[]{0, 0, 0};
|
||||
((GridBagLayout) contentPane.getLayout()).columnWeights = new double[]{0.01, 1.0E-4};
|
||||
((GridBagLayout) contentPane.getLayout()).rowWeights = new double[]{0.01, 0.0, 1.0E-4};
|
||||
|
||||
{
|
||||
panel1.setLayout(new GridBagLayout());
|
||||
((GridBagLayout) panel1.getLayout()).columnWidths = new int[]{0, 0, 0};
|
||||
((GridBagLayout) panel1.getLayout()).rowHeights = new int[]{0, 0};
|
||||
((GridBagLayout) panel1.getLayout()).columnWeights = new double[]{0.0, 0.01, 1.0E-4};
|
||||
((GridBagLayout) panel1.getLayout()).rowWeights = new double[]{0.01, 1.0E-4};
|
||||
|
||||
{
|
||||
panel2.setLayout(new GridBagLayout());
|
||||
((GridBagLayout) panel2.getLayout()).columnWidths = new int[]{0, 4, 0, 0};
|
||||
((GridBagLayout) panel2.getLayout()).rowHeights = new int[]{0, 0};
|
||||
((GridBagLayout) panel2.getLayout()).columnWeights = new double[]{0.01, 0.0, 0.01, 1.0E-4};
|
||||
((GridBagLayout) panel2.getLayout()).rowWeights = new double[]{0.0, 1.0E-4};
|
||||
|
||||
//---- buttonOK ----
|
||||
buttonOK.setText("Download from URLs");
|
||||
panel2.add(buttonOK, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
|
||||
GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
|
||||
new Insets(0, 0, 0, 0), 0, 0));
|
||||
|
||||
//---- buttonCancel ----
|
||||
buttonCancel.setText("Cancel");
|
||||
panel2.add(buttonCancel, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0,
|
||||
GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
|
||||
new Insets(0, 0, 0, 0), 0, 0));
|
||||
}
|
||||
panel1.add(panel2, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0,
|
||||
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
|
||||
new Insets(0, 0, 0, 0), 0, 0));
|
||||
}
|
||||
contentPane.add(panel1, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,
|
||||
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
|
||||
new Insets(0, 0, 0, 0), 0, 0));
|
||||
|
||||
{
|
||||
panel3.setLayout(new GridBagLayout());
|
||||
((GridBagLayout) panel3.getLayout()).columnWidths = new int[]{0, 0};
|
||||
((GridBagLayout) panel3.getLayout()).rowHeights = new int[]{0, 0};
|
||||
((GridBagLayout) panel3.getLayout()).columnWeights = new double[]{0.0, 1.0E-4};
|
||||
((GridBagLayout) panel3.getLayout()).rowWeights = new double[]{1.0, 1.0E-4};
|
||||
|
||||
txtDeckList.setMinimumSize(new Dimension(250, 400));
|
||||
txtDeckList.setPreferredSize(new Dimension(550, 400));
|
||||
|
||||
txtDeckList.setText("// Example follows. \nNB: **DELETE ALL TEXT AND GO SELECT THIS SOURCE AGAIN TO SEE THE NAMES CARDS YOU'RE MISSING IMAGES FOR!!!***\n\"SWS/Might of the Wild\", \"http://i.imgur.com/eNXOdxp.jpg\"\n\"PTC/Wolf of Devil's Breach\", \"https://img.scryfall.com/cards/large/en/psoi/192s.jpg\"\n\nExpected columns: Name of Card (Set Trigraph\\Name), URL of image\n\n\n");
|
||||
|
||||
JScrollPane txtScrollableDeckList = new JScrollPane(txtDeckList);
|
||||
panel3.add(txtScrollableDeckList, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0,
|
||||
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
|
||||
new Insets(0, 0, 0, 0), 0, 0));
|
||||
}
|
||||
contentPane.add(panel3, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
|
||||
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
|
||||
new Insets(0, 0, 5, 0), 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
Set<String> missingCards = null;
|
||||
|
||||
public void addMissingCards(Set<String> missingCards) {
|
||||
this.missingCards = missingCards;
|
||||
String missingCardsStr = "";
|
||||
boolean found = false;
|
||||
if (this.missingCards != null) {
|
||||
for (String card : this.missingCards) {
|
||||
found = true;
|
||||
missingCardsStr = missingCardsStr + card + "\n";
|
||||
}
|
||||
}
|
||||
if (found == false) {
|
||||
missingCardsStr = "\n\nNote: Leave blank to see your missing card names!\n";
|
||||
}
|
||||
txtDeckList.setText(txtDeckList.getText() + "\n\nYour missing card images are:\n" + missingCardsStr);
|
||||
}
|
||||
|
||||
public String getPastedData() {
|
||||
return txtDeckList.getText();
|
||||
}
|
||||
}
|
||||
|
|
@ -63,16 +63,16 @@ public class GathererSets implements Iterable<DownloadJob> {
|
|||
"POR", "P02", "PTK",
|
||||
"ARC", "DD3EVG",
|
||||
"W16", "W17",
|
||||
//"APAC" -- gatherer do not have that set, scrly have PALP
|
||||
//"APAC" -- gatherer do not have that set, scryfall has PALP
|
||||
//"ARENA" -- is't many set with different codes, not one
|
||||
"CLASH", "CP", "DD3GVL", "DPA", "EURO", "FNMP", "GPX", "GRC", "GUR", "H17", "JR", "MBP", "MGDC", "MLP", "MPRP", "MPS-AKH", "PTC", "S00", "S99", "SUS", "SWS", "UGIN", "UGL", "V10", "V17", "WMCQ", // need to fix
|
||||
"H09", "PD2", "PD3", "UNH", "CM1", "E02", "V11", "A25", "UST", "IMA", "DD2", "EVG", "DDC", "DDE", "DDD", "DDT", "8EB", "9EB", "CHR" // ok
|
||||
"H09", "PD2", "PD3", "UNH", "CM1", "V11", "A25", "UST", "IMA", "DD2", "EVG", "DDC", "DDE", "DDD", "8EB", "9EB", "CHR" // ok
|
||||
// current testing
|
||||
};
|
||||
|
||||
private static final String[] symbolsBasicWithMyth = {"M10", "M11", "M12", "M13", "M14", "M15", "ORI",
|
||||
"DDF", "DDG", "DDH", "DDI", "DDJ", "DDK", "DDL", "DDM", "DDN",
|
||||
"DD3DVD", "DD3JVC", "DDO", "DDP", "DDQ", "DDR", "DDS", "DDT",
|
||||
"DD3DVD", "DD3JVC", "DDO", "DDP", "DDQ", "DDR", "DDS", "DDT", "DDU",
|
||||
"ALA", "CON", "ARB",
|
||||
"ZEN", "WWK", "ROE",
|
||||
"SOM", "MBS", "NPH",
|
||||
|
|
@ -90,8 +90,9 @@ public class GathererSets implements Iterable<DownloadJob> {
|
|||
"KLD", "AER",
|
||||
"AKH", "HOU",
|
||||
"XLN", "C17",
|
||||
"RIX", "DOM", "M19", // not released
|
||||
"E01"
|
||||
"RIX", "DOM", "M19",
|
||||
"E01", "CM2", "E02",
|
||||
"GS1", "BBD", "C18"
|
||||
};
|
||||
|
||||
private static final String[] symbolsOnlyMyth = {
|
||||
|
|
@ -176,7 +177,7 @@ public class GathererSets implements Iterable<DownloadJob> {
|
|||
CheckResult res = setsToDownload.get(searchCode);
|
||||
|
||||
if (res != null) {
|
||||
logger.error(String.format("Symbols: founded duplicated code: %s", searchCode));
|
||||
logger.error(String.format("Symbols: found duplicate code: %s", searchCode));
|
||||
} else {
|
||||
res = new CheckResult(searchCode, foundedExp, haveCommon, haveUncommon, haveRare, haveMyth);
|
||||
setsToDownload.put(searchCode, res);
|
||||
|
|
@ -189,7 +190,7 @@ public class GathererSets implements Iterable<DownloadJob> {
|
|||
}
|
||||
|
||||
// checks for founded sets only
|
||||
// to early to download
|
||||
// too early to download
|
||||
if (!canDownloadTask) {
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.setTime(foundedExp.getReleaseDate());
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@ import java.util.LinkedHashSet;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.mage.plugins.card.images.CardDownloadData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author spjspj
|
||||
*/
|
||||
public enum GrabbagImageSource implements CardImageSource {
|
||||
|
|
@ -48,7 +48,7 @@ public enum GrabbagImageSource implements CardImageSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String generateURL(CardDownloadData card) throws Exception {
|
||||
public CardImageUrls generateURL(CardDownloadData card) throws Exception {
|
||||
if (singleLinks == null) {
|
||||
setupLinks();
|
||||
}
|
||||
|
|
@ -63,7 +63,7 @@ public enum GrabbagImageSource implements CardImageSource {
|
|||
}
|
||||
|
||||
if (url != null) {
|
||||
return getSourceName(card, url) + url;
|
||||
return new CardImageUrls(getSourceName(card, url) + url);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -357,10 +357,81 @@ public enum GrabbagImageSource implements CardImageSource {
|
|||
singleLinks.put("SWS/Yoda, Jedi Master", "6arN1Hl.png");
|
||||
singleLinks.put("SWS/Y-Wing", "aQQ5zwA.jpg");
|
||||
singleLinks.put("SWS/Zam Wesell", "ToG0C1r.jpg");
|
||||
singleLinks.put("SWS/Astromech Droid", "v0TpHMh.jpg");
|
||||
singleLinks.put("SWS/Buried Ruin", "QkmIWYg.png");
|
||||
singleLinks.put("SWS/Flame Trooper", "RkY7KFJ.jpg");
|
||||
singleLinks.put("SWS/Force Stasis", "FavLrcY.jpg");
|
||||
singleLinks.put("SWS/Salvage Trader", "qGwk7Bn.jpg");
|
||||
singleLinks.put("SWS/Outer Rim Gang", "kEjKQGy.png");
|
||||
singleLinks.put("SWS/Rathtar", "CYhHRqF.png");
|
||||
singleLinks.put("SWS/Riot Trooper", "PusvaQB.jpg");
|
||||
singleLinks.put("SWS/Sins of the Father", "32YHTPB.jpg");
|
||||
singleLinks.put("SWS/Upsilon-class Shuttle", "Le3F3oW.jpg");
|
||||
singleLinks.put("SWS/Finn", "TU2LI2q.jpg");
|
||||
singleLinks.put("SWS/General Hux", "UpWfcV6.png");
|
||||
singleLinks.put("SWS/Poe Dameron", "v8i21dn.png");
|
||||
singleLinks.put("SWS/Rey", "7n5ZZFA.png");
|
||||
singleLinks.put("SWS/Kylo Ren", "fFzDMTz.png");
|
||||
singleLinks.put("SWS/TIE Striker", "6b5GDUQ.jpg");
|
||||
singleLinks.put("SWS/Bludgeoning Pain", "ap5k3Wl.jpg");
|
||||
singleLinks.put("SWS/Force Protection", "GrOQLHO.jpg");
|
||||
singleLinks.put("SWS/Gerrera's Revolutionary", "FQFE1Jt.jpg");
|
||||
singleLinks.put("SWS/Thermal Detonator", "gTPLM83.jpg");
|
||||
singleLinks.put("SWS/Hammerhead Corvette", "IlhOAGv.jpg");
|
||||
singleLinks.put("SWS/U-Wing", "FmoRCmG.jpg");
|
||||
singleLinks.put("SWS/Bor Gullet", "jXafYHX.jpg");
|
||||
singleLinks.put("SWS/Imperial Hovertank", "6X1wL4d.jpg");
|
||||
singleLinks.put("SWS/Occupation", "h4mmkA5.jpg");
|
||||
singleLinks.put("SWS/Resistance", "lbNhA59.jpg");
|
||||
singleLinks.put("SWS/Jyn Erso and Cassian Andor", "o0SCGiJ.jpg");
|
||||
singleLinks.put("SWS/Chirrut Imwe", "wgtXfUF.jpg");
|
||||
singleLinks.put("SWS/Director Krennic", "52PGsH5.jpg");
|
||||
singleLinks.put("SWS/Vader's Command", "7Lql6UT.jpg");
|
||||
singleLinks.put("SWS/Delay Tactic", "ubmzD1m.jpg");
|
||||
singleLinks.put("SWS/Resistance Bomber", "Sudfkd7.jpg");
|
||||
singleLinks.put("SWS/Mouse Droid", "oO0p8QE.jpg");
|
||||
singleLinks.put("SWS/First Order Dreadnought", "80pO9Cc.jpg");
|
||||
singleLinks.put("SWS/TIE Silencer", "7yeYIjX.jpg");
|
||||
singleLinks.put("SWS/Canto Bight Enforcer", "VKPQVsn.jpg");
|
||||
singleLinks.put("SWS/Cantonica Casino", "7LiSvy6.jpg");
|
||||
singleLinks.put("SWS/Fathier", "0oKquQp.jpg");
|
||||
singleLinks.put("SWS/Code Slice", "7uNASji.jpg");
|
||||
singleLinks.put("SWS/Captain Phasma", "LWujx1B.jpg");
|
||||
singleLinks.put("SWS/Force Telepathy", "e90hswX.jpg");
|
||||
singleLinks.put("SWS/Praetorian Trooper", "pjS1wyS.jpg");
|
||||
singleLinks.put("SWS/Supreme Leader Snoke", "eewWiKE.jpg");
|
||||
singleLinks.put("SWS/Sai Tok", "FVn29tT.jpg");
|
||||
singleLinks.put("SWS/Porg Nest", "8DnNZKc.jpg");
|
||||
singleLinks.put("SWS/Inspire", "7lIXhtd.jpg");
|
||||
singleLinks.put("SWS/Force Projection", "5EfOwyn.jpg");
|
||||
singleLinks.put("SWS/Luke Skywalker, the Last Jedi", "WMmQcyD.jpg");
|
||||
singleLinks.put("SWS/Vulptex", "30WeCkw.jpg");
|
||||
singleLinks.put("SWS/Glorious Charge", "yJwvKzk.jpg");
|
||||
singleLinks.put("SWS/Plains-520b", "Fx59r9J.jpg");
|
||||
singleLinks.put("SWS/Island-520a", "jIPpWp5.jpg");
|
||||
singleLinks.put("SWS/Conscription", "An01yAe.jpg");
|
||||
singleLinks.put("SWS/Afterburn", "2ydqSvT.jpg");
|
||||
singleLinks.put("SWS/Corellian Gunship", "mZdDQWH.jpg");
|
||||
singleLinks.put("SWS/Despair", "TLTddMI.jpg");
|
||||
singleLinks.put("SWS/Dryden Vos", "6LbtUzN.jpg");
|
||||
singleLinks.put("SWS/Droid Uprising", "aWuoxho.jpg");
|
||||
singleLinks.put("SWS/Gamble", "Hwzr60O.jpg");
|
||||
singleLinks.put("SWS/Han Solo, Scrumrat", "Hqj39dG.jpg");
|
||||
singleLinks.put("SWS/Mud Trooper", "af8JaDy.jpg");
|
||||
singleLinks.put("SWS/Enfys Nest", "pstVfQg.jpg");
|
||||
singleLinks.put("SWS/Kalevan Star Yacht", "nHmSizp.jpg");
|
||||
singleLinks.put("SWS/Maelstrom Blockade", "sUYT0pc.jpg");
|
||||
singleLinks.put("SWS/Range Trooper", "kXGvTkE.jpg");
|
||||
singleLinks.put("SWS/Tobias Beckett", "hzm6ilE.jpg");
|
||||
singleLinks.put("SWS/Underground Forum", "FH2pRfU.jpg");
|
||||
singleLinks.put("SWS/Chewbacca, the Beast", "Zb5TitZ.jpg");
|
||||
|
||||
// Emblems
|
||||
singleLinks.put("SWS/Emblem Obi-Wan Kenobi", "Qyc10aT.png");
|
||||
singleLinks.put("SWS/Aurra Sing", "BLWbVJC.png");
|
||||
singleLinks.put("SWS/Yoda", "zH0sYxg.png");
|
||||
singleLinks.put("SWS/Emblem Luke Skywalker", "kHELZDJ.jpg");
|
||||
|
||||
// Tokens
|
||||
singleLinks.put("SWS/Ewok", "N2MvJyr.png");
|
||||
singleLinks.put("SWS/B-Wing", "oH62AUD.png");
|
||||
|
|
@ -372,10 +443,12 @@ public enum GrabbagImageSource implements CardImageSource {
|
|||
singleLinks.put("SWS/Royal Guard", "9tqE8vL.png");
|
||||
singleLinks.put("SWS/Tusken Raider", "gPMiSmP.png");
|
||||
singleLinks.put("SWS/Droid", "4PRrWFF.png");
|
||||
singleLinks.put("SWS/Trooper 2", "tcxvGOn.jpg");
|
||||
singleLinks.put("SWS/Porg", "HBjt1A3.jpg");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateTokenUrl(CardDownloadData card) throws IOException {
|
||||
public CardImageUrls generateTokenUrl(CardDownloadData card) throws IOException {
|
||||
try {
|
||||
return generateURL(card);
|
||||
} catch (Exception ex) {
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ import java.util.LinkedHashSet;
|
|||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import mage.client.dialog.PreferencesDialog;
|
||||
import org.mage.plugins.card.images.CardDownloadData;
|
||||
import org.mage.plugins.card.utils.CardImageUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author North
|
||||
*/
|
||||
public enum MagicCardsImageSource implements CardImageSource {
|
||||
|
|
@ -202,13 +202,15 @@ public enum MagicCardsImageSource implements CardImageSource {
|
|||
add("C17");
|
||||
add("XLN");
|
||||
add("DDT");
|
||||
add("DDU");
|
||||
add("IMA");
|
||||
add("E02");
|
||||
add("V17");
|
||||
add("UST");
|
||||
// add("RIX");
|
||||
// add("A25");
|
||||
// add("DOM");
|
||||
add("RIX");
|
||||
add("A25");
|
||||
add("DOM");
|
||||
// add("CM2");
|
||||
// add("M19");
|
||||
}
|
||||
};
|
||||
|
|
@ -263,7 +265,8 @@ public enum MagicCardsImageSource implements CardImageSource {
|
|||
put("DDQ", "duel-decks-blessed-vs-cursed");
|
||||
put("DDR", "duel-decks-nissa-vs-ob-nixilis");
|
||||
put("DDS", "duel-decks-mind-vs-might");
|
||||
put("DDS", "duel-decks-merfolk-vs-goblin");
|
||||
put("DDT", "duel-decks-merfolk-vs-goblin");
|
||||
put("DDU", "duel-decks-elves-vs-inventors");
|
||||
put("DGM", "dragons-maze");
|
||||
put("DKA", "dark-ascension");
|
||||
put("DRB", "from-the-vault-dragons");
|
||||
|
|
@ -339,6 +342,7 @@ public enum MagicCardsImageSource implements CardImageSource {
|
|||
put("WWK", "worldwake");
|
||||
put("ZEN", "zendikar");
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
};
|
||||
|
||||
|
|
@ -358,7 +362,7 @@ public enum MagicCardsImageSource implements CardImageSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String generateURL(CardDownloadData card) throws Exception {
|
||||
public CardImageUrls generateURL(CardDownloadData card) throws Exception {
|
||||
String collectorId = card.getCollectorId();
|
||||
String cardSet = card.getSet();
|
||||
if (collectorId == null || cardSet == null) {
|
||||
|
|
@ -386,11 +390,11 @@ public enum MagicCardsImageSource implements CardImageSource {
|
|||
}
|
||||
url.append(".jpg");
|
||||
|
||||
return url.toString();
|
||||
return new CardImageUrls(url.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateTokenUrl(CardDownloadData card) {
|
||||
public CardImageUrls generateTokenUrl(CardDownloadData card) {
|
||||
String name = card.getName();
|
||||
// add type to name if it's not 0
|
||||
if (card.getType() > 0) {
|
||||
|
|
@ -403,7 +407,7 @@ public enum MagicCardsImageSource implements CardImageSource {
|
|||
} else {
|
||||
set += '-' + card.getSet();
|
||||
}
|
||||
return "http://magiccards.info/extras/token/" + set + '/' + name + ".jpg";
|
||||
return new CardImageUrls("http://magiccards.info/extras/token/" + set + '/' + name + ".jpg");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ import java.util.LinkedHashSet;
|
|||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.mage.plugins.card.images.CardDownloadData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Pete Rossi
|
||||
*/
|
||||
public enum MagidexImageSource implements CardImageSource {
|
||||
|
|
@ -189,7 +189,6 @@ public enum MagidexImageSource implements CardImageSource {
|
|||
supportedSets.add("CN2");
|
||||
supportedSets.add("DDR");
|
||||
supportedSets.add("KLD");
|
||||
supportedSets.add("MPS");
|
||||
// supportedSets.add("PZ2"); // Treasure Chests
|
||||
supportedSets.add("C16");
|
||||
supportedSets.add("PCA");
|
||||
|
|
@ -208,11 +207,15 @@ public enum MagidexImageSource implements CardImageSource {
|
|||
supportedSets.add("IMA");
|
||||
supportedSets.add("E02");
|
||||
supportedSets.add("V17");
|
||||
// supportedSets.add("UST");
|
||||
// supportedSets.add("RIX");
|
||||
// supportedSets.add("A25");
|
||||
// supportedSets.add("DOM");
|
||||
// supportedSets.add("M19");
|
||||
supportedSets.add("UST");
|
||||
supportedSets.add("DDU");
|
||||
supportedSets.add("RIX");
|
||||
supportedSets.add("A25");
|
||||
supportedSets.add("DOM");
|
||||
supportedSets.add("CM2");
|
||||
supportedSets.add("M19");
|
||||
//supportedSets.add("BBD");
|
||||
//supportedSets.add("C18");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -231,7 +234,7 @@ public enum MagidexImageSource implements CardImageSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String generateURL(CardDownloadData card) throws Exception {
|
||||
public CardImageUrls generateURL(CardDownloadData card) throws Exception {
|
||||
String cardDownloadName = card.getDownloadName().toLowerCase(Locale.ENGLISH);
|
||||
String cardSet = card.getSet();
|
||||
|
||||
|
|
@ -245,7 +248,7 @@ public enum MagidexImageSource implements CardImageSource {
|
|||
|
||||
// This will properly escape the url
|
||||
URI uri = new URI("http", "magidex.com", "/extstatic/card/" + formatSetName(cardSet) + '/' + cardDownloadName + ".jpg", null, null);
|
||||
return uri.toASCIIString();
|
||||
return new CardImageUrls(uri.toASCIIString());
|
||||
}
|
||||
|
||||
private String formatSetName(String setName) {
|
||||
|
|
@ -262,7 +265,7 @@ public enum MagidexImageSource implements CardImageSource {
|
|||
};
|
||||
|
||||
@Override
|
||||
public String generateTokenUrl(CardDownloadData card) {
|
||||
public CardImageUrls generateTokenUrl(CardDownloadData card) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,14 +2,12 @@
|
|||
package org.mage.plugins.card.dl.sources;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.mage.plugins.card.images.CardDownloadData;
|
||||
|
||||
/**
|
||||
* Site was shutdown by wizards Feb. 2015
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public enum MtgImageSource implements CardImageSource {
|
||||
|
|
@ -32,7 +30,7 @@ public enum MtgImageSource implements CardImageSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String generateURL(CardDownloadData card) throws Exception {
|
||||
public CardImageUrls generateURL(CardDownloadData card) throws Exception {
|
||||
String collectorId = card.getCollectorId();
|
||||
String cardSet = card.getSet();
|
||||
if (collectorId == null || cardSet == null) {
|
||||
|
|
@ -59,11 +57,11 @@ public enum MtgImageSource implements CardImageSource {
|
|||
}
|
||||
url.append(".jpg");
|
||||
|
||||
return url.toString();
|
||||
return new CardImageUrls(url.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateTokenUrl(CardDownloadData card) {
|
||||
public CardImageUrls generateTokenUrl(CardDownloadData card) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,11 +3,11 @@ package org.mage.plugins.card.dl.sources;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.mage.plugins.card.images.CardDownloadData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author spjspj
|
||||
*/
|
||||
public enum MtgOnlTokensImageSource implements CardImageSource {
|
||||
|
|
@ -59,7 +59,7 @@ public enum MtgOnlTokensImageSource implements CardImageSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String generateURL(CardDownloadData card) throws Exception {
|
||||
public CardImageUrls generateURL(CardDownloadData card) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -324,7 +324,7 @@ public enum MtgOnlTokensImageSource implements CardImageSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String generateTokenUrl(CardDownloadData card) throws IOException {
|
||||
public CardImageUrls generateTokenUrl(CardDownloadData card) throws IOException {
|
||||
if (copyUrlToImage == null) {
|
||||
setupLinks();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package org.mage.plugins.card.dl.sources;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
|
|
@ -28,7 +27,6 @@ import org.jsoup.select.Elements;
|
|||
import org.mage.plugins.card.images.CardDownloadData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public enum MythicspoilerComSource implements CardImageSource {
|
||||
|
|
@ -232,6 +230,9 @@ public enum MythicspoilerComSource implements CardImageSource {
|
|||
supportedSets.add("RIX");
|
||||
supportedSets.add("DOM");
|
||||
supportedSets.add("BBD");
|
||||
supportedSets.add("M19");
|
||||
// supportedSets.add("C18");
|
||||
// supportedSets.add("CM2");
|
||||
|
||||
sets = new LinkedHashMap<>();
|
||||
setsAliases = new HashMap<>();
|
||||
|
|
@ -390,7 +391,7 @@ public enum MythicspoilerComSource implements CardImageSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String generateURL(CardDownloadData card) throws Exception {
|
||||
public CardImageUrls generateURL(CardDownloadData card) throws Exception {
|
||||
String collectorId = card.getCollectorId();
|
||||
String cardSet = card.getSet();
|
||||
if (collectorId == null || cardSet == null) {
|
||||
|
|
@ -409,11 +410,11 @@ public enum MythicspoilerComSource implements CardImageSource {
|
|||
.replaceAll(",", "")
|
||||
.replaceAll("/", "");
|
||||
String link = setLinks.get(searchName);
|
||||
return link;
|
||||
return new CardImageUrls(link);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateTokenUrl(CardDownloadData card
|
||||
public CardImageUrls generateTokenUrl(CardDownloadData card
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,19 +6,33 @@ import java.util.LinkedHashSet;
|
|||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import mage.client.dialog.PreferencesDialog;
|
||||
import org.mage.plugins.card.images.CardDownloadData;
|
||||
|
||||
/**
|
||||
* @author Quercitron, JayDi85
|
||||
*
|
||||
*/
|
||||
public enum ScryfallImageSource implements CardImageSource {
|
||||
|
||||
instance;
|
||||
|
||||
private final Set<String> supportedSets;
|
||||
private final Map<String, String> languageAliases;
|
||||
|
||||
ScryfallImageSource() {
|
||||
// https://scryfall.com/docs/api/languages
|
||||
languageAliases = new HashMap<>();
|
||||
languageAliases.put("en", "en");
|
||||
languageAliases.put("es", "es");
|
||||
languageAliases.put("jp", "ja");
|
||||
languageAliases.put("it", "it");
|
||||
languageAliases.put("fr", "fr");
|
||||
languageAliases.put("cn", "zhs"); // Simplified Chinese
|
||||
languageAliases.put("de", "de");
|
||||
languageAliases.put("ko", "ko");
|
||||
languageAliases.put("pt", "pt");
|
||||
languageAliases.put("ru", "ru");
|
||||
|
||||
supportedSets = new LinkedHashSet<>();
|
||||
// supportedSets.add("PTC"); //
|
||||
supportedSets.add("LEA");
|
||||
|
|
@ -205,40 +219,62 @@ public enum ScryfallImageSource implements CardImageSource {
|
|||
supportedSets.add("E02");
|
||||
supportedSets.add("V17");
|
||||
supportedSets.add("UST");
|
||||
supportedSets.add("DDU");
|
||||
supportedSets.add("RIX");
|
||||
supportedSets.add("WMCQ");
|
||||
supportedSets.add("PPRO");
|
||||
supportedSets.add("A25");
|
||||
supportedSets.add("DOM");
|
||||
supportedSets.add("BBD");
|
||||
// supportedSets.add("M19");
|
||||
|
||||
supportedSets.add("C18");
|
||||
supportedSets.add("CM2");
|
||||
supportedSets.add("M19");
|
||||
supportedSets.add("GS1");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateURL(CardDownloadData card) throws Exception {
|
||||
public CardImageUrls generateURL(CardDownloadData card) throws Exception {
|
||||
|
||||
String preferredLanguage = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PREF_LANGUAGE, "en");
|
||||
String defaultCode = "en";
|
||||
String localizedCode = languageAliases.getOrDefault(preferredLanguage, defaultCode);
|
||||
// loc example: https://api.scryfall.com/cards/xln/121/ru?format=image
|
||||
|
||||
// TODO: do not use API at all? It's can help with scryfall request limits (1 request instead 2)
|
||||
String baseUrl = null;
|
||||
String alternativeUrl = null;
|
||||
|
||||
// special card number like "103a" already compatible
|
||||
if (card.isCollectorIdWithStr()) {
|
||||
return "https://img.scryfall.com/cards/large/en/" + formatSetName(card.getSet()) + "/"
|
||||
if (baseUrl == null && card.isCollectorIdWithStr()) {
|
||||
baseUrl = "https://img.scryfall.com/cards/large/" + localizedCode + "/" + formatSetName(card.getSet()) + "/"
|
||||
+ card.getCollectorId() + ".jpg";
|
||||
alternativeUrl = "https://img.scryfall.com/cards/large/" + defaultCode + "/" + formatSetName(card.getSet()) + "/"
|
||||
+ card.getCollectorId() + ".jpg";
|
||||
}
|
||||
|
||||
// double faced cards do not supporte by API (need direct link for img)
|
||||
// double faced cards do not supports by API (need direct link for img)
|
||||
// example: https://img.scryfall.com/cards/large/en/xln/173b.jpg
|
||||
if (card.isTwoFacedCard()) {
|
||||
return "https://img.scryfall.com/cards/large/en/" + formatSetName(card.getSet()) + "/"
|
||||
if (baseUrl == null && card.isTwoFacedCard()) {
|
||||
baseUrl = "https://img.scryfall.com/cards/large/" + localizedCode + "/" + formatSetName(card.getSet()) + "/"
|
||||
+ card.getCollectorId() + (card.isSecondSide() ? "b" : "a") + ".jpg";
|
||||
alternativeUrl = "https://img.scryfall.com/cards/large/" + defaultCode + "/" + formatSetName(card.getSet()) + "/"
|
||||
+ card.getCollectorId() + (card.isSecondSide() ? "b" : "a") + ".jpg";
|
||||
}
|
||||
|
||||
// basic cards by api call (redirect to img link)
|
||||
// example: https://api.scryfall.com/cards/xln/121?format=image
|
||||
return "https://api.scryfall.com/cards/" + formatSetName(card.getSet()) + "/"
|
||||
+ card.getCollectorId() + "?format=image";
|
||||
// example: https://api.scryfall.com/cards/xln/121/en?format=image
|
||||
if (baseUrl == null) {
|
||||
baseUrl = "https://api.scryfall.com/cards/" + formatSetName(card.getSet()) + "/"
|
||||
+ card.getCollectorId() + "/" + localizedCode + "?format=image";
|
||||
alternativeUrl = "https://api.scryfall.com/cards/" + formatSetName(card.getSet()) + "/"
|
||||
+ card.getCollectorId() + "/" + defaultCode + "?format=image";
|
||||
}
|
||||
|
||||
return new CardImageUrls(baseUrl, alternativeUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateTokenUrl(CardDownloadData card) throws Exception {
|
||||
public CardImageUrls generateTokenUrl(CardDownloadData card) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,8 +9,13 @@ import java.util.*;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import mage.MageException;
|
||||
import mage.util.StreamUtils;
|
||||
import org.jsoup.select.Elements;
|
||||
import org.mage.plugins.card.dl.DownloadJob;
|
||||
import org.mage.plugins.card.utils.CardImageUtils;
|
||||
|
||||
import javax.swing.text.Document;
|
||||
|
||||
import static org.mage.card.arcane.ManaSymbols.getSymbolFileNameAsSVG;
|
||||
import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir;
|
||||
|
|
@ -18,14 +23,14 @@ import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir;
|
|||
// TODO: add force to download symbols (rewrite exist files)
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jaydi85@gmail.com
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
public class ScryfallSymbolsSource implements Iterable<DownloadJob> {
|
||||
|
||||
|
||||
static final String SOURCE_URL = "https://assets.scryfall.com/assets/scryfall.css"; // search css-file on https://scryfall.com/docs/api/colors
|
||||
//static final String SOURCE_URL = "https://assets.scryfall.com/assets/scryfall.css"; // old version with direct css-file on https://scryfall.com/docs/api/colors
|
||||
static final String CSS_SOURCE_URL = "https://scryfall.com/docs/api/colors";
|
||||
static final String CSS_SOURCE_SELECTOR = "link[rel=stylesheet]"; // <link rel="stylesheet" media="all" href="https://assets.scryfall.com/assets/scryfall-8cdaa786c4c86d5c49317e3e0fed72a0e409666753d3d3e8c906f33a188e19ed.css">
|
||||
static final String STATE_PROP_NAME = "state";
|
||||
static final String DOWNLOAD_TEMP_FILE = getImagesDir() + File.separator + "temp" + File.separator + "scryfall-symbols-source.txt";
|
||||
|
||||
|
|
@ -55,21 +60,21 @@ public class ScryfallSymbolsSource implements Iterable<DownloadJob> {
|
|||
return jobs.iterator();
|
||||
}
|
||||
|
||||
private void parseData(String sourcePath){
|
||||
private void parseData(String sourcePath) {
|
||||
|
||||
String sourceData = "";
|
||||
try {
|
||||
sourceData = new String(Files.readAllBytes(Paths.get(sourcePath)));
|
||||
}catch (IOException e) {
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Can't open file to parse data: " + sourcePath + " , reason: " + e.getMessage());
|
||||
}
|
||||
|
||||
// gen symbols list
|
||||
ArrayList<String> allMageSymbols = new ArrayList<>();
|
||||
for(int i = 0; i < SYMBOLS_LIST.length; i++){
|
||||
for (int i = 0; i < SYMBOLS_LIST.length; i++) {
|
||||
allMageSymbols.add(SYMBOLS_LIST[i]);
|
||||
}
|
||||
for(Integer i = SYMBOLS_NUMBER_START; i <= SYMBOLS_NUMBER_END; i++){
|
||||
for (Integer i = SYMBOLS_NUMBER_START; i <= SYMBOLS_NUMBER_END; i++) {
|
||||
allMageSymbols.add(String.valueOf(SYMBOLS_NUMBER_START + i));
|
||||
}
|
||||
|
||||
|
|
@ -88,23 +93,22 @@ public class ScryfallSymbolsSource implements Iterable<DownloadJob> {
|
|||
|
||||
// dirs maker
|
||||
File dir = getSymbolFileNameAsSVG("W").getParentFile();
|
||||
if(!dir.exists()){
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
|
||||
// decode and save data (only if not exist)
|
||||
for(String needCode: allMageSymbols){
|
||||
for (String needCode : allMageSymbols) {
|
||||
|
||||
String searchCode = needCode.replace("/", "");
|
||||
|
||||
if(!foundedData.containsKey(searchCode))
|
||||
{
|
||||
if (!foundedData.containsKey(searchCode)) {
|
||||
LOGGER.warn("Can't found symbol code from scryfall: " + searchCode);
|
||||
continue;
|
||||
}
|
||||
|
||||
File destFile = getSymbolFileNameAsSVG(searchCode);
|
||||
if (destFile.exists() && (destFile.length() > 0)){
|
||||
if (destFile.exists() && (destFile.length() > 0)) {
|
||||
continue;
|
||||
}
|
||||
FileOutputStream stream = null;
|
||||
|
|
@ -118,7 +122,7 @@ public class ScryfallSymbolsSource implements Iterable<DownloadJob> {
|
|||
stream.write(fileData);
|
||||
|
||||
LOGGER.info("New svg symbol downloaded: " + needCode);
|
||||
} catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Can't decode svg icon and save to file: " + destFile.getPath() + ", reason: " + e.getMessage());
|
||||
} finally {
|
||||
StreamUtils.closeQuietly(stream);
|
||||
|
|
@ -127,23 +131,26 @@ public class ScryfallSymbolsSource implements Iterable<DownloadJob> {
|
|||
}
|
||||
|
||||
|
||||
private class ScryfallSymbolsDownloadJob extends DownloadJob{
|
||||
private class ScryfallSymbolsDownloadJob extends DownloadJob {
|
||||
|
||||
private String cssUrl = ""; // need to find url from colors page https://scryfall.com/docs/api/colors
|
||||
|
||||
// listener for data parse after download complete
|
||||
private class ScryDownloadOnFinishedListener implements PropertyChangeListener {
|
||||
private class ScryfallDownloadOnFinishedListener implements PropertyChangeListener {
|
||||
private String downloadedFile;
|
||||
|
||||
public ScryDownloadOnFinishedListener(String ADestFile){
|
||||
public ScryfallDownloadOnFinishedListener(String ADestFile) {
|
||||
this.downloadedFile = ADestFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (!evt.getPropertyName().equals(STATE_PROP_NAME)){
|
||||
|
||||
if (!evt.getPropertyName().equals(STATE_PROP_NAME)) {
|
||||
throw new IllegalArgumentException("Unknown download property " + evt.getPropertyName());
|
||||
}
|
||||
|
||||
if (evt.getNewValue() != State.FINISHED){
|
||||
if (evt.getNewValue() != State.FINISHED) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -152,16 +159,34 @@ public class ScryfallSymbolsSource implements Iterable<DownloadJob> {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreparing() throws Exception {
|
||||
this.cssUrl = "";
|
||||
|
||||
org.jsoup.nodes.Document doc = CardImageUtils.downloadHtmlDocument(CSS_SOURCE_URL);
|
||||
org.jsoup.select.Elements cssList = doc.select(CSS_SOURCE_SELECTOR);
|
||||
if (cssList.size() == 1) {
|
||||
this.cssUrl = cssList.first().attr("href").toString();
|
||||
}
|
||||
|
||||
if (this.cssUrl.isEmpty()) {
|
||||
throw new IllegalStateException("Can't find stylesheet url from scryfall colors page.");
|
||||
} else {
|
||||
this.setSource(fromURL(this.cssUrl));
|
||||
}
|
||||
}
|
||||
|
||||
private String destFile = "";
|
||||
|
||||
public ScryfallSymbolsDownloadJob() {
|
||||
super("Scryfall symbols source", fromURL(SOURCE_URL), toFile(DOWNLOAD_TEMP_FILE));
|
||||
// download init
|
||||
super("Scryfall symbols source", fromURL(""), toFile(DOWNLOAD_TEMP_FILE)); // url setup on preparing stage
|
||||
this.destFile = DOWNLOAD_TEMP_FILE;
|
||||
this.addPropertyChangeListener(STATE_PROP_NAME, new ScryDownloadOnFinishedListener(this.destFile));
|
||||
this.addPropertyChangeListener(STATE_PROP_NAME, new ScryfallDownloadOnFinishedListener(this.destFile));
|
||||
|
||||
// clear dest file (always download new data)
|
||||
File file = new File(this.destFile);
|
||||
if (file.exists()){
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import java.util.Locale;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import mage.constants.SubType;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.mage.plugins.card.images.CardDownloadData;
|
||||
|
|
@ -23,7 +24,6 @@ import org.mage.plugins.card.images.DownloadPictures;
|
|||
import org.mage.plugins.card.utils.CardImageUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Quercitron
|
||||
*/
|
||||
public enum TokensMtgImageSource implements CardImageSource {
|
||||
|
|
@ -58,7 +58,7 @@ public enum TokensMtgImageSource implements CardImageSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String generateURL(CardDownloadData card) throws Exception {
|
||||
public CardImageUrls generateURL(CardDownloadData card) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ public enum TokensMtgImageSource implements CardImageSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String generateTokenUrl(CardDownloadData card) throws IOException {
|
||||
public CardImageUrls generateTokenUrl(CardDownloadData card) throws IOException {
|
||||
String name = card.getName();
|
||||
String set = card.getSet();
|
||||
int type = card.getType();
|
||||
|
|
@ -125,7 +125,7 @@ public enum TokensMtgImageSource implements CardImageSource {
|
|||
String url = "http://tokens.mtg.onl/tokens/" + tokenData.getExpansionSetCode().trim() + '_'
|
||||
+ tokenData.getNumber().trim() + '-' + tokenData.getName().trim() + ".jpg";
|
||||
url = url.replace(' ', '-');
|
||||
return url;
|
||||
return new CardImageUrls(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -248,7 +248,7 @@ public enum TokensMtgImageSource implements CardImageSource {
|
|||
List<TokenData> newTokensData = new ArrayList<>();
|
||||
|
||||
try (InputStreamReader inputReader = new InputStreamReader(inputStream, "Cp1252");
|
||||
BufferedReader reader = new BufferedReader(inputReader)) {
|
||||
BufferedReader reader = new BufferedReader(inputReader)) {
|
||||
// we have to specify encoding to read special comma
|
||||
|
||||
reader.readLine(); // skip header
|
||||
|
|
|
|||
|
|
@ -1,13 +1,6 @@
|
|||
|
||||
package org.mage.plugins.card.dl.sources;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
|
|
@ -19,21 +12,17 @@ import java.util.Set;
|
|||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.prefs.Preferences;
|
||||
import mage.cards.Sets;
|
||||
import mage.cards.repository.CardCriteria;
|
||||
import mage.cards.repository.CardInfo;
|
||||
import mage.cards.repository.CardRepository;
|
||||
import mage.client.MageFrame;
|
||||
import mage.client.dialog.PreferencesDialog;
|
||||
import mage.remote.Connection;
|
||||
import mage.remote.Connection.ProxyType;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
import org.mage.plugins.card.images.CardDownloadData;
|
||||
import org.mage.plugins.card.utils.CardImageUtils;
|
||||
|
||||
/**
|
||||
* @author North
|
||||
|
|
@ -231,13 +220,14 @@ public enum WizardCardsImageSource implements CardImageSource {
|
|||
supportedSets.add("DDS");
|
||||
supportedSets.add("W17");
|
||||
supportedSets.add("AKH");
|
||||
supportedSets.add("MPS");
|
||||
supportedSets.add("CMA");
|
||||
supportedSets.add("CM2"); // Commander Anthology, Vol. II
|
||||
supportedSets.add("E01");
|
||||
supportedSets.add("HOU");
|
||||
supportedSets.add("C17");
|
||||
supportedSets.add("XLN");
|
||||
supportedSets.add("DDT"); // Duel Decks: Merfolk vs. Goblins
|
||||
supportedSets.add("DDU"); // Duel Decks: Elves vs. Inventors
|
||||
supportedSets.add("IMA"); // Iconic Msters
|
||||
supportedSets.add("E02"); // Explorers of Ixalan
|
||||
supportedSets.add("V17"); // From the Vault: Transform
|
||||
|
|
@ -245,7 +235,12 @@ public enum WizardCardsImageSource implements CardImageSource {
|
|||
supportedSets.add("RIX"); // Rivals of Ixalan
|
||||
supportedSets.add("A25"); // Masters 25
|
||||
supportedSets.add("DOM"); // Dominaria
|
||||
// supportedSets.add("M19"); // Core 2019
|
||||
supportedSets.add("BBD"); // Battlebond
|
||||
supportedSets.add("GS1"); // Global Series: Jiang Yanggu and Mu Yanling
|
||||
supportedSets.add("M19"); // Core 2019
|
||||
supportedSets.add("C18"); // Commander 2018
|
||||
// supportedSets.add("GRN"); // Guilds of Ravnica
|
||||
// supportedSets.add("RNA"); // Ravnica Allegiance
|
||||
|
||||
sets = new HashMap<>();
|
||||
setsAliases = new HashMap<>();
|
||||
|
|
@ -282,6 +277,7 @@ public enum WizardCardsImageSource implements CardImageSource {
|
|||
setsAliases.put("C16", "Commander 2016");
|
||||
setsAliases.put("C17", "Commander 2017");
|
||||
setsAliases.put("CMA", "Commander Anthology");
|
||||
setsAliases.put("CM2", "Commander Anthology 2018");
|
||||
setsAliases.put("CHK", "Champions of Kamigawa");
|
||||
setsAliases.put("CHR", "Chronicles");
|
||||
setsAliases.put("CMD", "Magic: The Gathering-Commander");
|
||||
|
|
@ -312,6 +308,7 @@ public enum WizardCardsImageSource implements CardImageSource {
|
|||
setsAliases.put("DDR", "Duel Decks: Nissa vs. Ob Nixilis");
|
||||
setsAliases.put("DDS", "Duel Decks: Mind vs. Might");
|
||||
setsAliases.put("DDT", "Duel Decks: Merfolk vs. Goblins");
|
||||
setsAliases.put("DDU", "Duel Decks: Elves vs. Inventors");
|
||||
setsAliases.put("DGM", "Dragon's Maze");
|
||||
setsAliases.put("DIS", "Dissension");
|
||||
setsAliases.put("DKA", "Dark Ascension");
|
||||
|
|
@ -458,7 +455,7 @@ public enum WizardCardsImageSource implements CardImageSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String generateURL(CardDownloadData card) throws Exception {
|
||||
public CardImageUrls generateURL(CardDownloadData card) throws Exception {
|
||||
String collectorId = card.getCollectorId();
|
||||
String cardSet = card.getSet();
|
||||
if (collectorId == null || cardSet == null) {
|
||||
|
|
@ -491,7 +488,7 @@ public enum WizardCardsImageSource implements CardImageSource {
|
|||
List<String> l = new ArrayList<>(setLinks.values());
|
||||
if (l.size() >= number) {
|
||||
link = l.get(number - 1);
|
||||
} else {;
|
||||
} else {
|
||||
link = l.get(number - 21);
|
||||
if (link != null) {
|
||||
link = link.replace(Integer.toString(number - 20), (Integer.toString(number - 20) + 'a'));
|
||||
|
|
@ -504,8 +501,12 @@ public enum WizardCardsImageSource implements CardImageSource {
|
|||
if (link != null && !link.startsWith("http://")) {
|
||||
link = "http://gatherer.wizards.com" + link;
|
||||
}
|
||||
return link;
|
||||
|
||||
if (link != null) {
|
||||
return new CardImageUrls(link);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, String> getSetLinks(String cardSet) {
|
||||
|
|
@ -516,7 +517,7 @@ public enum WizardCardsImageSource implements CardImageSource {
|
|||
if (setNames == null) {
|
||||
setNames = Sets.getInstance().get(cardSet).getName();
|
||||
}
|
||||
String preferedLanguage = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PREF_LANGUAGE, "en");
|
||||
String preferredLanguage = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PREF_LANGUAGE, "en");
|
||||
for (String setName : setNames.split("\\^")) {
|
||||
// String URLSetName = URLEncoder.encode(setName, "UTF-8");
|
||||
String URLSetName = setName.replaceAll(" ", "%20");
|
||||
|
|
@ -526,7 +527,7 @@ public enum WizardCardsImageSource implements CardImageSource {
|
|||
while (page < 999) {
|
||||
String searchUrl = "http://gatherer.wizards.com/Pages/Search/Default.aspx?sort=cn+&page=" + page + "&action=advanced&output=spoiler&method=visual&set=+%5B%22" + URLSetName + "%22%5D";
|
||||
logger.debug("URL: " + searchUrl);
|
||||
Document doc = getDocument(searchUrl);
|
||||
Document doc = CardImageUtils.downloadHtmlDocument(searchUrl);
|
||||
Elements cardsImages = doc.select("img[src^=../../Handlers/]");
|
||||
if (cardsImages.isEmpty()) {
|
||||
break;
|
||||
|
|
@ -554,8 +555,8 @@ public enum WizardCardsImageSource implements CardImageSource {
|
|||
cardName = cardName.substring(0, pos1);
|
||||
}
|
||||
}
|
||||
Integer preferedMultiverseId = getLocalizedMultiverseId(preferedLanguage, multiverseId);
|
||||
setLinks.put(cardName.toLowerCase(Locale.ENGLISH) + numberChar, generateLink(preferedMultiverseId));
|
||||
Integer preferredMultiverseId = getLocalizedMultiverseId(preferredLanguage, multiverseId);
|
||||
setLinks.put(cardName.toLowerCase(Locale.ENGLISH) + numberChar, generateLink(preferredMultiverseId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -578,33 +579,6 @@ public enum WizardCardsImageSource implements CardImageSource {
|
|||
return setLinks;
|
||||
}
|
||||
|
||||
private Document getDocument(String urlString) throws NumberFormatException, IOException {
|
||||
Preferences prefs = MageFrame.getPreferences();
|
||||
Connection.ProxyType proxyType = Connection.ProxyType.valueByText(prefs.get("proxyType", "None"));
|
||||
Document doc;
|
||||
if (proxyType == ProxyType.NONE) {
|
||||
doc = Jsoup.connect(urlString).timeout(60 * 1000).get();
|
||||
} else {
|
||||
String proxyServer = prefs.get("proxyAddress", "");
|
||||
int proxyPort = Integer.parseInt(prefs.get("proxyPort", "0"));
|
||||
URL url = new URL(urlString);
|
||||
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyServer, proxyPort));
|
||||
HttpURLConnection uc = (HttpURLConnection) url.openConnection(proxy);
|
||||
uc.setConnectTimeout(10000);
|
||||
uc.setReadTimeout(60000);
|
||||
uc.connect();
|
||||
|
||||
String line;
|
||||
StringBuffer tmp = new StringBuffer();
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream()));
|
||||
while ((line = in.readLine()) != null) {
|
||||
tmp.append(line);
|
||||
}
|
||||
doc = Jsoup.parse(String.valueOf(tmp));
|
||||
}
|
||||
return doc;
|
||||
}
|
||||
|
||||
private void getLandVariations(LinkedHashMap<String, String> setLinks, String cardSet, int multiverseId, String cardName) throws IOException, NumberFormatException {
|
||||
CardCriteria criteria = new CardCriteria();
|
||||
criteria.nameExact(cardName);
|
||||
|
|
@ -612,7 +586,7 @@ public enum WizardCardsImageSource implements CardImageSource {
|
|||
List<CardInfo> cards = CardRepository.instance.findCards(criteria);
|
||||
|
||||
String urlLandDocument = "http://gatherer.wizards.com/Pages/Card/Details.aspx?multiverseid=" + multiverseId;
|
||||
Document landDoc = getDocument(urlLandDocument);
|
||||
Document landDoc = CardImageUtils.downloadHtmlDocument(urlLandDocument);
|
||||
Elements variations = landDoc.select("a.variationlink");
|
||||
if (!variations.isEmpty()) {
|
||||
if (variations.size() > cards.size()) {
|
||||
|
|
@ -643,12 +617,12 @@ public enum WizardCardsImageSource implements CardImageSource {
|
|||
return "/Handlers/Image.ashx?multiverseid=" + landMultiverseId + "&type=card";
|
||||
}
|
||||
|
||||
private int getLocalizedMultiverseId(String preferedLanguage, Integer multiverseId) throws IOException {
|
||||
if (preferedLanguage.equals("en")) {
|
||||
private int getLocalizedMultiverseId(String preferredLanguage, Integer multiverseId) throws IOException {
|
||||
if (preferredLanguage.equals("en")) {
|
||||
return multiverseId;
|
||||
}
|
||||
|
||||
String languageName = languageAliases.get(preferedLanguage);
|
||||
String languageName = languageAliases.get(preferredLanguage);
|
||||
HashMap<String, Integer> localizedLanguageIds = getlocalizedMultiverseIds(multiverseId);
|
||||
if (localizedLanguageIds.containsKey(languageName)) {
|
||||
return localizedLanguageIds.get(languageName);
|
||||
|
|
@ -659,7 +633,7 @@ public enum WizardCardsImageSource implements CardImageSource {
|
|||
|
||||
private HashMap<String, Integer> getlocalizedMultiverseIds(Integer englishMultiverseId) throws IOException {
|
||||
String cardLanguagesUrl = "http://gatherer.wizards.com/Pages/Card/Languages.aspx?multiverseid=" + englishMultiverseId;
|
||||
Document cardLanguagesDoc = getDocument(cardLanguagesUrl);
|
||||
Document cardLanguagesDoc = CardImageUtils.downloadHtmlDocument(cardLanguagesUrl);
|
||||
Elements languageTableRows = cardLanguagesDoc.select("tr.cardItem");
|
||||
HashMap<String, Integer> localizedIds = new HashMap<>();
|
||||
if (!languageTableRows.isEmpty()) {
|
||||
|
|
@ -699,7 +673,7 @@ public enum WizardCardsImageSource implements CardImageSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String generateTokenUrl(CardDownloadData card) {
|
||||
public CardImageUrls generateTokenUrl(CardDownloadData card) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -708,24 +682,24 @@ public enum WizardCardsImageSource implements CardImageSource {
|
|||
return 60.0f;
|
||||
}
|
||||
|
||||
// private final class GetImageLinkTask implements Runnable {
|
||||
// private final class GetImageLinkTask implements Runnable {
|
||||
//
|
||||
// private int multiverseId;
|
||||
// private String cardName;
|
||||
// private String preferedLanguage;
|
||||
// private String preferredLanguage;
|
||||
// private LinkedHashMap setLinks;
|
||||
//
|
||||
// public GetImageLinkTask(int multiverseId, String cardName, String preferedLanguage, LinkedHashMap setLinks) {
|
||||
// public GetImageLinkTask(int multiverseId, String cardName, String preferredLanguage, LinkedHashMap setLinks) {
|
||||
// try {
|
||||
// this.multiverseId = multiverseId;
|
||||
// this.cardName = cardName;
|
||||
// this.preferedLanguage = preferedLanguage;
|
||||
// this.preferredLanguage = preferredLanguage;
|
||||
// this.setLinks = setLinks;
|
||||
// } catch (Exception ex) {
|
||||
// logger.error(ex.getMessage());
|
||||
// logger.error("multiverseId: " + multiverseId);
|
||||
// logger.error("cardName: " + cardName);
|
||||
// logger.error("preferedLanguage: " + preferedLanguage);
|
||||
// logger.error("preferredLanguage: " + preferredLanguage);
|
||||
// logger.error("setLinks: " + setLinks.toString());
|
||||
// }
|
||||
// }
|
||||
|
|
@ -736,8 +710,8 @@ public enum WizardCardsImageSource implements CardImageSource {
|
|||
// if (cardName.equals("Forest") || cardName.equals("Swamp") || cardName.equals("Mountain") || cardName.equals("Island") || cardName.equals("Plains")) {
|
||||
// setLinks.putAll(getLandVariations(multiverseId, cardName));
|
||||
// } else {
|
||||
// Integer preferedMultiverseId = getLocalizedMultiverseId(preferedLanguage, multiverseId);
|
||||
// setLinks.put(cardName.toLowerCase(Locale.ENGLISH), generateLink(preferedMultiverseId));
|
||||
// Integer preferredMultiverseId = getLocalizedMultiverseId(preferredLanguage, multiverseId);
|
||||
// setLinks.put(cardName.toLowerCase(Locale.ENGLISH), generateLink(preferredMultiverseId));
|
||||
// }
|
||||
// } catch (IOException | NumberFormatException ex) {
|
||||
// logger.error("Exception when parsing the wizards page: " + ex.getMessage());
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import java.util.concurrent.ExecutorService;
|
|||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.swing.*;
|
||||
|
||||
import mage.cards.ExpansionSet;
|
||||
import mage.cards.Sets;
|
||||
import mage.cards.repository.CardCriteria;
|
||||
|
|
@ -33,6 +34,7 @@ import org.apache.log4j.Logger;
|
|||
import org.mage.plugins.card.dl.sources.*;
|
||||
import org.mage.plugins.card.properties.SettingsManager;
|
||||
import org.mage.plugins.card.utils.CardImageUtils;
|
||||
|
||||
import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir;
|
||||
|
||||
public class DownloadPictures extends DefaultBoundedRangeModel implements Runnable {
|
||||
|
|
@ -42,9 +44,9 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
|
|||
|
||||
private static final Logger logger = Logger.getLogger(DownloadPictures.class);
|
||||
|
||||
public static final String ALL_IMAGES = "- All images from that source";
|
||||
public static final String ALL_STANDARD_IMAGES = "- All images from standard from that source";
|
||||
public static final String ALL_TOKENS = "- Only all token images from that source";
|
||||
public static final String ALL_IMAGES = "- ALL images from selected source (CAN BE VERY SLOW)";
|
||||
public static final String ALL_STANDARD_IMAGES = "- Only images from STANDARD sets";
|
||||
public static final String ALL_TOKENS = "- Only token images from selected source";
|
||||
|
||||
private JDialog dialog;
|
||||
private final JProgressBar bar;
|
||||
|
|
@ -76,14 +78,15 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
|
|||
private Proxy p = Proxy.NO_PROXY;
|
||||
|
||||
enum DownloadSources {
|
||||
WIZARDS("wizards.com", WizardCardsImageSource.instance),
|
||||
MYTHICSPOILER("mythicspoiler.com", MythicspoilerComSource.instance),
|
||||
TOKENS("tokens.mtg.onl", TokensMtgImageSource.instance),
|
||||
WIZARDS("1. wizards.com - low quality CARDS, multi-language, can be SLOW", WizardCardsImageSource.instance),
|
||||
TOKENS("2. tokens.mtg.onl - high quality TOKENS", TokensMtgImageSource.instance),
|
||||
SCRYFALL("3. scryfall.com - high quality CARDS, multi-language", ScryfallImageSource.instance),
|
||||
MAGIDEX("4. magidex.com - high quality CARDS", MagidexImageSource.instance),
|
||||
GRAB_BAG("5. GrabBag - STAR WARS cards and tokens", GrabbagImageSource.instance),
|
||||
MYTHICSPOILER("6. mythicspoiler.com", MythicspoilerComSource.instance),
|
||||
ALTERNATIVE("7. alternative.mtg.onl", AltMtgOnlTokensImageSource.instance),
|
||||
COPYPASTE("8. Copy and Paste Image URLs", CopyPasteImageSource.instance);
|
||||
// MTG_ONL("mtg.onl", MtgOnlTokensImageSource.instance), Not working correctly yet
|
||||
ALTERNATIVE("alternative.mtg.onl", AltMtgOnlTokensImageSource.instance),
|
||||
GRAB_BAG("GrabBag", GrabbagImageSource.instance),
|
||||
MAGIDEX("magidex.com", MagidexImageSource.instance),
|
||||
SCRYFALL("scryfall.com", ScryfallImageSource.instance);
|
||||
// MAGICCARDS("magiccards.info", MagicCardsImageSource.instance)
|
||||
|
||||
private final String text;
|
||||
|
|
@ -485,7 +488,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
|
|||
}
|
||||
|
||||
try (InputStreamReader input = new InputStreamReader(in);
|
||||
BufferedReader reader = new BufferedReader(input)) {
|
||||
BufferedReader reader = new BufferedReader(input)) {
|
||||
|
||||
String line = reader.readLine();
|
||||
while (line != null) {
|
||||
|
|
@ -597,25 +600,25 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
|
|||
|
||||
logger.debug("Downloading image: " + card.getName() + " (" + card.getSet() + ')');
|
||||
|
||||
String url;
|
||||
CardImageUrls urls;
|
||||
|
||||
if (ignoreUrls.contains(card.getSet()) || card.isToken()) {
|
||||
if (!"0".equals(card.getCollectorId())) {
|
||||
continue;
|
||||
}
|
||||
url = cardImageSource.generateTokenUrl(card);
|
||||
urls = cardImageSource.generateTokenUrl(card);
|
||||
} else {
|
||||
url = cardImageSource.generateURL(card);
|
||||
urls = cardImageSource.generateURL(card);
|
||||
}
|
||||
|
||||
if (url == null) {
|
||||
if (urls == null) {
|
||||
String imageRef = cardImageSource.getNextHttpImageUrl();
|
||||
String fileName = cardImageSource.getFileForHttpImage(imageRef);
|
||||
if (imageRef != null && fileName != null) {
|
||||
imageRef = cardImageSource.getSourceName() + imageRef;
|
||||
try {
|
||||
URL imageUrl = new URL(imageRef);
|
||||
card.setToken(cardImageSource.isTokenSource());
|
||||
Runnable task = new DownloadTask(card, imageUrl, fileName, cardImageSource.getTotalImages());
|
||||
Runnable task = new DownloadTask(card, imageRef, fileName, cardImageSource.getTotalImages());
|
||||
executor.execute(task);
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
|
|
@ -626,7 +629,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
|
|||
}
|
||||
}
|
||||
} else {
|
||||
Runnable task = new DownloadTask(card, new URL(url), cardsToDownload.size());
|
||||
Runnable task = new DownloadTask(card, urls, cardsToDownload.size());
|
||||
executor.execute(task);
|
||||
}
|
||||
|
||||
|
|
@ -662,22 +665,26 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
|
|||
private final class DownloadTask implements Runnable {
|
||||
|
||||
private final CardDownloadData card;
|
||||
private final URL url;
|
||||
private final CardImageUrls urls;
|
||||
private final int count;
|
||||
private final String actualFilename;
|
||||
private final boolean useSpecifiedPaths;
|
||||
|
||||
DownloadTask(CardDownloadData card, URL url, int count) {
|
||||
DownloadTask(CardDownloadData card, String baseUrl, int count) {
|
||||
this(card, new CardImageUrls(baseUrl, null), count);
|
||||
}
|
||||
|
||||
DownloadTask(CardDownloadData card, CardImageUrls urls, int count) {
|
||||
this.card = card;
|
||||
this.url = url;
|
||||
this.urls = urls;
|
||||
this.count = count;
|
||||
this.actualFilename = "";
|
||||
useSpecifiedPaths = false;
|
||||
}
|
||||
|
||||
DownloadTask(CardDownloadData card, URL url, String actualFilename, int count) {
|
||||
DownloadTask(CardDownloadData card, String baseUrl, String actualFilename, int count) {
|
||||
this.card = card;
|
||||
this.url = url;
|
||||
this.urls = new CardImageUrls(baseUrl, null);
|
||||
this.count = count;
|
||||
this.actualFilename = actualFilename;
|
||||
useSpecifiedPaths = true;
|
||||
|
|
@ -751,14 +758,55 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
|
|||
}
|
||||
}
|
||||
|
||||
cardImageSource.doPause(url.getPath());
|
||||
URLConnection httpConn = url.openConnection(p);
|
||||
httpConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2");
|
||||
httpConn.connect();
|
||||
int responseCode = ((HttpURLConnection) httpConn).getResponseCode();
|
||||
// can download images from many alternative urls
|
||||
List<String> downloadUrls;
|
||||
if (this.urls != null) {
|
||||
downloadUrls = this.urls.getDownloadList();
|
||||
} else {
|
||||
downloadUrls = new ArrayList<>();
|
||||
}
|
||||
|
||||
if (responseCode == 200) {
|
||||
// download OK
|
||||
boolean isDownloadOK = false;
|
||||
URLConnection httpConn = null;
|
||||
List<String> errorsList = new ArrayList<>();
|
||||
for (String currentUrl : downloadUrls) {
|
||||
URL url = new URL(currentUrl);
|
||||
|
||||
// on download cancel need to stop
|
||||
if (cancel) {
|
||||
return;
|
||||
}
|
||||
|
||||
// download
|
||||
cardImageSource.doPause(url.getPath());
|
||||
httpConn = url.openConnection(p);
|
||||
httpConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2");
|
||||
httpConn.connect();
|
||||
int responseCode = ((HttpURLConnection) httpConn).getResponseCode();
|
||||
|
||||
// check result
|
||||
if (responseCode != 200) {
|
||||
// show errors only on full fail (all urls were not work)
|
||||
errorsList.add("Image download for " + card.getName()
|
||||
+ (!card.getDownloadName().equals(card.getName()) ? " downloadname: " + card.getDownloadName() : "")
|
||||
+ " (" + card.getSet() + ") failed - responseCode: " + responseCode + " url: " + url.toString());
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
// Shows the returned html from the request to the web server
|
||||
logger.debug("Returned HTML ERROR:\n" + convertStreamToString(((HttpURLConnection) httpConn).getErrorStream()));
|
||||
}
|
||||
|
||||
// go to next try
|
||||
continue;
|
||||
} else {
|
||||
// all fine
|
||||
isDownloadOK = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// can save result
|
||||
if (isDownloadOK & httpConn != null) {
|
||||
// save data to temp
|
||||
OutputStream out = null;
|
||||
OutputStream tfileout = null;
|
||||
|
|
@ -792,8 +840,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
|
|||
}
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
StreamUtils.closeQuietly(in);
|
||||
StreamUtils.closeQuietly(out);
|
||||
StreamUtils.closeQuietly(tfileout);
|
||||
|
|
@ -815,15 +862,9 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
|
|||
|
||||
}
|
||||
} else {
|
||||
// download ERROR
|
||||
logger.warn("Image download for " + card.getName()
|
||||
+ (!card.getDownloadName().equals(card.getName()) ? " downloadname: " + card.getDownloadName() : "")
|
||||
+ " (" + card.getSet() + ") failed - responseCode: " + responseCode + " url: " + url.toString()
|
||||
);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
// Shows the returned html from the request to the web server
|
||||
logger.debug("Returned HTML ERROR:\n" + convertStreamToString(((HttpURLConnection) httpConn).getErrorStream()));
|
||||
// download errors
|
||||
for (String err : errorsList) {
|
||||
logger.warn(err);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,17 @@
|
|||
package org.mage.plugins.card.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
import mage.client.MageFrame;
|
||||
import mage.client.constants.Constants;
|
||||
import mage.client.dialog.PreferencesDialog;
|
||||
|
|
@ -13,6 +19,8 @@ import mage.remote.Connection;
|
|||
import mage.remote.Connection.ProxyType;
|
||||
import net.java.truevfs.access.TFile;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.mage.plugins.card.images.CardDownloadData;
|
||||
import org.mage.plugins.card.properties.SettingsManager;
|
||||
|
||||
|
|
@ -22,7 +30,6 @@ public final class CardImageUtils {
|
|||
private static final Logger log = Logger.getLogger(CardImageUtils.class);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param card
|
||||
* @return String if image exists, else null
|
||||
*/
|
||||
|
|
@ -54,7 +61,6 @@ public final class CardImageUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param card
|
||||
* @return String regardless of whether image exists
|
||||
*/
|
||||
|
|
@ -280,4 +286,31 @@ public final class CardImageUtils {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Document downloadHtmlDocument(String urlString) throws NumberFormatException, IOException {
|
||||
Preferences prefs = MageFrame.getPreferences();
|
||||
Connection.ProxyType proxyType = Connection.ProxyType.valueByText(prefs.get("proxyType", "None"));
|
||||
Document doc;
|
||||
if (proxyType == ProxyType.NONE) {
|
||||
doc = Jsoup.connect(urlString).timeout(60 * 1000).get();
|
||||
} else {
|
||||
String proxyServer = prefs.get("proxyAddress", "");
|
||||
int proxyPort = Integer.parseInt(prefs.get("proxyPort", "0"));
|
||||
URL url = new URL(urlString);
|
||||
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyServer, proxyPort));
|
||||
HttpURLConnection uc = (HttpURLConnection) url.openConnection(proxy);
|
||||
uc.setConnectTimeout(10000);
|
||||
uc.setReadTimeout(60000);
|
||||
uc.connect();
|
||||
|
||||
String line;
|
||||
StringBuffer tmp = new StringBuffer();
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream()));
|
||||
while ((line = in.readLine()) != null) {
|
||||
tmp.append(line);
|
||||
}
|
||||
doc = Jsoup.parse(String.valueOf(tmp));
|
||||
}
|
||||
return doc;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -357,6 +357,7 @@
|
|||
|Generate|TOK:C17|Rat|||DeathtouchRatToken|
|
||||
|Generate|TOK:C17|Vampire|||EdgarMarkovToken|
|
||||
|Generate|TOK:C17|Zombie||
|
||||
|Generate|TOK:C18|Myr|||BrudicladTelchorMyrToken|
|
||||
|Generate|TOK:CHK|Dragon Spirit|||TatsumaDragonToken|
|
||||
|Generate|TOK:CHK|Elemental|||SeedGuardianToken|
|
||||
|Generate|TOK:CHK|Illusion|||MelokuTheCloudedMirrorToken|
|
||||
|
|
|
|||
|
|
@ -73,6 +73,6 @@ dd3evg=ddaevg
|
|||
dd3gvl=ddagvl
|
||||
dd3jvc=ddajvc
|
||||
# Remove setname as soon as the images can be downloaded
|
||||
ignore.urls=TOK,M19,H17
|
||||
ignore.urls=TOK,H17
|
||||
# sets ordered by release time (newest goes first)
|
||||
token.lookup.order=M19,A25,DOM,E02,RIX,UST,XLN,IMA,H17,C17,V17,E01,DDT,CMA,HOU,MM3,DDS,AKH,DD3DVD,DD3EVG,DD3GVL,DD3JVC,H09,AER,PCA,C16,V16,MPS,KLD,DDR,CN2,EMN,EMA,SOI,DDQ,CP,CMA,ARENA,SUS,APAC,EURO,UGIN,C15,OGW,EXP,DDP,BFZ,DRB,V09,V10,V11,V12,V13,V14,V15,TPR,MPRP,DD3,DDO,ORI,MM2,PTC,DTK,FRF,KTK,M15,VMA,CNS,JOU,BNG,THS,DDL,M14,MMA,DGM,GTC,RTR,M13,AVR,DDI,DKA,ISD,M12,NPH,MBS,SOM,M11,ROE,DDE,WWK,ZEN,M10,GVL,ARB,DVD,CFX,JVC,ALA,EVE,SHM,EVG,MOR,LRW,10E,CLS,CHK,GRC
|
||||
token.lookup.order=C18,M19,A25,DOM,E02,RIX,UST,XLN,IMA,H17,C17,V17,E01,DDT,CMA,HOU,MM3,DDS,AKH,DD3DVD,DD3EVG,DD3GVL,DD3JVC,H09,AER,PCA,C16,V16,MPS,KLD,DDR,CN2,EMN,EMA,SOI,DDQ,CP,CMA,ARENA,SUS,APAC,EURO,UGIN,C15,OGW,EXP,DDP,BFZ,DRB,V09,V10,V11,V12,V13,V14,V15,TPR,MPRP,DD3,DDO,ORI,MM2,PTC,DTK,FRF,KTK,M15,VMA,CNS,JOU,BNG,THS,DDL,M14,MMA,DGM,GTC,RTR,M13,AVR,DDI,DKA,ISD,M12,NPH,MBS,SOM,M11,ROE,DDE,WWK,ZEN,M10,GVL,ARB,DVD,CFX,JVC,ALA,EVE,SHM,EVG,MOR,LRW,10E,CLS,CHK,GRC
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -4,11 +4,11 @@ import org.junit.Assert;
|
|||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mage.plugins.card.dl.sources.CardImageSource;
|
||||
import org.mage.plugins.card.dl.sources.CardImageUrls;
|
||||
import org.mage.plugins.card.dl.sources.TokensMtgImageSource;
|
||||
import org.mage.plugins.card.images.CardDownloadData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Quercitron
|
||||
*/
|
||||
@Ignore
|
||||
|
|
@ -18,15 +18,16 @@ public class TokensMtgImageSourceTest {
|
|||
public void generateTokenUrlTest() throws Exception {
|
||||
CardImageSource imageSource = TokensMtgImageSource.instance;
|
||||
|
||||
String url = imageSource.generateTokenUrl(new CardDownloadData("Thopter", "ORI", "0", false, 1, "ORI", ""));
|
||||
Assert.assertEquals("http://tokens.mtg.onl/tokens/ORI_010-Thopter.jpg", url);
|
||||
CardImageUrls url = imageSource.generateTokenUrl(new CardDownloadData("Thopter", "ORI", "0", false, 1, "ORI", ""));
|
||||
Assert.assertEquals("http://tokens.mtg.onl/tokens/ORI_010-Thopter.jpg", url.baseUrl);
|
||||
|
||||
url = imageSource.generateTokenUrl(new CardDownloadData("Thopter", "ORI", "0", false, 2, "ORI", ""));
|
||||
Assert.assertEquals("http://tokens.mtg.onl/tokens/ORI_011-Thopter.jpg", url);
|
||||
Assert.assertEquals("http://tokens.mtg.onl/tokens/ORI_011-Thopter.jpg", url.baseUrl);
|
||||
|
||||
url = imageSource.generateTokenUrl(new CardDownloadData("Ashaya, the Awoken World", "ORI", "0", false, 0, "ORI", ""));
|
||||
Assert.assertEquals("http://tokens.mtg.onl/tokens/ORI_007-Ashaya,-the-Awoken-World.jpg", url);
|
||||
Assert.assertEquals("http://tokens.mtg.onl/tokens/ORI_007-Ashaya,-the-Awoken-World.jpg", url.baseUrl);
|
||||
|
||||
url = imageSource.generateTokenUrl(new CardDownloadData("Emblem Gideon, Ally of Zendikar", "BFZ", "0", false, 0, null, ""));
|
||||
Assert.assertEquals("http://tokens.mtg.onl/tokens/BFZ_012-Gideon-Emblem.jpg", url);
|
||||
Assert.assertEquals("http://tokens.mtg.onl/tokens/BFZ_012-Gideon-Emblem.jpg", url.baseUrl);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-root</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-common</artifactId>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.utils;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
|
@ -14,8 +13,8 @@ public class MageVersion implements Serializable, Comparable<MageVersion> {
|
|||
*/
|
||||
public final static int MAGE_VERSION_MAJOR = 1;
|
||||
public final static int MAGE_VERSION_MINOR = 4;
|
||||
public final static int MAGE_VERSION_PATCH = 30;
|
||||
public final static String MAGE_VERSION_MINOR_PATCH = "V2";
|
||||
public final static int MAGE_VERSION_PATCH = 31;
|
||||
public final static String MAGE_VERSION_MINOR_PATCH = "V1";
|
||||
public final static String MAGE_VERSION_INFO = "";
|
||||
|
||||
private final int major;
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ public class CardsView extends LinkedHashMap<UUID, CardView> {
|
|||
case BATTLEFIELD:
|
||||
sourceObject = game.getPermanent(ability.getSourceId());
|
||||
if (sourceObject == null) {
|
||||
sourceObject = (Permanent) game.getLastKnownInformation(ability.getSourceId(), Zone.BATTLEFIELD);
|
||||
sourceObject = game.getLastKnownInformation(ability.getSourceId(), Zone.BATTLEFIELD);
|
||||
}
|
||||
isPermanent = true;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-counter-plugin</artifactId>
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ public class CounterPluginImpl implements CounterPlugin {
|
|||
File data = new File(PLUGIN_DATA_FOLDER_PATH + File.separator + DATA_STORAGE_FILE);
|
||||
if (!data.exists()) {
|
||||
try {
|
||||
data.getParentFile().mkdirs();
|
||||
data.createNewFile();
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-root</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-plugins</artifactId>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-root</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<groupId>org.mage</groupId>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-deck-constructed</artifactId>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.deck;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
|
@ -15,6 +14,73 @@ import mage.constants.SetType;
|
|||
*/
|
||||
public class AusHighlander extends Constructed {
|
||||
|
||||
public static final Map<String, Integer> pointMap = new HashMap();
|
||||
|
||||
static {
|
||||
pointMap.put("Ancestral Recall", 4);
|
||||
pointMap.put("Black Lotus", 4);
|
||||
pointMap.put("Time Vault", 4);
|
||||
pointMap.put("Demonic Tutor", 3);
|
||||
pointMap.put("Imperial Seal", 3);
|
||||
pointMap.put("Mox Emerald", 3);
|
||||
pointMap.put("Mox Jet", 3);
|
||||
pointMap.put("Mox Pearl", 3);
|
||||
pointMap.put("Mox Ruby", 3);
|
||||
pointMap.put("Mox Sapphire", 3);
|
||||
pointMap.put("Sol Ring", 3);
|
||||
pointMap.put("Time Walk", 3);
|
||||
pointMap.put("Tinker", 3);
|
||||
pointMap.put("Vampiric Tutor", 3);
|
||||
pointMap.put("Yawgmoth’s Will", 3);
|
||||
pointMap.put("Channel", 2);
|
||||
pointMap.put("Dig Through Time", 2);
|
||||
pointMap.put("Library of Alexandria", 2);
|
||||
pointMap.put("Mana Crypt", 2);
|
||||
pointMap.put("Mystical Tutor", 2);
|
||||
pointMap.put("Protean Hulk", 2);
|
||||
pointMap.put("Skullclamp", 2);
|
||||
pointMap.put("Strip Mine", 2);
|
||||
pointMap.put("Tolarian Academy", 2);
|
||||
pointMap.put("Treasure Cruise", 2);
|
||||
pointMap.put("Back to Basics", 1);
|
||||
pointMap.put("Balance", 1);
|
||||
pointMap.put("Birthing Pod", 1);
|
||||
pointMap.put("Crop Rotation", 1);
|
||||
pointMap.put("Dark Petition", 1);
|
||||
pointMap.put("Enlightened Tutor", 1);
|
||||
pointMap.put("Fastbond", 1);
|
||||
pointMap.put("Force of Will", 1);
|
||||
pointMap.put("Gifts Ungiven", 1);
|
||||
pointMap.put("Green Sun’s Zenith", 1);
|
||||
pointMap.put("Hermit Druid", 1);
|
||||
pointMap.put("Intuition", 1);
|
||||
pointMap.put("Jace, the Mind Sculptor", 1);
|
||||
pointMap.put("Karakas", 1);
|
||||
pointMap.put("Lim-Dul’s Vault", 1);
|
||||
pointMap.put("Mana Drain", 1);
|
||||
pointMap.put("Mana Vault", 1);
|
||||
pointMap.put("Memory Jar", 1);
|
||||
pointMap.put("Merchant Scroll", 1);
|
||||
pointMap.put("Mind Twist", 1);
|
||||
pointMap.put("Mishra’s Workshop", 1);
|
||||
pointMap.put("Natural Order", 1);
|
||||
pointMap.put("Oath of Druids", 1);
|
||||
pointMap.put("Personal Tutor", 1);
|
||||
pointMap.put("Sensei’s Divining Top", 1);
|
||||
pointMap.put("Snapcaster Mage", 1);
|
||||
pointMap.put("Stoneforge Mystic", 1);
|
||||
pointMap.put("Survival of the Fittest", 1);
|
||||
pointMap.put("Tainted Pact", 1);
|
||||
pointMap.put("Time Spiral", 1);
|
||||
pointMap.put("Timetwister", 1);
|
||||
pointMap.put("True-Name Nemesis", 1);
|
||||
pointMap.put("Umezawa’s Jitte", 1);
|
||||
pointMap.put("Wasteland", 1);
|
||||
pointMap.put("Wheel of Fortune", 1);
|
||||
pointMap.put("Worldly Tutor", 1);
|
||||
pointMap.put("Yawgmoth’s Bargain", 1);
|
||||
}
|
||||
|
||||
public AusHighlander() {
|
||||
this("Australian Highlander");
|
||||
for (ExpansionSet set : Sets.getInstance().values()) {
|
||||
|
|
@ -82,79 +148,9 @@ public class AusHighlander extends Constructed {
|
|||
int totalPoints = 0;
|
||||
for (Map.Entry<String, Integer> entry : counts.entrySet()) {
|
||||
String cn = entry.getKey();
|
||||
if (cn.equals("Ancestral Recall")
|
||||
|| cn.equals("Black Lotus")
|
||||
|| cn.equals("Time Vault")) {
|
||||
totalPoints += 4;
|
||||
invalid.put(cn, "4 points");
|
||||
}
|
||||
if (cn.equals("Demonic Tutor")
|
||||
|| cn.equals("Imperial Seal")
|
||||
|| cn.equals("Mox Emerald")
|
||||
|| cn.equals("Mox Jet")
|
||||
|| cn.equals("Mox Pearl")
|
||||
|| cn.equals("Mox Ruby")
|
||||
|| cn.equals("Sol Ring")
|
||||
|| cn.equals("Time Walk")
|
||||
|| cn.equals("Tinker")
|
||||
|| cn.equals("Vampiric Tutor")
|
||||
|| cn.equals("Yawgmoth's Will")
|
||||
|| cn.equals("Mox Sapphire")) {
|
||||
totalPoints += 3;
|
||||
invalid.put(cn, "3 points");
|
||||
}
|
||||
if (cn.equals("Channel")
|
||||
|| cn.equals("Dig Through Time")
|
||||
|| cn.equals("Library of Alexandria")
|
||||
|| cn.equals("Mana Crypt")
|
||||
|| cn.equals("Mystical Tutor")
|
||||
|| cn.equals("Protean Hulk")
|
||||
|| cn.equals("Skullclamp")
|
||||
|| cn.equals("Strip Mine")
|
||||
|| cn.equals("Tolarian Academy")
|
||||
|| cn.equals("Treasure Cruise")) {
|
||||
totalPoints += 2;
|
||||
invalid.put(cn, "2 points");
|
||||
}
|
||||
if (cn.equals("Back to Basics")
|
||||
|| cn.equals("Balance")
|
||||
|| cn.equals("Birthing Pod")
|
||||
|| cn.equals("Crop Rotation")
|
||||
|| cn.equals("Dark Petition")
|
||||
|| cn.equals("Enlightened Tutor")
|
||||
|| cn.equals("Fastbond")
|
||||
|| cn.equals("Force of Will")
|
||||
|| cn.equals("Gifts Ungiven")
|
||||
|| cn.equals("Green Sun's Zenith")
|
||||
|| cn.equals("Hermit Druid")
|
||||
|| cn.equals("Intuition")
|
||||
|| cn.equals("Jace, the Mind Sculptor")
|
||||
|| cn.equals("Karakas")
|
||||
|| cn.equals("Lim-Dul's Vault")
|
||||
|| cn.equals("Mana Drain")
|
||||
|| cn.equals("Mana Vault")
|
||||
|| cn.equals("Memory Jar")
|
||||
|| cn.equals("Merchant Scroll")
|
||||
|| cn.equals("Mind Twist")
|
||||
|| cn.equals("Mishra's Workshop")
|
||||
|| cn.equals("Natural Order")
|
||||
|| cn.equals("Oath of Druids")
|
||||
|| cn.equals("Personal Tutor")
|
||||
|| cn.equals("Sensei's Divining Top")
|
||||
|| cn.equals("Snapcaster Mage")
|
||||
|| cn.equals("Stoneforge Mystic")
|
||||
|| cn.equals("Survival of the Fittest")
|
||||
|| cn.equals("Tainted Pact")
|
||||
|| cn.equals("Time Spiral")
|
||||
|| cn.equals("Timetwister")
|
||||
|| cn.equals("True-Name Nemesis")
|
||||
|| cn.equals("Umezawa's Jitte")
|
||||
|| cn.equals("Wasteland")
|
||||
|| cn.equals("Wheel of Fortune")
|
||||
|| cn.equals("Yawgmoth's Bargain")
|
||||
|| cn.equals("Worldly Tutor")) {
|
||||
totalPoints += 1;
|
||||
invalid.put(cn, "1 point");
|
||||
if (pointMap.containsKey(cn)) {
|
||||
totalPoints += pointMap.get(cn);
|
||||
invalid.put(entry.getKey(), " " + pointMap.get(cn) + " point " + cn);
|
||||
}
|
||||
}
|
||||
if (totalPoints > 7) {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,10 @@
|
|||
|
||||
package mage.deck;
|
||||
|
||||
import java.util.*;
|
||||
import mage.abilities.common.CanBeYourCommanderAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.ExpansionSet;
|
||||
import mage.cards.Sets;
|
||||
import mage.cards.decks.Constructed;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.constants.SetType;
|
||||
import mage.filter.FilterMana;
|
||||
|
||||
/**
|
||||
|
|
@ -23,41 +19,11 @@ public class Brawl extends Constructed {
|
|||
super("Brawl");
|
||||
|
||||
// Copy of standard sets
|
||||
GregorianCalendar current = new GregorianCalendar();
|
||||
List<ExpansionSet> sets = new ArrayList(Sets.getInstance().values());
|
||||
Collections.sort(sets, new Comparator<ExpansionSet>() {
|
||||
@Override
|
||||
public int compare(final ExpansionSet lhs, ExpansionSet rhs) {
|
||||
return lhs.getReleaseDate().after(rhs.getReleaseDate()) ? -1 : 1;
|
||||
}
|
||||
});
|
||||
int blocksAdded = 0;
|
||||
int blocksToAdd = 3;
|
||||
for (Iterator<ExpansionSet> iter = sets.iterator(); iter.hasNext() && blocksAdded < blocksToAdd;) {
|
||||
ExpansionSet set = iter.next();
|
||||
if (set.getSetType() == SetType.CORE || set.getSetType() == SetType.EXPANSION || set.getSetType() == SetType.SUPPLEMENTAL_STANDARD_LEGAL) { // Still adding core sets because of Magic Origins
|
||||
setCodes.addAll(Standard.makeLegalSets());
|
||||
|
||||
setCodes.add(set.getCode());
|
||||
if (set.getReleaseDate().before(current.getTime()) // This stops spoiled sets from counting as "new" blocks
|
||||
&& set.getParentSet() == null
|
||||
&& set.getSetType() == SetType.EXPANSION) {
|
||||
if (blocksAdded == 0 && !isFallBlock(set)) { // if the most current block is no fall block, 4 blocks are added
|
||||
blocksToAdd++;
|
||||
}
|
||||
blocksAdded++;
|
||||
}
|
||||
}
|
||||
}
|
||||
banned.add("Baral, Chief of Compliance");
|
||||
banned.add("Smuggler's Copter");
|
||||
banned.add("Sorcerers' Spyglass");
|
||||
}
|
||||
|
||||
private static boolean isFallBlock(ExpansionSet set) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(set.getReleaseDate());
|
||||
// Sets from fall block are normally released in September and January
|
||||
return cal.get(Calendar.MONTH) > 7 || cal.get(Calendar.MONTH) < 2;
|
||||
banned.add("Sorcerous Spyglass");
|
||||
}
|
||||
|
||||
public Brawl(String name) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.deck;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
|
@ -15,6 +14,53 @@ import mage.constants.SetType;
|
|||
*/
|
||||
public class CanadianHighlander extends Constructed {
|
||||
|
||||
public static final Map<String, Integer> pointMap = new HashMap();
|
||||
|
||||
static {
|
||||
pointMap.put("Ancestral Recall", 7);
|
||||
pointMap.put("Balance", 1);
|
||||
pointMap.put("Birthing Pod", 3);
|
||||
pointMap.put("Black Lotus", 7);
|
||||
pointMap.put("Demonic Tutor", 4);
|
||||
pointMap.put("Dig Through Time", 1);
|
||||
pointMap.put("Enlightened Tutor", 1);
|
||||
pointMap.put("Fastbond", 1);
|
||||
pointMap.put("Flash", 7);
|
||||
pointMap.put("Gifts Ungiven", 2);
|
||||
pointMap.put("Hermit Druid", 1);
|
||||
pointMap.put("Imperial Seal", 1);
|
||||
pointMap.put("Intuition", 1);
|
||||
pointMap.put("Library of Alexandria", 1);
|
||||
pointMap.put("Mana Crypt", 2);
|
||||
pointMap.put("Mana Drain", 1);
|
||||
pointMap.put("Mana Vault", 1);
|
||||
pointMap.put("Merchant Scroll", 1);
|
||||
pointMap.put("Mind Twist", 1);
|
||||
pointMap.put("Mox Emerald", 3);
|
||||
pointMap.put("Mox Jet", 3);
|
||||
pointMap.put("Mox Pearl", 3);
|
||||
pointMap.put("Mox Ruby", 3);
|
||||
pointMap.put("Mox Sapphire", 3);
|
||||
pointMap.put("Mystical Tutor", 2);
|
||||
pointMap.put("Natural Order", 4);
|
||||
pointMap.put("Personal Tutor", 1);
|
||||
pointMap.put("Protean Hulk", 3);
|
||||
pointMap.put("Sol Ring", 3);
|
||||
pointMap.put("Stoneforge Mystic", 1);
|
||||
pointMap.put("Strip Mine", 2);
|
||||
pointMap.put("Summoner's Pact", 2);
|
||||
pointMap.put("Survival of the Fittest", 2);
|
||||
pointMap.put("Time Vault", 6);
|
||||
pointMap.put("Time Walk", 6);
|
||||
pointMap.put("Tinker", 4);
|
||||
pointMap.put("Tolarian Academy", 1);
|
||||
pointMap.put("Transmute Artifact", 1);
|
||||
pointMap.put("Treasure Cruise", 1);
|
||||
pointMap.put("True-Name Nemesis", 1);
|
||||
pointMap.put("Umezawa's Jitte", 2);
|
||||
pointMap.put("Vampiric Tutor", 3);
|
||||
}
|
||||
|
||||
public CanadianHighlander() {
|
||||
this("Canadian Highlander");
|
||||
for (ExpansionSet set : Sets.getInstance().values()) {
|
||||
|
|
@ -54,74 +100,13 @@ public class CanadianHighlander extends Constructed {
|
|||
}
|
||||
}
|
||||
|
||||
int allowedPoints = 10 * (int) Math.floor(deck.getCards().size() / 100.0);
|
||||
int allowedPoints = 10;
|
||||
int totalPoints = 0;
|
||||
for (Map.Entry<String, Integer> entry : counts.entrySet()) {
|
||||
String cn = entry.getKey();
|
||||
if (cn.equals("Balance")
|
||||
|| cn.equals("Dig Through Time")
|
||||
|| cn.equals("Doomsday")
|
||||
|| cn.equals("Enlightened Tutor")
|
||||
|| cn.equals("Fastbond")
|
||||
|| cn.equals("Intuition")
|
||||
|| cn.equals("Library of Alexandria")
|
||||
|| cn.equals("Mana Vault")
|
||||
|| cn.equals("Merchant Scroll")
|
||||
|| cn.equals("Mind Twist")
|
||||
|| cn.equals("Personal Tutor")
|
||||
|| cn.equals("Stoneforge Mystic")
|
||||
|| cn.equals("Tainted Pact")
|
||||
|| cn.equals("Tolarian Academy")
|
||||
|| cn.equals("Transmute Artifact")
|
||||
|| cn.equals("Treasure Cruise")
|
||||
|| cn.equals("True-Name Nemesis")
|
||||
|| cn.equals("Worldly Tutor")) {
|
||||
totalPoints += 1;
|
||||
invalid.put(entry.getKey(), " 1 point " + cn);
|
||||
}
|
||||
if (cn.equals("Gifts Ungiven")
|
||||
|| cn.equals("Hermit Druid")
|
||||
|| cn.equals("Imperial Seal")
|
||||
|| cn.equals("Mana Crypt")
|
||||
|| cn.equals("Mystical Tutor")
|
||||
|| cn.equals("Strip Mine")
|
||||
|| cn.equals("Summoner's Pact")
|
||||
|| cn.equals("Survival of the Fittest")
|
||||
|| cn.equals("Umezawa's Jitte")) {
|
||||
totalPoints += 2;
|
||||
invalid.put(entry.getKey(), " 2 points " + cn);
|
||||
}
|
||||
if (cn.equals("Birthing Pod")
|
||||
|| cn.equals("Mox Emerald")
|
||||
|| cn.equals("Mox Jet")
|
||||
|| cn.equals("Mox Pearl")
|
||||
|| cn.equals("Mox Ruby")
|
||||
|| cn.equals("Mox Sapphire")
|
||||
|| cn.equals("Protean Hulk")
|
||||
|| cn.equals("Sol Ring")
|
||||
|| cn.equals("Vampiric Tutor")) {
|
||||
totalPoints += 3;
|
||||
invalid.put(entry.getKey(), " 3 points " + cn);
|
||||
}
|
||||
if (cn.equals("Demonic Tutor")
|
||||
|| cn.equals("Tinker")) {
|
||||
totalPoints += 4;
|
||||
invalid.put(entry.getKey(), " 4 points " + cn);
|
||||
}
|
||||
if (cn.equals("Natural Order")
|
||||
|| cn.equals("Time Walk")) {
|
||||
totalPoints += 5;
|
||||
invalid.put(entry.getKey(), " 5 points " + cn);
|
||||
}
|
||||
if (cn.equals("Ancestral Recall")
|
||||
|| cn.equals("Time Vault")) {
|
||||
totalPoints += 6;
|
||||
invalid.put(entry.getKey(), " 6 points " + cn);
|
||||
}
|
||||
if (cn.equals("Black Lotus")
|
||||
|| cn.equals("Flash")) {
|
||||
totalPoints += 7;
|
||||
invalid.put(entry.getKey(), " 7 points " + cn);
|
||||
if (pointMap.containsKey(cn)) {
|
||||
totalPoints += pointMap.get(cn);
|
||||
invalid.put(entry.getKey(), " " + pointMap.get(cn) + " point " + cn);
|
||||
}
|
||||
}
|
||||
if (totalPoints > allowedPoints) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.deck;
|
||||
|
||||
import java.util.*;
|
||||
|
|
@ -23,6 +22,7 @@ import mage.filter.FilterMana;
|
|||
public class Commander extends Constructed {
|
||||
|
||||
protected List<String> bannedCommander = new ArrayList<>();
|
||||
protected boolean partnerAllowed = true;
|
||||
|
||||
public Commander() {
|
||||
this("Commander");
|
||||
|
|
@ -105,6 +105,9 @@ public class Commander extends Constructed {
|
|||
}
|
||||
|
||||
if (deck.getSideboard().size() < 1 || deck.getSideboard().size() > 2) {
|
||||
if ((deck.getSideboard().size() > 1 && !partnerAllowed)) {
|
||||
invalid.put("Commander", "You may only have one commander");
|
||||
}
|
||||
invalid.put("Commander", "Sideboard must contain only the commander(s)");
|
||||
valid = false;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ public class FreeformCommander extends Constructed {
|
|||
|
||||
protected List<String> bannedCommander = new ArrayList<>();
|
||||
private static final Map<String, Integer> pdAllowed = new HashMap<>();
|
||||
private static boolean setupAllowed = false;
|
||||
|
||||
public FreeformCommander() {
|
||||
this("Freeform Commander");
|
||||
|
|
@ -43,7 +42,6 @@ public class FreeformCommander extends Constructed {
|
|||
valid = false;
|
||||
}
|
||||
|
||||
List<String> basicLandNames = new ArrayList<>(Arrays.asList("Forest", "Island", "Mountain", "Swamp", "Plains", "Wastes"));
|
||||
Map<String, Integer> counts = new HashMap<>();
|
||||
countCards(counts, deck.getCards());
|
||||
countCards(counts, deck.getSideboard());
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.deck;
|
||||
|
||||
import mage.cards.ExpansionSet;
|
||||
|
|
@ -32,6 +31,7 @@ public class Legacy extends Constructed {
|
|||
banned.add("Chaos Orb");
|
||||
banned.add("Contract from Below");
|
||||
banned.add("Darkpact");
|
||||
banned.add("Deathrite Shaman");
|
||||
banned.add("Demonic Attorney");
|
||||
banned.add("Demonic Consultation");
|
||||
banned.add("Demonic Tutor");
|
||||
|
|
@ -42,6 +42,7 @@ public class Legacy extends Constructed {
|
|||
banned.add("Fastbond");
|
||||
banned.add("Flash");
|
||||
banned.add("Frantic Search");
|
||||
banned.add("Gitaxian Probe");
|
||||
banned.add("Goblin Recruiter");
|
||||
banned.add("Gush");
|
||||
banned.add("Hermit Druid");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.deck;
|
||||
|
||||
/**
|
||||
|
|
@ -9,70 +8,49 @@ public class MTGO1v1Commander extends Commander {
|
|||
|
||||
public MTGO1v1Commander() {
|
||||
super("MTGO 1v1 Commander");
|
||||
partnerAllowed = false;
|
||||
|
||||
banned.add("Ancestral Recall");
|
||||
banned.add("Ancient Tomb");
|
||||
banned.add("Back to Basics");
|
||||
banned.add("Balance");
|
||||
banned.add("Baral, Chief of Compliance");
|
||||
banned.add("Black Lotus");
|
||||
banned.add("Braids, Cabal Minion");
|
||||
banned.add("Brainstorm");
|
||||
banned.add("Channel");
|
||||
banned.add("Chrome Mox");
|
||||
banned.add("Derevi, Empyrial Tactician");
|
||||
banned.add("Demonic Tutor");
|
||||
banned.add("Dig Through Time");
|
||||
banned.add("Doomsday");
|
||||
banned.add("Edgar Markov");
|
||||
banned.add("Edric, Spymaster of Trest");
|
||||
banned.add("Emrakul, the Aeons Torn");
|
||||
banned.add("Enlightened Tutor");
|
||||
banned.add("Entomb");
|
||||
banned.add("Erayo, Soratami Ascendant");
|
||||
banned.add("Fastbond");
|
||||
banned.add("Food Chain");
|
||||
banned.add("Gaea's Cradle");
|
||||
banned.add("Gifts Ungiven");
|
||||
banned.add("Hermit Druid");
|
||||
banned.add("Humility");
|
||||
banned.add("Imperial Seal");
|
||||
banned.add("Karakas");
|
||||
banned.add("Library of Alexandria");
|
||||
banned.add("Mana Crypt");
|
||||
banned.add("Mana Drain");
|
||||
banned.add("Mana Vault");
|
||||
banned.add("Mind Twist");
|
||||
banned.add("Moat");
|
||||
banned.add("Mox Diamond");
|
||||
banned.add("Mox Emerald");
|
||||
banned.add("Mox Jet");
|
||||
banned.add("Mox Pearl");
|
||||
banned.add("Mox Ruby");
|
||||
banned.add("Mox Sapphire");
|
||||
banned.add("Mystical Tutor");
|
||||
banned.add("Natural Order");
|
||||
banned.add("Necropotence");
|
||||
banned.add("Oath of Druids");
|
||||
banned.add("Ponder");
|
||||
banned.add("Preordain");
|
||||
banned.add("Rofellos, Llanowar Emissary");
|
||||
banned.add("Strip Mine");
|
||||
banned.add("Sensei's Divining Top");
|
||||
banned.add("Serra Ascendant");
|
||||
banned.add("Sol Ring");
|
||||
banned.add("Strip Mine");
|
||||
banned.add("Survival of the Fittest");
|
||||
banned.add("Sylvan Library");
|
||||
banned.add("Sylvan Tutor");
|
||||
banned.add("The Tabernacle at Pendrell Vale");
|
||||
banned.add("Time Vault");
|
||||
banned.add("Time Walk");
|
||||
banned.add("Tinker");
|
||||
banned.add("Tolarian Academy");
|
||||
banned.add("Treachery");
|
||||
banned.add("Treasure Cruise");
|
||||
banned.add("Vial Smasher the Fierce");
|
||||
banned.add("Vampiric Tutor");
|
||||
banned.add("Winter Orb");
|
||||
banned.add("Wordly Tutor");
|
||||
banned.add("Yamgmoth's Bargain");
|
||||
banned.add("Zur the Enchanter");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
|
||||
package mage.deck;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import mage.cards.ExpansionSet;
|
||||
import mage.cards.Sets;
|
||||
|
|
@ -21,31 +20,9 @@ public class Standard extends Constructed {
|
|||
|
||||
public Standard() {
|
||||
super("Constructed - Standard");
|
||||
GregorianCalendar current = new GregorianCalendar();
|
||||
List<ExpansionSet> sets = new ArrayList(Sets.getInstance().values());
|
||||
Collections.sort(sets, new Comparator<ExpansionSet>() {
|
||||
@Override
|
||||
public int compare(final ExpansionSet lhs, ExpansionSet rhs) {
|
||||
return lhs.getReleaseDate().after(rhs.getReleaseDate()) ? -1 : 1;
|
||||
}
|
||||
});
|
||||
int blocksAdded = 0;
|
||||
int blocksToAdd = 3;
|
||||
for (Iterator<ExpansionSet> iter = sets.iterator(); iter.hasNext() && blocksAdded < blocksToAdd;) {
|
||||
ExpansionSet set = iter.next();
|
||||
if (set.getSetType() == SetType.CORE || set.getSetType() == SetType.EXPANSION || set.getSetType() == SetType.SUPPLEMENTAL_STANDARD_LEGAL) { // Still adding core sets because of Magic Origins
|
||||
|
||||
setCodes.add(set.getCode());
|
||||
if (set.getReleaseDate().before(current.getTime()) // This stops spoiled sets from counting as "new" blocks
|
||||
&& set.getParentSet() == null
|
||||
&& set.getSetType() == SetType.EXPANSION) {
|
||||
if (blocksAdded == 0 && !isFallBlock(set)) { // if the most current block is no fall block, 4 blocks are added
|
||||
blocksToAdd++;
|
||||
}
|
||||
blocksAdded++;
|
||||
}
|
||||
}
|
||||
}
|
||||
setCodes.addAll(makeLegalSets());
|
||||
|
||||
banned.add("Attune with Aether"); // since 2018-01-15
|
||||
banned.add("Aetherworks Marvel");
|
||||
banned.add("Felidar Guardian");
|
||||
|
|
@ -55,10 +32,49 @@ public class Standard extends Constructed {
|
|||
banned.add("Smuggler's Copter");
|
||||
}
|
||||
|
||||
private static boolean isFallBlock(ExpansionSet set) {
|
||||
private static boolean isFallSet(ExpansionSet set) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(set.getReleaseDate());
|
||||
// Sets from fall block are normally released in September and January
|
||||
return cal.get(Calendar.MONTH) > 7 || cal.get(Calendar.MONTH) < 2;
|
||||
// Fall sets are normally released during or after September
|
||||
return set.getSetType() == SetType.EXPANSION
|
||||
&& (cal.get(Calendar.MONTH) > 7);
|
||||
}
|
||||
|
||||
public static List<String> makeLegalSets() {
|
||||
List<String> codes = new ArrayList();
|
||||
GregorianCalendar current = new GregorianCalendar();
|
||||
List<ExpansionSet> sets = new ArrayList(Sets.getInstance().values());
|
||||
Collections.sort(sets, new Comparator<ExpansionSet>() {
|
||||
@Override
|
||||
public int compare(final ExpansionSet lhs, ExpansionSet rhs) {
|
||||
return lhs.getReleaseDate().after(rhs.getReleaseDate()) ? -1 : 1;
|
||||
}
|
||||
});
|
||||
int fallSetsAdded = 0;
|
||||
Date earliestDate = null;
|
||||
// Get the second most recent fall set that's been released.
|
||||
for (ExpansionSet set : sets) {
|
||||
if (set.getReleaseDate().after(current.getTime())) {
|
||||
continue;
|
||||
}
|
||||
if (isFallSet(set)) {
|
||||
fallSetsAdded++;
|
||||
if (fallSetsAdded == 2) {
|
||||
earliestDate = set.getReleaseDate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Get all sets released on or after the second most recent fall set's release
|
||||
for (ExpansionSet set : sets) {
|
||||
if ((set.getSetType() == SetType.CORE
|
||||
|| set.getSetType() == SetType.EXPANSION
|
||||
|| set.getSetType() == SetType.SUPPLEMENTAL_STANDARD_LEGAL)
|
||||
&& !set.getReleaseDate().before(earliestDate)) {
|
||||
// && !set.getReleaseDate().after(current.getTime()))) {
|
||||
codes.add(set.getCode());
|
||||
}
|
||||
}
|
||||
return codes;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-deck-limited</artifactId>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-game-brawlduel</artifactId>
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ public class BrawlDuelMatch extends MatchImpl {
|
|||
|
||||
@Override
|
||||
public void startGame() throws GameException {
|
||||
int startLife = 20;
|
||||
int startLife = 25;
|
||||
boolean alsoHand = true;
|
||||
BrawlDuel game = new BrawlDuel(options.getAttackOption(), options.getRange(), options.getFreeMulligans(), startLife);
|
||||
game.setCheckCommanderDamage(false);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-game-brawlfreeforall</artifactId>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-game-canadianhighlanderduel</artifactId>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-game-commanderduel</artifactId>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-game-commanderfreeforall</artifactId>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-game-freeforall</artifactId>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-game-freeformcommanderfreeforall</artifactId>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-game-momirduel</artifactId>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-game-momirfreeforall</artifactId>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-game-pennydreadfulcommanderfreeforall</artifactId>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-game-tinyleadersduel</artifactId>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-game-twoplayerduel</artifactId>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-player-ai-draftbot</artifactId>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-player-ai-ma</artifactId>
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
|
|||
sb.setLength(0);
|
||||
sb.append("-> Permanents: [");
|
||||
for (Permanent permanent : game.getBattlefield().getAllPermanents()) {
|
||||
if (permanent.getOwnerId().equals(player.getId())) {
|
||||
if (permanent.isOwnedBy(player.getId())) {
|
||||
sb.append(permanent.getName());
|
||||
if (permanent.isTapped()) {
|
||||
sb.append("(tapped)");
|
||||
|
|
@ -254,7 +254,7 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
|
|||
} else if (stepFinished) {
|
||||
logger.debug("Step finished");
|
||||
int testScore = GameStateEvaluator2.evaluate(playerId, game);
|
||||
if (game.getActivePlayerId().equals(playerId)) {
|
||||
if (game.isActivePlayer(playerId)) {
|
||||
if (testScore < currentScore) {
|
||||
// if score at end of step is worse than original score don't check further
|
||||
//logger.debug("Add Action -- abandoning check, no immediate benefit");
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 {
|
|||
pass(game);
|
||||
return false;
|
||||
case PRECOMBAT_MAIN:
|
||||
if (game.getActivePlayerId().equals(playerId)) {
|
||||
if (game.isActivePlayer(playerId)) {
|
||||
printOutState(game);
|
||||
if (actions.isEmpty()) {
|
||||
logger.info("Sim Calculate pre combat actions ----------------------------------------------------- ");
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-player-ai</artifactId>
|
||||
|
|
|
|||
|
|
@ -987,7 +987,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
|
||||
private boolean priorityPlay(Game game) {
|
||||
UUID opponentId = game.getOpponents(playerId).iterator().next();
|
||||
if (game.getActivePlayerId().equals(playerId)) {
|
||||
if (game.isActivePlayer(playerId)) {
|
||||
if (game.isMainPhase() && game.getStack().isEmpty()) {
|
||||
playLand(game);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-player-ai-mcts</artifactId>
|
||||
|
|
|
|||
|
|
@ -348,7 +348,7 @@ public class ComputerPlayerMCTS extends ComputerPlayer implements Player {
|
|||
thinkTime = maxThinkTime / 2;
|
||||
}
|
||||
}
|
||||
else if (game.getActivePlayerId().equals(playerId) && (curStep == PhaseStep.PRECOMBAT_MAIN || curStep == PhaseStep.POSTCOMBAT_MAIN) && game.getStack().isEmpty()) {
|
||||
else if (game.isActivePlayer(playerId) && (curStep == PhaseStep.PRECOMBAT_MAIN || curStep == PhaseStep.POSTCOMBAT_MAIN) && game.getStack().isEmpty()) {
|
||||
if (nodeSizeRatio < THINK_MIN_RATIO) {
|
||||
thinkTime = maxThinkTime;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-player-aiminimax</artifactId>
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
|
|||
pass(game);
|
||||
return false;
|
||||
case PRECOMBAT_MAIN:
|
||||
if (game.getActivePlayerId().equals(playerId)) {
|
||||
if (game.isActivePlayer(playerId)) {
|
||||
if (actions.isEmpty()) {
|
||||
calculatePreCombatActions(game);
|
||||
}
|
||||
|
|
@ -64,7 +64,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
|
|||
pass(game);
|
||||
return false;
|
||||
case DECLARE_ATTACKERS:
|
||||
if (!game.getActivePlayerId().equals(playerId)) {
|
||||
if (!game.isActivePlayer(playerId)) {
|
||||
if (actions.isEmpty()) {
|
||||
calculatePreCombatActions(game);
|
||||
}
|
||||
|
|
@ -81,7 +81,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
|
|||
pass(game);
|
||||
return false;
|
||||
case POSTCOMBAT_MAIN:
|
||||
if (game.getActivePlayerId().equals(playerId)) {
|
||||
if (game.isActivePlayer(playerId)) {
|
||||
if (actions.isEmpty()) {
|
||||
calculatePostCombatActions(game);
|
||||
}
|
||||
|
|
@ -184,7 +184,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
|
|||
else if (stepFinished) {
|
||||
logger.debug(indent(node.depth) + "step finished");
|
||||
int testScore = GameStateEvaluator.evaluate(playerId, game);
|
||||
if (game.getActivePlayerId().equals(playerId)) {
|
||||
if (game.isActivePlayer(playerId)) {
|
||||
if (testScore < currentScore) {
|
||||
// if score at end of step is worse than original score don't check further
|
||||
logger.debug(indent(node.depth) + "simulating -- abandoning check, no immediate benefit");
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-player-human</artifactId>
|
||||
|
|
|
|||
|
|
@ -341,8 +341,18 @@ public class HumanPlayer extends PlayerImpl {
|
|||
|
||||
replacementEffectChoice.getChoices().clear();
|
||||
replacementEffectChoice.setKeyChoices(rEffects);
|
||||
|
||||
// Check if there are different ones
|
||||
int differentChoices = 0;
|
||||
String lastChoice = "";
|
||||
for (String value : replacementEffectChoice.getKeyChoices().values()) {
|
||||
if (!lastChoice.equalsIgnoreCase(value)) {
|
||||
lastChoice = value;
|
||||
differentChoices++;
|
||||
}
|
||||
}
|
||||
|
||||
while (!abort) {
|
||||
while (!abort && differentChoices > 1) {
|
||||
updateGameStatePriority("chooseEffect", game);
|
||||
prepareForResponse(game);
|
||||
if (!isExecutingMacro()) {
|
||||
|
|
@ -1943,7 +1953,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
if (userData.confirmEmptyManaPool()
|
||||
&& game.getStack().isEmpty() && getManaPool().count() > 0) {
|
||||
String activePlayerText;
|
||||
if (game.getActivePlayerId().equals(playerId)) {
|
||||
if (game.isActivePlayer(playerId)) {
|
||||
activePlayerText = "Your turn";
|
||||
} else {
|
||||
activePlayerText = game.getPlayer(game.getActivePlayerId()).getName() + "'s turn";
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-tournament-boosterdraft</artifactId>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,555 @@
|
|||
package mage.tournament.cubes;
|
||||
|
||||
import mage.game.draft.DraftCube;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author TheELk801
|
||||
*/
|
||||
public class VintageCubeJune2018 extends DraftCube {
|
||||
|
||||
public VintageCubeJune2018() {
|
||||
super("MTGO Vintage Cube June 2018");
|
||||
|
||||
cubeCards.add(new DraftCube.CardIdentity("Abbot of Keral Keep", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Abrade", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Abrupt Decay", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Academy Ruins", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Acidic Slime", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Adanto Vanguard", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ajani Vengeant", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ancestral Recall", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ancestral Vision", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ancient Grudge", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ancient Stirrings", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ancient Tomb", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Angel of Invention", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Angel of Sanctions", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Angel of Serenity", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Anguished Unmaking", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Animate Dead", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Arbor Elf", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Archangel of Thune", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Arguel's Blood Fast", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Arid Mesa", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Armageddon", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ashiok, Nightmare Weaver", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Augur of Bolas", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Avacyn's Pilgrim", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Avalanche Riders", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Avenger of Zendikar", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Awakening Zone", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Azorius Signet", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Badlands", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Balance", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Baleful Strix", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Baneslayer Angel", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Banisher Priest", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Banishing Light", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Basalt Monolith", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Batterskull", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Bayou", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Bazaar of Baghdad", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Beast Within", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Benalish Marshal", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Birds of Paradise", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Bitterblossom", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Black Lotus", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Blackcleave Cliffs", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Blade Splicer", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Blightsteel Colossus", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Blink of an Eye", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Blood Crypt", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Bloodbraid Elf", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Bloodstained Mire", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Blooming Marsh", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Bone Shredder", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Bonfire of the Damned", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Boros Signet", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Botanical Sanctum", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Braids, Cabal Minion", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Brain Freeze", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Brain Maggot", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Brainstorm", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Breeding Pool", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Bribery", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Brimaz, King of Oreskos", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Bring to Light", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Buried Alive", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Burning of Xinye", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Burst Lightning", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Cabal Ritual", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Cast Down", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Cast Out", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Celestial Colonnade", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Chain Lightning", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Chandra, Flamecaller", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Chandra, Pyromaster", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Chandra, Torch of Defiance", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Channel", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Char", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Chart a Course", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Chrome Mox", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Coalition Relic", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Coercive Portal", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Commit // Memory", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Compulsive Research", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Concealed Courtyard", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Consecrated Sphinx", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Control Magic", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Copperline Gorge", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Corpse Dance", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Council's Judgment", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Counterspell", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Courser of Kruphix", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Craterhoof Behemoth", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Creeping Tar Pit", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Crucible of Worlds", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Cryptic Command", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dack Fayden", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Damnation", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Daretti, Scrap Savant", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dark Confidant", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dark Petition", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dark Ritual", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Darkslick Shores", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Day of Judgment", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Daze", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Deathrite Shaman", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Deceiver Exarch", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Declaration in Stone", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Delver of Secrets", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Demonic Tutor", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Demonlord Belzenlok", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Den Protector", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Deranged Hermit", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Desperate Ritual", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dig Through Time", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dimir Signet", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dire Fleet Daredevil", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Disenchant", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dismember", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dissenter's Deliverance", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dragonlord Atarka", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dragonlord Dromoka", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dragonlord Ojutai", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dreadbore", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Dualcaster Mage", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Duplicant", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Duress", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Edric, Spymaster of Trest", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Eidolon of the Great Revel", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Electrolyze", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Elesh Norn, Grand Cenobite", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Elspeth, Knight-Errant", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Elspeth, Sun's Champion", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Elves of Deep Shadow", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Elvish Mystic", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Emeria Angel", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Empty the Warrens", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Emrakul, the Aeons Torn", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Emrakul, the Promised End", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Enlightened Tutor", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Entomb", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Eternal Witness", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Eureka", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Everflowing Chalice", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Exhume", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Exquisite Firecraft", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Fact or Fiction", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Faithless Looting", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Falkenrath Gorger", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Fastbond", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Fatal Push", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Fauna Shaman", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Field of Ruin", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Fiend Hunter", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Fiery Confluence", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Figure of Destiny", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Fire // Ice", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Fireblast", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Firebolt", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Firedrinker Satyr", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Flametongue Kavu", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Flickerwisp", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Flooded Strand", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Force Spike", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Force of Will", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Frantic Search", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Freyalise, Llanowar's Fury", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Frost Titan", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Fyndhorn Elves", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Gaea's Cradle", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Garruk Relentless", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Garruk Wildspeaker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Garruk, Primal Hunter", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Geist of Saint Traft", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Genesis Wave", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Gideon Jura", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Gideon of the Trials", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Gideon, Ally of Zendikar", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Gifts Ungiven", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Gilded Lotus", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Gitaxian Probe", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Glen Elendra Archmage", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Glorybringer", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Go for the Throat", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Goblin Chainwhirler", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Goblin Dark-Dwellers", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Goblin Guide", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Goblin Welder", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Godless Shrine", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Golgari Signet", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Gonti, Lord of Luxury", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Grave Titan", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Green Sun's Zenith", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Grim Lavamancer", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Grim Monolith", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Grim Tutor", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Griselbrand", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Gruul Signet", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Gush", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hallowed Fountain", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hangarback Walker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Harmonize", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hazoret the Fervent", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Heartbeat of Spring", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hellrider", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hero of Bladehold", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hero's Downfall", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("High Tide", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hissing Quagmire", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("History of Benalia", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Honor of the Pure", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hostage Taker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Huntmaster of the Fells", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hymn to Tourach", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Hypnotic Specter", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Imperial Recruiter", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Imperial Seal", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Impulse", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Incinerate", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Inferno Titan", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Inkwell Leviathan", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Inquisition of Kozilek", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Inspiring Vantage", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Iona, Shield of Emeria", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Izzet Charm", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Izzet Signet", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Jace Beleren", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Jace, Architect of Thought", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Jace, Vryn's Prodigy", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Jace, the Mind Sculptor", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Jackal Pup", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Jadelight Ranger", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Jhoira, Weatherlight Captain", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Joraga Treespeaker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Karakas", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Karn Liberated", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Karn, Scion of Urza", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Kiki-Jiki, Mirror Breaker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Kitchen Finks", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Kitesail Freebooter", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Knight of the White Orchi", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Kolaghan's Command", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Koth of the Hammer", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Kozilek, Butcher of Truth", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Kuldotha Forgemaster", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Kytheon, Hero of Akros", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Land Tax", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Lavaclaw Reaches", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Legion's Landing", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Leonin Relic-Warder", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Leovold, Emissary of Trest", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Leyline of Sanctity", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Library of Alexandria", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Lightning Bolt", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Lightning Greaves", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Lightning Helix", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Lightning Strike", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Liliana of the Veil", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Liliana, Death's Majesty", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Lingering Souls", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Linvala, Keeper of Silence", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Lion's Eye Diamond", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Living Death", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Llanowar Elves", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Lodestone Golem", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Looter il-Kor", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Lotus Bloom", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Lotus Cobra", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Lotus Petal", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Lumbering Falls", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Lyra Dawnbringer", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Maelstrom Pulse", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Magma Jet", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Magus of the Moon", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Makeshift Mannequin", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mana Confluence", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mana Crypt", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mana Drain", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mana Flare", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mana Leak", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mana Tithe", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mana Vault", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Manglehorn", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Manic Vandal", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Marsh Flats", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Massacre Wurm", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Master of the Wild Hunt", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Maze of Ith", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Memory Jar", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mesmeric Fiend", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Metalworker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mind Twist", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mind's Desire", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mindslaver", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mirari's Wake", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mirran Crusader", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mishra's Factory", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mishra's Workshop", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Misty Rainforest", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mizzium Mortars", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Moat", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Monastery Mentor", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Monastery Swiftspear", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mother of Runes", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mox Diamond", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mox Emerald", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mox Jet", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mox Pearl", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mox Ruby", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mox Sapphire", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mulldrifter", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Murderous Cut", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mutavault", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Myr Battlesphere", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mystic Confluence", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mystic Snake", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Mystical Tutor", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Nahiri, the Harbinger", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Natural Order", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Nature's Claim", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Necromancy", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Necropotence", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Needle Spires", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Nekrataal", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Nevinyrral's Disk", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Nezumi Graverobber", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Nezumi Shortfang", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Nicol Bolas, Planeswalker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Nissa, Worldwaker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Noble Hierarch", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Noxious Gearhulk", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Nykthos, Shrine to Nyx", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Oath of Druids", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Oath of Nissa", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Oblivion Ring", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Olivia Voldaren", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Oona's Prowler", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ophiomancer", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Opposition", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Oracle of Mul Daya", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Orzhov Signet", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Overgrown Tomb", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Pack Rat", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Painful Truths", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Palinchron", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Parallax Wave", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Path to Exile", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Pentad Prism", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Pernicious Deed", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Pestermite", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Phantasmal Image", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Phyrexian Metamorph", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Phyrexian Revoker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Plateau", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Polluted Delta", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Polukranos, World Eater", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ponder", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Porcelain Legionnaire", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Preordain", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Primal Command", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Primeval Titan", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Progenitus", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Putrid Imp", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Pyretic Ritual", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Qasali Pridemage", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Raging Ravine", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Rakdos Signet", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Rakdos's Return", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ravages of War", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ravenous Chupacabra", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Razorverge Thicket", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Reanimate", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Reclamation Sage", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Recruiter of the Guard", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Recurring Nightmare", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Regrowth", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Rekindling Phoenix", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Remand", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Repeal", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Restoration Angel", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Reveillark", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Rift Bolt", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Riftwing Cloudskate", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Rishadan Port", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Rishkar, Peema Renegade", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Rite of Flame", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Rofellos, Llanowar Emissary", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sacred Foundry", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sakura-Tribe Elder", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Savannah", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Scalding Tarn", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Scavenging Ooze", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Scrubland", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Seachrome Coast", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Search for Azcanta", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Search for Tomorrow", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Searing Spear", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Seething Song", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Selesnya Signet", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Selfless Spirit", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sensei's Divining Top", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Shallow Grave", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Shambling Vent", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Shardless Agent", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Shelldock Isle", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sheoldred, Whispering One", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Show and Tell", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Shriekmaw", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Shrine of Burning Rage", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Siege-Gang Commander", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Silverblade Paladin", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Simic Signet", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Skullclamp", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Skymarcher Aspirant", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Smokestack", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Smuggler's Copter", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Snapcaster Mage", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sneak Attack", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sol Ring", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Solemn Simulacrum", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Song of the Dryads", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sorcerous Spyglass", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Soulfire Grand Master", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sower of Temptation", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Spear of Heliod", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Spectral Procession", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Spell Pierce", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Spellskite", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sphinx of the Steel Wind", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sphinx's Revelation", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Spirebluff Canal", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Splinter Twin", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Steam Vents", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Stirring Wildwood", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Stomping Ground", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Stoneforge Mystic", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Stormbreath Dragon", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Strip Mine", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Student of Warfare", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sulfuric Vortex", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sun Titan", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sundering Titan", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Supreme Verdict", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Survival of the Fittest", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sweltering Suns", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sword of Body and Mind", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sword of Feast and Famine", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sword of Fire and Ice", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sword of Light and Shadow", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sword of War and Peace", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Swords to Plowshares", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sylvan Caryatid", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Sylvan Library", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Taiga", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tamiyo, the Moon Sage", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tangle Wire", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tarmogoyf", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tasigur, the Golden Fang", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Teferi, Hero of Dominaria", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Temple Garden", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tendrils of Agony", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Terastodon", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Terminate", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tezzeret the Seeker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tezzeret, Agent of Bolas", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Thalia, Guardian of Thraben", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("The Abyss", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("The Scarab God", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Thing in the Ice", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Thirst for Knowledge", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Thoughtseize", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Thragtusk", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Thran Dynamo", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Thrashing Brontodon", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Through the Breach", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Thrun, the Last Troll", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Thundermaw Hellkite", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tidehollow Sculler", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Time Spiral", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Time Walk", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Timely Reinforcements", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Timetwister", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tinker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tolarian Academy", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tooth and Nail", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Torrential Gearhulk", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Toxic Deluge", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Treachery", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Treasure Cruise", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Trinket Mage", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tropical Island", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("True-Name Nemesis", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Trygon Predator", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Tundra", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Turnabout", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ugin, the Spirit Dragon", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ulamog, the Ceaseless Hunger", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ulamog, the Infinite Gyre", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Ultimate Price", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Umezawa's Jitte", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Unburial Rites", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Underground Sea", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Unexpectedly Absent", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Upheaval", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Urborg, Tomb of Yawgmoth", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Vampire Nighthawk", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Vampiric Tutor", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Vedalken Shackles", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Vendilion Clique", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Venser, Shaper Savant", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Verdant Catacombs", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Verdurous Gearhulk", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Vindicate", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Voice of Resurgence", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Volcanic Island", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Vraska's Contempt", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Vraska, Relic Seeker", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Walking Ballista", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Wall of Blossoms", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Wall of Omens", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Wall of Roots", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Wandering Fumarole", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Wasteland", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Watery Grave", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Wear // Tear", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Wheel of Fortune", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Wildfire", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Windswept Heath", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Winter Orb", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Wooded Foothills", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Woodfall Primus", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Worn Powerstone", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Wrath of God", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Wurmcoil Engine", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Xenagos, the Reveler", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Yavimaya Elder", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Yawgmoth's Bargain", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Yawgmoth's Will", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Young Pyromancer", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Zealous Conscripts", ""));
|
||||
cubeCards.add(new DraftCube.CardIdentity("Zurgo Bellstriker", ""));
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-tournament-constructed</artifactId>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-tournament-sealed</artifactId>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-root</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-server-plugins</artifactId>
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@
|
|||
<draftCube name="MTGO Vintage Cube November 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeNovember2016"/>
|
||||
<draftCube name="MTGO Vintage Cube June 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeJune2017"/>
|
||||
<draftCube name="MTGO Vintage Cube December 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeDecember2017"/>
|
||||
<draftCube name="MTGO Vintage Cube June 2018" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCubeJune2018"/>
|
||||
<draftCube name="The Peasant's Toolbox" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.PeasantsToolboxCube"/>
|
||||
<draftCube name="www.MTGCube.com" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.MTGCube"/>
|
||||
<draftCube name="Cube From Deck" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.CubeFromDeck"/>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-root</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mage-server</artifactId>
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@
|
|||
<draftCube name="MTGO Vintage Cube November 2016" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCubeNovember2016"/>
|
||||
<draftCube name="MTGO Vintage Cube June 2017" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCubeJune2017"/>
|
||||
<draftCube name="MTGO Vintage Cube December 2017" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCubeDecember2017"/>
|
||||
<draftCube name="MTGO Vintage Cube June 2018" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCubeJune2018"/>
|
||||
<draftCube name="The Peasant's Toolbox" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.PeasantsToolboxCube"/>
|
||||
<draftCube name="www.MTGCube.com" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.MTGCube"/>
|
||||
<draftCube name="Cube From Deck" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.CubeFromDeck"/>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.server.game;
|
||||
|
||||
import java.io.*;
|
||||
|
|
@ -1149,7 +1148,7 @@ public class GameController implements GameCallback {
|
|||
sb.append(state.getTurnMods());
|
||||
sb.append("<br>getTurnNum: ");
|
||||
sb.append(state.getTurnNum());
|
||||
|
||||
|
||||
sb.append("<br>Using plane chase?:" + state.isPlaneChase());
|
||||
if (state.isPlaneChase()) {
|
||||
Plane currentPlane = state.getCurrentPlane();
|
||||
|
|
@ -1157,7 +1156,7 @@ public class GameController implements GameCallback {
|
|||
sb.append("<br>Current plane:" + currentPlane.getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sb.append("<br>Future Timeout:");
|
||||
if (futureTimeout != null) {
|
||||
sb.append("Cancelled?=");
|
||||
|
|
@ -1188,8 +1187,13 @@ public class GameController implements GameCallback {
|
|||
|
||||
sb.append("<br>Active player is: ");
|
||||
sb.append(game.getPlayer(state.getActivePlayerId()).getName());
|
||||
|
||||
PassAbility pass = new PassAbility();
|
||||
if (game.getPlayer(state.getActivePlayerId()).hasLeft()) {
|
||||
Player p = game.getPlayer(state.getActivePlayerId());
|
||||
if (p != null) {
|
||||
p.concede(game);
|
||||
}
|
||||
Phase currentPhase = game.getPhase();
|
||||
if (currentPhase != null) {
|
||||
currentPhase.getStep().skipStep(game, state.getActivePlayerId());
|
||||
|
|
@ -1204,6 +1208,10 @@ public class GameController implements GameCallback {
|
|||
sb.append("<br>getChoosingPlayerId: ");
|
||||
if (state.getChoosingPlayerId() != null) {
|
||||
if (game.getPlayer(state.getChoosingPlayerId()).hasLeft()) {
|
||||
Player p = game.getPlayer(state.getChoosingPlayerId());
|
||||
if (p != null) {
|
||||
p.concede(game);
|
||||
}
|
||||
Phase currentPhase = game.getPhase();
|
||||
if (currentPhase != null && !fixedAlready) {
|
||||
currentPhase.getStep().endStep(game, state.getActivePlayerId());
|
||||
|
|
@ -1218,7 +1226,11 @@ public class GameController implements GameCallback {
|
|||
|
||||
sb.append("<br><font color=orange>Player with Priority is: ");
|
||||
if (state.getPriorityPlayerId() != null) {
|
||||
if (game.getPlayer(state.getPriorityPlayerId()).hasLeft()) {
|
||||
if (game.getPlayer(state.getPriorityPlayerId()).hasLeft()) {
|
||||
Player p = game.getPlayer(state.getPriorityPlayerId());
|
||||
if (p != null) {
|
||||
p.concede(game);
|
||||
}
|
||||
Phase currentPhase = game.getPhase();
|
||||
if (currentPhase != null && !fixedAlready) {
|
||||
currentPhase.getStep().skipStep(game, state.getActivePlayerId());
|
||||
|
|
@ -1228,7 +1240,7 @@ public class GameController implements GameCallback {
|
|||
}
|
||||
sb.append(game.getPlayer(state.getPriorityPlayerId()).getName());
|
||||
sb.append("</font>");
|
||||
}
|
||||
}
|
||||
|
||||
sb.append("<br>Future Timeout:");
|
||||
if (futureTimeout != null) {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ public enum TournamentFactory {
|
|||
Map<String,Integer> setInfo = new LinkedHashMap<>();
|
||||
for (String setCode: options.getLimitedOptions().getSetCodes()) {
|
||||
tournament.getSets().add(Sets.findSet(setCode));
|
||||
int count = setInfo.containsKey(setCode) ? setInfo.get(setCode) : 0;
|
||||
int count = setInfo.getOrDefault(setCode, 0);
|
||||
setInfo.put(setCode, count + 1);
|
||||
}
|
||||
tournament.getOptions().getLimitedOptions().setNumberBoosters(tournament.getTournamentType().getNumBoosters());
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.mage</groupId>
|
||||
<artifactId>mage-root</artifactId>
|
||||
<version>1.4.30</version>
|
||||
<version>1.4.31</version>
|
||||
</parent>
|
||||
|
||||
<groupId>org.mage</groupId>
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ class AbandonedSarcophagusReplacementEffect extends ReplacementEffectImpl {
|
|||
Card card = game.getCard(event.getTargetId());
|
||||
if (card != null
|
||||
&& watcher != null
|
||||
&& card.getOwnerId().equals(controller.getId())) {
|
||||
&& card.isOwnedBy(controller.getId())) {
|
||||
for (Ability ability : card.getAbilities()) {
|
||||
if (ability instanceof CyclingAbility) {
|
||||
cardHasCycling = true;
|
||||
|
|
@ -199,7 +199,7 @@ class AbandonedSarcophagusWatcher extends Watcher {
|
|||
Player controller = game.getPlayer(event.getPlayerId());
|
||||
if (card != null
|
||||
&& controller != null
|
||||
&& card.getOwnerId().equals(controller.getId())) {
|
||||
&& card.isOwnedBy(controller.getId())) {
|
||||
Cards c = getCardsCycledThisTurn(event.getPlayerId());
|
||||
c.add(card);
|
||||
cycledCardsThisTurn.put(event.getPlayerId(), c);
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ class AbbotOfKeralKeepCastFromExileEffect extends AsThoughEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
|
||||
return source.getControllerId().equals(affectedControllerId)
|
||||
return source.isControlledBy(affectedControllerId)
|
||||
&& objectId.equals(getTargetPointer().getFirst(game, source));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
43
Mage.Sets/src/mage/cards/a/AbnormalEndurance.java
Normal file
43
Mage.Sets/src/mage/cards/a/AbnormalEndurance.java
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.common.DiesTriggeredAbility;
|
||||
import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostTargetEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class AbnormalEndurance extends CardImpl {
|
||||
|
||||
public AbnormalEndurance(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{B}");
|
||||
|
||||
// Until end of turn, target creature gets +2/+0 and gains "When this creature dies, return it to the battlefield tapped under its owner's control."
|
||||
getSpellAbility().addTarget(new TargetCreaturePermanent());
|
||||
getSpellAbility().addEffect(new BoostTargetEffect(2, 0, Duration.EndOfTurn)
|
||||
.setText("Until end of turn, target creature gets +2/+0")
|
||||
);
|
||||
getSpellAbility().addEffect(new GainAbilityTargetEffect(
|
||||
new DiesTriggeredAbility(new ReturnSourceFromGraveyardToBattlefieldEffect(true, true), false),
|
||||
Duration.EndOfTurn,
|
||||
"and gains \"When this creature dies, return it to the battlefield tapped under its owner's control.\""
|
||||
));
|
||||
}
|
||||
|
||||
public AbnormalEndurance(final AbnormalEndurance card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbnormalEndurance copy() {
|
||||
return new AbnormalEndurance(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -31,9 +31,9 @@ public final class AbruptDecay extends CardImpl {
|
|||
public AbruptDecay(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{B}{G}");
|
||||
|
||||
// Abrupt Decay can't be countered by spells or abilities.
|
||||
// Abrupt Decay can't be countered.
|
||||
Effect effect = new CantBeCounteredSourceEffect();
|
||||
effect.setText("{this} can't be countered by spells or abilities");
|
||||
effect.setText("this spell can't be countered");
|
||||
Ability ability = new SimpleStaticAbility(Zone.STACK, effect);
|
||||
ability.setRuleAtTheTop(true);
|
||||
this.addAbility(ability);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import java.util.UUID;
|
|||
import mage.MageInt;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.condition.common.ControlsCreatureGreatestToughnessCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -27,7 +27,7 @@ public final class AbzanBeastmaster extends CardImpl {
|
|||
this.toughness = new MageInt(1);
|
||||
|
||||
// At the beginning of your upkeep, draw a card if you control the creature with the greatest toughness or tied for the greatest toughness.
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
new BeginningOfUpkeepTriggeredAbility(new DrawCardSourceControllerEffect(1), TargetController.YOU, false),
|
||||
ControlsCreatureGreatestToughnessCondition.instance,
|
||||
"At the beginning of your upkeep, draw a card if you control the creature with the greatest toughness or tied for the greatest toughness."
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ class AcidicSoilEffect extends OneShotEffect {
|
|||
if (player != null) {
|
||||
int amount = 0;
|
||||
for (Permanent permanent : permanents) {
|
||||
if (permanent.getControllerId().equals(playerId)) {
|
||||
if (permanent.isControlledBy(playerId)) {
|
||||
amount++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue