diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java index 5b60e65ba1a..03b2f5a2720 100644 --- a/Mage.Client/src/main/java/mage/client/MageFrame.java +++ b/Mage.Client/src/main/java/mage/client/MageFrame.java @@ -277,6 +277,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { try { UIManager.put("desktop", new Color(0, 0, 0, 0)); UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); + //UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); // stop JSplitPane from eating F6 and F8 or any other function keys { Object value = UIManager.get("SplitPane.ancestorInputMap"); diff --git a/Mage.Client/src/main/java/mage/client/cards/Card.java b/Mage.Client/src/main/java/mage/client/cards/Card.java index 1a43fca1558..ddfbc789e95 100644 --- a/Mage.Client/src/main/java/mage/client/cards/Card.java +++ b/Mage.Client/src/main/java/mage/client/cards/Card.java @@ -92,6 +92,7 @@ import mage.view.CardView; import mage.view.CounterView; import mage.view.PermanentView; import mage.view.StackAbilityView; +import org.apache.log4j.Logger; /** * @@ -191,7 +192,7 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis gSmall.drawImage(ImageHelper.scaleImage(image, Config.dimensions.frameWidth, Config.dimensions.frameHeight), 0, 0, this); gImage.setFont(new Font("Arial", Font.PLAIN, NAME_FONT_MAX_SIZE)); - gImage.drawString(card.getName(), CONTENT_MAX_XOFFSET, NAME_MAX_YOFFSET); + gImage.drawString(card.getName()+"TEST", CONTENT_MAX_XOFFSET, NAME_MAX_YOFFSET); if (card.getCardTypes().contains(CardType.CREATURE)) { gImage.drawString(card.getPower() + "/" + card.getToughness(), POWBOX_TEXT_MAX_LEFT, POWBOX_TEXT_MAX_TOP); } else if (card.getCardTypes().contains(CardType.PLANESWALKER)) { @@ -205,9 +206,9 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis gImage.dispose(); gSmall.setFont(new Font("Arial", Font.PLAIN, Config.dimensions.nameFontSize)); - gSmall.drawString(card.getName(), Config.dimensions.contentXOffset, Config.dimensions.nameYOffset); + gSmall.drawString(card.getName()+"TEST2", Config.dimensions.contentXOffset, Config.dimensions.nameYOffset); if (card.getCardTypes().contains(CardType.CREATURE)) { - gSmall.drawString(card.getPower() + "/" + card.getToughness(), Config.dimensions.powBoxTextLeft, Config.dimensions.powBoxTextTop); + gSmall.drawString(card.getPower() + "/-/" + card.getToughness(), Config.dimensions.powBoxTextLeft, Config.dimensions.powBoxTextTop); } else if (card.getCardTypes().contains(CardType.PLANESWALKER)) { gSmall.drawString(card.getLoyalty(), Config.dimensions.powBoxTextLeft, Config.dimensions.powBoxTextTop); } @@ -221,7 +222,7 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis } @Override - public void updateImage() { + public void updateArtImage() { } @@ -318,6 +319,19 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis return sbType.toString(); } + + protected void drawDetailed(Graphics2D g) { + // Get the size of the card + int width = getWidth(); + int height = getHeight(); + + g.setColor(Color.black); + g.drawRoundRect(0, 0, width, height, 4, 4); + g.setColor(Color.white); + g.setFont(new Font("Arial", Font.PLAIN, NAME_FONT_MAX_SIZE)); + g.drawString(card.getName(), 0, 0); + Logger.getLogger(Card.class).info("Drawing"); + } /** * This method is called from within the constructor to initialize the form. @@ -355,6 +369,8 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis @Override public void paintComponent(Graphics graphics) { + drawDetailed((Graphics2D)graphics); + /* Graphics2D g2 = (Graphics2D) graphics; g2.drawImage(small, 0, 0, this); @@ -365,6 +381,7 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis g2.setColor(Color.BLACK); } g2.drawRect(0, 0, Config.dimensions.frameWidth - 1, Config.dimensions.frameHeight - 1); + */ } @Override diff --git a/Mage.Client/src/main/java/mage/client/cards/Cards.java b/Mage.Client/src/main/java/mage/client/cards/Cards.java index 67287d54d8d..d4b91472b65 100644 --- a/Mage.Client/src/main/java/mage/client/cards/Cards.java +++ b/Mage.Client/src/main/java/mage/client/cards/Cards.java @@ -114,7 +114,7 @@ public class Cards extends javax.swing.JPanel { setGUISize(); for (MageCard mageCard : cards.values()) { mageCard.setCardBounds(0, 0, getCardDimension().width, getCardDimension().height); - mageCard.updateImage(); + mageCard.updateArtImage(); mageCard.doLayout(); } layoutCards(); diff --git a/Mage.Client/src/main/java/mage/client/cards/CardsList.form b/Mage.Client/src/main/java/mage/client/cards/CardsList.form index 2e3e1c73b18..e64f4ae04bd 100644 --- a/Mage.Client/src/main/java/mage/client/cards/CardsList.form +++ b/Mage.Client/src/main/java/mage/client/cards/CardsList.form @@ -34,21 +34,16 @@ - - - - - - - + + - - - + + + @@ -81,15 +76,7 @@ - - - - - - - - - + @@ -97,7 +84,7 @@ - + @@ -109,11 +96,7 @@ - - - - @@ -177,60 +160,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -324,24 +253,6 @@ - - - - - - - - - - - - - - - - - - diff --git a/Mage.Client/src/main/java/mage/client/cards/CardsList.java b/Mage.Client/src/main/java/mage/client/cards/CardsList.java index 9d999ab6e40..e27eed4806a 100644 --- a/Mage.Client/src/main/java/mage/client/cards/CardsList.java +++ b/Mage.Client/src/main/java/mage/client/cards/CardsList.java @@ -211,7 +211,7 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar } }); - mainModel.setUpdateCountsCallback(new UpdateCountsCallback(lblCount, lblCreatureCount, lblLandCount, lblSorceryCount, lblInstantCount, lblEnchantmentCount, lblArtifactCount)); + mainModel.setUpdateCountsCallback(new UpdateCountsCallback(lblCount, lblCreatureCount, lblLandCount, null, null, null, null)); } // if you use the deck ediot to build a free deck, numbers can be set directly in deck and sideboard @@ -418,10 +418,6 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar this.lblCount.setText(Integer.toString(count)); this.lblCreatureCount.setText(Integer.toString(creatureCount)); this.lblLandCount.setText(Integer.toString(landCount)); - this.lblSorceryCount.setText(Integer.toString(sorceryCount)); - this.lblInstantCount.setText(Integer.toString(instantCount)); - this.lblEnchantmentCount.setText(Integer.toString(enchantmentCount)); - this.lblArtifactCount.setText(Integer.toString(artifactCount)); } private MageCard addCard(CardView card, BigCard bigCard, UUID gameId) { @@ -482,14 +478,10 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar lblCount = new javax.swing.JLabel(); lblLandCount = new javax.swing.JLabel(); lblCreatureCount = new javax.swing.JLabel(); - lblSorceryCount = new javax.swing.JLabel(); - lblInstantCount = new javax.swing.JLabel(); - lblEnchantmentCount = new javax.swing.JLabel(); chkPiles = new javax.swing.JCheckBox(); cbSortBy = new javax.swing.JComboBox(); jToggleListView = new javax.swing.JToggleButton(); jToggleCardView = new javax.swing.JToggleButton(); - lblArtifactCount = new javax.swing.JLabel(); panelCardArea = new javax.swing.JScrollPane(); cardArea = new javax.swing.JLayeredPane(); @@ -537,39 +529,6 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar lblCreatureCount.setRequestFocusEnabled(false); lblCreatureCount.setVerifyInputWhenFocusTarget(false); - lblSorceryCount.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - lblSorceryCount.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/type_sorcery.png"))); // NOI18N - lblSorceryCount.setText("999"); - lblSorceryCount.setToolTipText("Number of sorceries."); - lblSorceryCount.setVerticalAlignment(javax.swing.SwingConstants.TOP); - lblSorceryCount.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); - lblSorceryCount.setFocusable(false); - lblSorceryCount.setInheritsPopupMenu(false); - lblSorceryCount.setRequestFocusEnabled(false); - lblSorceryCount.setVerifyInputWhenFocusTarget(false); - - lblInstantCount.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - lblInstantCount.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/type_instant.png"))); // NOI18N - lblInstantCount.setText("999"); - lblInstantCount.setToolTipText("Number of instants."); - lblInstantCount.setVerticalAlignment(javax.swing.SwingConstants.TOP); - lblInstantCount.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); - lblInstantCount.setFocusable(false); - lblInstantCount.setInheritsPopupMenu(false); - lblInstantCount.setRequestFocusEnabled(false); - lblInstantCount.setVerifyInputWhenFocusTarget(false); - - lblEnchantmentCount.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - lblEnchantmentCount.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/type_enchantment.png"))); // NOI18N - lblEnchantmentCount.setText("999"); - lblEnchantmentCount.setToolTipText("Number of enchantments."); - lblEnchantmentCount.setVerticalAlignment(javax.swing.SwingConstants.TOP); - lblEnchantmentCount.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); - lblEnchantmentCount.setFocusable(false); - lblEnchantmentCount.setInheritsPopupMenu(false); - lblEnchantmentCount.setRequestFocusEnabled(false); - lblEnchantmentCount.setVerifyInputWhenFocusTarget(false); - chkPiles.setText("Piles"); chkPiles.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); chkPiles.setMargin(new java.awt.Insets(3, 2, 2, 2)); @@ -619,17 +578,6 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar } }); - lblArtifactCount.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - lblArtifactCount.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/type_artifact.png"))); // NOI18N - lblArtifactCount.setText("999"); - lblArtifactCount.setToolTipText("Number of artifacts"); - lblArtifactCount.setVerticalAlignment(javax.swing.SwingConstants.TOP); - lblArtifactCount.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); - lblArtifactCount.setFocusable(false); - lblArtifactCount.setInheritsPopupMenu(false); - lblArtifactCount.setRequestFocusEnabled(false); - lblArtifactCount.setVerifyInputWhenFocusTarget(false); - javax.swing.GroupLayout panelControlLayout = new javax.swing.GroupLayout(panelControl); panelControl.setLayout(panelControlLayout); panelControlLayout.setHorizontalGroup( @@ -641,14 +589,6 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(lblCreatureCount) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblSorceryCount) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblInstantCount) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblEnchantmentCount) - .addGap(4, 4, 4) - .addComponent(lblArtifactCount) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(chkPiles) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(cbSortBy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) @@ -656,7 +596,7 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar .addComponent(jToggleListView, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jToggleCardView, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 62, Short.MAX_VALUE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); panelControlLayout.setVerticalGroup( panelControlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -666,11 +606,7 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar .addComponent(lblCount) .addComponent(lblLandCount) .addComponent(lblCreatureCount) - .addComponent(lblSorceryCount) - .addComponent(lblInstantCount) - .addComponent(lblEnchantmentCount) - .addComponent(chkPiles) - .addComponent(lblArtifactCount)) + .addComponent(chkPiles)) .addComponent(cbSortBy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jToggleListView, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jToggleCardView, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) @@ -686,21 +622,27 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(1, 1, 1) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(panelControl, javax.swing.GroupLayout.DEFAULT_SIZE, 703, Short.MAX_VALUE) - .addComponent(panelCardArea))) + .addComponent(panelControl, javax.swing.GroupLayout.PREFERRED_SIZE, 467, Short.MAX_VALUE) + .addComponent(panelCardArea) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(panelControl, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, 0) - .addComponent(panelCardArea, javax.swing.GroupLayout.DEFAULT_SIZE, 86, Short.MAX_VALUE)) + .addComponent(panelControl, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(2, 2, 2) + .addComponent(panelCardArea, javax.swing.GroupLayout.DEFAULT_SIZE, 179, Short.MAX_VALUE)) ); }// //GEN-END:initComponents + private void jToggleCardViewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jToggleCardViewActionPerformed + currentView = this; + panelCardArea.setViewportView(cardArea); + cbSortBy.setEnabled(true); + chkPiles.setEnabled(true); + PreferencesDialog.saveValue(PreferencesDialog.KEY_DRAFT_VIEW, "cardView"); + redrawCards(); + }//GEN-LAST:event_jToggleCardViewActionPerformed + private void jToggleListViewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jToggleListViewActionPerformed currentView = mainModel; panelCardArea.setViewportView(mainTable); @@ -720,15 +662,6 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar drawCards(sortSetting); }//GEN-LAST:event_chkPilesActionPerformed - private void jToggleCardViewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jToggleCardViewActionPerformed - currentView = this; - panelCardArea.setViewportView(cardArea); - cbSortBy.setEnabled(true); - chkPiles.setEnabled(true); - PreferencesDialog.saveValue(PreferencesDialog.KEY_DRAFT_VIEW, "cardView"); - redrawCards(); - }//GEN-LAST:event_jToggleCardViewActionPerformed - // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.ButtonGroup bgView; private javax.swing.JLayeredPane cardArea; @@ -736,13 +669,9 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar private javax.swing.JCheckBox chkPiles; private javax.swing.JToggleButton jToggleCardView; private javax.swing.JToggleButton jToggleListView; - private javax.swing.JLabel lblArtifactCount; private javax.swing.JLabel lblCount; private javax.swing.JLabel lblCreatureCount; - private javax.swing.JLabel lblEnchantmentCount; - private javax.swing.JLabel lblInstantCount; private javax.swing.JLabel lblLandCount; - private javax.swing.JLabel lblSorceryCount; private javax.swing.JScrollPane panelCardArea; private javax.swing.JPanel panelControl; // End of variables declaration//GEN-END:variables diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckArea.form b/Mage.Client/src/main/java/mage/client/deckeditor/DeckArea.form index 625407e997b..e3178a5df72 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckArea.form +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckArea.form @@ -16,31 +16,26 @@ - + - + - - + + + + - - - - - - - @@ -48,6 +43,13 @@ + + + + + + + diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckArea.java b/Mage.Client/src/main/java/mage/client/deckeditor/DeckArea.java index 35d501a8f07..d7a2dd1b02f 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckArea.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckArea.java @@ -118,23 +118,23 @@ public class DeckArea extends javax.swing.JPanel { private void initComponents() { deckAreaSplitPane = new javax.swing.JSplitPane(); - deckList = new mage.client.cards.CardsList(); sideboardList = new mage.client.cards.CardsList(); + deckList = new mage.client.cards.CardsList(); - deckAreaSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); - deckAreaSplitPane.setResizeWeight(0.8); - deckAreaSplitPane.setLeftComponent(deckList); + deckAreaSplitPane.setBorder(null); + deckAreaSplitPane.setResizeWeight(0.6); deckAreaSplitPane.setRightComponent(sideboardList); + deckAreaSplitPane.setLeftComponent(deckList); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(deckAreaSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 740, Short.MAX_VALUE) + .addComponent(deckAreaSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 918, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(deckAreaSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 568, Short.MAX_VALUE) + .addComponent(deckAreaSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 377, Short.MAX_VALUE) ); }// //GEN-END:initComponents diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/table/UpdateCountsCallback.java b/Mage.Client/src/main/java/mage/client/deckeditor/table/UpdateCountsCallback.java index 64889c892d2..8960035cfe8 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/table/UpdateCountsCallback.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/table/UpdateCountsCallback.java @@ -11,7 +11,7 @@ public class UpdateCountsCallback { private final javax.swing.JLabel lblCount; private final javax.swing.JLabel lblCreatureCount; private final javax.swing.JLabel lblLandCount; - private final javax.swing.JLabel lblSoerceryCount; + private final javax.swing.JLabel lblSorceryCount; private final javax.swing.JLabel lblInstantCount; private final javax.swing.JLabel lblEnchantmentCount; private final javax.swing.JLabel lblArtifactCount; @@ -20,19 +20,26 @@ public class UpdateCountsCallback { this.lblCount = count; this.lblCreatureCount = creatures; this.lblLandCount = lands; - this.lblSoerceryCount = sorceries; + this.lblSorceryCount = sorceries; this.lblInstantCount = instants; this.lblEnchantmentCount = enchantments; this.lblArtifactCount = artifacts; } public void update(int count, int creatures, int lands, int sorceries, int instants, int enchantments, int artifacts) { - this.lblCount.setText(Integer.toString(count)); - this.lblCreatureCount.setText(Integer.toString(creatures)); - this.lblLandCount.setText(Integer.toString(lands)); - this.lblSoerceryCount.setText(Integer.toString(sorceries)); - this.lblInstantCount.setText(Integer.toString(instants)); - this.lblEnchantmentCount.setText(Integer.toString(enchantments)); - this.lblArtifactCount.setText(Integer.toString(artifacts)); + if (this.lblCount != null) + this.lblCount.setText(Integer.toString(count)); + if (this.lblCreatureCount != null) + this.lblCreatureCount.setText(Integer.toString(creatures)); + if (this.lblLandCount != null) + this.lblLandCount.setText(Integer.toString(lands)); + if (this.lblSorceryCount != null) + this.lblSorceryCount.setText(Integer.toString(sorceries)); + if (this.lblInstantCount != null) + this.lblInstantCount.setText(Integer.toString(instants)); + if (this.lblEnchantmentCount != null) + this.lblEnchantmentCount.setText(Integer.toString(enchantments)); + if (this.lblArtifactCount != null) + this.lblArtifactCount.setText(Integer.toString(artifacts)); } } diff --git a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form index 738a431c487..4cf0b3303cc 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form +++ b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form @@ -31,7 +31,11 @@ - + + + + + @@ -146,7 +150,7 @@ - + @@ -3945,7 +3949,7 @@ - + @@ -4147,11 +4151,12 @@ - + - - + + + @@ -4160,11 +4165,13 @@ + + - + @@ -4189,36 +4196,41 @@ - + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - + + + + + + + + - - + - + @@ -4228,14 +4240,13 @@ - - + @@ -4249,7 +4260,6 @@ - @@ -4473,6 +4483,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -5579,7 +5655,7 @@ - + diff --git a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java index 2b5c14bbeb3..74ba0968fa7 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java @@ -118,6 +118,10 @@ public class PreferencesDialog extends javax.swing.JDialog { public static final String KEY_CARD_IMAGES_SAVE_TO_ZIP = "cardImagesSaveToZip"; public static final String KEY_CARD_IMAGES_PREF_LANGUAGE = "cardImagesPreferedImageLaguage"; + public static final String KEY_CARD_RENDERING_FALLBACK = "cardRenderingFallback"; + public static final String KEY_CARD_RENDERING_REMINDER_TEXT = "cardRenderingReminderText"; + public static final String KEY_CARD_RENDERING_SET_SYMBOL = "cardRenderingSetSymbol"; + public static final String KEY_BACKGROUND_IMAGE = "backgroundImage"; public static final String KEY_BATTLEFIELD_IMAGE = "battlefieldImage"; public static final String KEY_BACKGROUND_IMAGE_DEFAULT = "backgroundImagedDefault"; @@ -464,6 +468,10 @@ public class PreferencesDialog extends javax.swing.JDialog { cbUseRandomBattleImage = new javax.swing.JCheckBox(); jLabel14 = new javax.swing.JLabel(); jLabel15 = new javax.swing.JLabel(); + jPanel1 = new javax.swing.JPanel(); + cbCardRenderImageFallback = new javax.swing.JCheckBox(); + cbCardRenderShowReminderText = new javax.swing.JCheckBox(); + cbCardRenderHideSetSymbol = new javax.swing.JCheckBox(); tabSounds = new javax.swing.JPanel(); sounds_clips = new javax.swing.JPanel(); cbEnableGameSounds = new javax.swing.JCheckBox(); @@ -1385,7 +1393,7 @@ public class PreferencesDialog extends javax.swing.JDialog { .add(jLabelEndOfTurn) .add(checkBoxEndTurnOthers)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) - .add(phases_stopSettings, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 260, Short.MAX_VALUE) + .add(phases_stopSettings, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 266, Short.MAX_VALUE) .addContainerGap()) ); @@ -1439,41 +1447,43 @@ public class PreferencesDialog extends javax.swing.JDialog { .add(panelCardImagesLayout.createSequentialGroup() .add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(panelCardImagesLayout.createSequentialGroup() - .add(24, 24, 24) + .addContainerGap() .add(txtImageFolderPath) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(btnBrowseImageLocation)) .add(panelCardImagesLayout.createSequentialGroup() - .add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING, false) - .add(org.jdesktop.layout.GroupLayout.LEADING, panelCardImagesLayout.createSequentialGroup() - .addContainerGap() - .add(labelNumberOfDownloadThreads) - .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) - .add(cbNumberOfDownloadThreads, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 153, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) - .add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) - .add(cbUseDefaultImageFolder) - .add(cbCheckForNewImages) + .add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING, false) .add(panelCardImagesLayout.createSequentialGroup() - .add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING, false) - .add(org.jdesktop.layout.GroupLayout.LEADING, panelCardImagesLayout.createSequentialGroup() - .addContainerGap() - .add(labelPreferedImageLanguage)) - .add(org.jdesktop.layout.GroupLayout.LEADING, cbSaveToZipFiles)) - .add(40, 40, 40) - .add(cbPreferedImageLanguage, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 153, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))) - .add(0, 251, Short.MAX_VALUE))) + .add(cbCheckForNewImages) + .add(147, 147, 147)) + .add(org.jdesktop.layout.GroupLayout.LEADING, panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING) + .add(panelCardImagesLayout.createSequentialGroup() + .add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING, false) + .add(org.jdesktop.layout.GroupLayout.LEADING, panelCardImagesLayout.createSequentialGroup() + .addContainerGap() + .add(labelPreferedImageLanguage)) + .add(org.jdesktop.layout.GroupLayout.LEADING, cbSaveToZipFiles)) + .add(20, 20, 20) + .add(cbPreferedImageLanguage, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 153, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .add(panelCardImagesLayout.createSequentialGroup() + .addContainerGap() + .add(labelNumberOfDownloadThreads) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(cbNumberOfDownloadThreads, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 153, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))) + .add(cbUseDefaultImageFolder)) + .add(0, 231, Short.MAX_VALUE))) .addContainerGap()) ); panelCardImagesLayout.setVerticalGroup( panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(panelCardImagesLayout.createSequentialGroup() - .addContainerGap() .add(cbUseDefaultImageFolder) .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) .add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(txtImageFolderPath, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(btnBrowseImageLocation)) - .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .add(cbCheckForNewImages) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(cbSaveToZipFiles) @@ -1484,8 +1494,7 @@ public class PreferencesDialog extends javax.swing.JDialog { .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(panelCardImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(cbPreferedImageLanguage, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) - .add(labelPreferedImageLanguage)) - .addContainerGap(48, Short.MAX_VALUE)) + .add(labelPreferedImageLanguage))) ); panelBackgroundImages.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Background images setting:")); @@ -1592,6 +1601,51 @@ public class PreferencesDialog extends javax.swing.JDialog { .add(jLabel15))) ); + jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Card rendering:")); + + cbCardRenderImageFallback.setText("Fall back to plain image based rendering"); + cbCardRenderImageFallback.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + cbCardRenderImageFallbackActionPerformed(evt); + } + }); + + cbCardRenderShowReminderText.setText("Show reminder text in rendered card textboxes"); + cbCardRenderShowReminderText.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + cbCardRenderShowReminderTextActionPerformed(evt); + } + }); + + cbCardRenderHideSetSymbol.setText("Hide set symbols on cards (more space on the type line for card types)"); + cbCardRenderHideSetSymbol.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + cbCardRenderHideSetSymbolActionPerformed(evt); + } + }); + + org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(jPanel1Layout.createSequentialGroup() + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(cbCardRenderImageFallback) + .add(cbCardRenderShowReminderText) + .add(cbCardRenderHideSetSymbol)) + .add(0, 0, Short.MAX_VALUE)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(jPanel1Layout.createSequentialGroup() + .add(cbCardRenderImageFallback) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(cbCardRenderShowReminderText) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(cbCardRenderHideSetSymbol) + .add(0, 0, Short.MAX_VALUE)) + ); + org.jdesktop.layout.GroupLayout tabImagesLayout = new org.jdesktop.layout.GroupLayout(tabImages); tabImages.setLayout(tabImagesLayout); tabImagesLayout.setHorizontalGroup( @@ -1600,6 +1654,7 @@ public class PreferencesDialog extends javax.swing.JDialog { .addContainerGap() .add(tabImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(panelCardImages, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .add(jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .add(panelBackgroundImages, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) ); @@ -1607,10 +1662,12 @@ public class PreferencesDialog extends javax.swing.JDialog { tabImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(tabImagesLayout.createSequentialGroup() .addContainerGap() + .add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(panelCardImages, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(panelBackgroundImages, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) - .addContainerGap(90, Short.MAX_VALUE)) + .addContainerGap(53, Short.MAX_VALUE)) ); tabsPanel.addTab("Images", tabImages); @@ -2220,7 +2277,7 @@ public class PreferencesDialog extends javax.swing.JDialog { .add(connection_serversLayout.createSequentialGroup() .add(141, 141, 141) .add(jLabel17))) - .addContainerGap(111, Short.MAX_VALUE)) + .addContainerGap(91, Short.MAX_VALUE)) ); connection_serversLayout.setVerticalGroup( connection_serversLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) @@ -2406,7 +2463,10 @@ public class PreferencesDialog extends javax.swing.JDialog { .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(exitButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 100, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(6, 6, 6)) - .add(tabsPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .add(tabsPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) @@ -2534,6 +2594,11 @@ public class PreferencesDialog extends javax.swing.JDialog { save(prefs, dialog.cbUseDefaultBattleImage, KEY_BATTLEFIELD_IMAGE_DEFAULT, "true", "false", UPDATE_CACHE_POLICY); save(prefs, dialog.cbUseRandomBattleImage, KEY_BATTLEFIELD_IMAGE_RANDOM, "true", "false", UPDATE_CACHE_POLICY); + // rendering + save(prefs, dialog.cbCardRenderImageFallback, KEY_CARD_RENDERING_FALLBACK, "true", "false", UPDATE_CACHE_POLICY); + save(prefs, dialog.cbCardRenderHideSetSymbol, KEY_CARD_RENDERING_SET_SYMBOL, "true", "false", UPDATE_CACHE_POLICY); + save(prefs, dialog.cbCardRenderShowReminderText, KEY_CARD_RENDERING_REMINDER_TEXT, "true", "false", UPDATE_CACHE_POLICY); + // sounds save(prefs, dialog.cbEnableGameSounds, KEY_SOUNDS_GAME_ON, "true", "false", UPDATE_CACHE_POLICY); save(prefs, dialog.cbEnableDraftSounds, KEY_SOUNDS_DRAFT_ON, "true", "false", UPDATE_CACHE_POLICY); @@ -2806,6 +2871,14 @@ public class PreferencesDialog extends javax.swing.JDialog { // TODO add your handling code here: }//GEN-LAST:event_cbAutoOrderTriggerActionPerformed + private void cbCardRenderImageFallbackActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbCardRenderImageFallbackActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_cbCardRenderImageFallbackActionPerformed + + private void cbCardRenderShowReminderTextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbCardRenderShowReminderTextActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_cbCardRenderShowReminderTextActionPerformed + private void cbSaveToZipFilesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbSaveToZipFilesActionPerformed // TODO add your handling code here: }//GEN-LAST:event_cbSaveToZipFilesActionPerformed @@ -2831,6 +2904,10 @@ public class PreferencesDialog extends javax.swing.JDialog { } }//GEN-LAST:event_cbUseDefaultImageFolderActionPerformed + private void cbCardRenderHideSetSymbolActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbCardRenderHideSetSymbolActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_cbCardRenderHideSetSymbolActionPerformed + private void showProxySettings() { Connection.ProxyType proxyType = (Connection.ProxyType) cbProxyType.getSelectedItem(); switch (proxyType) { @@ -3004,6 +3081,11 @@ public class PreferencesDialog extends javax.swing.JDialog { dialog.cbNumberOfDownloadThreads.setSelectedItem(MageFrame.getPreferences().get(KEY_CARD_IMAGES_THREADS, "10")); dialog.cbPreferedImageLanguage.setSelectedItem(MageFrame.getPreferences().get(KEY_CARD_IMAGES_PREF_LANGUAGE, "en")); + // rendering settings + load(prefs, dialog.cbCardRenderImageFallback, KEY_CARD_RENDERING_FALLBACK, "true"); + load(prefs, dialog.cbCardRenderHideSetSymbol, KEY_CARD_RENDERING_SET_SYMBOL, "true"); + load(prefs, dialog.cbCardRenderShowReminderText, KEY_CARD_RENDERING_REMINDER_TEXT, "true"); + //add background load precedure prop = prefs.get(KEY_BACKGROUND_IMAGE_DEFAULT, "true"); if (prop.equals("true")) { @@ -3384,6 +3466,9 @@ public class PreferencesDialog extends javax.swing.JDialog { private javax.swing.JCheckBox cbAllowRequestToShowHandCards; private javax.swing.JCheckBox cbAskMoveToGraveOrder; private javax.swing.JCheckBox cbAutoOrderTrigger; + private javax.swing.JCheckBox cbCardRenderHideSetSymbol; + private javax.swing.JCheckBox cbCardRenderImageFallback; + private javax.swing.JCheckBox cbCardRenderShowReminderText; private javax.swing.JCheckBox cbCheckForNewImages; private javax.swing.JCheckBox cbConfirmEmptyManaPool; private javax.swing.JCheckBox cbDraftLogAutoSave; @@ -3443,6 +3528,7 @@ public class PreferencesDialog extends javax.swing.JDialog { private javax.swing.JLabel jLabelOpponentsTurn; private javax.swing.JLabel jLabelUpkeep; private javax.swing.JLabel jLabelYourTurn; + private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel10; private javax.swing.JPanel jPanel11; private javax.swing.JPanel jPanel12; diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/Animation.java b/Mage.Client/src/main/java/org/mage/card/arcane/Animation.java index 67e17540ea7..ea69e5cc6e1 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/Animation.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/Animation.java @@ -159,7 +159,7 @@ public abstract class Animation { public static void transformCard(final CardPanel panel, final MagePermanent parent, final boolean transformed) { - new Animation(1200) { + new Animation(600) { private boolean state = false; @Override @@ -256,7 +256,7 @@ public abstract class Animation { public void run() { if (placeholder != null) { placeholder.setDisplayEnabled(true); - placeholder.setImage(animationPanel); + placeholder.transferResources(animationPanel); } animationPanel.setVisible(false); animationPanel.repaint(); @@ -303,7 +303,7 @@ public abstract class Animation { public void run() { if (placeholder != null) { placeholder.setDisplayEnabled(true); - placeholder.setImage(animationPanel); + placeholder.transferResources(animationPanel); } animationPanel.setVisible(false); animationPanel.repaint(); diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java index 94fd559cc53..72f4afc1cdf 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java @@ -1,17 +1,12 @@ package org.mage.card.arcane; -import com.google.common.base.Function; -import com.google.common.collect.MapMaker; -import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Dimension; -import java.awt.Font; +import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.Graphics2D; -import java.awt.Image; import java.awt.Point; import java.awt.Rectangle; -import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentEvent; @@ -22,44 +17,30 @@ import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.awt.image.BufferedImage; -import java.io.File; import java.util.ArrayList; import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; import java.util.UUID; -import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; import javax.swing.ImageIcon; import javax.swing.JButton; -import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPopupMenu; import mage.cards.MagePermanent; import mage.cards.TextPopup; import mage.cards.action.ActionCallback; import mage.cards.action.TransferData; -import mage.client.dialog.PreferencesDialog; +import mage.client.components.layout.RelativeLayout; import mage.client.plugins.adapters.MageActionCallback; import mage.client.plugins.impl.Plugins; -import mage.client.util.ImageCaches; -import mage.client.util.ImageHelper; import mage.client.util.audio.AudioManager; -import mage.components.ImagePanel; -import mage.constants.AbilityType; import mage.constants.CardType; import mage.constants.EnlargeMode; -import mage.utils.CardUtil; import mage.view.AbilityView; import mage.view.CardView; -import mage.view.CounterView; import mage.view.PermanentView; import mage.view.StackAbilityView; -import net.java.truevfs.access.TFile; import org.apache.log4j.Logger; -import org.jdesktop.swingx.graphics.GraphicsUtilities; -import static org.mage.plugins.card.constants.Constants.THUMBNAIL_SIZE_FULL; -import org.mage.plugins.card.dl.sources.DirectLinksForDownload; -import org.mage.plugins.card.images.ImageCache; import org.mage.plugins.card.utils.impl.ImageManagerImpl; /** @@ -68,26 +49,19 @@ import org.mage.plugins.card.utils.impl.ImageManagerImpl; * @author arcane, nantuko, noxx */ @SuppressWarnings({"unchecked", "rawtypes"}) -public class CardPanel extends MagePermanent implements MouseListener, MouseMotionListener, MouseWheelListener, ComponentListener { +public abstract class CardPanel extends MagePermanent implements MouseListener, MouseMotionListener, MouseWheelListener, ComponentListener { private static final long serialVersionUID = -3272134219262184410L; private static final Logger LOGGER = Logger.getLogger(CardPanel.class); - private static final int WIDTH_LIMIT = 90; // card width limit to create smaller counter public static final double TAPPED_ANGLE = Math.PI / 2; public static final double FLIPPED_ANGLE = Math.PI; public static final float ASPECT_RATIO = 3.5f / 2.5f; public static final int POPUP_X_GAP = 1; // prevent tooltip window from blinking - public static CardPanel dragAnimationPanel; - public static final Rectangle CARD_SIZE_FULL = new Rectangle(101, 149); - private static final float ROUNDED_CORNER_SIZE = 0.1f; - private static final float BLACK_BORDER_SIZE = 0.03f; - private static final int TEXT_GLOW_SIZE = 6; - private static final float TEXT_GLOW_INTENSITY = 3f; private static final float ROT_CENTER_TO_TOP_CORNER = 1.0295630140987000315797369464196f; private static final float ROT_CENTER_TO_BOTTOM_CORNER = 0.7071067811865475244008443621048f; @@ -96,52 +70,30 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti // for two faced cards public CardView temporary; - private List links = new ArrayList<>(); public double tappedAngle = 0; public double flippedAngle = 0; - public final ScaledImagePanel imagePanel; - public ImagePanel overlayPanel; + private final List links = new ArrayList<>(); + public JPanel buttonPanel; private JButton dayNightButton; - - public JPanel copyIconPanel; private JButton showCopySourceButton; - public JPanel iconPanel; - private JButton typeButton; - - public JPanel counterPanel; - private JLabel loyaltyCounterLabel; - private JLabel plusCounterLabel; - private JLabel otherCounterLabel; - private JLabel minusCounterLabel; - private int loyaltyCounter; - private int plusCounter; - private int otherCounter; - private int minusCounter; - private int lastCardWidth; - - private GlowText titleText; - private GlowText ptText; private boolean displayEnabled = true; private boolean isAnimationPanel; - public int cardXOffset, cardYOffset, cardWidth, cardHeight; + private int cardXOffset, cardYOffset, cardWidth, cardHeight; private int symbolWidth; private boolean isSelected; - private boolean isPlayable; private boolean isChoosable; - private boolean canAttack; private boolean showCastingCost; - private boolean hasImage = false; private float alpha = 1.0f; private ActionCallback callback; protected boolean tooltipShowing; - protected TextPopup tooltipText = new TextPopup(); + protected TextPopup tooltipText; protected UUID gameId; private TransferData data = new TransferData(); @@ -154,8 +106,6 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti private boolean transformed; private boolean animationInProgress = false; - private boolean displayTitleAnyway; - private JPanel cardArea; private int yTextOffset = 10; @@ -163,142 +113,36 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti // if this is set, it's opened if the user right clicks on the card panel private JPopupMenu popupMenu; - private static Map IMAGE_CACHE; - - private final static class Key { - - final int width; - final int height; - final int cardWidth; - final int cardHeight; - final int cardXOffset; - final int cardYOffset; - final boolean hasImage; - final boolean isSelected; - final boolean isChoosable; - final boolean isPlayable; - final boolean canAttack; - - public Key(int width, int height, int cardWidth, int cardHeight, int cardXOffset, int cardYOffset, boolean hasImage, boolean isSelected, boolean isChoosable, boolean isPlayable, boolean canAttack) { - this.width = width; - this.height = height; - this.cardWidth = cardWidth; - this.cardHeight = cardHeight; - this.cardXOffset = cardXOffset; - this.cardYOffset = cardYOffset; - this.hasImage = hasImage; - this.isSelected = isSelected; - this.isChoosable = isChoosable; - this.isPlayable = isPlayable; - this.canAttack = canAttack; - } - - @Override - public int hashCode() { - int hash = 3; - hash = 19 * hash + this.width; - hash = 19 * hash + this.height; - hash = 19 * hash + this.cardWidth; - hash = 19 * hash + this.cardHeight; - hash = 19 * hash + this.cardXOffset; - hash = 19 * hash + this.cardYOffset; - hash = 19 * hash + (this.hasImage ? 1 : 0); - hash = 19 * hash + (this.isSelected ? 1 : 0); - hash = 19 * hash + (this.isChoosable ? 1 : 0); - hash = 19 * hash + (this.isPlayable ? 1 : 0); - hash = 19 * hash + (this.canAttack ? 1 : 0); - return hash; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final Key other = (Key) obj; - if (this.width != other.width) { - return false; - } - if (this.height != other.height) { - return false; - } - if (this.cardWidth != other.cardWidth) { - return false; - } - if (this.cardHeight != other.cardHeight) { - return false; - } - if (this.cardXOffset != other.cardXOffset) { - return false; - } - if (this.cardYOffset != other.cardYOffset) { - return false; - } - if (this.hasImage != other.hasImage) { - return false; - } - if (this.isSelected != other.isSelected) { - return false; - } - if (this.isChoosable != other.isChoosable) { - return false; - } - if (this.isPlayable != other.isPlayable) { - return false; - } - if (this.canAttack != other.canAttack) { - return false; - } - return true; - } - } - - static { - IMAGE_CACHE = ImageCaches.register(new MapMaker().softValues().makeComputingMap(new Function() { - @Override - public BufferedImage apply(Key key) { - return createImage(key); - } - })); - } - public CardPanel(CardView newGameCard, UUID gameId, final boolean loadImage, ActionCallback callback, final boolean foil, Dimension dimension) { + // Store away params this.gameCard = newGameCard; this.callback = callback; this.gameId = gameId; - + + // Gather info about the card this.isPermanent = this.gameCard instanceof PermanentView; if (isPermanent) { this.hasSickness = ((PermanentView) this.gameCard).hasSummoningSickness(); } + // Set to requested size this.setCardBounds(0, 0, dimension.width, dimension.height); - - //for container debug (don't remove) - //setBorder(BorderFactory.createLineBorder(Color.green)); + + // Create button panel for Transform and Show Source (copied cards) + buttonPanel = new JPanel(); + buttonPanel.setLayout(null); + buttonPanel.setOpaque(false); + buttonPanel.setVisible(true); + add(buttonPanel); + + // Both card rendering implementations have a transform button if (this.gameCard.canTransform()) { - buttonPanel = new JPanel(); - buttonPanel.setLayout(null); - buttonPanel.setOpaque(false); - add(buttonPanel); - + // Create the day night button dayNightButton = new JButton(""); - dayNightButton.setLocation(2, 2); - dayNightButton.setSize(25, 25); - - buttonPanel.setVisible(true); - + dayNightButton.setSize(32, 32); + dayNightButton.setToolTipText("This permanent is a double faced card. To see the back face card, push this button or turn mouse wheel down while hovering with the mouse pointer over the permanent."); BufferedImage day = ImageManagerImpl.getInstance().getDayImage(); dayNightButton.setIcon(new ImageIcon(day)); - - buttonPanel.add(dayNightButton); - dayNightButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -311,60 +155,19 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti Animation.transformCard(CardPanel.this, CardPanel.this, true); } }); - } - if (!newGameCard.isAbility()) { - // panel to show counters on the card - counterPanel = new JPanel(); - counterPanel.setLayout(null); - counterPanel.setOpaque(false); - add(counterPanel); - - plusCounterLabel = new JLabel(""); - plusCounterLabel.setToolTipText("+1/+1"); - counterPanel.add(plusCounterLabel); - - minusCounterLabel = new JLabel(""); - minusCounterLabel.setToolTipText("-1/-1"); - counterPanel.add(minusCounterLabel); - - loyaltyCounterLabel = new JLabel(""); - loyaltyCounterLabel.setToolTipText("loyalty"); - counterPanel.add(loyaltyCounterLabel); - - otherCounterLabel = new JLabel(""); - counterPanel.add(otherCounterLabel); - - counterPanel.setVisible(false); - } - if (newGameCard.isAbility()) { - if (AbilityType.TRIGGERED.equals(newGameCard.getAbilityType())) { - setTypeIcon(ImageManagerImpl.getInstance().getTriggeredAbilityImage(), "Triggered Ability"); - } else if (AbilityType.ACTIVATED.equals(newGameCard.getAbilityType())) { - setTypeIcon(ImageManagerImpl.getInstance().getActivatedAbilityImage(), "Activated Ability"); - } + + // Add it + buttonPanel.add(dayNightButton); } - if (this.gameCard.isToken()) { - setTypeIcon(ImageManagerImpl.getInstance().getTokenIconImage(), "Token Permanent"); - } - - // icon to inform about permanent is copying something + // Both card rendering implementations have a view copy source button if (this.gameCard instanceof PermanentView) { - copyIconPanel = new JPanel(); - copyIconPanel.setLayout(null); - copyIconPanel.setOpaque(false); - add(copyIconPanel); - + // Create the show source button showCopySourceButton = new JButton(""); - showCopySourceButton.setLocation(2, 2); - showCopySourceButton.setSize(25, 25); - showCopySourceButton.setToolTipText("This permanent is copying a target. To see original image, push this button or turn mouse wheel down while hovering with the mouse pointer over the permanent."); - copyIconPanel.setVisible(((PermanentView) this.gameCard).isCopy()); - + showCopySourceButton.setSize(32, 32); + showCopySourceButton.setToolTipText("This permanent is copying a target. To see original card, push this button or turn mouse wheel down while hovering with the mouse pointer over the permanent."); + showCopySourceButton.setVisible(((PermanentView) this.gameCard).isCopy()); showCopySourceButton.setIcon(new ImageIcon(ImageManagerImpl.getInstance().getCopyInformIconImage())); - - copyIconPanel.add(showCopySourceButton); - showCopySourceButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -372,83 +175,58 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti ((MageActionCallback) callback).enlargeCard(EnlargeMode.COPY); } }); + + // Add it + buttonPanel.add(showCopySourceButton); } + // JPanel setup setBackground(Color.black); setOpaque(false); + // JPanel event listeners addMouseListener(this); addMouseMotionListener(this); addMouseWheelListener(this); addComponentListener(this); - displayTitleAnyway = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_CARD_NAMES, "true").equals("true"); - - titleText = new GlowText(); - setText(gameCard); -// int fontSize = (int) cardHeight / 11; -// titleText.setFont(getFont().deriveFont(Font.BOLD, fontSize)); - titleText.setForeground(Color.white); - titleText.setGlow(Color.black, TEXT_GLOW_SIZE, TEXT_GLOW_INTENSITY); - titleText.setWrap(true); - add(titleText); - - ptText = new GlowText(); - if (CardUtil.isCreature(gameCard)) { - ptText.setText(gameCard.getPower() + "/" + gameCard.getToughness()); - } else if (CardUtil.isPlaneswalker(gameCard)) { - ptText.setText(gameCard.getLoyalty()); - } -// ptText.setFont(getFont().deriveFont(Font.BOLD, fontSize)); - ptText.setForeground(Color.white); - ptText.setGlow(Color.black, TEXT_GLOW_SIZE, TEXT_GLOW_INTENSITY); - add(ptText); - - BufferedImage sickness = ImageManagerImpl.getInstance().getSicknessImage(); - overlayPanel = new ImagePanel(sickness, ImagePanel.SCALED); - overlayPanel.setOpaque(false); - add(overlayPanel); - - imagePanel = new ScaledImagePanel(); - imagePanel.setBorder(BorderFactory.createLineBorder(Color.white)); - add(imagePanel); - + // Tooltip for card details hover String cardType = getType(newGameCard); + tooltipText = new TextPopup(); tooltipText.setText(getText(cardType, newGameCard)); + // Animation setup tappedAngle = isTapped() ? CardPanel.TAPPED_ANGLE : 0; flippedAngle = isFlipped() ? CardPanel.FLIPPED_ANGLE : 0; - - if (!loadImage) { - return; + } + + @Override + public void doLayout() { + // Position transform and show source buttons + buttonPanel.setLocation(cardXOffset, cardYOffset); + buttonPanel.setSize(cardWidth, cardHeight); + int x = cardWidth/20; + int y = cardHeight/10; + if (dayNightButton != null) { + dayNightButton.setLocation(x, y); + y += 25; + y += 5; } - + if (showCopySourceButton != null) { + showCopySourceButton.setLocation(x, y); + } + } + + public final void initialDraw() { + // Kick off if (gameCard.isTransformed()) { // this calls updateImage toggleTransformed(); } else { - updateImage(); + updateArtImage(); } } - private void setTypeIcon(BufferedImage bufferedImage, String toolTipText) { - iconPanel = new JPanel(); - iconPanel.setLayout(null); - iconPanel.setOpaque(false); - add(iconPanel); - - typeButton = new JButton(""); - typeButton.setLocation(2, 2); - typeButton.setSize(25, 25); - - iconPanel.setVisible(true); - typeButton.setIcon(new ImageIcon(bufferedImage)); - if (toolTipText != null) { - typeButton.setToolTipText(toolTipText); - } - iconPanel.add(typeButton); - } - public void cleanUp() { if (dayNightButton != null) { for (ActionListener al : dayNightButton.getActionListeners()) { @@ -467,32 +245,12 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti // this holds reference to ActionCallback forever so set it to null to prevent this.callback = null; this.data = null; - this.counterPanel = null; - } - - private void setText(CardView card) { - titleText.setText(!displayTitleAnyway && hasImage ? "" : card.getName()); - } - - private void setImage(BufferedImage srcImage) { - synchronized (imagePanel) { - if (srcImage != null) { - imagePanel.setImage(srcImage); - } else { - imagePanel.clearImage(); - } - repaint(); - } - doLayout(); - } - - public void setImage(final CardPanel panel) { - synchronized (panel.imagePanel) { - if (panel.imagePanel.hasImage()) { - setImage(panel.imagePanel.getSrcImage()); - } - } } + + // Copy the graphical resources of another CardPanel over to this one, + // if possible (may not be possible if they have different implementations) + // Used when cards are moving between zones + public abstract void transferResources(CardPanel panel); @Override public void setZone(String zone) { @@ -515,36 +273,59 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti public void setAnimationPanel(boolean isAnimationPanel) { this.isAnimationPanel = isAnimationPanel; } + + public boolean isAnimationPanel() { + return this.isAnimationPanel; + } @Override public void setSelected(boolean isSelected) { this.isSelected = isSelected; - if (isSelected) { - this.titleText.setGlowColor(Color.green); - } else { - this.titleText.setGlowColor(Color.black); - } - // noxx: bad idea is to call repaint in setter method - ////repaint(); + } + + public boolean isSelected() { + return this.isSelected; } + @Override + public List getLinks() { + return links; + } + @Override public void setChoosable(boolean isChoosable) { this.isChoosable = isChoosable; } + + public boolean isChoosable() { + return this.isChoosable; + } + + public boolean hasSickness() { + return this.hasSickness; + } + public boolean isPermanent() { + return this.isPermanent; + } + @Override public void setCardAreaRef(JPanel cardArea) { this.cardArea = cardArea; } - public boolean getSelected() { - return this.isSelected; - } - public void setShowCastingCost(boolean showCastingCost) { this.showCastingCost = showCastingCost; } + + public boolean getShowCastingCost() { + return this.showCastingCost; + } + + /** + * Overridden by different card rendering styles + */ + protected abstract void paintCard(Graphics2D g); @Override public void paint(Graphics g) { @@ -573,169 +354,25 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti protected void paintComponent(Graphics g) { Graphics2D g2d = (Graphics2D) (g.create()); - if (alpha != 1.0f) { - AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha); - g2d.setComposite(composite); - } - - g2d.drawImage(IMAGE_CACHE.get(new Key(getWidth(), getHeight(), cardWidth, cardHeight, cardXOffset, cardYOffset, hasImage, isSelected, isChoosable, isPlayable, canAttack)), 0, 0, null); + // Deferr to subclasses + paintCard(g2d); + + // Done, dispose of the context g2d.dispose(); } - private static BufferedImage createImage(Key key) { - int cardWidth = key.cardWidth; - int cardHeight = key.cardHeight; - int cardXOffset = key.cardXOffset; - int cardYOffset = key.cardYOffset; - - BufferedImage image = GraphicsUtilities.createCompatibleTranslucentImage(key.width, key.height); - Graphics2D g2d = image.createGraphics(); - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - - if (!key.hasImage) { - g2d.setColor(new Color(30, 200, 200, 120)); - } else { - g2d.setColor(new Color(0, 0, 0, 0)); - } - - int cornerSize = Math.max(4, Math.round(cardWidth * ROUNDED_CORNER_SIZE)); - g2d.fillRoundRect(cardXOffset, cardYOffset, cardWidth, cardHeight, cornerSize, cornerSize); - - if (key.isSelected) { - g2d.setColor(Color.green); - g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize); - } else if (key.isChoosable) { - g2d.setColor(new Color(250, 250, 0, 230)); - g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize); - } else if (key.isPlayable) { - g2d.setColor(new Color(153, 102, 204, 200)); - //g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize); - g2d.fillRoundRect(cardXOffset, cardYOffset, cardWidth, cardHeight, cornerSize, cornerSize); - } - - if (key.canAttack) { - g2d.setColor(new Color(0, 0, 255, 230)); - g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize); - } - - //TODO:uncomment - /* - if (gameCard.isAttacking()) { - g2d.setColor(new Color(200,10,10,200)); - g2d.fillRoundRect(cardXOffset+1, cardYOffset+1, cardWidth-2, cardHeight-2, cornerSize, cornerSize); - }*/ - g2d.dispose(); - - return image; - } - - @Override - protected void paintChildren(Graphics g) { - super.paintChildren(g); - - if (showCastingCost && !isAnimationPanel && cardWidth < 200 && cardWidth > 60) { - String manaCost = ManaSymbols.getStringManaCost(gameCard.getManaCost()); - int width = getWidth(manaCost); - if (hasImage) { - ManaSymbols.draw(g, manaCost, cardXOffset + cardWidth - width - 5, cardYOffset + 5, symbolWidth); - } else { - ManaSymbols.draw(g, manaCost, cardXOffset + 8, cardHeight - 9, symbolWidth); - } - } - } - - private int getWidth(String manaCost) { - int width = 0; - manaCost = manaCost.replace("\\", ""); - StringTokenizer tok = new StringTokenizer(manaCost, " "); - while (tok.hasMoreTokens()) { - tok.nextToken(); - width += symbolWidth; - } - return width; - } - - @Override - public void doLayout() { - int borderSize = Math.round(cardWidth * BLACK_BORDER_SIZE); - imagePanel.setLocation(cardXOffset + borderSize, cardYOffset + borderSize); - imagePanel.setSize(cardWidth - borderSize * 2, cardHeight - borderSize * 2); - - if (hasSickness && CardUtil.isCreature(gameCard) && isPermanent) { - overlayPanel.setLocation(cardXOffset + borderSize, cardYOffset + borderSize); - overlayPanel.setSize(cardWidth - borderSize * 2, cardHeight - borderSize * 2); - } else { - overlayPanel.setVisible(false); - } - - if (buttonPanel != null) { - buttonPanel.setLocation(cardXOffset + borderSize, cardYOffset + borderSize); - buttonPanel.setSize(cardWidth - borderSize * 2, cardHeight - borderSize * 2); - dayNightButton.setLocation(0, cardHeight - 30); - } - if (iconPanel != null) { - iconPanel.setLocation(cardXOffset + borderSize, cardYOffset + borderSize); - iconPanel.setSize(cardWidth - borderSize * 2, cardHeight - borderSize * 2); - } - if (copyIconPanel != null) { - copyIconPanel.setLocation(cardXOffset + borderSize, cardYOffset + borderSize); - copyIconPanel.setSize(cardWidth - borderSize * 2, cardHeight - borderSize * 2); - } - if (counterPanel != null) { - counterPanel.setLocation(cardXOffset + borderSize, cardYOffset + borderSize); - counterPanel.setSize(cardWidth - borderSize * 2, cardHeight - borderSize * 2); - int size = cardWidth > WIDTH_LIMIT ? 40 : 20; - - minusCounterLabel.setLocation(counterPanel.getWidth() - size, counterPanel.getHeight() - size * 2); - minusCounterLabel.setSize(size, size); - - plusCounterLabel.setLocation(5, counterPanel.getHeight() - size * 2); - plusCounterLabel.setSize(size, size); - - loyaltyCounterLabel.setLocation(counterPanel.getWidth() - size, counterPanel.getHeight() - size); - loyaltyCounterLabel.setSize(size, size); - - otherCounterLabel.setLocation(5, counterPanel.getHeight() - size); - otherCounterLabel.setSize(size, size); - - } - int fontHeight = Math.round(cardHeight * (27f / 680)); - boolean showText = (!isAnimationPanel && fontHeight < 12); - titleText.setVisible(showText); - ptText.setVisible(showText); - - if (showText) { - int fontSize = (int) cardHeight / 11; - titleText.setFont(getFont().deriveFont(Font.BOLD, fontSize)); - - int titleX = Math.round(cardWidth * (20f / 480)); - int titleY = Math.round(cardHeight * (9f / 680)) + yTextOffset; - titleText.setBounds(cardXOffset + titleX, cardYOffset + titleY, cardWidth - titleX, cardHeight - titleY); - - ptText.setFont(getFont().deriveFont(Font.BOLD, fontSize)); - Dimension ptSize = ptText.getPreferredSize(); - ptText.setSize(ptSize.width, ptSize.height); - int ptX = Math.round(cardWidth * (420f / 480)) - ptSize.width / 2; - int ptY = Math.round(cardHeight * (675f / 680)) - ptSize.height; - - int offsetX = Math.round((CARD_SIZE_FULL.width - cardWidth) / 10.0f); - - ptText.setLocation(cardXOffset + ptX - TEXT_GLOW_SIZE / 2 - offsetX, cardYOffset + ptY - TEXT_GLOW_SIZE / 2); - } - } - @Override public String toString() { return gameCard.toString(); } @Override - public final void setCardBounds(int x, int y, int cardWidth, int cardHeight) { + public void setCardBounds(int x, int y, int cardWidth, int cardHeight) { if (cardWidth == this.cardWidth && cardHeight == this.cardHeight) { setBounds(x - cardXOffset, y - cardYOffset, getWidth(), getHeight()); return; } - + this.cardWidth = cardWidth; this.symbolWidth = cardWidth / 7; this.cardHeight = cardHeight; @@ -752,15 +389,12 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti int height = -yOffset + rotCenterY + rotCenterToBottomCorner; setBounds(x + xOffset, y + yOffset, width, height); } else { - cardXOffset = 5; - cardYOffset = 5; + cardXOffset = 0; + cardYOffset = 0; int width = cardXOffset * 2 + cardWidth; int height = cardYOffset * 2 + cardHeight; setBounds(x - cardXOffset, y - cardYOffset, width, height); } - if (imagePanel != null && imagePanel.getSrcImage() != null) { - updateImage(); - } } public int getXOffset(int cardWidth) { @@ -774,7 +408,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti } } - public int getYOffset(int cardWidth, int cardHeight) { + public final int getYOffset(int cardWidth, int cardHeight) { if (this.isPermanent) { int rotCenterX = Math.round(cardWidth / 2f); int rotCenterY = cardHeight - rotCenterX; @@ -787,120 +421,57 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti } - public int getCardX() { + public final int getCardX() { return getX() + cardXOffset; } - public int getCardY() { + public final int getCardY() { return getY() + cardYOffset; } - public int getCardWidth() { + public final int getCardWidth() { return cardWidth; } - public int getCardHeight() { + public final int getCardHeight() { return cardHeight; } + + public final int getSymbolWidth() { + return symbolWidth; + } - public Point getCardLocation() { + public final Point getCardLocation() { Point p = getLocation(); p.x += cardXOffset; p.y += cardYOffset; return p; } - public CardView getCard() { + public final CardView getCard() { return this.gameCard; } @Override public void setAlpha(float alpha) { this.alpha = alpha; - if (alpha == 0) { - this.ptText.setVisible(false); - this.titleText.setVisible(false); - } else if (alpha == 1.0f) { - this.ptText.setVisible(true); - this.titleText.setVisible(true); - } } @Override - public float getAlpha() { + public final float getAlpha() { return alpha; } - public int getCardXOffset() { + public final int getCardXOffset() { return cardXOffset; } - public int getCardYOffset() { + public final int getCardYOffset() { return cardYOffset; } - private int updateImageStamp; - @Override - public void updateImage() { - tappedAngle = isTapped() ? CardPanel.TAPPED_ANGLE : 0; - flippedAngle = isFlipped() ? CardPanel.FLIPPED_ANGLE : 0; - - //final CardView gameCard = this.gameCard; - final int stamp = ++updateImageStamp; - - Util.threadPool.submit(new Runnable() { - @Override - public void run() { - try { - final BufferedImage srcImage; - if (gameCard.isFaceDown()) { - srcImage = getFaceDownImage(); - } else if (cardWidth > THUMBNAIL_SIZE_FULL.width) { - srcImage = ImageCache.getImage(gameCard, cardWidth, cardHeight); - } else { - srcImage = ImageCache.getThumbnail(gameCard); - } - UI.invokeLater(new Runnable() { - @Override - public void run() { - if (stamp == updateImageStamp) { - hasImage = srcImage != null; - setText(gameCard); - setImage(srcImage); - } - } - }); - } catch (Exception e) { - e.printStackTrace(); - } catch (Error err) { - err.printStackTrace(); - } - } - }); - } - - private BufferedImage getFaceDownImage() { - if (isPermanent) { - if (((PermanentView) gameCard).isMorphed()) { - return ImageCache.getMorphImage(); - } else { - return ImageCache.getManifestImage(); - } - } else if (this.gameCard instanceof StackAbilityView) { - return ImageCache.getMorphImage(); - } else { - return ImageCache.loadImage(new TFile(DirectLinksForDownload.outDir + File.separator + DirectLinksForDownload.cardbackFilename)); - } - } - - @Override - public List getLinks() { - return links; - } - - @Override - public boolean isTapped() { + public final boolean isTapped() { if (isPermanent) { return ((PermanentView) gameCard).isTapped(); } @@ -908,7 +479,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti } @Override - public boolean isFlipped() { + public final boolean isFlipped() { if (isPermanent) { return ((PermanentView) gameCard).isFlipped(); } @@ -916,17 +487,16 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti } @Override - public boolean isTransformed() { + public final boolean isTransformed() { if (isPermanent) { - return gameCard.isTransformed(); + if (gameCard.isTransformed()) { + return !this.transformed; + } else { + return this.transformed; + } + } else { + return this.transformed; } - return false; - } - - @Override - public void showCardTitle() { - displayTitleAnyway = true; - setText(gameCard); } @Override @@ -939,9 +509,17 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti animationInProgress = false; } + /** + * Inheriting classes should implement update(CardView card) by + * using this. However, they should ALSO call repaint() after the superclass + * call to this function, that can't be done here as the overriders may need + * to do things both before and after this call before repainting. + */ @Override public void update(CardView card) { this.updateCard = card; + + // Animation update if (isPermanent && (card instanceof PermanentView)) { boolean needsTapping = isTapped() != ((PermanentView) card).isTapped(); boolean needsFlipping = isFlipped() != ((PermanentView) card).isFlipped(); @@ -956,140 +534,39 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti Animation.transformCard(this, this, card.isTransformed()); } } - if (card.canTransform()) { - dayNightButton.setVisible(!isPermanent); - } - if (CardUtil.isCreature(card) && CardUtil.isPlaneswalker(card)) { - ptText.setText(card.getPower() + "/" + card.getToughness() + " (" + card.getLoyalty() + ")"); - } else if (CardUtil.isCreature(card)) { - ptText.setText(card.getPower() + "/" + card.getToughness()); - } else if (CardUtil.isPlaneswalker(card)) { - ptText.setText(card.getLoyalty()); - } else { - ptText.setText(""); - } - setText(card); - - this.isPlayable = card.isPlayable(); + // Update panel attributes this.isChoosable = card.isChoosable(); - this.canAttack = card.isCanAttack(); this.isSelected = card.isSelected(); + + // Update art? + boolean mustUpdateArt = + (!gameCard.getName().equals(card.getName())) || + (gameCard.isFaceDown() != card.isFaceDown()); - boolean updateImage = !gameCard.getName().equals(card.getName()) || gameCard.isFaceDown() != card.isFaceDown(); // update after e.g. turning a night/day card - if (updateImage && gameCard.canTransform() && card.canTransform() && transformed) { - if (card.getSecondCardFace() != null && card.getSecondCardFace().getName().equals(gameCard.getName())) { - transformed = false; - } - } + // Set the new card this.gameCard = card; + // Update tooltip text String cardType = getType(card); tooltipText.setText(getText(cardType, card)); - - if (hasSickness && CardUtil.isCreature(gameCard) && isPermanent) { - overlayPanel.setVisible(true); - } else { - overlayPanel.setVisible(false); + + // Update the image + if (mustUpdateArt) { + updateArtImage(); } - if (updateImage) { - updateImage(); - if (card.canTransform()) { - BufferedImage transformIcon; - if (transformed || card.isTransformed()) { - transformIcon = ImageManagerImpl.getInstance().getNightImage(); - } else { - transformIcon = ImageManagerImpl.getInstance().getDayImage(); - } - dayNightButton.setIcon(new ImageIcon(transformIcon)); + + // Update transform circle + if (card.canTransform()) { + BufferedImage transformIcon; + if (isTransformed() || card.isTransformed()) { + transformIcon = ImageManagerImpl.getInstance().getNightImage(); + } else { + transformIcon = ImageManagerImpl.getInstance().getDayImage(); } + dayNightButton.setVisible(!isPermanent); + dayNightButton.setIcon(new ImageIcon(transformIcon)); } - - if (counterPanel != null) { - updateCounters(card); - } - - repaint(); - } - - private void updateCounters(CardView card) { - if (card.getCounters() != null && !card.getCounters().isEmpty()) { - String name = ""; - if (lastCardWidth != cardWidth) { - lastCardWidth = cardWidth; - plusCounter = 0; - minusCounter = 0; - otherCounter = 0; - loyaltyCounter = 0; - } - plusCounterLabel.setVisible(false); - minusCounterLabel.setVisible(false); - loyaltyCounterLabel.setVisible(false); - otherCounterLabel.setVisible(false); - for (CounterView counterView : card.getCounters()) { - if (counterView.getCount() == 0) { - continue; - } - switch (counterView.getName()) { - case "+1/+1": - if (counterView.getCount() != plusCounter) { - plusCounter = counterView.getCount(); - plusCounterLabel.setIcon(getCounterImageWithAmount(plusCounter, ImageManagerImpl.getInstance().getCounterImageGreen(), cardWidth)); - } - plusCounterLabel.setVisible(true); - break; - case "-1/-1": - if (counterView.getCount() != minusCounter) { - minusCounter = counterView.getCount(); - minusCounterLabel.setIcon(getCounterImageWithAmount(minusCounter, ImageManagerImpl.getInstance().getCounterImageRed(), cardWidth)); - } - minusCounterLabel.setVisible(true); - break; - case "loyalty": - if (counterView.getCount() != loyaltyCounter) { - loyaltyCounter = counterView.getCount(); - loyaltyCounterLabel.setIcon(getCounterImageWithAmount(loyaltyCounter, ImageManagerImpl.getInstance().getCounterImageViolet(), cardWidth)); - } - loyaltyCounterLabel.setVisible(true); - break; - default: - if (name.isEmpty()) { // only first other counter is shown - name = counterView.getName(); - otherCounter = counterView.getCount(); - otherCounterLabel.setToolTipText(name); - otherCounterLabel.setIcon(getCounterImageWithAmount(otherCounter, ImageManagerImpl.getInstance().getCounterImageGrey(), cardWidth)); - otherCounterLabel.setVisible(true); - } - } - } - - counterPanel.setVisible(true); - } else { - plusCounterLabel.setVisible(false); - minusCounterLabel.setVisible(false); - loyaltyCounterLabel.setVisible(false); - otherCounterLabel.setVisible(false); - counterPanel.setVisible(false); - } - - } - - private static ImageIcon getCounterImageWithAmount(int amount, BufferedImage image, int cardWidth) { - int factor = cardWidth > WIDTH_LIMIT ? 2 : 1; - int xOffset = amount > 9 ? 2 : 5; - int fontSize = factor == 1 ? amount < 10 ? 12 : amount < 100 ? 10 : amount < 1000 ? 7 : 6 - : amount < 10 ? 19 : amount < 100 ? 15 : amount < 1000 ? 12 : amount < 10000 ? 9 : 8; - BufferedImage newImage; - if (cardWidth > WIDTH_LIMIT) { - newImage = ImageManagerImpl.deepCopy(image); - } else { - newImage = ImageHelper.getResizedImage(image, 20, 20); - } - Graphics graphics = newImage.getGraphics(); - graphics.setColor(Color.BLACK); - graphics.setFont(new Font("Arial Black", amount > 100 ? Font.PLAIN : Font.BOLD, fontSize)); - graphics.drawString(Integer.toString(amount), xOffset * factor, 11 * factor); - return new ImageIcon(newImage); } @Override @@ -1118,18 +595,6 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti return this.gameCard; } - @Override - public Image getImage() { - if (this.hasImage) { - if (gameCard.isFaceDown()) { - return getFaceDownImage(); - } else { - return ImageCache.getImageOriginal(gameCard); - } - } - return null; - } - @Override public void mouseClicked(MouseEvent e) { } @@ -1276,14 +741,14 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti @Override public void update(PermanentView card) { this.hasSickness = card.hasSummoningSickness(); - this.copyIconPanel.setVisible(card.isCopy()); - update((CardView) card); + this.showCopySourceButton.setVisible(card.isCopy()); + update((CardView)card); } @Override public PermanentView getOriginalPermanent() { if (isPermanent) { - return (PermanentView) this.gameCard; + return (PermanentView)this.gameCard; } throw new IllegalStateException("Is not permanent."); } @@ -1327,7 +792,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti String temp = this.gameCard.getAlternateName(); this.gameCard.setAlternateName(this.gameCard.getOriginalName()); this.gameCard.setOriginalName(temp); - updateImage(); + updateArtImage(); } @Override @@ -1370,6 +835,10 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti public void setTextOffset(int yOffset) { yTextOffset = yOffset; } + + public int getTextOffset() { + return yTextOffset; + } @Override public JPopupMenu getPopupMenu() { diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelAttributes.java b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelAttributes.java new file mode 100644 index 00000000000..9382cb9a526 --- /dev/null +++ b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelAttributes.java @@ -0,0 +1,25 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.mage.card.arcane; + +/** + * @author stravant@gmail.com + * Attributes of a card panel outside of the CardView itself that the renderer + * needs to know in order to render a card. + */ +public class CardPanelAttributes { + public final int cardWidth; + public final int cardHeight; + public final boolean isSelected; + public final boolean isChoosable; + + public CardPanelAttributes(int cardWidth, int cardHeight, boolean isChoosable, boolean isSelected) { + this.cardWidth = cardWidth; + this.cardHeight = cardHeight; + this.isChoosable = isChoosable; + this.isSelected = isSelected; + } +} diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelComponentImpl.java b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelComponentImpl.java new file mode 100644 index 00000000000..549242710ca --- /dev/null +++ b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelComponentImpl.java @@ -0,0 +1,711 @@ +package org.mage.card.arcane; + +import com.google.common.base.Function; +import com.google.common.collect.MapMaker; +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; +import java.io.File; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.UUID; +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import mage.cards.action.ActionCallback; +import mage.client.dialog.PreferencesDialog; +import mage.client.util.ImageCaches; +import mage.client.util.ImageHelper; +import mage.components.ImagePanel; +import mage.constants.AbilityType; +import mage.utils.CardUtil; +import mage.view.CardView; +import mage.view.CounterView; +import mage.view.PermanentView; +import mage.view.StackAbilityView; +import net.java.truevfs.access.TFile; +import org.apache.log4j.Logger; +import org.jdesktop.swingx.graphics.GraphicsUtilities; +import static org.mage.plugins.card.constants.Constants.THUMBNAIL_SIZE_FULL; +import org.mage.plugins.card.dl.sources.DirectLinksForDownload; +import org.mage.plugins.card.images.ImageCache; +import org.mage.plugins.card.utils.impl.ImageManagerImpl; + +/** + * Class for drawing the mage card object by using a form based JComponent approach + * + * @author arcane, nantuko, noxx, stravant + */ +@SuppressWarnings({"unchecked", "rawtypes"}) +public class CardPanelComponentImpl extends CardPanel { + + private static final long serialVersionUID = -3272134219262184411L; + + private static final Logger LOGGER = Logger.getLogger(CardPanelComponentImpl.class); + + private static final int WIDTH_LIMIT = 90; // card width limit to create smaller counter + + private static final float ROUNDED_CORNER_SIZE = 0.1f; + private static final float BLACK_BORDER_SIZE = 0.03f; + private static final int TEXT_GLOW_SIZE = 6; + private static final float TEXT_GLOW_INTENSITY = 3f; + + public final ScaledImagePanel imagePanel; + public ImagePanel overlayPanel; + + public JPanel iconPanel; + private JButton typeButton; + + public JPanel counterPanel; + private JLabel loyaltyCounterLabel; + private JLabel plusCounterLabel; + private JLabel otherCounterLabel; + private JLabel minusCounterLabel; + private int loyaltyCounter; + private int plusCounter; + private int otherCounter; + private int minusCounter; + private int lastCardWidth; + + private final GlowText titleText; + private final GlowText ptText; + + private boolean hasImage = false; + + private boolean displayTitleAnyway; + + private final static Map IMAGE_CACHE; + + class Key { + + final int width; + final int height; + final int cardWidth; + final int cardHeight; + final int cardXOffset; + final int cardYOffset; + final boolean hasImage; + final boolean isSelected; + final boolean isChoosable; + final boolean isPlayable; + final boolean canAttack; + + public Key(int width, int height, int cardWidth, int cardHeight, int cardXOffset, int cardYOffset, boolean hasImage, boolean isSelected, boolean isChoosable, boolean isPlayable, boolean canAttack) { + this.width = width; + this.height = height; + this.cardWidth = cardWidth; + this.cardHeight = cardHeight; + this.cardXOffset = cardXOffset; + this.cardYOffset = cardYOffset; + this.hasImage = hasImage; + this.isSelected = isSelected; + this.isChoosable = isChoosable; + this.isPlayable = isPlayable; + this.canAttack = canAttack; + } + + @Override + public int hashCode() { + int hash = 3; + hash = 19 * hash + this.width; + hash = 19 * hash + this.height; + hash = 19 * hash + this.cardWidth; + hash = 19 * hash + this.cardHeight; + hash = 19 * hash + this.cardXOffset; + hash = 19 * hash + this.cardYOffset; + hash = 19 * hash + (this.hasImage ? 1 : 0); + hash = 19 * hash + (this.isSelected ? 1 : 0); + hash = 19 * hash + (this.isChoosable ? 1 : 0); + hash = 19 * hash + (this.isPlayable ? 1 : 0); + hash = 19 * hash + (this.canAttack ? 1 : 0); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Key other = (Key) obj; + if (this.width != other.width) { + return false; + } + if (this.height != other.height) { + return false; + } + if (this.cardWidth != other.cardWidth) { + return false; + } + if (this.cardHeight != other.cardHeight) { + return false; + } + if (this.cardXOffset != other.cardXOffset) { + return false; + } + if (this.cardYOffset != other.cardYOffset) { + return false; + } + if (this.hasImage != other.hasImage) { + return false; + } + if (this.isSelected != other.isSelected) { + return false; + } + if (this.isChoosable != other.isChoosable) { + return false; + } + if (this.isPlayable != other.isPlayable) { + return false; + } + if (this.canAttack != other.canAttack) { + return false; + } + return true; + } + } + + static { + IMAGE_CACHE = ImageCaches.register(new MapMaker().softValues().makeComputingMap(new Function() { + @Override + public BufferedImage apply(Key key) { + return createImage(key); + } + })); + } + + public CardPanelComponentImpl(CardView newGameCard, UUID gameId, final boolean loadImage, ActionCallback callback, final boolean foil, Dimension dimension) { + // Call to super + super(newGameCard, gameId, loadImage, callback, foil, dimension); + + // Counter panel + if (!newGameCard.isAbility()) { + // panel to show counters on the card + counterPanel = new JPanel(); + counterPanel.setLayout(null); + counterPanel.setOpaque(false); + add(counterPanel); + + plusCounterLabel = new JLabel(""); + plusCounterLabel.setToolTipText("+1/+1"); + counterPanel.add(plusCounterLabel); + + minusCounterLabel = new JLabel(""); + minusCounterLabel.setToolTipText("-1/-1"); + counterPanel.add(minusCounterLabel); + + loyaltyCounterLabel = new JLabel(""); + loyaltyCounterLabel.setToolTipText("loyalty"); + counterPanel.add(loyaltyCounterLabel); + + otherCounterLabel = new JLabel(""); + counterPanel.add(otherCounterLabel); + + counterPanel.setVisible(false); + } + + // Ability icon + if (newGameCard.isAbility()) { + if (AbilityType.TRIGGERED.equals(newGameCard.getAbilityType())) { + setTypeIcon(ImageManagerImpl.getInstance().getTriggeredAbilityImage(), "Triggered Ability"); + } else if (AbilityType.ACTIVATED.equals(newGameCard.getAbilityType())) { + setTypeIcon(ImageManagerImpl.getInstance().getActivatedAbilityImage(), "Activated Ability"); + } + } + + // Token icon + if (this.gameCard.isToken()) { + setTypeIcon(ImageManagerImpl.getInstance().getTokenIconImage(), "Token Permanent"); + } + + displayTitleAnyway = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_CARD_NAMES, "true").equals("true"); + + // Title Text + titleText = new GlowText(); + setText(gameCard); +// int fontSize = (int) cardHeight / 11; +// titleText.setFont(getFont().deriveFont(Font.BOLD, fontSize)); + titleText.setForeground(Color.white); + titleText.setGlow(Color.black, TEXT_GLOW_SIZE, TEXT_GLOW_INTENSITY); + titleText.setWrap(true); + add(titleText); + + // PT Text + ptText = new GlowText(); + if (CardUtil.isCreature(gameCard)) { + ptText.setText(gameCard.getPower() + "/" + gameCard.getToughness()); + } else if (CardUtil.isPlaneswalker(gameCard)) { + ptText.setText(gameCard.getLoyalty()); + } +// ptText.setFont(getFont().deriveFont(Font.BOLD, fontSize)); + ptText.setForeground(Color.white); + ptText.setGlow(Color.black, TEXT_GLOW_SIZE, TEXT_GLOW_INTENSITY); + add(ptText); + + // Sickness overlay + BufferedImage sickness = ImageManagerImpl.getInstance().getSicknessImage(); + overlayPanel = new ImagePanel(sickness, ImagePanel.SCALED); + overlayPanel.setOpaque(false); + add(overlayPanel); + + // Imagel panel + imagePanel = new ScaledImagePanel(); + imagePanel.setBorder(BorderFactory.createLineBorder(Color.white)); + add(imagePanel); + + // Do we need to load? + if (loadImage) { + initialDraw(); + } else { + // Nothing to do + } + } + + private void setTypeIcon(BufferedImage bufferedImage, String toolTipText) { + iconPanel = new JPanel(); + iconPanel.setLayout(null); + iconPanel.setOpaque(false); + add(iconPanel); + + typeButton = new JButton(""); + typeButton.setLocation(2, 2); + typeButton.setSize(25, 25); + + iconPanel.setVisible(true); + typeButton.setIcon(new ImageIcon(bufferedImage)); + if (toolTipText != null) { + typeButton.setToolTipText(toolTipText); + } + iconPanel.add(typeButton); + } + + @Override + public void cleanUp() { + super.cleanUp(); + this.counterPanel = null; + } + + private void setText(CardView card) { + titleText.setText(!displayTitleAnyway && hasImage ? "" : card.getName()); + } + + private void setImage(BufferedImage srcImage) { + synchronized (imagePanel) { + if (srcImage != null) { + imagePanel.setImage(srcImage); + } else { + imagePanel.clearImage(); + } + repaint(); + } + doLayout(); + } + + @Override + public void transferResources(final CardPanel panelAbstract) { + if (panelAbstract instanceof CardPanelComponentImpl) { + CardPanelComponentImpl panel = (CardPanelComponentImpl)panelAbstract; + synchronized (panel.imagePanel) { + if (panel.imagePanel.hasImage()) { + setImage(panel.imagePanel.getSrcImage()); + } + } + } + } + + @Override + public void setSelected(boolean isSelected) { + super.setSelected(isSelected); + if (isSelected) { + this.titleText.setGlowColor(Color.green); + } else { + this.titleText.setGlowColor(Color.black); + } + } + + @Override + protected void paintCard(Graphics2D g2d) { + float alpha = getAlpha(); + if (alpha != 1.0f) { + AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha); + g2d.setComposite(composite); + } + + g2d.drawImage( + IMAGE_CACHE.get( + new Key(getWidth(), getHeight(), getCardWidth(), getCardHeight(), getCardXOffset(), getCardYOffset(), + hasImage, isSelected(), isChoosable(), gameCard.isPlayable(), gameCard.isCanAttack())), + 0, 0, null); + g2d.dispose(); + } + + private static BufferedImage createImage(Key key) { + int cardWidth = key.cardWidth; + int cardHeight = key.cardHeight; + int cardXOffset = key.cardXOffset; + int cardYOffset = key.cardYOffset; + + BufferedImage image = GraphicsUtilities.createCompatibleTranslucentImage(key.width, key.height); + Graphics2D g2d = image.createGraphics(); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + if (!key.hasImage) { + g2d.setColor(new Color(30, 200, 200, 120)); + } else { + g2d.setColor(new Color(0, 0, 0, 255)); + } + + int cornerSize = Math.max(4, Math.round(cardWidth * ROUNDED_CORNER_SIZE)); + g2d.fillRoundRect(cardXOffset, cardYOffset, cardWidth, cardHeight, cornerSize, cornerSize); + + if (key.isSelected) { + g2d.setColor(Color.green); + g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize); + } else if (key.isChoosable) { + g2d.setColor(new Color(250, 250, 0, 230)); + g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize); + } else if (key.isPlayable) { + g2d.setColor(new Color(153, 102, 204, 200)); + //g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize); + g2d.fillRoundRect(cardXOffset, cardYOffset, cardWidth, cardHeight, cornerSize, cornerSize); + } + + if (key.canAttack) { + g2d.setColor(new Color(0, 0, 255, 230)); + g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize); + } + + //TODO:uncomment + /* + if (gameCard.isAttacking()) { + g2d.setColor(new Color(200,10,10,200)); + g2d.fillRoundRect(cardXOffset+1, cardYOffset+1, cardWidth-2, cardHeight-2, cornerSize, cornerSize); + }*/ + g2d.dispose(); + + return image; + } + + @Override + protected void paintChildren(Graphics g) { + super.paintChildren(g); + + if (getShowCastingCost() && !isAnimationPanel() && getCardWidth() < 200 && getCardWidth() > 60) { + String manaCost = ManaSymbols.getStringManaCost(gameCard.getManaCost()); + int width = getWidth(manaCost); + if (hasImage) { + ManaSymbols.draw(g, manaCost, getCardXOffset() + getCardWidth() - width - 5, getCardYOffset() + 5, getSymbolWidth()); + } else { + ManaSymbols.draw(g, manaCost, getCardXOffset() + 8, getCardHeight() - 9, getSymbolWidth()); + } + } + } + + private int getWidth(String manaCost) { + int width = 0; + manaCost = manaCost.replace("\\", ""); + StringTokenizer tok = new StringTokenizer(manaCost, " "); + while (tok.hasMoreTokens()) { + tok.nextToken(); + width += getSymbolWidth(); + } + return width; + } + + @Override + public void doLayout() { + super.doLayout(); + + int cardWidth = getCardWidth(); + int cardHeight = getCardHeight(); + int cardXOffset = getCardXOffset(); + int cardYOffset = getCardYOffset(); + int borderSize = Math.round(cardWidth * BLACK_BORDER_SIZE); + imagePanel.setLocation(cardXOffset + borderSize, cardYOffset + borderSize); + imagePanel.setSize(cardWidth - borderSize * 2, cardHeight - borderSize * 2); + + if (hasSickness() && CardUtil.isCreature(gameCard) && isPermanent()) { + overlayPanel.setLocation(cardXOffset + borderSize, cardYOffset + borderSize); + overlayPanel.setSize(cardWidth - borderSize * 2, cardHeight - borderSize * 2); + } else { + overlayPanel.setVisible(false); + } + + if (iconPanel != null) { + iconPanel.setLocation(cardXOffset + borderSize, cardYOffset + borderSize); + iconPanel.setSize(cardWidth - borderSize * 2, cardHeight - borderSize * 2); + } + if (counterPanel != null) { + counterPanel.setLocation(cardXOffset + borderSize, cardYOffset + borderSize); + counterPanel.setSize(cardWidth - borderSize * 2, cardHeight - borderSize * 2); + int size = cardWidth > WIDTH_LIMIT ? 40 : 20; + + minusCounterLabel.setLocation(counterPanel.getWidth() - size, counterPanel.getHeight() - size * 2); + minusCounterLabel.setSize(size, size); + + plusCounterLabel.setLocation(5, counterPanel.getHeight() - size * 2); + plusCounterLabel.setSize(size, size); + + loyaltyCounterLabel.setLocation(counterPanel.getWidth() - size, counterPanel.getHeight() - size); + loyaltyCounterLabel.setSize(size, size); + + otherCounterLabel.setLocation(5, counterPanel.getHeight() - size); + otherCounterLabel.setSize(size, size); + + } + int fontHeight = Math.round(cardHeight * (27f / 680)); + boolean showText = (!isAnimationPanel() && fontHeight < 12); + titleText.setVisible(showText); + ptText.setVisible(showText); + + if (showText) { + int fontSize = (int) cardHeight / 11; + titleText.setFont(getFont().deriveFont(Font.BOLD, fontSize)); + + int titleX = Math.round(cardWidth * (20f / 480)); + int titleY = Math.round(cardHeight * (9f / 680)) + getTextOffset(); + titleText.setBounds(cardXOffset + titleX, cardYOffset + titleY, cardWidth - titleX, cardHeight - titleY); + + ptText.setFont(getFont().deriveFont(Font.BOLD, fontSize)); + Dimension ptSize = ptText.getPreferredSize(); + ptText.setSize(ptSize.width, ptSize.height); + int ptX = Math.round(cardWidth * (420f / 480)) - ptSize.width / 2; + int ptY = Math.round(cardHeight * (675f / 680)) - ptSize.height; + + int offsetX = Math.round((CARD_SIZE_FULL.width - cardWidth) / 10.0f); + + ptText.setLocation(cardXOffset + ptX - TEXT_GLOW_SIZE / 2 - offsetX, cardYOffset + ptY - TEXT_GLOW_SIZE / 2); + } + } + + @Override + public String toString() { + return gameCard.toString(); + } + + @Override + public void setCardBounds(int x, int y, int cardWidth, int cardHeight) { + // Call to super + super.setCardBounds(x, y, cardWidth, cardHeight); + + // Update image + if (imagePanel != null && imagePanel.getSrcImage() != null) { + updateArtImage(); + } + } + + @Override + public void setAlpha(float alpha) { + super.setAlpha(alpha); + + // Update components + if (alpha == 0) { + this.ptText.setVisible(false); + this.titleText.setVisible(false); + } else if (alpha == 1.0f) { + this.ptText.setVisible(true); + this.titleText.setVisible(true); + } + } + + /////////////////////////////////////////////////////////// + // Image updating code + private int updateArtImageStamp; + + @Override + public void updateArtImage() { + tappedAngle = isTapped() ? CardPanel.TAPPED_ANGLE : 0; + flippedAngle = isFlipped() ? CardPanel.FLIPPED_ANGLE : 0; + + //final CardView gameCard = this.gameCard; + final int stamp = ++updateArtImageStamp; + + Util.threadPool.submit(new Runnable() { + @Override + public void run() { + try { + final BufferedImage srcImage; + if (gameCard.isFaceDown()) { + srcImage = getFaceDownImage(); + } else if (getCardWidth() > THUMBNAIL_SIZE_FULL.width) { + srcImage = ImageCache.getImage(gameCard, getCardWidth(), getCardHeight()); + } else { + srcImage = ImageCache.getThumbnail(gameCard); + } + UI.invokeLater(new Runnable() { + @Override + public void run() { + if (stamp == updateArtImageStamp) { + hasImage = srcImage != null; + setText(gameCard); + setImage(srcImage); + } + } + }); + } catch (Exception e) { + e.printStackTrace(); + } catch (Error err) { + err.printStackTrace(); + } + } + }); + } + + private BufferedImage getFaceDownImage() { + if (isPermanent()) { + if (((PermanentView) gameCard).isMorphed()) { + return ImageCache.getMorphImage(); + } else { + return ImageCache.getManifestImage(); + } + } else if (this.gameCard instanceof StackAbilityView) { + return ImageCache.getMorphImage(); + } else { + return ImageCache.loadImage(new TFile(DirectLinksForDownload.outDir + File.separator + DirectLinksForDownload.cardbackFilename)); + } + } + + @Override + public void showCardTitle() { + displayTitleAnyway = true; + setText(gameCard); + } + + @Override + public void update(CardView card) { + // Super + super.update(card); + + // Update card text + if (CardUtil.isCreature(card) && CardUtil.isPlaneswalker(card)) { + ptText.setText(card.getPower() + "/" + card.getToughness() + " (" + card.getLoyalty() + ")"); + } else if (CardUtil.isCreature(card)) { + ptText.setText(card.getPower() + "/" + card.getToughness()); + } else if (CardUtil.isPlaneswalker(card)) { + ptText.setText(card.getLoyalty()); + } else { + ptText.setText(""); + } + setText(card); + + // Summoning Sickness overlay + if (hasSickness() && CardUtil.isCreature(gameCard) && isPermanent()) { + overlayPanel.setVisible(true); + } else { + overlayPanel.setVisible(false); + } + + // Update counters panel + if (counterPanel != null) { + updateCounters(card); + } + + // Finally, queue a repaint + repaint(); + } + + private void updateCounters(CardView card) { + if (card.getCounters() != null && !card.getCounters().isEmpty()) { + String name = ""; + if (lastCardWidth != getCardWidth()) { + lastCardWidth = getCardWidth(); + plusCounter = 0; + minusCounter = 0; + otherCounter = 0; + loyaltyCounter = 0; + } + plusCounterLabel.setVisible(false); + minusCounterLabel.setVisible(false); + loyaltyCounterLabel.setVisible(false); + otherCounterLabel.setVisible(false); + for (CounterView counterView : card.getCounters()) { + if (counterView.getCount() == 0) { + continue; + } + switch (counterView.getName()) { + case "+1/+1": + if (counterView.getCount() != plusCounter) { + plusCounter = counterView.getCount(); + plusCounterLabel.setIcon(getCounterImageWithAmount(plusCounter, ImageManagerImpl.getInstance().getCounterImageGreen(), getCardWidth())); + } + plusCounterLabel.setVisible(true); + break; + case "-1/-1": + if (counterView.getCount() != minusCounter) { + minusCounter = counterView.getCount(); + minusCounterLabel.setIcon(getCounterImageWithAmount(minusCounter, ImageManagerImpl.getInstance().getCounterImageRed(), getCardWidth())); + } + minusCounterLabel.setVisible(true); + break; + case "loyalty": + if (counterView.getCount() != loyaltyCounter) { + loyaltyCounter = counterView.getCount(); + loyaltyCounterLabel.setIcon(getCounterImageWithAmount(loyaltyCounter, ImageManagerImpl.getInstance().getCounterImageViolet(), getCardWidth())); + } + loyaltyCounterLabel.setVisible(true); + break; + default: + if (name.isEmpty()) { // only first other counter is shown + name = counterView.getName(); + otherCounter = counterView.getCount(); + otherCounterLabel.setToolTipText(name); + otherCounterLabel.setIcon(getCounterImageWithAmount(otherCounter, ImageManagerImpl.getInstance().getCounterImageGrey(), getCardWidth())); + otherCounterLabel.setVisible(true); + } + } + } + + counterPanel.setVisible(true); + } else { + plusCounterLabel.setVisible(false); + minusCounterLabel.setVisible(false); + loyaltyCounterLabel.setVisible(false); + otherCounterLabel.setVisible(false); + counterPanel.setVisible(false); + } + + } + + private static ImageIcon getCounterImageWithAmount(int amount, BufferedImage image, int cardWidth) { + int factor = cardWidth > WIDTH_LIMIT ? 2 : 1; + int xOffset = amount > 9 ? 2 : 5; + int fontSize = factor == 1 ? amount < 10 ? 12 : amount < 100 ? 10 : amount < 1000 ? 7 : 6 + : amount < 10 ? 19 : amount < 100 ? 15 : amount < 1000 ? 12 : amount < 10000 ? 9 : 8; + BufferedImage newImage; + if (cardWidth > WIDTH_LIMIT) { + newImage = ImageManagerImpl.deepCopy(image); + } else { + newImage = ImageHelper.getResizedImage(image, 20, 20); + } + Graphics graphics = newImage.getGraphics(); + graphics.setColor(Color.BLACK); + graphics.setFont(new Font("Arial Black", amount > 100 ? Font.PLAIN : Font.BOLD, fontSize)); + graphics.drawString(Integer.toString(amount), xOffset * factor, 11 * factor); + return new ImageIcon(newImage); + } + + @Override + public Image getImage() { + if (this.hasImage) { + if (gameCard.isFaceDown()) { + return getFaceDownImage(); + } else { + return ImageCache.getImageOriginal(gameCard); + } + } + return null; + } +} diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderImpl.java b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderImpl.java new file mode 100644 index 00000000000..900bff8f42c --- /dev/null +++ b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderImpl.java @@ -0,0 +1,398 @@ +package org.mage.card.arcane; + +import com.google.common.base.Function; +import com.google.common.collect.MapMaker; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; +import java.io.File; +import java.util.Map; +import java.util.UUID; +import mage.cards.action.ActionCallback; +import mage.client.util.ImageCaches; +import mage.constants.CardType; +import mage.view.CardView; +import mage.view.CounterView; +import mage.view.PermanentView; +import mage.view.StackAbilityView; +import net.java.truevfs.access.TFile; +import org.apache.log4j.Logger; +import org.jdesktop.swingx.graphics.GraphicsUtilities; +import static org.mage.plugins.card.constants.Constants.THUMBNAIL_SIZE_FULL; +import org.mage.plugins.card.dl.sources.DirectLinksForDownload; +import org.mage.plugins.card.images.ImageCache; + +public class CardPanelRenderImpl extends CardPanel { + + private static final Logger LOGGER = Logger.getLogger(CardPanelRenderImpl.class); + + private static boolean cardViewEquals(CardView a, CardView b) { + if (a == b) { + return true; + } + if (a.getClass() != b.getClass()) { + return false; + } + if (!a.getName().equals(b.getName())) { + return false; + } + if (!a.getPower().equals(b.getPower())) { + return false; + } + if (!a.getToughness().equals(b.getToughness())) { + return false; + } + if (!a.getLoyalty().equals(b.getLoyalty())) { + return false; + } + if (0 != a.getColor().compareTo(b.getColor())) { + return false; + } + if (!a.getCardTypes().equals(b.getCardTypes())) { + return false; + } + if (!a.getSubTypes().equals(b.getSubTypes())) { + return false; + } + if (!a.getSuperTypes().equals(b.getSuperTypes())) { + return false; + } + if (!a.getManaCost().equals(b.getManaCost())) { + return false; + } + if (!a.getRules().equals(b.getRules())) { + return false; + } + if (!a.getExpansionSetCode().equals(b.getExpansionSetCode())) { + return false; + } + if (a.getCounters() == null) { + if (b.getCounters() != null) { + return false; + } + } else if (!a.getCounters().equals(b.getCounters())) { + return false; + } + if (a.isFaceDown() != b.isFaceDown()) { + return false; + } + if ((a instanceof PermanentView)) { + PermanentView aa = (PermanentView)a; + PermanentView bb = (PermanentView)b; + if (aa.hasSummoningSickness() != bb.hasSummoningSickness()) { + // Note: b must be a permanentview too as we aleady checked that classes + // are the same for a and b + return false; + } + if (aa.getDamage() != bb.getDamage()) { + return false; + } + } + return true; + } + + class ImageKey { + final BufferedImage artImage; + final int width; + final int height; + final boolean isChoosable; + final boolean isSelected; + final CardView view; + final int hashCode; + + public ImageKey(CardView view, BufferedImage artImage, int width, int height, boolean isChoosable, boolean isSelected) { + this.view = view; + this.artImage = artImage; + this.width = width; + this.height = height; + this.isChoosable = isChoosable; + this.isSelected = isSelected; + this.hashCode = hashCodeImpl(); + } + + private int hashCodeImpl() { + StringBuilder sb = new StringBuilder(); + sb.append((char)(artImage != null ? 1 : 0)); + sb.append((char)width); + sb.append((char)height); + sb.append((char)(isSelected ? 1 : 0)); + sb.append((char)(isChoosable ? 1 : 0)); + sb.append((char)(this.view.isPlayable() ? 1 : 0)); + sb.append((char)(this.view.isCanAttack() ? 1 : 0)); + sb.append((char)(this.view.isFaceDown() ? 1 : 0)); + if (this.view instanceof PermanentView) { + sb.append((char)(((PermanentView)this.view).hasSummoningSickness() ? 1 : 0)); + sb.append((char)(((PermanentView)this.view).getDamage())); + } + sb.append(this.view.getName()); + sb.append(this.view.getPower()); + sb.append(this.view.getToughness()); + sb.append(this.view.getLoyalty()); + sb.append(this.view.getColor().toString()); + sb.append(this.view.getExpansionSetCode()); + for (CardType type: this.view.getCardTypes()) { + sb.append((char)type.ordinal()); + } + for (String s: this.view.getSuperTypes()) { + sb.append(s); + } + for (String s: this.view.getSubTypes()) { + sb.append(s); + } + for (String s: this.view.getManaCost()) { + sb.append(s); + } + for (String s: this.view.getRules()) { + sb.append(s); + } + if (this.view.getCounters() != null) { + for (CounterView v: this.view.getCounters()) { + sb.append(v.getName()).append(v.getCount()); + } + } + return sb.toString().hashCode(); + } + + @Override + public int hashCode() { + return hashCode; + } + + @Override + public boolean equals(Object object) { + // Initial checks + if (this == object) { + return true; + } + if (object == null) { + return false; + } + if (!(object instanceof ImageKey)) { + return false; + } + final ImageKey other = (ImageKey)object; + + // Compare + if ((artImage != null) != (other.artImage != null)) { + return false; + } + if (width != other.width) { + return false; + } + if (height != other.height) { + return false; + } + if (isChoosable != other.isChoosable) { + return false; + } + if (isSelected != other.isSelected) { + return false; + } + return cardViewEquals(view, other.view); + } + } + + // Map of generated images + private final static Map IMAGE_CACHE = new MapMaker().softValues().makeMap(); + + // The art image for the card, loaded in from the disk + private BufferedImage artImage; + + // The rendered card image, with or without the art image loaded yet + // = null while invalid + private BufferedImage cardImage; + private CardRenderer cardRenderer; + + public CardPanelRenderImpl(CardView newGameCard, UUID gameId, final boolean loadImage, ActionCallback callback, final boolean foil, Dimension dimension) { + // Call to super + super(newGameCard, gameId, loadImage, callback, foil, dimension); + + // Renderer + cardRenderer = new ModernCardRenderer(gameCard, isTransformed()); + + // Draw the parts + initialDraw(); + } + + @Override + public void transferResources(CardPanel panel) { + if (panel instanceof CardPanelRenderImpl) { + CardPanelRenderImpl impl = (CardPanelRenderImpl)panel; + + // Use the art image and current rendered image from the card + artImage = impl.artImage; + cardRenderer.setArtImage(artImage); + cardImage = impl.cardImage; + } + } + + @Override + protected void paintCard(Graphics2D g) { + // Render the card if we don't have an image ready to use + if (cardImage == null) { + // Try to get card image from cache based on our card characteristics + ImageKey key = + new ImageKey(gameCard, artImage, + getCardWidth(), getCardHeight(), + isChoosable(), isSelected()); + cardImage = IMAGE_CACHE.get(key); + + // No cached copy exists? Render one and cache it + if (cardImage == null) { + cardImage = renderCard(); + IMAGE_CACHE.put(key, cardImage); + } + } + + // And draw the image we now have + g.drawImage(cardImage, getCardXOffset(), getCardYOffset(), null); + } + + /** + * Render the card to a new BufferedImage at it's current dimensions + * @return + */ + private BufferedImage renderCard() { + int cardWidth = getCardWidth(); + int cardHeight = getCardHeight(); + + // Create image to render to + BufferedImage image = + GraphicsUtilities.createCompatibleTranslucentImage(cardWidth, cardHeight); + Graphics2D g2d = image.createGraphics(); + + // Render with Antialialsing + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + // Attributes + CardPanelAttributes attribs = + new CardPanelAttributes(cardWidth, cardHeight, isChoosable(), isSelected()); + + // Draw card itself + cardRenderer.draw(g2d, attribs); + + // Done + g2d.dispose(); + return image; + } + + private int updateArtImageStamp; + @Override + public void updateArtImage() { + // Invalidate + artImage = null; + cardImage = null; + cardRenderer.setArtImage(null); + + // Stop animation + tappedAngle = isTapped() ? CardPanel.TAPPED_ANGLE : 0; + flippedAngle = isFlipped() ? CardPanel.FLIPPED_ANGLE : 0; + + // Schedule a repaint + repaint(); + + // See if the image is already loaded + //artImage = ImageCache.tryGetImage(gameCard, getCardWidth(), getCardHeight()); + //this.cardRenderer.setArtImage(artImage); + + // Submit a task to draw with the card art when it arrives + if (artImage == null) { + final int stamp = ++updateArtImageStamp; + Util.threadPool.submit(new Runnable() { + @Override + public void run() { + try { + final BufferedImage srcImage; + if (gameCard.isFaceDown()) { + // Nothing to do + srcImage = null; + } else if (getCardWidth() > THUMBNAIL_SIZE_FULL.width) { + srcImage = ImageCache.getImage(gameCard, getCardWidth(), getCardHeight()); + } else { + srcImage = ImageCache.getThumbnail(gameCard); + } + UI.invokeLater(new Runnable() { + @Override + public void run() { + if (stamp == updateArtImageStamp) { + artImage = srcImage; + cardRenderer.setArtImage(srcImage); + if (srcImage != null) { + // Invalidate and repaint + cardImage = null; + repaint(); + } + } + } + }); + } catch (Exception e) { + e.printStackTrace(); + } catch (Error err) { + err.printStackTrace(); + } + } + }); + } + } + + @Override + public void update(CardView card) { + // Update super + super.update(card); + + // Update renderer + cardImage = null; + cardRenderer = new ModernCardRenderer(gameCard, isTransformed()); + cardRenderer.setArtImage(artImage); + + // Repaint + repaint(); + } + + @Override + public void setCardBounds(int x, int y, int cardWidth, int cardHeight) { + int oldCardWidth = getCardWidth(); + int oldCardHeight = getCardHeight(); + + super.setCardBounds(x, y, cardWidth, cardHeight); + + // Rerender if card size changed + if (getCardWidth() != oldCardWidth || getCardHeight() != oldCardHeight) { + cardImage = null; + } + } + + private BufferedImage getFaceDownImage() { + if (isPermanent()) { + if (((PermanentView) gameCard).isMorphed()) { + return ImageCache.getMorphImage(); + } else { + return ImageCache.getManifestImage(); + } + } else if (this.gameCard instanceof StackAbilityView) { + return ImageCache.getMorphImage(); + } else { + return ImageCache.loadImage(new TFile(DirectLinksForDownload.outDir + File.separator + DirectLinksForDownload.cardbackFilename)); + } + } + + @Override + public Image getImage() { + if (artImage != null) { + if (gameCard.isFaceDown()) { + return getFaceDownImage(); + } else { + return ImageCache.getImageOriginal(gameCard); + } + } + return null; + } + + @Override + public void showCardTitle() { + // Nothing to do, rendered cards always have a title + } +} \ No newline at end of file diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/CardRenderer.java b/Mage.Client/src/main/java/org/mage/card/arcane/CardRenderer.java new file mode 100644 index 00000000000..b70ab56e725 --- /dev/null +++ b/Mage.Client/src/main/java/org/mage/card/arcane/CardRenderer.java @@ -0,0 +1,382 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.mage.card.arcane; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Paint; +import java.awt.Polygon; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import java.text.AttributedString; +import java.util.ArrayList; +import java.util.List; +import mage.client.dialog.PreferencesDialog; +import mage.constants.AbilityType; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.counters.Counter; +import mage.utils.CardUtil; +import mage.view.CardView; +import mage.view.CounterView; +import mage.view.PermanentView; +import org.apache.log4j.Logger; + +/** + * @author stravant@gmail.com + * + * Common base class for card renderers for each card frame / card type. + * + * Follows the template method pattern to implement a new renderer, implement + * the following methods (they are called in the following order): + * + * * drawBorder() + * Draws the outermost border of the card, white border or black border + * + * * drawBackground() + * Draws the background texture / color of the card + * + * * drawArt() + * Draws the card's art + * + * * drawFrame() + * Draws the card frame (over the art and background) + * + * * drawOverlays() + * Draws summoning sickness and possible other overlays + * + * * drawCounters() + * Draws counters on the card, such as +1/+1 and -1/-1 counters + * + * Predefined methods that the implementations can use: + * + * * drawRules(font, bounding box) + * + * * drawNameLine(font, bounding box) + * + * * drawTypeLine(font, bounding box) + * + */ +public abstract class CardRenderer { + private static final Logger LOGGER = Logger.getLogger(CardPanel.class); + + /////////////////////////////////////////////////////////////////////////// + // Common layout metrics between all cards + + // The card to be rendered + protected final CardView cardView; + + // Is the card transformed? + protected final boolean isTransformed; + + // The card image + protected BufferedImage artImage; + + /////////////////////////////////////////////////////////////////////////// + // Common layout metrics between all cards + + // Polygons for counters + private static final Polygon PLUS_COUNTER_POLY = new Polygon(new int[]{ + 0, 5, 10, 10, 5, 0 + }, new int[]{ + 3, 0, 3, 10, 9, 10 + }, 6); + private static final Polygon MINUS_COUNTER_POLY = new Polygon(new int[]{ + 0, 5, 10, 10, 5, 0 + }, new int[]{ + 0, 1, 0, 7, 10, 7 + }, 6); + private static final Polygon TIME_COUNTER_POLY = new Polygon(new int[]{ + 0, 10, 8, 10, 0, 2 + }, new int[]{ + 0, 0, 5, 10, 10, 5 + }, 6); + private static final Polygon OTHER_COUNTER_POLY = new Polygon(new int[]{ + 1, 9, 9, 1 + }, new int[]{ + 1, 1, 9, 9 + }, 4); + + // Paint for a card back + public static Paint BG_TEXTURE_CARDBACK = new Color(153, 102, 51); + + // The size of the card + protected int cardWidth; + protected int cardHeight; + + // Is it selectable / selected + protected boolean isChoosable; + protected boolean isSelected; + + // Radius of the corners of the cards + protected static float CORNER_RADIUS_FRAC = 0.1f; //x cardWidth + protected static int CORNER_RADIUS_MIN = 3; + protected int cornerRadius; + + // The inset of the actual card from the black / white border around it + protected static float BORDER_WIDTH_FRAC = 0.03f; //x cardWidth + protected static float BORDER_WIDTH_MIN = 2; + protected int borderWidth; + + // The parsed text of the card + protected ArrayList textboxRules = new ArrayList<>(); + protected ArrayList textboxKeywords = new ArrayList<>(); + + // The Construtor + // The constructor should prepare all of the things that it can + // without knowing the dimensions that the card will be rendered at. + // Then, the CardRenderer can be called on multiple times to render the + // card at various sizes (for instance, during animation) + public CardRenderer(CardView card, boolean isTransformed) { + // Set base parameters + this.cardView = card; + this.isTransformed = isTransformed; + + // Translate the textbox text + for (String rule: card.getRules()) { + // Kill reminder text + if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_RENDERING_REMINDER_TEXT, "false").equals("false")) { + rule = CardRendererUtils.killReminderText(rule).trim(); + } + if (!rule.isEmpty()) { + TextboxRule tbRule = TextboxRuleParser.parse(card, rule); + if (tbRule.type == TextboxRuleType.SIMPLE_KEYWORD) { + textboxKeywords.add(tbRule); + } else if (tbRule.text.isEmpty()) { + // Nothing to do, rule is empty + } else { + textboxRules.add(tbRule); + } + } + } + } + + // Layout operation + // Calculate common layout metrics that will be used by several + // of the operations in the template method. + protected void layout(int cardWidth, int cardHeight) { + // Store the dimensions for the template methods to use + this.cardWidth = cardWidth; + this.cardHeight = cardHeight; + + // Corner radius and border width + cornerRadius = (int)Math.max( + CORNER_RADIUS_MIN, + CORNER_RADIUS_FRAC * cardWidth); + + borderWidth = (int)Math.max( + BORDER_WIDTH_MIN, + BORDER_WIDTH_FRAC * cardWidth); + } + + // The Draw Method + // The draw method takes the information caculated by the constructor + // and uses it to draw to a concrete size of card and graphics. + public void draw(Graphics2D g, CardPanelAttributes attribs) { + // Pre template method layout, to calculate shared layout info + layout(attribs.cardWidth, attribs.cardHeight); + isSelected = attribs.isSelected; + isChoosable = attribs.isChoosable; + + // Call the template methods + drawBorder(g); + drawBackground(g); + drawArt(g); + drawFrame(g); + if (!cardView.isAbility()) { + drawOverlays(g); + drawCounters(g); + } + } + + // Template methods to be implemented by sub classes + // For instance, for the Modern vs Old border card frames + protected abstract void drawBorder(Graphics2D g); + protected abstract void drawBackground(Graphics2D g); + protected abstract void drawArt(Graphics2D g); + protected abstract void drawFrame(Graphics2D g); + + // Template methods that are possible to override, but unlikely to be + // overridden. + + // Draw the card back + protected void drawCardBack(Graphics2D g) { + g.setPaint(BG_TEXTURE_CARDBACK); + g.fillRect(borderWidth, borderWidth, + cardWidth - 2*borderWidth, cardHeight - 2*borderWidth); + } + + // Draw summoning sickness overlay, and possibly other overlays + protected void drawOverlays(Graphics2D g) { + if (CardUtil.isCreature(cardView) && cardView instanceof PermanentView) { + if (((PermanentView)cardView).hasSummoningSickness()) { + int x1 = (int)(0.2*cardWidth); + int x2 = (int)(0.8*cardWidth); + int y1 = (int)(0.2*cardHeight); + int y2 = (int)(0.8*cardHeight); + int xPoints[] = { + x1, x2, x1, x2 + }; + int yPoints[] = { + y1, y1, y2, y2 + }; + g.setColor(new Color(255, 255, 255, 200)); + g.setStroke(new BasicStroke(7)); + g.drawPolygon(xPoints, yPoints, 4); + g.setColor(new Color(0, 0, 0, 200)); + g.setStroke(new BasicStroke(5)); + g.drawPolygon(xPoints, yPoints, 4); + g.setStroke(new BasicStroke(1)); + int[] xPoints2 = { + x1, x2, cardWidth/2 + }; + int[] yPoints2 = { + y1, y1, cardHeight/2 + }; + g.setColor(new Color(0, 0, 0, 100)); + g.fillPolygon(xPoints2, yPoints2, 3); + } + } + } + + // Draw +1/+1 and other counters + protected void drawCounters(Graphics2D g) { + int xPos = (int)(0.65*cardWidth); + int yPos = (int)(0.15*cardHeight); + if (cardView.getCounters() != null) { + for (CounterView v: cardView.getCounters()) { + // Don't render loyalty, we do that in the bottom corner + if (!v.getName().equals("loyalty")) { + Polygon p; + if (v.getName().equals("+1/+1")) { + p = PLUS_COUNTER_POLY; + } else if (v.getName().equals("-1/-1")) { + p = MINUS_COUNTER_POLY; + } else if (v.getName().equals("time")) { + p = TIME_COUNTER_POLY; + } else { + p = OTHER_COUNTER_POLY; + } + double scale = (0.1*0.25*cardWidth); + Graphics2D g2 = (Graphics2D)g.create(); + g2.translate(xPos, yPos); + g2.scale(scale, scale); + g2.setColor(Color.white); + g2.fillPolygon(p); + g2.setColor(Color.black); + g2.drawPolygon(p); + g2.setFont(new Font("Arial", Font.BOLD, 7)); + String cstr = "" + v.getCount(); + int strW = g2.getFontMetrics().stringWidth(cstr); + g2.drawString(cstr, 5 - strW/2, 8); + g2.dispose(); + yPos += ((int)(0.30*cardWidth)); + } + } + } + } + + // Draw an expansion symbol, right justified, in a given region + // Return the width of the drawn symbol + protected int drawExpansionSymbol(Graphics2D g, int x, int y, int w, int h) { + // Draw the expansion symbol + Image setSymbol = ManaSymbols.getSetSymbolImage(cardView.getExpansionSetCode(), cardView.getRarity().getCode()); + int setSymbolWidth; + if (setSymbol == null) { + // Don't draw anything when we don't have a set symbol + return 0; + /* + // Just draw the as a code + String code = cardView.getExpansionSetCode(); + code = (code != null) ? code.toUpperCase() : ""; + FontMetrics metrics = g.getFontMetrics(); + setSymbolWidth = metrics.stringWidth(code); + if (cardView.getRarity() == Rarity.COMMON) { + g.setColor(Color.white); + } else { + g.setColor(Color.black); + } + g.fillRoundRect( + x + w - setSymbolWidth - 1, y + 2, + setSymbolWidth+2, h - 5, + 5, 5); + g.setColor(getRarityColor()); + g.drawString(code, x + w - setSymbolWidth, y + h - 3); + */ + } else { + // Draw the set symbol + int height = setSymbol.getHeight(null); + int scale = 1; + if (height != -1) { + while (height > h+2) { + scale *= 2; + height /= 2; + } + } + setSymbolWidth = setSymbol.getWidth(null) / scale; + g.drawImage(setSymbol, + x + w - setSymbolWidth, y + (h - height)/2, + setSymbolWidth, height, + null); + } + return setSymbolWidth; + } + private Color getRarityColor() { + switch (cardView.getRarity()) { + case RARE: + return new Color(255, 191, 0); + case UNCOMMON: + return new Color(192, 192, 192); + case MYTHIC: + return new Color(213, 51, 11); + case SPECIAL: + return new Color(204, 0, 255); + case BONUS: + return new Color(129, 228, 228); + case COMMON: + default: + return Color.black; + } + } + + // Get a string representing the type line + protected String getCardTypeLine() { + if (cardView.isAbility()) { + if (AbilityType.TRIGGERED.equals(cardView.getAbilityType())) { + return "Triggered Ability"; + } else if (AbilityType.ACTIVATED.equals(cardView.getAbilityType())) { + return "Activated Ability"; + } else { + return "??? Ability"; + } + } else { + StringBuilder sbType = new StringBuilder(); + for (String superType : cardView.getSuperTypes()) { + sbType.append(superType).append(" "); + } + for (CardType cardType : cardView.getCardTypes()) { + sbType.append(cardType.toString()).append(" "); + } + if (cardView.getSubTypes().size() > 0) { + sbType.append("- "); + for (String subType : cardView.getSubTypes()) { + sbType.append(subType).append(" "); + } + } + return sbType.toString(); + } + } + + // Set the card art image (CardPanel will give it to us when it + // is loaded and ready) + public void setArtImage(Image image) { + artImage = CardRendererUtils.toBufferedImage(image); + } +} diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/CardRendererUtils.java b/Mage.Client/src/main/java/org/mage/card/arcane/CardRendererUtils.java new file mode 100644 index 00000000000..bede760f806 --- /dev/null +++ b/Mage.Client/src/main/java/org/mage/card/arcane/CardRendererUtils.java @@ -0,0 +1,124 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.mage.card.arcane; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Paint; +import java.awt.image.BufferedImage; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author stravant@gmail.com + * + * Various static utilities for use in the card renderer + */ +public class CardRendererUtils { + /** + * Convert an abstract image, whose underlying implementation may or may + * not be a BufferedImage into a BufferedImage by creating one and coping + * the contents if it is not, and simply up-casting if it is. + * @param img The image to convert + * @return The converted image + */ + public static BufferedImage toBufferedImage(Image img) { + // Null? No conversion to do + if (img == null) { + return null; + } + + // Already a buffered image? + if (img instanceof BufferedImage) { + return (BufferedImage) img; + } + + // Create a buffered image with transparency + BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB); + + // Draw the image on to the buffered image + Graphics2D bGr = bimage.createGraphics(); + bGr.drawImage(img, 0, 0, null); + bGr.dispose(); + + // Return the buffered image + return bimage; + } + + // Draw a rounded box with a 2-pixel border + // Used on various card parts. + public static void drawRoundedBox(Graphics2D g, int x, int y, int w, int h, int bevel, Paint border, Color fill) { + g.setColor(new Color(0, 0, 0, 150)); + g.drawOval(x-1, y-1, bevel*2, h); + g.setPaint(border); + g.drawOval(x, y, bevel*2-1, h-1); + g.drawOval(x + w - bevel*2, y, bevel*2-1, h-1); + g.drawOval(x+1, y+1, bevel*2-3, h-3); + g.drawOval(x+1 + w - bevel*2, y+1, bevel*2-3, h-3); + g.drawRect(x + bevel, y, w - 2*bevel, h-1); + g.drawRect(x+1 + bevel, y+1, w - 2*bevel-2, h-3); + g.setColor(fill); + g.fillOval(x+2, y+2, bevel*2-4, h-4); + g.fillOval(x+2 + w - bevel*2, y+2, bevel*2-4, h-4); + g.fillRect(x + bevel, y+2, w - 2*bevel, h-4); + } + + // Get the width of a mana cost rendered with ManaSymbols.draw + public static int getManaCostWidth(String manaCost, int symbolSize) { + int width = 0; + manaCost = manaCost.replace("\\", ""); + StringTokenizer tok = new StringTokenizer(manaCost, " "); + while (tok.hasMoreTokens()) { + tok.nextToken(); + width += symbolSize; + } + return width; + } + + // Abbreviate a piece of rules text, making substitutions to decrease its + // length. Also abbreviate reminder text. + private static Pattern abbreviationPattern; + private static Map abbreviations = new HashMap(); + private static Pattern killReminderTextPattern; + static { + // Available abbreviations + abbreviations.put("enters the battlefield", "ETB"); + abbreviations.put("less than", "<"); + abbreviations.put("greater than", ">"); + + // Compile into regex + String patternString = "("; + Iterator it = abbreviations.keySet().iterator(); + while (it.hasNext()) { + patternString += it.next(); + if (it.hasNext()) { + patternString += "|"; + } + } + patternString += ")"; + abbreviationPattern = Pattern.compile(patternString); + + // Reminder text killing + killReminderTextPattern = Pattern.compile("\\([^\\)]*\\)"); + } + public static String abbreviateRule(String rule) { + StringBuffer build = new StringBuffer(); + Matcher match = abbreviationPattern.matcher(rule); + while (match.find()) { + match.appendReplacement(build, abbreviations.get(match.group(1))); + } + match.appendTail(build); + return build.toString(); + } + public static String killReminderText(String rule) { + return killReminderTextPattern.matcher(rule).replaceAll(""); + } +} diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java b/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java index 7d133699f0f..6b62e3f7381 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java @@ -37,7 +37,7 @@ public class ManaSymbols { private static boolean smallSymbolsFound = false; private static boolean mediumSymbolsFound = false; - private static final Map setImages = new HashMap<>(); + private static final Map> setImages = new HashMap<>(); private static final Map setImagesExist = new HashMap<>(); private static final Pattern REPLACE_SYMBOLS_PATTERN = Pattern.compile("\\{([^}/]*)/?([^}]*)\\}"); private static String cachedPath; @@ -57,25 +57,32 @@ public class ManaSymbols { return; } for (String set : setCodes) { - File file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET + set + "-C.jpg"); - try { - Image image = UI.getImageIcon(file.getAbsolutePath()).getImage(); - int width = image.getWidth(null); - if (width > 21) { - int h = image.getHeight(null); - if (h > 0) { - Rectangle r = new Rectangle(21, (int) (h * 21.0f / width)); - BufferedImage resized = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r); - setImages.put(set, resized); - } - } else { - setImages.put(set, image); - } - } catch (Exception e) { - } String[] codes = new String[]{"C", "U", "R", "M"}; + + Map rarityImages = new HashMap<>(); + setImages.put(set, rarityImages); + + for (String rarityCode: codes) { + File file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET + set + "-" + rarityCode + ".jpg"); + try { + Image image = UI.getImageIcon(file.getAbsolutePath()).getImage(); + int width = image.getWidth(null); + if (width > 21) { + int h = image.getHeight(null); + if (h > 0) { + Rectangle r = new Rectangle(21, (int) (h * 21.0f / width)); + BufferedImage resized = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r); + rarityImages.put(set, resized); + } + } else { + rarityImages.put(rarityCode, image); + } + } catch (Exception e) { + } + } + try { - file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET_SMALL); + File file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET_SMALL); if (!file.exists()) { file.mkdirs(); } @@ -298,14 +305,27 @@ public class ManaSymbols { } public static Image getSetSymbolImage(String set) { - return setImages.get(set); + return getSetSymbolImage(set, "C"); + } + + public static Image getSetSymbolImage(String set, String rarity) { + Map rarityImages = setImages.get(set); + if (rarityImages != null) { + return rarityImages.get(rarity); + } else { + return null; + } } public static BufferedImage getSizedManaSymbol(String symbol) { - if (!manaImages.containsKey(GUISizeHelper.symbolDialogSize)) { - loadSymbolsImages(GUISizeHelper.symbolDialogSize); + return getSizedManaSymbol(symbol, GUISizeHelper.symbolDialogSize); + } + + public static BufferedImage getSizedManaSymbol(String symbol, int size) { + if (!manaImages.containsKey(size)) { + loadSymbolsImages(size); } - Map sizedSymbols = manaImages.get(GUISizeHelper.symbolDialogSize); + Map sizedSymbols = manaImages.get(size); return sizedSymbols.get(symbol); } } diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/ModernCardRenderer.java b/Mage.Client/src/main/java/org/mage/card/arcane/ModernCardRenderer.java new file mode 100644 index 00000000000..542b26267cc --- /dev/null +++ b/Mage.Client/src/main/java/org/mage/card/arcane/ModernCardRenderer.java @@ -0,0 +1,1056 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.mage.card.arcane; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.FontFormatException; +import java.awt.GradientPaint; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.LinearGradientPaint; +import java.awt.Paint; +import java.awt.Polygon; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.TexturePaint; +import java.awt.font.FontRenderContext; +import java.awt.font.LineBreakMeasurer; +import java.awt.font.TextAttribute; +import java.awt.font.TextLayout; +import java.awt.font.TextMeasurer; +import java.awt.geom.Rectangle2D; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.net.URL; +import java.text.AttributedCharacterIterator; +import java.text.AttributedString; +import java.text.CharacterIterator; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import javax.swing.ImageIcon; +import mage.ObjectColor; +import mage.client.dialog.PreferencesDialog; +import mage.constants.CardType; +import mage.view.CardView; +import mage.view.PermanentView; +import net.java.balloontip.styles.RoundedBalloonStyle; +import org.apache.log4j.Logger; +import org.mage.card.arcane.CardRenderer; +import org.mage.card.arcane.CardRendererUtils; +import org.mage.card.arcane.ManaSymbols; +import org.mage.card.arcane.TextboxLoyaltyRule; +import org.mage.card.arcane.TextboxRule; +import org.mage.card.arcane.TextboxRuleType; +import sun.security.pkcs11.P11TlsKeyMaterialGenerator; + + +/* + private void cardRendererBasedRender(Graphics2D g) { + // Prepare for draw + g.translate(cardXOffset, cardYOffset); + int cardWidth = this.cardWidth - cardXOffset; + int cardHeight = this.cardHeight - cardYOffset; + + // AA on + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + // Renderer + CardRenderer render = new ModernCardRenderer(gameCard, transformed); + Image img = imagePanel.getSrcImage(); + if (img != null) { + render.setArtImage(img); + } + render.draw(g, cardWidth, cardHeight); + } + */ + +/** + * @author stravant@gmail.com + * + * Base rendering class for new border cards + */ +public class ModernCardRenderer extends CardRenderer { + private static Logger LOGGER = Logger.getLogger(ModernCardRenderer.class); + + /////////////////////////////////////////////////////////////////////////// + // Textures for modern frame cards + + private static TexturePaint loadBackgroundTexture(String name) { + URL url = ModernCardRenderer.class.getResource("/cardrender/background_texture_" + name + ".png"); + ImageIcon icon = new ImageIcon(url); + BufferedImage img = CardRendererUtils.toBufferedImage(icon.getImage()); + return new TexturePaint(img, new Rectangle(0, 0, img.getWidth(), img.getHeight())); + } + private static Font loadFont(String name) { + try { + return Font.createFont( + Font.TRUETYPE_FONT, + ModernCardRenderer.class.getResourceAsStream("/cardrender/" + name + ".ttf")); + } catch (IOException e) { + LOGGER.info("Failed to load font `" + name + "`, couldn't find resource."); + } catch (FontFormatException e) { + LOGGER.info("Failed to load font `" + name + "`, bad format."); + } + return new Font("Arial", Font.PLAIN, 1); + } + public static Font BASE_BELEREN_FONT = loadFont("beleren-bold"); + + public static Paint BG_TEXTURE_WHITE = loadBackgroundTexture("white"); + public static Paint BG_TEXTURE_BLUE = loadBackgroundTexture("blue"); + public static Paint BG_TEXTURE_BLACK = loadBackgroundTexture("black"); + public static Paint BG_TEXTURE_RED = loadBackgroundTexture("red"); + public static Paint BG_TEXTURE_GREEN = loadBackgroundTexture("green"); + public static Paint BG_TEXTURE_GOLD = loadBackgroundTexture("gold"); + public static Paint BG_TEXTURE_ARTIFACT = loadBackgroundTexture("artifact"); + public static Paint BG_TEXTURE_LAND = loadBackgroundTexture("land"); + + public static Color BORDER_WHITE = new Color(216, 203, 188); + public static Color BORDER_BLUE = new Color(20, 121, 175); + public static Color BORDER_BLACK = new Color(45, 45, 35); + public static Color BORDER_RED = new Color(201, 71, 58); + public static Color BORDER_GREEN = new Color(4, 136, 69); + public static Color BORDER_GOLD = new Color(255, 228, 124); + public static Color BORDER_COLORLESS = new Color(238, 242, 242); + public static Color BORDER_LAND = new Color(190, 173, 115); + + public static Color BOX_WHITE = new Color(244, 245, 239); + public static Color BOX_BLUE = new Color(201, 223, 237); + public static Color BOX_BLACK = new Color(204, 194, 192); + public static Color BOX_RED = new Color(246, 208, 185); + public static Color BOX_GREEN = new Color(205, 221, 213); + public static Color BOX_GOLD = new Color(223, 195, 136); + public static Color BOX_COLORLESS = new Color(220, 228, 232); + public static Color BOX_LAND = new Color(220, 215, 213); + + public static Color BOX_WHITE_NIGHT = new Color(169, 160, 145); + public static Color BOX_BLUE_NIGHT = new Color(46, 133, 176); + public static Color BOX_BLACK_NIGHT = new Color(95, 90, 89); + public static Color BOX_RED_NIGHT = new Color(188, 87, 57); + public static Color BOX_GREEN_NIGHT = new Color(31, 100, 44); + public static Color BOX_GOLD_NIGHT = new Color(171, 134, 70); + public static Color BOX_COLORLESS_NIGHT = new Color(118, 147, 158); + + public static Color TEXTBOX_WHITE = new Color(252, 249, 244, 244); + public static Color TEXTBOX_BLUE = new Color(229, 238, 247, 244); + public static Color TEXTBOX_BLACK = new Color(241, 241, 240, 244); + public static Color TEXTBOX_RED = new Color(243, 224, 217, 244); + public static Color TEXTBOX_GREEN = new Color(217, 232, 223, 244); + public static Color TEXTBOX_GOLD = new Color(240, 234, 209, 244); + public static Color TEXTBOX_COLORLESS = new Color(219, 229, 233, 244); + public static Color TEXTBOX_LAND = new Color(218, 214, 212, 244); + + public static Color ERROR_COLOR = new Color(255, 0, 255); + + + /////////////////////////////////////////////////////////////////////////// + // Layout metrics for modern border cards + + // How far the main box, art, and name / type line are inset from the + // card border. That is, the width of background texture that shows around + // the edge of the card. + protected int contentInset; + + // Helper: The total inset from card edge to rules box etc. + // = borderWidth + contentInset + protected int totalContentInset; + + // Width of the content region of the card + // = cardWidth - 2 x totalContentInset + protected int contentWidth; + + // How tall the name / type lines and P/T box are + protected static float BOX_HEIGHT_FRAC = 0.065f; // x cardHeight + protected static int BOX_HEIGHT_MIN = 16; + protected int boxHeight; + + // How far down the card is the type line placed? + protected static float TYPE_LINE_Y_FRAC = 0.57f; // x cardHeight + protected static float TYPE_LINE_Y_FRAC_TOKEN = 0.70f; + protected int typeLineY; + + // How large is the box text, and how far is it down the boxes + protected int boxTextHeight; + protected int boxTextOffset; + protected Font boxTextFont; + + // How large is the P/T text, and how far is it down the boxes + protected int ptTextHeight; + protected int ptTextOffset; + protected Font ptTextFont; + + // Processed mana cost string + protected String manaCostString; + + public ModernCardRenderer(CardView card, boolean isTransformed) { + // Pass off to parent + super(card, isTransformed); + + // Mana cost string + manaCostString = ManaSymbols.getStringManaCost(cardView.getManaCost()); + } + + @Override + protected void layout(int cardWidth, int cardHeight) { + // Pass to parent + super.layout(cardWidth, cardHeight); + + // Content inset, just equal to border width + contentInset = borderWidth; + + // Total content inset helper + totalContentInset = borderWidth + contentInset; + + // Content width + contentWidth = cardWidth - 2*totalContentInset; + + // Box height + boxHeight = (int)Math.max( + BOX_HEIGHT_MIN, + BOX_HEIGHT_FRAC * cardHeight); + + // Type line at + if (cardView.isToken()) { + typeLineY = (int)(TYPE_LINE_Y_FRAC_TOKEN * cardHeight); + } else { + typeLineY = (int)(TYPE_LINE_Y_FRAC * cardHeight); + } + + // Box text height + boxTextHeight = getTextHeightForBoxHeight(boxHeight); + boxTextOffset = (boxHeight - boxTextHeight)/2; + boxTextFont = BASE_BELEREN_FONT.deriveFont(Font.PLAIN, boxTextHeight); + + // Box text height + ptTextHeight = getPTTextHeightForLineHeight(boxHeight); + ptTextOffset = (boxHeight - ptTextHeight)/2; + ptTextFont = BASE_BELEREN_FONT.deriveFont(Font.PLAIN, ptTextHeight); + } + + @Override + protected void drawBorder(Graphics2D g) { + // Draw border as one rounded rectangle + g.setColor(Color.black); + g.fillRoundRect(0, 0, cardWidth, cardHeight, cornerRadius, cornerRadius); + + // Selection Borders + Color borderColor; + if (isSelected) { + borderColor = Color.green; + } else if (isChoosable) { + borderColor = new Color(250, 250, 0, 230); + } else if (cardView.isPlayable()) { + borderColor = new Color(153, 102, 204, 200); + } else if (cardView instanceof PermanentView && ((PermanentView)cardView).isCanAttack()) { + borderColor = new Color(0, 0, 255, 230); + } else { + borderColor = null; + } + if (borderColor != null) { + float hwidth = borderWidth / 2.0f; + Graphics2D g2 = (Graphics2D)g.create(); + g2.setColor(borderColor); + g2.setStroke(new BasicStroke(borderWidth)); + RoundRectangle2D.Float rect + = new RoundRectangle2D.Float( + hwidth, hwidth, + cardWidth - borderWidth, cardHeight - borderWidth, + cornerRadius, cornerRadius); + g2.draw(rect); + g2.dispose(); + } + } + + @Override + protected void drawBackground(Graphics2D g) { + // Draw background, in 3 parts + + if (cardView.isFaceDown()) { + // Just draw a brown rectangle + drawCardBack(g); + } else { + // Set texture to paint with + g.setPaint(getBackgroundPaint(cardView.getColor(), cardView.getCardTypes())); + + // Draw main part (most of card) + g.fillRoundRect( + borderWidth, borderWidth, + cardWidth - borderWidth*2, cardHeight - borderWidth*4 - cornerRadius*2, + cornerRadius - 1, cornerRadius - 1); + + // Draw the M15 rounded "swoosh" at the bottom + g.fillRoundRect( + borderWidth, cardHeight - borderWidth*4 - cornerRadius*4, + cardWidth - borderWidth*2, cornerRadius*4, + cornerRadius*2, cornerRadius*2); + + // Draw the cutout into the "swoosh" for the textbox to lie over + g.fillRect( + borderWidth + contentInset, cardHeight - borderWidth*5, + cardWidth - borderWidth*2 - contentInset*2, borderWidth*2); + } + } + + @Override + protected void drawArt(Graphics2D g) { + if (artImage != null && !cardView.isFaceDown()) { + int imgWidth = artImage.getWidth(); + int imgHeight = artImage.getHeight(); + BufferedImage subImg = + artImage.getSubimage( + (int)(.079*imgWidth), (int)(.11*imgHeight), + (int)(.84*imgWidth), (int)(.42*imgHeight)); + g.drawImage(subImg, + totalContentInset+1, totalContentInset+boxHeight, + contentWidth - 2, typeLineY - totalContentInset - boxHeight, + null); + } + } + + @Override + protected void drawFrame(Graphics2D g) { + // Get the card colors to base the frame on + ObjectColor frameColors = getFrameObjectColor(); + + // Get the border paint + Color boxColor = getBoxColor(frameColors, cardView.getCardTypes(), isTransformed); + Paint textboxPaint = getTextboxPaint(frameColors, cardView.getCardTypes(), cardWidth); + Paint borderPaint = getBorderPaint(frameColors, cardView.getCardTypes(), cardWidth); + + // Draw the main card content border + g.setPaint(borderPaint); + g.drawRect( + totalContentInset, totalContentInset, + contentWidth - 1, cardHeight - borderWidth*3 - totalContentInset - 1); + + // Draw the textbox fill + g.setPaint(textboxPaint); + g.fillRect( + totalContentInset + 1, typeLineY, + contentWidth - 2, cardHeight - borderWidth*3 - typeLineY - 1); + + // If it's a planeswalker, extend the textbox left border by some + if (cardView.getCardTypes().contains(CardType.PLANESWALKER)) { + g.setPaint(borderPaint); + g.fillRect( + totalContentInset, typeLineY + boxHeight, + cardWidth/16, cardHeight - typeLineY - boxHeight - borderWidth*3); + } + + // Draw a shadow highlight at the right edge of the content frame + g.setColor(new Color(0, 0, 0, 100)); + g.fillRect( + totalContentInset - 1, totalContentInset, + 1, cardHeight - borderWidth*3 - totalContentInset - 1); + + // Draw a shadow highlight separating the card art and rest of frame + g.drawRect( + totalContentInset + 1, totalContentInset + boxHeight, + contentWidth - 3, typeLineY - totalContentInset - boxHeight - 1); + + // Draw the name line box + CardRendererUtils.drawRoundedBox(g, + borderWidth, totalContentInset, + cardWidth - 2*borderWidth, boxHeight, + contentInset, + borderPaint, boxColor); + + // Draw the type line box + CardRendererUtils.drawRoundedBox(g, + borderWidth, typeLineY, + cardWidth - 2*borderWidth, boxHeight, + contentInset, + borderPaint, boxColor); + + // Draw a small separator between the type line and box, and shadow + // at the left of the texbox, and above the name line + g.setColor(new Color(0, 0, 0, 150)); + g.fillRect( + totalContentInset - 1, totalContentInset - 1, + contentWidth + 1, 1); + g.fillRect( + totalContentInset + 1, typeLineY + boxHeight, + contentWidth - 2, 1); + g.fillRect( + cardWidth - totalContentInset - 1, typeLineY + boxHeight, + 1, cardHeight - borderWidth*3 - typeLineY - boxHeight); + + // Draw the transform circle + int nameOffset = drawTransformationCircle(g, borderPaint); + + // Draw the name line + drawNameLine(g, + totalContentInset + nameOffset, totalContentInset, + contentWidth - nameOffset, boxHeight); + + // Draw the type line + drawTypeLine(g, + totalContentInset, typeLineY, + contentWidth, boxHeight); + + // Draw the textbox rules + drawRulesText(g, + totalContentInset + 2, typeLineY + boxHeight + 2, + contentWidth - 4, cardHeight - typeLineY - boxHeight - 4 - borderWidth*3); + + // Draw the bottom right stuff + drawBottomRight(g, borderPaint, boxColor); + } + + // Draw the name line + protected void drawNameLine(Graphics2D g, int x, int y, int w, int h) { + // Width of the mana symbols + int manaCostWidth; + if (cardView.isAbility()) { + manaCostWidth = 0; + } else { + manaCostWidth = CardRendererUtils.getManaCostWidth(manaCostString, boxTextHeight); + } + + // Available width for name. Add a little bit of slop so that one character + // can partially go underneath the mana cost + int availableWidth = w - manaCostWidth + 2; + + // Draw the name + String nameStr; + if (cardView.isFaceDown()) { + if (cardView instanceof PermanentView && ((PermanentView)cardView).isManifested()) { + nameStr = "Manifest: " + cardView.getName(); + } else { + nameStr = "Morph: " + cardView.getName(); + } + } else { + nameStr = cardView.getName(); + } + AttributedString str = new AttributedString(nameStr); + str.addAttribute(TextAttribute.FONT, boxTextFont); + TextMeasurer measure = new TextMeasurer(str.getIterator(), g.getFontRenderContext()); + TextLayout layout = measure.getLayout(0, measure.getLineBreakIndex(0, availableWidth)); + g.setColor(getBoxTextColor()); + layout.draw(g, x, y + boxTextOffset + boxTextHeight - 1); + + // Draw the mana symbols + if (!cardView.isAbility() && !cardView.isFaceDown()) { + ManaSymbols.draw(g, manaCostString, x + w - manaCostWidth, y + boxTextOffset, boxTextHeight); + } + } + + // Draw the type line (color indicator, types, and expansion symbol) + protected void drawTypeLine(Graphics2D g, int x, int y, int w, int h) { + // Draw expansion symbol + int expansionSymbolWidth; + if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_RENDERING_SET_SYMBOL, "false").equals("false")) { + if (cardView.isAbility()) { + expansionSymbolWidth = 0; + } else { + expansionSymbolWidth = drawExpansionSymbol(g, x, y, w, h); + } + } else { + expansionSymbolWidth = 0; + } + + // Draw type line text + int availableWidth = w - expansionSymbolWidth + 1; + String types = getCardTypeLine(); + g.setFont(boxTextFont); + + // Replace "Legendary" in type line if there's not enough space + if (g.getFontMetrics().stringWidth(types) > availableWidth) { + types = types.replace("Legendary", "L."); + } + + if (!types.isEmpty()) { + AttributedString str = new AttributedString(types); + str.addAttribute(TextAttribute.FONT, boxTextFont); + TextMeasurer measure = new TextMeasurer(str.getIterator(), g.getFontRenderContext()); + TextLayout layout = measure.getLayout(0, measure.getLineBreakIndex(0, availableWidth)); + g.setColor(getBoxTextColor()); + layout.draw(g, x, y + boxTextOffset + boxTextHeight - 1); + } + } + + // Draw the P/T and/or Loyalty boxes + protected void drawBottomRight(Graphics2D g, Paint borderPaint, Color fill) { + // No bottom right for abilities + if (cardView.isAbility()) { + return; + } + + // Where to start drawing the things + int curY = cardHeight - (int)(0.03f*cardHeight); + + // Width of the boxes + int partWidth = (int)Math.max(30, 0.20f*cardWidth); + + // Is it a creature? + if (cardView.getCardTypes().contains(CardType.CREATURE)) { + int x = cardWidth - borderWidth - partWidth; + + // Draw PT box + CardRendererUtils.drawRoundedBox(g, + x, curY - boxHeight, + partWidth, boxHeight, + contentInset, + borderPaint, + fill); + + // Draw shadow line top + g.setColor(new Color(0, 0, 0, 150)); + g.fillRect( + x + contentInset, curY - boxHeight - 1, + partWidth - 2*contentInset, 1); + + // Draw text + g.setColor(getBoxTextColor()); + g.setFont(ptTextFont); + String ptText = cardView.getPower() + "/" + cardView.getToughness(); + int ptTextWidth = g.getFontMetrics().stringWidth(ptText); + g.drawString(ptText, + x + (partWidth - ptTextWidth)/2, curY - ptTextOffset - 1); + + // Does it have damage on it? + if ((cardView instanceof PermanentView) && ((PermanentView)cardView).getDamage() > 0) { + // Show marked damage + + } + + curY -= boxHeight; + } + + // Is it a walker? (But don't draw the box if it's a non-permanent view + // of a walker without a starting loyalty (EG: Arlin Kord's flipped side). + if (cardView.getCardTypes().contains(CardType.PLANESWALKER) + && (cardView instanceof PermanentView || !cardView.getStartingLoyalty().equals("0"))) { + // Draw the PW loyalty box + int w = partWidth; + int h = partWidth/2; + int x = cardWidth - partWidth - borderWidth; + int y = curY - h; + + Polygon symbol = new Polygon( + new int[]{ + x + w/2, + (int)(x + w*0.9), + x + w, + (int)(x + w*0.6), + x + w/2, + (int)(x + w*0.4), + x, + (int)(x + w*0.1), + }, + new int[]{ + y + h, + (int)(y + 0.8*h), + y, + (int)(y - 0.2*h), + y, + (int)(y - 0.2*h), + y, + (int)(y + 0.8*h), + }, + 8); + + // Draw + stroke + g.setColor(Color.black); + g.fillPolygon(symbol); + g.setColor(new Color(200, 200, 200)); + g.setStroke(new BasicStroke(2)); + g.drawPolygon(symbol); + g.setStroke(new BasicStroke(1)); + + // Loyalty number + String loyalty; + if (cardView instanceof PermanentView) { + loyalty = cardView.getLoyalty(); + } else { + loyalty = cardView.getStartingLoyalty(); + } + + g.setFont(ptTextFont); + g.setColor(Color.white); + int loyaltyWidth = g.getFontMetrics().stringWidth(loyalty); + g.drawString(loyalty, x + (w - loyaltyWidth)/2, y + ptTextHeight + (h - ptTextHeight)/2); + + // Advance + curY -= (int)(1.2*y); + } + + // does it have damage on it? + if ((cardView instanceof PermanentView) && ((PermanentView)cardView).getDamage() > 0) { + int x = cardWidth - partWidth - borderWidth; + int y = curY - boxHeight; + String damage = "" + ((PermanentView)cardView).getDamage(); + g.setFont(ptTextFont); + int txWidth = g.getFontMetrics().stringWidth(damage); + g.setColor(Color.red); + g.fillRect(x, y, partWidth, boxHeight); + g.setColor(Color.white); + g.drawRect(x, y, partWidth, boxHeight); + g.drawString(damage, x + (partWidth - txWidth)/2, curY - 1); + } + } + + // Draw the card's textbox in a given rect + protected boolean loyaltyAbilityColorToggle = false; + protected void drawRulesText(Graphics2D g, int x, int y, int w, int h) { + // Initial font size to try to render at + Font font = new Font("Arial", Font.PLAIN, 12); + Font fontItalic = new Font("Arial", Font.ITALIC, 12); + + // Handle the keyword rules + boolean hasKeywords = !textboxKeywords.isEmpty(); + String keywordRulesString = getKeywordRulesString(); + AttributedString keywordRulesAttributed = new AttributedString(keywordRulesString); + if (hasKeywords) { + keywordRulesAttributed.addAttribute(TextAttribute.FONT, font); + } + + // Get the total height + List attributedRules = new ArrayList<>(); + boolean useSmallFont = false; + int remaining = h; + { + if (hasKeywords) { + remaining -= drawSingleRule(g, keywordRulesAttributed, null, 0, 0, w, remaining, false); + } + for (TextboxRule rule: textboxRules) { + AttributedString attributed = rule.generateAttributedString(font, fontItalic); + attributedRules.add(attributed); + remaining -= drawSingleRule(g, attributed, rule, 0, 0, w, remaining, false); + if (remaining < 0) { + useSmallFont = true; + break; + } + } + } + + // If there wasn't enough room, try using a smaller font + if (useSmallFont) { + font = new Font("Arial", Font.PLAIN, 9); + fontItalic = new Font("Arial", Font.ITALIC, 9); + if (hasKeywords) { + keywordRulesAttributed = new AttributedString(keywordRulesString); + keywordRulesAttributed.addAttribute(TextAttribute.FONT, font); + } + + // Clear out the attributed rules and reatribute them with the new font size + attributedRules.clear(); + for (TextboxRule rule: textboxRules) { + AttributedString attributed = rule.generateAttributedString(font, fontItalic); + attributedRules.add(attributed); + } + + // Get the new spacing for the small text + remaining = h; + if (hasKeywords) { + remaining -= drawSingleRule(g, keywordRulesAttributed, null, 0, 0, w, remaining, false); + } + for (TextboxRule rule: textboxRules) { + AttributedString attributed = rule.generateAttributedString(font, fontItalic); + attributedRules.add(attributed); + remaining -= drawSingleRule(g, attributed, rule, 0, 0, w, remaining, false); + if (remaining < 0) { + useSmallFont = true; + break; + } + } + } + + // Do we have room for additional spacing between the parts of text? + // If so, calculate the spacing based on how much space was left over + int spacing; + if (remaining <= 0) { + spacing = 0; + } else { + spacing = (int)(remaining / (hasKeywords ? + (textboxRules.size() + 2) : + (textboxRules.size() + 1))); + } + + // Do the actual draw + loyaltyAbilityColorToggle = false; + g.setColor(Color.black); + int curY = y + spacing; + if (hasKeywords) { + int adv = drawSingleRule(g, keywordRulesAttributed, null, x, curY, w, h, true); + curY += adv + spacing; + h -= adv; + } + for (int i = 0; i < textboxRules.size(); ++i) { + TextboxRule rule = textboxRules.get(i); + AttributedString attributedRule = attributedRules.get(i); + int adv = drawSingleRule(g, attributedRule, rule, x, curY, w, h, true); + curY += adv + spacing; + h -= adv; + if (h < 0) { + break; + } + } + } + + // Get the first line of the textbox, the keyword string + private String getKeywordRulesString() { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < textboxKeywords.size(); ++i) { + builder.append(textboxKeywords.get(i).text); + if (i != textboxKeywords.size() - 1) { + builder.append(", "); + } + } + return builder.toString(); + } + + // Draw a single rule and returns the amount vertically advanced by, but + // only if doDraw is true. If doDraw is false, just returns the vertical + // advance if the rule were to be drawn. + private int drawSingleRule(Graphics2D g, AttributedString text, TextboxRule rule, int x, int y, int w, int h, boolean doDraw) { + // Inset, in case we are a leveler or loyalty ability + int inset = 0; + if (rule != null && rule.type == TextboxRuleType.LOYALTY) { + inset = cardWidth/12; + } + int availWidth = w - inset; + + FontRenderContext frc = g.getFontRenderContext(); + AttributedCharacterIterator textIter = text.getIterator(); + LineBreakMeasurer measure = new LineBreakMeasurer(textIter, frc); + float yPos = y; + float remain = h; + AttributedCharacterIterator newLineCheck = text.getIterator(); + while (measure.getPosition() < textIter.getEndIndex()) { + // Advance iterator to next line break + char ch = newLineCheck.setIndex(measure.getPosition()); + while ((ch = newLineCheck.next()) != CharacterIterator.DONE) { + if (ch == '\n') { + break; + } + } + + // Get the text layout + TextLayout layout = measure.nextLayout(availWidth, newLineCheck.getIndex(), false); + float ascent = layout.getAscent(); + yPos += ascent; + remain -= ascent; + if (remain < 0) { + break; + } + if (doDraw) { + g.setColor(Color.black); + layout.draw(g, x + inset, yPos); + } + yPos += layout.getDescent() + layout.getLeading() - 2; + } + + // Advance + int advance = ((int)Math.ceil(yPos)) - y; + + // Is it a loyalty ability? + if (rule != null && rule.type == TextboxRuleType.LOYALTY) { + TextboxLoyaltyRule loyaltyRule = (TextboxLoyaltyRule)rule; + Polygon symbol; + int symbolWidth = (x + inset) - borderWidth - 4; + int symbolHeight = (int)(0.7f*symbolWidth); + if (symbolHeight > advance) { + advance = symbolHeight; + } + int symbolX = x - borderWidth; + int symbolY = y + (advance - symbolHeight)/2; + if (doDraw) { + if (loyaltyRule.loyaltyChange < 0 || loyaltyRule.loyaltyChange == TextboxLoyaltyRule.MINUS_X) { + symbol = new Polygon( + new int[]{ + symbolX, + symbolX + symbolWidth, + symbolX + symbolWidth, + symbolX + symbolWidth/2, + symbolX, + }, + new int[]{ + symbolY, + symbolY, + symbolY + symbolHeight - 3, + symbolY + symbolHeight + 3, + symbolY + symbolHeight - 3, + }, + 5); + } else if (loyaltyRule.loyaltyChange > 0) { + symbol = new Polygon( + new int[]{ + symbolX, + symbolX + symbolWidth/2, + symbolX + symbolWidth, + symbolX + symbolWidth, + symbolX, + }, + new int[]{ + symbolY + 3, + symbolY - 3, + symbolY + 3, + symbolY + symbolHeight, + symbolY + symbolHeight, + }, + 5); + } else { + symbol = new Polygon( + new int[]{ + symbolX, + symbolX + symbolWidth, + symbolX + symbolWidth, + symbolX, + }, + new int[]{ + symbolY, + symbolY, + symbolY + symbolHeight, + symbolY + symbolHeight, + }, + 4); + } + g.setColor(new Color(0, 0, 0, 128)); + g.fillRect(x+2, y+advance+1, w-2, 1); + g.setColor(Color.black); + g.fillPolygon(symbol); + g.setColor(new Color(200, 200, 200)); + g.setStroke(new BasicStroke(2)); + g.drawPolygon(symbol); + g.setStroke(new BasicStroke(1)); + g.setColor(Color.white); + g.setFont(boxTextFont); + String loyaltyString = loyaltyRule.getChangeString(); + int textWidth = g.getFontMetrics().stringWidth(loyaltyString); + g.drawString(loyaltyString, + symbolX + (symbolWidth - textWidth)/2, + symbolY + symbolHeight - (symbolHeight - boxTextHeight)/2); + + advance += 3; + loyaltyAbilityColorToggle = !loyaltyAbilityColorToggle; + } + } + + return advance; + } + + // Draw the transformation circle if there is one, and return the + // horizontal width taken up into the content space by it. + protected boolean isNightCard() { + return isTransformed; + } + protected boolean isTransformCard() { + return cardView.canTransform() || isTransformed; + } + protected int drawTransformationCircle(Graphics2D g, Paint borderPaint) { + int transformCircleOffset = 0; + if (isTransformCard()) { + transformCircleOffset = boxHeight - contentInset; + g.setPaint(borderPaint); + g.drawOval(borderWidth, totalContentInset, boxHeight - 1, boxHeight - 1); + g.setColor(Color.black); + g.fillOval(borderWidth+1, totalContentInset+1, boxHeight-2, boxHeight-2); + g.setColor(Color.white); + if (isNightCard()) { + g.fillArc(borderWidth+3, totalContentInset+3, boxHeight-6, boxHeight-6, 90, 270); + g.setColor(Color.black); + g.fillArc(borderWidth+3+3, totalContentInset+3, boxHeight-6-3, boxHeight-6, 90, 270); + } else { + g.fillOval(borderWidth+3, totalContentInset+3, boxHeight-6, boxHeight-6); + } + } + return transformCircleOffset; + } + + // Get the text height for a given box height + protected static int getTextHeightForBoxHeight(int h) { + if (h < 15) { + return h-3; + } else { + return (int)Math.ceil(.6*h); + } + } + + protected static int getPTTextHeightForLineHeight(int h) { + return h - 4; + } + + // Determine the color of the name / type line text + protected Color getBoxTextColor() { + if (isNightCard()) { + return Color.white; + } else if (cardView.isAbility()) { + return Color.white; + } else { + return Color.black; + } + } + + // Determine the colors to base the frame on + protected ObjectColor getFrameObjectColor() { + // TODO: Take into account devoid, land frame colors, etc + return cardView.getColor().union(cardView.getFrameColor()); + } + + // Determine which background paint to use from a set of colors + // and the current card. + protected static Paint getBackgroundPaint(ObjectColor colors, Collection types) { + if (types.contains(CardType.LAND)) { + return BG_TEXTURE_LAND; + } else if (types.contains(CardType.ARTIFACT)) { + return BG_TEXTURE_ARTIFACT; + } else if (colors.isMulticolored()) { + return BG_TEXTURE_GOLD; + } else if (colors.isWhite()) { + return BG_TEXTURE_WHITE; + } else if (colors.isBlue()) { + return BG_TEXTURE_BLUE; + } else if (colors.isBlack()) { + return BG_TEXTURE_BLACK; + } else if (colors.isRed()) { + return BG_TEXTURE_RED; + } else if (colors.isGreen()) { + return BG_TEXTURE_GREEN; + } else { + // Colorless + return new Color(71, 86, 101); + } + } + + // Get the box color for the given colors + protected Color getBoxColor(ObjectColor colors, Collection types, boolean isNightCard) { + if (cardView.isAbility()) { + return Color.BLACK; + } else if (colors.getColorCount() == 2 && types.contains(CardType.LAND)) { + // Special case for two color lands. Boxes should be normal land colored + // rather than multicolor. Three or greater color lands use a multi-color + // box as normal. + return BOX_LAND; + } else if (colors.isMulticolored()) { + return isNightCard ? BOX_GOLD_NIGHT : BOX_GOLD; + } else if (colors.isColorless()) { + if (types.contains(CardType.LAND)) { + return BOX_LAND; + } else { + return isNightCard ? BOX_COLORLESS_NIGHT : BOX_COLORLESS; + } + } else if (colors.isWhite()) { + return isNightCard ? BOX_WHITE_NIGHT : BOX_WHITE; + } else if (colors.isBlue()) { + return isNightCard ? BOX_BLUE_NIGHT : BOX_BLUE; + } else if (colors.isBlack()) { + return isNightCard ? BOX_BLACK_NIGHT : BOX_BLACK; + } else if (colors.isRed()) { + return isNightCard ? BOX_RED_NIGHT : BOX_RED; + } else if (colors.isGreen()) { + return isNightCard ? BOX_GREEN_NIGHT : BOX_GREEN; + } else { + return ERROR_COLOR; + } + } + + // Get the border color for a single color + protected static Color getBorderColor(ObjectColor color) { + if (color.isWhite()) { + return BORDER_WHITE; + } else if (color.isBlue()) { + return BORDER_BLUE; + } else if (color.isBlack()) { + return BORDER_BLACK; + } else if (color.isRed()) { + return BORDER_RED; + } else if (color.isGreen()) { + return BORDER_GREEN; + } else { + return ERROR_COLOR; + } + } + + // Determine the border paint to use, based on an ObjectColors + protected static Paint getBorderPaint(ObjectColor colors, Collection types, int width) { + if (colors.isMulticolored()) { + if (colors.getColorCount() == 2) { + List twoColors = colors.getColors(); + + // Two-color frames look better if we use a whiter white + // than the normal white frame color for them, as the normal + // white border color is very close to the gold background + // color. + Color color1, color2; + if (twoColors.get(0).isWhite()) { + color1 = new Color(240, 240, 240); + } else { + color1 = getBorderColor(twoColors.get(0)); + } + if (twoColors.get(1).isWhite()) { + color2 = new Color(240, 240, 240); + } else { + color2 = getBorderColor(twoColors.get(1)); + } + + // Special case for two colors, gradient paint + return new LinearGradientPaint( + 0, 0, width, 0, + new float[]{0.4f, 0.6f}, + new Color[]{color1, color2}); + } else { + return BORDER_GOLD; + } + } else if (colors.isColorless()) { + if (types.contains(CardType.LAND)) { + return BORDER_LAND; + } else { + return BORDER_COLORLESS; + } + } else { + return getBorderColor(colors); + } + } + + // Determine the textbox color for a single color + protected static Color getTextboxColor(ObjectColor color) { + if (color.isWhite()) { + return TEXTBOX_WHITE; + } else if (color.isBlue()) { + return TEXTBOX_BLUE; + } else if (color.isBlack()) { + return TEXTBOX_BLACK; + } else if (color.isRed()) { + return TEXTBOX_RED; + } else if (color.isGreen()) { + return TEXTBOX_GREEN; + } else { + return ERROR_COLOR; + } + } + + // Determine the border paint to use, based on an ObjectColors + protected static Paint getTextboxPaint(ObjectColor colors, Collection types, int width) { + if (colors.isMulticolored()) { + if (colors.getColorCount() == 2) { + List twoColors = colors.getColors(); + + // Special case for two colors, gradient paint + return new LinearGradientPaint( + 0, 0, width, 0, + new float[]{0.4f, 0.6f}, + new Color[]{ + getTextboxColor(twoColors.get(0)), + getTextboxColor(twoColors.get(1)) + }); + } else { + return TEXTBOX_GOLD; + } + } else if (colors.isColorless()) { + if (types.contains(CardType.LAND)) { + return TEXTBOX_LAND; + } else { + return TEXTBOX_COLORLESS; + } + } else { + return getTextboxColor(colors); + } + } +} diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/TextboxKeywordRule.java b/Mage.Client/src/main/java/org/mage/card/arcane/TextboxKeywordRule.java new file mode 100644 index 00000000000..50e15b04aac --- /dev/null +++ b/Mage.Client/src/main/java/org/mage/card/arcane/TextboxKeywordRule.java @@ -0,0 +1,17 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.mage.card.arcane; + +import java.util.List; + +/** + * @author stravant@gmail.com + */ +public class TextboxKeywordRule extends TextboxRule { + public TextboxKeywordRule(String text, List regions) { + super(text, regions, TextboxRuleType.SIMPLE_KEYWORD); + } +} diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/TextboxLevelRule.java b/Mage.Client/src/main/java/org/mage/card/arcane/TextboxLevelRule.java new file mode 100644 index 00000000000..7a5388e29e8 --- /dev/null +++ b/Mage.Client/src/main/java/org/mage/card/arcane/TextboxLevelRule.java @@ -0,0 +1,28 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.mage.card.arcane; + +import java.text.AttributedString; +import java.util.List; + +/** + * @author StravantUser + * + * Level rule associated with leveler cards + */ +public class TextboxLevelRule extends TextboxRule { + // The levels that this rule applies to + public int levelFrom; + public int levelTo; + + public static int AND_HIGHER = 100; + + public TextboxLevelRule(String text, List regions, int levelFrom, int levelTo) { + super(text, regions, TextboxRuleType.LEVEL); + this.levelFrom = levelFrom; + this.levelTo = levelTo; + } +} diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/TextboxLoyaltyRule.java b/Mage.Client/src/main/java/org/mage/card/arcane/TextboxLoyaltyRule.java new file mode 100644 index 00000000000..a60858e0883 --- /dev/null +++ b/Mage.Client/src/main/java/org/mage/card/arcane/TextboxLoyaltyRule.java @@ -0,0 +1,33 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.mage.card.arcane; + +import java.text.AttributedString; +import java.util.List; + +/** + * @author StravantUser + */ +public class TextboxLoyaltyRule extends TextboxRule { + public int loyaltyChange; + + public static int MINUS_X = 100; + + public String getChangeString() { + if (loyaltyChange == MINUS_X) { + return "-X"; + } else if (loyaltyChange > 0) { + return "+" + loyaltyChange; + } else { + return "" + loyaltyChange; + } + } + + public TextboxLoyaltyRule(String text, List regions, int loyaltyChange) { + super(text, regions, TextboxRuleType.LOYALTY); + this.loyaltyChange = loyaltyChange; + } +} diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/TextboxRule.java b/Mage.Client/src/main/java/org/mage/card/arcane/TextboxRule.java new file mode 100644 index 00000000000..660b8587e2d --- /dev/null +++ b/Mage.Client/src/main/java/org/mage/card/arcane/TextboxRule.java @@ -0,0 +1,94 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.mage.card.arcane; + +import java.awt.Font; +import java.awt.Image; +import java.awt.font.GraphicAttribute; +import java.awt.font.ImageGraphicAttribute; +import java.awt.font.TextAttribute; +import java.text.AttributedString; +import java.util.List; + +/** + * @author stravant@gmail.com + * + * Class describing parsed & translated rules in the text box of a card, + * ready to be rendered. + */ +public class TextboxRule { + // An attributed region in the text, which can be applied to an + // attributed string. + public interface AttributeRegion { + public void applyToAttributedString(AttributedString str, Font normal, Font italic); + } + + // A region of italics, or bold text in a + public static class ItalicRegion implements AttributeRegion { + ItalicRegion(int start, int end) { + this.start = start; + this.end = end; + } + private final int start; + private final int end; + + @Override + public void applyToAttributedString(AttributedString str, Font normal, Font italic) { + if (end > start+1) { + str.addAttribute(TextAttribute.FONT, italic, start, end); + } + } + } + + // A special symbol embedded at some point in a string + public static class EmbeddedSymbol implements AttributeRegion { + EmbeddedSymbol(String symbol, int location) { + this.symbol = symbol; + this.location = location; + } + private final String symbol; + private final int location; + + @Override + public void applyToAttributedString(AttributedString str, Font normal, Font italic) { + Image symbolImage = ManaSymbols.getSizedManaSymbol(symbol, normal.getSize()); + if (symbolImage != null) { + ImageGraphicAttribute imgAttr = + new ImageGraphicAttribute(symbolImage, GraphicAttribute.BOTTOM_ALIGNMENT); + str.addAttribute(TextAttribute.CHAR_REPLACEMENT, imgAttr, location, location+1); + } + } + } + + public String text; + public TextboxRuleType type; + + private List regions; + + protected TextboxRule(String text, List regions, TextboxRuleType type) { + this.text = text; + this.type = type; + this.regions = regions; + } + + public TextboxRule(String text, List regions) { + this(text, regions, TextboxRuleType.NORMAL); + } + + public AttributedString generateAttributedString(Font normal, Font italic) { + // Build the final attributed text using the regions + // Do it in reverse order for proper handling of regions where + // there are multiple attributes stacked (EG: bold + italic) + AttributedString attributedRule = new AttributedString(text); + if (text.length() != 0) { + attributedRule.addAttribute(TextAttribute.FONT, normal); + for (int i = regions.size()-1; i >= 0; --i) { + regions.get(i).applyToAttributedString(attributedRule, normal, italic); + } + } + return attributedRule; + } +} diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/TextboxRuleParser.java b/Mage.Client/src/main/java/org/mage/card/arcane/TextboxRuleParser.java new file mode 100644 index 00000000000..1cb66a1477f --- /dev/null +++ b/Mage.Client/src/main/java/org/mage/card/arcane/TextboxRuleParser.java @@ -0,0 +1,251 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.mage.card.arcane; + +import java.awt.Font; +import java.awt.Image; +import java.awt.font.GraphicAttribute; +import java.awt.font.ImageGraphicAttribute; +import java.awt.font.TextAttribute; +import java.text.AttributedString; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import mage.client.dialog.PreferencesDialog; +import mage.view.CardView; +import org.apache.log4j.Logger; + +/** + * + * @author StravantUser + */ +public class TextboxRuleParser { + private static final Logger LOGGER = Logger.getLogger(CardPanel.class); + + private static final Pattern LevelAbilityPattern = Pattern.compile("Level (\\d+)-?(\\d*)(\\+?)"); + private static final Pattern LoyaltyAbilityPattern = Pattern.compile("^(\\+|\\-)(\\d+|X): "); + private static final Pattern SimpleKeywordPattern = Pattern.compile("^(\\w+( \\w+)?)\\s*(\\([^\\)]*\\))?\\s*$"); + + // Parse a given rule (given as a string) into a TextboxRule, replacing + // symbol annotations, italics, etc, parsing out information such as + // if the ability is a loyalty ability, and returning an TextboxRule + // representing that information, which can be used to render the rule in + // the textbox of a card. + public static TextboxRule parse(CardView source, String rule) { + // List of regions to apply + ArrayList regions = new ArrayList<>(); + + // Leveler / loyalty + boolean isLeveler = false; + int levelFrom = 0; + int levelTo = 0; + + boolean isLoyalty = false; + int loyaltyChange = 0; + + // Parse the attributedString contents + int index = 0; + int outputIndex = 0; + + // Is it a simple keyword ability? + { + Matcher simpleKeywordMatch = SimpleKeywordPattern.matcher(rule); + if (simpleKeywordMatch.find()) { + return new TextboxKeywordRule(simpleKeywordMatch.group(1), regions); + } + } + + // Check if it's a loyalty ability. Must be right at the start of the rule + { + Matcher loyaltyMatch = LoyaltyAbilityPattern.matcher(rule); + if (loyaltyMatch.find()) { + // Get the loyalty change + if (loyaltyMatch.group(2).equals("X")) { + loyaltyChange = TextboxLoyaltyRule.MINUS_X; + } else { + loyaltyChange = Integer.parseInt(loyaltyMatch.group(2)); + if (loyaltyMatch.group(1).equals("-")) { + loyaltyChange = -loyaltyChange; + } + } + isLoyalty = true; + + // Go past the match + index = loyaltyMatch.group().length(); + } + } + + Deque openingStack = new ArrayDeque<>(); + StringBuilder build = new StringBuilder(); + while (index < rule.length()) { + int initialIndex = index; + char ch = rule.charAt(index); + if (ch == '{') { + // Handling for `{this}` + int closeIndex = rule.indexOf('}', index); + if (closeIndex == -1) { + // Malformed input, nothing to do + ++index; + ++outputIndex; + build.append(ch); + } else { + String contents = rule.substring(index+1, closeIndex); + if (contents.equals("this") || contents.equals("source")) { + // Replace {this} with the card's name + String cardName = source.getName(); + build.append(cardName); + index += contents.length() + 2; + outputIndex += cardName.length(); + } else { + Image symbol = ManaSymbols.getSizedManaSymbol(contents, 10); + if (symbol != null) { + // Mana or other inline symbol + build.append('#'); + regions.add(new TextboxRule.EmbeddedSymbol(contents, outputIndex)); + ++outputIndex; + index = closeIndex+1; + } else { + // Bad entry + build.append('{'); + build.append(contents); + build.append('}'); + index = closeIndex+1; + outputIndex += (contents.length() + 2); + } + } + } + + } else if (ch == '&') { + // Handling for `—` + if (rule.startsWith("—", index)) { + build.append('—'); + index += 7; + ++outputIndex; + } else if (rule.startsWith("&bull", index)) { + build.append('•'); + index += 5; + ++outputIndex; + } else { + LOGGER.error("Bad &...; sequence `" + rule.substring(index+1, index+10) + "` in rule."); + build.append('&'); + ++index; + ++outputIndex; + } + + + } else if (ch == '<') { + // Handling for `` and `
` + int closeIndex = rule.indexOf('>', index); + if (closeIndex != -1) { + // Is a tag + String tag = rule.substring(index+1, closeIndex); + if (tag.charAt(tag.length()-1) == '/') { + // Pure closing tag (like
) + if (tag.equals("br/")) { + build.append('\n'); + ++outputIndex; + } else { + // Unknown + build.append('<').append(tag).append('>'); + outputIndex += (tag.length() + 2); + } + } else if (tag.charAt(0) == '/') { + // Opening index for the tag + int openingIndex; + if (openingStack.isEmpty()) { + // Malformed input, just make an empty interval + openingIndex = outputIndex; + } else { + openingIndex = openingStack.pop(); + } + + // What tag is it? + if (tag.equals("/i")) { + // Italics + regions.add(new TextboxRule.ItalicRegion(openingIndex, outputIndex)); + } else if (tag.equals("/b")) { + // Bold, see if it's a level ability + String content = build.substring(openingIndex); + + Matcher levelMatch = LevelAbilityPattern.matcher(content); + if (levelMatch.find()) { + try { + levelFrom = Integer.parseInt(levelMatch.group(1)); + if (!levelMatch.group(2).equals("")) { + levelTo = Integer.parseInt(levelMatch.group(2)); + } + if (!levelMatch.group(3).equals("")) { + levelTo = TextboxLevelRule.AND_HIGHER; + } + isLeveler = true; + } catch (Exception e) { + LOGGER.error("Bad leveler levels in rule `" + rule + "`."); + } + } + } else { + // Unknown + build.append('<').append(tag).append('>'); + outputIndex += (tag.length() + 2); + } + } else { + // Is it a
tag special case? [Why can't it have a closing `/`... =( ] + if (tag.equals("br")) { + build.append('\n'); + ++outputIndex; + } else { + // Opening tag + openingStack.push(outputIndex); + } + } + // Skip characters + index = closeIndex+1; + } else { + // Malformed tag + build.append('<'); + ++outputIndex; + ++index; + } + + } else { + // Normal character + ++index; + ++outputIndex; + build.append(ch); + } + if (outputIndex != build.length()) { + // Somehow our parsing code output symbols but didn't update the output index correspondingly + LOGGER.error("The human is dead; mismatch! Failed on rule: `" + rule + "` due to not updating outputIndex properly."); + + // Bail out + build = new StringBuilder(rule); + regions.clear(); + break; + } + if (index == initialIndex) { + // Somehow our parsing failed to consume the + LOGGER.error("Failed on rule `" + rule + "` due to not consuming a character."); + + // Bail out + build = new StringBuilder(rule); + regions.clear(); + break; + } + } + + // Build and return the rule + rule = build.toString(); + if (isLoyalty) { + return new TextboxLoyaltyRule(rule, regions, loyaltyChange); + } else if (isLeveler) { + return new TextboxLevelRule(rule, regions, levelFrom, levelTo); + } else { + return new TextboxRule(rule, regions); + } + } +} diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/TextboxRuleType.java b/Mage.Client/src/main/java/org/mage/card/arcane/TextboxRuleType.java new file mode 100644 index 00000000000..4903130db44 --- /dev/null +++ b/Mage.Client/src/main/java/org/mage/card/arcane/TextboxRuleType.java @@ -0,0 +1,25 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.mage.card.arcane; + +/** + * @author stravant@gmail.com + */ +public enum TextboxRuleType { + /* Normal abilities, just rendered as lines of text with embedded symbols + * replaced to the relevant images. */ + NORMAL, + + /* Keyword ability. To be displayed in the comma separated list at the + * very top of the rules box */ + SIMPLE_KEYWORD, + + /* Loyalty abilities on planeswalkers */ + LOYALTY, + + /* Levelup creature - static ability at a given level */ + LEVEL +} diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java b/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java index 4be38a34567..3c53fa20f7d 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java @@ -17,6 +17,7 @@ import javax.swing.JDialog; import javax.swing.JLayeredPane; import mage.cards.MagePermanent; import mage.cards.action.ActionCallback; +import mage.client.dialog.PreferencesDialog; import mage.client.util.GUISizeHelper; import mage.constants.Rarity; import mage.interfaces.plugin.CardPlugin; @@ -31,6 +32,7 @@ import net.xeoh.plugins.base.annotations.meta.Author; import org.apache.log4j.Logger; import org.mage.card.arcane.Animation; import org.mage.card.arcane.CardPanel; +import org.mage.card.arcane.CardPanelComponentImpl; import org.mage.card.arcane.ManaSymbols; import org.mage.plugins.card.dl.DownloadGui; import org.mage.plugins.card.dl.DownloadJob; @@ -41,6 +43,7 @@ import org.mage.plugins.card.dl.sources.GathererSets; import org.mage.plugins.card.dl.sources.GathererSymbols; import org.mage.plugins.card.images.ImageCache; import org.mage.plugins.card.info.CardInfoPaneImpl; +import org.mage.card.arcane.CardPanelRenderImpl; /** * {@link CardPlugin} implementation. @@ -105,10 +108,23 @@ public class CardPluginImpl implements CardPlugin { cardWidthMin = (int) GUISizeHelper.battlefieldCardMinDimension.getWidth(); cardWidthMax = (int) GUISizeHelper.battlefieldCardMaxDimension.getWidth(); } + + /** + * Temporary card rendering shim. Split card rendering isn't implemented yet, so + * use old component based rendering for the split cards. + */ + private CardPanel makePanel(CardView view, UUID gameId, boolean loadImage, ActionCallback callback, boolean isFoil, Dimension dimension) { + String fallback = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_RENDERING_FALLBACK, "false"); + if (view.isSplitCard() || fallback.equals("true")) { + return new CardPanelComponentImpl(view, gameId, loadImage, callback, isFoil, dimension); + } else { + return new CardPanelRenderImpl(view, gameId, loadImage, callback, isFoil, dimension); + } + } @Override public MagePermanent getMagePermanent(PermanentView permanent, Dimension dimension, UUID gameId, ActionCallback callback, boolean canBeFoil, boolean loadImage) { - CardPanel cardPanel = new CardPanel(permanent, gameId, loadImage, callback, false, dimension); + CardPanel cardPanel = makePanel(permanent, gameId, loadImage, callback, false, dimension); boolean implemented = !permanent.getRarity().equals(Rarity.NA); cardPanel.setShowCastingCost(implemented); return cardPanel; @@ -116,7 +132,7 @@ public class CardPluginImpl implements CardPlugin { @Override public MagePermanent getMageCard(CardView cardView, Dimension dimension, UUID gameId, ActionCallback callback, boolean canBeFoil, boolean loadImage) { - CardPanel cardPanel = new CardPanel(cardView, gameId, loadImage, callback, false, dimension); + CardPanel cardPanel = makePanel(cardView, gameId, loadImage, callback, false, dimension); boolean implemented = cardView.getRarity() != null && !cardView.getRarity().equals(Rarity.NA); cardPanel.setShowCastingCost(implemented); return cardPanel; diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java index 8f53cc2f9f9..97a86655c27 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java @@ -201,6 +201,10 @@ public class ImageCache { public static BufferedImage getThumbnail(CardView card) { return getImage(getKey(card, card.getName(), "#thumb")); } + + public static BufferedImage tryGetThumbnail(CardView card) { + return tryGetImage(getKey(card, card.getName(), "#thumb")); + } public static BufferedImage getImageOriginal(CardView card) { return getImage(getKey(card, card.getName(), "")); @@ -231,6 +235,18 @@ public class ImageCache { return null; } } + + /** + * Returns the Image corresponding to the key only if it already exists + * in the cache. + */ + private static BufferedImage tryGetImage(String key) { + if (IMAGE_CACHE.containsKey(key)) { + return IMAGE_CACHE.get(key); + } else { + return null; + } + } /** * Returns the map key for a card, without any suffixes for the image size. @@ -344,6 +360,34 @@ public class ImageCache { return TransformedImageCache.getResizedImage(original, (int) (original.getWidth() * scale), (int) (original.getHeight() * scale)); } + + /** + * Returns the image appropriate to display for a card in a picture panel, but + * only it was ALREADY LOADED. That is, the call is immediate and will not block + * on file IO. + * @param card + * @param width + * @param height + * @return + */ + public static BufferedImage tryGetImage(CardView card, int width, int height) { + if (Constants.THUMBNAIL_SIZE_FULL.width + 10 > width) { + return tryGetThumbnail(card); + } + String key = getKey(card, card.getName(), Integer.toString(width)); + BufferedImage original = tryGetImage(key); + if (original == null) { + LOGGER.debug(key + " not found"); + return null; + } + + double scale = Math.min((double) width / original.getWidth(), (double) height / original.getHeight()); + if (scale >= 1) { + return original; + } + + return TransformedImageCache.getResizedImage(original, (int) (original.getWidth() * scale), (int) (original.getHeight() * scale)); + } public static TFile getTFile(String path) { try { diff --git a/Mage.Client/src/main/resources/cardrender/background_texture_artifact.png b/Mage.Client/src/main/resources/cardrender/background_texture_artifact.png new file mode 100644 index 00000000000..f34a1256d91 Binary files /dev/null and b/Mage.Client/src/main/resources/cardrender/background_texture_artifact.png differ diff --git a/Mage.Client/src/main/resources/cardrender/background_texture_black.png b/Mage.Client/src/main/resources/cardrender/background_texture_black.png new file mode 100644 index 00000000000..0237998b758 Binary files /dev/null and b/Mage.Client/src/main/resources/cardrender/background_texture_black.png differ diff --git a/Mage.Client/src/main/resources/cardrender/background_texture_blue.png b/Mage.Client/src/main/resources/cardrender/background_texture_blue.png new file mode 100644 index 00000000000..910d2f87603 Binary files /dev/null and b/Mage.Client/src/main/resources/cardrender/background_texture_blue.png differ diff --git a/Mage.Client/src/main/resources/cardrender/background_texture_gold.png b/Mage.Client/src/main/resources/cardrender/background_texture_gold.png new file mode 100644 index 00000000000..d325538a25d Binary files /dev/null and b/Mage.Client/src/main/resources/cardrender/background_texture_gold.png differ diff --git a/Mage.Client/src/main/resources/cardrender/background_texture_green.png b/Mage.Client/src/main/resources/cardrender/background_texture_green.png new file mode 100644 index 00000000000..08a3a1b3864 Binary files /dev/null and b/Mage.Client/src/main/resources/cardrender/background_texture_green.png differ diff --git a/Mage.Client/src/main/resources/cardrender/background_texture_land.png b/Mage.Client/src/main/resources/cardrender/background_texture_land.png new file mode 100644 index 00000000000..3b7f3984cc8 Binary files /dev/null and b/Mage.Client/src/main/resources/cardrender/background_texture_land.png differ diff --git a/Mage.Client/src/main/resources/cardrender/background_texture_red.png b/Mage.Client/src/main/resources/cardrender/background_texture_red.png new file mode 100644 index 00000000000..1cd186adc5b Binary files /dev/null and b/Mage.Client/src/main/resources/cardrender/background_texture_red.png differ diff --git a/Mage.Client/src/main/resources/cardrender/background_texture_white.png b/Mage.Client/src/main/resources/cardrender/background_texture_white.png new file mode 100644 index 00000000000..44acb90961d Binary files /dev/null and b/Mage.Client/src/main/resources/cardrender/background_texture_white.png differ diff --git a/Mage.Client/src/main/resources/cardrender/beleren-bold.ttf b/Mage.Client/src/main/resources/cardrender/beleren-bold.ttf new file mode 100644 index 00000000000..7dd1bff6a75 Binary files /dev/null and b/Mage.Client/src/main/resources/cardrender/beleren-bold.ttf differ diff --git a/Mage.Common/src/mage/cards/CardBorder.java b/Mage.Common/src/mage/cards/CardBorder.java new file mode 100644 index 00000000000..17f6cd8c27b --- /dev/null +++ b/Mage.Common/src/mage/cards/CardBorder.java @@ -0,0 +1,28 @@ + +package mage.cards; + +/** + * @author stravant@gmail.com + * + * Enum listing the possible card faces for a card + * + * Because of Time Spiral block's shifted cards it is + * not sufficient to just look at a card's edition to + * determine what the card face should be. + */ +public enum CardBorder { + /* Old border card frames. ALPHA -> 8th ED */ + OLD, + + /* Future Sight frames. FUT futureshifted */ + FUT, + + /* Planar Chaos frames. PLC planeshifted */ + PLC, + + /* Modern card frames. 8th ED -> M15 */ + MOD, + + /* New border cards, M15 -> current */ + M15 +} diff --git a/Mage.Common/src/mage/cards/MageCard.java b/Mage.Common/src/mage/cards/MageCard.java index 8ee0ec61ed8..61908d4daef 100644 --- a/Mage.Common/src/mage/cards/MageCard.java +++ b/Mage.Common/src/mage/cards/MageCard.java @@ -32,7 +32,7 @@ public abstract class MageCard extends JPanel { public abstract void update(CardView card); - public abstract void updateImage(); + public abstract void updateArtImage(); public abstract Image getImage(); diff --git a/Mage.Common/src/mage/view/CardView.java b/Mage.Common/src/mage/view/CardView.java index 7a4f6732481..ca3b6c48eed 100644 --- a/Mage.Common/src/mage/view/CardView.java +++ b/Mage.Common/src/mage/view/CardView.java @@ -68,14 +68,16 @@ public class CardView extends SimpleCardView { protected String power; protected String toughness; protected String loyalty; + protected String startingLoyalty; protected List cardTypes; protected List subTypes; protected List superTypes; protected ObjectColor color; + protected ObjectColor frameColor; protected List manaCost; protected int convertedManaCost; protected Rarity rarity; - + protected MageObjectType mageObjectType = MageObjectType.NULL; protected boolean isAbility; @@ -330,6 +332,12 @@ public class CardView extends SimpleCardView { } } } + + // Frame color + this.frameColor = card.getFrameColor(game); + + // Get starting loyalty + this.startingLoyalty = "" + card.getStartingLoyalty(); } public CardView(MageObject object) { @@ -374,6 +382,10 @@ public class CardView extends SimpleCardView { this.expansionSetCode = stackAbility.getExpansionSetCode(); } } + // Frame color + this.frameColor = object.getFrameColor(null); + // Starting loyalty. Must be extracted from an ability + this.startingLoyalty = "" + object.getStartingLoyalty(); } protected CardView() { @@ -408,10 +420,12 @@ public class CardView extends SimpleCardView { this.power = ""; this.toughness = ""; this.loyalty = ""; + this.startingLoyalty = ""; this.cardTypes = new ArrayList<>(); this.subTypes = new ArrayList<>(); this.superTypes = new ArrayList<>(); this.color = new ObjectColor(); + this.frameColor = new ObjectColor(); this.manaCost = new ArrayList<>(); this.convertedManaCost = 0; @@ -452,15 +466,16 @@ public class CardView extends SimpleCardView { this.power = token.getPower().toString(); this.toughness = token.getToughness().toString(); this.loyalty = ""; + this.startingLoyalty = ""; this.cardTypes = token.getCardType(); this.subTypes = token.getSubtype(null); this.superTypes = token.getSupertype(); this.color = token.getColor(null); + this.frameColor = token.getFrameColor(null); this.manaCost = token.getManaCost().getSymbols(); this.rarity = Rarity.NA; this.type = token.getTokenType(); this.tokenSetCode = token.getOriginalExpansionSetCode(); - this.tokenDescriptor = token.getTokenDescriptor(); } protected final void setTargets(Targets targets) { @@ -519,6 +534,10 @@ public class CardView extends SimpleCardView { public String getLoyalty() { return loyalty; } + + public String getStartingLoyalty() { + return startingLoyalty; + } public List getCardTypes() { return cardTypes; @@ -535,6 +554,10 @@ public class CardView extends SimpleCardView { public ObjectColor getColor() { return color; } + + public ObjectColor getFrameColor() { + return frameColor; + } public List getManaCost() { return manaCost; @@ -767,3 +790,4 @@ public class CardView extends SimpleCardView { } } + diff --git a/Mage.Common/src/mage/view/CounterView.java b/Mage.Common/src/mage/view/CounterView.java index b15802c3486..a9c2a61c4c0 100644 --- a/Mage.Common/src/mage/view/CounterView.java +++ b/Mage.Common/src/mage/view/CounterView.java @@ -53,4 +53,21 @@ public class CounterView implements Serializable { public int getCount() { return count; } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if (other == null) { + return false; + } + if (!(other instanceof CounterView)) { + return false; + } + CounterView oth = (CounterView)other; + return + (count == oth.count) && + (name.equals(oth.name)); + } } diff --git a/Mage.Sets/src/mage/sets/onslaught/BloodstainedMire.java b/Mage.Sets/src/mage/sets/onslaught/BloodstainedMire.java index be712d48cd9..c0ace424435 100644 --- a/Mage.Sets/src/mage/sets/onslaught/BloodstainedMire.java +++ b/Mage.Sets/src/mage/sets/onslaught/BloodstainedMire.java @@ -28,6 +28,7 @@ package mage.sets.onslaught; import java.util.UUID; +import mage.ObjectColor; import mage.constants.CardType; import mage.constants.Rarity; import mage.abilities.common.FetchLandActivatedAbility; @@ -42,6 +43,7 @@ public class BloodstainedMire extends CardImpl { public BloodstainedMire(UUID ownerId) { super(ownerId, 313, "Bloodstained Mire", Rarity.RARE, new CardType[]{CardType.LAND}, ""); this.expansionSetCode = "ONS"; + this.frameColor = new ObjectColor("RB"); // {tap}, Pay 1 life, Sacrifice Bloodstained Mire: Search your library for a Swamp or Mountain card and put it onto the battlefield. Then shuffle your library. this.addAbility(new FetchLandActivatedAbility(new String[]{"Swamp", "Mountain"})); diff --git a/Mage.Sets/src/mage/sets/onslaught/FloodedStrand.java b/Mage.Sets/src/mage/sets/onslaught/FloodedStrand.java index e6116d56d8e..97f542dee6e 100644 --- a/Mage.Sets/src/mage/sets/onslaught/FloodedStrand.java +++ b/Mage.Sets/src/mage/sets/onslaught/FloodedStrand.java @@ -28,6 +28,7 @@ package mage.sets.onslaught; import java.util.UUID; +import mage.ObjectColor; import mage.constants.CardType; import mage.constants.Rarity; import mage.abilities.common.FetchLandActivatedAbility; @@ -42,6 +43,7 @@ public class FloodedStrand extends CardImpl { public FloodedStrand(UUID ownerId) { super(ownerId, 316, "Flooded Strand", Rarity.RARE, new CardType[]{CardType.LAND}, ""); this.expansionSetCode = "ONS"; + this.frameColor = new ObjectColor("UW"); // {tap}, Pay 1 life, Sacrifice Flooded Strand: Search your library for a Plains or Island card and put it onto the battlefield. Then shuffle your library. this.addAbility(new FetchLandActivatedAbility(new String[]{"Plains", "Island"})); diff --git a/Mage.Sets/src/mage/sets/onslaught/PollutedDelta.java b/Mage.Sets/src/mage/sets/onslaught/PollutedDelta.java index 19ee047bb0c..44d229431d1 100644 --- a/Mage.Sets/src/mage/sets/onslaught/PollutedDelta.java +++ b/Mage.Sets/src/mage/sets/onslaught/PollutedDelta.java @@ -28,6 +28,7 @@ package mage.sets.onslaught; import java.util.UUID; +import mage.ObjectColor; import mage.constants.CardType; import mage.constants.Rarity; import mage.abilities.common.FetchLandActivatedAbility; @@ -42,6 +43,7 @@ public class PollutedDelta extends CardImpl { public PollutedDelta(UUID ownerId) { super(ownerId, 321, "Polluted Delta", Rarity.RARE, new CardType[]{CardType.LAND}, ""); this.expansionSetCode = "ONS"; + this.frameColor = new ObjectColor("UB"); // {tap}, Pay 1 life, Sacrifice Polluted Delta: Search your library for an Island or Swamp card and put it onto the battlefield. Then shuffle your library. this.addAbility(new FetchLandActivatedAbility(new String[]{"Island", "Swamp"})); diff --git a/Mage.Sets/src/mage/sets/onslaught/WindsweptHeath.java b/Mage.Sets/src/mage/sets/onslaught/WindsweptHeath.java index cef77f08152..78b8ecd6d17 100644 --- a/Mage.Sets/src/mage/sets/onslaught/WindsweptHeath.java +++ b/Mage.Sets/src/mage/sets/onslaught/WindsweptHeath.java @@ -28,6 +28,7 @@ package mage.sets.onslaught; import java.util.UUID; +import mage.ObjectColor; import mage.constants.CardType; import mage.constants.Rarity; import mage.abilities.common.FetchLandActivatedAbility; @@ -42,6 +43,7 @@ public class WindsweptHeath extends CardImpl { public WindsweptHeath(UUID ownerId) { super(ownerId, 328, "Windswept Heath", Rarity.RARE, new CardType[]{CardType.LAND}, ""); this.expansionSetCode = "ONS"; + this.frameColor = new ObjectColor("GW"); // {tap}, Pay 1 life, Sacrifice Windswept Heath: Search your library for a Forest or Plains card and put it onto the battlefield. Then shuffle your library. this.addAbility(new FetchLandActivatedAbility(new String[]{"Forest", "Plains"})); diff --git a/Mage.Sets/src/mage/sets/onslaught/WoodedFoothills.java b/Mage.Sets/src/mage/sets/onslaught/WoodedFoothills.java index 5c13350cfe4..7cce2364af6 100644 --- a/Mage.Sets/src/mage/sets/onslaught/WoodedFoothills.java +++ b/Mage.Sets/src/mage/sets/onslaught/WoodedFoothills.java @@ -28,6 +28,7 @@ package mage.sets.onslaught; import java.util.UUID; +import mage.ObjectColor; import mage.constants.CardType; import mage.constants.Rarity; import mage.abilities.common.FetchLandActivatedAbility; @@ -42,6 +43,7 @@ public class WoodedFoothills extends CardImpl { public WoodedFoothills(UUID ownerId) { super(ownerId, 330, "Wooded Foothills", Rarity.RARE, new CardType[]{CardType.LAND}, ""); this.expansionSetCode = "ONS"; + this.frameColor = new ObjectColor("RG"); // {tap}, Pay 1 life, Sacrifice Wooded Foothills: Search your library for a Mountain or Forest card and put it onto the battlefield. Then shuffle your library. this.addAbility(new FetchLandActivatedAbility(new String[]{"Mountain", "Forest"})); diff --git a/Mage.Sets/src/mage/sets/zendikar/AridMesa.java b/Mage.Sets/src/mage/sets/zendikar/AridMesa.java index d9a0567366f..f7c0c636464 100644 --- a/Mage.Sets/src/mage/sets/zendikar/AridMesa.java +++ b/Mage.Sets/src/mage/sets/zendikar/AridMesa.java @@ -29,6 +29,7 @@ package mage.sets.zendikar; import java.util.UUID; +import mage.ObjectColor; import mage.constants.CardType; import mage.constants.Rarity; import mage.abilities.common.FetchLandActivatedAbility; @@ -43,6 +44,7 @@ public class AridMesa extends CardImpl { public AridMesa(UUID ownerId) { super(ownerId, 211, "Arid Mesa", Rarity.RARE, new CardType[]{CardType.LAND}, null); this.expansionSetCode = "ZEN"; + this.frameColor = new ObjectColor("WR"); this.addAbility(new FetchLandActivatedAbility(new String[] {"Mountain", "Plains"})); } diff --git a/Mage.Sets/src/mage/sets/zendikar/MarshFlats.java b/Mage.Sets/src/mage/sets/zendikar/MarshFlats.java index 31c872f5971..edaf14fd4d3 100644 --- a/Mage.Sets/src/mage/sets/zendikar/MarshFlats.java +++ b/Mage.Sets/src/mage/sets/zendikar/MarshFlats.java @@ -29,6 +29,7 @@ package mage.sets.zendikar; import java.util.UUID; +import mage.ObjectColor; import mage.constants.CardType; import mage.constants.Rarity; import mage.abilities.common.FetchLandActivatedAbility; @@ -43,6 +44,7 @@ public class MarshFlats extends CardImpl { public MarshFlats(UUID ownerId) { super(ownerId, 219, "Marsh Flats", Rarity.RARE, new CardType[]{CardType.LAND}, null); this.expansionSetCode = "ZEN"; + this.frameColor = new ObjectColor("WB"); this.addAbility(new FetchLandActivatedAbility(new String[] {"Swamp", "Plains"})); } diff --git a/Mage.Sets/src/mage/sets/zendikar/MistyRainforest.java b/Mage.Sets/src/mage/sets/zendikar/MistyRainforest.java index c49c4847ed1..c9a80d3b709 100644 --- a/Mage.Sets/src/mage/sets/zendikar/MistyRainforest.java +++ b/Mage.Sets/src/mage/sets/zendikar/MistyRainforest.java @@ -29,6 +29,7 @@ package mage.sets.zendikar; import java.util.UUID; +import mage.ObjectColor; import mage.constants.CardType; import mage.constants.Rarity; import mage.abilities.common.FetchLandActivatedAbility; @@ -43,6 +44,7 @@ public class MistyRainforest extends CardImpl { public MistyRainforest(UUID ownerId) { super(ownerId, 220, "Misty Rainforest", Rarity.RARE, new CardType[]{CardType.LAND}, null); this.expansionSetCode = "ZEN"; + this.frameColor = new ObjectColor("UG"); this.addAbility(new FetchLandActivatedAbility(new String[] {"Forest", "Island"})); } diff --git a/Mage.Sets/src/mage/sets/zendikar/ScaldingTarn.java b/Mage.Sets/src/mage/sets/zendikar/ScaldingTarn.java index b3a9ecf96c4..8c02ba86241 100644 --- a/Mage.Sets/src/mage/sets/zendikar/ScaldingTarn.java +++ b/Mage.Sets/src/mage/sets/zendikar/ScaldingTarn.java @@ -29,6 +29,7 @@ package mage.sets.zendikar; import java.util.UUID; +import mage.ObjectColor; import mage.constants.CardType; import mage.constants.Rarity; import mage.abilities.common.FetchLandActivatedAbility; @@ -43,6 +44,7 @@ public class ScaldingTarn extends CardImpl { public ScaldingTarn(UUID ownerId) { super(ownerId, 223, "Scalding Tarn", Rarity.RARE, new CardType[]{CardType.LAND}, null); this.expansionSetCode = "ZEN"; + this.frameColor = new ObjectColor("UR"); this.addAbility(new FetchLandActivatedAbility(new String[] {"Island", "Mountain"})); } diff --git a/Mage.Sets/src/mage/sets/zendikar/VerdantCatacombs.java b/Mage.Sets/src/mage/sets/zendikar/VerdantCatacombs.java index c3776aa3c96..753ce8a6d36 100644 --- a/Mage.Sets/src/mage/sets/zendikar/VerdantCatacombs.java +++ b/Mage.Sets/src/mage/sets/zendikar/VerdantCatacombs.java @@ -29,6 +29,7 @@ package mage.sets.zendikar; import java.util.UUID; +import mage.ObjectColor; import mage.constants.CardType; import mage.constants.Rarity; import mage.abilities.common.FetchLandActivatedAbility; @@ -43,6 +44,7 @@ public class VerdantCatacombs extends CardImpl { public VerdantCatacombs(UUID ownerId) { super(ownerId, 229, "Verdant Catacombs", Rarity.RARE, new CardType[]{CardType.LAND}, null); this.expansionSetCode = "ZEN"; + this.frameColor = new ObjectColor("BG"); this.addAbility(new FetchLandActivatedAbility(new String[] {"Forest", "Swamp"})); } diff --git a/Mage.Tests/replay_pid4548.log b/Mage.Tests/replay_pid4548.log new file mode 100644 index 00000000000..42adf46b25d --- /dev/null +++ b/Mage.Tests/replay_pid4548.log @@ -0,0 +1,2127 @@ +JvmtiExport can_access_local_variables 0 +JvmtiExport can_hotswap_or_post_breakpoint 0 +JvmtiExport can_post_on_exceptions 0 +# 108 ciObject found +ciMethod java/lang/ref/ReferenceQueue reallyPoll ()Ljava/lang/ref/Reference; 9 1 8004 0 256 +ciMethod java/lang/ref/ReferenceQueue poll ()Ljava/lang/ref/Reference; 2081 1 6409 0 -1 +ciMethod sun/misc/VM addFinalRefCount (I)V 4097 1 15988 0 -1 +ciMethodData java/lang/ref/ReferenceQueue poll ()Ljava/lang/ref/Reference; 2 6410 orig 264 72 34 174 107 0 0 0 0 184 251 220 22 0 0 0 0 80 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 77 68 79 32 101 120 116 114 97 32 100 97 116 97 32 108 111 99 107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 1 0 0 49 192 0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 9 0 2 0 0 0 48 0 0 0 255 255 255 255 7 0 4 0 0 0 0 0 data 6 0x40007 0x7 0x20 0x17ff 0x110002 0x7 oops 0 +ciMethodData java/lang/ref/ReferenceQueue reallyPoll ()Ljava/lang/ref/Reference; 2 8004 orig 264 72 34 174 107 0 0 0 0 240 250 220 22 0 0 0 0 0 2 0 0 64 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 77 68 79 32 101 120 116 114 97 32 100 97 116 97 32 108 111 99 107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 25 250 0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 14 0 2 0 0 0 184 0 0 0 255 255 255 255 7 0 6 0 0 0 0 0 data 23 0x60007 0x6 0xb8 0x1f3d 0xf0007 0x1f35 0x38 0x8 0x130003 0x8 0x18 0x340004 0xfffffffffffffffd 0x297ae60 0x1f3a 0x19890300 0x1 0x370007 0x3 0x30 0x1f3a 0x3b0002 0x1f3a oops 2 13 java/lang/ref/Finalizer 15 java/util/WeakHashMap$Entry +instanceKlass org/apache/maven/surefire/common/junit4/JUnit4StackTraceWriter +instanceKlass org/junit/runner/notification/Failure +instanceKlass mage/sets/mirrodin/GolemSkinGauntletsAttachedCount +instanceKlass mage/sets/mirrodin/ElectrostaticBoltDamageValue +instanceKlass mage/sets/mirrodin/DuplicantContinuousEffect$1 +instanceKlass mage/sets/mirrodin/CantBeBlockedByMoreThanOneAttachedEffect$1 +instanceKlass mage/filter/predicate/permanent/AttachedToPredicate +instanceKlass mage/sets/mirage/AsmiraHolyAvengerDynamicValue +instanceKlass mage/sets/mercadianmasques/NetherSpiritCondition +instanceKlass mage/sets/mercadianmasques/LandGrantCondition +instanceKlass mage/sets/masterseditioniv/XenicPoltergeistEffect$1 +instanceKlass mage/sets/mastersedition/TargetPlayerCardsInHandCount +instanceKlass mage/sets/magicorigins/StarfieldOfNyxEffect$1 +instanceKlass mage/sets/magicorigins/SigilOfValorCount +instanceKlass mage/sets/magicorigins/PsychicRebuttalPredicate +instanceKlass mage/sets/magicorigins/NissaSageAnimistMinusSevenEffect$1 +instanceKlass mage/sets/magicorigins/KytheonHeroOfAkrosCondition +instanceKlass mage/sets/magicorigins/PowerToughnessNotEqualPredicate +instanceKlass mage/sets/magicorigins/EmbermawHellionEffect$1 +instanceKlass mage/sets/magic2015/TheChainVeilCondition +instanceKlass mage/sets/magic2015/PolymorphistsJestEffect$1 +instanceKlass mage/sets/magic2015/OpponentOwnsCardInExileCondition +instanceKlass mage/sets/magic2015/FeastOnTheFallenCondition +instanceKlass mage/sets/magic2015/ControlsEachCreatureWithGreatestPowerCondition +instanceKlass mage/sets/magic2015/ControllerLifeLowerThanStrtingLife +instanceKlass mage/sets/magic2014/LifeCondition +instanceKlass mage/sets/magic2014/DismissIntoDreamEffect$1 +instanceKlass mage/sets/magic2014/CreatureCardsInControllerGraveCondition +instanceKlass mage/sets/magic2013/IsBeingCastFromHandCondition +instanceKlass mage/sets/magic2012/SuturedGhoulToughnessCount +instanceKlass mage/sets/magic2012/SuturedGhoulPowerCount +instanceKlass mage/sets/magic2012/GrandAbolisherEffect$1 +instanceKlass mage/sets/magic2011/VolcanicStrengthEffect$1 +instanceKlass mage/sets/magic2011/StormtideLeviathanEffect$1 +instanceKlass mage/sets/magic2011/SerraAscendantEffect$1 +instanceKlass mage/sets/magic2011/GargoyleSentinelEffect$1 +instanceKlass mage/sets/magic2011/DryadsFavorEffect$1 +instanceKlass mage/sets/magic2011/CaptivatingVampireEffect$1 +instanceKlass mage/sets/magic2010/VampireNocturnusCondition +instanceKlass mage/sets/magic2010/RiseFromTheGraveEffect$1 +instanceKlass mage/sets/magic2010/OakenformEffect$1 +instanceKlass mage/sets/magic2010/FaceUpPredicate +instanceKlass mage/sets/magic2010/ConvincingMirageContinousEffect$1 +instanceKlass mage/sets/magic2010/ChandraNalaarXValue +instanceKlass mage/sets/lorwyn/WindbriskHeightsAttackersCondition +instanceKlass mage/sets/lorwyn/SoulbrightFlamekinEffect$ActivationInfo +instanceKlass mage/sets/lorwyn/InnerFlameIgniterEffect$ActivationInfo +instanceKlass mage/sets/lorwyn/DamagedThisTurnPredicate +instanceKlass mage/sets/lorwyn/AshlingThePilgrimEffect$ActivationInfo +instanceKlass mage/sets/limitedalpha/PhantasmalTerrainContinuousEffect$1 +instanceKlass mage/sets/limitedalpha/HalfForestsUpCount +instanceKlass mage/sets/limitedalpha/HalfForestsDownCount +instanceKlass mage/sets/limitedalpha/Conversion$1 +instanceKlass mage/sets/limitedalpha/BurrowingEffect$1 +instanceKlass mage/sets/legions/CallerOfTheClawDynamicValue +instanceKlass mage/sets/legends/BeforeCombatDamageCondition +instanceKlass mage/sets/knightsvsdragons/PaladinOfPrahvTriggeredAbility$1 +instanceKlass mage/sets/khansoftarkir/TargetHasCounterCondition +instanceKlass mage/sets/khansoftarkir/SarkhanTheDragonspeakerEffect$1 +instanceKlass mage/sets/judgment/FiftyOrMoreLifeCondition +instanceKlass mage/sets/journeyintonyx/DictateOfTheTwinGodsEffect$1 +instanceKlass mage/sets/jacevschandra/HostilityEffect$1 +instanceKlass mage/sets/invasion/SpiritOfResistanceCondition +instanceKlass mage/sets/invasion/KangeeAerieKeeperGetKickerXValue +instanceKlass mage/sets/invasion/GetKickerXValue +instanceKlass mage/sets/invasion/DivinePresenceEffect$1 +instanceKlass mage/sets/innistrad/RunechantersPikeValue +instanceKlass mage/sets/innistrad/HasDefenderCondition +instanceKlass mage/sets/innistrad/HalfZombiesCount +instanceKlass mage/sets/innistrad/GutterGrimeCounters +instanceKlass mage/sets/innistrad/GrimoireOfTheDeadEffect2$1 +instanceKlass mage/sets/innistrad/GarrukTheVeilCursedValue +instanceKlass mage/sets/innistrad/EvilTwinPredicate +instanceKlass mage/sets/heroesvsmonsters/OpponentWasDealtDamageCondition +instanceKlass mage/filter/predicate/permanent/EnchantedPredicate +instanceKlass mage/sets/gatecrash/TargetPermanentPowerPlusToughnessCount +instanceKlass mage/sets/gatecrash/SameControllerPredicate +instanceKlass mage/sets/gatecrash/RealmwrightEffect2$1 +instanceKlass mage/sets/gatecrash/greatestPowerCountCreatureYouControl +instanceKlass mage/sets/gatecrash/greatestPowerCount +instanceKlass mage/filter/predicate/mageobject/VariableManaCostPredicate +instanceKlass mage/sets/gatecrash/DyingWishAttachedPermanentPowerCount +instanceKlass mage/sets/gatecrash/CardsInOpponentsGraveyardsCount +instanceKlass mage/sets/gatecrash/CardsInOpponentGraveyardsCount +instanceKlass mage/sets/gatecrash/CardsInEnchantedCreaturesControllerGraveyardCount +instanceKlass mage/sets/gatecrash/CardsInControllerLibraryCount +instanceKlass mage/sets/gatecrash/CantBeBlockedByMoreThanOneAttachedEffect$1 +instanceKlass mage/sets/gatecrash/AttachedPermanentPowerCount +instanceKlass mage/sets/gameday/ScaleguardSentinelsCondition +instanceKlass mage/sets/futuresight/OtherSpellsCastThisTurnCount +instanceKlass mage/sets/futuresight/MagusOfTheMoon$1 +instanceKlass mage/sets/futuresight/MadnessPaidCondition +instanceKlass mage/sets/futuresight/CastWhiteSpellThisTurnCondition +instanceKlass mage/sets/futuresight/AuraAttachedPredicate +instanceKlass mage/sets/shadowmoor/BeseechTheQueenPredicate +instanceKlass mage/sets/fourthedition/TitaniasSongEffect$1 +instanceKlass mage/sets/fourthedition/TargetPermanentToughnessMinus1Value +instanceKlass mage/sets/fourthedition/TargetMatchesFilterCondition +instanceKlass mage/sets/fourthedition/ErgRaidersCondition +instanceKlass mage/sets/fifthedition/CardIdPredicate +instanceKlass mage/sets/modernmasters/PowerIslandPredicate +instanceKlass mage/filter/predicate/permanent/DamagedPlayerThisTurnPredicate +instanceKlass mage/target/targetpointer/FirstTargetPointer +instanceKlass mage/abilities/costs/AdjustingSourceCosts +instanceKlass mage/sets/fifthdawn/MephidrossVampireEffect$1 +instanceKlass mage/sets/fifthdawn/HelmOfKaldraCondition +instanceKlass mage/sets/fifthdawn/GetXValue +instanceKlass mage/abilities/costs/mana/ManaCostImpl$1 +instanceKlass mage/Mana$1 +instanceKlass mage/sets/fifthdawn/ChimericCoilsEffect$1 +instanceKlass mage/sets/fatereforged/YasovaDragonclawPowerLessThanSourcePredicate +instanceKlass mage/abilities/effects/common/continuous/SourceEffect +instanceKlass mage/sets/fatereforged/SagesReveriePredicate +instanceKlass mage/sets/fatereforged/RenownedWeaponsmithCondition +instanceKlass mage/sets/fatereforged/CrucibleOfTheSpiritDragonManaCondition +instanceKlass mage/sets/fatereforged/BloodfireEnforcersCondition +instanceKlass mage/sets/fallenempires/AttachmentByUUIDPredicate +instanceKlass mage/sets/exodus/OathOfLiegesPredicate +instanceKlass mage/sets/exodus/OathOfDruidsPredicate +instanceKlass mage/abilities/effects/PayCostToAttackBlockEffect +instanceKlass mage/sets/exodus/CardsInTargetPlayerHandCount +instanceKlass mage/sets/eventide/OpponentHasNoCardsInHandCondition +instanceKlass mage/sets/eventide/TargetYouPredicate +instanceKlass mage/sets/eventide/DivinityOfPrideCondition +instanceKlass mage/sets/eventide/ChromaUmbraStalkerCount +instanceKlass mage/sets/eventide/ChromaSpringjackShepherdCount +instanceKlass mage/sets/eventide/ChromaSanityGrindingCount +instanceKlass mage/sets/eventide/ChromaPrimalcruxCount +instanceKlass mage/sets/eventide/ChromaOutrageShamanCount +instanceKlass mage/sets/eventide/ChromaLightFromWithinCount +instanceKlass mage/sets/eventide/ChromaHeartlashCinderCount +instanceKlass mage/sets/eventide/CastRedSpellThisTurnCondition +instanceKlass mage/sets/eventide/CastGreenSpellThisTurnCondition +instanceKlass mage/sets/eventide/CastBlueSpellThisTurnCondition +instanceKlass mage/sets/eventide/CastBlackSpellThisTurnCondition +instanceKlass mage/sets/eldritchmoon/ZombiesControlledByTargetPlayerCount +instanceKlass mage/filter/predicate/other/TargetsPermanentPredicate +instanceKlass mage/sets/eldritchmoon/OathOfLilianaCondition +instanceKlass mage/sets/eldritchmoon/LilianaZombiesCount +instanceKlass mage/sets/eldritchmoon/IsBeingCastFromHandCondition +instanceKlass mage/sets/eldritchmoon/InstantOrSorceryCardsInControllerGraveCondition +instanceKlass mage/sets/eldritchmoon/GalvanicBombardmentCardsInControllerGraveyardCount +instanceKlass mage/sets/eldritchmoon/EquippedDealtCombatDamageToCreatureCondition +instanceKlass mage/filter/predicate/other/PlayerPredicate +instanceKlass mage/sets/eldritchmoon/BecomesColorlessLandEffect$1 +instanceKlass mage/sets/dragonsoftarkir/VolcanicVisionReturnToHandTargetEffect$1 +instanceKlass mage/sets/dragonsoftarkir/ShamanOfForgottenWaysManaCondition +instanceKlass mage/sets/dragonsoftarkir/QarsiDeceiverManaCondition +instanceKlass mage/sets/dragonsoftarkir/PlayerCastNonCreatureSpellCondition +instanceKlass mage/sets/dragonsoftarkir/UginPlaneswalkerCardPredicate +instanceKlass mage/sets/dragonsoftarkir/DragonlordsPrerogativeCondition +instanceKlass mage/sets/dragonsoftarkir/DragonCreatureCardPredicate +instanceKlass mage/sets/dragonsoftarkir/DeathbringerRegentCondition +instanceKlass mage/sets/dragonsoftarkir/CountersOnControlledCount +instanceKlass mage/sets/dragonsmaze/TurnBurn$1 +instanceKlass mage/sets/dragonsmaze/TargetPlayerCardsInHandCount +instanceKlass mage/sets/dragonsmaze/MasterOfCrueltiesNoDamageEffect$1 +instanceKlass mage/filter/predicate/other/PlayerIdPredicate +instanceKlass mage/sets/dragonsmaze/BloodBaronOfVizkopaEffect$1 +instanceKlass mage/sets/dissension/SameControllerPredicate +instanceKlass mage/sets/dissension/SacrificedWasCondition +instanceKlass mage/sets/dissension/MightOfTheNephilimValue +instanceKlass mage/sets/dissension/HasAbilityWithTapSymbolPredicate +instanceKlass mage/filter/predicate/mageobject/MonocoloredPredicate +instanceKlass mage/sets/dissension/EnchantedCreatureColorsCount +instanceKlass mage/sets/darksteel/SwordOfLightAndShadowReturnToHandTargetEffect$1 +instanceKlass mage/sets/darksteel/SourceUntappedCondition +instanceKlass mage/abilities/effects/AsThoughManaEffect +instanceKlass mage/sets/darksteel/EmissaryOfDespairCount +instanceKlass mage/sets/darksteel/BurdenOfGreedCount +instanceKlass mage/sets/darkascension/SpellZonePredicate +instanceKlass mage/sets/darkascension/DungeonGeistsEffect$1 +instanceKlass mage/sets/darkascension/CursesAttachedCount +instanceKlass mage/sets/darkascension/AltarOfTheLostManaCondition +instanceKlass mage/sets/conspiracy/TappedLandsCount +instanceKlass mage/sets/conflux/TwiceDevouredGoblins +instanceKlass mage/sets/conflux/testCondition +instanceKlass mage/sets/conflux/ParagonOfTheAmesha$1 +instanceKlass mage/sets/conflux/DragonsoulKnight$1 +instanceKlass mage/sets/conflux/ControlsAnotherArtifactCondition +instanceKlass mage/sets/conflux/CardsInChosenPlayerHandCount +instanceKlass mage/sets/commander2015/SourceControllerExperienceCountersCount +instanceKlass mage/sets/commander2015/MizzixOfTheIzmagnusPredicate +instanceKlass mage/filter/predicate/permanent/CommanderPredicate +instanceKlass mage/sets/commander2015/ArachnogenesisCount +instanceKlass mage/sets/commander2015/AnyaMercilessAngelDynamicValue +instanceKlass mage/sets/commander2015/AnyaMercilessAngelCondition +instanceKlass mage/sets/commander2014/NecromanticSelectionContinuousEffect$1 +instanceKlass mage/filter/predicate/other/FaceDownPredicate +instanceKlass mage/sets/commander2014/GreatestAmountOfDamageWatcher$1 +instanceKlass mage/sets/commander2014/GreatestAmountOfDamageDealtValue +instanceKlass mage/sets/commander2014/BitterFeudEffect$1 +instanceKlass mage/sets/commander2014/BecomesColorlessForestLandEffect$1 +instanceKlass mage/sets/commander2013/TerraRavagerLandCount +instanceKlass mage/counters/CounterType$1 +instanceKlass mage/sets/commander2013/SydriGalvanicGeniusEffect$1 +instanceKlass mage/sets/commander2013/RubiniaSoulsingerCondition +instanceKlass mage/choices/ChoiceImpl +instanceKlass mage/sets/commander2013/MosswortBridgeTotalPowerCondition +instanceKlass mage/sets/commander2013/ChangeMaxAttackedBySourceEffect$1 +instanceKlass mage/sets/commander/VishKalBloodArbiterDynamicValue +instanceKlass mage/filter/predicate/mageobject/AnotherCardPredicate +instanceKlass mage/sets/commander/CardsInTargetOpponentsGraveyardCount +instanceKlass mage/abilities/costs/VariableCostImpl +instanceKlass mage/sets/coldsnap/LightningStormCountCondition +instanceKlass mage/sets/championsofkamigawa/ZuberasDiedDynamicValue +instanceKlass mage/sets/championsofkamigawa/WickedAkubaPredicate +instanceKlass mage/sets/championsofkamigawa/SilentChantZuberaDynamicValue +instanceKlass mage/sets/championsofkamigawa/SiftThroughSandsCondition +instanceKlass mage/sets/championsofkamigawa/TargetYouPredicate +instanceKlass mage/sets/championsofkamigawa/OathkeeperEquippedMatchesFilterCondition +instanceKlass mage/sets/championsofkamigawa/CardsInTargetOpponentHandCondition +instanceKlass mage/sets/championsofkamigawa/CardsInTargetOpponentHandCondition$1 +instanceKlass mage/filter/predicate/permanent/WasDealtDamageThisTurnPredicate +instanceKlass mage/sets/championsofkamigawa/AttachmentAttachedToCardTypePredicate +instanceKlass mage/sets/bornofthegods/MindreaverNamePredicate +instanceKlass mage/sets/bornofthegods/HeroesPodiumLegendaryCount +instanceKlass mage/sets/bornofthegods/HadAnotherCreatureEnterTheBattlefieldCondition +instanceKlass mage/sets/betrayersofkamigawa/UmezawasJitteAbility$1 +instanceKlass mage/filter/predicate/permanent/CounterPredicate +instanceKlass mage/sets/betrayersofkamigawa/TallowispAbilityPredicate +instanceKlass mage/sets/betrayersofkamigawa/SlumberingTora$1 +instanceKlass mage/filter/predicate/permanent/UnblockedPredicate +instanceKlass mage/abilities/condition/common/SourceIsSpellCondition +instanceKlass mage/abilities/costs/AlternativeCost2 +instanceKlass mage/abilities/costs/AlternativeSourceCosts +instanceKlass mage/sets/betrayersofkamigawa/ColorlessConvertedManaCost +instanceKlass mage/abilities/costs/DynamicCost +instanceKlass mage/filter/predicate/permanent/CounterAnyPredicate +instanceKlass mage/sets/betrayersofkamigawa/CallForBloodDynamicValue +instanceKlass mage/sets/battleforzendikar/FirstCastCreatureSpellPredicate +instanceKlass mage/filter/predicate/mageobject/ColorlessPredicate +instanceKlass mage/sets/avacynrestored/VanguardsShieldEffect$1 +instanceKlass mage/sets/avacynrestored/TappedCreaturesControlledByTargetCount +instanceKlass mage/game/command/Emblem +instanceKlass mage/game/command/CommandObject +instanceKlass mage/sets/avacynrestored/SecondSpellPredicate +instanceKlass mage/util/functions/ApplyToMageObject +instanceKlass mage/sets/avacynrestored/HighestLifeTotalAmongOpponentsCount +instanceKlass mage/sets/avacynrestored/GiselaBladeOfGoldnightDoubleDamageEffect$1 +instanceKlass mage/sets/avacynrestored/DreadSlaverContiniousEffect$1 +instanceKlass mage/abilities/mana/conditional/ManaCondition +instanceKlass mage/sets/avacynrestored/CardsInTargetHandCount +instanceKlass mage/sets/arabiannights/SourcePowerGreaterEqualTargetCondition +instanceKlass mage/sets/arabiannights/PyramidsPredicate +instanceKlass mage/sets/arabiannights/PowerLowerEqualSourcePredicate +instanceKlass mage/sets/arabiannights/NoColoredPermanentOpponentCondition +instanceKlass mage/Mana +instanceKlass mage/sets/arabiannights/MagneticMountainEffect$MagneticMountainPredicate +instanceKlass mage/abilities/condition/IntCompareCondition +instanceKlass mage/abilities/effects/PreventionEffect +instanceKlass mage/abilities/effects/CostModificationEffect +instanceKlass mage/filter/predicate/other/OwnerPredicate +instanceKlass mage/abilities/mana/builder/ConditionalManaBuilder +instanceKlass mage/abilities/mana/builder/Builder +instanceKlass mage/filter/predicate/other/ExpansionSetPredicate +instanceKlass mage/filter/predicate/mageobject/NumberOfTargetsPredicate +instanceKlass mage/MageInt +instanceKlass sun/nio/fs/BasicFileAttributesHolder +instanceKlass sun/nio/fs/WindowsDirectoryStream$WindowsDirectoryIterator +instanceKlass sun/nio/fs/WindowsFileAttributes +instanceKlass java/nio/file/attribute/DosFileAttributes +instanceKlass java/nio/file/attribute/BasicFileAttributes +instanceKlass sun/nio/fs/NativeBuffer$Deallocator +instanceKlass sun/nio/fs/NativeBuffer +instanceKlass sun/nio/fs/NativeBuffers +instanceKlass sun/nio/fs/WindowsNativeDispatcher$BackupResult +instanceKlass sun/nio/fs/WindowsNativeDispatcher$CompletionStatus +instanceKlass sun/nio/fs/WindowsNativeDispatcher$AclInformation +instanceKlass sun/nio/fs/WindowsNativeDispatcher$Account +instanceKlass sun/nio/fs/WindowsNativeDispatcher$DiskFreeSpace +instanceKlass sun/nio/fs/WindowsNativeDispatcher$VolumeInformation +instanceKlass sun/nio/fs/WindowsNativeDispatcher$FirstStream +instanceKlass sun/nio/fs/WindowsNativeDispatcher$FirstFile +instanceKlass sun/nio/fs/WindowsNativeDispatcher$1 +instanceKlass sun/nio/fs/WindowsNativeDispatcher +instanceKlass sun/nio/fs/WindowsDirectoryStream +instanceKlass java/nio/file/DirectoryStream +instanceKlass java/nio/file/Files$AcceptAllFilter +instanceKlass java/nio/file/DirectoryStream$Filter +instanceKlass java/nio/file/Files +instanceKlass sun/nio/fs/AbstractPath +instanceKlass sun/nio/fs/Util +instanceKlass sun/nio/fs/WindowsPathParser$Result +instanceKlass sun/nio/fs/WindowsPathParser +instanceKlass java/nio/file/FileSystem +instanceKlass java/nio/file/spi/FileSystemProvider +instanceKlass sun/nio/fs/DefaultFileSystemProvider +instanceKlass java/nio/file/FileSystems$DefaultFileSystemHolder$1 +instanceKlass java/nio/file/FileSystems$DefaultFileSystemHolder +instanceKlass java/nio/file/FileSystems +instanceKlass java/net/NetworkInterface$2 +instanceKlass java/net/DefaultInterface +instanceKlass java/net/InterfaceAddress +instanceKlass java/net/NetworkInterface$1 +instanceKlass java/net/NetworkInterface +instanceKlass sun/security/provider/SeedGenerator$1 +instanceKlass sun/security/provider/SecureRandom$SeederHolder +instanceKlass java/util/UUID$Holder +instanceKlass mage/filter/predicate/Predicates$AndPredicate +instanceKlass mage/filter/FilterMana +instanceKlass mage/filter/predicate/mageobject/NamePredicate +instanceKlass mage/abilities/dynamicvalue/common/ManacostVariableValue +instanceKlass mage/abilities/costs/CostImpl +instanceKlass mage/sets/alarareborn/XPaid +instanceKlass mage/filter/predicate/permanent/TokenPredicate +instanceKlass mage/abilities/effects/AsThoughEffect +instanceKlass mage/abilities/effects/ReplacementEffect +instanceKlass mage/abilities/effects/ContinuousRuleModifyingEffect +instanceKlass mage/sets/alarareborn/LordOfExtinctionDynamicCount +instanceKlass mage/filter/predicate/permanent/TappedPredicate +instanceKlass mage/filter/predicate/IntComparePredicate +instanceKlass mage/filter/predicate/permanent/AttackingPredicate +instanceKlass mage/filter/predicate/permanent/BlockedPredicate +instanceKlass mage/filter/predicate/permanent/BlockingPredicate +instanceKlass mage/sets/alarareborn/DidNotCastCreatureCondition +instanceKlass mage/abilities/MageSingleton +instanceKlass mage/filter/predicate/mageobject/AbilityPredicate +instanceKlass mage/filter/predicate/mageobject/MulticoloredPredicate +instanceKlass mage/sets/alarareborn/AnathemancerCount +instanceKlass org/h2/mvstore/WriteBuffer +instanceKlass mage/sets/alarareborn/AllPlayersLostLifeCount +instanceKlass org/h2/mvstore/Chunk +instanceKlass mage/filter/predicate/mageobject/SupertypePredicate +instanceKlass mage/abilities/dynamicvalue/DynamicValue +instanceKlass mage/watchers/Watcher +instanceKlass mage/filter/predicate/mageobject/SubtypePredicate +instanceKlass mage/abilities/effects/ContinuousEffect +instanceKlass mage/filter/predicate/Predicates$OrPredicate +instanceKlass mage/filter/predicate/permanent/ControllerPredicate +instanceKlass mage/abilities/condition/Condition +instanceKlass mage/filter/predicate/permanent/AnotherPredicate +instanceKlass mage/filter/predicate/ObjectSourcePlayerPredicate +instanceKlass mage/filter/predicate/ObjectPlayerPredicate +instanceKlass mage/filter/predicate/Predicates$NotPredicate +instanceKlass mage/filter/predicate/Predicates +instanceKlass mage/ObjectColor +instanceKlass mage/filter/predicate/mageobject/ColorPredicate +instanceKlass mage/filter/predicate/mageobject/CardTypePredicate +instanceKlass mage/target/targetpointer/TargetPointer +instanceKlass mage/abilities/effects/EffectImpl +instanceKlass mage/abilities/effects/Effect +instanceKlass mage/game/stack/StackObject +instanceKlass mage/game/events/GameEvent +instanceKlass mage/MageObjectImpl +instanceKlass org/h2/mvstore/DataUtils$MapEntry +instanceKlass org/h2/mvstore/Page$PageReference +instanceKlass org/h2/mvstore/db/TransactionStore$TransactionMap$1 +instanceKlass org/h2/util/DateTimeUtils +instanceKlass org/h2/mvstore/db/MVTable$1 +instanceKlass org/h2/index/SpatialIndex +instanceKlass org/h2/engine/Constants +instanceKlass java/text/FieldPosition$Delegate +instanceKlass mage/cards/repository/ExpansionInfo +instanceKlass com/j256/ormlite/support/GeneratedKeyHolder +instanceKlass com/j256/ormlite/misc/BaseDaoEnabled +instanceKlass java/sql/Array +instanceKlass org/h2/result/ResultExternal +instanceKlass org/h2/result/LocalResult +instanceKlass com/j256/ormlite/jdbc/JdbcDatabaseResults +instanceKlass com/j256/ormlite/stmt/SelectIterator +instanceKlass com/j256/ormlite/jdbc/TypeValMapper$1 +instanceKlass com/j256/ormlite/jdbc/TypeValMapper +instanceKlass org/h2/table/Plan$1 +instanceKlass org/h2/table/Plan +instanceKlass org/h2/command/dml/Optimizer +instanceKlass com/j256/ormlite/stmt/mapped/BaseMappedStatement +instanceKlass com/j256/ormlite/stmt/PreparedUpdate +instanceKlass com/j256/ormlite/stmt/PreparedDelete +instanceKlass com/j256/ormlite/stmt/ColumnArg +instanceKlass com/j256/ormlite/stmt/query/ManyClause +instanceKlass com/j256/ormlite/stmt/query/BaseComparison +instanceKlass com/j256/ormlite/stmt/query/Comparison +instanceKlass com/j256/ormlite/stmt/BaseArgumentHolder +instanceKlass com/j256/ormlite/stmt/ArgumentHolder +instanceKlass com/j256/ormlite/stmt/query/NeedsFutureClause +instanceKlass com/j256/ormlite/stmt/query/Clause +instanceKlass com/j256/ormlite/stmt/Where +instanceKlass com/j256/ormlite/stmt/PreparedQuery +instanceKlass com/j256/ormlite/stmt/StatementBuilder +instanceKlass com/j256/ormlite/jdbc/JdbcCompiledStatement +instanceKlass java/nio/DirectByteBuffer$Deallocator +instanceKlass sun/nio/ch/Util$BufferCache +instanceKlass sun/nio/ch/Util$2 +instanceKlass sun/nio/ch/Util +instanceKlass sun/nio/ch/IOStatus +instanceKlass java/nio/channels/spi/AbstractInterruptibleChannel$1 +instanceKlass sun/nio/ch/FileKey +instanceKlass sun/nio/ch/FileLockTable +instanceKlass sun/nio/ch/NativeThread +instanceKlass java/nio/channels/FileLock +instanceKlass sun/nio/ch/FileDispatcherImpl$1 +instanceKlass sun/nio/ch/NativeDispatcher +instanceKlass sun/nio/ch/NativeThreadSet +instanceKlass sun/nio/ch/IOUtil$1 +instanceKlass sun/nio/ch/IOUtil +instanceKlass java/io/RandomAccessFile +instanceKlass java/nio/file/attribute/FileAttribute +instanceKlass org/h2/mvstore/cache/CacheLongKeyLIRS$Entry +instanceKlass org/h2/mvstore/cache/CacheLongKeyLIRS$Segment +instanceKlass org/h2/mvstore/cache/CacheLongKeyLIRS +instanceKlass org/h2/mvstore/FreeSpaceBitSet +instanceKlass org/h2/mvstore/FileStore +instanceKlass org/h2/mvstore/db/MVTableEngine$1 +instanceKlass org/h2/mvstore/MVStoreTool +instanceKlass sun/net/ResourceManager +instanceKlass java/lang/Throwable$PrintStreamOrWriter +instanceKlass java/net/Socket$3 +instanceKlass java/net/Socket$2 +instanceKlass org/h2/value/Transfer +instanceKlass org/h2/util/SmallMap +instanceKlass org/h2/server/TcpServerThread +instanceKlass java/net/Proxy +instanceKlass sun/net/spi/DefaultProxySelector$3 +instanceKlass sun/net/spi/DefaultProxySelector$NonProxyInfo +instanceKlass sun/net/NetProperties$1 +instanceKlass sun/net/NetProperties +instanceKlass sun/net/spi/DefaultProxySelector$1 +instanceKlass java/net/ProxySelector +instanceKlass java/net/SocksSocketImpl$3 +instanceKlass sun/net/util/IPAddressUtil +instanceKlass java/net/Socket +instanceKlass java/net/InetAddress$CacheEntry +instanceKlass sun/net/InetAddressCachePolicy$2 +instanceKlass sun/net/InetAddressCachePolicy$1 +instanceKlass sun/net/InetAddressCachePolicy +instanceKlass org/h2/table/PlanItem +instanceKlass org/h2/index/IndexCondition +instanceKlass org/h2/index/IndexCursor +instanceKlass org/h2/table/TableFilter +instanceKlass org/h2/result/ResultInterface +instanceKlass java/sql/ParameterMetaData +instanceKlass java/sql/ResultSetMetaData +instanceKlass org/h2/expression/ExpressionVisitor +instanceKlass org/h2/engine/FunctionAlias$JavaMethod +instanceKlass org/h2/engine/Session$Savepoint +instanceKlass org/h2/expression/FunctionInfo +instanceKlass java/util/concurrent/atomic/AtomicReference +instanceKlass org/h2/mvstore/StreamStore +instanceKlass org/h2/value/Value$ValueBlob +instanceKlass org/h2/value/Value$ValueClob +instanceKlass org/h2/store/LobStorageMap +instanceKlass org/h2/mvstore/rtree/SpatialKey +instanceKlass org/h2/mvstore/db/TransactionStore$VersionedValue +instanceKlass org/h2/engine/MetaRecord +instanceKlass org/h2/result/Row +instanceKlass org/h2/mvstore/db/TransactionStore$TransactionMap$2 +instanceKlass org/h2/mvstore/db/MVPrimaryIndex$MVStoreCursor +instanceKlass org/h2/util/StatementBuilder +instanceKlass org/h2/table/TableFilter$TableFilterVisitor +instanceKlass org/h2/command/Command +instanceKlass org/h2/expression/ParameterInterface +instanceKlass org/h2/expression/FunctionCall +instanceKlass org/h2/result/ResultTarget +instanceKlass org/h2/command/Prepared +instanceKlass org/h2/command/Parser +instanceKlass org/h2/mvstore/db/TransactionStore$TransactionMap +instanceKlass org/h2/mvstore/db/TransactionStore$Transaction +instanceKlass org/h2/index/IndexType +instanceKlass org/h2/table/IndexColumn +instanceKlass org/h2/index/Cursor +instanceKlass org/h2/mvstore/db/MVIndex +instanceKlass org/h2/index/Index +instanceKlass org/h2/api/ErrorCode +instanceKlass org/h2/util/JdbcUtils +instanceKlass org/h2/value/DataType +instanceKlass org/h2/table/ColumnResolver +instanceKlass org/h2/expression/Expression +instanceKlass org/h2/table/Column +instanceKlass org/h2/command/ddl/CreateTableData +instanceKlass org/h2/engine/UndoLog +instanceKlass org/h2/mvstore/CursorPos +instanceKlass org/h2/mvstore/Cursor +instanceKlass org/h2/mvstore/db/TransactionStore$ArrayType +instanceKlass org/h2/mvstore/db/TransactionStore$VersionedValueType +instanceKlass org/h2/mvstore/type/ObjectDataType$AutoDetectDataType +instanceKlass org/h2/mvstore/type/ObjectDataType +instanceKlass org/h2/mvstore/MVMap$Builder +instanceKlass org/h2/mvstore/db/ValueDataType +instanceKlass org/h2/mvstore/db/TransactionStore +instanceKlass org/h2/mvstore/DataUtils +instanceKlass org/h2/mvstore/Page +instanceKlass org/h2/mvstore/ConcurrentArrayList +instanceKlass org/h2/mvstore/type/StringDataType +instanceKlass org/h2/mvstore/MVMap$MapBuilder +instanceKlass org/h2/mvstore/MVStore +instanceKlass org/h2/mvstore/type/DataType +instanceKlass org/h2/mvstore/db/MVTableEngine$Store +instanceKlass org/h2/mvstore/MVStore$Builder +instanceKlass org/h2/engine/DbObjectBase +instanceKlass org/h2/mvstore/db/MVTableEngine +instanceKlass org/h2/api/TableEngine +instanceKlass java/net/Inet6Address$Inet6AddressHolder +instanceKlass sun/net/NetHooks +instanceKlass java/net/Inet4AddressImpl +instanceKlass java/net/InetAddress$2 +instanceKlass sun/net/spi/nameservice/NameService +instanceKlass java/net/Inet6AddressImpl +instanceKlass java/net/InetAddressImpl +instanceKlass java/net/InetAddressImplFactory +instanceKlass java/net/InetAddress$Cache +instanceKlass java/net/InetAddress$InetAddressHolder +instanceKlass java/net/InetAddress$1 +instanceKlass java/net/InetSocketAddress$InetSocketAddressHolder +instanceKlass java/net/InetAddress +instanceKlass sun/misc/FloatingDecimal$ASCIIToBinaryBuffer +instanceKlass java/net/PlainSocketImpl$1 +instanceKlass java/net/AbstractPlainSocketImpl$1 +instanceKlass java/net/SocketImpl +instanceKlass java/net/SocketOptions +instanceKlass java/net/SocksConsts +instanceKlass java/net/ServerSocket +instanceKlass java/net/SocketAddress +instanceKlass org/h2/util/NetUtils +instanceKlass org/h2/server/TcpServer +instanceKlass org/h2/server/Service +instanceKlass org/h2/util/Tool +instanceKlass org/h2/server/ShutdownHandler +instanceKlass sun/util/locale/provider/TimeZoneNameUtility$TimeZoneNameGetter +instanceKlass sun/util/locale/provider/TimeZoneNameUtility +instanceKlass sun/nio/cs/Surrogate +instanceKlass sun/nio/cs/Surrogate$Parser +instanceKlass org/h2/util/IOUtils +instanceKlass sun/security/provider/ByteArrayAccess +instanceKlass sun/security/provider/SeedGenerator +instanceKlass org/h2/util/MathUtils$1 +instanceKlass sun/security/jca/GetInstance$Instance +instanceKlass java/security/MessageDigestSpi +instanceKlass java/security/Provider$UString +instanceKlass java/security/Provider$Service +instanceKlass sun/security/provider/NativePRNG$NonBlocking +instanceKlass sun/security/provider/NativePRNG$Blocking +instanceKlass sun/security/provider/NativePRNG +instanceKlass sun/security/provider/SunEntries$1 +instanceKlass sun/security/provider/SunEntries +instanceKlass sun/security/jca/ProviderConfig$2 +instanceKlass java/security/Security$1 +instanceKlass java/security/Security +instanceKlass sun/security/jca/ProviderList$2 +instanceKlass sun/misc/FDBigInteger +instanceKlass sun/misc/FloatingDecimal$PreparedASCIIToBinaryBuffer +instanceKlass sun/misc/FloatingDecimal$ASCIIToBinaryConverter +instanceKlass sun/misc/FloatingDecimal$BinaryToASCIIBuffer +instanceKlass sun/misc/FloatingDecimal$ExceptionalBinaryToASCIIBuffer +instanceKlass sun/misc/FloatingDecimal$BinaryToASCIIConverter +instanceKlass sun/misc/FloatingDecimal +instanceKlass java/security/Provider$EngineDescription +instanceKlass java/security/Provider$ServiceKey +instanceKlass sun/security/jca/ProviderConfig +instanceKlass sun/security/jca/ProviderList +instanceKlass sun/security/jca/Providers +instanceKlass sun/security/jca/GetInstance +instanceKlass java/security/SecureRandomSpi +instanceKlass org/h2/message/Trace +instanceKlass org/h2/message/TraceSystem +instanceKlass org/h2/message/TraceWriter +instanceKlass org/h2/util/TempFileDeleter +instanceKlass org/h2/engine/Mode +instanceKlass org/h2/util/BitField +instanceKlass org/h2/schema/SchemaObject +instanceKlass org/h2/engine/DbObject +instanceKlass org/h2/result/SearchRow +instanceKlass org/h2/engine/Database +instanceKlass org/h2/compress/CompressLZF +instanceKlass org/h2/compress/Compressor +instanceKlass org/h2/store/fs/FileMemData +instanceKlass java/nio/channels/spi/AbstractInterruptibleChannel +instanceKlass java/nio/channels/InterruptibleChannel +instanceKlass java/nio/channels/ScatteringByteChannel +instanceKlass java/nio/channels/GatheringByteChannel +instanceKlass java/nio/channels/SeekableByteChannel +instanceKlass java/nio/channels/ByteChannel +instanceKlass java/nio/channels/WritableByteChannel +instanceKlass java/nio/channels/ReadableByteChannel +instanceKlass java/nio/channels/Channel +instanceKlass org/h2/store/fs/FilePath +instanceKlass org/h2/store/fs/FileUtils +instanceKlass org/h2/store/FileLock +instanceKlass org/h2/engine/Engine +instanceKlass org/h2/engine/SessionFactory +instanceKlass org/h2/command/CommandInterface +instanceKlass org/h2/store/LobStorageInterface +instanceKlass org/h2/engine/SessionWithState +instanceKlass org/h2/engine/SessionInterface +instanceKlass org/h2/store/DataHandler +instanceKlass org/h2/value/CompareMode +instanceKlass org/h2/util/StringUtils +instanceKlass org/h2/engine/SettingsBase +instanceKlass org/h2/util/MathUtils +instanceKlass org/h2/engine/SysProperties +instanceKlass org/h2/command/dml/SetTypes +instanceKlass org/h2/engine/ConnectionInfo +instanceKlass java/sql/CallableStatement +instanceKlass java/sql/NClob +instanceKlass java/sql/Clob +instanceKlass java/sql/Blob +instanceKlass org/h2/value/Value +instanceKlass java/sql/ResultSet +instanceKlass java/sql/DatabaseMetaData +instanceKlass java/sql/PreparedStatement +instanceKlass java/sql/Statement +instanceKlass org/h2/message/TraceObject +instanceKlass org/h2/util/New +instanceKlass org/h2/util/Utils +instanceKlass org/h2/upgrade/DbUpgrade +instanceKlass com/j256/ormlite/misc/VersionUtils +instanceKlass com/j256/ormlite/jdbc/JdbcDatabaseConnection$OneLongWrapper +instanceKlass com/j256/ormlite/support/DatabaseResults +instanceKlass java/sql/Savepoint +instanceKlass com/j256/ormlite/support/CompiledStatement +instanceKlass com/j256/ormlite/db/BaseDatabaseType$1 +instanceKlass com/j256/ormlite/dao/RawRowMapper +instanceKlass com/j256/ormlite/dao/GenericRawResults +instanceKlass com/j256/ormlite/stmt/StatementExecutor +instanceKlass com/j256/ormlite/field/DataPersisterManager +instanceKlass com/j256/ormlite/field/DatabaseField +instanceKlass com/j256/ormlite/field/types/BaseDateType$DateStringFormatConfig +instanceKlass com/j256/ormlite/field/DataPersister +instanceKlass com/j256/ormlite/field/DatabaseFieldConfig +instanceKlass com/j256/ormlite/dao/BaseForeignCollection +instanceKlass com/j256/ormlite/table/DatabaseTableConfig +instanceKlass com/j256/ormlite/table/TableInfo +instanceKlass com/j256/ormlite/dao/CloseableIterator +instanceKlass com/j256/ormlite/stmt/PreparedStmt +instanceKlass com/j256/ormlite/stmt/GenericRowMapper +instanceKlass com/j256/ormlite/dao/ObjectCache +instanceKlass com/j256/ormlite/dao/ForeignCollection +instanceKlass com/j256/ormlite/dao/CloseableWrappedIterable +instanceKlass com/j256/ormlite/dao/BaseDaoImpl +instanceKlass com/j256/ormlite/table/DatabaseTable +instanceKlass com/j256/ormlite/dao/DaoManager$ClassConnectionSource +instanceKlass com/j256/ormlite/dao/Dao +instanceKlass com/j256/ormlite/dao/CloseableIterable +instanceKlass com/j256/ormlite/dao/DaoManager +instanceKlass com/j256/ormlite/field/FieldType +instanceKlass com/j256/ormlite/table/TableUtils +instanceKlass mage/cards/repository/DatabaseVersion +instanceKlass mage/cards/repository/RepositoryUtil +instanceKlass java/sql/DriverInfo +instanceKlass java/sql/DriverManager$2 +instanceKlass java/sql/DriverManager$1 +instanceKlass java/sql/DriverManager +instanceKlass java/sql/Connection +instanceKlass java/sql/Wrapper +instanceKlass org/h2/Driver +instanceKlass java/sql/Driver +instanceKlass com/j256/ormlite/field/BaseFieldConverter +instanceKlass com/j256/ormlite/field/FieldConverter +instanceKlass com/j256/ormlite/db/BaseDatabaseType +instanceKlass com/j256/ormlite/db/DatabaseType +instanceKlass com/j256/ormlite/db/DatabaseTypeUtils +instanceKlass com/j256/ormlite/logger/Logger +instanceKlass com/j256/ormlite/logger/Slf4jLoggingLog$1 +instanceKlass java/util/concurrent/ConcurrentHashMap$Traverser +instanceKlass org/slf4j/helpers/NamedLoggerBase +instanceKlass org/slf4j/spi/LocationAwareLogger +instanceKlass org/slf4j/impl/Log4jLoggerFactory +instanceKlass org/slf4j/impl/StaticLoggerBinder +instanceKlass org/slf4j/spi/LoggerFactoryBinder +instanceKlass com/j256/ormlite/logger/Slf4jLoggingLog +instanceKlass org/slf4j/helpers/NOPLoggerFactory +instanceKlass org/slf4j/Logger +instanceKlass org/slf4j/helpers/SubstituteLoggerFactory +instanceKlass org/slf4j/ILoggerFactory +instanceKlass org/slf4j/LoggerFactory +instanceKlass com/j256/ormlite/logger/LocalLog +instanceKlass com/j256/ormlite/logger/Log +instanceKlass com/j256/ormlite/logger/LoggerFactory +instanceKlass com/j256/ormlite/jdbc/JdbcDatabaseConnection +instanceKlass com/j256/ormlite/support/DatabaseConnection +instanceKlass com/j256/ormlite/support/BaseConnectionSource +instanceKlass com/j256/ormlite/support/ConnectionSource +instanceKlass java/util/EnumMap$1 +instanceKlass java/util/Random +instanceKlass java/util/zip/ZipUtils +instanceKlass java/net/URLEncoder +instanceKlass java/net/URLDecoder +instanceKlass mage/util/ClassScanner +instanceKlass mage/cards/ExpansionSet +instanceKlass mage/cards/repository/CardScanner +instanceKlass mage/util/Copier +instanceKlass mage/game/match/MatchImpl +instanceKlass org/apache/log4j/spi/LocationInfo +instanceKlass java/text/DontCareFieldPosition$1 +instanceKlass java/text/Format$FieldDelegate +instanceKlass java/net/URI$Parser +instanceKlass mage/server/game/GameFactory +instanceKlass com/sun/org/apache/xerces/internal/impl/Constants$ArrayEnumeration +instanceKlass java/util/ArrayList$SubList$1 +instanceKlass com/sun/org/apache/xerces/internal/impl/Constants +instanceKlass com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser$LocatorProxy +instanceKlass org/xml/sax/ext/Locator2 +instanceKlass com/sun/org/apache/xerces/internal/util/XMLSymbols +instanceKlass com/sun/org/apache/xerces/internal/util/XMLChar +instanceKlass com/sun/xml/internal/stream/Entity +instanceKlass com/sun/xml/internal/stream/util/BufferAllocator +instanceKlass com/sun/xml/internal/stream/util/ThreadLocalBufferAllocator +instanceKlass com/sun/org/apache/xerces/internal/util/URI +instanceKlass com/sun/org/apache/xerces/internal/utils/XMLLimitAnalyzer +instanceKlass com/sun/org/apache/xerces/internal/xni/parser/XMLInputSource +instanceKlass com/sun/org/apache/xerces/internal/util/ErrorHandlerWrapper +instanceKlass com/sun/org/apache/xerces/internal/xni/parser/XMLErrorHandler +instanceKlass com/sun/xml/bind/v2/runtime/unmarshaller/TagName +instanceKlass com/sun/xml/bind/v2/runtime/unmarshaller/SAXConnector +instanceKlass com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser$AttributesProxy +instanceKlass org/xml/sax/ext/Attributes2 +instanceKlass org/xml/sax/Attributes +instanceKlass org/xml/sax/AttributeList +instanceKlass com/sun/org/apache/xerces/internal/util/PropertyState +instanceKlass com/sun/org/apache/xerces/internal/util/FeatureState +instanceKlass com/sun/org/apache/xerces/internal/impl/msg/XMLMessageFormatter +instanceKlass com/sun/org/apache/xerces/internal/util/MessageFormatter +instanceKlass com/sun/org/apache/xerces/internal/impl/XMLVersionDetector +instanceKlass com/sun/org/apache/xerces/internal/impl/validation/ValidationManager +instanceKlass com/sun/org/apache/xerces/internal/impl/dv/dtd/NMTOKENDatatypeValidator +instanceKlass com/sun/org/apache/xerces/internal/impl/dv/dtd/NOTATIONDatatypeValidator +instanceKlass com/sun/org/apache/xerces/internal/impl/dv/dtd/ENTITYDatatypeValidator +instanceKlass com/sun/org/apache/xerces/internal/impl/dv/dtd/ListDatatypeValidator +instanceKlass com/sun/org/apache/xerces/internal/impl/dv/dtd/IDREFDatatypeValidator +instanceKlass com/sun/org/apache/xerces/internal/impl/dv/dtd/IDDatatypeValidator +instanceKlass com/sun/org/apache/xerces/internal/impl/dv/dtd/StringDatatypeValidator +instanceKlass com/sun/org/apache/xerces/internal/impl/dv/DatatypeValidator +instanceKlass com/sun/org/apache/xerces/internal/impl/dv/DTDDVFactory +instanceKlass com/sun/org/apache/xerces/internal/impl/dtd/DTDGrammarBucket +instanceKlass com/sun/org/apache/xerces/internal/impl/dtd/XMLAttributeDecl +instanceKlass com/sun/org/apache/xerces/internal/impl/dtd/XMLSimpleType +instanceKlass com/sun/org/apache/xerces/internal/impl/dtd/XMLElementDecl +instanceKlass com/sun/org/apache/xerces/internal/impl/validation/ValidationState +instanceKlass com/sun/org/apache/xerces/internal/impl/dv/ValidationContext +instanceKlass com/sun/org/apache/xerces/internal/impl/dtd/XMLDTDValidator +instanceKlass com/sun/org/apache/xerces/internal/impl/RevalidationHandler +instanceKlass com/sun/org/apache/xerces/internal/impl/dtd/XMLDTDValidatorFilter +instanceKlass com/sun/org/apache/xerces/internal/xni/parser/XMLDocumentFilter +instanceKlass com/sun/org/apache/xerces/internal/impl/dtd/XMLEntityDecl +instanceKlass com/sun/org/apache/xerces/internal/impl/dtd/XMLDTDProcessor +instanceKlass com/sun/org/apache/xerces/internal/xni/parser/XMLDTDContentModelFilter +instanceKlass com/sun/org/apache/xerces/internal/xni/parser/XMLDTDFilter +instanceKlass com/sun/org/apache/xerces/internal/xni/parser/XMLDTDScanner +instanceKlass com/sun/org/apache/xerces/internal/xni/parser/XMLDTDContentModelSource +instanceKlass com/sun/org/apache/xerces/internal/xni/parser/XMLDTDSource +instanceKlass com/sun/org/apache/xerces/internal/xni/grammars/XMLDTDDescription +instanceKlass com/sun/org/apache/xerces/internal/xni/grammars/XMLGrammarDescription +instanceKlass com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl$TrailingMiscDriver +instanceKlass com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl$PrologDriver +instanceKlass com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl$XMLDeclDriver +instanceKlass com/sun/org/apache/xerces/internal/util/NamespaceSupport +instanceKlass com/sun/org/apache/xerces/internal/xni/NamespaceContext +instanceKlass com/sun/org/apache/xerces/internal/util/XMLAttributesImpl$Attribute +instanceKlass com/sun/org/apache/xerces/internal/util/XMLAttributesImpl +instanceKlass com/sun/org/apache/xerces/internal/xni/XMLAttributes +instanceKlass com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl$FragmentContentDriver +instanceKlass com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl$Driver +instanceKlass com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl$ElementStack2 +instanceKlass com/sun/org/apache/xerces/internal/xni/QName +instanceKlass com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl$ElementStack +instanceKlass com/sun/org/apache/xerces/internal/xni/XMLString +instanceKlass com/sun/org/apache/xerces/internal/impl/XMLScanner +instanceKlass com/sun/xml/internal/stream/XMLBufferListener +instanceKlass com/sun/org/apache/xerces/internal/impl/XMLEntityHandler +instanceKlass com/sun/org/apache/xerces/internal/xni/parser/XMLDocumentScanner +instanceKlass com/sun/org/apache/xerces/internal/xni/parser/XMLDocumentSource +instanceKlass com/sun/org/apache/xerces/internal/impl/XMLErrorReporter +instanceKlass com/sun/org/apache/xerces/internal/impl/XMLEntityScanner +instanceKlass com/sun/org/apache/xerces/internal/xni/XMLLocator +instanceKlass com/sun/xml/internal/stream/XMLEntityStorage +instanceKlass com/sun/org/apache/xerces/internal/impl/XMLEntityManager$CharacterBuffer +instanceKlass com/sun/org/apache/xerces/internal/impl/XMLEntityManager$CharacterBufferPool +instanceKlass com/sun/org/apache/xerces/internal/util/AugmentationsImpl$AugmentationsItemsContainer +instanceKlass com/sun/org/apache/xerces/internal/util/AugmentationsImpl +instanceKlass com/sun/org/apache/xerces/internal/xni/Augmentations +instanceKlass com/sun/org/apache/xerces/internal/util/XMLResourceIdentifierImpl +instanceKlass com/sun/org/apache/xerces/internal/xni/XMLResourceIdentifier +instanceKlass com/sun/org/apache/xerces/internal/impl/XMLEntityManager +instanceKlass com/sun/org/apache/xerces/internal/xni/parser/XMLEntityResolver +instanceKlass com/sun/org/apache/xerces/internal/xni/parser/XMLComponent +instanceKlass com/sun/org/apache/xerces/internal/util/SymbolTable$Entry +instanceKlass com/sun/org/apache/xerces/internal/util/SymbolTable +instanceKlass com/sun/org/apache/xerces/internal/util/ParserConfigurationSettings +instanceKlass com/sun/org/apache/xerces/internal/parsers/XML11Configurable +instanceKlass com/sun/org/apache/xerces/internal/xni/parser/XMLPullParserConfiguration +instanceKlass com/sun/org/apache/xerces/internal/xni/parser/XMLParserConfiguration +instanceKlass com/sun/org/apache/xerces/internal/xni/parser/XMLComponentManager +instanceKlass com/sun/org/apache/xerces/internal/parsers/XMLParser +instanceKlass com/sun/org/apache/xerces/internal/xni/XMLDTDContentModelHandler +instanceKlass com/sun/org/apache/xerces/internal/xni/XMLDTDHandler +instanceKlass com/sun/org/apache/xerces/internal/xni/XMLDocumentHandler +instanceKlass org/xml/sax/XMLReader +instanceKlass org/xml/sax/Parser +instanceKlass com/sun/org/apache/xerces/internal/utils/XMLSecurityPropertyManager +instanceKlass com/sun/org/apache/xerces/internal/utils/SecuritySupport$8 +instanceKlass com/sun/org/apache/xerces/internal/utils/SecuritySupport$4 +instanceKlass com/sun/org/apache/xerces/internal/utils/SecuritySupport +instanceKlass com/sun/org/apache/xerces/internal/utils/XMLSecurityManager +instanceKlass javax/xml/parsers/SAXParser +instanceKlass com/sun/org/apache/xerces/internal/xs/PSVIProvider +instanceKlass com/sun/org/apache/xerces/internal/jaxp/JAXPConstants +instanceKlass javax/xml/parsers/SecuritySupport$1 +instanceKlass javax/xml/parsers/FactoryFinder$1 +instanceKlass javax/xml/parsers/SecuritySupport$5 +instanceKlass javax/xml/parsers/SecuritySupport$2 +instanceKlass javax/xml/parsers/SecuritySupport +instanceKlass javax/xml/parsers/FactoryFinder +instanceKlass javax/xml/parsers/SAXParserFactory +instanceKlass org/xml/sax/InputSource +instanceKlass com/sun/xml/bind/v2/runtime/unmarshaller/UnmarshallingContext$State +instanceKlass com/sun/xml/bind/v2/runtime/unmarshaller/Scope +instanceKlass com/sun/xml/bind/v2/runtime/unmarshaller/LocatorExWrapper +instanceKlass org/xml/sax/helpers/LocatorImpl +instanceKlass java/util/concurrent/Callable +instanceKlass javax/xml/bind/helpers/DefaultValidationEventHandler +instanceKlass org/xml/sax/helpers/DefaultHandler +instanceKlass org/xml/sax/DTDHandler +instanceKlass org/xml/sax/EntityResolver +instanceKlass com/sun/xml/bind/IDResolver +instanceKlass javax/xml/bind/UnmarshallerHandler +instanceKlass com/sun/xml/bind/v2/runtime/unmarshaller/ValidatingUnmarshaller +instanceKlass com/sun/xml/bind/v2/runtime/Coordinator +instanceKlass com/sun/xml/bind/v2/runtime/unmarshaller/XmlVisitor$TextPredictor +instanceKlass com/sun/xml/bind/v2/runtime/unmarshaller/LocatorEx +instanceKlass com/sun/xml/bind/v2/runtime/unmarshaller/XmlVisitor +instanceKlass org/xml/sax/ContentHandler +instanceKlass javax/xml/bind/helpers/AbstractUnmarshallerImpl +instanceKlass javax/xml/bind/ValidationEventHandler +instanceKlass com/sun/xml/bind/v2/runtime/NameList +instanceKlass com/sun/xml/bind/v2/runtime/unmarshaller/ChildLoader +instanceKlass com/sun/xml/bind/v2/runtime/property/ArrayERProperty$ReceiverImpl +instanceKlass com/sun/xml/bind/v2/runtime/unmarshaller/StructureLoader$1 +instanceKlass com/sun/xml/bind/v2/runtime/property/UnmarshallerChain +instanceKlass javax/xml/bind/annotation/W3CDomHandler +instanceKlass javax/xml/bind/annotation/DomHandler +instanceKlass com/sun/xml/bind/v2/runtime/ElementBeanInfoImpl$1 +instanceKlass com/sun/xml/bind/v2/runtime/unmarshaller/Intercepter +instanceKlass javax/xml/bind/JAXBElement +instanceKlass com/sun/xml/bind/v2/runtime/property/TagAndType +instanceKlass com/sun/xml/bind/v2/runtime/LifecycleMethods +instanceKlass com/sun/xml/bind/v2/runtime/reflect/opt/OptimizedTransducedAccessorFactory +instanceKlass com/sun/xml/bind/v2/runtime/reflect/TransducedAccessor +instanceKlass com/sun/xml/bind/v2/runtime/Name +instanceKlass com/sun/xml/bind/v2/runtime/reflect/opt/Injector$1 +instanceKlass java/util/concurrent/locks/ReentrantReadWriteLock$WriteLock +instanceKlass java/util/concurrent/locks/ReentrantReadWriteLock$ReadLock +instanceKlass sun/nio/ch/Interruptible +instanceKlass java/util/concurrent/locks/ReentrantReadWriteLock +instanceKlass java/util/concurrent/locks/ReadWriteLock +instanceKlass com/sun/xml/bind/v2/runtime/reflect/opt/Injector +instanceKlass com/sun/xml/bind/v2/runtime/reflect/opt/AccessorInjector +instanceKlass com/sun/xml/bind/v2/runtime/reflect/opt/Ref +instanceKlass com/sun/xml/bind/v2/runtime/reflect/opt/Bean +instanceKlass com/sun/xml/bind/v2/bytecode/ClassTailor +instanceKlass com/sun/xml/bind/v2/runtime/reflect/opt/OptimizedAccessorFactory +instanceKlass com/sun/xml/bind/v2/ClassFactory +instanceKlass com/sun/xml/bind/v2/runtime/reflect/Lister$2 +instanceKlass java/util/Collections$SynchronizedMap +instanceKlass com/sun/xml/bind/v2/runtime/reflect/ListIterator +instanceKlass com/sun/xml/bind/v2/runtime/reflect/Lister +instanceKlass com/sun/xml/bind/v2/runtime/property/PropertyFactory$1 +instanceKlass com/sun/xml/bind/v2/runtime/property/PropertyFactory +instanceKlass com/sun/xml/bind/v2/runtime/property/PropertyImpl +instanceKlass org/xml/sax/Locator +instanceKlass com/sun/xml/bind/v2/runtime/property/Property +instanceKlass com/sun/xml/bind/v2/runtime/property/StructureLoaderBuilder +instanceKlass com/sun/xml/bind/v2/runtime/unmarshaller/Loader +instanceKlass com/sun/xml/bind/v2/runtime/FilterTransducer +instanceKlass com/sun/xml/bind/v2/util/FlattenIterator +instanceKlass javax/xml/bind/annotation/XmlSchemaType$DEFAULT +instanceKlass com/sun/xml/bind/v2/TODO +instanceKlass java/util/NavigableSet +instanceKlass java/util/SortedSet +instanceKlass com/sun/xml/bind/annotation/XmlLocation +instanceKlass javax/xml/bind/annotation/XmlSchemaTypes +instanceKlass javax/xml/bind/annotation/XmlSeeAlso +instanceKlass com/sun/xml/bind/v2/model/nav/ParameterizedTypeImpl +instanceKlass com/sun/xml/bind/v2/model/nav/ReflectionNavigator$BinderArg +instanceKlass javax/xml/bind/annotation/adapters/XmlJavaTypeAdapters +instanceKlass sun/reflect/generics/tree/TypeVariableSignature +instanceKlass com/sun/xml/bind/v2/model/impl/Util +instanceKlass com/sun/xml/bind/v2/model/runtime/RuntimeTypeRef +instanceKlass com/sun/xml/bind/v2/model/impl/TypeRefImpl +instanceKlass com/sun/xml/bind/v2/model/core/TypeRef +instanceKlass com/sun/xml/bind/v2/model/impl/ClassInfoImpl$1 +instanceKlass com/sun/xml/bind/v2/model/impl/FieldPropertySeed +instanceKlass com/sun/xml/bind/v2/model/impl/RuntimeClassInfoImpl$RuntimePropertySeed +instanceKlass java/lang/Short$ShortCache +instanceKlass java/lang/Character$CharacterCache +instanceKlass java/lang/Byte$ByteCache +instanceKlass javax/xml/bind/annotation/XmlElement$DEFAULT +instanceKlass com/sun/xml/bind/AccessorFactoryImpl +instanceKlass com/sun/xml/bind/InternalAccessorFactory +instanceKlass javax/xml/bind/annotation/XmlAccessorOrder +instanceKlass java/lang/Package$1PackageInfoProxy +instanceKlass com/sun/xml/bind/annotation/OverrideAnnotationOf +instanceKlass javax/xml/bind/annotation/XmlMixed +instanceKlass javax/xml/bind/annotation/XmlAnyElement +instanceKlass javax/xml/bind/annotation/XmlElements +instanceKlass javax/xml/bind/annotation/XmlAnyAttribute +instanceKlass javax/xml/bind/annotation/XmlList +instanceKlass javax/xml/bind/annotation/XmlElementWrapper +instanceKlass javax/xml/bind/annotation/XmlAttachmentRef +instanceKlass javax/xml/bind/annotation/XmlMimeType +instanceKlass javax/xml/bind/annotation/XmlInlineBinaryData +instanceKlass javax/xml/bind/annotation/XmlIDREF +instanceKlass javax/xml/bind/annotation/XmlID +instanceKlass javax/xml/bind/annotation/adapters/XmlJavaTypeAdapter +instanceKlass com/sun/xml/bind/AccessorFactory +instanceKlass com/sun/xml/bind/v2/model/runtime/RuntimeReferencePropertyInfo +instanceKlass com/sun/xml/bind/v2/model/runtime/RuntimeAttributePropertyInfo +instanceKlass com/sun/xml/bind/v2/model/core/AttributePropertyInfo +instanceKlass com/sun/xml/bind/v2/model/runtime/RuntimeElementPropertyInfo +instanceKlass com/sun/xml/bind/v2/model/core/ElementPropertyInfo +instanceKlass com/sun/xml/bind/v2/model/runtime/RuntimeMapPropertyInfo +instanceKlass com/sun/xml/bind/v2/model/core/MapPropertyInfo +instanceKlass com/sun/xml/bind/v2/runtime/reflect/Accessor +instanceKlass com/sun/xml/bind/v2/runtime/unmarshaller/Receiver +instanceKlass com/sun/xml/bind/v2/model/runtime/RuntimeValuePropertyInfo +instanceKlass com/sun/xml/bind/v2/model/runtime/RuntimeNonElementRef +instanceKlass com/sun/xml/bind/v2/model/runtime/RuntimePropertyInfo +instanceKlass com/sun/xml/bind/v2/model/core/ValuePropertyInfo +instanceKlass com/sun/xml/bind/v2/model/core/NonElementRef +instanceKlass com/sun/xml/bind/v2/model/impl/PropertySeed +instanceKlass com/sun/xml/bind/v2/model/impl/DummyPropertyInfo +instanceKlass com/sun/xml/bind/v2/model/core/ReferencePropertyInfo +instanceKlass com/sun/xml/bind/v2/model/impl/PropertyInfoImpl +instanceKlass com/sun/xml/bind/v2/model/core/PropertyInfo +instanceKlass com/sun/xml/bind/v2/model/annotation/AnnotationSource +instanceKlass javax/xml/bind/annotation/XmlType$DEFAULT +instanceKlass javax/xml/bind/annotation/XmlAccessorType +instanceKlass com/sun/xml/bind/v2/model/annotation/MethodLocatable +instanceKlass mage/server/util/config/Server +instanceKlass mage/server/util/config/Config +instanceKlass mage/server/util/config/DeckTypes +instanceKlass mage/server/util/config/GameTypes +instanceKlass mage/server/util/config/DraftCubes +instanceKlass mage/server/util/config/TournamentTypes +instanceKlass mage/server/util/config/PlayerTypes +instanceKlass com/sun/xml/bind/v2/model/impl/RegistryInfoImpl +instanceKlass javax/xml/bind/annotation/XmlValue +instanceKlass javax/xml/bind/annotation/XmlType +instanceKlass javax/xml/bind/annotation/XmlTransient +instanceKlass javax/xml/bind/annotation/XmlSchemaType +instanceKlass javax/xml/bind/annotation/XmlRootElement +instanceKlass javax/xml/bind/annotation/XmlEnum +instanceKlass javax/xml/bind/annotation/XmlElementRefs +instanceKlass javax/xml/bind/annotation/XmlElementRef +instanceKlass javax/xml/bind/annotation/XmlElementDecl +instanceKlass javax/xml/bind/annotation/XmlElement +instanceKlass javax/xml/bind/annotation/XmlAttribute +instanceKlass com/sun/xml/bind/v2/model/annotation/Quick +instanceKlass com/sun/xml/bind/v2/model/annotation/Init +instanceKlass com/sun/xml/bind/v2/model/annotation/LocatableAnnotation +instanceKlass javax/xml/bind/annotation/XmlRegistry +instanceKlass com/sun/xml/bind/v2/model/core/Ref +instanceKlass com/sun/xml/bind/api/CompositeStructure +instanceKlass com/sun/xml/bind/v2/runtime/IllegalAnnotationsException$Builder +instanceKlass java/util/Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntry +instanceKlass java/util/Collections$UnmodifiableMap$UnmodifiableEntrySet$1 +instanceKlass javax/xml/bind/ValidationEventLocator +instanceKlass com/sun/xml/bind/v2/runtime/RuntimeUtil +instanceKlass com/sun/xml/bind/v2/model/impl/AnyTypeImpl +instanceKlass com/sun/xml/bind/v2/model/impl/TypeInfoSetImpl$1 +instanceKlass javax/xml/datatype/Duration +instanceKlass javax/xml/namespace/NamespaceContext +instanceKlass javax/xml/datatype/XMLGregorianCalendar +instanceKlass javax/xml/transform/Result +instanceKlass javax/xml/transform/Source +instanceKlass javax/activation/DataHandler +instanceKlass java/awt/datatransfer/Transferable +instanceKlass javax/activation/DataSource +instanceKlass javax/xml/bind/ValidationEvent +instanceKlass com/sun/xml/bind/v2/runtime/output/Pcdata +instanceKlass java/awt/Transparency +instanceKlass java/awt/image/WritableRenderedImage +instanceKlass java/awt/image/RenderedImage +instanceKlass java/awt/Image +instanceKlass java/awt/Graphics +instanceKlass java/awt/Component +instanceKlass java/awt/MenuContainer +instanceKlass java/awt/image/ImageObserver +instanceKlass java/net/URI +instanceKlass javax/xml/datatype/DatatypeConstants$Field +instanceKlass javax/xml/datatype/DatatypeConstants +instanceKlass javax/xml/namespace/QName$1 +instanceKlass javax/xml/namespace/QName +instanceKlass com/sun/xml/bind/v2/model/impl/LeafInfoImpl +instanceKlass com/sun/xml/bind/v2/model/impl/ModelBuilder$1 +instanceKlass com/sun/xml/bind/v2/model/nav/TypeVisitor +instanceKlass com/sun/xml/bind/v2/model/nav/ReflectionNavigator +instanceKlass com/sun/xml/bind/WhiteSpaceProcessor +instanceKlass javax/xml/bind/annotation/XmlSchema +instanceKlass com/sun/xml/bind/v2/model/runtime/RuntimeClassInfo +instanceKlass com/sun/xml/bind/v2/model/core/ClassInfo +instanceKlass com/sun/xml/bind/v2/model/runtime/RuntimeArrayInfo +instanceKlass com/sun/xml/bind/v2/runtime/Location +instanceKlass com/sun/xml/bind/v2/model/core/ArrayInfo +instanceKlass com/sun/xml/bind/v2/model/runtime/RuntimeTypeInfoSet +instanceKlass com/sun/xml/bind/v2/model/impl/TypeInfoSetImpl +instanceKlass com/sun/xml/bind/v2/model/runtime/RuntimeElementInfo +instanceKlass com/sun/xml/bind/v2/model/runtime/RuntimeElement +instanceKlass com/sun/xml/bind/v2/model/core/ElementInfo +instanceKlass com/sun/xml/bind/v2/runtime/Transducer +instanceKlass com/sun/xml/bind/v2/model/runtime/RuntimeEnumLeafInfo +instanceKlass com/sun/xml/bind/v2/model/core/RegistryInfo +instanceKlass com/sun/xml/bind/v2/model/impl/TypeInfoImpl +instanceKlass com/sun/xml/bind/v2/model/core/Element +instanceKlass com/sun/xml/bind/v2/model/core/EnumLeafInfo +instanceKlass com/sun/xml/bind/v2/model/impl/ModelBuilder +instanceKlass javax/xml/bind/DatatypeConverter +instanceKlass javax/xml/datatype/SecuritySupport$1 +instanceKlass javax/xml/datatype/FactoryFinder$1 +instanceKlass javax/xml/datatype/SecuritySupport$5 +instanceKlass javax/xml/datatype/SecuritySupport$2 +instanceKlass javax/xml/datatype/SecuritySupport +instanceKlass javax/xml/datatype/FactoryFinder +instanceKlass javax/xml/datatype/DatatypeFactory +instanceKlass com/sun/xml/bind/DatatypeConverterImpl +instanceKlass javax/xml/bind/DatatypeConverterInterface +instanceKlass com/sun/xml/bind/v2/runtime/JAXBContextImpl$3 +instanceKlass com/sun/xml/bind/v2/runtime/NameBuilder +instanceKlass com/sun/istack/Pool$Impl +instanceKlass com/sun/xml/bind/v2/util/QNameMap$Entry +instanceKlass com/sun/xml/bind/v2/util/QNameMap +instanceKlass com/sun/xml/bind/v2/runtime/JAXBContextImpl$8 +instanceKlass com/sun/xml/bind/api/Bridge +instanceKlass com/sun/xml/bind/v2/model/runtime/RuntimeBuiltinLeafInfo +instanceKlass com/sun/xml/bind/v2/model/core/BuiltinLeafInfo +instanceKlass com/sun/istack/Pool +instanceKlass javax/xml/bind/Unmarshaller +instanceKlass com/sun/xml/bind/api/BridgeContext +instanceKlass com/sun/xml/bind/v2/model/core/TypeInfoSet +instanceKlass com/sun/xml/bind/api/RawAccessor +instanceKlass javax/xml/bind/SchemaOutputResolver +instanceKlass com/sun/xml/bind/v2/model/core/ErrorHandler +instanceKlass com/sun/xml/bind/v2/model/runtime/RuntimeLeafInfo +instanceKlass com/sun/xml/bind/v2/model/runtime/RuntimeNonElement +instanceKlass com/sun/xml/bind/v2/model/runtime/RuntimeTypeInfo +instanceKlass com/sun/xml/bind/v2/model/core/LeafInfo +instanceKlass com/sun/xml/bind/v2/model/core/MaybeElement +instanceKlass com/sun/xml/bind/v2/model/core/NonElement +instanceKlass com/sun/xml/bind/v2/model/core/TypeInfo +instanceKlass com/sun/xml/bind/v2/model/annotation/Locatable +instanceKlass com/sun/xml/bind/v2/runtime/AttributeAccessor +instanceKlass com/sun/xml/bind/v2/runtime/JaxBeanInfo +instanceKlass com/sun/xml/bind/v2/model/nav/Navigator +instanceKlass javax/xml/bind/Binder +instanceKlass com/sun/xml/bind/unmarshaller/InfosetScanner +instanceKlass javax/xml/bind/JAXBIntrospector +instanceKlass javax/xml/bind/Marshaller +instanceKlass com/sun/xml/bind/api/ErrorListener +instanceKlass org/xml/sax/ErrorHandler +instanceKlass com/sun/xml/bind/v2/model/annotation/AbstractInlineAnnotationReaderImpl +instanceKlass com/sun/xml/bind/v2/runtime/JAXBContextImpl$JAXBContextBuilder +instanceKlass com/sun/xml/bind/v2/util/TypeCast +instanceKlass com/sun/xml/bind/Util +instanceKlass mage/server/util/config/ObjectFactory +instanceKlass com/sun/xml/bind/v2/model/annotation/RuntimeAnnotationReader +instanceKlass com/sun/xml/bind/v2/model/annotation/AnnotationReader +instanceKlass com/sun/xml/bind/v2/ContextFactory +instanceKlass sun/net/www/protocol/jar/JarFileFactory +instanceKlass sun/net/www/protocol/jar/URLJarFile$URLJarFileCloseController +instanceKlass javax/xml/bind/GetPropertyAction +instanceKlass java/util/logging/LogManager$5 +instanceKlass java/util/logging/LoggingProxyImpl +instanceKlass sun/util/logging/LoggingProxy +instanceKlass sun/util/logging/LoggingSupport$1 +instanceKlass sun/util/logging/LoggingSupport +instanceKlass sun/util/logging/PlatformLogger$LoggerProxy +instanceKlass sun/util/logging/PlatformLogger$1 +instanceKlass sun/util/logging/PlatformLogger +instanceKlass java/util/logging/LogManager$LoggerContext$1 +instanceKlass java/util/logging/LogManager$3 +instanceKlass java/util/logging/LogManager$2 +instanceKlass java/lang/Shutdown$Lock +instanceKlass java/lang/Shutdown +instanceKlass java/lang/ApplicationShutdownHooks$1 +instanceKlass java/lang/ApplicationShutdownHooks +instanceKlass java/util/logging/LogManager$LogNode +instanceKlass java/util/logging/LogManager$LoggerContext +instanceKlass java/util/logging/LogManager$1 +instanceKlass java/util/logging/LogManager +instanceKlass java/util/logging/Logger$LoggerBundle +instanceKlass java/util/logging/Level$KnownLevel +instanceKlass java/util/logging/Level +instanceKlass java/util/logging/Handler +instanceKlass java/util/logging/Logger +instanceKlass javax/xml/bind/ContextFinder +instanceKlass javax/xml/bind/JAXBContext +instanceKlass mage/server/util/ConfigSettings +instanceKlass org/mage/test/serverside/base/MageTestPlayerBase$1 +instanceKlass org/apache/log4j/CategoryKey +instanceKlass org/apache/log4j/helpers/AppenderAttachableImpl +instanceKlass java/util/Vector$1 +instanceKlass java/util/Collections$EmptyEnumeration +instanceKlass org/apache/log4j/SortedKeyEnumeration +instanceKlass org/apache/log4j/spi/Filter +instanceKlass java/util/Date +instanceKlass java/text/DigitList +instanceKlass java/text/FieldPosition +instanceKlass java/text/DateFormatSymbols +instanceKlass sun/util/calendar/CalendarUtils +instanceKlass sun/util/calendar/CalendarDate +instanceKlass sun/util/locale/provider/CalendarDataUtility$CalendarWeekParameterGetter +instanceKlass sun/util/locale/provider/CalendarDataUtility +instanceKlass java/util/Calendar$Builder +instanceKlass java/util/Calendar +instanceKlass java/util/TimeZone$1 +instanceKlass java/util/zip/CRC32 +instanceKlass java/util/zip/Checksum +instanceKlass sun/util/calendar/ZoneInfoFile$ZoneOffsetTransitionRule +instanceKlass sun/util/calendar/ZoneInfoFile$1 +instanceKlass sun/util/calendar/ZoneInfoFile +instanceKlass sun/util/calendar/CalendarSystem +instanceKlass java/util/TimeZone +instanceKlass java/text/AttributedCharacterIterator$Attribute +instanceKlass org/apache/log4j/spi/LoggingEvent +instanceKlass java/beans/SimpleBeanInfo +instanceKlass java/util/TreeMap$PrivateEntryIterator +instanceKlass java/beans/Transient +instanceKlass com/sun/beans/WildcardTypeImpl +instanceKlass sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl +instanceKlass java/lang/reflect/ParameterizedType +instanceKlass sun/reflect/generics/reflectiveObjects/LazyReflectiveObjectGenerator +instanceKlass java/lang/reflect/WildcardType +instanceKlass sun/reflect/generics/tree/MethodTypeSignature +instanceKlass sun/reflect/generics/tree/Wildcard +instanceKlass sun/reflect/generics/tree/BottomSignature +instanceKlass java/lang/reflect/TypeVariable +instanceKlass sun/reflect/generics/tree/ClassSignature +instanceKlass sun/reflect/generics/tree/Signature +instanceKlass sun/reflect/generics/tree/FormalTypeParameter +instanceKlass com/sun/beans/TypeResolver +instanceKlass java/beans/MethodRef +instanceKlass com/sun/beans/util/Cache$CacheEntry +instanceKlass com/sun/beans/util/Cache +instanceKlass com/sun/beans/finder/AbstractFinder +instanceKlass com/sun/beans/finder/ClassFinder +instanceKlass com/sun/beans/finder/InstanceFinder +instanceKlass java/beans/WeakIdentityMap +instanceKlass java/beans/ThreadGroupContext +instanceKlass java/beans/FeatureDescriptor +instanceKlass java/util/EventListener +instanceKlass com/sun/beans/WeakCache +instanceKlass java/beans/Introspector +instanceKlass java/beans/BeanInfo +instanceKlass org/apache/log4j/config/PropertySetter +instanceKlass org/apache/log4j/helpers/FormattingInfo +instanceKlass java/text/Format +instanceKlass org/apache/log4j/helpers/PatternConverter +instanceKlass org/apache/log4j/helpers/PatternParser +instanceKlass org/apache/log4j/helpers/OnlyOnceErrorHandler +instanceKlass org/apache/log4j/Layout +instanceKlass org/apache/log4j/spi/ErrorHandler +instanceKlass org/apache/log4j/AppenderSkeleton +instanceKlass org/apache/log4j/spi/OptionHandler +instanceKlass org/apache/log4j/Appender +instanceKlass sun/net/DefaultProgressMeteringPolicy +instanceKlass sun/net/ProgressMeteringPolicy +instanceKlass sun/net/ProgressMonitor +instanceKlass org/apache/log4j/PropertyConfigurator +instanceKlass java/net/URLClassLoader$2 +instanceKlass org/apache/log4j/helpers/LogLog +instanceKlass org/apache/log4j/helpers/Loader +instanceKlass org/apache/log4j/spi/Configurator +instanceKlass org/apache/log4j/helpers/OptionConverter +instanceKlass org/apache/log4j/spi/DefaultRepositorySelector +instanceKlass org/apache/log4j/DefaultCategoryFactory +instanceKlass org/apache/log4j/or/DefaultRenderer +instanceKlass org/apache/log4j/or/ObjectRenderer +instanceKlass org/apache/log4j/or/RendererMap +instanceKlass org/apache/log4j/spi/LoggerFactory +instanceKlass org/apache/log4j/Hierarchy +instanceKlass org/apache/log4j/spi/ThrowableRendererSupport +instanceKlass org/apache/log4j/spi/RendererSupport +instanceKlass org/apache/log4j/spi/RepositorySelector +instanceKlass org/apache/log4j/spi/LoggerRepository +instanceKlass org/apache/log4j/LogManager +instanceKlass org/apache/log4j/Priority +instanceKlass org/junit/internal/runners/model/ReflectiveCallable +instanceKlass org/junit/rules/TestRule +instanceKlass org/junit/runners/ParentRunner$3 +instanceKlass java/util/Formattable +instanceKlass java/util/Formatter$FixedString +instanceKlass java/util/Formatter$Conversion +instanceKlass java/util/Formatter$Flags +instanceKlass java/util/Formatter$FormatSpecifier +instanceKlass java/util/Formatter$FormatString +instanceKlass java/util/regex/ASCII +instanceKlass java/util/regex/Matcher +instanceKlass java/util/regex/MatchResult +instanceKlass java/util/Currency$CurrencyNameGetter +instanceKlass sun/util/locale/provider/LocaleServiceProviderPool$LocalizedObjectGetter +instanceKlass sun/util/locale/provider/SPILocaleProviderAdapter$1 +instanceKlass sun/util/locale/provider/LocaleServiceProviderPool +instanceKlass java/util/Currency$1 +instanceKlass java/util/Currency +instanceKlass java/util/concurrent/atomic/AtomicMarkableReference$Pair +instanceKlass java/util/concurrent/atomic/AtomicMarkableReference +instanceKlass java/util/ResourceBundle$CacheKeyReference +instanceKlass java/util/ResourceBundle$CacheKey +instanceKlass java/util/ResourceBundle$RBClassLoader$1 +instanceKlass java/net/URLClassLoader$3$1 +instanceKlass sun/misc/CompoundEnumeration +instanceKlass java/net/URLClassLoader$3 +instanceKlass sun/misc/URLClassPath$1 +instanceKlass java/lang/ClassLoader$2 +instanceKlass sun/misc/URLClassPath$2 +instanceKlass sun/misc/Launcher$BootClassPathHolder$1 +instanceKlass sun/misc/Launcher$BootClassPathHolder +instanceKlass java/util/ServiceLoader$1 +instanceKlass java/util/ServiceLoader$LazyIterator +instanceKlass java/util/ServiceLoader +instanceKlass java/util/spi/ResourceBundleControlProvider +instanceKlass java/util/ResourceBundle +instanceKlass java/util/ResourceBundle$Control +instanceKlass sun/util/resources/LocaleData$1 +instanceKlass sun/util/resources/LocaleData +instanceKlass sun/util/locale/provider/LocaleResources +instanceKlass sun/util/locale/LanguageTag +instanceKlass sun/util/locale/provider/JRELocaleProviderAdapter$1 +instanceKlass sun/util/locale/provider/LocaleDataMetaInfo +instanceKlass sun/util/locale/provider/AvailableLanguageTags +instanceKlass sun/util/locale/provider/LocaleProviderAdapter$1 +instanceKlass sun/util/locale/provider/ResourceBundleBasedAdapter +instanceKlass sun/util/locale/provider/LocaleProviderAdapter +instanceKlass java/util/spi/LocaleServiceProvider +instanceKlass java/text/DecimalFormatSymbols +instanceKlass java/util/Locale$1 +instanceKlass java/util/Formatter +instanceKlass java/util/concurrent/ConcurrentLinkedQueue$Node +instanceKlass java/util/regex/Pattern$TreeInfo +instanceKlass org/junit/runner/Description +instanceKlass org/junit/internal/runners/model/EachTestNotifier +instanceKlass org/junit/After +instanceKlass org/junit/Assert +instanceKlass org/junit/validator/ValidateWith +instanceKlass java/util/Collections$1 +instanceKlass org/junit/internal/runners/rules/RuleMemberValidator$MethodMustBeARule +instanceKlass org/junit/internal/runners/rules/RuleMemberValidator$MethodMustBeATestRule +instanceKlass org/junit/internal/runners/rules/RuleMemberValidator$FieldMustBeARule +instanceKlass org/junit/internal/runners/rules/RuleMemberValidator$MemberMustBeNonStaticOrAlsoClassRule +instanceKlass org/junit/Rule +instanceKlass org/junit/internal/runners/rules/RuleMemberValidator$FieldMustBeATestRule +instanceKlass org/junit/internal/runners/rules/RuleMemberValidator$MemberMustBePublic +instanceKlass org/junit/internal/runners/rules/RuleMemberValidator$MemberMustBeStatic +instanceKlass org/junit/internal/runners/rules/RuleMemberValidator$DeclaringClassMustBePublic +instanceKlass org/junit/ClassRule +instanceKlass org/junit/internal/runners/rules/RuleMemberValidator$Builder +instanceKlass org/junit/internal/runners/rules/RuleMemberValidator$RuleValidator +instanceKlass org/junit/internal/runners/rules/RuleMemberValidator +instanceKlass org/junit/AfterClass +instanceKlass java/util/Collections$UnmodifiableCollection$1 +instanceKlass org/apache/log4j/Category +instanceKlass org/apache/log4j/spi/AppenderAttachable +instanceKlass mage/game/GameOptions +instanceKlass java/util/TimSort +instanceKlass org/junit/FixMethodOrder +instanceKlass org/junit/internal/MethodSorter$2 +instanceKlass org/junit/internal/MethodSorter$1 +instanceKlass org/junit/internal/MethodSorter +instanceKlass org/junit/runners/model/TestClass$MethodComparator +instanceKlass org/junit/runners/model/TestClass$FieldComparator +instanceKlass org/junit/runners/model/FrameworkMember +instanceKlass org/junit/runners/model/TestClass +instanceKlass org/junit/runners/model/Annotatable +instanceKlass org/junit/runners/ParentRunner$1 +instanceKlass org/junit/validator/PublicClassValidator +instanceKlass org/junit/validator/AnnotationValidatorFactory +instanceKlass org/junit/validator/AnnotationsValidator$AnnotatableValidator +instanceKlass org/junit/validator/AnnotationsValidator +instanceKlass org/junit/validator/TestClassValidator +instanceKlass org/junit/runners/model/RunnerScheduler +instanceKlass org/hamcrest/SelfDescribing +instanceKlass org/junit/runners/model/Statement +instanceKlass junit/framework/Assert +instanceKlass java/util/AbstractList$Itr +instanceKlass org/junit/runner/manipulation/Sortable +instanceKlass org/junit/runner/manipulation/Filterable +instanceKlass org/junit/runners/model/RunnerBuilder +instanceKlass org/junit/runner/Runner +instanceKlass org/junit/runner/Describable +instanceKlass org/junit/runner/Request +instanceKlass org/apache/maven/surefire/junit4/JUnit4TestSet +instanceKlass org/apache/maven/surefire/report/SimpleReportEntry +instanceKlass java/util/concurrent/CopyOnWriteArrayList$COWIterator +instanceKlass org/junit/runner/notification/RunNotifier$SafeNotifier +instanceKlass java/util/LinkedList$ListItr +instanceKlass java/util/ListIterator +instanceKlass org/junit/runner/notification/RunListener$ThreadSafe +instanceKlass org/junit/runner/notification/RunNotifier +instanceKlass java/util/concurrent/locks/AbstractQueuedSynchronizer$Node +instanceKlass java/util/concurrent/locks/AbstractOwnableSynchronizer +instanceKlass java/util/concurrent/CopyOnWriteArrayList +instanceKlass java/io/ObjectStreamClass$FieldReflector +instanceKlass java/io/ObjectInput +instanceKlass java/io/DataInput +instanceKlass java/io/ObjectStreamConstants +instanceKlass java/io/ObjectOutput +instanceKlass java/util/ComparableTimSort +instanceKlass java/util/Arrays$LegacyMergeSort +instanceKlass sun/reflect/UnsafeFieldAccessorFactory +instanceKlass java/io/ObjectStreamClass$2 +instanceKlass java/io/Externalizable +instanceKlass java/io/ObjectStreamClass$EntryFuture +instanceKlass java/io/ObjectStreamClass$Caches +instanceKlass java/io/ObjectStreamClass +instanceKlass org/junit/runner/Result$SerializedForm +instanceKlass org/junit/runner/Result +instanceKlass java/util/regex/Pattern$Node +instanceKlass java/util/regex/Pattern +instanceKlass org/apache/maven/surefire/report/ConsoleOutputCapture +instanceKlass org/apache/maven/surefire/util/internal/StringUtils +instanceKlass org/apache/maven/surefire/booter/ForkingRunListener +instanceKlass org/apache/maven/surefire/report/ConsoleOutputReceiver +instanceKlass org/apache/maven/surefire/util/TestsToRun +instanceKlass mage/interfaces/rate/RateCallback +instanceKlass org/mage/test/utils/DeckBuilderTest +instanceKlass mage/game/tournament/TournamentPlayer +instanceKlass org/mage/test/serverside/tournament/SwissPairingMinimalWeightMatchingTest +instanceKlass org/mage/test/serverside/rating/GlickoRatingSystemTest +instanceKlass org/mage/test/serverside/base/MageTestBase +instanceKlass mage/cards/decks/DeckValidator +instanceKlass java/lang/annotation/Documented +instanceKlass java/lang/Deprecated +instanceKlass mage/game/combat/CombatGroup +instanceKlass mage/abilities/costs/mana/ManaCosts +instanceKlass mage/abilities/costs/Costs +instanceKlass mage/game/match/Match +instanceKlass mage/game/Table +instanceKlass mage/abilities/Mode +instanceKlass mage/choices/Choice +instanceKlass mage/game/draft/Draft +instanceKlass mage/util/MessageToClient +instanceKlass mage/abilities/costs/VariableCost +instanceKlass mage/game/match/MatchPlayer +instanceKlass mage/game/tournament/Tournament +instanceKlass mage/players/ManaPool +instanceKlass mage/abilities/TriggeredAbility +instanceKlass mage/target/TargetImpl +instanceKlass mage/target/Target +instanceKlass mage/players/net/UserData +instanceKlass mage/counters/Counter +instanceKlass mage/players/Library +instanceKlass mage/cards/Cards +instanceKlass mage/abilities/AbilityImpl +instanceKlass mage/abilities/ActivatedAbility +instanceKlass mage/remote/Connection +instanceKlass mage/cards/decks/Deck +instanceKlass mage/game/match/MatchOptions +instanceKlass mage/view/GameTypeView +instanceKlass mage/cards/decks/DeckCardLists +instanceKlass mage/remote/Session +instanceKlass mage/remote/interfaces/Testable +instanceKlass mage/remote/interfaces/Replays +instanceKlass mage/remote/interfaces/PlayerActions +instanceKlass mage/remote/interfaces/Feedback +instanceKlass mage/remote/interfaces/ChatSession +instanceKlass mage/remote/interfaces/ServerState +instanceKlass mage/remote/interfaces/GameTypes +instanceKlass mage/remote/interfaces/GamePlay +instanceKlass mage/remote/interfaces/Connect +instanceKlass mage/remote/interfaces/ClientData +instanceKlass mage/interfaces/MageClient +instanceKlass mage/interfaces/callback/CallbackClient +instanceKlass org/mage/test/load/LoadTest +instanceKlass org/mage/test/decks/importer/TxtDeckImporterTest +instanceKlass mage/abilities/Abilities +instanceKlass sun/reflect/ClassDefiner$1 +instanceKlass sun/reflect/ClassDefiner +instanceKlass sun/reflect/MethodAccessorGenerator$1 +instanceKlass sun/reflect/Label$PatchInfo +instanceKlass sun/reflect/Label +instanceKlass sun/reflect/UTF8 +instanceKlass sun/reflect/ClassFileAssembler +instanceKlass sun/reflect/ByteVectorImpl +instanceKlass sun/reflect/ByteVector +instanceKlass sun/reflect/ByteVectorFactory +instanceKlass sun/reflect/AccessorGenerator +instanceKlass sun/reflect/ClassFileConstants +instanceKlass mage/abilities/costs/mana/ManaCost +instanceKlass mage/abilities/costs/Cost +instanceKlass mage/filter/FilterImpl +instanceKlass mage/filter/FilterInPlay +instanceKlass mage/filter/Filter +instanceKlass org/junit/BeforeClass +instanceKlass mage/game/tournament/TournamentType +instanceKlass mage/game/match/MatchType +instanceKlass org/junit/Before +instanceKlass java/util/LinkedHashMap$LinkedHashIterator +instanceKlass org/junit/Ignore +instanceKlass java/lang/annotation/Target +instanceKlass java/lang/reflect/WeakCache$Value +instanceKlass sun/misc/ProxyGenerator$ExceptionTableEntry +instanceKlass sun/misc/ProxyGenerator$PrimitiveTypeInfo +instanceKlass sun/misc/ProxyGenerator$FieldInfo +instanceKlass java/io/DataOutput +instanceKlass sun/misc/ProxyGenerator$ConstantPool$Entry +instanceKlass sun/misc/ProxyGenerator$MethodInfo +instanceKlass sun/misc/ProxyGenerator$ProxyMethod +instanceKlass sun/misc/ProxyGenerator$ConstantPool +instanceKlass sun/security/action/GetBooleanAction +instanceKlass sun/misc/ProxyGenerator +instanceKlass java/lang/reflect/WeakCache$Factory +instanceKlass java/util/function/Supplier +instanceKlass java/lang/reflect/Proxy$ProxyClassFactory +instanceKlass java/lang/reflect/Proxy$KeyFactory +instanceKlass java/util/function/BiFunction +instanceKlass java/lang/reflect/WeakCache +instanceKlass java/lang/reflect/Proxy +instanceKlass sun/reflect/annotation/AnnotationInvocationHandler +instanceKlass java/lang/reflect/InvocationHandler +instanceKlass sun/reflect/annotation/AnnotationParser$1 +instanceKlass java/lang/Class$4 +instanceKlass java/lang/annotation/Inherited +instanceKlass java/lang/annotation/Retention +instanceKlass sun/reflect/annotation/ExceptionProxy +instanceKlass java/lang/Long$LongCache +instanceKlass sun/reflect/annotation/AnnotationType$1 +instanceKlass java/lang/reflect/GenericArrayType +instanceKlass org/junit/Test +instanceKlass sun/reflect/generics/visitor/Reifier +instanceKlass sun/reflect/generics/visitor/TypeTreeVisitor +instanceKlass sun/reflect/generics/factory/CoreReflectionFactory +instanceKlass sun/reflect/generics/factory/GenericsFactory +instanceKlass sun/reflect/generics/scope/AbstractScope +instanceKlass sun/reflect/generics/scope/Scope +instanceKlass sun/reflect/generics/tree/ClassTypeSignature +instanceKlass sun/reflect/generics/tree/SimpleClassTypeSignature +instanceKlass sun/reflect/generics/tree/FieldTypeSignature +instanceKlass sun/reflect/generics/tree/BaseType +instanceKlass sun/reflect/generics/tree/TypeSignature +instanceKlass sun/reflect/generics/tree/ReturnType +instanceKlass sun/reflect/generics/tree/TypeArgument +instanceKlass sun/reflect/generics/tree/TypeTree +instanceKlass sun/reflect/generics/tree/Tree +instanceKlass sun/reflect/generics/parser/SignatureParser +instanceKlass java/util/Collections$EmptyIterator +instanceKlass sun/reflect/annotation/AnnotationParser +instanceKlass mage/game/permanent/Permanent +instanceKlass mage/cards/Card +instanceKlass mage/MageObject +instanceKlass java/util/UUID +instanceKlass mage/abilities/Ability +instanceKlass mage/game/Controllable +instanceKlass org/mage/test/player/TestPlayer +instanceKlass mage/players/PlayerImpl +instanceKlass mage/game/Game +instanceKlass mage/filter/predicate/Predicate +instanceKlass mage/players/Player +instanceKlass mage/util/Copyable +instanceKlass mage/MageItem +instanceKlass java/io/FilenameFilter +instanceKlass mage/server/util/config/Plugin +instanceKlass org/mage/test/serverside/base/MageTestPlayerBase +instanceKlass org/mage/test/serverside/base/CardTestAPI +instanceKlass org/apache/maven/surefire/shade/org/codehaus/plexus/util/SelectorUtils +instanceKlass org/apache/maven/surefire/shade/org/codehaus/plexus/util/AbstractScanner +instanceKlass org/apache/maven/surefire/shade/org/codehaus/plexus/util/Scanner +instanceKlass org/apache/maven/surefire/booter/ProviderFactory$ProviderProxy +instanceKlass org/junit/runner/RunWith +instanceKlass junit/framework/Test +instanceKlass org/apache/maven/surefire/NonAbstractClassFilter +instanceKlass org/apache/maven/surefire/common/junit3/JUnit3TestChecker +instanceKlass org/apache/maven/surefire/common/junit4/JUnit4TestChecker +instanceKlass org/apache/maven/surefire/common/junit4/JUnit4RunListenerFactory +instanceKlass org/apache/maven/surefire/util/DefaultDirectoryScanner +instanceKlass org/junit/runner/notification/RunListener +instanceKlass org/apache/maven/surefire/report/StackTraceWriter +instanceKlass org/apache/maven/surefire/report/ReportEntry +instanceKlass org/apache/maven/surefire/util/ScannerFilter +instanceKlass org/apache/maven/surefire/providerapi/AbstractProvider +instanceKlass java/util/LinkedList$Node +instanceKlass org/apache/maven/surefire/util/DirectoryScanner +instanceKlass org/apache/maven/surefire/report/ConsoleLogger +instanceKlass org/apache/maven/surefire/booter/BaseProviderFactory +instanceKlass org/apache/maven/surefire/providerapi/SurefireProvider +instanceKlass org/apache/maven/surefire/booter/ProviderFactory +instanceKlass org/apache/maven/surefire/util/ReflectionUtils +instanceKlass org/apache/maven/surefire/report/RunListener +instanceKlass org/apache/maven/surefire/booter/ForkingReporterFactory +instanceKlass org/apache/maven/surefire/providerapi/ProviderParameters +instanceKlass org/apache/maven/surefire/suite/RunResult +instanceKlass org/apache/maven/surefire/report/ReporterFactory +instanceKlass org/apache/maven/surefire/booter/ProviderPropertiesAware +instanceKlass org/apache/maven/surefire/booter/ReporterConfigurationAware +instanceKlass org/apache/maven/surefire/booter/SurefireClassLoadersAware +instanceKlass org/apache/maven/surefire/booter/TestRequestAware +instanceKlass org/apache/maven/surefire/booter/DirectoryScannerParametersAware +instanceKlass org/apache/maven/surefire/booter/TestArtifactInfoAware +instanceKlass org/apache/maven/surefire/report/AbstractReporter +instanceKlass org/apache/maven/surefire/report/Reporter +instanceKlass org/apache/maven/surefire/booter/StartupReportConfiguration +instanceKlass org/apache/maven/surefire/booter/SurefireReflector +instanceKlass java/lang/AssertionStatusDirectives +instanceKlass org/apache/maven/surefire/util/UrlUtils +instanceKlass org/apache/maven/surefire/booter/SurefireStarter +instanceKlass org/apache/maven/surefire/booter/StartupConfiguration +instanceKlass java/util/ArrayList$Itr +instanceKlass org/apache/maven/surefire/booter/Classpath +instanceKlass org/apache/maven/surefire/booter/ClasspathConfiguration +instanceKlass org/apache/maven/surefire/booter/ClassLoaderConfiguration +instanceKlass org/apache/maven/surefire/booter/ProviderConfiguration +instanceKlass org/apache/maven/surefire/report/ReporterConfiguration +instanceKlass org/apache/maven/surefire/testset/TestRequest +instanceKlass org/apache/maven/surefire/testset/TestArtifactInfo +instanceKlass org/apache/maven/surefire/util/RunOrder +instanceKlass org/apache/maven/surefire/testset/DirectoryScannerParameters +instanceKlass org/apache/maven/surefire/booter/TypeEncodedValue +instanceKlass org/apache/maven/surefire/booter/BooterDeserializer +instanceKlass org/apache/maven/surefire/booter/BooterConstants +instanceKlass org/apache/maven/surefire/booter/PropertiesWrapper +instanceKlass java/util/Properties$LineReader +instanceKlass org/apache/maven/surefire/booter/SystemPropertyManager +instanceKlass java/lang/Void +instanceKlass java/lang/Class$MethodArray +instanceKlass sun/launcher/LauncherHelper$FXHelper +instanceKlass org/apache/maven/surefire/booter/ForkedBooter +instanceKlass java/io/FilePermission$1 +instanceKlass sun/net/www/MessageHeader +instanceKlass java/net/URLConnection +instanceKlass java/security/PermissionCollection +instanceKlass sun/nio/ByteBuffered +instanceKlass sun/security/util/ManifestEntryVerifier +instanceKlass sun/security/util/SignatureFileVerifier +instanceKlass java/lang/Package +instanceKlass sun/misc/Resource +instanceKlass sun/misc/ExtensionDependency +instanceKlass sun/misc/JarIndex +instanceKlass sun/misc/FileURLMapper +instanceKlass sun/misc/URLClassPath$JarLoader$1 +instanceKlass sun/nio/cs/ThreadLocalCoders$Cache +instanceKlass sun/nio/cs/ThreadLocalCoders +instanceKlass sun/misc/URLClassPath$Loader +instanceKlass sun/misc/URLClassPath$3 +instanceKlass sun/net/util/URLUtil +instanceKlass java/net/URLClassLoader$1 +instanceKlass java/util/jar/JarVerifier$3 +instanceKlass java/security/CodeSigner +instanceKlass java/util/jar/JarVerifier +instanceKlass sun/misc/ASCIICaseInsensitiveComparator +instanceKlass java/util/jar/Attributes$Name +instanceKlass java/util/jar/Attributes +instanceKlass sun/misc/IOUtils +instanceKlass java/util/zip/ZStreamRef +instanceKlass java/util/zip/Inflater +instanceKlass java/util/zip/ZipEntry +instanceKlass sun/nio/ch/DirectBuffer +instanceKlass sun/misc/PerfCounter$CoreCounters +instanceKlass sun/misc/Perf +instanceKlass sun/misc/Perf$GetPerfAction +instanceKlass sun/misc/PerfCounter +instanceKlass java/util/zip/ZipCoder +instanceKlass java/util/Deque +instanceKlass java/util/Queue +instanceKlass java/nio/charset/StandardCharsets +instanceKlass java/util/jar/JavaUtilJarAccessImpl +instanceKlass sun/misc/JavaUtilJarAccess +instanceKlass java/util/zip/ZipFile$1 +instanceKlass sun/misc/JavaUtilZipFileAccess +instanceKlass java/util/zip/ZipFile +instanceKlass java/util/zip/ZipConstants +instanceKlass java/lang/StringCoding$StringDecoder +instanceKlass sun/nio/cs/SingleByte +instanceKlass java/io/FileOutputStream$1 +instanceKlass java/lang/StringCoding$StringEncoder +instanceKlass java/lang/ThreadLocal$ThreadLocalMap +instanceKlass java/lang/StringCoding +instanceKlass sun/usagetracker/UsageTrackerClient$3 +instanceKlass java/util/TreeMap$Entry +instanceKlass java/lang/ProcessEnvironment$CheckedEntry +instanceKlass java/util/HashMap$HashIterator +instanceKlass java/lang/ProcessEnvironment$CheckedEntrySet$1 +instanceKlass java/util/NavigableMap +instanceKlass java/util/SortedMap +instanceKlass java/util/Collections$UnmodifiableMap +instanceKlass java/lang/ProcessEnvironment$EntryComparator +instanceKlass java/lang/ProcessEnvironment$NameComparator +instanceKlass sun/usagetracker/UsageTrackerClient$2 +instanceKlass sun/usagetracker/UsageTrackerClient$4 +instanceKlass sun/usagetracker/UsageTrackerClient$1 +instanceKlass java/util/concurrent/atomic/AtomicBoolean +instanceKlass sun/usagetracker/UsageTrackerClient +instanceKlass sun/misc/PostVMInitHook +instanceKlass java/lang/invoke/MethodHandleStatics$1 +instanceKlass java/lang/invoke/MethodHandleStatics +instanceKlass java/lang/invoke/MemberName$Factory +instanceKlass java/lang/ClassValue$Version +instanceKlass java/lang/ClassValue$Identity +instanceKlass java/lang/ClassValue +instanceKlass java/lang/invoke/MethodHandleImpl$3 +instanceKlass java/lang/invoke/MethodHandleImpl$2 +instanceKlass java/util/function/Function +instanceKlass java/lang/invoke/MethodHandleImpl$1 +instanceKlass java/lang/invoke/MethodHandleImpl +instanceKlass java/lang/SystemClassLoaderAction +instanceKlass sun/misc/Launcher$AppClassLoader$1 +instanceKlass sun/misc/URLClassPath +instanceKlass java/security/Principal +instanceKlass java/security/ProtectionDomain$Key +instanceKlass java/security/ProtectionDomain$2 +instanceKlass sun/misc/JavaSecurityProtectionDomainAccess +instanceKlass java/security/ProtectionDomain$JavaSecurityAccessImpl +instanceKlass sun/misc/JavaSecurityAccess +instanceKlass java/net/URLStreamHandler +instanceKlass java/net/Parts +instanceKlass java/util/BitSet +instanceKlass sun/net/www/ParseUtil +instanceKlass java/io/FileInputStream$1 +instanceKlass java/lang/CharacterData +instanceKlass sun/util/locale/LocaleUtils +instanceKlass java/util/Locale$LocaleKey +instanceKlass sun/util/locale/BaseLocale$Key +instanceKlass sun/util/locale/BaseLocale +instanceKlass java/util/concurrent/ConcurrentHashMap$CollectionView +instanceKlass java/util/concurrent/ConcurrentHashMap$CounterCell +instanceKlass java/util/concurrent/ConcurrentHashMap$Node +instanceKlass java/util/concurrent/locks/ReentrantLock +instanceKlass java/util/concurrent/locks/Lock +instanceKlass java/util/concurrent/ConcurrentMap +instanceKlass sun/util/locale/LocaleObjectCache +instanceKlass java/util/Locale +instanceKlass java/lang/reflect/Array +instanceKlass java/nio/charset/CoderResult$Cache +instanceKlass java/nio/charset/CoderResult +instanceKlass java/nio/charset/CharsetDecoder +instanceKlass sun/nio/cs/ArrayDecoder +instanceKlass java/io/Reader +instanceKlass java/lang/Readable +instanceKlass sun/misc/MetaIndex +instanceKlass sun/misc/Launcher$ExtClassLoader$1 +instanceKlass java/util/StringTokenizer +instanceKlass java/net/URLClassLoader$7 +instanceKlass sun/misc/JavaNetAccess +instanceKlass java/lang/ClassLoader$ParallelLoaders +instanceKlass sun/security/util/Debug +instanceKlass sun/misc/Launcher$Factory +instanceKlass java/net/URLStreamHandlerFactory +instanceKlass java/lang/Compiler$1 +instanceKlass java/lang/Compiler +instanceKlass java/lang/System$2 +instanceKlass sun/misc/JavaLangAccess +instanceKlass sun/io/Win32ErrorMode +instanceKlass sun/misc/OSEnvironment +instanceKlass java/lang/Integer$IntegerCache +instanceKlass sun/misc/NativeSignalHandler +instanceKlass sun/misc/Signal +instanceKlass java/lang/Terminator$1 +instanceKlass sun/misc/SignalHandler +instanceKlass java/lang/Terminator +instanceKlass java/lang/ClassLoader$NativeLibrary +instanceKlass java/io/ExpiringCache$Entry +instanceKlass java/lang/ClassLoader$3 +instanceKlass java/nio/file/Path +instanceKlass java/nio/file/Watchable +instanceKlass java/lang/Enum +instanceKlass java/io/ExpiringCache +instanceKlass java/io/FileSystem +instanceKlass java/io/DefaultFileSystem +instanceKlass java/nio/Bits$1 +instanceKlass sun/misc/JavaNioAccess +instanceKlass java/nio/ByteOrder +instanceKlass java/nio/Bits +instanceKlass java/nio/charset/CodingErrorAction +instanceKlass java/nio/charset/CharsetEncoder +instanceKlass sun/nio/cs/ArrayEncoder +instanceKlass sun/reflect/ReflectionFactory$1 +instanceKlass java/lang/Class$1 +instanceKlass sun/nio/cs/HistoricallyNamedCharset +instanceKlass java/util/Arrays +instanceKlass sun/security/action/GetPropertyAction +instanceKlass java/lang/ThreadLocal +instanceKlass java/nio/charset/spi/CharsetProvider +instanceKlass java/nio/charset/Charset +instanceKlass java/io/Writer +instanceKlass sun/reflect/misc/ReflectUtil +instanceKlass java/lang/reflect/ReflectAccess +instanceKlass sun/reflect/LangReflectAccess +instanceKlass java/lang/reflect/Modifier +instanceKlass sun/reflect/annotation/AnnotationType +instanceKlass java/lang/Class$AnnotationData +instanceKlass sun/reflect/generics/repository/AbstractRepository +instanceKlass java/lang/Class$Atomic +instanceKlass java/lang/Class$ReflectionData +instanceKlass java/lang/Class$3 +instanceKlass java/util/concurrent/atomic/AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl$1 +instanceKlass java/security/PrivilegedExceptionAction +instanceKlass java/util/concurrent/atomic/AtomicReferenceFieldUpdater +instanceKlass java/io/OutputStream +instanceKlass java/io/Flushable +instanceKlass java/io/FileDescriptor$1 +instanceKlass sun/misc/JavaIOFileDescriptorAccess +instanceKlass java/io/FileDescriptor +instanceKlass sun/misc/Version +instanceKlass java/lang/Runtime +instanceKlass java/util/Hashtable$Enumerator +instanceKlass java/util/Iterator +instanceKlass java/util/Enumeration +instanceKlass java/util/Objects +instanceKlass java/util/Collections$SynchronizedCollection +instanceKlass java/lang/Math +instanceKlass java/util/Hashtable$Entry +instanceKlass sun/misc/VM +instanceKlass java/util/HashMap$Node +instanceKlass java/util/Map$Entry +instanceKlass sun/reflect/Reflection +instanceKlass sun/misc/SharedSecrets +instanceKlass java/lang/ref/Reference$1 +instanceKlass sun/misc/JavaLangRefAccess +instanceKlass java/lang/ref/ReferenceQueue$Lock +instanceKlass java/lang/ref/ReferenceQueue +instanceKlass java/util/Collections$UnmodifiableCollection +instanceKlass java/util/AbstractMap +instanceKlass java/util/Set +instanceKlass java/util/Collections +instanceKlass java/lang/ref/Reference$Lock +instanceKlass sun/reflect/ReflectionFactory +instanceKlass java/util/AbstractCollection +instanceKlass java/util/RandomAccess +instanceKlass java/util/List +instanceKlass java/util/Collection +instanceKlass java/lang/Iterable +instanceKlass java/security/cert/Certificate +instanceKlass sun/reflect/ReflectionFactory$GetReflectionFactoryAction +instanceKlass java/security/PrivilegedAction +instanceKlass java/security/AccessController +instanceKlass java/security/Permission +instanceKlass java/security/Guard +instanceKlass java/lang/String$CaseInsensitiveComparator +instanceKlass java/util/Comparator +instanceKlass java/io/ObjectStreamField +instanceKlass java/lang/Number +instanceKlass java/lang/Character +instanceKlass java/lang/Boolean +instanceKlass java/nio/Buffer +instanceKlass java/lang/StackTraceElement +instanceKlass java/security/CodeSource +instanceKlass sun/misc/Launcher +instanceKlass java/util/jar/Manifest +instanceKlass java/net/URL +instanceKlass java/io/File +instanceKlass java/io/InputStream +instanceKlass java/io/Closeable +instanceKlass java/lang/AutoCloseable +instanceKlass sun/misc/Unsafe +instanceKlass java/lang/AbstractStringBuilder +instanceKlass java/lang/Appendable +instanceKlass java/lang/invoke/CallSite +instanceKlass java/lang/invoke/MethodType +instanceKlass java/lang/invoke/LambdaForm +instanceKlass java/lang/invoke/MethodHandleNatives +instanceKlass java/lang/invoke/MemberName +instanceKlass java/lang/invoke/MethodHandle +instanceKlass sun/reflect/CallerSensitive +instanceKlass java/lang/annotation/Annotation +instanceKlass sun/reflect/FieldAccessor +instanceKlass sun/reflect/ConstantPool +instanceKlass sun/reflect/ConstructorAccessor +instanceKlass sun/reflect/MethodAccessor +instanceKlass sun/reflect/MagicAccessorImpl +instanceKlass java/lang/reflect/Parameter +instanceKlass java/lang/reflect/Member +instanceKlass java/lang/reflect/AccessibleObject +instanceKlass java/util/Dictionary +instanceKlass java/util/Map +instanceKlass java/lang/ThreadGroup +instanceKlass java/lang/Thread$UncaughtExceptionHandler +instanceKlass java/lang/Thread +instanceKlass java/lang/Runnable +instanceKlass java/lang/ref/Reference +instanceKlass java/security/AccessControlContext +instanceKlass java/security/ProtectionDomain +instanceKlass java/lang/SecurityManager +instanceKlass java/lang/Throwable +instanceKlass java/lang/System +instanceKlass java/lang/ClassLoader +instanceKlass java/lang/Cloneable +instanceKlass java/lang/Class +instanceKlass java/lang/reflect/Type +instanceKlass java/lang/reflect/GenericDeclaration +instanceKlass java/lang/reflect/AnnotatedElement +instanceKlass java/lang/String +instanceKlass java/lang/CharSequence +instanceKlass java/lang/Comparable +instanceKlass java/io/Serializable +ciInstanceKlass java/lang/Object 1 1 78 3 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 7 100 7 7 7 7 7 1 1 1 12 12 12 12 12 12 12 12 12 12 10 10 10 10 10 10 10 10 10 10 1 +ciInstanceKlass java/io/Serializable 1 0 7 1 1 1 100 100 1 +ciInstanceKlass java/lang/String 1 1 540 3 3 3 3 8 8 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 100 100 7 7 100 100 100 7 7 100 100 7 100 100 100 7 100 100 7 100 7 7 100 7 100 100 7 100 7 100 100 7 7 7 7 100 7 7 100 100 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 11 1 1 +staticfield java/lang/String serialPersistentFields [Ljava/io/ObjectStreamField; 0 [Ljava/io/ObjectStreamField; +staticfield java/lang/String CASE_INSENSITIVE_ORDER Ljava/util/Comparator; java/lang/String$CaseInsensitiveComparator +ciInstanceKlass java/lang/Class 1 1 1190 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 5 0 8 8 8 8 8 7 7 7 100 100 100 7 7 100 7 100 7 7 7 7 100 7 7 100 7 100 100 100 7 100 100 100 100 100 100 7 7 7 7 100 100 100 7 7 7 100 100 100 7 100 100 7 7 100 7 100 7 7 100 100 7 7 100 100 100 100 7 100 7 7 100 7 7 7 7 100 100 7 7 7 7 100 7 100 7 7 100 100 7 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 1 1 1 1 1 1 1 1 +staticfield java/lang/Class serialPersistentFields [Ljava/io/ObjectStreamField; 0 [Ljava/io/ObjectStreamField; +ciInstanceKlass java/lang/Cloneable 1 0 7 1 1 1 100 100 1 +instanceKlass java/util/ResourceBundle$RBClassLoader +instanceKlass sun/reflect/DelegatingClassLoader +instanceKlass java/security/SecureClassLoader +ciInstanceKlass java/lang/ClassLoader 1 1 842 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 7 7 7 7 100 7 100 7 7 100 7 7 7 7 100 7 100 7 100 100 7 7 100 100 7 100 7 7 100 100 100 100 7 100 100 7 7 100 7 7 100 7 7 7 7 7 7 7 7 7 7 7 7 7 100 7 7 7 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 1 1 +staticfield java/lang/ClassLoader nocerts [Ljava/security/cert/Certificate; 0 [Ljava/security/cert/Certificate; +ciInstanceKlass java/lang/System 1 1 369 8 8 8 8 8 8 8 8 8 8 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 7 7 7 7 100 7 100 100 100 100 100 100 7 7 100 100 7 100 100 7 7 7 7 100 100 100 7 100 100 7 7 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 1 +staticfield java/lang/System in Ljava/io/InputStream; java/io/BufferedInputStream +staticfield java/lang/System out Ljava/io/PrintStream; org/apache/maven/surefire/report/ConsoleOutputCapture$ForwardingPrintStream +staticfield java/lang/System err Ljava/io/PrintStream; org/apache/maven/surefire/report/ConsoleOutputCapture$ForwardingPrintStream +instanceKlass org/junit/Test$None +instanceKlass java/lang/Exception +instanceKlass java/lang/Error +ciInstanceKlass java/lang/Throwable 1 1 327 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 7 100 100 100 100 100 100 7 100 100 100 100 7 7 100 7 100 100 100 7 100 100 7 7 7 7 100 100 100 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 11 1 1 1 1 1 +staticfield java/lang/Throwable UNASSIGNED_STACK [Ljava/lang/StackTraceElement; 0 [Ljava/lang/StackTraceElement; +staticfield java/lang/Throwable SUPPRESSED_SENTINEL Ljava/util/List; java/util/Collections$UnmodifiableRandomAccessList +staticfield java/lang/Throwable EMPTY_THROWABLE_ARRAY [Ljava/lang/Throwable; 0 [Ljava/lang/Throwable; +staticfield java/lang/Throwable $assertionsDisabled Z 1 +instanceKlass javax/xml/parsers/FactoryConfigurationError +instanceKlass java/lang/AssertionError +instanceKlass java/lang/VirtualMachineError +instanceKlass java/lang/LinkageError +instanceKlass java/lang/ThreadDeath +ciInstanceKlass java/lang/Error 1 1 30 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 7 1 1 12 12 12 12 12 10 10 10 10 10 1 +ciInstanceKlass java/lang/ThreadDeath 0 0 18 1 1 1 1 1 1 1 1 1 1 5 0 100 100 12 10 1 +instanceKlass org/junit/runners/model/MultipleFailureException +instanceKlass java/text/ParseException +instanceKlass java/sql/SQLException +instanceKlass javax/xml/stream/XMLStreamException +instanceKlass com/sun/xml/bind/v2/model/impl/ClassInfoImpl$ConflictException +instanceKlass com/sun/xml/bind/v2/model/impl/ClassInfoImpl$DuplicateException +instanceKlass javax/activation/MimeTypeParseException +instanceKlass java/net/URISyntaxException +instanceKlass javax/xml/datatype/DatatypeConfigurationException +instanceKlass com/sun/xml/bind/api/AccessorException +instanceKlass javax/xml/transform/TransformerException +instanceKlass javax/xml/parsers/ParserConfigurationException +instanceKlass org/xml/sax/SAXException +instanceKlass javax/xml/bind/JAXBException +instanceKlass java/beans/PropertyVetoException +instanceKlass org/apache/log4j/config/PropertySetterException +instanceKlass java/beans/IntrospectionException +instanceKlass org/junit/runner/manipulation/NoTestsRemainException +instanceKlass org/junit/runners/model/InitializationError +instanceKlass java/lang/CloneNotSupportedException +instanceKlass mage/MageException +instanceKlass java/security/PrivilegedActionException +instanceKlass org/apache/maven/surefire/util/NestedCheckedException +instanceKlass java/io/IOException +instanceKlass java/lang/InterruptedException +instanceKlass java/lang/ReflectiveOperationException +instanceKlass java/lang/RuntimeException +ciInstanceKlass java/lang/Exception 1 1 30 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 7 1 1 12 12 12 12 12 10 10 10 10 10 1 +instanceKlass org/h2/message/DbException +instanceKlass java/util/NoSuchElementException +instanceKlass java/lang/reflect/MalformedParameterizedTypeException +instanceKlass java/lang/SecurityException +instanceKlass java/lang/IndexOutOfBoundsException +instanceKlass java/util/MissingResourceException +instanceKlass org/junit/internal/AssumptionViolatedException +instanceKlass org/junit/runner/notification/StoppedByUserException +instanceKlass java/lang/reflect/UndeclaredThrowableException +instanceKlass java/lang/UnsupportedOperationException +instanceKlass org/apache/maven/surefire/util/NestedRuntimeException +instanceKlass java/lang/IllegalStateException +instanceKlass java/lang/IllegalArgumentException +instanceKlass java/lang/ArithmeticException +instanceKlass java/lang/NullPointerException +instanceKlass java/lang/IllegalMonitorStateException +instanceKlass java/lang/ArrayStoreException +instanceKlass java/lang/ClassCastException +ciInstanceKlass java/lang/RuntimeException 1 1 30 1 1 1 1 1 1 1 1 1 1 1 1 5 0 7 100 1 1 12 12 12 12 12 10 10 10 10 10 1 +ciInstanceKlass java/lang/SecurityManager 0 0 375 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 +ciInstanceKlass java/security/ProtectionDomain 1 1 272 8 8 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 7 100 100 100 100 100 100 100 100 100 7 7 100 7 7 100 7 7 7 100 100 100 7 7 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 1 1 +staticfield java/security/ProtectionDomain debug Lsun/security/util/Debug; null +ciInstanceKlass java/security/AccessControlContext 1 1 305 8 8 8 8 8 8 8 8 8 8 8 8 8 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 7 100 100 100 100 100 7 100 100 7 100 100 100 100 7 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 1 +instanceKlass java/net/URLClassLoader +ciInstanceKlass java/security/SecureClassLoader 1 1 130 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 100 100 100 100 7 100 7 7 7 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 +staticfield java/security/SecureClassLoader debug Lsun/security/util/Debug; null +instanceKlass java/lang/NoSuchFieldException +instanceKlass java/lang/InstantiationException +instanceKlass java/lang/NoSuchMethodException +instanceKlass java/lang/IllegalAccessException +instanceKlass java/lang/reflect/InvocationTargetException +instanceKlass java/lang/ClassNotFoundException +ciInstanceKlass java/lang/ReflectiveOperationException 1 1 27 1 1 1 1 1 1 1 1 1 1 1 1 5 0 7 100 1 12 12 12 12 10 10 10 10 1 +ciInstanceKlass java/lang/ClassNotFoundException 1 1 32 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 7 100 1 1 1 12 12 12 9 10 10 1 +instanceKlass java/lang/ClassFormatError +instanceKlass java/lang/ExceptionInInitializerError +instanceKlass java/lang/IncompatibleClassChangeError +instanceKlass java/lang/BootstrapMethodError +instanceKlass java/lang/NoClassDefFoundError +ciInstanceKlass java/lang/LinkageError 1 1 24 1 1 1 1 1 1 1 1 1 1 1 5 0 7 100 1 12 12 12 10 10 10 1 +ciInstanceKlass java/lang/NoClassDefFoundError 1 1 21 1 1 1 1 1 1 1 1 1 1 1 5 0 7 100 12 12 10 10 1 +ciInstanceKlass java/lang/ClassCastException 1 1 21 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 12 12 10 10 1 +ciInstanceKlass java/lang/ArrayStoreException 1 1 21 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 12 12 10 10 1 +instanceKlass java/lang/InternalError +instanceKlass java/lang/StackOverflowError +instanceKlass java/lang/OutOfMemoryError +ciInstanceKlass java/lang/VirtualMachineError 1 1 27 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 1 12 12 12 12 10 10 10 10 1 +ciInstanceKlass java/lang/OutOfMemoryError 1 1 21 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 12 12 10 10 1 +ciInstanceKlass java/lang/StackOverflowError 1 1 21 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 12 12 10 10 1 +ciInstanceKlass java/lang/IllegalMonitorStateException 1 1 21 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 12 12 10 10 1 +instanceKlass java/lang/ref/PhantomReference +instanceKlass java/lang/ref/FinalReference +instanceKlass java/lang/ref/WeakReference +instanceKlass java/lang/ref/SoftReference +ciInstanceKlass java/lang/ref/Reference 1 1 134 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 7 100 7 7 100 7 7 7 7 7 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 1 +instanceKlass sun/util/locale/provider/LocaleResources$ResourceReference +instanceKlass java/util/ResourceBundle$BundleReference +instanceKlass sun/util/locale/LocaleObjectCache$CacheEntry +ciInstanceKlass java/lang/ref/SoftReference 1 1 35 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 7 7 1 1 1 1 12 12 12 12 12 9 9 10 10 10 1 +instanceKlass sun/nio/ch/SharedFileLockTable$FileLockReference +instanceKlass java/lang/reflect/Proxy$Key2 +instanceKlass java/util/logging/LogManager$LoggerWeakRef +instanceKlass java/beans/WeakIdentityMap$Entry +instanceKlass java/util/ResourceBundle$LoaderReference +instanceKlass java/io/ObjectStreamClass$FieldReflectorKey +instanceKlass java/io/ObjectStreamClass$WeakClassKey +instanceKlass java/lang/reflect/WeakCache$CacheValue +instanceKlass java/lang/reflect/Proxy$Key1 +instanceKlass java/lang/reflect/WeakCache$CacheKey +instanceKlass java/lang/ThreadLocal$ThreadLocalMap$Entry +instanceKlass java/lang/ClassValue$Entry +instanceKlass java/util/WeakHashMap$Entry +ciInstanceKlass java/lang/ref/WeakReference 1 1 20 1 1 1 1 1 1 1 1 7 100 1 1 1 1 12 12 10 10 1 +instanceKlass java/lang/ref/Finalizer +ciInstanceKlass java/lang/ref/FinalReference 1 1 16 1 1 1 1 1 1 1 100 7 1 1 1 12 10 1 +instanceKlass org/h2/util/CloseWatcher +instanceKlass sun/misc/Cleaner +ciInstanceKlass java/lang/ref/PhantomReference 1 1 19 1 1 1 1 1 1 1 1 1 1 100 7 1 1 1 12 10 1 +ciInstanceKlass sun/misc/Cleaner 1 1 74 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 7 7 100 7 100 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 10 10 10 10 10 10 10 11 1 +staticfield sun/misc/Cleaner dummyQueue Ljava/lang/ref/ReferenceQueue; java/lang/ref/ReferenceQueue +ciInstanceKlass java/lang/ref/Finalizer 1 1 148 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 7 7 7 100 7 7 100 100 100 7 7 100 7 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 1 1 +staticfield java/lang/ref/Finalizer lock Ljava/lang/Object; java/lang/Object +instanceKlass org/h2/mvstore/MVStore$BackgroundWriterThread +instanceKlass org/h2/engine/DatabaseCloser +instanceKlass java/util/logging/LogManager$Cleaner +instanceKlass java/lang/ref/Finalizer$FinalizerThread +instanceKlass java/lang/ref/Reference$ReferenceHandler +ciInstanceKlass java/lang/Thread 1 1 539 3 3 8 8 8 8 8 8 8 8 8 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 100 100 100 100 100 100 100 100 100 7 100 100 7 7 7 100 7 100 7 7 100 100 100 100 100 100 7 100 100 100 100 100 100 100 7 100 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 1 1 1 1 1 +staticfield java/lang/Thread EMPTY_STACK_TRACE [Ljava/lang/StackTraceElement; 0 [Ljava/lang/StackTraceElement; +staticfield java/lang/Thread SUBCLASS_IMPLEMENTATION_PERMISSION Ljava/lang/RuntimePermission; java/lang/RuntimePermission +ciInstanceKlass java/lang/ThreadGroup 1 1 268 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 100 100 7 100 100 7 7 100 100 7 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 1 1 +instanceKlass java/util/Hashtable +ciInstanceKlass java/util/Dictionary 1 1 31 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 100 1 1 1 1 1 1 12 10 1 +instanceKlass java/util/Properties +ciInstanceKlass java/util/Hashtable 1 1 402 3 3 4 4 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 5 0 100 100 100 100 100 100 100 100 100 100 7 100 100 7 100 7 100 100 100 7 100 7 7 100 7 7 7 7 100 7 7 7 7 7 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 11 11 11 11 11 1 1 1 1 1 +instanceKlass java/security/Provider +instanceKlass org/h2/util/SortedProperties +ciInstanceKlass java/util/Properties 1 1 263 3 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 7 100 100 100 7 100 100 100 100 100 7 7 7 100 7 7 7 100 100 7 7 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 1 1 1 +staticfield java/util/Properties hexDigit [C 16 +instanceKlass java/lang/reflect/Executable +instanceKlass java/lang/reflect/Field +ciInstanceKlass java/lang/reflect/AccessibleObject 1 1 144 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 7 100 100 7 7 7 7 100 7 7 7 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 1 1 +staticfield java/lang/reflect/AccessibleObject ACCESS_PERMISSION Ljava/security/Permission; java/lang/reflect/ReflectPermission +staticfield java/lang/reflect/AccessibleObject reflectionFactory Lsun/reflect/ReflectionFactory; sun/reflect/ReflectionFactory +ciInstanceKlass java/lang/reflect/Field 1 1 362 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 100 100 100 100 7 7 7 100 100 100 7 7 7 7 7 100 7 7 100 100 100 100 7 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 1 1 +ciInstanceKlass java/lang/reflect/Parameter 0 0 210 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 1 +instanceKlass java/lang/reflect/Constructor +instanceKlass java/lang/reflect/Method +ciInstanceKlass java/lang/reflect/Executable 1 1 378 3 8 8 8 8 8 8 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 100 100 7 100 100 100 100 7 7 7 7 100 100 100 7 100 7 100 7 7 7 7 7 100 100 100 100 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 1 1 +ciInstanceKlass java/lang/reflect/Method 1 1 346 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 7 7 100 100 7 7 7 100 7 100 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 1 +ciInstanceKlass java/lang/reflect/Constructor 1 1 330 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 100 7 100 100 100 100 100 100 7 7 100 100 100 100 100 7 7 7 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 1 1 +instanceKlass sun/reflect/FieldAccessorImpl +instanceKlass sun/reflect/ConstructorAccessorImpl +instanceKlass sun/reflect/MethodAccessorImpl +ciInstanceKlass sun/reflect/MagicAccessorImpl 1 1 13 1 1 1 1 1 1 1 7 100 12 10 1 +instanceKlass sun/reflect/GeneratedMethodAccessor8 +instanceKlass sun/reflect/GeneratedMethodAccessor7 +instanceKlass sun/reflect/GeneratedMethodAccessor6 +instanceKlass sun/reflect/GeneratedMethodAccessor5 +instanceKlass sun/reflect/GeneratedMethodAccessor4 +instanceKlass sun/reflect/GeneratedMethodAccessor3 +instanceKlass sun/reflect/GeneratedMethodAccessor2 +instanceKlass sun/reflect/GeneratedMethodAccessor1 +instanceKlass sun/reflect/DelegatingMethodAccessorImpl +instanceKlass sun/reflect/NativeMethodAccessorImpl +ciInstanceKlass sun/reflect/MethodAccessorImpl 1 1 22 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 7 100 100 12 10 1 +instanceKlass sun/reflect/GeneratedConstructorAccessor4 +instanceKlass sun/reflect/SerializationConstructorAccessorImpl +instanceKlass sun/reflect/BootstrapConstructorAccessorImpl +instanceKlass sun/reflect/DelegatingConstructorAccessorImpl +instanceKlass sun/reflect/NativeConstructorAccessorImpl +ciInstanceKlass sun/reflect/ConstructorAccessorImpl 1 1 24 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 100 7 12 10 1 +ciInstanceKlass sun/reflect/DelegatingClassLoader 1 1 13 1 1 1 1 1 1 1 7 100 1 12 10 +ciInstanceKlass sun/reflect/ConstantPool 1 1 106 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 +instanceKlass sun/reflect/UnsafeFieldAccessorImpl +ciInstanceKlass sun/reflect/FieldAccessorImpl 1 1 56 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 7 1 1 1 1 1 1 1 1 1 1 1 1 1 12 10 1 +instanceKlass sun/reflect/UnsafeBooleanFieldAccessorImpl +instanceKlass sun/reflect/UnsafeObjectFieldAccessorImpl +instanceKlass sun/reflect/UnsafeStaticFieldAccessorImpl +ciInstanceKlass sun/reflect/UnsafeFieldAccessorImpl 1 1 229 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 7 100 100 100 100 100 100 7 100 100 100 7 7 7 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 +staticfield sun/reflect/UnsafeFieldAccessorImpl unsafe Lsun/misc/Unsafe; sun/misc/Unsafe +instanceKlass sun/reflect/UnsafeQualifiedStaticFieldAccessorImpl +ciInstanceKlass sun/reflect/UnsafeStaticFieldAccessorImpl 1 1 38 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 7 7 7 1 1 1 1 12 12 12 12 12 9 9 10 10 10 1 +ciInstanceKlass sun/reflect/CallerSensitive 0 0 17 1 1 1 1 1 1 1 1 100 100 100 1 1 1 1 1 +instanceKlass java/lang/invoke/DirectMethodHandle +ciInstanceKlass java/lang/invoke/MethodHandle 1 1 438 8 8 8 8 8 8 8 8 8 8 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 7 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 7 100 7 100 100 100 100 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 1 1 1 +staticfield java/lang/invoke/MethodHandle FORM_OFFSET J 20 +staticfield java/lang/invoke/MethodHandle $assertionsDisabled Z 1 +ciInstanceKlass java/lang/invoke/DirectMethodHandle 0 0 692 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 100 100 100 100 100 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 1 1 1 1 1 1 1 +ciInstanceKlass java/lang/invoke/MemberName 1 1 642 3 3 3 3 3 3 3 3 3 3 3 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 100 100 7 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 100 100 100 100 100 100 7 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 1 1 +staticfield java/lang/invoke/MemberName $assertionsDisabled Z 1 +ciInstanceKlass java/lang/invoke/MethodHandleNatives 1 1 427 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 100 100 100 7 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 7 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 7 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 1 +staticfield java/lang/invoke/MethodHandleNatives COUNT_GWT Z 1 +staticfield java/lang/invoke/MethodHandleNatives $assertionsDisabled Z 1 +ciInstanceKlass java/lang/invoke/LambdaForm 0 0 967 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 8 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 1 1 1 1 1 1 +ciInstanceKlass java/lang/invoke/MethodType 0 0 591 8 8 8 8 8 8 8 8 8 8 8 8 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 5 0 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 1 1 +ciInstanceKlass java/lang/BootstrapMethodError 0 0 38 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 100 100 1 1 12 12 12 12 12 10 10 10 10 10 1 +instanceKlass java/lang/invoke/VolatileCallSite +instanceKlass java/lang/invoke/MutableCallSite +instanceKlass java/lang/invoke/ConstantCallSite +ciInstanceKlass java/lang/invoke/CallSite 0 0 311 8 8 8 8 8 8 8 8 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 +ciInstanceKlass java/lang/invoke/ConstantCallSite 0 0 42 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 100 1 1 12 12 12 12 12 12 9 9 10 10 10 10 10 1 +ciInstanceKlass java/lang/invoke/MutableCallSite 0 0 57 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 9 9 10 10 10 10 10 10 10 10 1 +ciInstanceKlass java/lang/invoke/VolatileCallSite 0 0 33 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 1 1 1 12 12 12 12 12 12 10 10 10 10 10 10 1 +instanceKlass java/lang/StringBuilder +instanceKlass java/lang/StringBuffer +ciInstanceKlass java/lang/AbstractStringBuilder 1 1 318 3 3 3 8 8 8 8 8 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 7 100 7 100 100 100 7 7 7 100 7 100 100 100 7 7 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 1 +ciInstanceKlass java/lang/StringBuffer 1 1 371 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 100 100 100 7 100 7 7 100 100 7 7 7 100 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 1 1 1 +staticfield java/lang/StringBuffer serialPersistentFields [Ljava/io/ObjectStreamField; 3 [Ljava/io/ObjectStreamField; +ciInstanceKlass java/lang/StringBuilder 1 1 326 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 100 100 100 7 100 100 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 1 +ciInstanceKlass sun/misc/Unsafe 1 1 389 8 8 7 7 7 7 7 7 7 7 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 100 7 100 100 7 100 7 100 100 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 +staticfield sun/misc/Unsafe theUnsafe Lsun/misc/Unsafe; sun/misc/Unsafe +staticfield sun/misc/Unsafe ARRAY_BOOLEAN_BASE_OFFSET I 16 +staticfield sun/misc/Unsafe ARRAY_BYTE_BASE_OFFSET I 16 +staticfield sun/misc/Unsafe ARRAY_SHORT_BASE_OFFSET I 16 +staticfield sun/misc/Unsafe ARRAY_CHAR_BASE_OFFSET I 16 +staticfield sun/misc/Unsafe ARRAY_INT_BASE_OFFSET I 16 +staticfield sun/misc/Unsafe ARRAY_LONG_BASE_OFFSET I 16 +staticfield sun/misc/Unsafe ARRAY_FLOAT_BASE_OFFSET I 16 +staticfield sun/misc/Unsafe ARRAY_DOUBLE_BASE_OFFSET I 16 +staticfield sun/misc/Unsafe ARRAY_OBJECT_BASE_OFFSET I 16 +staticfield sun/misc/Unsafe ARRAY_BOOLEAN_INDEX_SCALE I 1 +staticfield sun/misc/Unsafe ARRAY_BYTE_INDEX_SCALE I 1 +staticfield sun/misc/Unsafe ARRAY_SHORT_INDEX_SCALE I 2 +staticfield sun/misc/Unsafe ARRAY_CHAR_INDEX_SCALE I 2 +staticfield sun/misc/Unsafe ARRAY_INT_INDEX_SCALE I 4 +staticfield sun/misc/Unsafe ARRAY_LONG_INDEX_SCALE I 8 +staticfield sun/misc/Unsafe ARRAY_FLOAT_INDEX_SCALE I 4 +staticfield sun/misc/Unsafe ARRAY_DOUBLE_INDEX_SCALE I 8 +staticfield sun/misc/Unsafe ARRAY_OBJECT_INDEX_SCALE I 4 +staticfield sun/misc/Unsafe ADDRESS_SIZE I 8 +instanceKlass org/h2/util/AutoCloseInputStream +instanceKlass org/h2/mvstore/StreamStore$Stream +instanceKlass org/h2/store/CountingReaderInputStream +instanceKlass java/io/SequenceInputStream +instanceKlass org/h2/store/fs/FileChannelInputStream +instanceKlass com/sun/org/apache/xerces/internal/impl/XMLEntityManager$RewindableInputStream +instanceKlass java/io/ObjectInputStream +instanceKlass java/util/zip/ZipFile$ZipFileInputStream +instanceKlass java/io/FilterInputStream +instanceKlass java/io/FileInputStream +instanceKlass java/io/ByteArrayInputStream +ciInstanceKlass java/io/InputStream 1 1 61 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 5 0 100 100 100 7 100 100 100 7 12 12 12 12 12 10 10 10 10 10 10 10 1 +ciInstanceKlass java/io/ByteArrayInputStream 1 1 62 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 100 7 100 100 100 7 1 12 12 12 12 12 12 12 9 9 9 9 10 10 10 10 10 1 +ciInstanceKlass java/io/File 1 1 578 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 7 100 7 100 7 100 100 7 100 100 100 100 100 100 100 7 100 100 100 100 100 7 100 100 100 100 7 7 7 100 100 7 100 7 7 7 100 7 100 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 1 1 1 1 +staticfield java/io/File fs Ljava/io/FileSystem; java/io/WinNTFileSystem +staticfield java/io/File separatorChar C 92 +staticfield java/io/File separator Ljava/lang/String; "\" +staticfield java/io/File pathSeparatorChar C 59 +staticfield java/io/File pathSeparator Ljava/lang/String; ";" +staticfield java/io/File PATH_OFFSET J 16 +staticfield java/io/File PREFIX_LENGTH_OFFSET J 12 +staticfield java/io/File UNSAFE Lsun/misc/Unsafe; sun/misc/Unsafe +staticfield java/io/File $assertionsDisabled Z 1 +instanceKlass mage/server/util/PluginClassLoader +instanceKlass org/apache/maven/surefire/booter/IsolatedClassLoader +instanceKlass sun/misc/Launcher$ExtClassLoader +instanceKlass sun/misc/Launcher$AppClassLoader +ciInstanceKlass java/net/URLClassLoader 1 1 522 8 8 8 8 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 7 7 100 100 100 7 7 7 100 100 7 100 100 100 7 7 7 100 7 100 7 7 7 7 7 100 100 100 7 7 100 100 100 7 7 7 7 7 7 100 100 100 7 7 7 100 7 7 7 7 7 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 11 +ciInstanceKlass java/net/URL 1 1 550 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 100 100 100 100 7 100 7 7 100 100 100 100 100 7 7 100 7 7 100 100 100 100 7 100 100 100 100 7 7 7 100 100 7 7 7 100 7 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 1 +staticfield java/net/URL serialPersistentFields [Ljava/io/ObjectStreamField; 7 [Ljava/io/ObjectStreamField; +ciInstanceKlass java/util/jar/Manifest 1 1 230 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 100 100 7 7 7 100 100 7 100 7 100 100 7 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 11 11 11 11 11 1 1 +ciInstanceKlass sun/misc/Launcher 1 1 218 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 7 100 100 100 100 100 100 100 100 7 100 7 100 7 7 100 7 7 100 7 7 7 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 1 1 +ciInstanceKlass sun/misc/Launcher$AppClassLoader 1 1 201 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 100 7 7 100 7 100 7 7 100 100 7 100 7 100 7 100 7 7 7 100 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 1 +staticfield sun/misc/Launcher$AppClassLoader $assertionsDisabled Z 1 +ciInstanceKlass sun/misc/Launcher$ExtClassLoader 1 1 209 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 7 100 7 7 7 7 7 100 7 100 100 100 7 7 7 7 7 7 100 7 7 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 1 +ciInstanceKlass java/security/CodeSource 1 1 322 8 8 8 8 8 8 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 100 100 100 100 100 100 100 7 100 100 100 100 7 100 7 100 100 100 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 1 +ciInstanceKlass java/lang/StackTraceElement 1 1 98 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 7 7 7 7 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 1 +instanceKlass java/nio/LongBuffer +instanceKlass java/nio/CharBuffer +instanceKlass java/nio/ByteBuffer +ciInstanceKlass java/nio/Buffer 1 1 103 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 100 100 7 100 7 100 100 100 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 1 +ciInstanceKlass java/lang/Boolean 1 1 110 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 7 7 100 100 100 7 100 7 7 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 10 10 10 10 10 10 10 10 10 10 1 +staticfield java/lang/Boolean TRUE Ljava/lang/Boolean; java/lang/Boolean +staticfield java/lang/Boolean FALSE Ljava/lang/Boolean; java/lang/Boolean +staticfield java/lang/Boolean TYPE Ljava/lang/Class; java/lang/Class +ciInstanceKlass java/lang/Character 1 1 459 3 3 3 3 3 3 3 3 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 5 0 5 0 100 100 7 7 100 100 100 7 100 7 100 100 100 100 7 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 1 1 1 1 1 +staticfield java/lang/Character TYPE Ljava/lang/Class; java/lang/Class +staticfield java/lang/Character $assertionsDisabled Z 1 +instanceKlass java/math/BigDecimal +instanceKlass java/math/BigInteger +instanceKlass java/util/concurrent/atomic/AtomicLong +instanceKlass java/util/concurrent/atomic/AtomicInteger +instanceKlass java/lang/Long +instanceKlass java/lang/Integer +instanceKlass java/lang/Short +instanceKlass java/lang/Byte +instanceKlass java/lang/Double +instanceKlass java/lang/Float +ciInstanceKlass java/lang/Number 1 1 34 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 7 12 12 10 10 1 +ciInstanceKlass java/lang/Float 1 1 169 3 3 3 4 4 4 4 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 4 4 5 0 7 100 100 7 100 7 100 100 7 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 +staticfield java/lang/Float TYPE Ljava/lang/Class; java/lang/Class +ciInstanceKlass java/lang/Double 1 1 223 8 8 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 5 0 5 0 5 0 5 0 5 0 6 0 6 0 6 0 6 0 6 0 6 0 6 0 7 100 7 100 100 7 100 100 100 7 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 +staticfield java/lang/Double TYPE Ljava/lang/Class; java/lang/Class +ciInstanceKlass java/lang/Byte 1 1 153 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 5 0 5 0 7 7 7 100 100 7 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 +staticfield java/lang/Byte TYPE Ljava/lang/Class; java/lang/Class +ciInstanceKlass java/lang/Short 1 1 159 3 3 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 5 0 5 0 7 100 100 7 100 7 7 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 +staticfield java/lang/Short TYPE Ljava/lang/Class; java/lang/Class +ciInstanceKlass java/lang/Integer 1 1 309 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 5 0 5 0 5 0 100 7 7 100 100 7 7 100 7 100 7 100 100 100 7 100 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 +staticfield java/lang/Integer TYPE Ljava/lang/Class; java/lang/Class +staticfield java/lang/Integer digits [C 36 +staticfield java/lang/Integer DigitTens [C 100 +staticfield java/lang/Integer DigitOnes [C 100 +staticfield java/lang/Integer sizeTable [I 10 +ciInstanceKlass java/lang/Long 1 1 356 3 3 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 100 100 7 100 100 7 7 7 7 100 7 100 100 100 7 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 +staticfield java/lang/Long TYPE Ljava/lang/Class; java/lang/Class +ciInstanceKlass java/lang/NullPointerException 1 1 21 1 1 1 1 1 1 1 1 1 1 1 5 0 100 7 12 12 10 10 1 +ciInstanceKlass java/lang/ArithmeticException 1 1 21 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 12 12 10 10 1 +instanceKlass java/lang/ref/ReferenceQueue$Null +ciInstanceKlass java/lang/ref/ReferenceQueue 1 1 121 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 7 100 100 7 100 100 7 7 100 7 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 1 1 +staticfield java/lang/ref/ReferenceQueue $assertionsDisabled Z 1 +ciInstanceKlass java/lang/ref/ReferenceQueue$Lock 1 1 21 1 1 1 1 1 1 1 1 1 1 7 100 100 7 1 12 10 10 1 1 +ciInstanceKlass sun/misc/VM 1 1 226 8 8 8 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 5 0 5 0 100 100 100 100 7 7 7 100 100 100 100 7 7 7 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 +staticfield sun/misc/VM lock Ljava/lang/Object; java/lang/Object +staticfield sun/misc/VM savedProps Ljava/util/Properties; java/util/Properties +ciInstanceKlass java/util/WeakHashMap$Entry 1 1 91 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 7 100 100 100 100 7 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 10 10 10 10 10 10 10 10 10 10 10 11 11 1 +compile java/lang/ref/ReferenceQueue poll ()Ljava/lang/ref/Reference; -1 4 inline 1 0 -1 java/lang/ref/ReferenceQueue poll ()Ljava/lang/ref/Reference; diff --git a/Mage/src/main/java/mage/MageObject.java b/Mage/src/main/java/mage/MageObject.java index 5e3fb97dea2..db9ed97dee6 100644 --- a/Mage/src/main/java/mage/MageObject.java +++ b/Mage/src/main/java/mage/MageObject.java @@ -35,6 +35,8 @@ public interface MageObject extends MageItem, Serializable { boolean hasAbility(UUID abilityId, Game game); ObjectColor getColor(Game game); + + ObjectColor getFrameColor(Game game); ManaCosts getManaCost(); @@ -43,6 +45,10 @@ public interface MageObject extends MageItem, Serializable { MageInt getPower(); MageInt getToughness(); + + int getStartingLoyalty(); + + void adjustCosts(Ability ability, Game game); diff --git a/Mage/src/main/java/mage/MageObjectImpl.java b/Mage/src/main/java/mage/MageObjectImpl.java index 82d082df6d6..80b3d7fd8d2 100644 --- a/Mage/src/main/java/mage/MageObjectImpl.java +++ b/Mage/src/main/java/mage/MageObjectImpl.java @@ -33,10 +33,12 @@ import java.util.UUID; import mage.abilities.Abilities; import mage.abilities.AbilitiesImpl; import mage.abilities.Ability; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCosts; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.keyword.ChangelingAbility; +import mage.abilities.mana.ManaAbility; import mage.constants.CardType; import mage.game.Game; import mage.util.CardUtil; @@ -49,6 +51,7 @@ public abstract class MageObjectImpl implements MageObject { protected String name; protected ManaCosts manaCost; protected ObjectColor color; + protected ObjectColor frameColor; protected List cardType = new ArrayList<>(); protected List subtype = new ArrayList<>(); protected List supertype = new ArrayList<>(); @@ -67,6 +70,7 @@ public abstract class MageObjectImpl implements MageObject { power = new MageInt(0); toughness = new MageInt(0); color = new ObjectColor(); + frameColor = new ObjectColor(); manaCost = new ManaCostsImpl<>(""); abilities = new AbilitiesImpl<>(); } @@ -77,6 +81,7 @@ public abstract class MageObjectImpl implements MageObject { manaCost = object.manaCost.copy(); text = object.text; color = object.color.copy(); + frameColor = object.frameColor.copy(); power = object.power.copy(); toughness = object.toughness.copy(); abilities = object.abilities.copy(); @@ -154,11 +159,67 @@ public abstract class MageObjectImpl implements MageObject { public MageInt getToughness() { return toughness; } + + @Override + public int getStartingLoyalty() { + for (Ability ab: getAbilities()) { + if (ab instanceof PlanswalkerEntersWithLoyalityCountersAbility) { + return ((PlanswalkerEntersWithLoyalityCountersAbility)ab).getStartingLoyalty(); + } + } + return 0; + } @Override public ObjectColor getColor(Game game) { return color; } + + @Override + public ObjectColor getFrameColor(Game game) { + // For lands, add any colors of mana the land can produce to + // its frame colors. + if (getCardType().contains(CardType.LAND)) { + ObjectColor cl = frameColor.copy(); + for (Ability ab: getAbilities()) { + if (ab instanceof ManaAbility) { + ManaAbility mana = (ManaAbility)ab; + try { + List manaAdded = mana.getNetMana(game); + for (Mana m: manaAdded) { + if (m.getAny() > 0) { + return new ObjectColor("WUBRG"); + } + if (m.getWhite() > 0) { + cl.setWhite(true); + } + if (m.getBlue() > 0) { + cl.setBlue(true); + } + if (m.getBlack() > 0) { + cl.setBlack(true); + } + if (m.getRed() > 0) { + cl.setRed(true); + } + if (m.getGreen() > 0) { + cl.setGreen(true); + } + } + } catch (NullPointerException e) { + // Ability depends on game + // but no game passed + // All such abilities are 5-color ones + return new ObjectColor("WUBRG"); + } + } + } + return cl; + } else { + // For everything else, just return the frame colors + return frameColor; + } + } @Override public ManaCosts getManaCost() { diff --git a/Mage/src/main/java/mage/ObjectColor.java b/Mage/src/main/java/mage/ObjectColor.java index 91a30015840..60827481e64 100644 --- a/Mage/src/main/java/mage/ObjectColor.java +++ b/Mage/src/main/java/mage/ObjectColor.java @@ -81,6 +81,22 @@ public class ObjectColor implements Serializable, Copyable, Compara red = color.red; green = color.green; } + + /** + * Returns a new color which contains all of the colors of this ObjectColor + * in addition to all of the colors of the other ObjectColor. + * @param other The other ObjectColor to union with + * @return A new color which is the union of this and other + */ + public ObjectColor union(ObjectColor other) { + ObjectColor newColor = new ObjectColor(); + newColor.white = white | other.white; + newColor.blue = blue | other.blue; + newColor.black = black | other.black; + newColor.red = red | other.red; + newColor.green = green | other.green; + return newColor; + } public int getColorCount() { int count = 0; diff --git a/Mage/src/main/java/mage/abilities/common/PlanswalkerEntersWithLoyalityCountersAbility.java b/Mage/src/main/java/mage/abilities/common/PlanswalkerEntersWithLoyalityCountersAbility.java index 963f5168d4e..d47119c7f89 100644 --- a/Mage/src/main/java/mage/abilities/common/PlanswalkerEntersWithLoyalityCountersAbility.java +++ b/Mage/src/main/java/mage/abilities/common/PlanswalkerEntersWithLoyalityCountersAbility.java @@ -14,13 +14,21 @@ import mage.counters.CounterType; */ public class PlanswalkerEntersWithLoyalityCountersAbility extends EntersBattlefieldAbility { - public PlanswalkerEntersWithLoyalityCountersAbility(int loyality) { - super(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(loyality))); + private final int startingLoyalty; + + public PlanswalkerEntersWithLoyalityCountersAbility(int loyalty) { + super(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(loyalty))); + startingLoyalty = loyalty; setRuleVisible(false); } public PlanswalkerEntersWithLoyalityCountersAbility(final PlanswalkerEntersWithLoyalityCountersAbility ability) { super(ability); + startingLoyalty = ability.startingLoyalty; + } + + public int getStartingLoyalty() { + return startingLoyalty; } @Override diff --git a/Mage/src/main/java/mage/cards/basiclands/Forest.java b/Mage/src/main/java/mage/cards/basiclands/Forest.java index abecdb2a85d..46aa777d13a 100644 --- a/Mage/src/main/java/mage/cards/basiclands/Forest.java +++ b/Mage/src/main/java/mage/cards/basiclands/Forest.java @@ -29,6 +29,7 @@ package mage.cards.basiclands; import java.util.UUID; +import mage.ObjectColor; import mage.abilities.mana.GreenManaAbility; /** @@ -43,6 +44,7 @@ public abstract class Forest extends BasicLand { public Forest(UUID ownerId, String cardNumber) { super(ownerId, cardNumber, "Forest", new GreenManaAbility()); + this.frameColor = ObjectColor.GREEN; } public Forest(final Forest land) { diff --git a/Mage/src/main/java/mage/cards/basiclands/Island.java b/Mage/src/main/java/mage/cards/basiclands/Island.java index 74d53377ea3..569d7c9bc69 100644 --- a/Mage/src/main/java/mage/cards/basiclands/Island.java +++ b/Mage/src/main/java/mage/cards/basiclands/Island.java @@ -29,6 +29,7 @@ package mage.cards.basiclands; import java.util.UUID; +import mage.ObjectColor; import mage.abilities.mana.BlueManaAbility; /** @@ -43,6 +44,7 @@ public abstract class Island extends BasicLand { public Island(UUID ownerId, String cardNumber) { super(ownerId, cardNumber, "Island", new BlueManaAbility()); + this.frameColor = ObjectColor.BLUE; } public Island(Island land) { diff --git a/Mage/src/main/java/mage/cards/basiclands/Mountain.java b/Mage/src/main/java/mage/cards/basiclands/Mountain.java index 3616be6cb75..dc38fcc2b8f 100644 --- a/Mage/src/main/java/mage/cards/basiclands/Mountain.java +++ b/Mage/src/main/java/mage/cards/basiclands/Mountain.java @@ -29,6 +29,7 @@ package mage.cards.basiclands; import java.util.UUID; +import mage.ObjectColor; import mage.abilities.mana.RedManaAbility; /** @@ -43,6 +44,7 @@ public abstract class Mountain extends BasicLand { public Mountain(UUID ownerId, String cardNumber) { super(ownerId, cardNumber, "Mountain", new RedManaAbility()); + this.frameColor = ObjectColor.RED; } public Mountain(Mountain land) { diff --git a/Mage/src/main/java/mage/cards/basiclands/Plains.java b/Mage/src/main/java/mage/cards/basiclands/Plains.java index a69f3496567..50637352285 100644 --- a/Mage/src/main/java/mage/cards/basiclands/Plains.java +++ b/Mage/src/main/java/mage/cards/basiclands/Plains.java @@ -29,6 +29,7 @@ package mage.cards.basiclands; import java.util.UUID; +import mage.ObjectColor; import mage.abilities.mana.WhiteManaAbility; /** @@ -43,6 +44,7 @@ public abstract class Plains extends BasicLand { public Plains(UUID ownerId, String cardNumber) { super(ownerId, cardNumber, "Plains", new WhiteManaAbility()); + this.frameColor = ObjectColor.WHITE; } public Plains(Plains land) { diff --git a/Mage/src/main/java/mage/cards/basiclands/Swamp.java b/Mage/src/main/java/mage/cards/basiclands/Swamp.java index d6df027b693..d262d5510f4 100644 --- a/Mage/src/main/java/mage/cards/basiclands/Swamp.java +++ b/Mage/src/main/java/mage/cards/basiclands/Swamp.java @@ -29,6 +29,7 @@ package mage.cards.basiclands; import java.util.UUID; +import mage.ObjectColor; import mage.abilities.mana.BlackManaAbility; /** @@ -43,6 +44,7 @@ public abstract class Swamp extends BasicLand { public Swamp(UUID ownerId, String cardNumber) { super(ownerId, cardNumber, "Swamp", new BlackManaAbility()); + this.frameColor = ObjectColor.BLACK; } public Swamp(Swamp land) { diff --git a/Mage/src/main/java/mage/cards/mock/MockCard.java b/Mage/src/main/java/mage/cards/mock/MockCard.java index 22254765676..7a0d375d972 100644 --- a/Mage/src/main/java/mage/cards/mock/MockCard.java +++ b/Mage/src/main/java/mage/cards/mock/MockCard.java @@ -7,11 +7,18 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.cards.CardImpl; import mage.cards.repository.CardInfo; import mage.cards.repository.CardRepository; +import mage.constants.CardType; +import org.apache.log4j.Logger; /** * @author North */ public class MockCard extends CardImpl { + // Needs to be here, as it is normally calculated from the + // PlaneswalkerEntersWithLoyaltyAbility of the card... but the MockCard + // only has MockAbilities. + private int startingLoyalty; + public MockCard(CardInfo card) { super(null, card.getName()); this.cardNumber = card.getCardNumber(); @@ -28,6 +35,9 @@ public class MockCard extends CardImpl { this.manaCost = new ManaCostsImpl(join(card.getManaCosts())); this.color = card.getColor(); + + this.frameColor = card.getFrameColor(); + this.splitCard = card.isSplitCard(); this.flipCard = card.isFlipCard(); @@ -36,9 +46,21 @@ public class MockCard extends CardImpl { if (card.getSecondSideName() != null && !card.getSecondSideName().isEmpty()) { this.secondSideCard = new MockCard(CardRepository.instance.findCard(card.getSecondSideName())); } + + if (this.cardType.contains(CardType.PLANESWALKER)) { + String startingLoyaltyString = card.getStartingLoyalty(); + if (startingLoyaltyString.isEmpty()) { + //Logger.getLogger(MockCard.class).warn("Planeswalker `" + this.name + "` has empty starting loyalty."); + } else { + try { + this.startingLoyalty = Integer.parseInt(startingLoyaltyString); + } catch (NumberFormatException e) { + Logger.getLogger(MockCard.class).warn("Planeswalker `" + this.name + "` starting loyalty in bad format: `" + startingLoyaltyString + "`."); + } + } + } this.flipCardName = card.getFlipCardName(); - for(String ruleText: card.getRules()) { this.addAbility(textAbilityFromString(ruleText)); } @@ -47,6 +69,11 @@ public class MockCard extends CardImpl { public MockCard(final MockCard card) { super(card); } + + @Override + public int getStartingLoyalty() { + return startingLoyalty; + } @Override public MockCard copy() { diff --git a/Mage/src/main/java/mage/cards/repository/CardInfo.java b/Mage/src/main/java/mage/cards/repository/CardInfo.java index 92b0a4e817e..a9ead5ffcc9 100644 --- a/Mage/src/main/java/mage/cards/repository/CardInfo.java +++ b/Mage/src/main/java/mage/cards/repository/CardInfo.java @@ -39,7 +39,9 @@ import java.util.List; import mage.constants.CardType; import mage.constants.Rarity; import mage.ObjectColor; +import mage.abilities.Ability; import mage.abilities.SpellAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.mock.MockCard; @@ -70,6 +72,8 @@ public class CardInfo { @DatabaseField protected String toughness; @DatabaseField + protected String startingLoyalty; + @DatabaseField protected int convertedManaCost; @DatabaseField(dataType = DataType.ENUM_STRING) protected Rarity rarity; @@ -94,6 +98,8 @@ public class CardInfo { @DatabaseField protected boolean white; @DatabaseField + protected String frameColor; + @DatabaseField protected boolean splitCard; @DatabaseField protected boolean splitCardHalf; @@ -132,6 +138,7 @@ public class CardInfo { this.secondSideName = secondSide.getName(); } + this.frameColor = card.getFrameColor(null).toString(); this.blue = card.getColor(null).isBlue(); this.black = card.getColor(null).isBlack(); this.green = card.getColor(null).isGreen(); @@ -144,13 +151,13 @@ public class CardInfo { this.setManaCosts(card.getManaCost().getSymbols()); int length = 0; - for (String rule :card.getRules()) { + for (String rule: card.getRules()) { length += rule.length(); } if (length > MAX_RULE_LENGTH) { length = 0; ArrayList shortRules = new ArrayList<>(); - for (String rule :card.getRules()) { + for (String rule: card.getRules()) { if (length + rule.length() + 3 <= MAX_RULE_LENGTH) { shortRules.add(rule); length += rule.length() + 3; @@ -173,6 +180,21 @@ public class CardInfo { this.splitCardHalf = true; } } + + // Starting loyalty + if (card.getCardType().contains(CardType.PLANESWALKER)) { + for (Ability ab: card.getAbilities()) { + if (ab instanceof PlanswalkerEntersWithLoyalityCountersAbility) { + this.startingLoyalty = "" + ((PlanswalkerEntersWithLoyalityCountersAbility) ab).getStartingLoyalty(); + } + } + if (this.startingLoyalty == null) { + //Logger.getLogger(CardInfo.class).warn("Planeswalker `" + card.getName() + "` missing starting loyalty"); + this.startingLoyalty = ""; + } + } else { + this.startingLoyalty = ""; + } } public Card getCard() { @@ -200,6 +222,10 @@ public class CardInfo { color.setWhite(white); return color; } + + public ObjectColor getFrameColor() { + return new ObjectColor(frameColor); + } private String joinList(List items) { StringBuilder sb = new StringBuilder(); @@ -286,6 +312,10 @@ public class CardInfo { public String getToughness() { return toughness; } + + public String getStartingLoyalty() { + return startingLoyalty; + } public String getSetCode() { return setCode; diff --git a/Mage/src/main/java/mage/cards/repository/CardRepository.java b/Mage/src/main/java/mage/cards/repository/CardRepository.java index 6f0b2e78854..448771998b8 100644 --- a/Mage/src/main/java/mage/cards/repository/CardRepository.java +++ b/Mage/src/main/java/mage/cards/repository/CardRepository.java @@ -61,9 +61,9 @@ public enum CardRepository { private static final String JDBC_URL = "jdbc:h2:file:./db/cards.h2;AUTO_SERVER=TRUE"; private static final String VERSION_ENTITY_NAME = "card"; // raise this if db structure was changed - private static final long CARD_DB_VERSION = 44; + private static final long CARD_DB_VERSION = 46; // raise this if new cards were added to the server - private static final long CARD_CONTENT_VERSION = 55; + private static final long CARD_CONTENT_VERSION = 57; private final Random random = new Random(); private Dao cardDao; diff --git a/Mage/src/main/java/mage/game/command/Commander.java b/Mage/src/main/java/mage/game/command/Commander.java index ccfbe86e535..2805caeb80c 100644 --- a/Mage/src/main/java/mage/game/command/Commander.java +++ b/Mage/src/main/java/mage/game/command/Commander.java @@ -144,6 +144,11 @@ public class Commander implements CommandObject { public ObjectColor getColor(Game game) { return card.getColor(game); } + + @Override + public ObjectColor getFrameColor(Game game) { + return card.getFrameColor(game); + } @Override public ManaCosts getManaCost() { @@ -164,6 +169,11 @@ public class Commander implements CommandObject { public MageInt getToughness() { return card.getToughness(); } + + @Override + public int getStartingLoyalty() { + return card.getStartingLoyalty(); + } @Override public void adjustCosts(Ability ability, Game game) { diff --git a/Mage/src/main/java/mage/game/command/Emblem.java b/Mage/src/main/java/mage/game/command/Emblem.java index f4984fb8a9e..6f9f10a864b 100644 --- a/Mage/src/main/java/mage/game/command/Emblem.java +++ b/Mage/src/main/java/mage/game/command/Emblem.java @@ -153,6 +153,11 @@ public class Emblem implements CommandObject { public ObjectColor getColor(Game game) { return emptyColor; } + + @Override + public ObjectColor getFrameColor(Game game) { + return emptyColor; + } @Override public ManaCosts getManaCost() { @@ -173,6 +178,11 @@ public class Emblem implements CommandObject { public MageInt getToughness() { return MageInt.EmptyMageInt; } + + @Override + public int getStartingLoyalty() { + return 0; + } @Override public void adjustCosts(Ability ability, Game game) { diff --git a/Mage/src/main/java/mage/game/permanent/PermanentCard.java b/Mage/src/main/java/mage/game/permanent/PermanentCard.java index 8323a19e762..bb583cd2921 100644 --- a/Mage/src/main/java/mage/game/permanent/PermanentCard.java +++ b/Mage/src/main/java/mage/game/permanent/PermanentCard.java @@ -118,6 +118,7 @@ public class PermanentCard extends PermanentImpl { this.cardType.clear(); this.cardType.addAll(card.getCardType()); this.color = card.getColor(null).copy(); + this.frameColor = card.getFrameColor(null).copy(); this.manaCost = card.getManaCost().copy(); if (card instanceof PermanentCard) { this.maxLevelCounters = ((PermanentCard) card).maxLevelCounters; diff --git a/Mage/src/main/java/mage/game/permanent/PermanentToken.java b/Mage/src/main/java/mage/game/permanent/PermanentToken.java index 595da012e2c..e95fc3c0ca6 100644 --- a/Mage/src/main/java/mage/game/permanent/PermanentToken.java +++ b/Mage/src/main/java/mage/game/permanent/PermanentToken.java @@ -82,6 +82,7 @@ public class PermanentToken extends PermanentImpl { } this.cardType = token.getCardType(); this.color = token.getColor(game).copy(); + this.frameColor = token.getFrameColor(game); this.power.modifyBaseValue(token.getPower().getBaseValueModified()); this.toughness.modifyBaseValue(token.getToughness().getBaseValueModified()); this.supertype = token.getSupertype(); diff --git a/Mage/src/main/java/mage/game/permanent/token/Token.java b/Mage/src/main/java/mage/game/permanent/token/Token.java index f399a8af700..84dfc613676 100644 --- a/Mage/src/main/java/mage/game/permanent/token/Token.java +++ b/Mage/src/main/java/mage/game/permanent/token/Token.java @@ -187,7 +187,7 @@ public class Token extends MageObjectImpl { } else { MageObject object = game.getObject(sourceId); if (object instanceof PermanentToken) { - ((PermanentToken) object).getExpansionSetCode(); + setCode = ((PermanentToken) object).getExpansionSetCode(); } } } diff --git a/Mage/src/main/java/mage/game/stack/Spell.java b/Mage/src/main/java/mage/game/stack/Spell.java index fac945694d5..6ce48963faf 100644 --- a/Mage/src/main/java/mage/game/stack/Spell.java +++ b/Mage/src/main/java/mage/game/stack/Spell.java @@ -75,6 +75,7 @@ public class Spell extends StackObjImpl implements Card { private final Card card; private final ObjectColor color; + private final ObjectColor frameColor; private final SpellAbility ability; private final Zone fromZone; private final UUID id; @@ -87,6 +88,7 @@ public class Spell extends StackObjImpl implements Card { public Spell(Card card, SpellAbility ability, UUID controllerId, Zone fromZone) { this.card = card; this.color = card.getColor(null).copy(); + this.frameColor = card.getFrameColor(null).copy(); id = ability.getId(); this.ability = ability; this.ability.setControllerId(controllerId); @@ -127,6 +129,7 @@ public class Spell extends StackObjImpl implements Card { this.copiedSpell = spell.copiedSpell; this.faceDown = spell.faceDown; this.color = spell.color.copy(); + this.frameColor = spell.color.copy(); } public boolean activate(Game game, boolean noMana) { @@ -482,6 +485,11 @@ public class Spell extends StackObjImpl implements Card { public ObjectColor getColor(Game game) { return color; } + + @Override + public ObjectColor getFrameColor(Game game) { + return frameColor; + } @Override public ManaCosts getManaCost() { @@ -518,6 +526,11 @@ public class Spell extends StackObjImpl implements Card { public MageInt getToughness() { return card.getToughness(); } + + @Override + public int getStartingLoyalty() { + return card.getStartingLoyalty(); + } @Override public UUID getId() { diff --git a/Mage/src/main/java/mage/game/stack/StackAbility.java b/Mage/src/main/java/mage/game/stack/StackAbility.java index 33f836d8a49..824787d22a9 100644 --- a/Mage/src/main/java/mage/game/stack/StackAbility.java +++ b/Mage/src/main/java/mage/game/stack/StackAbility.java @@ -192,6 +192,11 @@ public class StackAbility extends StackObjImpl implements Ability { public ObjectColor getColor(Game game) { return emptyColor; } + + @Override + public ObjectColor getFrameColor(Game game) { + return ability.getSourceObject(game).getFrameColor(game); + } @Override public ManaCosts getManaCost() { @@ -207,6 +212,11 @@ public class StackAbility extends StackObjImpl implements Ability { public MageInt getToughness() { return MageInt.EmptyMageInt; } + + @Override + public int getStartingLoyalty() { + return 0; + } @Override public Zone getZone() {