Merge pull request #7 from magefree/master

pulling changes
This commit is contained in:
brodee 2019-01-16 22:44:31 -08:00 committed by GitHub
commit 9851b4dc1d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2590 changed files with 29302 additions and 12276 deletions

3
.gitignore vendored
View file

@ -78,6 +78,7 @@ Mage.Tests/Mage.log
Mage.Tests/watchdog.log
# Mage
*.log
Mage/target
# Mage.Updater
@ -91,7 +92,7 @@ Mage.Verify/AllCards.json.zip
Mage.Verify/AllSets.json.zip
Mage.Verify/AllCards.json
Mage.Verify/AllSets.json
/db
Mage.Verify/db
releases
Utils/author.txt

View file

@ -3,3 +3,10 @@ dist: trusty
language: java
before_install:
- echo "MAVEN_OPTS='-Xmx2g'" > ~/.mavenrc
# addons:
# sonarcloud:
# organization: "magefree"
# token:
# secure: SONAR_TOKEN
# script:
# - mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent install sonar:sonar

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<groupId>org.mage</groupId>

View file

@ -1,22 +1,22 @@
NAME:Douglas Scheinberg's Séance Combo
1 [AVR:42] Alchemist's Apprentice
4 [RTR:1] Angel of Serenity
1 [ISD:68] Mirror-Mad Phantasm
2 [ISD:248] Sulfur Falls
4 [RTR:249] Transguild Promenade
3 [RTR:247] Steam Vents
1 [AVR:1] Angel of Glory's Rise
4 [ISD:122] Unburial Rites
4 [RTR:201] Supreme Verdict
1 [ISD:55] Forbidden Alchemy
1 [ISD:61] Laboratory Maniac
3 [ISD:238] Clifftop Retreat
3 [ISD:43] Armored Skaab
2 [GTC:245] Sacred Foundry
4 [M13:69] Sphinx of Uthuun
3 [M13:225] Glacial Fortress
4 [RTR:172] Izzet Charm
2 [AVR:229] Slayers' Stronghold
2 [AVR:226] Cavern of Souls
4 [DKA:87] Faithless Looting
4 [RTR:241] Hallowed Fountain
NAME:Douglas Scheinberg's Séance Combo
1 [AVR:42] Alchemist's Apprentice
4 [RTR:1] Angel of Serenity
1 [ISD:68] Mirror-Mad Phantasm
2 [ISD:248] Sulfur Falls
4 [RTR:249] Transguild Promenade
3 [RTR:247] Steam Vents
1 [AVR:1] Angel of Glory's Rise
4 [ISD:122] Unburial Rites
4 [RTR:201] Supreme Verdict
1 [ISD:55] Forbidden Alchemy
1 [ISD:61] Laboratory Maniac
3 [ISD:238] Clifftop Retreat
3 [ISD:43] Armored Skaab
2 [GTC:245] Sacred Foundry
4 [M13:69] Sphinx of Uthuun
3 [M13:225] Glacial Fortress
4 [RTR:172] Izzet Charm
2 [AVR:229] Slayers' Stronghold
2 [AVR:226] Cavern of Souls
4 [DKA:87] Faithless Looting
4 [RTR:241] Hallowed Fountain

View file

@ -1,31 +1,31 @@
NAME:Emmanuel Ramírez's Reanimator
4 [ISD:170] Avacyn's Pilgrim
2 [ISD:249] Woodland Cemetery
3 [M13:159] Acidic Slime
3 [ISD:196] Mulch
1 [ISD:239] Gavony Township
3 [ISD:15] Fiend Hunter
3 [RTR:1] Angel of Serenity
2 [AVR:226] Cavern of Souls
4 [AVR:32] Restoration Angel
2 [ISD:242] Isolated Chapel
4 [RTR:248] Temple Garden
4 [RTR:243] Overgrown Tomb
3 [M13:160] Arbor Elf
4 [M13:193] Thragtusk
2 [DGM:103] Sin Collector
4 [RTR:165] Grisly Salvage
3 [M13:229] Sunpetal Grove
3 [RTR:270] Forest
2 [GTC:242] Godless Shrine
4 [ISD:122] Unburial Rites
SB: 1 [RTR:148] Centaur Healer
SB: 2 [DKA:17] Ray of Revelation
SB: 1 [M13:159] Acidic Slime
SB: 2 [ISD:181] Garruk Relentless
SB: 2 [RTR:141] Abrupt Decay
SB: 1 [ISD:15] Fiend Hunter
SB: 2 [RTR:213] Deathrite Shaman
SB: 1 [DGM:103] Sin Collector
SB: 2 [RTR:178] Loxodon Smiter
SB: 1 [ISD:115] Sever the Bloodline
NAME:Emmanuel Ramírez's Reanimator
4 [ISD:170] Avacyn's Pilgrim
2 [ISD:249] Woodland Cemetery
3 [M13:159] Acidic Slime
3 [ISD:196] Mulch
1 [ISD:239] Gavony Township
3 [ISD:15] Fiend Hunter
3 [RTR:1] Angel of Serenity
2 [AVR:226] Cavern of Souls
4 [AVR:32] Restoration Angel
2 [ISD:242] Isolated Chapel
4 [RTR:248] Temple Garden
4 [RTR:243] Overgrown Tomb
3 [M13:160] Arbor Elf
4 [M13:193] Thragtusk
2 [DGM:103] Sin Collector
4 [RTR:165] Grisly Salvage
3 [M13:229] Sunpetal Grove
3 [RTR:270] Forest
2 [GTC:242] Godless Shrine
4 [ISD:122] Unburial Rites
SB: 1 [RTR:148] Centaur Healer
SB: 2 [DKA:17] Ray of Revelation
SB: 1 [M13:159] Acidic Slime
SB: 2 [ISD:181] Garruk Relentless
SB: 2 [RTR:141] Abrupt Decay
SB: 1 [ISD:15] Fiend Hunter
SB: 2 [RTR:213] Deathrite Shaman
SB: 1 [DGM:103] Sin Collector
SB: 2 [RTR:178] Loxodon Smiter
SB: 1 [ISD:115] Sever the Bloodline

View file

@ -1,33 +1,33 @@
NAME:Frédéric Mercier's Esper Control
2 [M13:26] Planar Cleansing
1 [RTR:250] Plains
4 [M13:225] Glacial Fortress
2 [GTC:63] Devour Flesh
4 [ISD:83] Think Twice
4 [RTR:145] Azorius Charm
2 [ISD:78] Snapcaster Mage
2 [GTC:249] Watery Grave
1 [RTR:82] Ultimate Price
1 [RTR:156] Dramatic Rescue
2 [GPT:157] Godless Shrine
3 [AVR:32] Restoration Angel
4 [M13:43] Augur of Bolas
4 [ISD:242] Isolated Chapel
4 [RTR:201] Supreme Verdict
2 [MIR:61] Dissipate
1 [RTR:256] Island
1 [RTR:255] Island
4 [ISD:245] Nephalia Drownyard
4 [RTR:241] Hallowed Fountain
4 [M13:223] Drowned Catacomb
4 [RTR:200] Sphinx's Revelation
SB: 1 [WWK:26] Dispel
SB: 3 [AVR:104] Gloom Surgeon
SB: 2 [M11:96] Duress
SB: 2 [ISD:236] Witchbane Orb
SB: 1 [RTR:18] Rest in Peace
SB: 1 [RTR:36] Dispel
SB: 1 [SOK:158] Pithing Needle
SB: 1 [RTR:47] Psychic Spiral
SB: 2 [M13:56] Jace, Memory Adept
SB: 1 [M12:69] Negate
NAME:Frédéric Mercier's Esper Control
2 [M13:26] Planar Cleansing
1 [RTR:250] Plains
4 [M13:225] Glacial Fortress
2 [GTC:63] Devour Flesh
4 [ISD:83] Think Twice
4 [RTR:145] Azorius Charm
2 [ISD:78] Snapcaster Mage
2 [GTC:249] Watery Grave
1 [RTR:82] Ultimate Price
1 [RTR:156] Dramatic Rescue
2 [GPT:157] Godless Shrine
3 [AVR:32] Restoration Angel
4 [M13:43] Augur of Bolas
4 [ISD:242] Isolated Chapel
4 [RTR:201] Supreme Verdict
2 [MIR:61] Dissipate
1 [RTR:256] Island
1 [RTR:255] Island
4 [ISD:245] Nephalia Drownyard
4 [RTR:241] Hallowed Fountain
4 [M13:223] Drowned Catacomb
4 [RTR:200] Sphinx's Revelation
SB: 1 [WWK:26] Dispel
SB: 3 [AVR:104] Gloom Surgeon
SB: 2 [M11:96] Duress
SB: 2 [ISD:236] Witchbane Orb
SB: 1 [RTR:18] Rest in Peace
SB: 1 [RTR:36] Dispel
SB: 1 [SOK:158] Pithing Needle
SB: 1 [RTR:47] Psychic Spiral
SB: 2 [M13:56] Jace, Memory Adept
SB: 1 [M12:69] Negate

View file

@ -1,36 +1,36 @@
NAME:Jérémy Dezani's Jund Midrange
4 [M13:170] Farseek
3 [AVR:129] Bonfire of the Damned
1 [DKA:76] Tragic Slip
4 [ISD:249] Woodland Cemetery
2 [RTR:141] Abrupt Decay
3 [ISD:105] Liliana of the Veil
3 [M13:222] Dragonskull Summit
1 [RTR:82] Ultimate Price
2 [ISD:243] Kessig Wolf Run
1 [M13:217] Staff of Nin
1 [M13:101] Murder
4 [GTC:247] Stomping Ground
3 [ISD:215] Olivia Voldaren
2 [M13:174] Garruk, Primal Hunter
2 [RTR:188] Rakdos's Return
4 [DKA:140] Huntmaster of the Fells
4 [RTR:243] Overgrown Tomb
2 [M13:160] Arbor Elf
4 [M13:193] Thragtusk
4 [RTR:238] Blood Crypt
2 [M13:228] Rootbound Crag
1 [RTR:101] Mizzium Mortars
1 [RTR:157] Dreadbore
2 [RTR:270] Forest
SB: 1 [RTR:188] Rakdos's Return
SB: 1 [AVR:129] Bonfire of the Damned
SB: 1 [DKA:76] Tragic Slip
SB: 2 [M13:159] Acidic Slime
SB: 1 [RTR:141] Abrupt Decay
SB: 1 [DKA:149] Grafdigger's Cage
SB: 2 [M13:90] Duress
SB: 1 [M13:219] Tormod's Crypt
SB: 3 [RTR:197] Slaughter Games
SB: 1 [RTR:101] Mizzium Mortars
SB: 1 [AVR:149] Pillar of Flame
NAME:Jérémy Dezani's Jund Midrange
4 [M13:170] Farseek
3 [AVR:129] Bonfire of the Damned
1 [DKA:76] Tragic Slip
4 [ISD:249] Woodland Cemetery
2 [RTR:141] Abrupt Decay
3 [ISD:105] Liliana of the Veil
3 [M13:222] Dragonskull Summit
1 [RTR:82] Ultimate Price
2 [ISD:243] Kessig Wolf Run
1 [M13:217] Staff of Nin
1 [M13:101] Murder
4 [GTC:247] Stomping Ground
3 [ISD:215] Olivia Voldaren
2 [M13:174] Garruk, Primal Hunter
2 [RTR:188] Rakdos's Return
4 [DKA:140] Huntmaster of the Fells
4 [RTR:243] Overgrown Tomb
2 [M13:160] Arbor Elf
4 [M13:193] Thragtusk
4 [RTR:238] Blood Crypt
2 [M13:228] Rootbound Crag
1 [RTR:101] Mizzium Mortars
1 [RTR:157] Dreadbore
2 [RTR:270] Forest
SB: 1 [RTR:188] Rakdos's Return
SB: 1 [AVR:129] Bonfire of the Damned
SB: 1 [DKA:76] Tragic Slip
SB: 2 [M13:159] Acidic Slime
SB: 1 [RTR:141] Abrupt Decay
SB: 1 [DKA:149] Grafdigger's Cage
SB: 2 [M13:90] Duress
SB: 1 [M13:219] Tormod's Crypt
SB: 3 [RTR:197] Slaughter Games
SB: 1 [RTR:101] Mizzium Mortars
SB: 1 [AVR:149] Pillar of Flame

View file

@ -1,32 +1,32 @@
NAME:Philipp Schönegger's Miracles
4 [C13:341] Island
4 [CHK:268] Sensei's Divining Top
4 [ONS:316] Flooded Strand
2 [AVR:20] Entreat the Angels
3 [WWK:31] Jace, the Mind Sculptor
3 [ISD:78] Snapcaster Mage
4 [ALL:42] Force of Will
2 [ZEN:211] Arid Mesa
2 [M12:73] Ponder
1 [MMA:70] Vendilion Clique
4 [CMD:40] Brainstorm
1 [LEG:248] Karakas
2 [7ED:67] Counterspell
3 [CSP:31] Counterbalance
4 [AVR:38] Terminus
4 [ZEN:223] Scalding Tarn
2 [ZEN:67] Spell Pierce
2 [C13:337] Plains
2 [3ED:306] Volcanic Island
3 [3ED:304] Tundra
4 [DDF:22] Swords to Plowshares
SB: 1 [5ED:262] Pyroblast
SB: 1 [AVR:20] Entreat the Angels
SB: 3 [CMD:46] Flusterstorm
SB: 2 [4ED:236] Red Elemental Blast
SB: 1 [TSB:6] Disenchant
SB: 2 [MMA:204] Engineered Explosives
SB: 1 [7ED:67] Counterspell
SB: 1 [RTR:201] Supreme Verdict
SB: 1 [MMA:70] Vendilion Clique
SB: 2 [RTR:18] Rest in Peace
NAME:Philipp Schönegger's Miracles
4 [C13:341] Island
4 [CHK:268] Sensei's Divining Top
4 [ONS:316] Flooded Strand
2 [AVR:20] Entreat the Angels
3 [WWK:31] Jace, the Mind Sculptor
3 [ISD:78] Snapcaster Mage
4 [ALL:42] Force of Will
2 [ZEN:211] Arid Mesa
2 [M12:73] Ponder
1 [MMA:70] Vendilion Clique
4 [CMD:40] Brainstorm
1 [LEG:248] Karakas
2 [7ED:67] Counterspell
3 [CSP:31] Counterbalance
4 [AVR:38] Terminus
4 [ZEN:223] Scalding Tarn
2 [ZEN:67] Spell Pierce
2 [C13:337] Plains
2 [3ED:306] Volcanic Island
3 [3ED:304] Tundra
4 [DDF:22] Swords to Plowshares
SB: 1 [5ED:262] Pyroblast
SB: 1 [AVR:20] Entreat the Angels
SB: 3 [CMD:46] Flusterstorm
SB: 2 [4ED:236] Red Elemental Blast
SB: 1 [TSB:6] Disenchant
SB: 2 [MMA:204] Engineered Explosives
SB: 1 [7ED:67] Counterspell
SB: 1 [RTR:201] Supreme Verdict
SB: 1 [MMA:70] Vendilion Clique
SB: 2 [RTR:18] Rest in Peace

View file

@ -1,42 +1,42 @@
NAME:Stefan Böttcher's Deathblade
1 [WWK:134] Creeping Tar Pit
4 [RTR:213] Deathrite Shaman
1 [AVR:20] Entreat the Angels
2 [C13:63] True-Name Nemesis
2 [WWK:31] Jace, the Mind Sculptor
3 [ISD:78] Snapcaster Mage
3 [MMA:75] Dark Confidant
1 [MMA:70] Vendilion Clique
1 [NPH:130] Batterskull
1 [ARB:85] Zealous Persecution
4 [CMD:40] Brainstorm
2 [THS:107] Thoughtseize
1 [MMA:204] Engineered Explosives
1 [BOK:163] Umezawa's Jitte
1 [3ED:298] Scrubland
1 [C13:337] Plains
3 [3ED:305] Underground Sea
3 [3ED:304] Tundra
4 [DDF:22] Swords to Plowshares
1 [3ED:303] Tropical Island
1 [C13:341] Island
3 [ONS:316] Flooded Strand
1 [C13:345] Swamp
1 [ZEN:219] Marsh Flats
2 [TMP:340] Wasteland
1 [LEG:248] Karakas
1 [MMA:219] Academy Ruins
1 [7ED:67] Counterspell
3 [ONS:321] Polluted Delta
3 [ZEN:67] Spell Pierce
3 [WWK:20] Stoneforge Mystic
SB: 1 [ISD:105] Liliana of the Veil
SB: 1 [RTR:155] Detention Sphere
SB: 3 [ALL:42] Force of Will
SB: 1 [RTR:201] Supreme Verdict
SB: 3 [M11:21] Leyline of Sanctity
SB: 1 [MBS:138] Sword of Feast and Famine
SB: 2 [NPH:74] Surgical Extraction
SB: 1 [THS:65] Swan Song
SB: 1 [MMA:213] Relic of Progenitus
SB: 1 [NMS:111] Reverent Silence
NAME:Stefan Böttcher's Deathblade
1 [WWK:134] Creeping Tar Pit
4 [RTR:213] Deathrite Shaman
1 [AVR:20] Entreat the Angels
2 [C13:63] True-Name Nemesis
2 [WWK:31] Jace, the Mind Sculptor
3 [ISD:78] Snapcaster Mage
3 [MMA:75] Dark Confidant
1 [MMA:70] Vendilion Clique
1 [NPH:130] Batterskull
1 [ARB:85] Zealous Persecution
4 [CMD:40] Brainstorm
2 [THS:107] Thoughtseize
1 [MMA:204] Engineered Explosives
1 [BOK:163] Umezawa's Jitte
1 [3ED:298] Scrubland
1 [C13:337] Plains
3 [3ED:305] Underground Sea
3 [3ED:304] Tundra
4 [DDF:22] Swords to Plowshares
1 [3ED:303] Tropical Island
1 [C13:341] Island
3 [ONS:316] Flooded Strand
1 [C13:345] Swamp
1 [ZEN:219] Marsh Flats
2 [TMP:340] Wasteland
1 [LEG:248] Karakas
1 [MMA:219] Academy Ruins
1 [7ED:67] Counterspell
3 [ONS:321] Polluted Delta
3 [ZEN:67] Spell Pierce
3 [WWK:20] Stoneforge Mystic
SB: 1 [ISD:105] Liliana of the Veil
SB: 1 [RTR:155] Detention Sphere
SB: 3 [ALL:42] Force of Will
SB: 1 [RTR:201] Supreme Verdict
SB: 3 [M11:21] Leyline of Sanctity
SB: 1 [MBS:138] Sword of Feast and Famine
SB: 2 [NPH:74] Surgical Extraction
SB: 1 [THS:65] Swan Song
SB: 1 [MMA:213] Relic of Progenitus
SB: 1 [NMS:111] Reverent Silence

View file

@ -3,6 +3,8 @@ package mage.client;
import mage.cards.action.ActionCallback;
import mage.cards.decks.Deck;
import mage.cards.repository.CardRepository;
import mage.cards.repository.ExpansionRepository;
import mage.cards.repository.RepositoryUtil;
import mage.client.cards.BigCard;
import mage.client.chat.ChatPanelBasic;
import mage.client.components.*;
@ -212,6 +214,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
LOGGER.fatal(null, ex);
}
RepositoryUtil.bootstrapLocalDb();
ManaSymbols.loadImages();
Plugins.instance.loadPlugins();
@ -281,7 +284,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
if (Plugins.instance.isCounterPluginLoaded()) {
int i = Plugins.instance.getGamesPlayed();
JLabel label = new JLabel(" Games played: " + String.valueOf(i));
JLabel label = new JLabel(" Games played: " + i);
desktopPane.add(label, JLayeredPane.DEFAULT_LAYER + 1);
label.setVisible(true);
label.setForeground(Color.white);
@ -717,6 +720,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
boolean autoConnectParamValue = startUser != null || Boolean.parseBoolean(PREFS.get("autoConnect", "false"));
boolean status = false;
if (autoConnectParamValue) {
LOGGER.info("Auto-connecting to " + MagePreferences.getServerAddress());
status = performConnect(false);
}
return status;
@ -739,6 +743,9 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
currentConnection.setPassword(password);
currentConnection.setHost(server);
currentConnection.setPort(port);
// force to redownload db on updates
boolean redownloadDatabase = (ExpansionRepository.instance.getSetByCode("GRN") == null || CardRepository.instance.findCard("Island") == null);
currentConnection.setForceDBComparison(redownloadDatabase);
String allMAC = "";
try {
allMAC = Connection.getMAC();
@ -1160,7 +1167,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
/**
* @param args the command line arguments
*/
public static void main(final String args[]) {
public static void main(final String[] args) {
// Workaround for #451
System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
LOGGER.info("Starting MAGE client version " + VERSION);

View file

@ -85,11 +85,6 @@ public class StackDialog extends IDialogPanel {
jTitle.setFont(new Font("Dialog", Font.BOLD, 14));
jTitle.setText("Current stack: ");
/*jTitle2 = new CustomLabel();
jTitle2.setBounds(new Rectangle(5, 5 + SettingsManager.getInstance().getCardSize().height + 30, 129, 20));
jTitle2.setFont(new Font("Dialog", Font.BOLD, 14));
jTitle2.setText("Spell targets:");*/
this.setLayout(null);
jLayeredPane.setLayout(null);

View file

@ -94,7 +94,6 @@ public final class Constants {
public interface IO {
String DEFAULT_IMAGES_DIR = "plugins" + File.separator + "images" + File.separator;
String IMAGE_PROPERTIES_FILE = "image.url.properties";
}
public enum DeckEditorMode {

View file

@ -253,7 +253,7 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
predicates.add(new ColorPredicate(ObjectColor.WHITE));
}
if (this.tbColorless.isSelected()) {
predicates.add(new ColorlessPredicate());
predicates.add(ColorlessPredicate.instance);
}
filter.add(Predicates.or(predicates));

View file

@ -14,7 +14,6 @@ import mage.cards.Sets;
import mage.cards.decks.Deck;
import mage.cards.decks.DeckCardLists;
import mage.cards.decks.importer.DeckImporter;
import mage.cards.decks.importer.DeckImporterUtil;
import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
import mage.client.MageFrame;
@ -798,7 +797,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
MageFrame.getDesktop().setCursor(new Cursor(Cursor.WAIT_CURSOR));
try {
newDeck = Deck.load(DeckImporterUtil.importDeck(dialog.getTmpPath(), errorMessages), true, true);
newDeck = Deck.load(DeckImporter.importDeckFromFile(dialog.getTmpPath(), errorMessages), true, true);
processAndShowImportErrors(errorMessages);
if (newDeck != null) {
@ -831,7 +830,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
MageFrame.getDesktop().setCursor(new Cursor(Cursor.WAIT_CURSOR));
try {
deckToAppend = Deck.load(DeckImporterUtil.importDeck(dialog.getTmpPath(), errorMessages), true, true);
deckToAppend = Deck.load(DeckImporter.importDeckFromFile(dialog.getTmpPath(), errorMessages), true, true);
processAndShowImportErrors(errorMessages);
if (deckToAppend != null) {
@ -878,7 +877,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
Deck newDeck = null;
StringBuilder errorMessages = new StringBuilder();
newDeck = Deck.load(DeckImporterUtil.importDeck(file.getPath(), errorMessages), true, true);
newDeck = Deck.load(DeckImporter.importDeckFromFile(file.getPath(), errorMessages), true, true);
processAndShowImportErrors(errorMessages);
if (newDeck != null) {
@ -977,7 +976,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
File file = fcImportDeck.getSelectedFile();
MageFrame.getDesktop().setCursor(new Cursor(Cursor.WAIT_CURSOR));
try {
DeckImporter importer = DeckImporterUtil.getDeckImporter(file.getPath());
DeckImporter importer = DeckImporter.getDeckImporter(file.getPath());
if (importer != null) {
StringBuilder errorMessages = new StringBuilder();
@ -1048,7 +1047,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
try {
MageFrame.getDesktop().setCursor(new Cursor(Cursor.WAIT_CURSOR));
String path = DeckGenerator.generateDeck();
deck = Deck.load(DeckImporterUtil.importDeck(path), true, true);
deck = Deck.load(DeckImporter.importDeckFromFile(path), true, true);
} catch (GameException ex) {
JOptionPane.showMessageDialog(MageFrame.getDesktop(), ex.getMessage(), "Error loading generated deck", JOptionPane.ERROR_MESSAGE);
} catch (DeckGeneratorException ex) {
@ -1120,7 +1119,12 @@ class ImportFilter extends FileFilter {
ext = s.substring(i + 1).toLowerCase(Locale.ENGLISH);
}
if (ext != null) {
if (ext.toLowerCase(Locale.ENGLISH).equals("dec") || ext.toLowerCase(Locale.ENGLISH).equals("mwdeck") || ext.toLowerCase(Locale.ENGLISH).equals("txt") || ext.toLowerCase(Locale.ENGLISH).equals("dek")) {
if (ext.toLowerCase(Locale.ENGLISH).equals("dec")
|| ext.toLowerCase(Locale.ENGLISH).equals("mwdeck")
|| ext.toLowerCase(Locale.ENGLISH).equals("txt")
|| ext.toLowerCase(Locale.ENGLISH).equals("dek")
|| ext.toLowerCase(Locale.ENGLISH).equals("cod")
|| ext.toLowerCase(Locale.ENGLISH).equals("o8d")) {
return true;
}
}
@ -1129,7 +1133,7 @@ class ImportFilter extends FileFilter {
@Override
public String getDescription() {
return "*.dec | *.mwDeck | *.txt | *.dek";
return "*.dec | *.mwDeck | *.txt | *.dek | *.cod | *.o8d";
}
}

View file

@ -1,20 +1,5 @@
package mage.client.deckeditor.collection.viewer;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.InputStream;
import static java.lang.Math.min;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
import javax.imageio.ImageIO;
import javax.swing.*;
import mage.cards.*;
import mage.cards.repository.CardCriteria;
import mage.cards.repository.CardInfo;
@ -24,12 +9,13 @@ import mage.client.MageFrame;
import mage.client.cards.BigCard;
import mage.client.components.HoverButton;
import mage.client.plugins.impl.Plugins;
import mage.client.util.*;
import mage.client.util.Config;
import mage.client.util.ImageHelper;
import mage.client.util.NaturalOrderCardNumberComparator;
import mage.client.util.audio.AudioManager;
import mage.client.util.sets.ConstructedFormats;
import mage.components.ImagePanel;
import mage.components.ImagePanelStyle;
import mage.constants.Rarity;
import mage.game.command.Emblem;
import mage.game.command.Plane;
import mage.game.permanent.PermanentToken;
@ -41,6 +27,19 @@ import mage.view.PlaneView;
import org.apache.log4j.Logger;
import org.mage.card.arcane.ManaSymbols;
import org.mage.plugins.card.images.CardDownloadData;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.*;
import static java.lang.Math.min;
import static org.mage.plugins.card.images.DownloadPicturesService.getTokenCardUrls;
/**
@ -307,25 +306,33 @@ public class MageBook extends JComponent {
// Already have numTokens tokens presented. Appending the emblems to the end of these.
numTokens = numTokens % conf.CARDS_PER_PAGE;
if (numTokens < conf.CARDS_PER_PAGE / 2) {
// page 1 with tokens
for (int z = 0; z < numTokens && z < conf.CARDS_PER_PAGE / 2; z++) {
rectangle = CardPosition.translatePosition(z, rectangle, conf);
}
} else {
// page 2 with tokens
rectangle.setLocation(second_page_x, OFFSET_Y);
for (int z = 0; z < numTokens - conf.CARDS_PER_PAGE / 2; z++) {
rectangle = CardPosition.translatePosition(z, rectangle, conf);
}
}
// page 1 with emblems after tokens
int lastI = 0;
boolean needContinueFromPage1 = false;
for (int i = 0; i < size && i + numTokens < conf.CARDS_PER_PAGE / 2; i++) {
Emblem emblem = emblems.get(i);
addEmblem(emblem, bigCard, null, rectangle);
rectangle = CardPosition.translatePosition(i + numTokens, rectangle, conf);
lastI++;
needContinueFromPage1 = true;
}
rectangle.setLocation(second_page_x, OFFSET_Y);
// page 2 with emblems after tokens
if (needContinueFromPage1) {
rectangle.setLocation(second_page_x, OFFSET_Y);
}
if (size + numTokens > conf.CARDS_PER_PAGE / 2) {
for (int i = lastI; i < size && i + numTokens < conf.CARDS_PER_PAGE; i++) {
Emblem emblem = emblems.get(i);
@ -354,25 +361,33 @@ public class MageBook extends JComponent {
numTokensEmblems = numTokensEmblems % conf.CARDS_PER_PAGE;
if (numTokensEmblems < conf.CARDS_PER_PAGE / 2) {
// page 1 with tokens/emblems
for (int z = 0; z < numTokensEmblems && z < conf.CARDS_PER_PAGE / 2; z++) {
rectangle = CardPosition.translatePosition(z, rectangle, conf);
}
} else {
// page 2 with tokens/emblems
rectangle.setLocation(second_page_x, OFFSET_Y);
for (int z = 0; z < numTokensEmblems - conf.CARDS_PER_PAGE / 2; z++) {
rectangle = CardPosition.translatePosition(z, rectangle, conf);
}
}
// page 1 with planes after tokens/emblems
int lastI = 0;
boolean needContinueFromPage1 = false;
for (int i = 0; i < size && i + numTokensEmblems < conf.CARDS_PER_PAGE / 2; i++) {
Plane plane = planes.get(i);
addPlane(plane, bigCard, null, rectangle);
rectangle = CardPosition.translatePosition(i + numTokensEmblems, rectangle, conf);
lastI++;
needContinueFromPage1 = true;
}
rectangle.setLocation(second_page_x, OFFSET_Y);
// page 2 with planes after tokens/emblems
if (needContinueFromPage1) {
rectangle.setLocation(second_page_x, OFFSET_Y);
}
if (size + numTokensEmblems > conf.CARDS_PER_PAGE / 2) {
for (int i = lastI; i < size && i + numTokensEmblems < conf.CARDS_PER_PAGE; i++) {
Plane plane = planes.get(i);
@ -602,13 +617,13 @@ public class MageBook extends JComponent {
}
}
}
int totalTokens = getTotalNumTokens(set);
int start = 0;
if (!(page * conf.CARDS_PER_PAGE <= totalTokens && (page + 1) * conf.CARDS_PER_PAGE >= totalTokens)) {
start = page * conf.CARDS_PER_PAGE - totalTokens;
}
int end = emblems.size();
if ((page + 1) * conf.CARDS_PER_PAGE < totalTokens + emblems.size()) {
end = (page + 1) * conf.CARDS_PER_PAGE - totalTokens;
@ -659,7 +674,7 @@ public class MageBook extends JComponent {
}
}
}
int totalTokens = getTotalNumTokens(set);
int totalTokensEmblems = totalTokens + getTotalNumEmblems(set);
int start = 0;
@ -667,7 +682,7 @@ public class MageBook extends JComponent {
start = page * conf.CARDS_PER_PAGE - totalTokensEmblems;
pageRight.setVisible(true);
}
int end = planes.size();
if ((page + 1) * conf.CARDS_PER_PAGE < totalTokensEmblems + planes.size()) {
end = (page + 1) * conf.CARDS_PER_PAGE - totalTokensEmblems;

View file

@ -3,9 +3,6 @@
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JInternalFrameFormInfo">
<Properties>
<Property name="title" type="java.lang.String" value="Connect to server"/>
<Property name="normalBounds" type="java.awt.Rectangle" editor="org.netbeans.beaninfo.editors.RectangleEditor">
<Rectangle value="[100, 100, 410, 307]"/>
</Property>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
@ -26,30 +23,26 @@
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="-2" pref="29" max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="lblPort" alignment="1" min="-2" max="-2" attributes="0"/>
<Component id="lblServer" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="lblFlag" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lblUserName" min="-2" max="-2" attributes="0"/>
<Component id="lblPassword" alignment="1" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="lblUserName" alignment="0" max="32767" attributes="0"/>
<Component id="lblServer" alignment="0" max="32767" attributes="0"/>
<Component id="lblFastConnect" alignment="0" max="32767" attributes="0"/>
<Component id="lblPassword" alignment="0" max="32767" attributes="0"/>
<Component id="lblFlag" alignment="0" max="32767" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="jProxySettingsButton" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
<Component id="lblStatus" alignment="1" max="32767" attributes="0"/>
<Component id="chkForceUpdateDB" alignment="0" max="32767" attributes="0"/>
<Component id="chkAutoConnect" alignment="0" max="32767" attributes="0"/>
<Component id="txtUserName" alignment="0" max="32767" attributes="0"/>
<Component id="txtPassword" alignment="0" max="32767" attributes="0"/>
<Component id="panelFlag" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="btnConnect" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
@ -57,82 +50,58 @@
<Component id="btnRegister" max="32767" attributes="0"/>
<Component id="btnForgotPassword" max="32767" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnCancel" min="-2" pref="77" max="-2" attributes="0"/>
</Group>
<Component id="lblStatus" alignment="1" max="32767" attributes="0"/>
<Component id="chkForceUpdateDB" alignment="0" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Component id="jProxySettingsButton" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
<Component id="chkAutoConnect" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<Group type="103" groupAlignment="1" attributes="0">
<Component id="panelFlag" alignment="0" max="32767" attributes="0"/>
<Component id="txtServer" alignment="0" max="32767" attributes="0"/>
<Component id="txtUserName" alignment="0" max="32767" attributes="0"/>
<Component id="txtPassword" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<Component id="txtPort" min="-2" pref="71" max="-2" attributes="0"/>
<EmptySpace pref="11" max="32767" attributes="0"/>
<Component id="lblFastConnect" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnFind1" min="-2" pref="70" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnFind3" min="-2" pref="70" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnFind2" min="-2" pref="40" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Component id="btnFind" max="-2" attributes="0"/>
</Group>
<Component id="panelFast" alignment="0" max="32767" attributes="0"/>
<Component id="panelServer" alignment="1" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="filler2" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lblServer" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="txtServer" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnFind" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="txtPort" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lblPort" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnFind1" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnFind2" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnFind3" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lblFastConnect" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="txtUserName" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lblUserName" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="txtPassword" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lblPassword" alignment="3" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="panelFast" max="32767" attributes="0"/>
<Component id="lblFastConnect" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="panelServer" max="32767" attributes="0"/>
<Component id="lblServer" max="32767" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="txtUserName" min="-2" max="-2" attributes="0"/>
<Component id="lblUserName" min="-2" pref="20" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="txtPassword" max="32767" attributes="0"/>
<Component id="lblPassword" max="32767" attributes="0"/>
</Group>
</Group>
<Component id="filler2" pref="53" max="32767" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="panelFlag" min="-2" pref="20" max="-2" attributes="0"/>
<Component id="lblFlag" min="-2" pref="18" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
<Component id="chkAutoConnect" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="chkForceUpdateDB" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
<Component id="jProxySettingsButton" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="jProxySettingsButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
<Component id="lblStatus" min="-2" pref="24" max="-2" attributes="0"/>
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" max="-2" attributes="0">
@ -152,49 +121,27 @@
<SubComponents>
<Component class="javax.swing.JLabel" name="lblServer">
<Properties>
<Property name="horizontalAlignment" type="int" value="4"/>
<Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
<ComponentRef name="txtServer"/>
</Property>
<Property name="text" type="java.lang.String" value="Server:"/>
<Property name="text" type="java.lang.String" value="Server name:"/>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="txtServer">
</Component>
<Component class="javax.swing.JButton" name="btnFind">
<Properties>
<Property name="text" type="java.lang.String" value="Find..."/>
<Property name="toolTipText" type="java.lang.String" value="Shows the list of public servers"/>
<Property name="name" type="java.lang.String" value="findServerBtn" noResource="true"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="findPublicServerActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="lblPort">
<Properties>
<Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
<ComponentRef name="txtPort"/>
</Property>
<Property name="text" type="java.lang.String" value="Port:"/>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="txtPort">
<Events>
<EventHandler event="keyTyped" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="keyTyped"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="lblUserName">
<Properties>
<Property name="horizontalAlignment" type="int" value="4"/>
<Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
<ComponentRef name="txtUserName"/>
</Property>
<Property name="text" type="java.lang.String" value="User name:"/>
<Property name="text" type="java.lang.String" value="Username:"/>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="txtUserName">
</Component>
<Component class="javax.swing.JLabel" name="lblPassword">
<Properties>
<Property name="horizontalAlignment" type="int" value="4"/>
<Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
<ComponentRef name="txtPassword"/>
</Property>
@ -205,10 +152,11 @@
</Component>
<Component class="javax.swing.JLabel" name="lblFlag">
<Properties>
<Property name="horizontalAlignment" type="int" value="4"/>
<Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
<ComponentRef name="txtUserName"/>
</Property>
<Property name="text" type="java.lang.String" value="User flag:"/>
<Property name="text" type="java.lang.String" value="User&apos;s flag:"/>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="chkAutoConnect">
@ -289,86 +237,23 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnForgotPasswordActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnFind1">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/flags/de.png"/>
</Property>
<Property name="text" type="java.lang.String" value="X"/>
<Property name="toolTipText" type="java.lang.String" value="Connect to xmage.de (Europe, most popular)"/>
<Property name="actionCommand" type="java.lang.String" value="connectXmageDe"/>
<Property name="alignmentY" type="float" value="0.0"/>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[2, 2, 2, 2]"/>
</Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[42, 23]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[42, 23]"/>
</Property>
<Property name="name" type="java.lang.String" value="connectXmageDeBtn" noResource="true"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[23, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="connectXmageDe"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnFind2">
<Properties>
<Property name="text" type="java.lang.String" value="L"/>
<Property name="toolTipText" type="java.lang.String" value="Connect to localhost (local server)"/>
<Property name="actionCommand" type="java.lang.String" value="connectLocalhost"/>
<Property name="alignmentY" type="float" value="0.0"/>
<Property name="horizontalTextPosition" type="int" value="0"/>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[2, 2, 2, 2]"/>
</Property>
<Property name="name" type="java.lang.String" value="connectLocalhostBtn" noResource="true"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[23, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="connectLocalhost"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnFind3">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/flags/us.png"/>
</Property>
<Property name="text" type="java.lang.String" value="P"/>
<Property name="toolTipText" type="java.lang.String" value="Connect to mtg.powersofwar.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">
<Insets value="[2, 2, 2, 2]"/>
</Property>
<Property name="name" type="java.lang.String" value="connectXmageusBtn" noResource="true"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[23, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="connectXmageus"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="lblFastConnect">
<Properties>
<Property name="horizontalAlignment" type="int" value="0"/>
<Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
<ComponentRef name="btnFind1"/>
<ComponentRef name="btnFindMain"/>
</Property>
<Property name="text" type="java.lang.String" value="Fast connect to:"/>
<Property name="text" type="java.lang.String" value="Connect to:"/>
<Property name="name" type="java.lang.String" value="" noResource="true"/>
</Properties>
<AccessibilityProperties>
<Property name="AccessibleContext.accessibleName" type="java.lang.String" value="Fast connect to:"/>
</AccessibilityProperties>
</Component>
<Container class="javax.swing.JPanel" name="panelFlag">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[189, 30]"/>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[50, 33]"/>
</Property>
</Properties>
@ -420,5 +305,223 @@
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="panelFast">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
<Component id="btnFindMain" min="-2" pref="75" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="btnFindUs" min="-2" pref="75" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="btnFindBeta" min="-2" pref="75" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="btnFindLocal" min="-2" pref="75" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnFindOther" max="32767" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="btnFindMain" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnFindLocal" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnFindUs" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnFindBeta" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnFindOther" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JButton" name="btnFindMain">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/flags/de.png"/>
</Property>
<Property name="text" type="java.lang.String" value="X"/>
<Property name="toolTipText" type="java.lang.String" value="Connect to xmage.de (Europe, most popular, registration needs)"/>
<Property name="actionCommand" type="java.lang.String" value="connectXmageDe"/>
<Property name="alignmentY" type="float" value="0.0"/>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[2, 2, 2, 2]"/>
</Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[42, 23]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[42, 23]"/>
</Property>
<Property name="name" type="java.lang.String" value="connectXmageDeBtn" noResource="true"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[23, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="connectXmageDe"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnFindLocal">
<Properties>
<Property name="text" type="java.lang.String" value="LOCAL"/>
<Property name="toolTipText" type="java.lang.String" value="Connect to localhost (local server)"/>
<Property name="actionCommand" type="java.lang.String" value="connectLocalhost"/>
<Property name="alignmentY" type="float" value="0.0"/>
<Property name="horizontalTextPosition" type="int" value="0"/>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[2, 2, 2, 2]"/>
</Property>
<Property name="name" type="java.lang.String" value="connectLocalhostBtn" noResource="true"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[23, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="connectLocalhost"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnFindBeta">
<Properties>
<Property name="text" type="java.lang.String" value="BETA"/>
<Property name="toolTipText" type="java.lang.String" value="Connect to BETA server (use any username without registration)"/>
<Property name="alignmentY" type="float" value="0.0"/>
<Property name="horizontalTextPosition" type="int" value="0"/>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[2, 2, 2, 2]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[23, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnFindBetaconnectLocalhost"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnFindUs">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/flags/us.png"/>
</Property>
<Property name="text" type="java.lang.String" value="P"/>
<Property name="toolTipText" type="java.lang.String" value="Connect to mtg.powersofwar.com (USA, use any username without registration)"/>
<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">
<Insets value="[2, 2, 2, 2]"/>
</Property>
<Property name="name" type="java.lang.String" value="connectXmageusBtn" noResource="true"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[23, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="connectXmageus"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnFindOther">
<Properties>
<Property name="text" type="java.lang.String" value="Other servers..."/>
<Property name="toolTipText" type="java.lang.String" value="Choose server from full servers list"/>
<Property name="horizontalTextPosition" type="int" value="0"/>
<Property name="name" type="java.lang.String" value="findServerBtn" noResource="true"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="findPublicServerActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="panelServer">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="txtServer" min="-2" pref="212" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="lblPort" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="txtPort" min="-2" pref="75" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnCheckStatus" pref="141" max="32767" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="txtServer" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="txtPort" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lblPort" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnCheckStatus" alignment="3" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JTextField" name="txtServer">
</Component>
<Component class="javax.swing.JTextField" name="txtPort">
<Events>
<EventHandler event="keyTyped" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="keyTyped"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="lblPort">
<Properties>
<Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
<ComponentRef name="txtPort"/>
</Property>
<Property name="text" type="java.lang.String" value="Port:"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="btnCheckStatus">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/flags/world.png"/>
</Property>
<Property name="text" type="java.lang.String" value="Check online status"/>
<Property name="toolTipText" type="java.lang.String" value="Go to servers online statuses page"/>
<Property name="alignmentY" type="float" value="0.0"/>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[2, 2, 2, 2]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[23, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnCheckStatusActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.Box$Filler" name="filler2">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[32767, 50]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 50]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 50]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalStrut"/>
</AuxValues>
</Component>
</SubComponents>
</Form>

View file

@ -5,43 +5,11 @@
*/
package mage.client.dialog;
import java.awt.Cursor;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.Writer;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import mage.cards.repository.CardRepository;
import mage.cards.repository.ExpansionRepository;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.client.MageFrame;
import static mage.client.dialog.PreferencesDialog.KEY_CONNECTION_URL_SERVER_LIST;
import static mage.client.dialog.PreferencesDialog.KEY_CONNECT_AUTO_CONNECT;
import static mage.client.dialog.PreferencesDialog.KEY_CONNECT_FLAG;
import mage.client.preference.MagePreferences;
import mage.client.util.Config;
import mage.client.util.gui.countryBox.CountryItemEditor;
@ -50,6 +18,20 @@ import mage.remote.Connection;
import mage.utils.StreamUtils;
import org.apache.log4j.Logger;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.*;
import java.util.List;
import java.util.*;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import static mage.client.dialog.PreferencesDialog.*;
/**
* @author BetaSteward_at_googlemail.com
*/
@ -123,10 +105,6 @@ public class ConnectDialog extends MageDialog {
private void initComponents() {
lblServer = new javax.swing.JLabel();
txtServer = new javax.swing.JTextField();
btnFind = new javax.swing.JButton();
lblPort = new javax.swing.JLabel();
txtPort = new javax.swing.JTextField();
lblUserName = new javax.swing.JLabel();
txtUserName = new javax.swing.JTextField();
lblPassword = new javax.swing.JLabel();
@ -140,47 +118,41 @@ public class ConnectDialog extends MageDialog {
lblStatus = new javax.swing.JLabel();
btnRegister = new javax.swing.JButton();
btnForgotPassword = new javax.swing.JButton();
btnFind1 = new javax.swing.JButton();
btnFind2 = new javax.swing.JButton();
btnFind3 = new javax.swing.JButton();
lblFastConnect = new javax.swing.JLabel();
panelFlag = new javax.swing.JPanel();
cbFlag = new mage.client.util.gui.countryBox.CountryComboBox();
filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(4, 0), new java.awt.Dimension(5, 32767));
btnFlagSearch = new javax.swing.JButton();
panelFast = new javax.swing.JPanel();
btnFindMain = new javax.swing.JButton();
btnFindLocal = new javax.swing.JButton();
btnFindBeta = new javax.swing.JButton();
btnFindUs = new javax.swing.JButton();
btnFindOther = new javax.swing.JButton();
panelServer = new javax.swing.JPanel();
txtServer = new javax.swing.JTextField();
txtPort = new javax.swing.JTextField();
lblPort = new javax.swing.JLabel();
btnCheckStatus = new javax.swing.JButton();
filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 50), new java.awt.Dimension(0, 50), new java.awt.Dimension(32767, 50));
setTitle("Connect to server");
setNormalBounds(new java.awt.Rectangle(100, 100, 410, 307));
lblServer.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
lblServer.setLabelFor(txtServer);
lblServer.setText("Server:");
btnFind.setText("Find...");
btnFind.setToolTipText("Shows the list of public servers");
btnFind.setName("findServerBtn"); // NOI18N
btnFind.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
findPublicServerActionPerformed(evt);
}
});
lblPort.setLabelFor(txtPort);
lblPort.setText("Port:");
txtPort.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyTyped(java.awt.event.KeyEvent evt) {
ConnectDialog.this.keyTyped(evt);
}
});
lblServer.setText("Server name:");
lblUserName.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
lblUserName.setLabelFor(txtUserName);
lblUserName.setText("User name:");
lblUserName.setText("Username:");
lblPassword.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
lblPassword.setLabelFor(txtPassword);
lblPassword.setText("Password:");
lblFlag.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
lblFlag.setLabelFor(txtUserName);
lblFlag.setText("User flag:");
lblFlag.setText("User's flag:");
chkAutoConnect.setText("Automatically connect to this server next time");
chkAutoConnect.setToolTipText("<HTML>If active this connect dialog will not be shown if you choose to connect.<br>\nInstead XMage tries to connect to the last server you were connected to.");
@ -241,55 +213,12 @@ public class ConnectDialog extends MageDialog {
}
});
btnFind1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/flags/de.png"))); // NOI18N
btnFind1.setText("X");
btnFind1.setToolTipText("Connect to xmage.de (Europe, most popular)");
btnFind1.setActionCommand("connectXmageDe");
btnFind1.setAlignmentY(0.0F);
btnFind1.setMargin(new java.awt.Insets(2, 2, 2, 2));
btnFind1.setMaximumSize(new java.awt.Dimension(42, 23));
btnFind1.setMinimumSize(new java.awt.Dimension(42, 23));
btnFind1.setName("connectXmageDeBtn"); // NOI18N
btnFind1.setPreferredSize(new java.awt.Dimension(23, 23));
btnFind1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
connectXmageDe(evt);
}
});
btnFind2.setText("L");
btnFind2.setToolTipText("Connect to localhost (local server)");
btnFind2.setActionCommand("connectLocalhost");
btnFind2.setAlignmentY(0.0F);
btnFind2.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
btnFind2.setMargin(new java.awt.Insets(2, 2, 2, 2));
btnFind2.setName("connectLocalhostBtn"); // NOI18N
btnFind2.setPreferredSize(new java.awt.Dimension(23, 23));
btnFind2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
connectLocalhost(evt);
}
});
btnFind3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/flags/us.png"))); // NOI18N
btnFind3.setText("P");
btnFind3.setToolTipText("Connect to mtg.powersofwar.com (USA)");
btnFind3.setActionCommand("connectXmageus");
btnFind3.setAlignmentY(0.0F);
btnFind3.setMargin(new java.awt.Insets(2, 2, 2, 2));
btnFind3.setName("connectXmageusBtn"); // NOI18N
btnFind3.setPreferredSize(new java.awt.Dimension(23, 23));
btnFind3.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
connectXmageus(evt);
}
});
lblFastConnect.setLabelFor(btnFind1);
lblFastConnect.setText("Fast connect to:");
lblFastConnect.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
lblFastConnect.setLabelFor(btnFindMain);
lblFastConnect.setText("Connect to:");
lblFastConnect.setName(""); // NOI18N
panelFlag.setPreferredSize(new java.awt.Dimension(189, 30));
panelFlag.setMinimumSize(new java.awt.Dimension(50, 33));
panelFlag.setLayout(new javax.swing.BoxLayout(panelFlag, javax.swing.BoxLayout.LINE_AXIS));
cbFlag.setEditable(true);
@ -311,109 +240,232 @@ public class ConnectDialog extends MageDialog {
});
panelFlag.add(btnFlagSearch);
btnFindMain.setIcon(new javax.swing.ImageIcon(getClass().getResource("/flags/de.png"))); // NOI18N
btnFindMain.setText("X");
btnFindMain.setToolTipText("Connect to xmage.de (Europe, most popular, registration needs)");
btnFindMain.setActionCommand("connectXmageDe");
btnFindMain.setAlignmentY(0.0F);
btnFindMain.setMargin(new java.awt.Insets(2, 2, 2, 2));
btnFindMain.setMaximumSize(new java.awt.Dimension(42, 23));
btnFindMain.setMinimumSize(new java.awt.Dimension(42, 23));
btnFindMain.setName("connectXmageDeBtn"); // NOI18N
btnFindMain.setPreferredSize(new java.awt.Dimension(23, 23));
btnFindMain.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
connectXmageDe(evt);
}
});
btnFindLocal.setText("LOCAL");
btnFindLocal.setToolTipText("Connect to localhost (local server)");
btnFindLocal.setActionCommand("connectLocalhost");
btnFindLocal.setAlignmentY(0.0F);
btnFindLocal.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
btnFindLocal.setMargin(new java.awt.Insets(2, 2, 2, 2));
btnFindLocal.setName("connectLocalhostBtn"); // NOI18N
btnFindLocal.setPreferredSize(new java.awt.Dimension(23, 23));
btnFindLocal.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
connectLocalhost(evt);
}
});
btnFindBeta.setText("BETA");
btnFindBeta.setToolTipText("Connect to BETA server (use any username without registration)");
btnFindBeta.setAlignmentY(0.0F);
btnFindBeta.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
btnFindBeta.setMargin(new java.awt.Insets(2, 2, 2, 2));
btnFindBeta.setPreferredSize(new java.awt.Dimension(23, 23));
btnFindBeta.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnFindBetaconnectLocalhost(evt);
}
});
btnFindUs.setIcon(new javax.swing.ImageIcon(getClass().getResource("/flags/us.png"))); // NOI18N
btnFindUs.setText("P");
btnFindUs.setToolTipText("Connect to mtg.powersofwar.com (USA, use any username without registration)");
btnFindUs.setActionCommand("connectXmageus");
btnFindUs.setAlignmentY(0.0F);
btnFindUs.setMargin(new java.awt.Insets(2, 2, 2, 2));
btnFindUs.setName("connectXmageusBtn"); // NOI18N
btnFindUs.setPreferredSize(new java.awt.Dimension(23, 23));
btnFindUs.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
connectXmageus(evt);
}
});
btnFindOther.setText("Other servers...");
btnFindOther.setToolTipText("Choose server from full servers list");
btnFindOther.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
btnFindOther.setName("findServerBtn"); // NOI18N
btnFindOther.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
findPublicServerActionPerformed(evt);
}
});
javax.swing.GroupLayout panelFastLayout = new javax.swing.GroupLayout(panelFast);
panelFast.setLayout(panelFastLayout);
panelFastLayout.setHorizontalGroup(
panelFastLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelFastLayout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(btnFindMain, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnFindUs, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnFindBeta, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnFindLocal, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnFindOther, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
panelFastLayout.setVerticalGroup(
panelFastLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelFastLayout.createSequentialGroup()
.addGap(0, 0, 0)
.addGroup(panelFastLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btnFindMain, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnFindLocal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnFindUs, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnFindBeta, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnFindOther))
.addGap(0, 0, 0))
);
txtPort.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyTyped(java.awt.event.KeyEvent evt) {
ConnectDialog.this.keyTyped(evt);
}
});
lblPort.setLabelFor(txtPort);
lblPort.setText("Port:");
btnCheckStatus.setIcon(new javax.swing.ImageIcon(getClass().getResource("/flags/world.png"))); // NOI18N
btnCheckStatus.setText("Check online status");
btnCheckStatus.setToolTipText("Go to servers online statuses page");
btnCheckStatus.setAlignmentY(0.0F);
btnCheckStatus.setMargin(new java.awt.Insets(2, 2, 2, 2));
btnCheckStatus.setPreferredSize(new java.awt.Dimension(23, 23));
btnCheckStatus.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnCheckStatusActionPerformed(evt);
}
});
javax.swing.GroupLayout panelServerLayout = new javax.swing.GroupLayout(panelServer);
panelServer.setLayout(panelServerLayout);
panelServerLayout.setHorizontalGroup(
panelServerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelServerLayout.createSequentialGroup()
.addComponent(txtServer, javax.swing.GroupLayout.PREFERRED_SIZE, 212, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(lblPort)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(txtPort, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnCheckStatus, javax.swing.GroupLayout.DEFAULT_SIZE, 141, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
panelServerLayout.setVerticalGroup(
panelServerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelServerLayout.createSequentialGroup()
.addGap(0, 0, 0)
.addGroup(panelServerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(txtServer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(txtPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblPort)
.addComponent(btnCheckStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(29, 29, 29)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(lblPort)
.addComponent(lblServer)))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(lblFlag)))
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lblUserName)
.addComponent(lblPassword, javax.swing.GroupLayout.Alignment.TRAILING))))
.addGap(0, 0, 0)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(btnConnect, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(btnRegister, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btnForgotPassword, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 77, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(lblStatus, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(chkForceUpdateDB, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(jProxySettingsButton)
.addGap(0, 0, Short.MAX_VALUE))
.addComponent(chkAutoConnect, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(panelFlag, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(txtServer, javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(txtUserName, javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(txtPassword, javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(txtPort, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 11, Short.MAX_VALUE)
.addComponent(lblFastConnect)
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(lblUserName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(lblServer, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(lblFastConnect, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(lblPassword, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(lblFlag, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jProxySettingsButton)
.addGap(0, 0, Short.MAX_VALUE))
.addComponent(lblStatus, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(chkForceUpdateDB, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(chkAutoConnect, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(txtUserName)
.addComponent(txtPassword)
.addComponent(panelFlag, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(btnConnect, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(btnRegister, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btnForgotPassword, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 77, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(panelFast, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(panelServer, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnFind1, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnFind3, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnFind2, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGap(0, 0, 0)
.addComponent(btnFind)))
.addContainerGap())
.addComponent(filler2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lblServer)
.addComponent(txtServer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnFind))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(txtPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblPort)
.addComponent(btnFind1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnFind2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnFind3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblFastConnect))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(txtUserName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblUserName))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(txtPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblPassword))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(panelFlag, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblFlag, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(chkAutoConnect)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(chkForceUpdateDB)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jProxySettingsButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(lblStatus, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addGroup(layout.createSequentialGroup()
.addComponent(btnRegister, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnForgotPassword, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addComponent(btnConnect, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btnCancel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGap(23, 23, 23))
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(panelFast, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(lblFastConnect, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(panelServer, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(lblServer, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(txtUserName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblUserName, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(txtPassword)
.addComponent(lblPassword, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addComponent(filler2, javax.swing.GroupLayout.DEFAULT_SIZE, 53, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(panelFlag, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblFlag, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(chkAutoConnect)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(chkForceUpdateDB)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jProxySettingsButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(lblStatus, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addGroup(layout.createSequentialGroup()
.addComponent(btnRegister, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnForgotPassword, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addComponent(btnConnect, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btnCancel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGap(23, 23, 23))
);
lblFastConnect.getAccessibleContext().setAccessibleName("Fast connect to:");
pack();
}// </editor-fold>//GEN-END:initComponents
@ -456,7 +508,8 @@ public class ConnectDialog extends MageDialog {
connection.setPort(Integer.valueOf(this.txtPort.getText().trim()));
connection.setUsername(this.txtUserName.getText().trim());
connection.setPassword(this.txtPassword.getText().trim());
boolean redownloadDatabase = CardRepository.instance.findCard("Island") == null;
// force to redownload db
boolean redownloadDatabase = (ExpansionRepository.instance.getSetByCode("GRN") == null || CardRepository.instance.findCard("Island") == null);
connection.setForceDBComparison(this.chkForceUpdateDB.isSelected() || redownloadDatabase);
String allMAC = "";
try {
@ -676,8 +729,7 @@ public class ConnectDialog extends MageDialog {
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));
this.txtPassword.setText(MagePreferences.getPassword(serverAddress)); // TODO add your handling code here:
}//GEN-LAST:event_btnFind1findPublicServerActionPerformed
private void connectLocalhost(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFind2findPublicServerActionPerformed
@ -699,10 +751,33 @@ public class ConnectDialog extends MageDialog {
this.txtPassword.setText(MagePreferences.getPassword(serverAddress));
}
private void connectBeta(java.awt.event.ActionEvent evt) {
String serverAddress = "xmage.today";
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 btnFindBetaconnectLocalhost(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFindBetaconnectLocalhost
connectBeta(evt);
}//GEN-LAST:event_btnFindBetaconnectLocalhost
private void btnCheckStatusActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCheckStatusActionPerformed
if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
try {
Desktop.getDesktop().browse(new URI("http://xmageservers.online/"));
} catch (Exception e) {
//
}
}
}//GEN-LAST:event_btnCheckStatusActionPerformed
private void doFastFlagSearch() {
Choice choice = new ChoiceImpl(false);
@ -748,11 +823,13 @@ public class ConnectDialog extends MageDialog {
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnCancel;
private javax.swing.JButton btnCheckStatus;
private javax.swing.JButton btnConnect;
private javax.swing.JButton btnFind;
private javax.swing.JButton btnFind1;
private javax.swing.JButton btnFind2;
private javax.swing.JButton btnFind3;
private javax.swing.JButton btnFindBeta;
private javax.swing.JButton btnFindLocal;
private javax.swing.JButton btnFindMain;
private javax.swing.JButton btnFindOther;
private javax.swing.JButton btnFindUs;
private javax.swing.JButton btnFlagSearch;
private javax.swing.JButton btnForgotPassword;
private javax.swing.JButton btnRegister;
@ -760,6 +837,7 @@ public class ConnectDialog extends MageDialog {
private javax.swing.JCheckBox chkAutoConnect;
private javax.swing.JCheckBox chkForceUpdateDB;
private javax.swing.Box.Filler filler1;
private javax.swing.Box.Filler filler2;
private javax.swing.JButton jProxySettingsButton;
private javax.swing.JLabel lblFastConnect;
private javax.swing.JLabel lblFlag;
@ -768,7 +846,9 @@ public class ConnectDialog extends MageDialog {
private javax.swing.JLabel lblServer;
private javax.swing.JLabel lblStatus;
private javax.swing.JLabel lblUserName;
private javax.swing.JPanel panelFast;
private javax.swing.JPanel panelFlag;
private javax.swing.JPanel panelServer;
private javax.swing.JPasswordField txtPassword;
private javax.swing.JTextField txtPort;
private javax.swing.JTextField txtServer;

View file

@ -1,7 +1,7 @@
package mage.client.dialog;
import mage.cards.decks.importer.DeckImporterUtil;
import mage.cards.decks.importer.DeckImporter;
import mage.client.MageFrame;
import mage.client.SessionHandler;
import mage.players.PlayerType;
@ -119,9 +119,9 @@ public class JoinTableDialog extends MageDialog {
try {
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_PASSWORD_JOIN, txtPassword.getText());
if (isTournament) {
joined = session.joinTournamentTable(roomId, tableId, this.newPlayerPanel.getPlayerName(), PlayerType.HUMAN, 1, DeckImporterUtil.importDeck(this.newPlayerPanel.getDeckFile()), this.txtPassword.getText());
joined = session.joinTournamentTable(roomId, tableId, this.newPlayerPanel.getPlayerName(), PlayerType.HUMAN, 1, DeckImporter.importDeckFromFile(this.newPlayerPanel.getDeckFile()), this.txtPassword.getText());
} else {
joined = session.joinTable(roomId, tableId, this.newPlayerPanel.getPlayerName(), PlayerType.HUMAN, 1, DeckImporterUtil.importDeck(this.newPlayerPanel.getDeckFile()), this.txtPassword.getText());
joined = session.joinTable(roomId, tableId, this.newPlayerPanel.getPlayerName(), PlayerType.HUMAN, 1, DeckImporter.importDeckFromFile(this.newPlayerPanel.getDeckFile()), this.txtPassword.getText());
}
} catch (Exception ex) {

View file

@ -7,7 +7,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.swing.*;
import mage.cards.decks.importer.DeckImporterUtil;
import mage.cards.decks.importer.DeckImporter;
import mage.client.MageFrame;
import mage.client.SessionHandler;
import mage.client.components.MageComponents;
@ -425,7 +426,7 @@ public class NewTableDialog extends MageDialog {
table.getTableId(),
this.player1Panel.getPlayerName(),
PlayerType.HUMAN, 1,
DeckImporterUtil.importDeck(this.player1Panel.getDeckFile()),
DeckImporter.importDeckFromFile(this.player1Panel.getDeckFile()),
this.txtPassword.getText())) {
for (TablePlayerPanel player : players) {
if (player.getPlayerType() != PlayerType.HUMAN) {

View file

@ -18,7 +18,7 @@ import java.util.UUID;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import mage.cards.decks.Deck;
import mage.cards.decks.importer.DeckImporterUtil;
import mage.cards.decks.importer.DeckImporter;
import mage.cards.repository.ExpansionInfo;
import mage.cards.repository.ExpansionRepository;
import mage.client.MageFrame;
@ -557,7 +557,7 @@ public class NewTournamentDialog extends MageDialog {
if (!(cubeFromDeckFilename.isEmpty())) {
Deck cubeFromDeck = new Deck();
try {
cubeFromDeck = Deck.load(DeckImporterUtil.importDeck(cubeFromDeckFilename), true, true);
cubeFromDeck = Deck.load(DeckImporter.importDeckFromFile(cubeFromDeckFilename), true, true);
} catch (GameException e1) {
JOptionPane.showMessageDialog(MageFrame.getDesktop(), e1.getMessage(), "Error loading deck", JOptionPane.ERROR_MESSAGE);
}
@ -631,11 +631,11 @@ public class NewTournamentDialog extends MageDialog {
table.getTableId(),
this.player1Panel.getPlayerName(),
PlayerType.HUMAN, 1,
DeckImporterUtil.importDeck(this.player1Panel.getDeckFile()),
DeckImporter.importDeckFromFile(this.player1Panel.getDeckFile()),
tOptions.getPassword())) {
for (TournamentPlayerPanel player : players) {
if (player.getPlayerType().getSelectedItem() != PlayerType.HUMAN) {
if (!player.joinTournamentTable(roomId, table.getTableId(), DeckImporterUtil.importDeck(this.player1Panel.getDeckFile()))) {
if (!player.joinTournamentTable(roomId, table.getTableId(), DeckImporter.importDeckFromFile(this.player1Panel.getDeckFile()))) {
// error message must be send by sever
SessionHandler.removeTable(roomId, table.getTableId());
table = null;

View file

@ -20,7 +20,8 @@ import javax.swing.JPopupMenu;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.MenuSelectionManager;
import javax.swing.event.ChangeListener;
import mage.cards.decks.importer.DeckImporterUtil;
import mage.cards.decks.importer.DeckImporter;
import mage.client.MageFrame;
import mage.client.SessionHandler;
import mage.client.cards.BigCard;
@ -569,7 +570,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
}
private void btnCheatActionPerformed(java.awt.event.ActionEvent evt) {
SessionHandler.cheat(gameId, playerId, DeckImporterUtil.importDeck("cheat.dck"));
SessionHandler.cheat(gameId, playerId, DeckImporter.importDeckFromFile("cheat.dck"));
}
public boolean isSmallMode() {

View file

@ -8,7 +8,7 @@
package mage.client.table;
import mage.cards.decks.importer.DeckImporterUtil;
import mage.cards.decks.importer.DeckImporter;
import mage.client.SessionHandler;
import mage.client.util.Config;
import mage.client.util.Event;
@ -53,7 +53,7 @@ public class TablePlayerPanel extends javax.swing.JPanel {
public boolean joinTable(UUID roomId, UUID tableId) throws IOException, ClassNotFoundException {
if (this.cbPlayerType.getSelectedItem() != PlayerType.HUMAN) {
return SessionHandler.joinTable(roomId, tableId, this.newPlayerPanel.getPlayerName(), (PlayerType) this.cbPlayerType.getSelectedItem(), this.newPlayerPanel.getLevel(), DeckImporterUtil.importDeck(this.newPlayerPanel.getDeckFile()), "");
return SessionHandler.joinTable(roomId, tableId, this.newPlayerPanel.getPlayerName(), (PlayerType) this.cbPlayerType.getSelectedItem(), this.newPlayerPanel.getLevel(), DeckImporter.importDeckFromFile(this.newPlayerPanel.getDeckFile()), "");
}
return true;
}

View file

@ -1,6 +1,6 @@
package mage.client.table;
import mage.cards.decks.importer.DeckImporterUtil;
import mage.cards.decks.importer.DeckImporter;
import mage.client.MageFrame;
import mage.client.SessionHandler;
import mage.client.chat.ChatPanelBasic;
@ -1263,8 +1263,8 @@ public class TablesPanel extends javax.swing.JPanel {
options.setBannedUsers(IgnoreList.ignoreList(serverAddress));
table = SessionHandler.createTable(roomId, options);
SessionHandler.joinTable(roomId, table.getTableId(), "Human", PlayerType.HUMAN, 1, DeckImporterUtil.importDeck("test.dck"), "");
SessionHandler.joinTable(roomId, table.getTableId(), "Computer", PlayerType.COMPUTER_MAD, 5, DeckImporterUtil.importDeck("test.dck"), "");
SessionHandler.joinTable(roomId, table.getTableId(), "Human", PlayerType.HUMAN, 1, DeckImporter.importDeckFromFile("test.dck"), "");
SessionHandler.joinTable(roomId, table.getTableId(), "Computer", PlayerType.COMPUTER_MAD, 5, DeckImporter.importDeckFromFile("test.dck"), "");
SessionHandler.startMatch(roomId, table.getTableId());
} catch (HeadlessException ex) {
handleError(ex);

View file

@ -18,6 +18,8 @@ public class TablesUtil {
searchId = ((TablesTableModel) table.getModel()).findTableAndGameInfoByRow(row);
} else if (table.getModel() instanceof MatchesTableModel) {
searchId = ((MatchesTableModel) table.getModel()).findTableAndGameInfoByRow(row);
} else if (table.getModel() instanceof TournamentMatchesTableModel) {
searchId = ((TournamentMatchesTableModel) table.getModel()).findTableAndGameInfoByRow(row);
} else {
logger.error("Not supported tables model " + table.getModel().getClass().toString());
}
@ -31,6 +33,8 @@ public class TablesUtil {
row = ((TablesTableModel) tableModel).findRowByTableAndGameInfo(searchId);
} else if (tableModel instanceof MatchesTableModel) {
row = ((MatchesTableModel) tableModel).findRowByTableAndGameInfo(searchId);
} else if (tableModel instanceof TournamentMatchesTableModel) {
row = ((TournamentMatchesTableModel) tableModel).findRowByTableAndGameInfo(searchId);
} else {
logger.error("Not supported tables model " + tableModel.getClass().toString());
}

View file

@ -0,0 +1,116 @@
package mage.client.table;
import mage.view.RoundView;
import mage.view.TournamentGameView;
import mage.view.TournamentView;
import javax.swing.table.AbstractTableModel;
import java.util.ArrayList;
import java.util.List;
/**
* @author JayDi85
*/
public class TournamentMatchesTableModel extends AbstractTableModel {
public static final int ACTION_COLUMN = 4; // column the action is located
private final String[] columnNames = new String[]{"Round Number", "Players", "State", "Result", "Action"};
private TournamentGameView[] games = new TournamentGameView[0];
private boolean watchingAllowed;
public void loadData(TournamentView tournament) {
List<TournamentGameView> views = new ArrayList<>();
watchingAllowed = tournament.isWatchingAllowed();
for (RoundView round : tournament.getRounds()) {
for (TournamentGameView game : round.getGames()) {
views.add(game);
}
}
games = views.toArray(new TournamentGameView[0]);
this.fireTableDataChanged();
}
public String getTableAndGameInfo(int row) {
return this.games[row].getTableId().toString() + ";" + games[row].toString();
}
public String findTableAndGameInfoByRow(int row) {
if (row >= 0 && row < this.games.length) {
return getTableAndGameInfo(row);
} else {
return null;
}
}
public int findRowByTableAndGameInfo(String tableAndGame) {
for (int i = 0; i < this.games.length; i++) {
String rowID = this.games[i].getTableId().toString() + ";" + this.games[i].toString();
if (tableAndGame.equals(rowID)) {
return i;
}
}
return -1;
}
@Override
public int getRowCount() {
return games.length;
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public Object getValueAt(int arg0, int arg1) {
switch (arg1) {
case 0:
return Integer.toString(games[arg0].getRoundNum());
case 1:
return games[arg0].getPlayers();
case 2:
return games[arg0].getState();
case 3:
return games[arg0].getResult();
case 4:
// if (games[arg0].getState().equals("Finished")) {
// return "Replay";
// }
if (watchingAllowed && games[arg0].getState().startsWith("Dueling")) {
return "Watch";
}
return "";
case 5:
return games[arg0].getTableId().toString();
case 6:
return games[arg0].getMatchId().toString();
case 7:
return games[arg0].getGameId().toString();
}
return "";
}
@Override
public String getColumnName(int columnIndex) {
String colName = "";
if (columnIndex <= getColumnCount()) {
colName = columnNames[columnIndex];
}
return colName;
}
@Override
public Class getColumnClass(int columnIndex) {
return String.class;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return columnIndex == ACTION_COLUMN;
}
}

View file

@ -5,12 +5,16 @@ import mage.client.SessionHandler;
import mage.client.chat.ChatPanelBasic;
import mage.client.dialog.PreferencesDialog;
import mage.client.table.TablesButtonColumn;
import mage.client.table.TablesUtil;
import mage.client.table.TournamentMatchesTableModel;
import mage.client.util.Format;
import mage.client.util.GUISizeHelper;
import mage.client.util.gui.TableUtil;
import mage.client.util.gui.countryBox.CountryCellRenderer;
import mage.constants.PlayerAction;
import mage.view.*;
import mage.view.TournamentPlayerView;
import mage.view.TournamentView;
import mage.view.UserRequestMessage;
import org.apache.log4j.Logger;
import javax.swing.*;
@ -18,7 +22,6 @@ import javax.swing.table.AbstractTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@ -74,7 +77,11 @@ public class TournamentPanel extends javax.swing.JPanel {
Action action = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
int modelRow = Integer.valueOf(e.getActionCommand());
String searchID = e.getActionCommand();
int modelRow = TablesUtil.findTableRowFromSearchId(matchesModel, searchID);
if (modelRow == -1) {
return;
}
String state = (String) tableMatches.getValueAt(modelRow, tableMatches.convertColumnIndexToView(2));
String actionText = (String) tableMatches.getValueAt(modelRow, tableMatches.convertColumnIndexToView(TournamentMatchesTableModel.ACTION_COLUMN));
@ -132,7 +139,7 @@ public class TournamentPanel extends javax.swing.JPanel {
private void saveDividerLocations() {
// save panel sizes and divider locations.
Rectangle rec = MageFrame.getDesktop().getBounds();
String sb = Double.toString(rec.getWidth()) + 'x' + Double.toString(rec.getHeight());
String sb = Double.toString(rec.getWidth()) + 'x' + rec.getHeight();
PreferencesDialog.saveValue(PreferencesDialog.KEY_MAGE_PANEL_LAST_SIZE, sb);
PreferencesDialog.saveValue(PreferencesDialog.KEY_TOURNAMENT_DIVIDER_LOCATION_1, Integer.toString(this.jSplitPane1.getDividerLocation()));
PreferencesDialog.saveValue(PreferencesDialog.KEY_TOURNAMENT_DIVIDER_LOCATION_2, Integer.toString(this.jSplitPane2.getDividerLocation()));
@ -142,7 +149,7 @@ public class TournamentPanel extends javax.swing.JPanel {
Rectangle rec = MageFrame.getDesktop().getBounds();
if (rec != null) {
String size = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_MAGE_PANEL_LAST_SIZE, null);
String sb = Double.toString(rec.getWidth()) + 'x' + Double.toString(rec.getHeight());
String sb = Double.toString(rec.getWidth()) + 'x' + rec.getHeight();
// use divider positions only if screen size is the same as it was the time the settings were saved
if (size != null && size.equals(sb)) {
String location = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_TOURNAMENT_DIVIDER_LOCATION_1, null);
@ -585,88 +592,6 @@ class TournamentPlayersTableModel extends AbstractTableModel {
}
class TournamentMatchesTableModel extends AbstractTableModel {
public static final int ACTION_COLUMN = 4; // column the action is located
private final String[] columnNames = new String[]{"Round Number", "Players", "State", "Result", "Action"};
private TournamentGameView[] games = new TournamentGameView[0];
private boolean watchingAllowed;
public void loadData(TournamentView tournament) {
List<TournamentGameView> views = new ArrayList<>();
watchingAllowed = tournament.isWatchingAllowed();
for (RoundView round : tournament.getRounds()) {
for (TournamentGameView game : round.getGames()) {
views.add(game);
}
}
games = views.toArray(new TournamentGameView[0]);
this.fireTableDataChanged();
}
@Override
public int getRowCount() {
return games.length;
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public Object getValueAt(int arg0, int arg1) {
switch (arg1) {
case 0:
return Integer.toString(games[arg0].getRoundNum());
case 1:
return games[arg0].getPlayers();
case 2:
return games[arg0].getState();
case 3:
return games[arg0].getResult();
case 4:
// if (games[arg0].getState().equals("Finished")) {
// return "Replay";
// }
if (watchingAllowed && games[arg0].getState().startsWith("Dueling")) {
return "Watch";
}
return "";
case 5:
return games[arg0].getTableId().toString();
case 6:
return games[arg0].getMatchId().toString();
case 7:
return games[arg0].getGameId().toString();
}
return "";
}
@Override
public String getColumnName(int columnIndex) {
String colName = "";
if (columnIndex <= getColumnCount()) {
colName = columnNames[columnIndex];
}
return colName;
}
@Override
public Class getColumnClass(int columnIndex) {
return String.class;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return columnIndex == ACTION_COLUMN;
}
}
class UpdateTournamentTask extends SwingWorker<Void, TournamentView> {
@ -709,4 +634,4 @@ class UpdateTournamentTask extends SwingWorker<Void, TournamentView> {
}
}
}
}

View file

@ -1,17 +1,15 @@
package mage.client.util.gui;
import mage.choices.ChoiceImpl;
import mage.client.dialog.CheckBoxList;
import mage.client.dialog.PickCheckBoxDialog;
import mage.client.dialog.PickChoiceDialog;
import mage.client.dialog.CheckBoxList;
import javax.swing.*;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author JayDi85
*/
public class FastSearchUtil {
@ -19,27 +17,28 @@ public class FastSearchUtil {
public static String DEFAULT_EXPANSION_SEARCH_MESSAGE = "Select set or expansion";
public static String DEFAULT_EXPANSION_TOOLTIP_MESSAGE = "Fast search set or expansion";
public static void showFastSearchForStringComboBox(JComboBox combo, String chooseMessage){
public static void showFastSearchForStringComboBox(JComboBox combo, String chooseMessage) {
showFastSearchForStringComboBox(combo, chooseMessage, 300, 500);
}
/**
* Show fast choice modal dialog with incremental searching for any string combobox components
* @param combo combobox control with default data model
*
* @param combo combobox control with default data model
* @param chooseMessage caption message for dialog
*/
public static void showFastSearchForStringComboBox(JComboBox combo, String chooseMessage, int windowWidth, int windowHeight){
public static void showFastSearchForStringComboBox(JComboBox combo, String chooseMessage, int windowWidth, int windowHeight) {
// fast search/choice dialog for string combobox
mage.choices.Choice choice = new ChoiceImpl(false);
// collect data from expansion combobox (String)
DefaultComboBoxModel comboModel = (DefaultComboBoxModel)combo.getModel();
DefaultComboBoxModel comboModel = (DefaultComboBoxModel) combo.getModel();
Map<String, String> choiceItems = new HashMap<>(comboModel.getSize());
Map<String, Integer> choiceSorting = new HashMap<>(comboModel.getSize());
String item;
for(int i = 0; i < comboModel.getSize(); i++){
for (int i = 0; i < comboModel.getSize(); i++) {
item = comboModel.getElementAt(i).toString();
choiceItems.put(item, item);
choiceSorting.put(item, i); // need so sorting
@ -57,35 +56,36 @@ public class FastSearchUtil {
PickChoiceDialog dlg = new PickChoiceDialog();
dlg.setWindowSize(windowWidth, windowHeight);
dlg.showDialog(choice, needSelectValue);
if(choice.isChosen()){
if (choice.isChosen()) {
item = choice.getChoiceKey();
// compatible select for object's models (use setSelectedIndex instead setSelectedObject)
for(int i = 0; i < comboModel.getSize(); i++){
if(comboModel.getElementAt(i).toString().equals(item)){
for (int i = 0; i < comboModel.getSize(); i++) {
if (comboModel.getElementAt(i).toString().equals(item)) {
combo.setSelectedIndex(i);
}
}
}
}
/**
* Show fast choice modal dialog with incremental searching for any string CheckBoxList components
* @param combo CheckBoxList control with default data model
*
* @param combo CheckBoxList control with default data model
* @param chooseMessage caption message for dialog
*/
public static void showFastSearchForStringComboBox(CheckBoxList combo, String chooseMessage){
public static void showFastSearchForStringComboBox(CheckBoxList combo, String chooseMessage) {
// fast search/choice dialog for string combobox
mage.choices.Choice choice = new ChoiceImpl(false);
// collect data from expansion combobox (String)
DefaultListModel comboModel = (DefaultListModel)combo.getModel();
DefaultListModel comboModel = (DefaultListModel) combo.getModel();
Map<String, String> choiceItems = new HashMap<>(comboModel.getSize());
Map<String, Integer> choiceSorting = new HashMap<>(comboModel.getSize());
String item;
for(int i = 0; i < comboModel.size(); i++){
for (int i = 0; i < comboModel.size(); i++) {
item = comboModel.getElementAt(i).toString();
choiceItems.put(item, item);
choiceSorting.put(item, i); // need so sorting
@ -96,21 +96,22 @@ public class FastSearchUtil {
choice.setMessage(chooseMessage);
// current selection value restore
String needSelectValue;
needSelectValue = comboModel.firstElement().toString();
String needSelectValue = null;
if (comboModel.size() > 0) {
needSelectValue = comboModel.firstElement().toString();
}
// ask for new value
PickCheckBoxDialog dlg = new PickCheckBoxDialog(combo);
PickCheckBoxDialog dlg = new PickCheckBoxDialog(combo);
dlg.setWindowSize(300, 500);
dlg.showDialog(choice, needSelectValue);
if(choice.isChosen()){
if (choice.isChosen()) {
item = choice.getChoiceKey();
// compatible select for object's models (use setSelectedIndex instead setSelectedObject)
for(int i = 0; i < comboModel.getSize(); i++){
if(comboModel.getElementAt(i).toString().equals(item)){
for (int i = 0; i < comboModel.getSize(); i++) {
if (comboModel.getElementAt(i).toString().equals(item)) {
combo.setSelectedIndex(i);
}
}

View file

@ -1,17 +1,13 @@
package mage.client.util.sets;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import mage.cards.repository.ExpansionInfo;
import mage.cards.repository.ExpansionRepository;
import mage.cards.repository.RepositoryEvent;
import mage.constants.SetType;
import static mage.constants.SetType.EXPANSION;
import static mage.constants.SetType.SUPPLEMENTAL;
import mage.deck.Standard;
import mage.game.events.Listener;
import java.util.*;
/**
* Utility class for constructed formats (expansions and other editions).
@ -26,11 +22,36 @@ public final class ConstructedFormats {
public static final String FRONTIER = "- Frontier";
public static final String MODERN = "- Modern";
public static final String VINTAGE_LEGACY = "- Vintage / Legacy";
public static final String JOKE = "- Joke Sets";
public static final String CUSTOM = "- Custom";
public static final Standard STANDARD_CARDS = new Standard();
// Attention -Month is 0 Based so Feb = 1 for example. //
private static final Date extendedDate = new GregorianCalendar(2009, 7, 20).getTime();
private static final Date frontierDate = new GregorianCalendar(2014, 6, 17).getTime();
private static final Date modernDate = new GregorianCalendar(2003, 6, 20).getTime();
// for all sets just return empty list
private static final List<String> all = new ArrayList<>();
private static final Map<String, List<String>> underlyingSetCodesPerFormat = new HashMap<>();
private static final List<String> formats = new ArrayList<>();
private static final Listener<RepositoryEvent> setsDbListener;
static {
buildLists();
// auto-update sets list on changes
setsDbListener = new Listener<RepositoryEvent>() {
@Override
public void event(RepositoryEvent event) {
if (event.getEventType().equals(RepositoryEvent.RepositoryEventType.DB_UPDATED)) {
buildLists();
}
}
};
ExpansionRepository.instance.subscribe(setsDbListener);
}
private ConstructedFormats() {
}
@ -57,12 +78,13 @@ public final class ConstructedFormats {
}
}
private static void buildLists() {
public static void buildLists() {
underlyingSetCodesPerFormat.put(STANDARD, new ArrayList<>());
underlyingSetCodesPerFormat.put(EXTENDED, new ArrayList<>());
underlyingSetCodesPerFormat.put(FRONTIER, new ArrayList<>());
underlyingSetCodesPerFormat.put(MODERN, new ArrayList<>());
underlyingSetCodesPerFormat.put(VINTAGE_LEGACY, new ArrayList<>());
underlyingSetCodesPerFormat.put(JOKE, new ArrayList<>());
underlyingSetCodesPerFormat.put(CUSTOM, new ArrayList<>());
final Map<String, ExpansionInfo> expansionInfo = new HashMap<>();
formats.clear(); // prevent NPE on sorting if this is not the first try
@ -85,6 +107,10 @@ public final class ConstructedFormats {
underlyingSetCodesPerFormat.get(CUSTOM).add(set.getCode());
continue;
}
if (set.getType() == SetType.JOKESET) {
underlyingSetCodesPerFormat.get(JOKE).add(set.getCode());
continue;
}
underlyingSetCodesPerFormat.get(VINTAGE_LEGACY).add(set.getCode());
if (set.getType() == SetType.CORE || set.getType() == SetType.EXPANSION || set.getType() == SetType.SUPPLEMENTAL_STANDARD_LEGAL) {
if (STANDARD_CARDS.getSetCodes().contains(set.getCode())) {
@ -211,12 +237,12 @@ public final class ConstructedFormats {
});
if (!formats.isEmpty()) {
formats.add(0, CUSTOM);
formats.add(0, JOKE);
formats.add(0, VINTAGE_LEGACY);
formats.add(0, MODERN);
formats.add(0, EXTENDED);
formats.add(0, FRONTIER);
formats.add(0, EXTENDED);
formats.add(0, STANDARD);
}
formats.add(0, ALL);
}
@ -224,15 +250,4 @@ public final class ConstructedFormats {
private static String getBlockDisplayName(String blockName) {
return "* " + blockName + " Block";
}
// Attention -Month is 0 Based so Feb = 1 for example.
private static final Date extendedDate = new GregorianCalendar(2009, 7, 20).getTime();
private static final Date frontierDate = new GregorianCalendar(2014, 6, 17).getTime();
private static final Date modernDate = new GregorianCalendar(2003, 6, 20).getTime();
// for all sets just return empty list
private static final List<String> all = new ArrayList<>();
static {
buildLists();
}
}

View file

@ -1,4 +1,3 @@
package org.mage.plugins.card.dl.sources;
import org.apache.log4j.Logger;
@ -59,7 +58,7 @@ public enum AltMtgOnlTokensImageSource implements CardImageSource {
}
@Override
public CardImageUrls generateURL(CardDownloadData card) throws Exception {
public CardImageUrls generateCardUrl(CardDownloadData card) throws Exception {
return null;
}

View file

@ -6,11 +6,11 @@ import org.mage.plugins.card.images.CardDownloadData;
import java.util.ArrayList;
/**
* @author North
* @author North, JayDi85
*/
public interface CardImageSource {
CardImageUrls generateURL(CardDownloadData card) throws Exception;
CardImageUrls generateCardUrl(CardDownloadData card) throws Exception;
CardImageUrls generateTokenUrl(CardDownloadData card) throws Exception;
@ -53,7 +53,11 @@ public interface CardImageSource {
return true;
}
default boolean isImageProvided(String setCode, String cardName) {
default boolean isCardImageProvided(String setCode, String cardName) {
return false;
}
default boolean isTokenImageProvided(String setCode, String cardName, Integer tokenNumber) {
return false;
}
}

View file

@ -1,6 +1,10 @@
package org.mage.plugins.card.dl.sources;
import java.awt.Toolkit;
import mage.cards.Sets;
import org.mage.plugins.card.images.CardDownloadData;
import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.io.IOException;
@ -10,12 +14,8 @@ 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 {
@ -74,7 +74,7 @@ public enum CopyPasteImageSource implements CardImageSource {
}
@Override
public CardImageUrls generateURL(CardDownloadData card) throws Exception {
public CardImageUrls generateCardUrl(CardDownloadData card) throws Exception {
if (singleLinks == null) {
setupLinks();
}
@ -198,7 +198,7 @@ public enum CopyPasteImageSource implements CardImageSource {
@Override
public CardImageUrls generateTokenUrl(CardDownloadData card) throws IOException {
try {
return generateURL(card);
return generateCardUrl(card);
} catch (Exception ex) {
}
return null;
@ -239,7 +239,7 @@ public enum CopyPasteImageSource implements CardImageSource {
}
@Override
public boolean isImageProvided(String setCode, String cardName) {
public boolean isCardImageProvided(String setCode, String cardName) {
missingCards.add(setCode + "/" + cardName);
if (singleLinks != null) {
@ -248,6 +248,11 @@ public enum CopyPasteImageSource implements CardImageSource {
return false;
}
@Override
public boolean isTokenImageProvided(String setCode, String cardName, Integer tokenNumber) {
return false;
}
@Override
public boolean isSetSupportedComplete(String setCode) {
return false;

View file

@ -1,6 +1,8 @@
package org.mage.plugins.card.dl.sources;
import org.apache.log4j.Logger;
import org.mage.plugins.card.images.CardDownloadData;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
@ -9,9 +11,6 @@ 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
*/
@ -48,7 +47,7 @@ public enum GrabbagImageSource implements CardImageSource {
}
@Override
public CardImageUrls generateURL(CardDownloadData card) throws Exception {
public CardImageUrls generateCardUrl(CardDownloadData card) throws Exception {
if (singleLinks == null) {
setupLinks();
}
@ -450,7 +449,7 @@ public enum GrabbagImageSource implements CardImageSource {
@Override
public CardImageUrls generateTokenUrl(CardDownloadData card) throws IOException {
try {
return generateURL(card);
return generateCardUrl(card);
} catch (Exception ex) {
java.util.logging.Logger.getLogger(GrabbagImageSource.class.getName()).log(Level.SEVERE, null, ex);
}
@ -501,7 +500,7 @@ public enum GrabbagImageSource implements CardImageSource {
}
@Override
public boolean isImageProvided(String setCode, String cardName) {
public boolean isCardImageProvided(String setCode, String cardName) {
if (singleLinks == null) {
setupLinks();
}

View file

@ -1,16 +1,10 @@
package org.mage.plugins.card.dl.sources;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.mage.plugins.card.images.CardDownloadData;
import java.net.URI;
import java.util.*;
/**
* @author Pete Rossi
*/
@ -234,7 +228,7 @@ public enum MagidexImageSource implements CardImageSource {
}
@Override
public CardImageUrls generateURL(CardDownloadData card) throws Exception {
public CardImageUrls generateCardUrl(CardDownloadData card) throws Exception {
String cardDownloadName = card.getDownloadName().toLowerCase(Locale.ENGLISH);
String cardSet = card.getSet();

View file

@ -1,10 +1,9 @@
package org.mage.plugins.card.dl.sources;
import java.util.Locale;
import org.mage.plugins.card.images.CardDownloadData;
import java.util.Locale;
/**
* Site was shutdown by wizards Feb. 2015
*
@ -30,7 +29,7 @@ public enum MtgImageSource implements CardImageSource {
}
@Override
public CardImageUrls generateURL(CardDownloadData card) throws Exception {
public CardImageUrls generateCardUrl(CardDownloadData card) throws Exception {
String collectorId = card.getCollectorId();
String cardSet = card.getSet();
if (collectorId == null || cardSet == null) {

View file

@ -1,12 +1,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;
import java.io.IOException;
import java.util.HashMap;
/**
* @author spjspj
*/
@ -59,7 +58,7 @@ public enum MtgOnlTokensImageSource implements CardImageSource {
}
@Override
public CardImageUrls generateURL(CardDownloadData card) throws Exception {
public CardImageUrls generateCardUrl(CardDownloadData card) throws Exception {
return null;
}
@ -352,8 +351,12 @@ public enum MtgOnlTokensImageSource implements CardImageSource {
}
@Override
public boolean isImageProvided(String setCode, String cardName) {
return true;
public boolean isCardImageProvided(String setCode, String cardName) {
return false;
}
@Override
public boolean isTokenImageProvided(String setCode, String cardName, Integer tokenNumber) {
return true;
}
}

View file

@ -1,22 +1,5 @@
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.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.prefs.Preferences;
import mage.client.MageFrame;
import mage.remote.Connection;
import mage.remote.Connection.ProxyType;
@ -26,6 +9,13 @@ import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.mage.plugins.card.images.CardDownloadData;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
import java.util.*;
import java.util.prefs.Preferences;
/**
* @author LevelX2
*/
@ -330,7 +320,7 @@ public enum MythicspoilerComSource implements CardImageSource {
}
private Map<String, String> getSetLinksFromPage(String cardSet, Set<String> aliasesStart, Preferences prefs,
ProxyType proxyType, String baseUrl, String pageUrl) throws IOException {
ProxyType proxyType, String baseUrl, String pageUrl) throws IOException {
Map<String, String> pageLinks = new HashMap<>();
String urlDocument;
@ -392,7 +382,7 @@ public enum MythicspoilerComSource implements CardImageSource {
}
@Override
public CardImageUrls generateURL(CardDownloadData card) throws Exception {
public CardImageUrls generateCardUrl(CardDownloadData card) throws Exception {
String collectorId = card.getCollectorId();
String cardSet = card.getSet();
if (collectorId == null || cardSet == null) {

View file

@ -3,20 +3,23 @@ package org.mage.plugins.card.dl.sources;
import mage.client.util.CardLanguage;
import org.mage.plugins.card.images.CardDownloadData;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
/**
* @author Quercitron, JayDi85
* @author JayDi85
*/
public enum ScryfallImageSource implements CardImageSource {
instance;
private final Set<String> supportedSets;
private final Map<CardLanguage, String> languageAliases;
private CardLanguage currentLanguage = CardLanguage.ENGLISH; // working language
ScryfallImageSource() {
// LANGUAGES
// https://scryfall.com/docs/api/languages
languageAliases = new HashMap<>();
languageAliases.put(CardLanguage.ENGLISH, "en");
@ -30,225 +33,9 @@ public enum ScryfallImageSource implements CardImageSource {
languageAliases.put(CardLanguage.RUSSIAN, "ru");
languageAliases.put(CardLanguage.CHINES_SIMPLE, "zhs");
languageAliases.put(CardLanguage.CHINES_TRADITION, "zht");
supportedSets = new LinkedHashSet<>();
// supportedSets.add("PTC"); //
supportedSets.add("LEA");
supportedSets.add("LEB");
supportedSets.add("2ED");
supportedSets.add("ARN");
supportedSets.add("ATQ");
supportedSets.add("3ED");
supportedSets.add("LEG");
supportedSets.add("DRK");
supportedSets.add("FEM");
supportedSets.add("4ED");
supportedSets.add("ICE");
supportedSets.add("CHR");
supportedSets.add("HML");
supportedSets.add("ALL");
supportedSets.add("MIR");
supportedSets.add("VIS");
supportedSets.add("5ED");
supportedSets.add("POR");
supportedSets.add("WTH");
supportedSets.add("TMP");
supportedSets.add("STH");
supportedSets.add("EXO");
supportedSets.add("P02");
supportedSets.add("UGL");
supportedSets.add("USG");
supportedSets.add("DD3DVD");
supportedSets.add("DD3EVG");
supportedSets.add("DD3GVL");
supportedSets.add("DD3JVC");
supportedSets.add("ULG");
supportedSets.add("6ED");
supportedSets.add("UDS");
supportedSets.add("PTK");
supportedSets.add("S99");
supportedSets.add("MMQ");
// supportedSets.add("BRB");Battle Royale Box Set
supportedSets.add("NEM");
supportedSets.add("S00");
supportedSets.add("PCY");
supportedSets.add("INV");
// supportedSets.add("BTD"); // Beatdown Boxset
supportedSets.add("PLS");
supportedSets.add("7ED");
supportedSets.add("APC");
supportedSets.add("ODY");
// supportedSets.add("DKM"); // Deckmasters 2001
supportedSets.add("TOR");
supportedSets.add("JUD");
supportedSets.add("ONS");
supportedSets.add("LGN");
supportedSets.add("SCG");
supportedSets.add("8ED");
supportedSets.add("MRD");
supportedSets.add("DST");
supportedSets.add("5DN");
supportedSets.add("CHK");
supportedSets.add("UNH");
supportedSets.add("BOK");
supportedSets.add("SOK");
supportedSets.add("9ED");
supportedSets.add("RAV");
supportedSets.add("GPT");
supportedSets.add("DIS");
supportedSets.add("CSP");
supportedSets.add("TSP");
supportedSets.add("TSB");
supportedSets.add("PLC");
supportedSets.add("FUT");
supportedSets.add("10E");
supportedSets.add("MED");
supportedSets.add("LRW");
supportedSets.add("EVG");
supportedSets.add("MOR");
supportedSets.add("SHM");
supportedSets.add("EVE");
supportedSets.add("DRB");
supportedSets.add("ME2");
supportedSets.add("ALA");
supportedSets.add("DD2");
supportedSets.add("CON");
supportedSets.add("DDC");
supportedSets.add("ARB");
supportedSets.add("M10");
// supportedSets.add("TD0"); // Magic Online Deck Series
supportedSets.add("V09");
supportedSets.add("HOP");
supportedSets.add("ME3");
supportedSets.add("ZEN");
supportedSets.add("DDD");
supportedSets.add("H09");
supportedSets.add("WWK");
supportedSets.add("DDE");
supportedSets.add("ROE");
// duels of the planewalkers:
supportedSets.add("DPA");
supportedSets.add("DPAP");
//
supportedSets.add("ARC");
supportedSets.add("M11");
supportedSets.add("V10");
supportedSets.add("DDF");
supportedSets.add("SOM");
// supportedSets.add("TD0"); // Commander Theme Decks
supportedSets.add("PD2");
supportedSets.add("ME4");
supportedSets.add("MBS");
supportedSets.add("DDG");
supportedSets.add("NPH");
supportedSets.add("CMD");
supportedSets.add("M12");
supportedSets.add("V11");
supportedSets.add("DDH");
supportedSets.add("ISD");
supportedSets.add("PD3");
supportedSets.add("DKA");
supportedSets.add("DDI");
supportedSets.add("AVR");
supportedSets.add("PC2");
supportedSets.add("M13");
supportedSets.add("V12");
supportedSets.add("DDJ");
supportedSets.add("RTR");
supportedSets.add("CM1");
// supportedSets.add("TD2"); // Duel Decks: Mirrodin Pure vs. New Phyrexia
supportedSets.add("GTC");
supportedSets.add("DDK");
supportedSets.add("DGM");
supportedSets.add("MMA");
supportedSets.add("M14");
supportedSets.add("V13");
supportedSets.add("DDL");
supportedSets.add("THS");
supportedSets.add("C13");
supportedSets.add("BNG");
supportedSets.add("DDM");
supportedSets.add("JOU");
// supportedSets.add("MD1"); // Modern Event Deck
supportedSets.add("CNS");
supportedSets.add("VMA");
supportedSets.add("M15");
supportedSets.add("V14");
supportedSets.add("DDN");
supportedSets.add("KTK");
supportedSets.add("C14");
// supportedSets.add("DD3"); // Duel Decks Anthology
supportedSets.add("FRF");
supportedSets.add("DDO");
supportedSets.add("DTK");
supportedSets.add("TPR");
supportedSets.add("MM2");
supportedSets.add("ORI");
supportedSets.add("V15");
supportedSets.add("DDP");
supportedSets.add("BFZ");
supportedSets.add("EXP");
supportedSets.add("C15");
// supportedSets.add("PZ1"); // Legendary Cube
supportedSets.add("OGW");
supportedSets.add("DDQ");
supportedSets.add("W16");
supportedSets.add("SOI");
supportedSets.add("EMA");
supportedSets.add("EMN");
supportedSets.add("V16");
supportedSets.add("CN2");
supportedSets.add("DDR");
supportedSets.add("KLD");
supportedSets.add("MPS");
// supportedSets.add("PZ2");
supportedSets.add("C16");
supportedSets.add("PCA");
supportedSets.add("AER");
supportedSets.add("MM3");
supportedSets.add("DDS");
supportedSets.add("W17");
supportedSets.add("AKH");
supportedSets.add("CMA");
supportedSets.add("E01");
supportedSets.add("HOU");
supportedSets.add("C17");
supportedSets.add("XLN");
supportedSets.add("DDT");
supportedSets.add("IMA");
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("C18");
supportedSets.add("CM2");
supportedSets.add("M19");
supportedSets.add("GS1");
supportedSets.add("GRN");
supportedSets.add("GK1");
supportedSets.add("GNT");
supportedSets.add("UMA");
supportedSets.add("PUMA");
supportedSets.add("RNA");
//
supportedSets.add("EURO");
supportedSets.add("GPX");
supportedSets.add("ATH");
supportedSets.add("GRC");
supportedSets.add("ANA");
}
@Override
public CardImageUrls generateURL(CardDownloadData card) throws Exception {
String preferredCode = this.getCurrentLanguage().getCode();
private CardImageUrls innerGenerateURL(CardDownloadData card, boolean isToken) {
String defaultCode = CardLanguage.ENGLISH.getCode();
String localizedCode = languageAliases.getOrDefault(this.getCurrentLanguage(), defaultCode);
// loc example: https://api.scryfall.com/cards/xln/121/ru?format=image
@ -259,22 +46,20 @@ public enum ScryfallImageSource implements CardImageSource {
String baseUrl = null;
String alternativeUrl = null;
// TOKENS TRY
// tokens support only direct links
if (baseUrl == null && isToken) {
baseUrl = ScryfallImageSupportTokens.findTokenLink(card.getSet(), card.getName(), card.getType());
alternativeUrl = null;
}
// CARDS TRY
// direct links to images (non localization)
if (baseUrl == null) {
// set/card/number
String linkCode1 = card.getSet() + "/" + card.getName() + "/" + card.getCollectorId();
if (directDownloadLinks.containsKey(linkCode1)) {
baseUrl = directDownloadLinks.get(linkCode1);
alternativeUrl = null;
}
// set/card
String linkCode2 = card.getSet() + "/" + card.getName();
if (directDownloadLinks.containsKey(linkCode2)) {
baseUrl = directDownloadLinks.get(linkCode2);
alternativeUrl = null;
}
baseUrl = ScryfallImageSupportCards.findDirectDownloadLink(card.getSet(), card.getName(), card.getCollectorId());
alternativeUrl = null;
}
// special card number like "103a" and "U123" already compatible
@ -285,9 +70,9 @@ public enum ScryfallImageSource implements CardImageSource {
// fix for Ultimate Box Topper (PUMA) -- need to use API
// ignored and go to API call at the end
} else {
baseUrl = "https://img.scryfall.com/cards/large/" + localizedCode + "/" + formatSetName(card.getSet()) + "/"
baseUrl = "https://img.scryfall.com/cards/large/" + localizedCode + "/" + formatSetName(card.getSet(), isToken) + "/"
+ card.getCollectorId() + ".jpg";
alternativeUrl = "https://img.scryfall.com/cards/large/" + defaultCode + "/" + formatSetName(card.getSet()) + "/"
alternativeUrl = "https://img.scryfall.com/cards/large/" + defaultCode + "/" + formatSetName(card.getSet(), isToken) + "/"
+ card.getCollectorId() + ".jpg";
}
}
@ -295,27 +80,33 @@ public enum ScryfallImageSource implements CardImageSource {
// 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 (baseUrl == null && card.isTwoFacedCard()) {
baseUrl = "https://img.scryfall.com/cards/large/" + localizedCode + "/" + formatSetName(card.getSet()) + "/"
baseUrl = "https://img.scryfall.com/cards/large/" + localizedCode + "/" + formatSetName(card.getSet(), isToken) + "/"
+ card.getCollectorId() + (card.isSecondSide() ? "b" : "a") + ".jpg";
alternativeUrl = "https://img.scryfall.com/cards/large/" + defaultCode + "/" + formatSetName(card.getSet()) + "/"
alternativeUrl = "https://img.scryfall.com/cards/large/" + defaultCode + "/" + formatSetName(card.getSet(), isToken) + "/"
+ card.getCollectorId() + (card.isSecondSide() ? "b" : "a") + ".jpg";
}
// basic cards by api call (redirect to img link)
// example: https://api.scryfall.com/cards/xln/121/en?format=image
if (baseUrl == null) {
baseUrl = "https://api.scryfall.com/cards/" + formatSetName(card.getSet()) + "/"
baseUrl = "https://api.scryfall.com/cards/" + formatSetName(card.getSet(), isToken) + "/"
+ card.getCollectorId() + "/" + localizedCode + "?format=image";
alternativeUrl = "https://api.scryfall.com/cards/" + formatSetName(card.getSet()) + "/"
alternativeUrl = "https://api.scryfall.com/cards/" + formatSetName(card.getSet(), isToken) + "/"
+ card.getCollectorId() + "/" + defaultCode + "?format=image";
}
return new CardImageUrls(baseUrl, alternativeUrl);
}
@Override
public CardImageUrls generateCardUrl(CardDownloadData card) throws Exception {
return innerGenerateURL(card, false);
}
@Override
public CardImageUrls generateTokenUrl(CardDownloadData card) throws Exception {
return null;
return innerGenerateURL(card, true);
}
@Override
@ -345,7 +136,7 @@ public enum ScryfallImageSource implements CardImageSource {
@Override
public boolean isTokenSource() {
return false;
return true;
}
@Override
@ -368,132 +159,41 @@ public enum ScryfallImageSource implements CardImageSource {
}
private String formatSetName(String setName) {
if (setNameReplacement.containsKey(setName)) {
setName = setNameReplacement.get(setName);
private String formatSetName(String setName, boolean isToken) {
if (isToken) {
// token uses direct link download, not set
return setName.toLowerCase(Locale.ENGLISH);
} else {
return ScryfallImageSupportCards.findScryfallSetCode(setName);
}
return setName.toLowerCase(Locale.ENGLISH);
}
private static final Map<String, String> setNameReplacement = new HashMap<String, String>() {
{
put("DD3GVL", "gvl");
put("DD3JVC", "jvc");
put("DD3DVD", "dvd");
put("DD3EVG", "evg");
put("MPS-AKH", "mp2");
put("MBP", "pmei");
put("WMCQ", "pwcq");
put("EURO", "pelp");
put("GPX", "pgpx");
put("MED", "me1");
}
};
private static final Map<String, String> directDownloadLinks = new HashMap<String, String>() {
{
// direct links to download images for special cards
// Duels of the Planeswalkers Promos -- xmage uses one set (DPAP), but scryfall store it by years
// 2009 - https://scryfall.com/sets/pdtp
put("DPAP/Garruk Wildspeaker", "https://img.scryfall.com/cards/large/en/pdtp/1.jpg");
// 2010 - https://scryfall.com/sets/pdp10
put("DPAP/Liliana Vess", "https://img.scryfall.com/cards/large/en/pdp10/1.jpg");
put("DPAP/Nissa Revane", "https://img.scryfall.com/cards/large/en/pdp10/2.jpg");
// 2011 - https://scryfall.com/sets/pdp11
put("DPAP/Frost Titan", "https://img.scryfall.com/cards/large/en/pdp11/1.jpg");
put("DPAP/Grave Titan", "https://img.scryfall.com/cards/large/en/pdp11/2.jpg");
put("DPAP/Inferno Titan", "https://img.scryfall.com/cards/large/en/pdp11/3.jpg");
// 2012 - https://scryfall.com/sets/pdp12
put("DPAP/Primordial Hydra", "https://img.scryfall.com/cards/large/en/pdp12/1.jpg");
put("DPAP/Serra Avatar", "https://img.scryfall.com/cards/large/en/pdp12/2.jpg");
put("DPAP/Vampire Nocturnus", "https://img.scryfall.com/cards/large/en/pdp12/3.jpg");
// 2013 - https://scryfall.com/sets/pdp13
put("DPAP/Bonescythe Sliver", "https://img.scryfall.com/cards/large/en/pdp13/1.jpg");
put("DPAP/Ogre Battledriver", "https://img.scryfall.com/cards/large/en/pdp13/2.jpg");
put("DPAP/Scavenging Ooze", "https://img.scryfall.com/cards/large/en/pdp13/3.jpg");
// 2014 - https://scryfall.com/sets/pdp14
put("DPAP/Soul of Ravnica", "https://img.scryfall.com/cards/large/en/pdp14/1.jpg");
put("DPAP/Soul of Zendikar", "https://img.scryfall.com/cards/large/en/pdp14/2.jpg");
// Gateway Promos -- xmage uses one set (GRC), but scryfall store it by years
// 2006 - https://scryfall.com/sets/pgtw
put("GRC/Fiery Temper", "https://img.scryfall.com/cards/large/en/pgtw/3.jpg");
put("GRC/Icatian Javelineers", "https://img.scryfall.com/cards/large/en/pgtw/2.jpg");
put("GRC/Wood Elves", "https://img.scryfall.com/cards/large/en/pgtw/1.jpg");
// 2007 - https://scryfall.com/sets/pg07
put("GRC/Boomerang", "https://img.scryfall.com/cards/large/en/pg07/4.jpg");
put("GRC/Calciderm", "https://img.scryfall.com/cards/large/en/pg07/5.jpg");
put("GRC/Dauntless Dourbark", "https://img.scryfall.com/cards/large/en/pg07/12.jpg");
put("GRC/Llanowar Elves", "https://img.scryfall.com/cards/large/en/pg07/9.jpg");
put("GRC/Mind Stone", "https://img.scryfall.com/cards/large/en/pg07/11.jpg");
put("GRC/Mogg Fanatic", "https://img.scryfall.com/cards/large/en/pg07/10.jpg");
put("GRC/Reckless Wurm", "https://img.scryfall.com/cards/large/en/pg07/6.jpg");
put("GRC/Yixlid Jailer", "https://img.scryfall.com/cards/large/en/pg07/7.jpg");
put("GRC/Zoetic Cavern", "https://img.scryfall.com/cards/large/en/pg07/8.jpg");
// 2008a - https://scryfall.com/sets/pg08
put("GRC/Boggart Ram-Gang", "https://img.scryfall.com/cards/large/en/pg08/17.jpg");
put("GRC/Cenn's Tactician", "https://img.scryfall.com/cards/large/en/pg08/14.jpg");
put("GRC/Duergar Hedge-Mage", "https://img.scryfall.com/cards/large/en/pg08/19.jpg");
put("GRC/Gravedigger", "https://img.scryfall.com/cards/large/en/pg08/16.jpg");
put("GRC/Lava Axe", "https://img.scryfall.com/cards/large/en/pg08/13.jpg");
put("GRC/Oona's Blackguard", "https://img.scryfall.com/cards/large/en/pg08/15.jpg");
put("GRC/Selkie Hedge-Mage", "https://img.scryfall.com/cards/large/en/pg08/20.jpg");
put("GRC/Wilt-Leaf Cavaliers", "https://img.scryfall.com/cards/large/en/pg08/18.jpg");
// Wizards Play Network Promos -- xmage uses one set (GRC), but scryfall store it by years
// 2008b - https://scryfall.com/sets/pwpn
put("GRC/Sprouting Thrinax", "https://img.scryfall.com/cards/large/en/pwpn/21.jpg");
put("GRC/Woolly Thoctar", "https://img.scryfall.com/cards/large/en/pwpn/22.jpg");
// 2009 - https://scryfall.com/sets/pwp09
put("GRC/Hellspark Elemental", "https://img.scryfall.com/cards/large/en/pwp09/25.jpg");
put("GRC/Kor Duelist", "https://img.scryfall.com/cards/large/en/pwp09/32.jpg");
put("GRC/Marisi's Twinclaws", "https://img.scryfall.com/cards/large/en/pwp09/26.jpg");
put("GRC/Mind Control", "https://img.scryfall.com/cards/large/en/pwp09/30.jpg");
put("GRC/Path to Exile", "https://img.scryfall.com/cards/large/en/pwp09/24.jpg");
put("GRC/Rise from the Grave", "https://img.scryfall.com/cards/large/en/pwp09/31.jpg");
put("GRC/Slave of Bolas", "https://img.scryfall.com/cards/large/en/pwp09/27.jpg");
put("GRC/Vampire Nighthawk", "https://img.scryfall.com/cards/large/en/pwp09/33.jpg");
// 2010 - https://scryfall.com/sets/pwp10
put("GRC/Kor Firewalker", "https://img.scryfall.com/cards/large/en/pwp10/36.jpg");
put("GRC/Leatherback Baloth", "https://img.scryfall.com/cards/large/en/pwp10/37.jpg");
put("GRC/Syphon Mind", "https://img.scryfall.com/cards/large/en/pwp10/40.jpg");
put("GRC/Pathrazer of Ulamog", "https://img.scryfall.com/cards/large/en/pwp10/46.jpg");
put("GRC/Curse of Wizardry", "https://img.scryfall.com/cards/large/en/pwp10/47.jpg");
put("GRC/Fling/50", "https://img.scryfall.com/cards/large/en/pwp10/50.jpg"); // same card but different year
put("GRC/Sylvan Ranger/51", "https://img.scryfall.com/cards/large/en/pwp10/51.jpg"); // same card but different year
put("GRC/Plague Stinger", "https://img.scryfall.com/cards/large/en/pwp10/59.jpg");
put("GRC/Golem's Heart", "https://img.scryfall.com/cards/large/en/pwp10/60.jpg");
put("GRC/Skinrender", "https://img.scryfall.com/cards/large/en/pwp10/63.jpg");
// 2011 - https://scryfall.com/sets/pwp11
put("GRC/Auramancer", "https://img.scryfall.com/cards/large/en/pwp11/77.jpg");
put("GRC/Bloodcrazed Neonate", "https://img.scryfall.com/cards/large/en/pwp11/83.jpg");
put("GRC/Boneyard Wurm", "https://img.scryfall.com/cards/large/en/pwp11/84.jpg");
put("GRC/Circle of Flame", "https://img.scryfall.com/cards/large/en/pwp11/78.jpg");
put("GRC/Curse of the Bloody Tome", "https://img.scryfall.com/cards/large/en/pwp11/80.jpg");
put("GRC/Fling/69", "https://img.scryfall.com/cards/large/en/pwp11/69.jpg"); // same card but different year
put("GRC/Master's Call", "https://img.scryfall.com/cards/large/en/pwp11/64.jpg");
put("GRC/Maul Splicer", "https://img.scryfall.com/cards/large/en/pwp11/72.jpg");
put("GRC/Plague Myr", "https://img.scryfall.com/cards/large/en/pwp11/65.jpg");
put("GRC/Shrine of Burning Rage", "https://img.scryfall.com/cards/large/en/pwp11/73.jpg");
put("GRC/Signal Pest", "https://img.scryfall.com/cards/large/en/pwp11/66.jpg");
put("GRC/Sylvan Ranger/70", "https://img.scryfall.com/cards/large/en/pwp11/70.jpg"); // same card but different year
put("GRC/Tormented Soul", "https://img.scryfall.com/cards/large/en/pwp11/76.jpg");
put("GRC/Vault Skirge", "https://img.scryfall.com/cards/large/en/pwp11/71.jpg");
// 2012 - https://scryfall.com/sets/pwp12
put("GRC/Curse of Thirst", "https://img.scryfall.com/cards/large/en/pwp12/81.jpg");
put("GRC/Gather the Townsfolk", "https://img.scryfall.com/cards/large/en/pwp12/79.jpg");
put("GRC/Nearheath Stalker", "https://img.scryfall.com/cards/large/en/pwp12/82.jpg");
// TODO: remove Grand Prix fix after scryfall fix image's link (that's link must be work: https://img.scryfall.com/cards/large/en/pgpx/2016b.jpg )
put("GPX/Sword of Feast and Famine", "https://img.scryfall.com/cards/large/en/pgpx/1%E2%98%85.jpg");
}
};
@Override
public ArrayList<String> getSupportedSets() {
ArrayList<String> supportedSetsCopy = new ArrayList<>();
supportedSetsCopy.addAll(supportedSets);
// cards
supportedSetsCopy.addAll(ScryfallImageSupportCards.getSupportedSets());
// tokens
for (String code : ScryfallImageSupportTokens.getSupportedSets().keySet()) {
if (!supportedSetsCopy.contains(code)) {
supportedSetsCopy.add(code);
}
}
return supportedSetsCopy;
}
@Override
public boolean isCardImageProvided(String setCode, String cardName) {
// all cards from set
return ScryfallImageSupportCards.getSupportedSets().contains(setCode);
}
@Override
public boolean isTokenImageProvided(String setCode, String cardName, Integer tokenNumber) {
// only direct tokens from set
return ScryfallImageSupportTokens.findTokenLink(setCode, cardName, tokenNumber) != null;
}
}

View file

@ -0,0 +1,392 @@
package org.mage.plugins.card.dl.sources;
import org.tritonus.share.ArraySet;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
/**
* @author JayDi85
*/
public class ScryfallImageSupportCards {
private static final Map<String, String> xmageSetsToScryfall = new HashMap<String, String>() {
{
// xmage -> scryfall
put("DD3GVL", "gvl");
put("DD3JVC", "jvc");
put("DD3DVD", "dvd");
put("DD3EVG", "evg");
put("MPS-AKH", "mp2");
put("MBP", "pmei");
put("WMCQ", "pwcq");
put("EURO", "pelp");
put("GPX", "pgpx");
put("MED", "me1");
}
};
private static final Set<String> supportedSets = new ArraySet<String>() {
{
// xmage set codes
// add("PTC"); //
add("LEA");
add("LEB");
add("2ED");
add("ARN");
add("ATQ");
add("3ED");
add("LEG");
add("DRK");
add("FEM");
add("4ED");
add("ICE");
add("CHR");
add("HML");
add("ALL");
add("MIR");
add("VIS");
add("5ED");
add("POR");
add("WTH");
add("TMP");
add("STH");
add("EXO");
add("P02");
add("UGL");
add("USG");
add("DD3DVD");
add("DD3EVG");
add("DD3GVL");
add("DD3JVC");
add("ULG");
add("6ED");
add("UDS");
add("PTK");
add("S99");
add("MMQ");
// add("BRB");Battle Royale Box Set
add("NEM");
add("S00");
add("PCY");
add("INV");
// add("BTD"); // Beatdown Boxset
add("PLS");
add("7ED");
add("APC");
add("ODY");
// add("DKM"); // Deckmasters 2001
add("TOR");
add("JUD");
add("ONS");
add("LGN");
add("SCG");
add("8ED");
add("MRD");
add("DST");
add("5DN");
add("CHK");
add("UNH");
add("BOK");
add("SOK");
add("9ED");
add("RAV");
add("GPT");
add("DIS");
add("CSP");
add("TSP");
add("TSB");
add("PLC");
add("FUT");
add("10E");
add("MED");
add("LRW");
add("EVG");
add("MOR");
add("SHM");
add("EVE");
add("DRB");
add("ME2");
add("ALA");
add("DD2");
add("CON");
add("DDC");
add("ARB");
add("M10");
// add("TD0"); // Magic Online Deck Series
add("V09");
add("HOP");
add("ME3");
add("ZEN");
add("DDD");
add("H09");
add("WWK");
add("DDE");
add("ROE");
// duels of the planewalkers:
add("DPA");
add("DPAP");
//
add("ARC");
add("M11");
add("V10");
add("DDF");
add("SOM");
// add("TD0"); // Commander Theme Decks
add("PD2");
add("ME4");
add("MBS");
add("DDG");
add("NPH");
add("CMD");
add("M12");
add("V11");
add("DDH");
add("ISD");
add("PD3");
add("DKA");
add("DDI");
add("AVR");
add("PC2");
add("M13");
add("V12");
add("DDJ");
add("RTR");
add("CM1");
// add("TD2"); // Duel Decks: Mirrodin Pure vs. New Phyrexia
add("GTC");
add("DDK");
add("DGM");
add("MMA");
add("M14");
add("V13");
add("DDL");
add("THS");
add("C13");
add("BNG");
add("DDM");
add("JOU");
// add("MD1"); // Modern Event Deck
add("CNS");
add("VMA");
add("M15");
add("V14");
add("DDN");
add("KTK");
add("C14");
// add("DD3"); // Duel Decks Anthology
add("FRF");
add("DDO");
add("DTK");
add("TPR");
add("MM2");
add("ORI");
add("V15");
add("DDP");
add("BFZ");
add("EXP");
add("C15");
// add("PZ1"); // Legendary Cube
add("OGW");
add("DDQ");
add("W16");
add("SOI");
add("EMA");
add("EMN");
add("V16");
add("CN2");
add("DDR");
add("KLD");
add("MPS");
// add("PZ2");
add("C16");
add("PCA");
add("AER");
add("MM3");
add("DDS");
add("W17");
add("AKH");
add("CMA");
add("E01");
add("HOU");
add("C17");
add("XLN");
add("DDT");
add("IMA");
add("E02");
add("V17");
add("UST");
add("DDU");
add("RIX");
add("WMCQ");
add("PPRO");
add("A25");
add("DOM");
add("BBD");
add("C18");
add("CM2");
add("M19");
add("GS1");
add("GRN");
add("GK1");
add("GNT");
add("UMA");
add("PUMA");
add("RNA");
//
add("EURO");
add("GPX");
add("ATH");
add("GRC");
add("ANA");
}
};
private static final Map<String, String> directDownloadLinks = new HashMap<String, String>() {
{
// xmage card -> direct or api link:
// examples:
// direct example: https://img.scryfall.com/cards/large/en/trix/6.jpg
// api example: https://api.scryfall.com/cards/trix/6/en?format=image
// api example: https://api.scryfall.com/cards/trix/6?format=image
// api format is primary
//
// code form for one card:
// set/card_name
//
// code form for same name cards (alternative images):
// set/card_name/card_number
// set/card_name/card_number
// Duels of the Planeswalkers Promos -- xmage uses one set (DPAP), but scryfall store it by years
// 2009 - https://scryfall.com/sets/pdtp
put("DPAP/Garruk Wildspeaker", "https://img.scryfall.com/cards/large/en/pdtp/1.jpg");
// 2010 - https://scryfall.com/sets/pdp10
put("DPAP/Liliana Vess", "https://img.scryfall.com/cards/large/en/pdp10/1.jpg");
put("DPAP/Nissa Revane", "https://img.scryfall.com/cards/large/en/pdp10/2.jpg");
// 2011 - https://scryfall.com/sets/pdp11
put("DPAP/Frost Titan", "https://img.scryfall.com/cards/large/en/pdp11/1.jpg");
put("DPAP/Grave Titan", "https://img.scryfall.com/cards/large/en/pdp11/2.jpg");
put("DPAP/Inferno Titan", "https://img.scryfall.com/cards/large/en/pdp11/3.jpg");
// 2012 - https://scryfall.com/sets/pdp12
put("DPAP/Primordial Hydra", "https://img.scryfall.com/cards/large/en/pdp12/1.jpg");
put("DPAP/Serra Avatar", "https://img.scryfall.com/cards/large/en/pdp12/2.jpg");
put("DPAP/Vampire Nocturnus", "https://img.scryfall.com/cards/large/en/pdp12/3.jpg");
// 2013 - https://scryfall.com/sets/pdp13
put("DPAP/Bonescythe Sliver", "https://img.scryfall.com/cards/large/en/pdp13/1.jpg");
put("DPAP/Ogre Battledriver", "https://img.scryfall.com/cards/large/en/pdp13/2.jpg");
put("DPAP/Scavenging Ooze", "https://img.scryfall.com/cards/large/en/pdp13/3.jpg");
// 2014 - https://scryfall.com/sets/pdp14
put("DPAP/Soul of Ravnica", "https://img.scryfall.com/cards/large/en/pdp14/1.jpg");
put("DPAP/Soul of Zendikar", "https://img.scryfall.com/cards/large/en/pdp14/2.jpg");
// Gateway Promos -- xmage uses one set (GRC), but scryfall store it by years
// 2006 - https://scryfall.com/sets/pgtw
put("GRC/Fiery Temper", "https://img.scryfall.com/cards/large/en/pgtw/3.jpg");
put("GRC/Icatian Javelineers", "https://img.scryfall.com/cards/large/en/pgtw/2.jpg");
put("GRC/Wood Elves", "https://img.scryfall.com/cards/large/en/pgtw/1.jpg");
// 2007 - https://scryfall.com/sets/pg07
put("GRC/Boomerang", "https://img.scryfall.com/cards/large/en/pg07/4.jpg");
put("GRC/Calciderm", "https://img.scryfall.com/cards/large/en/pg07/5.jpg");
put("GRC/Dauntless Dourbark", "https://img.scryfall.com/cards/large/en/pg07/12.jpg");
put("GRC/Llanowar Elves", "https://img.scryfall.com/cards/large/en/pg07/9.jpg");
put("GRC/Mind Stone", "https://img.scryfall.com/cards/large/en/pg07/11.jpg");
put("GRC/Mogg Fanatic", "https://img.scryfall.com/cards/large/en/pg07/10.jpg");
put("GRC/Reckless Wurm", "https://img.scryfall.com/cards/large/en/pg07/6.jpg");
put("GRC/Yixlid Jailer", "https://img.scryfall.com/cards/large/en/pg07/7.jpg");
put("GRC/Zoetic Cavern", "https://img.scryfall.com/cards/large/en/pg07/8.jpg");
// 2008a - https://scryfall.com/sets/pg08
put("GRC/Boggart Ram-Gang", "https://img.scryfall.com/cards/large/en/pg08/17.jpg");
put("GRC/Cenn's Tactician", "https://img.scryfall.com/cards/large/en/pg08/14.jpg");
put("GRC/Duergar Hedge-Mage", "https://img.scryfall.com/cards/large/en/pg08/19.jpg");
put("GRC/Gravedigger", "https://img.scryfall.com/cards/large/en/pg08/16.jpg");
put("GRC/Lava Axe", "https://img.scryfall.com/cards/large/en/pg08/13.jpg");
put("GRC/Oona's Blackguard", "https://img.scryfall.com/cards/large/en/pg08/15.jpg");
put("GRC/Selkie Hedge-Mage", "https://img.scryfall.com/cards/large/en/pg08/20.jpg");
put("GRC/Wilt-Leaf Cavaliers", "https://img.scryfall.com/cards/large/en/pg08/18.jpg");
// Wizards Play Network Promos -- xmage uses one set (GRC), but scryfall store it by years
// 2008b - https://scryfall.com/sets/pwpn
put("GRC/Sprouting Thrinax", "https://img.scryfall.com/cards/large/en/pwpn/21.jpg");
put("GRC/Woolly Thoctar", "https://img.scryfall.com/cards/large/en/pwpn/22.jpg");
// 2009 - https://scryfall.com/sets/pwp09
put("GRC/Hellspark Elemental", "https://img.scryfall.com/cards/large/en/pwp09/25.jpg");
put("GRC/Kor Duelist", "https://img.scryfall.com/cards/large/en/pwp09/32.jpg");
put("GRC/Marisi's Twinclaws", "https://img.scryfall.com/cards/large/en/pwp09/26.jpg");
put("GRC/Mind Control", "https://img.scryfall.com/cards/large/en/pwp09/30.jpg");
put("GRC/Path to Exile", "https://img.scryfall.com/cards/large/en/pwp09/24.jpg");
put("GRC/Rise from the Grave", "https://img.scryfall.com/cards/large/en/pwp09/31.jpg");
put("GRC/Slave of Bolas", "https://img.scryfall.com/cards/large/en/pwp09/27.jpg");
put("GRC/Vampire Nighthawk", "https://img.scryfall.com/cards/large/en/pwp09/33.jpg");
// 2010 - https://scryfall.com/sets/pwp10
put("GRC/Kor Firewalker", "https://img.scryfall.com/cards/large/en/pwp10/36.jpg");
put("GRC/Leatherback Baloth", "https://img.scryfall.com/cards/large/en/pwp10/37.jpg");
put("GRC/Syphon Mind", "https://img.scryfall.com/cards/large/en/pwp10/40.jpg");
put("GRC/Pathrazer of Ulamog", "https://img.scryfall.com/cards/large/en/pwp10/46.jpg");
put("GRC/Curse of Wizardry", "https://img.scryfall.com/cards/large/en/pwp10/47.jpg");
put("GRC/Fling/50", "https://img.scryfall.com/cards/large/en/pwp10/50.jpg"); // same card but different year
put("GRC/Sylvan Ranger/51", "https://img.scryfall.com/cards/large/en/pwp10/51.jpg"); // same card but different year
put("GRC/Plague Stinger", "https://img.scryfall.com/cards/large/en/pwp10/59.jpg");
put("GRC/Golem's Heart", "https://img.scryfall.com/cards/large/en/pwp10/60.jpg");
put("GRC/Skinrender", "https://img.scryfall.com/cards/large/en/pwp10/63.jpg");
// 2011 - https://scryfall.com/sets/pwp11
put("GRC/Auramancer", "https://img.scryfall.com/cards/large/en/pwp11/77.jpg");
put("GRC/Bloodcrazed Neonate", "https://img.scryfall.com/cards/large/en/pwp11/83.jpg");
put("GRC/Boneyard Wurm", "https://img.scryfall.com/cards/large/en/pwp11/84.jpg");
put("GRC/Circle of Flame", "https://img.scryfall.com/cards/large/en/pwp11/78.jpg");
put("GRC/Curse of the Bloody Tome", "https://img.scryfall.com/cards/large/en/pwp11/80.jpg");
put("GRC/Fling/69", "https://img.scryfall.com/cards/large/en/pwp11/69.jpg"); // same card but different year
put("GRC/Master's Call", "https://img.scryfall.com/cards/large/en/pwp11/64.jpg");
put("GRC/Maul Splicer", "https://img.scryfall.com/cards/large/en/pwp11/72.jpg");
put("GRC/Plague Myr", "https://img.scryfall.com/cards/large/en/pwp11/65.jpg");
put("GRC/Shrine of Burning Rage", "https://img.scryfall.com/cards/large/en/pwp11/73.jpg");
put("GRC/Signal Pest", "https://img.scryfall.com/cards/large/en/pwp11/66.jpg");
put("GRC/Sylvan Ranger/70", "https://img.scryfall.com/cards/large/en/pwp11/70.jpg"); // same card but different year
put("GRC/Tormented Soul", "https://img.scryfall.com/cards/large/en/pwp11/76.jpg");
put("GRC/Vault Skirge", "https://img.scryfall.com/cards/large/en/pwp11/71.jpg");
// 2012 - https://scryfall.com/sets/pwp12
put("GRC/Curse of Thirst", "https://img.scryfall.com/cards/large/en/pwp12/81.jpg");
put("GRC/Gather the Townsfolk", "https://img.scryfall.com/cards/large/en/pwp12/79.jpg");
put("GRC/Nearheath Stalker", "https://img.scryfall.com/cards/large/en/pwp12/82.jpg");
// TODO: remove Grand Prix fix after scryfall fix image's link (that's link must be work: https://img.scryfall.com/cards/large/en/pgpx/2016b.jpg )
put("GPX/Sword of Feast and Famine", "https://img.scryfall.com/cards/large/en/pgpx/1%E2%98%85.jpg");
// TODO: remove after scryfall add lands to RNA (that's link must works: https://api.scryfall.com/cards/rna/262/en?format=image)
put("RNA/Plains", "https://api.scryfall.com/cards/grn/260/en?format=image");
put("RNA/Island", "https://api.scryfall.com/cards/grn/261/en?format=image");
put("RNA/Swamp", "https://api.scryfall.com/cards/grn/262/en?format=image");
put("RNA/Mountain", "https://api.scryfall.com/cards/grn/263/en?format=image");
put("RNA/Forest", "https://api.scryfall.com/cards/grn/264/en?format=image");
}
};
public static String findScryfallSetCode(String xmageCode) {
return xmageSetsToScryfall.getOrDefault(xmageCode, xmageCode).toLowerCase(Locale.ENGLISH);
}
public static Set<String> getSupportedSets() {
return supportedSets;
}
public static String findDirectDownloadLink(String setCode, String cardName, String cardNumber) {
// set/card/number
String linkCode1 = setCode + "/" + cardName + "/" + cardNumber;
if (directDownloadLinks.containsKey(linkCode1)) {
return directDownloadLinks.get(linkCode1);
}
// set/card
String linkCode2 = setCode + "/" + cardName;
if (directDownloadLinks.containsKey(linkCode2)) {
return directDownloadLinks.get(linkCode2);
}
// default
return null;
}
}

View file

@ -0,0 +1,72 @@
package org.mage.plugins.card.dl.sources;
import java.util.HashMap;
import java.util.Map;
/**
* @author JayDi85
*/
public class ScryfallImageSupportTokens {
private static final Map<String, String> supportedSets = new HashMap<>();
private static final Map<String, String> supportedCards = new HashMap<String, String>() {
{
// xmage token -> direct or api link:
// examples:
// direct example: https://img.scryfall.com/cards/large/en/trix/6.jpg
// api example: https://api.scryfall.com/cards/trix/6/en?format=image
// api example: https://api.scryfall.com/cards/trix/6?format=image
// api format is primary
//
// code form for one token:
// set/token_name
//
// code form for same name tokens (alternative images):
// set/token_name/1
// set/token_name/2
// RIX
put("RIX/City's Blessing", "https://api.scryfall.com/cards/trix/6/en?format=image"); // TODO: missing from tokens data
put("RIX/Elemental/1", "https://api.scryfall.com/cards/trix/1/en?format=image");
put("RIX/Elemental/2", "https://api.scryfall.com/cards/trix/2/en?format=image");
put("RIX/Golem", "https://api.scryfall.com/cards/trix/4/en?format=image");
put("RIX/Emblem Huatli, Radiant Champion", "https://api.scryfall.com/cards/trix/5/en?format=image");
put("RIX/Saproling", "https://api.scryfall.com/cards/trix/3/en?format=image");
// RNA
put("RNA/Beast", "https://api.scryfall.com/cards/trna/8/en?format=image");
put("RNA/Centaur", "https://api.scryfall.com/cards/trna/5/en?format=image");
put("RNA/Emblem Domri, Chaos Bringer", "https://api.scryfall.com/cards/trna/13/en?format=image");
put("RNA/Frog Lizard", "https://api.scryfall.com/cards/trna/6/en?format=image");
put("RNA/Goblin", "https://api.scryfall.com/cards/trna/4/en?format=image");
put("RNA/Human", "https://api.scryfall.com/cards/trna/1/en?format=image");
put("RNA/Illusion", "https://api.scryfall.com/cards/trna/2/en?format=image");
put("RNA/Ooze", "https://api.scryfall.com/cards/trna/7/en?format=image");
put("RNA/Sphinx", "https://api.scryfall.com/cards/trna/9/en?format=image");
put("RNA/Spirit", "https://api.scryfall.com/cards/trna/10/en?format=image");
put("RNA/Thopter", "https://api.scryfall.com/cards/trna/11/en?format=image");
put("RNA/Treasure", "https://api.scryfall.com/cards/trna/12/en?format=image");
put("RNA/Zombie", "https://api.scryfall.com/cards/trna/3/en?format=image");
// generate supported sets
supportedSets.clear();
for (String cardName : this.keySet()) {
String[] s = cardName.split("\\/");
if (s.length > 1) {
supportedSets.putIfAbsent(s[0], s[0]);
}
}
}
};
public static Map<String, String> getSupportedSets() {
return supportedSets;
}
public static String findTokenLink(String setCode, String tokenName, Integer tokenNumber) {
String search = setCode + "/" + tokenName + (!tokenNumber.equals(0) ? "/" + tokenNumber : "");
return supportedCards.getOrDefault(search, null);
}
}

View file

@ -1,6 +1,11 @@
package org.mage.plugins.card.dl.sources;
import mage.constants.SubType;
import org.apache.log4j.Logger;
import org.mage.plugins.card.images.CardDownloadData;
import org.mage.plugins.card.images.DownloadPicturesService;
import org.mage.plugins.card.utils.CardImageUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
@ -8,21 +13,9 @@ import java.io.InputStreamReader;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.logging.Level;
import mage.constants.SubType;
import org.apache.log4j.Logger;
import org.mage.plugins.card.images.CardDownloadData;
import org.mage.plugins.card.images.DownloadPicturesService;
import org.mage.plugins.card.utils.CardImageUtils;
/**
* @author Quercitron
*/
@ -58,7 +51,7 @@ public enum TokensMtgImageSource implements CardImageSource {
}
@Override
public CardImageUrls generateURL(CardDownloadData card) throws Exception {
public CardImageUrls generateCardUrl(CardDownloadData card) throws Exception {
return null;
}
@ -160,7 +153,12 @@ public enum TokensMtgImageSource implements CardImageSource {
}
@Override
public boolean isImageProvided(String setCode, String cardName) {
public boolean isCardImageProvided(String setCode, String cardName) {
return false;
}
@Override
public boolean isTokenImageProvided(String setCode, String cardName, Integer tokenNumber) {
String searchName = cardName;
if (cardName.toLowerCase(Locale.ENGLISH).contains("emblem")) {
searchName = getEmblemName(cardName);

View file

@ -452,7 +452,7 @@ public enum WizardCardsImageSource implements CardImageSource {
}
@Override
public CardImageUrls generateURL(CardDownloadData card) throws Exception {
public CardImageUrls generateCardUrl(CardDownloadData card) throws Exception {
String collectorId = card.getCollectorId();
String cardSet = card.getSet();
if (collectorId == null || cardSet == null) {

View file

@ -18,7 +18,6 @@ import net.java.truevfs.access.TVFS;
import net.java.truevfs.kernel.spec.FsSyncException;
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 javax.swing.*;
@ -45,10 +44,10 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
private static DownloadPicturesService instance;
private static final Logger logger = Logger.getLogger(DownloadPicturesService.class);
public static final String ALL_IMAGES = "- ALL images from selected source (can be slow)";
public static final String ALL_MODERN_IMAGES = "- MODERN images (can be slow)";
public static final String ALL_STANDARD_IMAGES = "- STANDARD images";
public static final String ALL_TOKENS = "- TOKEN images";
private static final String ALL_IMAGES = "- ALL images from selected source (can be slow)";
private static final String ALL_MODERN_IMAGES = "- MODERN images (can be slow)";
private static final String ALL_STANDARD_IMAGES = "- STANDARD images";
private static final String ALL_TOKENS = "- TOKEN images";
private DownloadImagesDialog uiDialog;
private boolean needCancel;
@ -60,16 +59,16 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
private int missingCardsCount = 0;
private int missingTokensCount = 0;
List<String> selectedSets = new ArrayList<>();
private List<String> selectedSets = new ArrayList<>();
private static CardImageSource selectedSource;
private final Object sync = new Object();
private Proxy p = Proxy.NO_PROXY;
enum DownloadSources {
WIZARDS("1. wizards.com - low quality CARDS, multi-language, can be SLOW", WizardCardsImageSource.instance),
WIZARDS("1. wizards.com - low quality CARDS, multi-language, slow download", WizardCardsImageSource.instance),
TOKENS("2. tokens.mtg.onl - high quality TOKENS", TokensMtgImageSource.instance),
SCRYFALL("3. scryfall.com - high quality CARDS, multi-language", ScryfallImageSource.instance),
SCRYFALL("3. scryfall.com - high quality CARDS and TOKENS, 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),
@ -333,7 +332,7 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
int numberCardImagesAvailable = 0;
for (CardDownloadData data : cardsMissing) {
if (data.isToken()) {
if (selectedSource.isTokenSource() && selectedSource.isImageProvided(data.getSet(), data.getName())) {
if (selectedSource.isTokenSource() && selectedSource.isTokenImageProvided(data.getSet(), data.getName(), data.getType())) {
numberTokenImagesAvailable++;
cardsDownloadQueue.add(data);
} else {
@ -341,7 +340,7 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
}
} else {
if (selectedSets != null && selectedSets.contains(data.getSet())) {
if (selectedSource.isSetSupportedComplete(data.getSet()) || selectedSource.isImageProvided(data.getSet(), data.getName())) {
if (selectedSource.isSetSupportedComplete(data.getSet()) || selectedSource.isCardImageProvided(data.getSet(), data.getName())) {
numberCardImagesAvailable++;
cardsDownloadQueue.add(data);
}
@ -393,7 +392,6 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
}
private static List<CardDownloadData> prepareMissingCards(List<CardInfo> allCards, boolean redownloadMode) {
HashSet<String> ignoreUrls = SettingsManager.getIntance().getIgnoreUrls();
// get filter for Standard Type 2 cards
Set<String> type2SetsFilter = new HashSet<>();
@ -408,8 +406,7 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
List<CardDownloadData> allCardsUrls = Collections.synchronizedList(new ArrayList<>());
try {
allCards.parallelStream().forEach(card -> {
if (!card.getCardNumber().isEmpty() && !"0".equals(card.getCardNumber()) && !card.getSetCode().isEmpty()
&& !ignoreUrls.contains(card.getSetCode())) {
if (!card.getCardNumber().isEmpty() && !"0".equals(card.getCardNumber()) && !card.getSetCode().isEmpty()) {
String cardName = card.getName();
boolean isType2 = type2SetsFilter.contains(card.getSetCode());
CardDownloadData url = new CardDownloadData(cardName, card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), 0, "", "", false, card.isDoubleFaced(), card.isNightCard());
@ -498,7 +495,7 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
if (params.length >= 5) {
int type = 0;
if (params[4] != null && !params[4].isEmpty()) {
type = Integer.parseInt(params[4].trim());
type = Integer.parseInt(params[4].trim()); // token number for same names
}
String fileName = "";
if (params.length > 5 && params[5] != null && !params[5].isEmpty()) {
@ -547,6 +544,16 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
logger.error(ex);
throw new RuntimeException("DownloadPicturesService : readFile() error");
}
// TODO: delete and move to copy-pate images download mode
/*
for (CardDownloadData card : list) {
if (card.isToken()) {
System.out.println(card.getSet() + "/" + card.getName() + (!card.getType().equals(0) ? "/" + card.getType() : ""));
}
}
*/
return list;
}
@ -586,8 +593,6 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
}
if (p != null) {
HashSet<String> ignoreUrls = SettingsManager.getIntance().getIgnoreUrls();
update(0, cardsDownloadQueue.size());
logger.info("Started download of " + cardsDownloadQueue.size() + " images"
+ " from source: " + selectedSource.getSourceName()
@ -602,13 +607,13 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
logger.debug("Downloading image: " + card.getName() + " (" + card.getSet() + ')');
CardImageUrls urls;
if (ignoreUrls.contains(card.getSet()) || card.isToken()) {
if (card.isToken()) {
if (!"0".equals(card.getCollectorId())) {
continue;
}
urls = selectedSource.generateTokenUrl(card);
} else {
urls = selectedSource.generateURL(card);
urls = selectedSource.generateCardUrl(card);
}
if (urls == null) {
@ -929,7 +934,7 @@ class LoadMissingCardDataNew implements Runnable {
private static DownloadPicturesService downloadPicturesService;
public LoadMissingCardDataNew(DownloadPicturesService downloadPicturesService) {
this.downloadPicturesService = downloadPicturesService;
LoadMissingCardDataNew.downloadPicturesService = downloadPicturesService;
}
@Override
@ -940,5 +945,4 @@ class LoadMissingCardDataNew implements Runnable {
public static void main() {
(new Thread(new LoadMissingCardDataNew(downloadPicturesService))).start();
}
}

View file

@ -1,76 +0,0 @@
package org.mage.plugins.card.properties;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Properties;
import mage.client.constants.Constants;
public class SettingsManager {
private static SettingsManager settingsManager = null;
public static synchronized SettingsManager getIntance() {
if (settingsManager == null) {
settingsManager = new SettingsManager();
}
return settingsManager;
}
private SettingsManager() {
loadImageProperties();
}
public void reloadImageProperties() {
loadImageProperties();
}
private void loadImageProperties() {
imageUrlProperties = new Properties();
try {
InputStream is = SettingsManager.class.getClassLoader().getResourceAsStream(Constants.IO.IMAGE_PROPERTIES_FILE);
if (is == null) {
throw new RuntimeException("Couldn't load " + Constants.IO.IMAGE_PROPERTIES_FILE);
}
imageUrlProperties.load(is);
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
public String getSetNameReplacement(String setName) {
String result = setName;
if (imageUrlProperties != null) {
result = imageUrlProperties.getProperty(setName, setName);
}
return result;
}
public HashSet<String> getIgnoreUrls() {
HashSet<String> ignoreUrls = new HashSet<>();
if (imageUrlProperties != null) {
String result = imageUrlProperties.getProperty("ignore.urls");
if (result != null) {
String[] ignore = result.split(",");
ignoreUrls.addAll(Arrays.asList(ignore));
}
}
return ignoreUrls;
}
public ArrayList<String> getTokenLookupOrder() {
ArrayList<String> order = new ArrayList<>();
if (imageUrlProperties != null) {
String result = imageUrlProperties.getProperty("token.lookup.order");
if (result != null) {
String[] sets = result.split(",");
order.addAll(Arrays.asList(sets));
}
}
return order;
}
private Properties imageUrlProperties;
}

View file

@ -1,5 +1,16 @@
package org.mage.plugins.card.utils;
import mage.client.MageFrame;
import mage.client.constants.Constants;
import mage.client.dialog.PreferencesDialog;
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 java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
@ -12,18 +23,6 @@ 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;
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;
public final class CardImageUtils {
private static final HashMap<CardDownloadData, String> pathCache = new HashMap<>();
@ -53,7 +52,7 @@ public final class CardImageUtils {
return filePath;
}
log.warn("Token image file not found. Set: " + card.getSet() + " Token Set Code: " + card.getTokenSetCode() + " Name: " + card.getName() + " File path: " + filePath);
log.warn("Token image file not found. Set: " + card.getSet() + " Token Set Code: " + card.getTokenSetCode() + " Name: " + card.getName() + " File path: " + getTokenImagePath(card));
} else {
log.warn("Trying to get token path for non token card. Set: " + card.getSet() + " Set Code: " + card.getTokenSetCode() + " Name: " + card.getName());
}
@ -85,20 +84,6 @@ public final class CardImageUtils {
}
}
return filename;
// makes no longer sense
// file = new TFile(filename);
// if (!file.exists()) {
// CardDownloadData updated = new CardDownloadData(card);
// updated.setName(card.getName() + " 1");
// filename = buildImagePathToCard(updated);
// file = new TFile(filename);
// if (!file.exists()) {
// updated = new CardDownloadData(card);
// updated.setName(card.getName() + " 2");
// filename = buildImagePathToCard(updated);
// }
// }
}
private static String searchForCardImage(CardDownloadData card) {
@ -112,30 +97,9 @@ public final class CardImageUtils {
pathCache.put(card, path);
return path;
}
// for (String set : SettingsManager.getIntance().getTokenLookupOrder()) {
// c.setSet(set);
// path = getTokenImagePath(c);
// file = new TFile(path);
// if (file.exists()) {
// pathCache.put(card, path);
// return path;
// }
// }
return generateTokenDescriptorImagePath(card);
}
public static String updateSet(String cardSet, boolean forUrl) {
String set = cardSet.toLowerCase(Locale.ENGLISH);
if (set.equals("con")) {
set = "cfx";
}
if (forUrl) {
set = SettingsManager.getIntance().getSetNameReplacement(set);
}
return set;
}
public static String prepareCardNameForFile(String cardName) {
return cardName.replace(":", "").replace("\"", "").replace("//", "-");
}
@ -162,6 +126,15 @@ public final class CardImageUtils {
return path;
}
public static String fixSetNameForWindows(String set) {
// windows can't create con folders
if (set.equals("CON") || set.equals("con")) {
return "COX";
} else {
return set;
}
}
public static String buildImagePathToTokens() {
String imagesPath = getImagesDir() + File.separator;
@ -182,7 +155,7 @@ public final class CardImageUtils {
throw new IllegalArgumentException("Card " + card.getName() + " have empty set.");
}
String set = updateSet(card.getSet(), false).toUpperCase(Locale.ENGLISH); // TODO: research auto-replace... old code?
String set = card.getSet().toUpperCase(Locale.ENGLISH);
if (card.isToken()) {
return buildImagePathToSetAsToken(set);
@ -195,14 +168,14 @@ public final class CardImageUtils {
String imagesPath = getImagesDir() + File.separator;
if (PreferencesDialog.isSaveImagesToZip()) {
return imagesPath + set + ".zip" + File.separator + set + File.separator;
return imagesPath + fixSetNameForWindows(set) + ".zip" + File.separator + fixSetNameForWindows(set) + File.separator;
} else {
return imagesPath + set + File.separator;
return imagesPath + fixSetNameForWindows(set) + File.separator;
}
}
private static String buildImagePathToSetAsToken(String set) {
return buildImagePathToTokens() + set + File.separator;
return buildImagePathToTokens() + fixSetNameForWindows(set) + File.separator;
}
public static String buildImagePathToCard(CardDownloadData card) {
@ -211,7 +184,7 @@ public final class CardImageUtils {
String prefixType = "";
if (card.getType() != 0) {
prefixType = " " + Integer.toString(card.getType());
prefixType = " " + card.getType();
}
String cardName = card.getFileName();
@ -228,6 +201,7 @@ public final class CardImageUtils {
finalFileName = cardName + prefixType + ".full.jpg";
}
/* 2019-01-12: no needs in name corrections, all files must be same and auto-downloaded
// if image file exists, correct name (for case sensitive systems)
// use TFile for zips
TFile dirFile = new TFile(setPath);
@ -246,12 +220,13 @@ public final class CardImageUtils {
} catch (Exception ex) {
log.error("Can't read card name from file, may be it broken: " + setPath);
}
*/
return setPath + finalFileName;
}
public static String generateFaceImagePath(String cardname, String set) {
return getImagesDir() + File.separator + "FACE" + File.separator + set + File.separator + prepareCardNameForFile(cardname) + ".jpg";
return getImagesDir() + File.separator + "FACE" + File.separator + fixSetNameForWindows(set) + File.separator + prepareCardNameForFile(cardname) + ".jpg";
}
public static String generateTokenDescriptorImagePath(CardDownloadData card) {

View file

@ -86,6 +86,7 @@
|Generate|EMBLEM:MMA|Elspeth, Knight Errant||Emblem Elspeth|ElspethKnightErrantEmblem|
|Generate|EMBLEM:SWS|Obi-Wan Kenobi||Emblem Obi-Wan Kenobi|ObiWanKenobiEmblem|
|Generate|EMBLEM:RIX|Huatli, Radiant Champion||Emblem Huatli|HuatliRadiantChampionEmblem|
|Generate|EMBLEM:RNA|Domri, Chaos Bringer||Emblem Domri|DomriChaosBringerEmblem|
|Generate|PLANE:PCA|Plane - Academy At Tolaria West|||AcademyAtTolariaWestPlane|
|Generate|PLANE:PCA|Plane - Agyrem|||AgyremPlane|
|Generate|PLANE:PCA|Plane - Akoum|||AkoumPlane|
@ -1185,3 +1186,15 @@
|Generate|TOK:ZEN|Vampire||
|Generate|TOK:ZEN|Wolf|||WolfToken|
|Generate|TOK:ZEN|Zombie Giant|||QuestForTheGravelordZombieToken|
|Generate|TOK:RNA|Beast|||RedGreenBeastToken|
|Generate|TOK:RNA|Centaur|||CentaurToken|
|Generate|TOK:RNA|Frog Lizard|||FrogLizardToken|
|Generate|TOK:RNA|Goblin|||GoblinToken|
|Generate|TOK:RNA|Human|||HumanToken|
|Generate|TOK:RNA|Illusion|||MesmerizingBenthidToken|
|Generate|TOK:RNA|Ooze|||BiogenicOozeToken|
|Generate|TOK:RNA|Sphinx|||WardenSphinxToken|
|Generate|TOK:RNA|Spirit|||SpiritWhiteToken|
|Generate|TOK:RNA|Thopter|||ThopterToken|
|Generate|TOK:RNA|Treasure|||TreasureToken|
|Generate|TOK:RNA|Zombie|||ZombieToken|

View file

@ -1,78 +0,0 @@
tsp=ts
tor=tr
mor=mt
ody=od
lrw=lw
plc=pc
gpt=gp
inv=in
ons=on
scg=sc
jud=ju
mmq=mm
pls=ps
mrd=mi
mir=mr
tst=ts
usg=us
apc=ap
nem=ne
dis=di
vis=vi
9ed=9e
8ed=8e
7ed=7e
4ed=4e
tsb=tsts
ulg=ul
5ed=5e
6ed=6e
btd=bd
sth=sh
por=po
s99=st
lgn=le
ice=ia
csp=cs
tmp=tp
s00=st2k
dst=ds
pcy=pr
uds=ud
exo=ex
lea=al
hop=pch
chr=ch
arn=an
wth=wl
leb=be
2ed=un
3ed=rv
brb=br
atq=aq
fem=fe
leg=lg
hml=hl
all=ai
drk=dk
ptk=p3k
gur=guru
ddc=dvd
dd2=jvc
ddd=gvl
unh=uh
dde=pvc
v09=fve
v10=fvr
v11=fvl
drb=fvd
h09=pds
ugl=ug
dd3dvd=ddadvd
dd3evg=ddaevg
dd3gvl=ddagvl
dd3jvc=ddajvc
# Remove setname as soon as the images can be downloaded
ignore.urls=TOK,H17
# sets ordered by release time (newest goes first)
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

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-common</artifactId>

View file

@ -80,7 +80,7 @@ public class SessionImpl implements Session {
// handling.
public interface RemotingTask {
public boolean run() throws Throwable;
boolean run() throws Throwable;
}
// handleRemotingTaskExceptions runs the given task and handles exceptions appropriately. This
@ -223,7 +223,7 @@ public class SessionImpl implements Session {
@Override
public Optional<String> getServerHostname() {
return isConnected() ? Optional.of(connection.getHost()) : Optional.<String>empty();
return isConnected() ? Optional.of(connection.getHost()) : Optional.empty();
}
@Override
@ -392,26 +392,22 @@ public class SessionImpl implements Session {
}
private void updateDatabase(boolean forceDBComparison, ServerState serverState) {
long cardDBVersion = CardRepository.instance.getContentVersionFromDB();
if (forceDBComparison || serverState.getCardsContentVersion() > cardDBVersion) {
List<String> classNames = CardRepository.instance.getClassNames();
List<CardInfo> cards = server.getMissingCardsData(classNames);
CardRepository.instance.addCards(cards);
CardRepository.instance.setContentVersion(serverState.getCardsContentVersion());
logger.info("Updating client cards DB - existing cards: " + classNames.size() + " new cards: " + cards.size()
+ " content versions - server: " + serverState.getCardsContentVersion() + " client: " + cardDBVersion);
}
// sets
long expansionDBVersion = ExpansionRepository.instance.getContentVersionFromDB();
if (forceDBComparison || serverState.getExpansionsContentVersion() > expansionDBVersion) {
List<String> setCodes = ExpansionRepository.instance.getSetCodes();
List<ExpansionInfo> expansions = server.getMissingExpansionData(setCodes);
for (ExpansionInfo expansion : expansions) {
ExpansionRepository.instance.add(expansion);
}
ExpansionRepository.instance.setContentVersion(serverState.getExpansionsContentVersion());
logger.info("Updating client expansions DB - existing sets: " + setCodes.size() + " new sets: " + expansions.size()
+ " content versions - server: " + serverState.getExpansionsContentVersion() + " client: " + expansionDBVersion);
logger.info("DB: updating sets... Founded new: " + expansions.size());
ExpansionRepository.instance.saveSets(expansions, null, serverState.getExpansionsContentVersion());
}
// cards
long cardDBVersion = CardRepository.instance.getContentVersionFromDB();
if (forceDBComparison || serverState.getCardsContentVersion() > cardDBVersion) {
List<String> classNames = CardRepository.instance.getClassNames();
List<CardInfo> cards = server.getMissingCardsData(classNames);
logger.info("DB: updating cards... Founded new: " + cards.size());
CardRepository.instance.saveCards(cards, serverState.getCardsContentVersion());
}
}

View file

@ -14,7 +14,7 @@ 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 = 32;
public final static int MAGE_VERSION_PATCH = 33;
public final static String MAGE_EDITION_INFO = ""; // set "-beta" for 1.4.32-betaV0
public final static String MAGE_VERSION_MINOR_PATCH = "V0";

View file

@ -1,14 +1,7 @@
package mage.view;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.costs.Cost;
import mage.cards.Card;
@ -32,8 +25,10 @@ import mage.players.Player;
import mage.watchers.common.CastSpellLastTurnWatcher;
import org.apache.log4j.Logger;
import java.io.Serializable;
import java.util.*;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class GameView implements Serializable {
@ -90,7 +85,7 @@ public class GameView implements Serializable {
if (object != null) {
if (object instanceof Permanent) {
boolean controlled = ((Permanent) object).getControllerId().equals(createdForPlayerId);
stack.put(stackObject.getId(), new StackAbilityView(game, (StackAbility) stackObject, ((Permanent) object).getName(), new CardView(((Permanent) object), game, controlled, false, false)));
stack.put(stackObject.getId(), new StackAbilityView(game, (StackAbility) stackObject, object.getName(), new CardView(((Permanent) object), game, controlled, false, false)));
} else {
stack.put(stackObject.getId(), new StackAbilityView(game, (StackAbility) stackObject, card.getName(), new CardView(card, game, false, false, false)));
}
@ -109,14 +104,14 @@ public class GameView implements Serializable {
} else if (object instanceof Emblem) {
CardView cardView = new CardView(new EmblemView((Emblem) object));
// Card sourceCard = (Card) ((Emblem) object).getSourceObject();
((StackAbility) stackObject).setName(((Emblem) object).getName());
stackObject.setName(object.getName());
// ((StackAbility) stackObject).setExpansionSetCode(sourceCard.getExpansionSetCode());
stack.put(stackObject.getId(),
new StackAbilityView(game, (StackAbility) stackObject, object.getName(), cardView));
checkPaid(stackObject.getId(), ((StackAbility) stackObject));
} else if (object instanceof Plane) {
CardView cardView = new CardView(new PlaneView((Plane) object));
((StackAbility) stackObject).setName(((Plane) object).getName());
stackObject.setName(object.getName());
stack.put(stackObject.getId(),
new StackAbilityView(game, (StackAbility) stackObject, object.getName(), cardView));
checkPaid(stackObject.getId(), ((StackAbility) stackObject));
@ -131,7 +126,7 @@ public class GameView implements Serializable {
} else if (object instanceof StackAbility) {
StackAbility stackAbility = ((StackAbility) object);
stackAbility.newId();
stack.put(stackObject.getId(), new CardView(((StackAbility) stackObject)));
stack.put(stackObject.getId(), new CardView(stackObject));
checkPaid(stackObject.getId(), ((StackAbility) stackObject));
} else {
LOGGER.fatal("Object can't be cast to StackAbility: " + object.getName() + ' ' + object.toString() + ' ' + object.getClass().toString());
@ -182,7 +177,7 @@ public class GameView implements Serializable {
this.special = false;
}
CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(CastSpellLastTurnWatcher.class.getSimpleName());
CastSpellLastTurnWatcher watcher = game.getState().getWatcher(CastSpellLastTurnWatcher.class);
if (watcher != null) {
spellsCastCurrentTurn = watcher.getAmountOfSpellsAllPlayersCastOnCurrentTurn();
} else {

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-counter-plugin</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-plugins</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<groupId>org.mage</groupId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-deck-constructed</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-deck-limited</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-game-brawlduel</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-game-brawlfreeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-game-canadianhighlanderduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-game-commanderduel</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-game-commanderfreeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-game-freeforall</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-game-freeformcommanderfreeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-game-momirduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-game-momirfreeforall</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-game-pennydreadfulcommanderfreeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-game-tinyleadersduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-game-twoplayerduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-player-ai-draftbot</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-player-ai-ma</artifactId>

View file

@ -1,28 +1,12 @@
package mage.player.ai;
import java.io.File;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
import mage.abilities.SpellAbility;
import mage.abilities.common.PassAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.SearchEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.DoubleStrikeAbility;
import mage.abilities.keyword.ExaltedAbility;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.IndestructibleAbility;
import mage.abilities.keyword.ReachAbility;
import mage.abilities.keyword.*;
import mage.cards.Card;
import mage.cards.Cards;
import mage.choices.Choice;
@ -49,8 +33,11 @@ import mage.target.Targets;
import mage.util.RandomUtil;
import org.apache.log4j.Logger;
import java.io.File;
import java.util.*;
import java.util.concurrent.*;
/**
*
* @author nantuko
*/
public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
@ -180,10 +167,9 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
if (!suggested.isEmpty() && !(ability instanceof PassAbility)) {
Iterator<String> it = suggested.iterator();
while (it.hasNext()) {
Card card = game.getCard(ability.getSourceId());
String action = it.next();
logger.info("Suggested action=" + action + ";card=" + card);
if (action.equals(card.getName())) {
Card card = game.getCard(ability.getSourceId());
if (card != null && action.equals(card.getName())) {
logger.info("-> removed from suggested=" + action);
it.remove();
}
@ -930,7 +916,7 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
String line = scanner.nextLine();
if (line.startsWith("cast:")
|| line.startsWith("play:")) {
suggested.add(line.substring(5, line.length()));
suggested.add(line.substring(5));
}
}
System.out.println("suggested::");
@ -953,7 +939,7 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
if (action != null
&& (action.startsWith("cast:")
|| action.startsWith("play:"))) {
suggested.add(action.substring(5, action.length()));
suggested.add(action.substring(5));
}
}

View file

@ -1,4 +1,3 @@
package mage.player.ai;
import mage.MageObject;
@ -25,7 +24,6 @@ import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class SimulatedPlayer2 extends ComputerPlayer {
@ -173,6 +171,7 @@ public class SimulatedPlayer2 extends ComputerPlayer {
// allActions.add(new SimulatedAction(sim, actions));
// }
// }
/**
* if suggested abilities exist, return only those from playables
*
@ -191,11 +190,13 @@ public class SimulatedPlayer2 extends ComputerPlayer {
List<Ability> filtered = new ArrayList<>();
for (Ability ability : playables) {
Card card = game.getCard(ability.getSourceId());
for (String s : suggested) {
if (s.equals(card.getName())) {
logger.debug("matched: " + s);
forced = true;
filtered.add(ability);
if (card != null) {
for (String s : suggested) {
if (s.equals(card.getName())) {
logger.debug("matched: " + s);
forced = true;
filtered.add(ability);
}
}
}
}
@ -216,26 +217,28 @@ public class SimulatedPlayer2 extends ComputerPlayer {
for (Ability option : options) {
if (!option.getTargets().isEmpty() && option.getTargets().get(0).getMaxNumberOfTargets() == 1) {
Card card = game.getCard(ability.getSourceId());
for (String s : suggested) {
String[] groups = s.split(";");
logger.trace("s=" + s + ";groups=" + groups.length);
if (groups.length == 2) {
if (groups[0].equals(card.getName()) && groups[1].startsWith("name=")) {
// extract target and compare to suggested
String targetName = groups[1].split("=")[1];
Player player = game.getPlayer(option.getFirstTarget());
if (player != null && targetName.equals(player.getName())) {
System.out.println("matched(option): " + s);
filtered.add(option);
return filtered;
} else {
Card target = game.getCard(option.getFirstTarget());
if (target != null && target.getName().equals(targetName)) {
if (card != null) {
for (String s : suggested) {
String[] groups = s.split(";");
logger.trace("s=" + s + ";groups=" + groups.length);
if (groups.length == 2) {
if (groups[0].equals(card.getName()) && groups[1].startsWith("name=")) {
// extract target and compare to suggested
String targetName = groups[1].split("=")[1];
Player player = game.getPlayer(option.getFirstTarget());
if (player != null && targetName.equals(player.getName())) {
System.out.println("matched(option): " + s);
filtered.add(option);
return filtered;
} else {
Card target = game.getCard(option.getFirstTarget());
if (target != null && target.getName().equals(targetName)) {
System.out.println("matched(option): " + s);
filtered.add(option);
return filtered;
}
System.out.println("not equal UUID for target, player=" + player);
}
System.out.println("not equal UUID for target, player=" + player);
}
}
}

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-player-ai</artifactId>

View file

@ -500,6 +500,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
if (target.getOriginalTarget() instanceof TargetPermanent) {
List<Permanent> targets;
TargetPermanent t = (TargetPermanent) target.getOriginalTarget();
boolean outcomeTargets = true;
if (outcome.isGood()) {
targets = threats(abilityControllerId, source == null ? null : source.getSourceId(), ((TargetPermanent) target).getFilter(), game, target.getTargets());
@ -512,6 +513,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
outcomeTargets = false;
//targets = game.getBattlefield().getActivePermanents(((TargetPermanent)target).getFilter(), playerId, game);
}
if (targets.isEmpty() && target.isRequired()) {
targets = game.getBattlefield().getActivePermanents(t.getFilter(), playerId, game);
}
for (Permanent permanent : targets) {
if (((TargetPermanent) target).canTarget(abilityControllerId, permanent.getId(), source, game)) {
target.addTarget(permanent.getId(), source, game);

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-player-ai-mcts</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-player-aiminimax</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-player-human</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-tournament-boosterdraft</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-tournament-constructed</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-tournament-sealed</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-server-plugins</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<artifactId>mage-server</artifactId>

View file

@ -4,6 +4,7 @@ import mage.cards.ExpansionSet;
import mage.cards.Sets;
import mage.cards.repository.CardScanner;
import mage.cards.repository.PluginClassloaderRegistery;
import mage.cards.repository.RepositoryUtil;
import mage.game.match.MatchType;
import mage.game.tournament.TournamentType;
import mage.interfaces.MageServer;
@ -88,6 +89,10 @@ public final class Main {
logger.info("Done.");
}
// db init and updates checks (e.g. cleanup cards db on new version)
RepositoryUtil.bootstrapLocalDb();
logger.info("Done.");
logger.info("Loading extension packages...");
if (!extensionFolder.exists()) {
if (!extensionFolder.mkdirs()) {

View file

@ -1,30 +1,31 @@
package mage.server.util;
import mage.abilities.Ability;
import mage.cards.Card;
import mage.cards.repository.CardCriteria;
import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.util.RandomUtil;
import java.io.File;
import java.lang.reflect.Constructor;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import mage.abilities.Ability;
import mage.cards.Card;
import mage.cards.Cards;
import mage.cards.repository.CardCriteria;
import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
import mage.util.RandomUtil;
/**
* @author JayDi85
*/
@ -111,6 +112,9 @@ public final class SystemUtil {
for (UUID cardID : cardsList) {
Card card = game.getCard(cardID);
if (card == null) {
continue;
}
// basic info (card + set)
String cardInfo = card.getName() + " - " + card.getExpansionSetCode();
@ -225,7 +229,7 @@ public final class SystemUtil {
* <br/>
* <b>Implementation note:</b><br/>
* 1. Read init.txt line by line<br/>
* 2. Parse line using for searching groups like: [group 1]
* 2. Parse line using for searching groups like: [group 1]
* 3. Parse line using the following format: line ::=
* <zone>:<nickname>:<card name>:<amount><br/>
* 4. If zone equals to 'hand', add card to player's library<br/>
@ -432,6 +436,13 @@ public final class SystemUtil {
game.addPlane((mage.game.command.Plane) plane, null, player.getId());
continue;
}
} else if ("loyalty".equalsIgnoreCase(command.zone)) {
for (Permanent perm : game.getBattlefield().getAllActivePermanents(player.getId())) {
if (perm.getName().equals(command.cardName) && perm.getCardType().contains(CardType.PLANESWALKER)) {
perm.addCounters(CounterType.LOYALTY.createInstance(command.Amount), null, game);
}
}
continue;
}
Zone gameZone;
@ -537,8 +548,8 @@ public final class SystemUtil {
/**
* Get a diff between two dates
*
* @param date1 the oldest date
* @param date2 the newest date
* @param date1 the oldest date
* @param date2 the newest date
* @param timeUnit the unit in which you want the diff
* @return the diff value, in the provided unit
*/

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.32</version>
<version>1.4.33</version>
</parent>
<groupId>org.mage</groupId>

View file

@ -1,26 +1,26 @@
package mage.cards.a;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.CostAdjuster;
import mage.abilities.costs.common.DiscardTargetCost;
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.InfoEffect;
import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.target.TargetPlayer;
import mage.target.common.TargetCardInHand;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public final class AbandonHope extends CardImpl {
@ -29,52 +29,35 @@ public final class AbandonHope extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{1}{B}");
// As an additional cost to cast Abandon Hope, discard X cards.
Ability ability = new SimpleStaticAbility(Zone.ALL, new AbandonHopeRuleEffect());
Ability ability = new SimpleStaticAbility(Zone.ALL, new InfoEffect("As an additional cost to cast this spell, discard X cards"));
ability.setRuleAtTheTop(true);
this.addAbility(ability);
// Look at target opponent's hand and choose X cards from it. That player discards those cards.
ManacostVariableValue manaX = new ManacostVariableValue();
ManacostVariableValue manaX = ManacostVariableValue.instance;
this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(manaX, TargetController.ANY));
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().setCostAdjuster(AbandonHopeAdjuster.instance);
}
public AbandonHope(final AbandonHope card) {
super(card);
}
@Override
public void adjustCosts(Ability ability, Game game) {
int xValue = ability.getManaCostsToPay().getX();
if (xValue > 0) {
ability.addCost(new DiscardTargetCost(new TargetCardInHand(xValue, xValue, new FilterCard("cards"))));
}
}
@Override
public AbandonHope copy() {
return new AbandonHope(this);
}
}
class AbandonHopeRuleEffect extends OneShotEffect {
public AbandonHopeRuleEffect() {
super(Outcome.Benefit);
this.staticText = "As an additional cost to cast this spell, discard X cards";
}
public AbandonHopeRuleEffect(final AbandonHopeRuleEffect effect) {
super(effect);
}
enum AbandonHopeAdjuster implements CostAdjuster {
instance;
@Override
public AbandonHopeRuleEffect copy() {
return new AbandonHopeRuleEffect(this);
public void adjustCosts(Ability ability, Game game) {
int xValue = ability.getManaCostsToPay().getX();
if (xValue > 0) {
ability.addCost(new DiscardTargetCost(new TargetCardInHand(xValue, xValue, StaticFilters.FILTER_CARD_CARDS)));
}
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
}
}

View file

@ -1,25 +1,12 @@
package mage.cards.a;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneAllEffect;
import mage.abilities.keyword.CyclingAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.WatcherScope;
import mage.constants.Zone;
import mage.cards.*;
import mage.constants.*;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.AbilityPredicate;
@ -31,8 +18,12 @@ import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.watchers.Watcher;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
public final class AbandonedSarcophagus extends CardImpl {
@ -55,7 +46,7 @@ public final class AbandonedSarcophagus extends CardImpl {
}
public AbandonedSarcophagus(final AbandonedSarcophagus card) {
private AbandonedSarcophagus(final AbandonedSarcophagus card) {
super(card);
}
@ -67,15 +58,12 @@ public final class AbandonedSarcophagus extends CardImpl {
class AbandonedSarcophagusReplacementEffect extends ReplacementEffectImpl {
boolean cardHasCycling;
boolean cardWasCycledThisTurn;
public AbandonedSarcophagusReplacementEffect() {
AbandonedSarcophagusReplacementEffect() {
super(Duration.WhileOnBattlefield, Outcome.Exile);
staticText = "If a card with cycling would be put into your graveyard from anywhere and it wasn't cycled, exile it instead";
}
public AbandonedSarcophagusReplacementEffect(final AbandonedSarcophagusReplacementEffect effect) {
private AbandonedSarcophagusReplacementEffect(final AbandonedSarcophagusReplacementEffect effect) {
super(effect);
}
@ -112,34 +100,33 @@ class AbandonedSarcophagusReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
cardWasCycledThisTurn = false;
cardHasCycling = false;
if (((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD
&& !game.isSimulation()) {
Player controller = game.getPlayer(source.getControllerId());
AbandonedSarcophagusWatcher watcher = (AbandonedSarcophagusWatcher) game.getState().getWatchers().get(AbandonedSarcophagusWatcher.class.getSimpleName());
Card card = game.getCard(event.getTargetId());
if (card != null
&& controller != null
&& watcher != null
&& card.isOwnedBy(controller.getId())) {
for (Ability ability : card.getAbilities()) {
if (ability instanceof CyclingAbility) {
cardHasCycling = true;
}
}
Cards cards = watcher.getCardsCycledThisTurn(controller.getId());
for (Card c : cards.getCards(game)) {
if (c == card) {
cardWasCycledThisTurn = true;
watcher.getCardsCycledThisTurn(controller.getId()).remove(card); //remove reference to the card as it is no longer needed
}
}
return (!cardWasCycledThisTurn
&& cardHasCycling);
boolean cardWasCycledThisTurn = false;
boolean cardHasCycling = false;
if (!(((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD) || game.isSimulation()) {
return false;
}
Player controller = game.getPlayer(source.getControllerId());
AbandonedSarcophagusWatcher watcher = game.getState().getWatcher(AbandonedSarcophagusWatcher.class);
Card card = game.getCard(event.getTargetId());
if (card == null
|| controller == null
|| watcher == null
|| !card.isOwnedBy(controller.getId())) {
return false;
}
for (Ability ability : card.getAbilities()) {
if (ability instanceof CyclingAbility) {
cardHasCycling = true;
}
}
return false;
Cards cards = watcher.getCardsCycledThisTurn(controller.getId());
for (Card c : cards.getCards(game)) {
if (c == card) {
cardWasCycledThisTurn = true;
watcher.getCardsCycledThisTurn(controller.getId()).remove(card); //remove reference to the card as it is no longer needed
}
}
return !cardWasCycledThisTurn && cardHasCycling;
}
}
@ -147,11 +134,11 @@ class AbandonedSarcophagusWatcher extends Watcher {
private final Map<UUID, Cards> cycledCardsThisTurn = new HashMap<>();
public AbandonedSarcophagusWatcher() {
AbandonedSarcophagusWatcher() {
super(AbandonedSarcophagusWatcher.class.getSimpleName(), WatcherScope.GAME);
}
public AbandonedSarcophagusWatcher(final AbandonedSarcophagusWatcher watcher) {
private AbandonedSarcophagusWatcher(final AbandonedSarcophagusWatcher watcher) {
super(watcher);
for (Entry<UUID, Cards> entry : watcher.cycledCardsThisTurn.entrySet()) {
cycledCardsThisTurn.put(entry.getKey(), entry.getValue().copy());

View file

@ -1,8 +1,5 @@
package mage.cards.a;
import java.util.Optional;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
@ -17,8 +14,10 @@ import mage.game.Game;
import mage.game.events.GameEvent;
import mage.target.TargetPlayer;
import java.util.Optional;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public final class Abeyance extends CardImpl {
@ -46,12 +45,13 @@ public final class Abeyance extends CardImpl {
class AbeyanceEffect extends ContinuousRuleModifyingEffectImpl {
public AbeyanceEffect() {
AbeyanceEffect() {
super(Duration.EndOfTurn, Outcome.Detriment);
staticText = "Until end of turn, target player can't cast instant or sorcery spells, and that player can't activate abilities that aren't mana abilities";
staticText = "Until end of turn, target player can't cast instant or sorcery spells, " +
"and that player can't activate abilities that aren't mana abilities";
}
public AbeyanceEffect(final AbeyanceEffect effect) {
private AbeyanceEffect(final AbeyanceEffect effect) {
super(effect);
}
@ -69,29 +69,29 @@ class AbeyanceEffect extends ContinuousRuleModifyingEffectImpl {
public String getInfoMessage(Ability source, GameEvent event, Game game) {
MageObject mageObject = game.getObject(source.getSourceId());
if (mageObject != null) {
return "You can't cast instant or sorcery spells or activate abilities that aren't mana abilities this turn (" + mageObject.getIdName() + ").";
return "You can't cast instant or sorcery spells or activate abilities " +
"that aren't mana abilities this turn (" + mageObject.getIdName() + ").";
}
return null;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (source.getFirstTarget() != null && source.getFirstTarget().equals(event.getPlayerId())) {
MageObject object = game.getObject(event.getSourceId());
if(object == null){
return false;
}
if (event.getType() == GameEvent.EventType.CAST_SPELL) {
if (object.isInstant() || object.isSorcery()) {
return true;
}
}
if (event.getType() == GameEvent.EventType.ACTIVATE_ABILITY) {
Optional<Ability> ability = game.getAbility(event.getTargetId(), event.getSourceId());
if (ability.isPresent() && !(ability.get() instanceof ActivatedManaAbilityImpl)) {
return true;
}
}
if (source.getFirstTarget() != null
&& source.getFirstTarget().equals(event.getPlayerId())) {
return false;
}
MageObject object = game.getObject(event.getSourceId());
if (object == null) {
return false;
}
if (event.getType() == GameEvent.EventType.CAST_SPELL
&& (object.isInstant() || object.isSorcery())) {
return true;
}
if (event.getType() == GameEvent.EventType.ACTIVATE_ABILITY) {
Optional<Ability> ability = game.getAbility(event.getTargetId(), event.getSourceId());
return ability.isPresent() && !(ability.get() instanceof ActivatedManaAbilityImpl);
}
return false;
}

View file

@ -28,7 +28,7 @@ public final class AbzanAscendancy extends CardImpl {
static {
filter.add(new ControllerPredicate(TargetController.YOU));
filter.add(Predicates.not(new TokenPredicate()));
filter.add(Predicates.not(TokenPredicate.instance));
}
public AbzanAscendancy(UUID ownerId, CardSetInfo setInfo) {

View file

@ -1,7 +1,6 @@
package mage.cards.a;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
@ -17,23 +16,23 @@ import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.filter.predicate.permanent.CounterPredicate;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class AbzanBattlePriest extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent();
static {
filter.add(new CardTypePredicate(CardType.CREATURE));
filter.add(new ControllerPredicate(TargetController.YOU));
filter.add(new CounterPredicate(CounterType.P1P1));
}
static final String rule = "Each creature you control with a +1/+1 counter on it has lifelink";
public AbzanBattlePriest(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.CLERIC);
@ -42,9 +41,15 @@ public final class AbzanBattlePriest extends CardImpl {
// Outlast {W}
this.addAbility(new OutlastAbility(new ManaCostsImpl<>("{W}")));
// Each creature you control with a +1/+1 counter on it has lifelink.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(LifelinkAbility.getInstance(), Duration.WhileOnBattlefield, filter, rule)));
this.addAbility(new SimpleStaticAbility(
Zone.BATTLEFIELD,
new GainAbilityAllEffect(
LifelinkAbility.getInstance(), Duration.WhileOnBattlefield,
filter, "Each creature you control with a +1/+1 counter on it has lifelink"
)
));
}
public AbzanBattlePriest(final AbzanBattlePriest card) {

View file

@ -1,8 +1,6 @@
package mage.cards.a;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.Mode;
@ -22,6 +20,8 @@ import mage.players.Player;
import mage.target.Target;
import mage.util.CardUtil;
import java.util.UUID;
/**
* @author halljared
*/
@ -44,7 +44,7 @@ public final class AccursedWitch extends CardImpl {
this.addAbility(new DiesTriggeredAbility(new AccursedWitchReturnTransformedEffect()));
}
public AccursedWitch(final AccursedWitch card) {
private AccursedWitch(final AccursedWitch card) {
super(card);
}
@ -56,12 +56,12 @@ public final class AccursedWitch extends CardImpl {
class AccursedWitchReturnTransformedEffect extends OneShotEffect {
public AccursedWitchReturnTransformedEffect() {
AccursedWitchReturnTransformedEffect() {
super(Outcome.PutCardInPlay);
this.staticText = "Put {this} from your graveyard onto the battlefield transformed";
}
public AccursedWitchReturnTransformedEffect(final AccursedWitchReturnTransformedEffect effect) {
private AccursedWitchReturnTransformedEffect(final AccursedWitchReturnTransformedEffect effect) {
super(effect);
}
@ -73,29 +73,27 @@ class AccursedWitchReturnTransformedEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
if (game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) {
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
//note: should check for null after game.getCard
Card card = game.getCard(source.getSourceId());
if (card != null) {
controller.moveCards(card, Zone.BATTLEFIELD, source, game);
}
}
return true;
if (controller == null || !(game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD)) {
return false;
}
return false;
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
//note: should check for null after game.getCard
Card card = game.getCard(source.getSourceId());
if (card != null) {
controller.moveCards(card, Zone.BATTLEFIELD, source, game);
}
return true;
}
}
class AccursedWitchSpellsCostReductionEffect extends CostModificationEffectImpl {
public AccursedWitchSpellsCostReductionEffect() {
AccursedWitchSpellsCostReductionEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment, CostModificationType.REDUCE_COST);
this.staticText = "Spells your opponents cast that target {this} cost {1} less to cast.";
}
protected AccursedWitchSpellsCostReductionEffect(AccursedWitchSpellsCostReductionEffect effect) {
private AccursedWitchSpellsCostReductionEffect(AccursedWitchSpellsCostReductionEffect effect) {
super(effect);
}
@ -107,17 +105,16 @@ class AccursedWitchSpellsCostReductionEffect extends CostModificationEffectImpl
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
if (abilityToModify instanceof SpellAbility) {
if (game.getOpponents(source.getControllerId()).contains(abilityToModify.getControllerId())) {
for (UUID modeId : abilityToModify.getModes().getSelectedModes()) {
Mode mode = abilityToModify.getModes().get(modeId);
for (Target target : mode.getTargets()) {
for (UUID targetUUID : target.getTargets()) {
Permanent permanent = game.getPermanent(targetUUID);
if (permanent != null && permanent.getId().equals(source.getSourceId())) {
return true;
}
}
if (!(abilityToModify instanceof SpellAbility) || !game.getOpponents(source.getControllerId()).contains(abilityToModify.getControllerId())) {
return false;
}
for (UUID modeId : abilityToModify.getModes().getSelectedModes()) {
Mode mode = abilityToModify.getModes().get(modeId);
for (Target target : mode.getTargets()) {
for (UUID targetUUID : target.getTargets()) {
Permanent permanent = game.getPermanent(targetUUID);
if (permanent != null && permanent.getId().equals(source.getSourceId())) {
return true;
}
}
}

View file

@ -1,7 +1,6 @@
package mage.cards.a;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
@ -25,8 +24,9 @@ import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/**
*
* @author L_J
*/
public final class AchHansRun extends CardImpl {
@ -38,7 +38,7 @@ public final class AchHansRun extends CardImpl {
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new AchHansRunEffect(), TargetController.YOU, true));
}
public AchHansRun(final AchHansRun card) {
private AchHansRun(final AchHansRun card) {
super(card);
}
@ -50,12 +50,12 @@ public final class AchHansRun extends CardImpl {
class AchHansRunEffect extends OneShotEffect {
public AchHansRunEffect() {
AchHansRunEffect() {
super(Outcome.PutCreatureInPlay);
this.staticText = "you may say \"Ach! Hans, run! Its the …\" and the name of a creature card. If you do, search your library for a card with that name, put it onto the battlefield, then shuffle your library. That creature gains haste. Exile it at the beginning of the next end step";
}
public AchHansRunEffect(final AchHansRunEffect effect) {
private AchHansRunEffect(final AchHansRunEffect effect) {
super(effect);
}
@ -67,41 +67,41 @@ class AchHansRunEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
ChoiceImpl cardChoice = new ChoiceImpl(true);
cardChoice.setChoices(CardRepository.instance.getCreatureNames());
cardChoice.setMessage("Choose a creature card name");
if (controller.choose(Outcome.Detriment, cardChoice, game)) {
String cardName = cardChoice.getChoice();
if (!game.isSimulation()) {
game.informPlayers(controller.getLogName() + ": \"Ach! Hans, run! It's the " + cardName + "!\"");
}
FilterCard nameFilter = new FilterCard();
nameFilter.add(new NamePredicate(cardName));
TargetCardInLibrary target = new TargetCardInLibrary(1, 1, nameFilter);
if (controller.searchLibrary(target, game)) {
Card card = controller.getLibrary().remove(target.getFirstTarget(), game);
if (card != null) {
if (card != null && controller.moveCards(card, Zone.BATTLEFIELD, source, game)) {
Permanent creature = game.getPermanent(card.getId());
if (creature != null) {
// gains haste
ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn);
effect.setTargetPointer(new FixedTarget(creature, game));
game.addEffect(effect, source);
// Exile at begin of next end step
ExileTargetEffect exileEffect = new ExileTargetEffect(null, null, Zone.BATTLEFIELD);
exileEffect.setTargetPointer(new FixedTarget(creature, game));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect);
game.addDelayedTriggeredAbility(delayedAbility, source);
}
}
}
controller.shuffleLibrary(source, game);
}
return true;
}
if (controller == null) {
return false;
}
return false;
ChoiceImpl cardChoice = new ChoiceImpl(true);
cardChoice.setChoices(CardRepository.instance.getCreatureNames());
cardChoice.setMessage("Choose a creature card name");
if (!controller.choose(Outcome.Detriment, cardChoice, game)) {
return false;
}
String cardName = cardChoice.getChoice();
game.informPlayers(controller.getLogName() + ": \"Ach! Hans, run! It's the " + cardName + "!\"");
FilterCard nameFilter = new FilterCard();
nameFilter.add(new NamePredicate(cardName));
TargetCardInLibrary target = new TargetCardInLibrary(1, 1, nameFilter);
if (!controller.searchLibrary(target, game)) {
return false;
}
Card card = controller.getLibrary().remove(target.getFirstTarget(), game);
if (card == null || !controller.moveCards(card, Zone.BATTLEFIELD, source, game)) {
return false;
}
Permanent creature = game.getPermanent(card.getId());
if (creature == null) {
return false;
}
// gains haste
ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn);
effect.setTargetPointer(new FixedTarget(creature, game));
game.addEffect(effect, source);
// Exile at begin of next end step
ExileTargetEffect exileEffect = new ExileTargetEffect(null, null, Zone.BATTLEFIELD);
exileEffect.setTargetPointer(new FixedTarget(creature, game));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect);
game.addDelayedTriggeredAbility(delayedAbility, source);
controller.shuffleLibrary(source, game);
return true;
}
}

View file

@ -27,7 +27,7 @@ public final class AcidSpewerDragon extends CardImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("other Dragon creature you control");
static {
filter.add(new AnotherPredicate());
filter.add(AnotherPredicate.instance);
filter.add(new SubtypePredicate(SubType.DRAGON));
}

View file

@ -1,7 +1,6 @@
package mage.cards.a;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
@ -14,14 +13,15 @@ import mage.constants.*;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class AdamaroFirstToDesire extends CardImpl {
public AdamaroFirstToDesire(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}{R}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{R}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.SPIRIT);
@ -46,7 +46,7 @@ class MostCardsInOpponentsHandCount implements DynamicValue {
@Override
public int calculate(Game game, Ability source, Effect effect) {
int maxCards = 0;
for (UUID opponentId: game.getOpponents(source.getControllerId())) {
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
Player opponent = game.getPlayer(opponentId);
if (opponent != null) {
int cards = opponent.getHand().size();
@ -60,7 +60,7 @@ class MostCardsInOpponentsHandCount implements DynamicValue {
@Override
public DynamicValue copy() {
return new mage.abilities.dynamicvalue.common.CardsInControllerHandCount();
return new MostCardsInOpponentsHandCount();
}
@Override

View file

@ -34,7 +34,7 @@ public final class AdarkarValkyrie extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("another creature");
static {
filter.add(new AnotherPredicate());
filter.add(AnotherPredicate.instance);
}
public AdarkarValkyrie(UUID ownerId, CardSetInfo setInfo) {

View file

@ -1,26 +1,23 @@
package mage.cards.a;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.constants.*;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
import java.util.UUID;
/**
*
* @author JRHerlehy
*/
public final class AdelizTheCinderWind extends CardImpl {
@ -34,7 +31,7 @@ public final class AdelizTheCinderWind extends CardImpl {
public AdelizTheCinderWind(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{R}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN, SubType.WIZARD);
this.power = new MageInt(2);
@ -48,7 +45,7 @@ public final class AdelizTheCinderWind extends CardImpl {
// Whenever you cast an instant or sorcery spell, Wizards you control get +1/+1 until end of turn.
Effect effect = new BoostControlledEffect(1, 1, Duration.EndOfTurn, filter);
Ability ability = new SpellCastControllerTriggeredAbility(effect, StaticFilters.FILTER_SPELL_INSTANT_OR_SORCERY, false);
Ability ability = new SpellCastControllerTriggeredAbility(effect, StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false);
this.addAbility(ability);
}

View file

@ -124,7 +124,7 @@ class ControllerDealtDamageByPiratesPredicate implements Predicate<Permanent> {
@Override
public boolean apply(Permanent input, Game game) {
DamagedByPiratesWatcher watcher = (DamagedByPiratesWatcher) game.getState().getWatchers().get(DamagedByPiratesWatcher.class.getSimpleName());
DamagedByPiratesWatcher watcher = game.getState().getWatcher(DamagedByPiratesWatcher.class);
if (watcher != null) {
return watcher.damagedByEnoughPirates(input.getControllerId(), game);
}

View file

@ -30,7 +30,7 @@ public final class AdmonitionAngel extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("nonland permanent other than Admonition Angel");
static {
filter.add(new AnotherPredicate());
filter.add(AnotherPredicate.instance);
filter.add(Predicates.not(new CardTypePredicate(CardType.LAND)));
}

View file

@ -27,7 +27,7 @@ public final class AegisAngel extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("another target permanent");
static {
filter.add(new AnotherPredicate());
filter.add(AnotherPredicate.instance);
}
public AegisAngel(UUID ownerId, CardSetInfo setInfo) {

View file

@ -25,7 +25,7 @@ public final class AegisAutomaton extends CardImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("another target creature you control");
static {
filter.add(new AnotherPredicate());
filter.add(AnotherPredicate.instance);
}
public AegisAutomaton(UUID ownerId, CardSetInfo setInfo) {

View file

@ -36,7 +36,7 @@ public final class AeonChronicler extends CardImpl {
this.toughness = new MageInt(0);
// Aeon Chronicler's power and toughness are each equal to the number of cards in your hand.
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new CardsInControllerHandCount(), Duration.EndOfGame)));
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(CardsInControllerHandCount.instance, Duration.EndOfGame)));
// Suspend X-{X}{3}{U}. X can't be 0.
this.addAbility(new SuspendAbility(Integer.MAX_VALUE, new ManaCostsImpl("{3}{U}"), this, true));

Some files were not shown because too many files have changed in this diff Show more