deck improves:

* gui: removed public deck hash info;
* gui: improved xmage dck-file - now it correctly load a card's amount (related to files from third party services);
* server: fixed wrong cheating warning on deck construction (closes #11877);
* refactor: removed outdated hash code and calculations;
* other: added docs, added multiple deck hash tests;
This commit is contained in:
Oleg Agafonov 2024-04-10 22:18:07 +04:00
parent 889c1125e8
commit 7817a5cac6
32 changed files with 551 additions and 247 deletions

View file

@ -87,7 +87,6 @@ import java.util.prefs.Preferences;
public class MageFrame extends javax.swing.JFrame implements MageClient {
private static final String TITLE_NAME = "XMage";
private static final Logger logger = Logger.getLogger(MageFrame.class);
private static final Logger LOGGER = Logger.getLogger(MageFrame.class);
private static final String LITE_MODE_ARG = "-lite";
@ -398,7 +397,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
}
private void bootstrapSetsAndFormats() {
logger.info("Loading sets and formats...");
LOGGER.info("Loading sets and formats...");
ConstructedFormats.ensureLists();
}
@ -1460,7 +1459,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
try {
instance = new MageFrame();
} catch (Throwable e) {
logger.fatal("Critical error on start up, app will be closed: " + e.getMessage(), e);
LOGGER.fatal("Critical error on start up, app will be closed: " + e.getMessage(), e);
System.exit(1);
}

View file

@ -1861,9 +1861,9 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
List<CardView> gridStack = new ArrayList<>();
gridRow.add(gridStack);
for (DeckCardInfo info : stack) {
if (trackedCards.containsKey(info.getSetCode()) && trackedCards.get(info.getSetCode()).containsKey(info.getCardNum())) {
if (trackedCards.containsKey(info.getSetCode()) && trackedCards.get(info.getSetCode()).containsKey(info.getCardNumber())) {
List<CardView> candidates
= trackedCards.get(info.getSetCode()).get(info.getCardNum());
= trackedCards.get(info.getSetCode()).get(info.getCardNumber());
if (!candidates.isEmpty()) {
gridStack.add(candidates.remove(0));
thisMaxStackSize = Math.max(thisMaxStackSize, gridStack.size());

View file

@ -328,7 +328,7 @@ public class DeckGeneratorDialog {
tmp.getParentFile().mkdirs();
tmp.createNewFile();
deck.setName(deckName);
XMAGE.getExporter().writeDeck(tmp.getAbsolutePath(), deck.getDeckCardLists());
XMAGE.getExporter().writeDeck(tmp.getAbsolutePath(), deck.prepareCardsOnlyDeck());
cleanUp();
return tmp.getAbsolutePath();
} catch (Exception e) {

View file

@ -794,18 +794,14 @@ public class DeckEditorPanel extends javax.swing.JPanel {
dialog.showDialog();
if (!dialog.getTmpPath().isEmpty()) {
Deck deckToAppend = null;
StringBuilder errorMessages = new StringBuilder();
MageFrame.getDesktop().setCursor(new Cursor(Cursor.WAIT_CURSOR));
try {
deckToAppend = Deck.load(DeckImporter.importDeckFromFile(dialog.getTmpPath(), errorMessages, false), true, true);
Deck deckToAppend = Deck.load(DeckImporter.importDeckFromFile(dialog.getTmpPath(), errorMessages, false), true, true);
processAndShowImportErrors(errorMessages);
if (deckToAppend != null) {
deck = Deck.append(deckToAppend, deck);
refreshDeck();
}
this.deck = Deck.append(deckToAppend, this.deck);
refreshDeck();
} catch (GameException e1) {
JOptionPane.showMessageDialog(MageFrame.getDesktop(), e1.getMessage(), "Error loading deck", JOptionPane.ERROR_MESSAGE);
} finally {
@ -864,7 +860,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
MageFrame.getDesktop().setCursor(new Cursor(Cursor.WAIT_CURSOR));
try {
DeckFormats.writeDeck(needFileName, deck.getDeckCardLists());
DeckFormats.writeDeck(needFileName, deck.prepareCardsOnlyDeck());
try {
MageFrame.getPreferences().put("lastExportFolder", file.getCanonicalPath());
@ -1364,7 +1360,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
useDeckInfo = true;
}
MageFrame.getDesktop().setCursor(new Cursor(Cursor.WAIT_CURSOR));
DeckCardLists cardLists = deck.getDeckCardLists();
DeckCardLists cardLists = deck.prepareCardsOnlyDeck();
cardLists.setCardLayout(deckArea.getCardLayout());
cardLists.setSideboardLayout(deckArea.getSideboardLayout());
if (!useDeckInfo) {
@ -1444,12 +1440,14 @@ public class DeckEditorPanel extends javax.swing.JPanel {
if (mode == DeckEditorMode.SIDEBOARDING
|| mode == DeckEditorMode.LIMITED_BUILDING
|| mode == DeckEditorMode.LIMITED_SIDEBOARD_BUILDING) {
// in game mode - move all to sideboard
for (Card card : deck.getCards()) {
deck.getSideboard().add(card);
}
deck.getCards().clear();
cardSelector.loadSideboard(new ArrayList<>(deck.getSideboard()), this.bigCard);
} else {
// in deck editor mode - clear all cards
deck = new Deck();
}
refreshDeck();
@ -1488,7 +1486,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
updateDeckTask.cancel(true);
}
if (SessionHandler.submitDeck(mode, tableId, deck.getDeckCardLists())) {
if (SessionHandler.submitDeck(mode, tableId, deck.prepareCardsOnlyDeck())) {
removeDeckEditor();
}
}//GEN-LAST:event_btnSubmitActionPerformed
@ -1504,7 +1502,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
updateDeckTask.cancel(true);
}
if (SessionHandler.submitDeck(mode, tableId, deck.getDeckCardLists())) {
if (SessionHandler.submitDeck(mode, tableId, deck.prepareCardsOnlyDeck())) {
SwingUtilities.invokeLater(this::removeDeckEditor);
}
return null;
@ -1617,7 +1615,7 @@ class UpdateDeckTask extends SwingWorker<Void, Void> {
@Override
protected Void doInBackground() throws Exception {
while (!isCancelled()) {
SessionHandler.updateDeck(tableId, deck.getDeckCardLists());
SessionHandler.updateDeck(tableId, deck.prepareCardsOnlyDeck());
TimeUnit.SECONDS.sleep(5);
}
return null;

View file

@ -89,7 +89,7 @@ public class DeckExportClipboardDialog extends MageDialog {
DeckExporter exporter = formats.get(formatIndex).getExporter();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
exporter.writeDeck(baos, deck.getDeckCardLists());
exporter.writeDeck(baos, deck.prepareCardsOnlyDeck());
editData.setText(baos.toString());
editData.setCaretPosition(0);
}

View file

@ -135,7 +135,7 @@ public class DeckLegalityPanel extends javax.swing.JPanel {
} else {
// contains mock cards, e.g. it's a Deck Editor
try {
deckToValidate = Deck.load(deck.getDeckCardLists(), true, false);
deckToValidate = Deck.load(deck.prepareCardsOnlyDeck(), true, false);
} catch (Exception ex) {
logger.error("Can't load real deck cards for validate: " + ex.getMessage(), ex);
return;

View file

@ -557,7 +557,7 @@ public class CustomOptionsDialog extends MageDialog {
}
if (perPlayerEmblemDeck != null) {
perPlayerEmblemDeck.clearLayouts();
options.setPerPlayerEmblemCards(perPlayerEmblemDeck.getDeckCardLists().getCards());
options.setPerPlayerEmblemCards(perPlayerEmblemDeck.prepareCardsOnlyDeck().getCards());
} else {
options.setPerPlayerEmblemCards(Collections.emptySet());
}
@ -571,7 +571,7 @@ public class CustomOptionsDialog extends MageDialog {
}
if (startingPlayerEmblemDeck != null) {
startingPlayerEmblemDeck.clearLayouts();
options.setGlobalEmblemCards(startingPlayerEmblemDeck.getDeckCardLists().getCards());
options.setGlobalEmblemCards(startingPlayerEmblemDeck.prepareCardsOnlyDeck().getCards());
} else {
options.setGlobalEmblemCards(Collections.emptySet());
}

View file

@ -394,7 +394,6 @@ public class PlayerPanelExt extends javax.swing.JPanel {
String countryName = CountryUtil.getCountryName(flagName);
basicTooltipText = "<HTML>Name: " + player.getName()
+ "<br/>Flag: " + (countryName == null ? "Unknown" : countryName)
+ "<br/>Deck hash code: " + player.getDeckHashCode()
+ "<br/>This match wins: " + player.getWins() + " of " + player.getWinsNeeded() + " (to win the match)";
}