forked from External/mage
Merge branch 'External-master'
All checks were successful
/ build_release (push) Successful in 10m38s
All checks were successful
/ build_release (push) Successful in 10m38s
This commit is contained in:
commit
3062dd066d
838 changed files with 24448 additions and 4173 deletions
|
|
@ -122,6 +122,9 @@ public final class Constants {
|
|||
public static final String RESOURCE_SYMBOL_FOLDER_SVG = "svg";
|
||||
public static final String RESOURCE_SYMBOL_FOLDER_PNG = "png";
|
||||
|
||||
// download rarity icons to large folder by default
|
||||
public static final String RESOURCE_PATH_SYMBOLS_RARITY_DEFAULT_PATH = RESOURCE_PATH_SYMBOLS + File.separator + RESOURCE_SYMBOL_FOLDER_LARGE;
|
||||
|
||||
public enum ResourceSymbolSize {
|
||||
SMALL, // TODO: delete SMALL, MEDIUM and LARGE as outdated (svg or generated png works fine)
|
||||
MEDIUM,
|
||||
|
|
@ -133,12 +136,12 @@ public final class Constants {
|
|||
// resources - sets
|
||||
public static final String RESOURCE_PATH_SETS = File.separator + "sets";
|
||||
public static final String RESOURCE_SET_FOLDER_SMALL = "small";
|
||||
public static final String RESOURCE_SET_FOLDER_MEDIUM = ""; // empty, medium images laydown in "sets" folder, TODO: delete that and auto gen, use png for html, not gif
|
||||
public static final String RESOURCE_SET_FOLDER_LARGE = "large";
|
||||
public static final String RESOURCE_SET_FOLDER_SVG = "svg";
|
||||
|
||||
public enum ResourceSetSize {
|
||||
SMALL,
|
||||
MEDIUM,
|
||||
LARGE,
|
||||
SVG
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public class DeckGeneratorPool {
|
|||
// List of cards so far in the deck
|
||||
private final List<Card> deckCards = new ArrayList<>();
|
||||
// List of reserve cards found to fix up undersized decks
|
||||
private final List<Card> reserveSpells = new ArrayList<>();
|
||||
private final Map<String, Card> reserveSpells = new HashMap<>();
|
||||
private final Deck deck;
|
||||
|
||||
/**
|
||||
|
|
@ -170,12 +170,13 @@ public class DeckGeneratorPool {
|
|||
* @param card the card to add.
|
||||
*/
|
||||
public void addCard(Card card) {
|
||||
Object cnt = cardCounts.get((card.getName()));
|
||||
if (cnt == null)
|
||||
cardCounts.put(card.getName(), 0);
|
||||
int existingCount = cardCounts.get((card.getName()));
|
||||
cardCounts.put(card.getName(), existingCount + 1);
|
||||
int count = cardCounts.getOrDefault(card.getName(), 0);
|
||||
cardCounts.put(card.getName(), count + 1);
|
||||
deckCards.add(card);
|
||||
|
||||
if (deckCards.stream().distinct().collect(Collectors.toList()).size() != deckCards.size()) {
|
||||
System.out.println("wtf " + card.getName());
|
||||
}
|
||||
}
|
||||
|
||||
public void clearCards(boolean isClearReserve) {
|
||||
|
|
@ -198,8 +199,8 @@ public class DeckGeneratorPool {
|
|||
// Only cards with CMC < 7 and don't already exist in the deck
|
||||
// can be added to our reserve pool as not to overwhelm the curve
|
||||
// with high CMC cards and duplicates.
|
||||
if (cardCMC < 7 && getCardCount(card.getName()) == 0) {
|
||||
this.reserveSpells.add(card);
|
||||
if (cardCMC < 7 && getCardCount(card.getName()) == 0 && !this.reserveSpells.containsKey(card.getName())) {
|
||||
this.reserveSpells.put(card.getName(), card);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -416,48 +417,38 @@ public class DeckGeneratorPool {
|
|||
* @return a fixed list of cards for this deck.
|
||||
*/
|
||||
private List<Card> getFixedSpells() {
|
||||
int spellSize = deckCards.size();
|
||||
int spellsSize = deckCards.size();
|
||||
int nonLandSize = (deckSize - landCount);
|
||||
|
||||
// Less spells than needed
|
||||
if (spellSize < nonLandSize) {
|
||||
|
||||
int spellsNeeded = nonLandSize - spellSize;
|
||||
|
||||
// If we haven't got enough spells in reserve to fulfil the amount we need, skip adding any.
|
||||
if (reserveSpells.size() >= spellsNeeded) {
|
||||
|
||||
List<Card> spellsToAdd = new ArrayList<>(spellsNeeded);
|
||||
|
||||
// Initial reservoir
|
||||
for (int i = 0; i < spellsNeeded; i++)
|
||||
spellsToAdd.add(reserveSpells.get(i));
|
||||
|
||||
for (int i = spellsNeeded + 1; i < reserveSpells.size() - 1; i++) {
|
||||
int j = RandomUtil.nextInt(i);
|
||||
Card randomCard = reserveSpells.get(j);
|
||||
if (isValidSpellCard(randomCard) && j < spellsToAdd.size()) {
|
||||
spellsToAdd.set(j, randomCard);
|
||||
}
|
||||
// fewer spells than needed - add
|
||||
if (spellsSize < nonLandSize) {
|
||||
int needExtraSpells = nonLandSize - spellsSize;
|
||||
List<Card> possibleSpells = new ArrayList<>(reserveSpells.values());
|
||||
while (needExtraSpells > 0) {
|
||||
Card card = RandomUtil.randomFromCollection(possibleSpells);
|
||||
if (card == null) {
|
||||
break;
|
||||
}
|
||||
// Add randomly selected spells needed
|
||||
deckCards.addAll(spellsToAdd);
|
||||
if (isValidSpellCard(card)) {
|
||||
needExtraSpells--;
|
||||
deckCards.add(card);
|
||||
}
|
||||
possibleSpells.remove(card);
|
||||
}
|
||||
}
|
||||
|
||||
// More spells than needed
|
||||
else if (spellSize > (deckSize - landCount)) {
|
||||
int spellsRemoved = (spellSize) - (deckSize - landCount);
|
||||
for (int i = 0; i < spellsRemoved; ++i) {
|
||||
deckCards.remove(RandomUtil.nextInt(deckCards.size()));
|
||||
// more spells than needed - remove
|
||||
if (spellsSize > nonLandSize) {
|
||||
int removeCount = spellsSize - nonLandSize;
|
||||
for (int i = 0; i < removeCount; ++i) {
|
||||
deckCards.remove(RandomUtil.randomFromCollection(deckCards));
|
||||
}
|
||||
}
|
||||
|
||||
// Check we have exactly the right amount of cards for a deck.
|
||||
if (deckCards.size() != nonLandSize) {
|
||||
logger.info("Can't generate full deck for selected settings - try again or choose more sets and less colors");
|
||||
logger.info("Can't generate full deck for selected settings - try again or choose more sets and less colors (wrong non land cards amount)");
|
||||
}
|
||||
// Return the fixed amount
|
||||
|
||||
return deckCards;
|
||||
}
|
||||
|
||||
|
|
@ -619,48 +610,75 @@ public class DeckGeneratorPool {
|
|||
if (needCommandersCount > 0 && !genPool.cardCounts.isEmpty()) {
|
||||
throw new IllegalArgumentException("Wrong code usage: generateSpells with creatures and commanders must be called as first");
|
||||
}
|
||||
List<CardInfo> cardPool = CardRepository.instance.findCards(criteria);
|
||||
List<Card> cardsPool = CardRepository.instance.findCards(criteria).stream()
|
||||
.map(CardInfo::createMockCard)
|
||||
.filter(genPool::isValidSpellCard)
|
||||
.collect(Collectors.toList());
|
||||
List<Card> commandersPool = cardsPool.stream()
|
||||
.filter(genPool::isValidCommander)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<DeckGeneratorCMC.CMC> deckCMCs = genPool.getCMCsForSpellCount(needCardsCount);
|
||||
int count = 0;
|
||||
int usedCardsCount = 0;
|
||||
int validCommanders = 0;
|
||||
int reservesAdded = 0;
|
||||
if (cardPool.size() > 0 && cardPool.size() >= needCardsCount) {
|
||||
if (cardsPool.size() > 0 && cardsPool.size() >= needCardsCount) {
|
||||
int tries = 0;
|
||||
List<Card> possibleCards = new ArrayList<>(cardsPool);
|
||||
List<Card> possibleCommanders = new ArrayList<>(commandersPool);
|
||||
while (true) {
|
||||
tries++;
|
||||
|
||||
// can't finish deck, stop and use reserved cards later
|
||||
if (tries > DeckGenerator.MAX_TRIES) {
|
||||
logger.info("Can't generate full deck for selected settings - try again or choose more sets and less colors");
|
||||
logger.info("Can't generate full deck for selected settings - try again or choose more sets and less colors (max tries exceeded)");
|
||||
break;
|
||||
}
|
||||
|
||||
// can finish deck - but make sure it has commander
|
||||
if (count >= needCardsCount) {
|
||||
if (usedCardsCount >= needCardsCount) {
|
||||
if (validCommanders < needCommandersCount) {
|
||||
// reset deck search from scratch (except reserved cards)
|
||||
count = 0;
|
||||
usedCardsCount = 0;
|
||||
validCommanders = 0;
|
||||
deckCMCs = genPool.getCMCsForSpellCount(needCardsCount);
|
||||
genPool.clearCards(false);
|
||||
genPool.clearCards(true);
|
||||
possibleCards = new ArrayList<>(cardsPool);
|
||||
possibleCommanders = new ArrayList<>(commandersPool);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Card card = cardPool.get(RandomUtil.nextInt(cardPool.size())).createMockCard();
|
||||
if (possibleCards.isEmpty()) {
|
||||
throw new IllegalStateException("Not enough cards to generate deck (possible cards is empty)");
|
||||
}
|
||||
|
||||
// choose commander first
|
||||
Card card = null;
|
||||
if (validCommanders < needCommandersCount && !possibleCommanders.isEmpty()) {
|
||||
card = RandomUtil.randomFromCollection(possibleCommanders);
|
||||
}
|
||||
|
||||
// choose other cards after commander
|
||||
if (card == null) {
|
||||
card = RandomUtil.randomFromCollection(possibleCards);
|
||||
}
|
||||
|
||||
if (!genPool.isValidSpellCard(card)) {
|
||||
possibleCards.remove(card);
|
||||
possibleCommanders.remove(card);
|
||||
continue;
|
||||
}
|
||||
|
||||
int cardCMC = card.getManaValue();
|
||||
for (DeckGeneratorCMC.CMC deckCMC : deckCMCs) {
|
||||
if (cardCMC >= deckCMC.min && cardCMC <= deckCMC.max) {
|
||||
int currentAmount = deckCMC.getAmount();
|
||||
if (currentAmount > 0) {
|
||||
deckCMC.setAmount(currentAmount - 1);
|
||||
int needAmount = deckCMC.getAmount();
|
||||
if (needAmount > 0) {
|
||||
deckCMC.setAmount(needAmount - 1);
|
||||
genPool.addCard(card.copy());
|
||||
count++;
|
||||
usedCardsCount++;
|
||||
// make sure it has compatible commanders
|
||||
if (genPool.isValidCommander(card)) {
|
||||
validCommanders++;
|
||||
|
|
@ -674,7 +692,7 @@ public class DeckGeneratorPool {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException("Not enough cards to generate deck.");
|
||||
throw new IllegalStateException("Not enough cards to generate deck (cards pool too small)");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ import mage.client.dialog.AddLandDialog;
|
|||
import mage.client.dialog.PreferencesDialog;
|
||||
import mage.client.plugins.impl.Plugins;
|
||||
import mage.client.util.Event;
|
||||
import mage.client.util.GUISizeHelper;
|
||||
import mage.client.util.Listener;
|
||||
import mage.client.util.audio.AudioManager;
|
||||
import mage.components.CardInfoPane;
|
||||
|
|
@ -31,7 +30,6 @@ import mage.util.XmageThreadFactory;
|
|||
import mage.view.CardView;
|
||||
import mage.view.SimpleCardView;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.mage.card.arcane.ManaSymbols;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
|
|
@ -534,7 +532,8 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
}
|
||||
}
|
||||
});
|
||||
refreshDeck(true);
|
||||
|
||||
refreshDeck(true, false);
|
||||
|
||||
// auto-import dropped files from OS
|
||||
if (mode == DeckEditorMode.FREE_BUILDING) {
|
||||
|
|
@ -673,20 +672,28 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
|
||||
private void refreshDeck() {
|
||||
if (this.isVisible()) { // TODO: test auto-close deck with active lands dialog, e.g. on timeout
|
||||
refreshDeck(false);
|
||||
refreshDeck(false, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshDeck(boolean useLayout) {
|
||||
private void refreshDeck(boolean useLayout, boolean useDeckValidation) {
|
||||
try {
|
||||
setCursor(new Cursor(Cursor.WAIT_CURSOR));
|
||||
MageFrame.getDesktop().setCursor(new Cursor(Cursor.WAIT_CURSOR));
|
||||
this.txtDeckName.setText(deck.getName());
|
||||
deckArea.loadDeck(deck, useLayout, bigCard);
|
||||
if (useDeckValidation) {
|
||||
validateDeck();
|
||||
}
|
||||
} finally {
|
||||
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
|
||||
MageFrame.getDesktop().setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
|
||||
}
|
||||
}
|
||||
|
||||
private void validateDeck() {
|
||||
this.deckLegalityDisplay.setVisible(true);
|
||||
this.deckLegalityDisplay.validateDeck(deck);
|
||||
}
|
||||
|
||||
private void setTimeout(int s) {
|
||||
int minute = s / 60;
|
||||
int second = s - (minute * 60);
|
||||
|
|
@ -762,7 +769,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
|
||||
if (newDeck != null) {
|
||||
deck = newDeck;
|
||||
refreshDeck();
|
||||
refreshDeck(false, true);
|
||||
}
|
||||
|
||||
// save last deck import folder
|
||||
|
|
@ -818,7 +825,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
Deck deckToAppend = Deck.load(DeckImporter.importDeckFromFile(tempDeckPath, errorMessages, false), true, true);
|
||||
processAndShowImportErrors(errorMessages);
|
||||
this.deck = Deck.append(deckToAppend, this.deck);
|
||||
refreshDeck();
|
||||
refreshDeck(false, true);
|
||||
} catch (GameException e1) {
|
||||
JOptionPane.showMessageDialog(MageFrame.getDesktop(), e1.getMessage(), "Error loading deck", JOptionPane.ERROR_MESSAGE);
|
||||
} finally {
|
||||
|
|
@ -922,7 +929,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
|
||||
if (newDeck != null) {
|
||||
deck = newDeck;
|
||||
refreshDeck();
|
||||
refreshDeck(false, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1441,7 +1448,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
|
||||
if (newDeck != null) {
|
||||
deck = newDeck;
|
||||
refreshDeck(true);
|
||||
refreshDeck(true, true);
|
||||
}
|
||||
|
||||
// save last deck history
|
||||
|
|
@ -1474,7 +1481,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
// in deck editor mode - clear all cards
|
||||
deck = new Deck();
|
||||
}
|
||||
refreshDeck();
|
||||
refreshDeck(false, true);
|
||||
}//GEN-LAST:event_btnNewActionPerformed
|
||||
|
||||
private void btnExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnExitActionPerformed
|
||||
|
|
@ -1483,7 +1490,9 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
|
||||
private void btnAddLandActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAddLandActionPerformed
|
||||
AddLandDialog dialog = new AddLandDialog();
|
||||
dialog.showDialog(deck, mode, this::refreshDeck);
|
||||
dialog.showDialog(deck, mode, () -> {
|
||||
this.refreshDeck(false, true);
|
||||
});
|
||||
}//GEN-LAST:event_btnAddLandActionPerformed
|
||||
|
||||
private void btnGenDeckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnGenDeckActionPerformed
|
||||
|
|
@ -1501,7 +1510,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
} finally {
|
||||
MageFrame.getDesktop().setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
|
||||
}
|
||||
refreshDeck();
|
||||
refreshDeck(false, true);
|
||||
}//GEN-LAST:event_btnGenDeckActionPerformed
|
||||
|
||||
private void btnSubmitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSubmitActionPerformed
|
||||
|
|
@ -1548,8 +1557,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
}//GEN-LAST:event_btnExportActionPerformed
|
||||
|
||||
private void btnLegalityActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLegalityActionPerformed
|
||||
this.deckLegalityDisplay.setVisible(true);
|
||||
this.deckLegalityDisplay.validateDeck(deck);
|
||||
validateDeck();
|
||||
}//GEN-LAST:event_btnLegalityActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ public class DraftPickLogger {
|
|||
private void appendToDraftLog(String data) {
|
||||
if (logging) {
|
||||
try {
|
||||
Files.write(logPath, data.getBytes(), StandardOpenOption.APPEND);
|
||||
Files.write(logPath, data.getBytes(), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
|
||||
} catch (IOException ex) {
|
||||
LOGGER.error(null, ex);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -257,10 +257,7 @@ public class CallbackClientImpl implements CallbackClient {
|
|||
if (panel != null) {
|
||||
Session session = SessionHandler.getSession();
|
||||
if (session.isJsonLogActive()) {
|
||||
UUID gameId = callback.getObjectId();
|
||||
appendJsonEvent("GAME_OVER", callback.getObjectId(), message);
|
||||
String logFileName = "game-" + gameId + ".json";
|
||||
S3Uploader.upload(logFileName, gameId.toString());
|
||||
}
|
||||
panel.endMessage(callback.getMessageId(), message.getGameView(), message.getOptions(), message.getMessage());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,46 +0,0 @@
|
|||
package mage.client.remote;
|
||||
|
||||
import com.amazonaws.AmazonClientException;
|
||||
import com.amazonaws.auth.BasicAWSCredentials;
|
||||
import com.amazonaws.services.s3.transfer.TransferManager;
|
||||
import com.amazonaws.services.s3.transfer.Upload;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class S3Uploader {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(S3Uploader.class);
|
||||
|
||||
public static Boolean upload(String filePath, String keyName) throws Exception {
|
||||
String existingBucketName = System.getenv("S3_BUCKET") != null ? System.getenv("S3_BUCKET")
|
||||
: "xmage-game-logs-dev";
|
||||
|
||||
String accessKeyId = System.getenv("AWS_ACCESS_ID");
|
||||
String secretKeyId = System.getenv("AWS_SECRET_KEY");
|
||||
|
||||
if (accessKeyId == null || accessKeyId.isEmpty()
|
||||
|| secretKeyId == null || secretKeyId.isEmpty()
|
||||
|| existingBucketName.isEmpty()) {
|
||||
logger.info("Aborting json log sync.");
|
||||
return false;
|
||||
}
|
||||
|
||||
String path = new File("./" + filePath).getCanonicalPath();
|
||||
logger.info("Syncing " + path + " to bucket: " + existingBucketName + " with AWS Access Id: " + accessKeyId);
|
||||
|
||||
BasicAWSCredentials awsCreds = new BasicAWSCredentials(accessKeyId, secretKeyId);
|
||||
TransferManager tm = new TransferManager(awsCreds);
|
||||
Upload upload = tm.upload(existingBucketName, "/game/" + keyName + ".json", new File(path));
|
||||
|
||||
try {
|
||||
upload.waitForUploadResult();
|
||||
logger.info("Sync Complete For " + path + " to bucket: " + existingBucketName + " with AWS Access Id: " + accessKeyId);
|
||||
new File(path);
|
||||
return true;
|
||||
} catch (AmazonClientException amazonClientException) {
|
||||
logger.fatal("Unable to upload file, upload was aborted.", amazonClientException);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -896,7 +896,7 @@ public class TablesPanel extends javax.swing.JPanel {
|
|||
formatFilterList.add(RowFilter.regexFilter("^Limited", TablesTableModel.COLUMN_DECK_TYPE));
|
||||
}
|
||||
if (btnFormatOther.isSelected()) {
|
||||
formatFilterList.add(RowFilter.regexFilter("^Momir Basic|^Constructed - Pauper|^Constructed - Frontier|^Constructed - Extended|^Constructed - Eternal|^Constructed - Historical|^Constructed - Super|^Constructed - Freeform|^Australian Highlander|^European Highlander|^Canadian Highlander|^Constructed - Old|^Constructed - Historic", TablesTableModel.COLUMN_DECK_TYPE));
|
||||
formatFilterList.add(RowFilter.regexFilter("^Momir Basic|^Constructed - Pauper|^Constructed - Frontier|^Constructed - Extended|^Constructed - Eternal|^Constructed - Historical|^Constructed - Super|^Constructed - Freeform|^Constructed - Freeform Unlimited|^Australian Highlander|^European Highlander|^Canadian Highlander|^Constructed - Old|^Constructed - Historic", TablesTableModel.COLUMN_DECK_TYPE));
|
||||
}
|
||||
|
||||
// skill
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue